public/js/components/ContentSuggestions/ContentSuggestions.js (115 lines of code) (raw):
import React from 'react';
import {PropTypes} from 'prop-types';
import CopyUrlButton from './CopyUrlButton';
import {FrontendIcon, ComposerIcon, ViewerIcon} from '../../util/icons.js';
import {SuggestedAtomsPropType} from '../../actions/AtomActions/getSuggestionsForLatestContent.js';
class ContentSuggestions extends React.Component {
static propTypes = {
suggestionsForLatestContent: PropTypes.arrayOf(SuggestedAtomsPropType),
atomActions: PropTypes.shape({
getSuggestionsForLatestContent: PropTypes.func.isRequired
}).isRequired,
config: PropTypes.shape({
composerUrl: PropTypes.string.isRequired,
viewerUrl: PropTypes.string.isRequired,
liveCapiUrl: PropTypes.string
}).isRequired
};
UNSAFE_componentWillMount() {
this.props.atomActions.getSuggestionsForLatestContent();
}
renderAtom = atom => {
const workshopUrl = `/atoms/${ atom.atomType }/${ atom.id }/edit`;
return (
<li className="suggestions-content" key={`suggested-atom-${atom.id}`}>
<div className="suggestions-atom">
<div className="suggestions-atom-details">
<a className="suggestions-atom-title atom-list__link" href={ workshopUrl } target="_blank" rel="noreferrer">{ atom.title }</a>
<span className="suggestions-atom-type">({ atom.atomType.charAt(0) + atom.atomType.slice(1).toLowerCase() } atom)</span>
</div>
<CopyUrlButton config={this.props.config} atom={atom}/>
</div>
</li>
);
};
renderContent = content => {
const composerLink = `${this.props.config.composerUrl}/content/${content.internalComposerCode}`;
const viewerLink = `${this.props.config.viewerUrl}/preview/${content.contentId}`;
const websiteLink = `https://www.theguardian.com/${content.contentId}`;
return (
<div className="suggestions-content-container">
<div className="suggestions-headline">
<span className="suggestions-list__item__name">{content.headline}</span>
</div>
<div className="suggestions-list__links">
<p className="suggestions-list__item__date">
<a className="suggestions-list__link" href={websiteLink} title="Open on theguardian.com" target="_blank" rel="noreferrer">
<FrontendIcon />
</a>
<a className="suggestions-list__link" href={composerLink} title="Open in Composer" target="_blank" rel="noreferrer">
<ComposerIcon />
</a>
<a className="suggestions-list__link" href={viewerLink} title="Open in Viewer" target="_blank" rel="noreferrer">
<ViewerIcon />
</a></p>
</div>
</div>
);
};
renderAtomsArray = (atomsArray) => {
return (
<div className="suggestions-atom-container">
<div className="suggestions-atom-container-heading">Suggested atoms:</div>
<ul className="suggestions-list">
{atomsArray.map(atom => this.renderAtom(atom))}
</ul>
</div>
);
};
renderContentAndSuggestions = (item, i) => {
return (
<li className="suggestions-list__item" key={`usage-${i}`}>
{ this.renderContent(item) }
{ this.renderAtomsArray(item.atoms) }
</li>
);
};
renderSuggestionsForLatestContent() {
if (this.props.suggestionsForLatestContent) {
return (
<ul className="suggestions-list">
{ this.props.suggestionsForLatestContent
.filter(item => item.atoms.length > 0)
.map((item, i) => this.renderContentAndSuggestions(item, i))
}
</ul>
);
} else {
return (
<div>Loading atom suggestions for most viewed content...</div>
);
}
}
render() {
return (
<div className="atom-editor suggestions-container">
{this.renderSuggestionsForLatestContent()}
</div>
);
}
}
//REDUX CONNECTIONS
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as getSuggestionsForLatestContent from '../../actions/AtomActions/getSuggestionsForLatestContent.js';
function mapStateToProps(state) {
return {
suggestionsForLatestContent: state.suggestionsForLatestContent,
config: state.config
};
}
function mapDispatchToProps(dispatch) {
return {
atomActions: bindActionCreators(Object.assign({}, getSuggestionsForLatestContent), dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ContentSuggestions);