mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-17 07:41:26 +00:00
display draft&review activities (#2851)
* dispaly draft&review activities * repalce obj_id with old_path * use [for loop] filter events * repair code * prohibit [publish draft]
This commit is contained in:
@@ -23,7 +23,7 @@ class DraftListMenu extends React.Component {
|
||||
return (
|
||||
<ul className="dropdown-menu" style={style}>
|
||||
<li className="dropdown-item" onClick={this.props.onDeleteHandler}>{gettext('Delete')}</li>
|
||||
<li className="dropdown-item" onClick={this.props.onPublishHandler}>{gettext('Publish')}</li>
|
||||
{/* <li className="dropdown-item" onClick={this.props.onPublishHandler}>{gettext('Publish')}</li> */}
|
||||
<li className="dropdown-item" onClick={this.props.onReviewHandler}>{gettext('Ask for review')}</li>
|
||||
</ul>
|
||||
);
|
||||
|
@@ -82,15 +82,42 @@ class TableBody extends Component {
|
||||
details = <td>{libLink}</td>;
|
||||
break;
|
||||
}
|
||||
} else if (item.obj_type == 'review') {
|
||||
let fileURL = `${siteRoot}drafts/review/${item.review_id}`;
|
||||
let fileLink = <a href={fileURL}>{item.name}</a>;
|
||||
switch(item.op_type) {
|
||||
case 'open':
|
||||
op = gettext('Open review');
|
||||
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
case 'closed':
|
||||
op = gettext('Close review');
|
||||
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
case 'finished':
|
||||
op = gettext('Publish draft');
|
||||
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
}
|
||||
} else if (item.obj_type == 'file') {
|
||||
let fileURL = `${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`;
|
||||
let fileLink = <a href={fileURL}>{item.name}</a>;
|
||||
switch(item.op_type) {
|
||||
case 'create':
|
||||
if (item.name.endsWith("(draft).md")) {
|
||||
op = gettext('Created draft');
|
||||
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
}
|
||||
op = gettext('Created file');
|
||||
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
case 'delete':
|
||||
if (item.name.endsWith("(draft).md")) {
|
||||
op = gettext('Deleted draft');
|
||||
details = <td>{item.name}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
}
|
||||
op = gettext('Deleted file');
|
||||
details = <td>{item.name}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
@@ -108,6 +135,11 @@ class TableBody extends Component {
|
||||
details = <td>{item.old_path} => {filePathLink}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
case 'edit': // update
|
||||
if (item.name.endsWith("(draft).md")) {
|
||||
op = gettext('Updated draft');
|
||||
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
}
|
||||
op = gettext('Updated file');
|
||||
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||
break;
|
||||
@@ -177,6 +209,8 @@ class FilesActivities extends Component {
|
||||
items: [],
|
||||
};
|
||||
this.avatarSize = 72;
|
||||
this.curPathList = [];
|
||||
this.oldPathList = [];
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -184,7 +218,7 @@ class FilesActivities extends Component {
|
||||
seafileAPI.listActivities(currentPage, this.avatarSize).then(res => {
|
||||
// {"events":[...]}
|
||||
this.setState({
|
||||
items: res.data.events,
|
||||
items: this.filterSuperfluousEvents(res.data.events),
|
||||
currentPage: currentPage + 1,
|
||||
isFirstLoading: false,
|
||||
hasMore: true,
|
||||
@@ -199,13 +233,42 @@ class FilesActivities extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
filterSuperfluousEvents = (events) => {
|
||||
events.map((item) => {
|
||||
if (item.op_type === "finished") {
|
||||
this.curPathList.push(item.path);
|
||||
this.oldPathList.push(item.old_path);
|
||||
}
|
||||
});
|
||||
let actuallyEvents = [];
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
if (events[i].obj_type === 'file') {
|
||||
if (events[i].op_type === 'delete' && this.oldPathList.includes(events[i].path)) {
|
||||
this.oldPathList.splice(this.oldPathList.indexOf(events[i].path), 1);
|
||||
continue;
|
||||
} else if (events[i].op_type === 'edit' && this.curPathList.includes(events[i].path)) {
|
||||
this.curPathList.splice(this.curPathList.indexOf(events[i].path), 1);
|
||||
continue;
|
||||
} else if (events[i].op_type === 'rename' && this.oldPathList.includes(events[i].old_path)) {
|
||||
this.oldPathList.splice(this.oldPathList.indexOf(events[i].old_path), 1);
|
||||
continue;
|
||||
} else {
|
||||
actuallyEvents.push(events[i]);
|
||||
}
|
||||
} else {
|
||||
actuallyEvents.push(events[i]);
|
||||
}
|
||||
}
|
||||
return actuallyEvents;
|
||||
}
|
||||
|
||||
getMore() {
|
||||
let currentPage = this.state.currentPage;
|
||||
seafileAPI.listActivities(currentPage, this.avatarSize).then(res => {
|
||||
// {"events":[...]}
|
||||
this.setState({
|
||||
isLoadingMore: false,
|
||||
items: [...this.state.items, ...res.data.events],
|
||||
items: [...this.state.items, ...this.filterSuperfluousEvents(res.data.events)],
|
||||
currentPage: currentPage + 1,
|
||||
hasMore: res.data.events.length === 0 ? false : true
|
||||
});
|
||||
|
@@ -83,6 +83,9 @@ class ActivitiesView(APIView):
|
||||
elif e.op_type == 'rename' and e.obj_type in ['dir', 'file']:
|
||||
d['old_path'] = e.old_path
|
||||
d['old_name'] = os.path.basename(e.old_path)
|
||||
elif e.obj_type == 'review':
|
||||
d['old_path'] = e.old_path
|
||||
d['review_id'] = e.review_id
|
||||
|
||||
events_list.append(d)
|
||||
|
||||
|
@@ -20,6 +20,7 @@ from seahub.views import check_folder_permission
|
||||
from seahub.drafts.models import Draft, DraftReview, DraftReviewExist, \
|
||||
DraftFileConflict, ReviewReviewer, OriginalFileConflict
|
||||
from seahub.drafts.signals import update_review_successful
|
||||
from seahub.drafts.utils import send_review_status_msg
|
||||
|
||||
|
||||
class DraftReviewsView(APIView):
|
||||
@@ -82,6 +83,9 @@ class DraftReviewsView(APIView):
|
||||
except (DraftReviewExist):
|
||||
return api_error(status.HTTP_409_CONFLICT, 'Draft review already exists.')
|
||||
|
||||
# send review status change message
|
||||
send_review_status_msg(request, d_r)
|
||||
|
||||
return Response(d_r.to_dict())
|
||||
|
||||
|
||||
@@ -154,6 +158,9 @@ class DraftReviewView(APIView):
|
||||
update_review_successful.send(sender=None, from_user=username,
|
||||
to_user=r.creator, review_id=r.id, status=st)
|
||||
|
||||
# send review status change message
|
||||
send_review_status_msg(request, r)
|
||||
|
||||
result = r.to_dict()
|
||||
|
||||
return Response(result)
|
||||
|
@@ -13,6 +13,7 @@ from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.api2.utils import api_error
|
||||
from seahub.views import check_folder_permission
|
||||
from seahub.drafts.utils import send_review_status_msg
|
||||
from seahub.drafts.models import Draft, DraftReview, ReviewReviewer, \
|
||||
DraftFileExist, DraftReviewExist
|
||||
|
||||
@@ -57,6 +58,9 @@ class FileReviewView(APIView):
|
||||
except (DraftReviewExist):
|
||||
return api_error(status.HTTP_409_CONFLICT, 'Draft review already exists.')
|
||||
|
||||
# send review status change message
|
||||
send_review_status_msg(request, r)
|
||||
|
||||
# new reviewer
|
||||
if username != d.username:
|
||||
ReviewReviewer.objects.add(username, r)
|
||||
|
@@ -1,12 +1,18 @@
|
||||
import hashlib
|
||||
import os
|
||||
import logging
|
||||
import posixpath
|
||||
|
||||
from seaserv import seafile_api
|
||||
from seaserv import send_message
|
||||
|
||||
from seahub.utils import normalize_file_path, check_filename_with_rename
|
||||
from seahub.tags.models import FileUUIDMap
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_user_draft_repo(username, org_id=-1):
|
||||
repo_name = 'Drafts'
|
||||
if org_id > 0:
|
||||
@@ -109,3 +115,38 @@ def get_file_draft_and_related_review(repo_id, file_path, is_draft=False, has_dr
|
||||
review['draft_file_path'] = d.draft_file_path
|
||||
|
||||
return review
|
||||
|
||||
|
||||
def send_review_status_msg(request, review):
|
||||
"""
|
||||
send review status change to seafevents
|
||||
"""
|
||||
status = review.status.lower()
|
||||
if status not in ['open', 'finished', 'closed']:
|
||||
logger.warn('Invalid status in review status msg: %s' % status)
|
||||
return
|
||||
|
||||
repo_id = review.origin_repo_id
|
||||
op_user = review.creator
|
||||
review_id = review.id
|
||||
draft_flag = os.path.splitext(os.path.basename(review.draft_file_path))[0][-7:]
|
||||
if draft_flag == '(draft)':
|
||||
old_path = review.draft_file_path
|
||||
if status == 'finished':
|
||||
publish_path = posixpath.join(review.origin_file_uuid.parent_path, review.origin_file_uuid.filename)
|
||||
else:
|
||||
publish_path = None
|
||||
else:
|
||||
old_path = posixpath.join(review.origin_file_uuid.parent_path, review.origin_file_uuid.filename)
|
||||
publish_path = review.draft_file_path if status == 'finished' else None
|
||||
path = publish_path if publish_path else old_path
|
||||
|
||||
username = request.user.username
|
||||
|
||||
msg = '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s' % (status, repo_id, op_user, "review", path, review_id, old_path, username)
|
||||
msg_utf8 = msg.encode('utf-8')
|
||||
|
||||
try:
|
||||
send_message('seahub.review', msg_utf8)
|
||||
except Exception as e:
|
||||
logger.error("Error when sending %s message: %s" % (status, str(e)))
|
||||
|
Reference in New Issue
Block a user