public/js/components/AtomStats/AtomStats.js (113 lines of code) (raw):
import React from 'react';
import {PropTypes} from 'prop-types';
import {atomPropType} from '../../constants/atomPropType';
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
import {FrontendIcon, ComposerIcon, ViewerIcon} from '../../util/icons.js';
class AtomStats extends React.Component {
static propTypes = {
routeParams: PropTypes.shape({
atomType: PropTypes.string.isRequired,
id: PropTypes.string.isRequired
}).isRequired,
atomActions: PropTypes.shape({
getAtomUsages: PropTypes.func.isRequired,
getSuggestedContent: PropTypes.func.isRequired
}).isRequired,
atom: atomPropType,
atomUsages: PropTypes.array,
suggestedContent: PropTypes.array,
config: PropTypes.shape({
composerUrl: PropTypes.string.isRequired,
viewerUrl: PropTypes.string.isRequired
}).isRequired
};
UNSAFE_componentWillMount() {
this.props.atomActions.getAtomUsages(this.props.routeParams.atomType, this.props.routeParams.id);
this.props.atomActions.getSuggestedContent(this.props.routeParams.id, this.props.routeParams.atomType);
}
renderContent = (usage, i) => {
const headline = usage.fields.headline;
if (headline) {
const composerLink = `${this.props.config.composerUrl}/content/${usage.fields.internalComposerCode}`;
const viewerLink = `${this.props.config.viewerUrl}/preview/${usage.id}`;
const websiteLink = `https://www.theguardian.com/${usage.id}`;
return (
<li className="usages-list__item" key={`usage-${i}`}>
<p className="usages-list__item__name">{headline}</p>
<div className="usages-list__links">
<p className="usages-list__item__date">
Created: {distanceInWordsToNow(usage.fields.creationDate, {addSuffix: true})}
<a className="usages-list__link" href={websiteLink} title="Open on theguardian.com" target="_blank" rel="noreferrer">
<FrontendIcon />
</a>
<a className="usages-list__link" href={composerLink} title="Open in Composer" target="_blank" rel="noreferrer">
<ComposerIcon />
</a>
<a className="usages-list__link" href={viewerLink} title="Open in Viewer" target="_blank" rel="noreferrer">
<ViewerIcon />
</a></p>
</div>
</li>
);
}
};
renderAtomUsages = () => {
if (this.props.atomUsages && this.props.atomUsages.length > 0) {
return (
<ul className="usages-list">
{this.props.atomUsages.map((usage, i) => this.renderContent(usage, i))}
</ul>
);
} else {
return (
<div>This atom is not currently used in any content.</div>
);
}
};
renderSuggestedContent = () => {
if (this.props.suggestedContent && this.props.suggestedContent.length > 0) {
return (
<ul className="usages-list">
{this.props.suggestedContent.map((usage, i) => this.renderContent(usage, i))}
</ul>
);
} else {
return (
<div>No suggested content for the last 7 days.</div>
);
}
};
render() {
return (
<div className="atom-editor">
<h1 className="atom-editor__title">{this.props.atom ? this.props.atom.title : ''}</h1>
<h2>Usages</h2>
<div className="atom-editor__section">
{this.renderAtomUsages()}
</div>
<h2>Not yet included</h2>
<div className="atom-editor__section">
{this.renderSuggestedContent()}
</div>
</div>
);
}
}
//REDUX CONNECTIONS
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as getAtomUsagesActions from '../../actions/AtomActions/getAtomUsages.js';
import * as getSuggestedContentActions from '../../actions/AtomActions/getSuggestedContent.js';
function mapStateToProps(state) {
return {
atom: state.atom,
atomUsages: state.atomUsages,
suggestedContent: state.suggestedContent,
config: state.config
};
}
function mapDispatchToProps(dispatch) {
return {
atomActions: bindActionCreators(Object.assign({}, getAtomUsagesActions, getSuggestedContentActions), dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(AtomStats);