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 (
|
return (
|
||||||
<ul className="dropdown-menu" style={style}>
|
<ul className="dropdown-menu" style={style}>
|
||||||
<li className="dropdown-item" onClick={this.props.onDeleteHandler}>{gettext('Delete')}</li>
|
<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>
|
<li className="dropdown-item" onClick={this.props.onReviewHandler}>{gettext('Ask for review')}</li>
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
|
@@ -82,15 +82,42 @@ class TableBody extends Component {
|
|||||||
details = <td>{libLink}</td>;
|
details = <td>{libLink}</td>;
|
||||||
break;
|
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') {
|
} else if (item.obj_type == 'file') {
|
||||||
let fileURL = `${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`;
|
let fileURL = `${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`;
|
||||||
let fileLink = <a href={fileURL}>{item.name}</a>;
|
let fileLink = <a href={fileURL}>{item.name}</a>;
|
||||||
switch(item.op_type) {
|
switch(item.op_type) {
|
||||||
case 'create':
|
case 'create':
|
||||||
|
if (item.name.endsWith("(draft).md")) {
|
||||||
|
op = gettext('Created draft');
|
||||||
|
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||||
|
break;
|
||||||
|
}
|
||||||
op = gettext('Created file');
|
op = gettext('Created file');
|
||||||
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
|
if (item.name.endsWith("(draft).md")) {
|
||||||
|
op = gettext('Deleted draft');
|
||||||
|
details = <td>{item.name}<br />{smallLibLink}</td>;
|
||||||
|
break;
|
||||||
|
}
|
||||||
op = gettext('Deleted file');
|
op = gettext('Deleted file');
|
||||||
details = <td>{item.name}<br />{smallLibLink}</td>;
|
details = <td>{item.name}<br />{smallLibLink}</td>;
|
||||||
break;
|
break;
|
||||||
@@ -108,6 +135,11 @@ class TableBody extends Component {
|
|||||||
details = <td>{item.old_path} => {filePathLink}<br />{smallLibLink}</td>;
|
details = <td>{item.old_path} => {filePathLink}<br />{smallLibLink}</td>;
|
||||||
break;
|
break;
|
||||||
case 'edit': // update
|
case 'edit': // update
|
||||||
|
if (item.name.endsWith("(draft).md")) {
|
||||||
|
op = gettext('Updated draft');
|
||||||
|
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||||
|
break;
|
||||||
|
}
|
||||||
op = gettext('Updated file');
|
op = gettext('Updated file');
|
||||||
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
details = <td>{fileLink}<br />{smallLibLink}</td>;
|
||||||
break;
|
break;
|
||||||
@@ -177,6 +209,8 @@ class FilesActivities extends Component {
|
|||||||
items: [],
|
items: [],
|
||||||
};
|
};
|
||||||
this.avatarSize = 72;
|
this.avatarSize = 72;
|
||||||
|
this.curPathList = [];
|
||||||
|
this.oldPathList = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -184,7 +218,7 @@ class FilesActivities extends Component {
|
|||||||
seafileAPI.listActivities(currentPage, this.avatarSize).then(res => {
|
seafileAPI.listActivities(currentPage, this.avatarSize).then(res => {
|
||||||
// {"events":[...]}
|
// {"events":[...]}
|
||||||
this.setState({
|
this.setState({
|
||||||
items: res.data.events,
|
items: this.filterSuperfluousEvents(res.data.events),
|
||||||
currentPage: currentPage + 1,
|
currentPage: currentPage + 1,
|
||||||
isFirstLoading: false,
|
isFirstLoading: false,
|
||||||
hasMore: true,
|
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() {
|
getMore() {
|
||||||
let currentPage = this.state.currentPage;
|
let currentPage = this.state.currentPage;
|
||||||
seafileAPI.listActivities(currentPage, this.avatarSize).then(res => {
|
seafileAPI.listActivities(currentPage, this.avatarSize).then(res => {
|
||||||
// {"events":[...]}
|
// {"events":[...]}
|
||||||
this.setState({
|
this.setState({
|
||||||
isLoadingMore: false,
|
isLoadingMore: false,
|
||||||
items: [...this.state.items, ...res.data.events],
|
items: [...this.state.items, ...this.filterSuperfluousEvents(res.data.events)],
|
||||||
currentPage: currentPage + 1,
|
currentPage: currentPage + 1,
|
||||||
hasMore: res.data.events.length === 0 ? false : true
|
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']:
|
elif e.op_type == 'rename' and e.obj_type in ['dir', 'file']:
|
||||||
d['old_path'] = e.old_path
|
d['old_path'] = e.old_path
|
||||||
d['old_name'] = os.path.basename(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)
|
events_list.append(d)
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ from seahub.views import check_folder_permission
|
|||||||
from seahub.drafts.models import Draft, DraftReview, DraftReviewExist, \
|
from seahub.drafts.models import Draft, DraftReview, DraftReviewExist, \
|
||||||
DraftFileConflict, ReviewReviewer, OriginalFileConflict
|
DraftFileConflict, ReviewReviewer, OriginalFileConflict
|
||||||
from seahub.drafts.signals import update_review_successful
|
from seahub.drafts.signals import update_review_successful
|
||||||
|
from seahub.drafts.utils import send_review_status_msg
|
||||||
|
|
||||||
|
|
||||||
class DraftReviewsView(APIView):
|
class DraftReviewsView(APIView):
|
||||||
@@ -82,6 +83,9 @@ class DraftReviewsView(APIView):
|
|||||||
except (DraftReviewExist):
|
except (DraftReviewExist):
|
||||||
return api_error(status.HTTP_409_CONFLICT, 'Draft review already exists.')
|
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())
|
return Response(d_r.to_dict())
|
||||||
|
|
||||||
|
|
||||||
@@ -154,6 +158,9 @@ class DraftReviewView(APIView):
|
|||||||
update_review_successful.send(sender=None, from_user=username,
|
update_review_successful.send(sender=None, from_user=username,
|
||||||
to_user=r.creator, review_id=r.id, status=st)
|
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()
|
result = r.to_dict()
|
||||||
|
|
||||||
return Response(result)
|
return Response(result)
|
||||||
|
@@ -13,6 +13,7 @@ from seahub.api2.authentication import TokenAuthentication
|
|||||||
from seahub.api2.throttling import UserRateThrottle
|
from seahub.api2.throttling import UserRateThrottle
|
||||||
from seahub.api2.utils import api_error
|
from seahub.api2.utils import api_error
|
||||||
from seahub.views import check_folder_permission
|
from seahub.views import check_folder_permission
|
||||||
|
from seahub.drafts.utils import send_review_status_msg
|
||||||
from seahub.drafts.models import Draft, DraftReview, ReviewReviewer, \
|
from seahub.drafts.models import Draft, DraftReview, ReviewReviewer, \
|
||||||
DraftFileExist, DraftReviewExist
|
DraftFileExist, DraftReviewExist
|
||||||
|
|
||||||
@@ -57,6 +58,9 @@ class FileReviewView(APIView):
|
|||||||
except (DraftReviewExist):
|
except (DraftReviewExist):
|
||||||
return api_error(status.HTTP_409_CONFLICT, 'Draft review already exists.')
|
return api_error(status.HTTP_409_CONFLICT, 'Draft review already exists.')
|
||||||
|
|
||||||
|
# send review status change message
|
||||||
|
send_review_status_msg(request, r)
|
||||||
|
|
||||||
# new reviewer
|
# new reviewer
|
||||||
if username != d.username:
|
if username != d.username:
|
||||||
ReviewReviewer.objects.add(username, r)
|
ReviewReviewer.objects.add(username, r)
|
||||||
|
@@ -1,12 +1,18 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
import posixpath
|
||||||
|
|
||||||
from seaserv import seafile_api
|
from seaserv import seafile_api
|
||||||
|
from seaserv import send_message
|
||||||
|
|
||||||
from seahub.utils import normalize_file_path, check_filename_with_rename
|
from seahub.utils import normalize_file_path, check_filename_with_rename
|
||||||
from seahub.tags.models import FileUUIDMap
|
from seahub.tags.models import FileUUIDMap
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def create_user_draft_repo(username, org_id=-1):
|
def create_user_draft_repo(username, org_id=-1):
|
||||||
repo_name = 'Drafts'
|
repo_name = 'Drafts'
|
||||||
if org_id > 0:
|
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
|
review['draft_file_path'] = d.draft_file_path
|
||||||
|
|
||||||
return review
|
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