import React from 'react'; import PropTypes from 'prop-types'; import Comment from './PageComment/Comment'; import DeleteCommentModal from './PageComment/DeleteCommentModal'; /** * Load data of comments and render the list of * * @author Yuki Takei * * @export * @class PageComments * @extends {React.Component} */ export default class PageComments extends React.Component { constructor(props) { super(props); this.state = { // desc order array comments: [], isLayoutTypeGrowi: false, // for deleting comment commentToDelete: undefined, isDeleteConfirmModalShown: false, errorMessageForDeleting: undefined, }; this.init = this.init.bind(this); this.confirmToDeleteComment = this.confirmToDeleteComment.bind(this); this.deleteComment = this.deleteComment.bind(this); this.showDeleteConfirmModal = this.showDeleteConfirmModal.bind(this); this.closeDeleteConfirmModal = this.closeDeleteConfirmModal.bind(this); } componentWillMount() { const pageId = this.props.pageId; if (pageId) { this.init(); } } init() { if (!this.props.pageId) { return ; } const pageId = this.props.pageId; const layoutType = this.props.crowi.getConfig()['layoutType']; this.setState({isLayoutTypeGrowi: 'crowi-plus' === layoutType || 'growi' === layoutType}); // get data (desc order array) this.props.crowi.apiGet('/comments.get', {page_id: pageId}) .then(res => { if (res.ok) { this.setState({comments: res.comments}); } }).catch(err => { }); } confirmToDeleteComment(comment) { this.setState({commentToDelete: comment}); this.showDeleteConfirmModal(); } deleteComment() { const comment = this.state.commentToDelete; this.props.crowi.apiPost('/comments.remove', {comment_id: comment._id}) .then(res => { if (res.ok) { this.findAndSplice(comment); } this.closeDeleteConfirmModal(); }).catch(err => { this.setState({errorMessageForDeleting: err.message}); }); } findAndSplice(comment) { let comments = this.state.comments; const index = comments.indexOf(comment); if (index < 0) { return; } comments.splice(index, 1); this.setState({comments}); } showDeleteConfirmModal() { this.setState({isDeleteConfirmModalShown: true}); } closeDeleteConfirmModal() { this.setState({ commentToDelete: undefined, isDeleteConfirmModalShown: false, errorMessageForDeleting: undefined, }); } /** * generate Elements of Comment * * @param {any} comments Array of Comment Model Obj * * @memberOf PageComments */ generateCommentElements(comments) { return comments.map((comment) => { return ( ); }); } render() { let currentComments = []; let newerComments = []; let olderComments = []; let comments = this.state.comments; if (this.state.isLayoutTypeGrowi) { // replace with asc order array comments = comments.slice().reverse(); // non-destructive reverse } // divide by revisionId and createdAt const revisionId = this.props.revisionId; const revisionCreatedAt = this.props.revisionCreatedAt; comments.forEach((comment) => { if (comment.revision == revisionId) { currentComments.push(comment); } else if (Date.parse(comment.createdAt)/1000 > revisionCreatedAt) { newerComments.push(comment); } else { olderComments.push(comment); } }); // generate elements const currentElements = this.generateCommentElements(currentComments); const newerElements = this.generateCommentElements(newerComments); const olderElements = this.generateCommentElements(olderComments); // generate blocks const currentBlock = (
{currentElements}
); const newerBlock = (
{newerElements}
); const olderBlock = (
{olderElements}
); // generate toggle elements const iconForNewer = (this.state.isLayoutTypeGrowi) ? : ; const toggleNewer = (newerElements.length === 0) ?
: ( {iconForNewer} Comments for Newer Revision {iconForNewer} ); const iconForOlder = (this.state.isLayoutTypeGrowi) ? : ; const toggleOlder = (olderElements.length === 0) ?
: ( {iconForOlder} Comments for Older Revision {iconForOlder} ); // layout blocks const commentsElements = (this.state.isLayoutTypeGrowi) ? (
{olderBlock} {toggleOlder} {currentBlock} {toggleNewer} {newerBlock}
) : (
{newerBlock} {toggleNewer} {currentBlock} {toggleOlder} {olderBlock}
); return (
{commentsElements}
); } } PageComments.propTypes = { pageId: PropTypes.string, revisionId: PropTypes.string, revisionCreatedAt: PropTypes.number, crowi: PropTypes.object.isRequired, };