1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-11 03:41:12 +00:00

[update] review info (#2940)

This commit is contained in:
Michael An
2019-02-14 15:44:22 +08:00
committed by Daniel Pan
parent 84c9aaf3c9
commit ad620699c6
3 changed files with 93 additions and 6 deletions

View File

@@ -6,6 +6,7 @@ import { seafileAPI } from '../../utils/seafile-api';
import { reviewID, gettext } from '../../utils/constants'; import { reviewID, gettext } from '../../utils/constants';
import Loading from '../../components/loading.js'; import Loading from '../../components/loading.js';
import reviewComment from '../../models/review-comment.js'; import reviewComment from '../../models/review-comment.js';
import { username } from '../../utils/constants.js';
import '../../css/review-comments.css'; import '../../css/review-comments.css';
@@ -27,7 +28,6 @@ class ReviewComments extends React.Component {
showResolvedComment: true, showResolvedComment: true,
comment: '', comment: '',
}; };
this.accountInfo = {};
} }
listComments = (scroll) => { listComments = (scroll) => {
@@ -68,6 +68,7 @@ class ReviewComments extends React.Component {
resolveComment = (event) => { resolveComment = (event) => {
seafileAPI.updateReviewComment(reviewID, event.target.id, 'true').then((res) => { seafileAPI.updateReviewComment(reviewID, event.target.id, 'true').then((res) => {
this.props.getCommentsNumber();
this.listComments(); this.listComments();
}); });
} }
@@ -172,7 +173,7 @@ class ReviewComments extends React.Component {
this.state.commentsList.map((item, index) => { this.state.commentsList.map((item, index) => {
return ( return (
<CommentItem item={item} showResolvedComment={this.state.showResolvedComment} <CommentItem item={item} showResolvedComment={this.state.showResolvedComment}
resolveComment={this.resolveComment} accountInfo={this.accountInfo} key={index} resolveComment={this.resolveComment} key={index}
scrollToQuote={this.scrollToQuote} deleteComment={this.deleteComment}/> scrollToQuote={this.scrollToQuote} deleteComment={this.deleteComment}/>
); );
}) })
@@ -202,7 +203,6 @@ const commentItemPropTypes = {
item: PropTypes.object.isRequired, item: PropTypes.object.isRequired,
deleteComment: PropTypes.func.isRequired, deleteComment: PropTypes.func.isRequired,
resolveComment: PropTypes.func.isRequired, resolveComment: PropTypes.func.isRequired,
accountInfo: PropTypes.object.isRequired,
showResolvedComment: PropTypes.bool.isRequired, showResolvedComment: PropTypes.bool.isRequired,
scrollToQuote: PropTypes.func.isRequired scrollToQuote: PropTypes.func.isRequired
}; };
@@ -277,7 +277,7 @@ class CommentItem extends React.Component {
<i className="fas fa-ellipsis-v"></i> <i className="fas fa-ellipsis-v"></i>
</DropdownToggle> </DropdownToggle>
<DropdownMenu> <DropdownMenu>
{ (item.userEmail === this.props.accountInfo.email) && { (item.userEmail === username) &&
<DropdownItem onClick={this.props.deleteComment} <DropdownItem onClick={this.props.deleteComment}
className="delete-comment" id={item.id}>{gettext('Delete')}</DropdownItem>} className="delete-comment" id={item.id}>{gettext('Delete')}</DropdownItem>}
<DropdownItem onClick={this.props.resolveComment} <DropdownItem onClick={this.props.resolveComment}

View File

@@ -90,10 +90,16 @@
.review-side-panel-body { .review-side-panel-body {
padding: 1rem 2rem; padding: 1rem 2rem;
} }
.review-side-panel-body .dirent-table-container {
padding-left: 0;
}
.review-side-panel-item { .review-side-panel-item {
border-bottom: 1px solid #e6e6dd; border-bottom: 1px solid #e6e6dd;
padding: 1em 0; padding: 1em 0;
} }
.review-side-panel-item:last-child {
border: 0;
}
.reviewer-info, .author-info { .reviewer-info, .author-info {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Button } from 'reactstrap';
/* eslint-disable */ /* eslint-disable */
import Prism from 'prismjs'; import Prism from 'prismjs';
/* eslint-enable */ /* eslint-enable */
@@ -28,6 +29,7 @@ import './assets/css/fa-regular.css';
import './assets/css/fontawesome.css'; import './assets/css/fontawesome.css';
import './css/layout.css'; import './css/layout.css';
import './css/toolbar.css'; import './css/toolbar.css';
import './css/dirent-detail.css';
import './css/draft-review.css'; import './css/draft-review.css';
const URL = require('url-parse'); const URL = require('url-parse');
@@ -42,6 +44,7 @@ class DraftReview extends React.Component {
reviewStatus: opStatus, reviewStatus: opStatus,
isLoading: true, isLoading: true,
commentsNumber: null, commentsNumber: null,
unresolvedComments: 0,
inResizing: false, inResizing: false,
commentWidth: 30, commentWidth: 30,
isShowDiff: true, isShowDiff: true,
@@ -54,6 +57,7 @@ class DraftReview extends React.Component {
changedNodes: [], changedNodes: [],
isShowCommentDialog: false, isShowCommentDialog: false,
activeItem: null, activeItem: null,
originRepoName: '',
}; };
this.quote = ''; this.quote = '';
this.newIndex = null; this.newIndex = null;
@@ -245,8 +249,16 @@ class DraftReview extends React.Component {
getCommentsNumber = () => { getCommentsNumber = () => {
seafileAPI.listReviewComments(reviewID).then((res) => { seafileAPI.listReviewComments(reviewID).then((res) => {
let number = res.data.total_count; let number = res.data.total_count;
let comments = res.data.comments;
let unresolvedComments = 0;
for (let i = 0; i < res.data.total_count; i++) {
if (comments[i].resolved === false) {
unresolvedComments++;
}
}
this.setState({ this.setState({
commentsNumber: number, commentsNumber: number,
unresolvedComments: unresolvedComments,
}); });
}); });
} }
@@ -379,8 +391,6 @@ class DraftReview extends React.Component {
const focusText = document.getNode(focus.key); const focusText = document.getNode(focus.key);
const anchorInline = document.getClosestInline(anchor.key); const anchorInline = document.getClosestInline(anchor.key);
const focusInline = document.getClosestInline(focus.key); const focusInline = document.getClosestInline(focus.key);
const focusBlock = document.getClosestBlock(focus.key);
const anchorBlock = document.getClosestBlock(anchor.key);
// COMPAT: If the selection is at the end of a non-void inline node, and // COMPAT: If the selection is at the end of a non-void inline node, and
// there is a node after it, put it in the node after instead. This // there is a node after it, put it in the node after instead. This
// standardizes the behavior, since it's indistinguishable to the user. // standardizes the behavior, since it's indistinguishable to the user.
@@ -571,6 +581,15 @@ class DraftReview extends React.Component {
componentWillMount() { componentWillMount() {
this.getCommentsNumber(); this.getCommentsNumber();
this.listReviewers(); this.listReviewers();
this.getOriginRepoInfo();
}
getOriginRepoInfo = () => {
seafileAPI.getRepoInfo(draftOriginRepoID).then((res) => {
this.setState({
originRepoName: res.data.repo_name
});
});
} }
initialDiffViewerContent = () => { initialDiffViewerContent = () => {
@@ -867,11 +886,18 @@ class DraftReview extends React.Component {
reviewers={this.state.reviewers} reviewers={this.state.reviewers}
toggleAddReviewerDialog={this.toggleAddReviewerDialog}/> toggleAddReviewerDialog={this.toggleAddReviewerDialog}/>
<SidePanelAuthor/> <SidePanelAuthor/>
<UnresolvedComments number={this.state.unresolvedComments}/>
{ this.state.isShowDiff && { this.state.isShowDiff &&
<SidePanelChanges <SidePanelChanges
changedNumber={this.state.changedNodes.length} changedNumber={this.state.changedNodes.length}
scrollToChangedNode={this.scrollToChangedNode}/> scrollToChangedNode={this.scrollToChangedNode}/>
} }
<SidePanelOrigin originRepoName={this.state.originRepoName}/>
<div className="review-side-panel-item">
<a href={draftLink}>
<Button color="secondary" size="sm">{gettext('Edit Draft')}</Button>
</a>
</div>
</div> </div>
</TabPane> </TabPane>
<TabPane tabId="comments" className="comments"> <TabPane tabId="comments" className="comments">
@@ -970,6 +996,61 @@ class SidePanelAuthor extends React.Component {
} }
} }
class SidePanelOrigin extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="dirent-table-container">
<table className="table-thead-hidden">
<thead>
<tr><th width="25%"></th><th width="75%"></th></tr>
</thead>
<tbody>
<tr><th>{gettext('Library')}</th><td>{this.props.originRepoName}</td></tr>
<tr><th>{gettext('Position')}</th><td>{draftOriginFilePath}</td></tr>
</tbody>
</table>
</div>
);
}
}
const SidePanelOriginPropTypes = {
originRepoName: PropTypes.string.isRequired
};
SidePanelOrigin.propTypes = SidePanelOriginPropTypes;
class UnresolvedComments extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="review-side-panel-item">
<div className="review-side-panel-header">{gettext('Comments')}</div>
<div className="changes-info">
<span>{gettext('Unresolved comments:')}{' '}{this.props.number}</span>
</div>
</div>
);
}
}
const UnresolvedCommentsPropTypes = {
number: PropTypes.number.isRequired
};
UnresolvedComments.propTypes = UnresolvedCommentsPropTypes;
class SidePanelChanges extends React.Component { class SidePanelChanges extends React.Component {
constructor(props) { constructor(props) {