scripts/apps/authoring-react/article-widgets/metadata/metadata.tsx
import React, {Fragment} from 'react';
import {IArticleSideWidget, IExtensionActivationResult, IVocabularyItem} from 'superdesk-api';
import {gettext} from 'core/utils';
import {AuthoringWidgetHeading} from 'apps/dashboard/widget-heading';
import {AuthoringWidgetLayout} from 'apps/dashboard/widget-layout';
import {Spacer} from 'core/ui/components/Spacer';
import {Input, Select, Switch, Option, Heading, ContentDivider, Label} from 'superdesk-ui-framework/react';
import {MetadataItem} from './metadata-item';
import {dataApi} from 'core/helpers/CrudManager';
import {ILanguage} from 'superdesk-interfaces/Language';
import {DateTime} from 'core/ui/components/DateTime';
import {vocabularies} from 'api/vocabularies';
import Datetime from 'core/datetime/datetime';
import {sdApi} from 'api';
import {StateComponent} from 'apps/search/components/fields/state';
import {AnnotationsPreview} from './AnnotationsPreview';
// Can't call `gettext` in the top level
const getLabel = () => gettext('Metadata');
type IProps = React.ComponentProps<
IExtensionActivationResult['contributions']['authoringSideWidgets'][0]['component']
>;
interface IState {
languages: Array<ILanguage>;
}
class MetadataWidget extends React.PureComponent<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
languages: [],
};
}
componentDidMount(): void {
dataApi.query<ILanguage>(
'languages',
1,
{field: 'language', direction: 'ascending'},
{},
).then(({_items}) => {
this.setState({
languages: _items,
});
});
}
render() {
const {article} = this.props;
const {
flags,
usageterms,
pubstatus,
expiry,
urgency,
priority,
word_count,
source,
anpa_take_key,
genre,
dateline,
slugline,
byline,
sign_off,
guid,
unique_name,
type,
language,
copyrightholder,
copyrightnotice,
creditline,
original_source,
ingest_provider_sequence,
ingest_provider,
keywords,
signal,
anpa_category,
place,
ednote,
_current_version,
firstcreated,
versioncreated,
renditions,
original_id,
originalCreator,
versioncreator,
rewritten_by,
} = article;
const {onItemChange} = this.props;
const allVocabularies = sdApi.vocabularies.getAll();
return (
<AuthoringWidgetLayout
header={(
<AuthoringWidgetHeading
widgetName={getLabel()}
editMode={false}
/>
)}
body={(
<Spacer v gap="16" noWrap>
<Spacer h gap="64" justifyContent="space-between" noWrap>
<Heading type="h6" align="start">
{gettext('Not For Publication')}
</Heading>
<Switch
label={{content: ''}} // TODO: Implement accessibility
onChange={() => {
onItemChange({
...article,
flags: {
...flags,
marked_for_not_publication: !flags.marked_for_not_publication,
},
});
}}
value={flags.marked_for_not_publication}
/>
</Spacer>
<ContentDivider border type="dotted" margin="none" />
<Spacer h gap="64" justifyContent="space-between" noWrap>
<Heading type="h6" align="start">
{gettext('Legal')}
</Heading>
<Switch
label={{content: ''}} // TODO: Implement accessibility
onChange={() => {
onItemChange({
...article,
flags: {...flags, marked_for_legal: !flags.marked_for_legal},
});
}}
value={flags.marked_for_legal}
/>
</Spacer>
<ContentDivider border type="dotted" margin="x-small" />
<Input
label={gettext('Usage terms').toUpperCase()}
inlineLabel
type="text"
value={usageterms}
onChange={(value) => {
onItemChange({
...article,
usageterms: value,
});
}}
/>
<ContentDivider border type="dotted" margin="x-small" />
<Select
inlineLabel
label={gettext('Language').toUpperCase()}
value={language}
onChange={(val) => {
onItemChange({
...article,
language: val,
});
}}
>
{
this.state.languages.map((lang) =>
<Option value={lang.language} key={lang._id}>{lang.label}</Option>,
)
}
</Select>
<ContentDivider border type="dotted" margin="x-small" />
{(pubstatus?.length ?? 0) > 0 && (
<MetadataItem
label={gettext('Pubstatus')}
value={pubstatus}
/>
)}
{(original_source?.length ?? 0) > 0 && (
<MetadataItem
label={gettext('Original source')}
value={original_source}
/>
)}
{(copyrightholder?.length ?? 0) > 0 && (
<MetadataItem
label={gettext('Copyright')}
value={copyrightholder}
/>
)}
{(copyrightnotice?.length ?? 0) > 0 && (
<MetadataItem
label={gettext('Copyright notice')}
value={copyrightnotice}
/>
)}
{(creditline?.length ?? 0) > 0 && (
<MetadataItem
label={gettext('Credit')}
value={creditline}
/>
)}
{
<>
<Spacer h gap="64" justifyContent="space-between" noWrap>
<Heading type="h6">
{gettext('State').toUpperCase()}
</Heading>
<Spacer h gap="4" justifyContent="start" noWrap style={{flexWrap: 'wrap'}} >
<StateComponent item={article} />
{article.embargo && (
<Label
style="hollow"
type="alert"
text={gettext('embargo')}
/>
)}
{flags.marked_for_not_publication && (
<Label
text={gettext('Not For Publication')}
style="hollow"
type="alert"
/>
)}
{flags.marked_for_legal && (
<Label
text={gettext('Legal')}
style="hollow"
type="alert"
/>
)}
{flags.marked_for_sms && (
<Label
text={gettext('Sms')}
style="hollow"
type="alert"
/>
)}
{(rewritten_by?.length ?? 0) > 0 && (
<Label
text={gettext('Updated')}
style="hollow"
type="alert"
/>
)}
</Spacer>
</Spacer>
<ContentDivider border type="dotted" margin="x-small" />
</>
}
{ingest_provider != null && (
<MetadataItem
label={gettext('Ingest Provider')}
value={ingest_provider}
/>
)}
{
(ingest_provider_sequence?.length ?? 0) > 0 && (
<MetadataItem
label={gettext('Ingest sequence')}
value={ingest_provider_sequence}
/>
)
}
{expiry && (
<MetadataItem
label={gettext('Expiry')}
value={<Datetime datetime={expiry} />}
/>
)}
{(slugline?.length ?? 0) > 0 && <MetadataItem label={gettext('Slugline')} value={slugline} />}
{(urgency?.length ?? 0) > 0 && <MetadataItem label={gettext('Urgency')} value={urgency} />}
{priority && <MetadataItem label={gettext('Priority')} value={priority} />}
{word_count > 0 && <MetadataItem label={gettext('Word Count')} value={word_count} />}
{keywords && (
<MetadataItem
label={gettext('Word Count')}
value={sdApi.vocabularies.vocabularyItemsToString(keywords)}
/>
)}
{(source?.length ?? 0) > 0 && <MetadataItem label={gettext('Source')} value={source} />}
<MetadataItem label={gettext('Take key')} value={anpa_take_key} />
{
signal && (
<MetadataItem
label={gettext('Signal')}
value={(
<div>
{(signal.map(({name, qcode}) => (
<Fragment key={name}>{name ?? qcode}</Fragment>
)))}
</div>
)}
/>
)
}
{
anpa_category?.name != null && (
<MetadataItem
label={gettext('Category')}
value={sdApi.vocabularies.vocabularyItemsToString(anpa_category, 'name')}
/>
)
}
{
allVocabularies
.filter((cv) => article[cv.schema_field] != null)
.toArray()
.map((vocabulary) => (
<MetadataItem
key={vocabulary._id}
label={vocabulary.display_name}
value={vocabularies.getVocabularyItemLabel(
article[vocabulary.schema_field],
article,
)}
/>
))
}
{
(genre.length ?? 0) > 0
&& allVocabularies.map((v) => v.schema_field).includes('genre') === false
&& (
<MetadataItem
label={gettext('Genre')}
value={sdApi.vocabularies.vocabularyItemsToString(genre, 'name')}
/>
)
}
{
(place.length ?? 0) > 0
&& allVocabularies.map((v) => v.schema_field).includes('place') === false
&& (
<MetadataItem
label={gettext('Place')}
value={sdApi.vocabularies.vocabularyItemsToString(place, 'name')}
/>
)
}
{(ednote?.length ?? 0) > 0 && <MetadataItem label={gettext('Editorial note')} value={ednote} />}
<Spacer v gap="4" justifyContent="space-between">
<Heading type="h6" align="start">
{gettext('Dateline').toUpperCase()}
</Heading>
<Spacer h gap="4" justifyContent="space-between" noWrap>
<DateTime dateTime={dateline?.date} /> /
<span>{dateline?.located.city}</span>
</Spacer>
</Spacer>
<ContentDivider border type="dotted" margin="x-small" />
<MetadataItem label={gettext('Byline')} value={byline} />
<MetadataItem label={gettext('Sign-off')} value={sign_off} />
{_current_version && <MetadataItem label={gettext('Version')} value={_current_version} />}
{firstcreated && (
<MetadataItem
label={gettext('Created')}
value={(
<DateTime
dateTime={firstcreated}
/>
)}
/>
)}
{versioncreated && (
<MetadataItem
label={gettext('Last updated')}
value={<DateTime dateTime={versioncreated} />}
/>
)}
<MetadataItem label={gettext('Original Id')} value={original_id} />
{(originalCreator?.length ?? 0) > 0 && (
<MetadataItem
label={gettext('Original creator')}
value={originalCreator}
/>
)}
{(versioncreator?.length ?? 0) > 0 && (
<MetadataItem
label={gettext('Version creator')}
value={versioncreator}
/>
)}
<MetadataItem label={gettext('Guid').toUpperCase()} value={guid} />
<Input
label={gettext('Unique name').toUpperCase()}
inlineLabel
type="text"
value={unique_name}
onChange={(value) => {
onItemChange({
...article,
unique_name: value,
});
}}
/>
<ContentDivider border type="dotted" margin="x-small" />
<MetadataItem label={gettext('Type')} value={type} />
{
renditions?.original != null && (
<MetadataItem
label={gettext('Type')}
value={`${renditions.original.width} x ${renditions.original.height}`}
/>
)
}
{
article.type === 'picture'
&& article.archive_description !== article.description_text
&& (
<AnnotationsPreview article={article} />
)
}
</Spacer>
)}
/>
);
}
}
export function getMetadataWidget() {
const metadataWidget: IArticleSideWidget = {
_id: 'metadata-widget',
label: getLabel(),
order: 1,
icon: 'info',
component: MetadataWidget,
};
return metadataWidget;
}