Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Feature/CV2-4629: Managing articles in item page #1999

Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"id": "factCheckCard.dateLabel",
"description": "Date tooltip label for fact-check cards",
"defaultMessage": "Published at"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"id": "mediaArticleCard.editButton",
"description": "Label for edit button",
"defaultMessage": "Edit Article"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{
"id": "article.readOnlyAlertTitle",
"description": "Title of the alert message displayed on data points section of the edit feed page.",
"defaultMessage": "Fact-Check Added"
},
{
"id": "article.readOnlyAlertContent",
"description": "Description of the alert message displayed on data points section of the edit feed page.",
"defaultMessage": "When a fact-check article is added it will be prioritized to be sent to all media and requests that match this item."
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{
"id": "article.readOnlyAlertTitle",
"description": "Title of the alert message displayed on data points section of the edit feed page.",
"defaultMessage": "Fact-Check Added"
},
{
"id": "article.readOnlyAlertContent",
"description": "Description of the alert message displayed on data points section of the edit feed page.",
"defaultMessage": "When a fact-check article is added it will be prioritized to be sent to all media and requests that match this item."
}
]
19 changes: 19 additions & 0 deletions src/app/components/article/ArticleCard.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.articleCard {
display: block;
min-width: 500px;
}

.card {
background-color: var(--color-white-100);
border: 1px solid var(--color-gray-88);
border-radius: 8px;
outline: solid 1px transparent;
padding: 8px;
transition: border-color 225ms cubic-bezier(0, 0, .2, 1) 0ms, outline-color 225ms cubic-bezier(0, 0, .2, 1) 0ms;
width: 100%;
}

.articleIcon {
font-size: var(--font-size-body-2);
margin-right: 0.5px;
}
113 changes: 113 additions & 0 deletions src/app/components/article/MediaArticleCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames/bind';
import { FormattedMessage } from 'react-intl';
import Card from '../cds/media-cards/Card';
import EllipseIcon from '../../icons/ellipse.svg';
import FactCheckIcon from '../../icons/fact_check.svg';
import BookIcon from '../../icons/book.svg';
import BulletSeparator from '../layout/BulletSeparator';
import styles from './ArticleCard.module.css';
import Language from '../cds/media-cards/Language';
import LastRequestDate from '../cds/media-cards/LastRequestDate';
import ArticleUrl from '../cds/media-cards/ArticleUrl';
import ItemReportStatus from '../cds/media-cards/ItemReportStatus';
import ButtonMain from '../cds/buttons-checkboxes-chips/ButtonMain';

const MediaArticleCard = ({
title,
url,
date,
statusLabel,
statusColor,
languageCode,
publishedAt,
variant,
}) => (
<div className={cx('article-card', styles.articleCard)}>
<Card>
<div>
<div className={cx('typography-body2')}>
<span className={styles.articleIcon}>
{variant === 'fact-check' ?
<FactCheckIcon /> : <BookIcon />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: I prefer to make it explicit:

{ variant === 'fact-check' && <FactCheckIcon /> }
{ variant === 'explainer' && <BookIcon /> }

}
</span>
{variant === 'fact-check' ? 'Fact-Check' : 'Explainer'}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: I prefer to make it explicit:

{ variant === 'fact-check' && 'Fact-Check' }
{ variant === 'explainer' && 'Explainer' }

Actually, we need to localize those two strings too.

{statusLabel && (
<>
:<EllipseIcon style={{ color: statusColor }} /> {statusLabel}
</>
)}
</div>
<span>
{url ? (
<ArticleUrl url={url} title={title} variant={variant} showIcon={false} />
) : (
title
)}
</span>
<div />
<BulletSeparator
details={[
variant === 'fact-check ' && (<ItemReportStatus
publishedAt={publishedAt ? new Date(publishedAt * 1000) : null}
variant="text"
theme="lightText"
tooltip={false}
/>),
languageCode && (
<Language
languageCode={languageCode}
variant="text"
theme="lightText"
/>
),
date && (
<LastRequestDate
tooltip={false}
variant="text"
theme="lightText"
lastRequestDate={new Date(date * 1000)}
/>
),
(
<ButtonMain
disabled
buttonProps={{
type: null,
}}
label={<FormattedMessage id="mediaArticleCard.editButton" defaultMessage="Edit Article" description="Label for edit button" />}
variant="contained"
size="small"
theme="text"
onClick={() => {}}
/>
),
]}
/>
</div>
</Card>
</div>
);

MediaArticleCard.defaultProps = {
url: null,
languageCode: null,
variant: 'explainer',
statusLabel: null,
publishedAt: null,
};

MediaArticleCard.propTypes = {
title: PropTypes.string.isRequired,
url: PropTypes.string,
date: PropTypes.number.isRequired, // Timestamp
statusLabel: PropTypes.string,
statusColor: PropTypes.string.isRequired,
languageCode: PropTypes.string,
publishedAt: PropTypes.number, // Timestamp
variant: PropTypes.oneOf(['explainer', 'fact-check']),
};

export default MediaArticleCard;
52 changes: 15 additions & 37 deletions src/app/components/article/MediaArticles.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import MediasLoading from '../media/MediasLoading';
import DescriptionIcon from '../../icons/description.svg';
import { getErrorMessage } from '../../helpers';
import styles from './Articles.module.css';
import MediaArticlesDisplay from './MediaArticlesDisplay';
// eslint-disable-next-line no-unused-vars
import ArticleForm from './ArticleForm'; // For GraphQL fragment

Expand All @@ -22,16 +23,7 @@ const addExplainerMutation = graphql`
createExplainerItem(input: $input) {
project_media {
id
fact_check {
id
}
explainers(first: 100) {
edges {
node {
id
}
}
}
...MediaArticlesDisplay_projectMedia
}
}
}
Expand All @@ -42,16 +34,7 @@ const addFactCheckMutation = graphql`
updateClaimDescription(input: $input) {
project_media {
id
fact_check {
id
}
explainers(first: 100) {
edges {
node {
id
}
}
}
...MediaArticlesDisplay_projectMedia
}
}
}
Expand All @@ -64,7 +47,7 @@ const MediaArticlesComponent = ({
}) => {
const [adding, setAdding] = React.useState(false);
const setFlashMessage = React.useContext(FlashMessageSetterContext);
const hasArticle = (projectMedia.fact_check?.id || projectMedia.explainers.edges[0]?.node?.id);
const hasArticle = projectMedia.articles_count > 0;

const onCompleted = () => {
setFlashMessage(
Expand Down Expand Up @@ -121,7 +104,11 @@ const MediaArticlesComponent = ({
{/* FIXME: Make sure the form can receive the right reference for the current item */}
<NewArticleButton team={team} buttonMainProps={{ size: 'small', theme: 'text' }} disabled={projectMedia.type === 'Blank'} />
</div>
{ !hasArticle && (
{ hasArticle ? (
<>
<MediaArticlesDisplay projectMedia={projectMedia} />
</>
) : (
<>
<div className={cx('typography-body1', styles.articlesSidebarNoArticle)}>
<DescriptionIcon style={{ fontSize: 'var(--font-size-h4)' }} />
Expand Down Expand Up @@ -155,10 +142,10 @@ MediaArticlesComponent.propTypes = {
id: PropTypes.string.isRequired,
dbid: PropTypes.number.isRequired,
type: PropTypes.string.isRequired,
fact_check: PropTypes.object,
explainers: PropTypes.exact({
edges: PropTypes.arrayOf(PropTypes.object),
}),
// fact_check: PropTypes.object,
// explainers: PropTypes.exact({
// edges: PropTypes.arrayOf(PropTypes.object),
// }),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Why is this commented?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

}).isRequired,
onUpdate: PropTypes.func.isRequired,
};
Expand All @@ -182,19 +169,10 @@ const MediaArticles = ({ teamSlug, projectMediaDbid }) => {
...ArticleForm_team
}
project_media(ids: $ids) {
id
dbid
type
fact_check: fact_check {
id
}
explainers(first: 100) {
edges {
node {
id
}
}
}
articles_count
...MediaArticlesDisplay_projectMedia
}
}
`}
Expand Down
108 changes: 108 additions & 0 deletions src/app/components/article/MediaArticlesDisplay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { graphql, createFragmentContainer } from 'react-relay/compat';
import Alert from '../cds/alerts-and-prompts/Alert';
import MediaArticleCard from './MediaArticleCard';
import { getStatus } from '../../helpers';
import styles from './MediaArticlesDisplay.module.css';


const MediaArticlesDisplay = ({ projectMedia }) => {
const explainers = projectMedia?.explainer_items?.edges?.map(edge => edge.node.explainer);
const factCheck = projectMedia?.fact_check;

let currentStatus = null;
if (projectMedia?.status) {
currentStatus = getStatus(projectMedia.team.verification_statuses, projectMedia.status);
}

return (
<div className={styles.articles}>
{factCheck ?
<MediaArticleCard
key={factCheck.id}
variant="fact-check"
title={factCheck.title || factCheck.claim_description?.description}
url={factCheck.url}
languageCode={factCheck.language !== 'und' ? factCheck?.language : null}
date={factCheck.updated_at}
statusColor={currentStatus ? currentStatus.style?.color : null}
statusLabel={currentStatus ? currentStatus.label : null}
publishedAt={factCheck?.claim_description?.project_media?.report_status === 'published' && factCheck?.claim_description?.project_media?.published ? parseInt(factCheck?.claim_description?.project_media?.published, 10) : null}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: We can make the code more deterministic by removing the ? from factCheck in this block, since they're all under a factCheck ? condition already.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

/>
: null}
<br />
{factCheck && explainers?.length > 0 ?
<>
<Alert
variant="info"
contained
title={
<FormattedMessage
id="article.readOnlyAlertTitle"
defaultMessage="Fact-Check Added"
description="Title of the alert message displayed on data points section of the edit feed page."
/>
}
content={
<FormattedMessage
id="article.readOnlyAlertContent"
defaultMessage="When a fact-check article is added it will be prioritized to be sent to all media and requests that match this item."
description="Description of the alert message displayed on data points section of the edit feed page."
/>
}
/>
<br />
</>
: null}
{explainers?.filter(explainer => explainer !== null).map(explainer => (
<>
<MediaArticleCard
key={explainer?.id}
variant="explainer"
title={explainer?.title || explainer?.claim_description?.description}
url={explainer?.url}
languageCode={explainer?.language !== 'und' ? explainer?.language : null}
date={explainer?.updated_at}
/>
<br />
</>
))}
</div>
);
};
export default createFragmentContainer(MediaArticlesDisplay, graphql`
fragment MediaArticlesDisplay_projectMedia on ProjectMedia {
status
team {
verification_statuses
}
id
fact_check {
title
language
updated_at
url
claim_description {
description
project_media {
published
report_status
}
}
}
explainer_items(first: 100) {
edges {
node {
id
explainer {
language
title
url
updated_at
}
}
}
}
}
`);
5 changes: 5 additions & 0 deletions src/app/components/article/MediaArticlesDisplay.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.articles {
align-items: center;
gap: 10px;
margin-top: 10px;
}
Loading