mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-12 13:24:52 +00:00
[update] review info (#2940)
This commit is contained in:
@@ -6,6 +6,7 @@ import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { reviewID, gettext } from '../../utils/constants';
|
||||
import Loading from '../../components/loading.js';
|
||||
import reviewComment from '../../models/review-comment.js';
|
||||
import { username } from '../../utils/constants.js';
|
||||
|
||||
import '../../css/review-comments.css';
|
||||
|
||||
@@ -27,7 +28,6 @@ class ReviewComments extends React.Component {
|
||||
showResolvedComment: true,
|
||||
comment: '',
|
||||
};
|
||||
this.accountInfo = {};
|
||||
}
|
||||
|
||||
listComments = (scroll) => {
|
||||
@@ -68,6 +68,7 @@ class ReviewComments extends React.Component {
|
||||
|
||||
resolveComment = (event) => {
|
||||
seafileAPI.updateReviewComment(reviewID, event.target.id, 'true').then((res) => {
|
||||
this.props.getCommentsNumber();
|
||||
this.listComments();
|
||||
});
|
||||
}
|
||||
@@ -172,7 +173,7 @@ class ReviewComments extends React.Component {
|
||||
this.state.commentsList.map((item, index) => {
|
||||
return (
|
||||
<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}/>
|
||||
);
|
||||
})
|
||||
@@ -202,7 +203,6 @@ const commentItemPropTypes = {
|
||||
item: PropTypes.object.isRequired,
|
||||
deleteComment: PropTypes.func.isRequired,
|
||||
resolveComment: PropTypes.func.isRequired,
|
||||
accountInfo: PropTypes.object.isRequired,
|
||||
showResolvedComment: PropTypes.bool.isRequired,
|
||||
scrollToQuote: PropTypes.func.isRequired
|
||||
};
|
||||
@@ -277,7 +277,7 @@ class CommentItem extends React.Component {
|
||||
<i className="fas fa-ellipsis-v"></i>
|
||||
</DropdownToggle>
|
||||
<DropdownMenu>
|
||||
{ (item.userEmail === this.props.accountInfo.email) &&
|
||||
{ (item.userEmail === username) &&
|
||||
<DropdownItem onClick={this.props.deleteComment}
|
||||
className="delete-comment" id={item.id}>{gettext('Delete')}</DropdownItem>}
|
||||
<DropdownItem onClick={this.props.resolveComment}
|
||||
|
@@ -90,10 +90,16 @@
|
||||
.review-side-panel-body {
|
||||
padding: 1rem 2rem;
|
||||
}
|
||||
.review-side-panel-body .dirent-table-container {
|
||||
padding-left: 0;
|
||||
}
|
||||
.review-side-panel-item {
|
||||
border-bottom: 1px solid #e6e6dd;
|
||||
padding: 1em 0;
|
||||
}
|
||||
.review-side-panel-item:last-child {
|
||||
border: 0;
|
||||
}
|
||||
.reviewer-info, .author-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button } from 'reactstrap';
|
||||
/* eslint-disable */
|
||||
import Prism from 'prismjs';
|
||||
/* eslint-enable */
|
||||
@@ -28,6 +29,7 @@ import './assets/css/fa-regular.css';
|
||||
import './assets/css/fontawesome.css';
|
||||
import './css/layout.css';
|
||||
import './css/toolbar.css';
|
||||
import './css/dirent-detail.css';
|
||||
import './css/draft-review.css';
|
||||
|
||||
const URL = require('url-parse');
|
||||
@@ -42,6 +44,7 @@ class DraftReview extends React.Component {
|
||||
reviewStatus: opStatus,
|
||||
isLoading: true,
|
||||
commentsNumber: null,
|
||||
unresolvedComments: 0,
|
||||
inResizing: false,
|
||||
commentWidth: 30,
|
||||
isShowDiff: true,
|
||||
@@ -54,6 +57,7 @@ class DraftReview extends React.Component {
|
||||
changedNodes: [],
|
||||
isShowCommentDialog: false,
|
||||
activeItem: null,
|
||||
originRepoName: '',
|
||||
};
|
||||
this.quote = '';
|
||||
this.newIndex = null;
|
||||
@@ -245,8 +249,16 @@ class DraftReview extends React.Component {
|
||||
getCommentsNumber = () => {
|
||||
seafileAPI.listReviewComments(reviewID).then((res) => {
|
||||
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({
|
||||
commentsNumber: number,
|
||||
unresolvedComments: unresolvedComments,
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -379,8 +391,6 @@ class DraftReview extends React.Component {
|
||||
const focusText = document.getNode(focus.key);
|
||||
const anchorInline = document.getClosestInline(anchor.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
|
||||
// there is a node after it, put it in the node after instead. This
|
||||
// standardizes the behavior, since it's indistinguishable to the user.
|
||||
@@ -571,6 +581,15 @@ class DraftReview extends React.Component {
|
||||
componentWillMount() {
|
||||
this.getCommentsNumber();
|
||||
this.listReviewers();
|
||||
this.getOriginRepoInfo();
|
||||
}
|
||||
|
||||
getOriginRepoInfo = () => {
|
||||
seafileAPI.getRepoInfo(draftOriginRepoID).then((res) => {
|
||||
this.setState({
|
||||
originRepoName: res.data.repo_name
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
initialDiffViewerContent = () => {
|
||||
@@ -867,11 +886,18 @@ class DraftReview extends React.Component {
|
||||
reviewers={this.state.reviewers}
|
||||
toggleAddReviewerDialog={this.toggleAddReviewerDialog}/>
|
||||
<SidePanelAuthor/>
|
||||
<UnresolvedComments number={this.state.unresolvedComments}/>
|
||||
{ this.state.isShowDiff &&
|
||||
<SidePanelChanges
|
||||
changedNumber={this.state.changedNodes.length}
|
||||
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>
|
||||
</TabPane>
|
||||
<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 {
|
||||
|
||||
constructor(props) {
|
||||
|
Reference in New Issue
Block a user