##// END OF EJS Templates
drafts: sidebar functionality
milka -
r4562:20bc1204 default
parent child Browse files
Show More
@@ -355,6 +355,11 b' def includeme(config):'
355 355 pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/todos',
356 356 repo_route=True)
357 357
358 config.add_route(
359 name='pullrequest_drafts',
360 pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/drafts',
361 repo_route=True)
362
358 363 # Artifacts, (EE feature)
359 364 config.add_route(
360 365 name='repo_artifacts_list',
@@ -501,6 +501,11 b' class RepoPullRequestsView(RepoAppView, '
501 501 c.resolved_comments = CommentsModel() \
502 502 .get_pull_request_resolved_todos(pull_request_latest)
503 503
504 # Drafts
505 c.draft_comments = CommentsModel().get_pull_request_drafts(
506 self._rhodecode_db_user.user_id,
507 pull_request_latest)
508
504 509 # if we use version, then do not show later comments
505 510 # than current version
506 511 display_inline_comments = collections.defaultdict(
@@ -1071,6 +1076,48 b' class RepoPullRequestsView(RepoAppView, '
1071 1076 @NotAnonymous()
1072 1077 @HasRepoPermissionAnyDecorator(
1073 1078 'repository.read', 'repository.write', 'repository.admin')
1079 @view_config(
1080 route_name='pullrequest_drafts', request_method='POST',
1081 renderer='string_html', xhr=True)
1082 def pullrequest_drafts(self):
1083 self.load_default_context()
1084
1085 pull_request = PullRequest.get_or_404(
1086 self.request.matchdict['pull_request_id'])
1087 pull_request_id = pull_request.pull_request_id
1088 version = self.request.GET.get('version')
1089
1090 _render = self.request.get_partial_renderer(
1091 'rhodecode:templates/base/sidebar.mako')
1092 c = _render.get_call_context()
1093
1094 (pull_request_latest,
1095 pull_request_at_ver,
1096 pull_request_display_obj,
1097 at_version) = PullRequestModel().get_pr_version(
1098 pull_request_id, version=version)
1099 versions = pull_request_display_obj.versions()
1100 latest_ver = PullRequest.get_pr_display_object(pull_request_latest, pull_request_latest)
1101 c.versions = versions + [latest_ver]
1102
1103 c.at_version = at_version
1104 c.at_version_num = (at_version
1105 if at_version and at_version != PullRequest.LATEST_VER
1106 else None)
1107
1108 c.draft_comments = CommentsModel() \
1109 .get_pull_request_drafts(self._rhodecode_db_user.user_id, pull_request)
1110
1111 all_comments = c.draft_comments
1112
1113 existing_ids = self.get_comment_ids(self.request.POST)
1114 return _render('comments_table', all_comments, len(all_comments),
1115 existing_ids=existing_ids, draft_comments=True)
1116
1117 @LoginRequired()
1118 @NotAnonymous()
1119 @HasRepoPermissionAnyDecorator(
1120 'repository.read', 'repository.write', 'repository.admin')
1074 1121 @CSRFRequired()
1075 1122 @view_config(
1076 1123 route_name='pullrequest_create', request_method='POST',
@@ -37,7 +37,7 b' from rhodecode.lib.exceptions import Com'
37 37 from rhodecode.lib.utils2 import extract_mentioned_users, safe_str, safe_int
38 38 from rhodecode.model import BaseModel
39 39 from rhodecode.model.db import (
40 false,
40 false, true,
41 41 ChangesetComment,
42 42 User,
43 43 Notification,
@@ -201,6 +201,13 b' class CommentsModel(BaseModel):'
201 201
202 202 return todos
203 203
204 def get_pull_request_drafts(self, user_id, pull_request):
205 drafts = Session().query(ChangesetComment) \
206 .filter(ChangesetComment.pull_request == pull_request) \
207 .filter(ChangesetComment.user_id == user_id) \
208 .filter(ChangesetComment.draft == true())
209 return drafts.all()
210
204 211 def get_commit_unresolved_todos(self, commit_id, show_outdated=True, include_drafts=True):
205 212
206 213 todos = Session().query(ChangesetComment) \
@@ -248,6 +248,7 b' function registerRCRoutes() {'
248 248 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/delete', ['repo_name', 'pull_request_id', 'comment_id']);
249 249 pyroutes.register('pullrequest_comments', '/%(repo_name)s/pull-request/%(pull_request_id)s/comments', ['repo_name', 'pull_request_id']);
250 250 pyroutes.register('pullrequest_todos', '/%(repo_name)s/pull-request/%(pull_request_id)s/todos', ['repo_name', 'pull_request_id']);
251 pyroutes.register('pullrequest_drafts', '/%(repo_name)s/pull-request/%(pull_request_id)s/drafts', ['repo_name', 'pull_request_id']);
251 252 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
252 253 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
253 254 pyroutes.register('edit_repo_advanced_archive', '/%(repo_name)s/settings/advanced/archive', ['repo_name']);
@@ -730,6 +730,10 b' var CommentsController = function() {'
730 730 // if we have this handler, run it, and refresh all comments boxes
731 731 refreshAllComments()
732 732 }
733 else if (window.refreshDraftComments !== undefined && isDraft) {
734 // if we have this handler, run it, and refresh all comments boxes
735 refreshDraftComments();
736 }
733 737 return false;
734 738 };
735 739
@@ -796,7 +800,7 b' var CommentsController = function() {'
796 800
797 801 }
798 802
799 this.finalizeDrafts = function(commentIds) {
803 this.finalizeDrafts = function(commentIds, callback) {
800 804
801 805 SwalNoAnimation.fire({
802 806 title: _ngettext('Submit {0} draft comment.', 'Submit {0} draft comments.', commentIds.length).format(commentIds.length),
@@ -806,6 +810,9 b' var CommentsController = function() {'
806 810
807 811 }).then(function(result) {
808 812 if (result.value) {
813 if (callback !== undefined) {
814 callback(result)
815 }
809 816 self._finalizeDrafts(commentIds);
810 817 }
811 818 })
@@ -1220,6 +1227,10 b' var CommentsController = function() {'
1220 1227 // if we have this handler, run it, and refresh all comments boxes
1221 1228 refreshAllComments()
1222 1229 }
1230 else if (window.refreshDraftComments !== undefined && isDraft) {
1231 // if we have this handler, run it, and refresh all comments boxes
1232 refreshDraftComments();
1233 }
1223 1234
1224 1235 commentForm.setActionButtonsDisabled(false);
1225 1236
@@ -1415,6 +1426,10 b' var CommentsController = function() {'
1415 1426 // if we have this handler, run it, and refresh all comments boxes
1416 1427 refreshAllComments()
1417 1428 }
1429 else if (window.refreshDraftComments !== undefined && isDraft) {
1430 // if we have this handler, run it, and refresh all comments boxes
1431 refreshDraftComments();
1432 }
1418 1433
1419 1434 commentForm.setActionButtonsDisabled(false);
1420 1435
@@ -1036,6 +1036,30 b' window.ReviewerPresenceController = func'
1036 1036
1037 1037 };
1038 1038
1039 window.refreshCommentsSuccess = function(targetNode, counterNode, extraCallback) {
1040 var $targetElem = targetNode;
1041 var $counterElem = counterNode;
1042
1043 return function (data) {
1044 var newCount = $(data).data('counter');
1045 if (newCount !== undefined) {
1046 var callback = function () {
1047 $counterElem.animate({'opacity': 1.00}, 200)
1048 $counterElem.html(newCount);
1049 };
1050 $counterElem.animate({'opacity': 0.15}, 200, callback);
1051 }
1052
1053 $targetElem.css('opacity', 1);
1054 $targetElem.html(data);
1055 tooltipActivate();
1056
1057 if (extraCallback !== undefined) {
1058 extraCallback(data)
1059 }
1060 }
1061 }
1062
1039 1063 window.refreshComments = function (version) {
1040 1064 version = version || templateContext.pull_request_data.pull_request_version || '';
1041 1065
@@ -1060,23 +1084,8 b' window.refreshComments = function (versi'
1060 1084
1061 1085 var $targetElem = $('.comments-content-table');
1062 1086 $targetElem.css('opacity', 0.3);
1063
1064 var success = function (data) {
1065 var $counterElem = $('#comments-count');
1066 var newCount = $(data).data('counter');
1067 if (newCount !== undefined) {
1068 var callback = function () {
1069 $counterElem.animate({'opacity': 1.00}, 200)
1070 $counterElem.html(newCount);
1071 };
1072 $counterElem.animate({'opacity': 0.15}, 200, callback);
1073 }
1074
1075 $targetElem.css('opacity', 1);
1076 $targetElem.html(data);
1077 tooltipActivate();
1078 }
1079
1087 var $counterElem = $('#comments-count');
1088 var success = refreshCommentsSuccess($targetElem, $counterElem);
1080 1089 ajaxPOST(loadUrl, data, success, null, {})
1081 1090
1082 1091 }
@@ -1104,27 +1113,46 b' window.refreshTODOs = function (version)'
1104 1113 var data = {"comments": currentIDs};
1105 1114 var $targetElem = $('.todos-content-table');
1106 1115 $targetElem.css('opacity', 0.3);
1107
1108 var success = function (data) {
1109 var $counterElem = $('#todos-count')
1110 var newCount = $(data).data('counter');
1111 if (newCount !== undefined) {
1112 var callback = function () {
1113 $counterElem.animate({'opacity': 1.00}, 200)
1114 $counterElem.html(newCount);
1115 };
1116 $counterElem.animate({'opacity': 0.15}, 200, callback);
1117 }
1118
1119 $targetElem.css('opacity', 1);
1120 $targetElem.html(data);
1121 tooltipActivate();
1122 }
1116 var $counterElem = $('#todos-count');
1117 var success = refreshCommentsSuccess($targetElem, $counterElem);
1123 1118
1124 1119 ajaxPOST(loadUrl, data, success, null, {})
1125 1120
1126 1121 }
1127 1122
1123 window.refreshDraftComments = function () {
1124
1125 // Pull request case
1126 if (templateContext.pull_request_data.pull_request_id !== null) {
1127 var params = {
1128 'pull_request_id': templateContext.pull_request_data.pull_request_id,
1129 'repo_name': templateContext.repo_name,
1130 };
1131 var loadUrl = pyroutes.url('pullrequest_drafts', params);
1132 } // commit case
1133 else {
1134 return
1135 }
1136
1137 var data = {};
1138
1139 var $targetElem = $('.drafts-content-table');
1140 $targetElem.css('opacity', 0.3);
1141 var $counterElem = $('#drafts-count');
1142 var extraCallback = function(data) {
1143 if ($(data).data('counter') == 0){
1144 $('#draftsTable').hide();
1145 } else {
1146 $('#draftsTable').show();
1147 }
1148 // uncheck on load the select all checkbox
1149 $('[name=select_all_drafts]').prop('checked', 0);
1150 }
1151 var success = refreshCommentsSuccess($targetElem, $counterElem, extraCallback);
1152
1153 ajaxPOST(loadUrl, data, success, null, {})
1154 };
1155
1128 1156 window.refreshAllComments = function (version) {
1129 1157 version = version || templateContext.pull_request_data.pull_request_version || '';
1130 1158
@@ -1132,10 +1160,6 b' window.refreshAllComments = function (ve'
1132 1160 refreshTODOs(version);
1133 1161 };
1134 1162
1135 window.refreshDraftComments = function () {
1136 alert('TODO: refresh Draft Comments needs implementation')
1137 };
1138
1139 1163 window.sidebarComment = function (commentId) {
1140 1164 var jsonData = $('#commentHovercard{0}'.format(commentId)).data('commentJsonB64');
1141 1165 if (!jsonData) {
@@ -4,7 +4,7 b''
4 4 ## ${sidebar.comments_table()}
5 5 <%namespace name="base" file="/base/base.mako"/>
6 6
7 <%def name="comments_table(comments, counter_num, todo_comments=False, existing_ids=None, is_pr=True)">
7 <%def name="comments_table(comments, counter_num, todo_comments=False, draft_comments=False, existing_ids=None, is_pr=True)">
8 8 <%
9 9 if todo_comments:
10 10 cls_ = 'todos-content-table'
@@ -15,10 +15,13 b''
15 15 # own comments first
16 16 user_id = 0
17 17 return '{}'.format(str(entry.comment_id).zfill(10000))
18 elif draft_comments:
19 cls_ = 'drafts-content-table'
20 def sorter(entry):
21 return '{}'.format(str(entry.comment_id).zfill(10000))
18 22 else:
19 23 cls_ = 'comments-content-table'
20 24 def sorter(entry):
21 user_id = entry.author.user_id
22 25 return '{}'.format(str(entry.comment_id).zfill(10000))
23 26
24 27 existing_ids = existing_ids or []
@@ -32,7 +35,7 b''
32 35 display = ''
33 36 _cls = ''
34 37 ## Extra precaution to not show drafts in the sidebar for todo/comments
35 if comment_obj.draft:
38 if comment_obj.draft and not draft_comments:
36 39 continue
37 40 %>
38 41
@@ -87,6 +90,11 b''
87 90 % endif
88 91
89 92 <tr class="${_cls}" style="display: ${display};" data-sidebar-comment-id="${comment_obj.comment_id}">
93 % if draft_comments:
94 <td style="width: 15px;">
95 ${h.checkbox('submit_draft', id=None, value=comment_obj.comment_id)}
96 </td>
97 % endif
90 98 <td class="td-todo-number">
91 99 <%
92 100 version_info = ''
@@ -552,28 +552,35 b''
552 552
553 553 ## Drafts
554 554 % if c.rhodecode_edition_id == 'EE':
555 <div class="sidebar-element clear-both">
556 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="${_('Drafts')}">
555 <div id="draftsTable" class="sidebar-element clear-both" style="display: ${'block' if c.draft_comments else 'none'}">
556 <div class="tooltip right-sidebar-collapsed-state" style="display: none;" onclick="toggleSidebar(); return false" title="${_('Drafts')}">
557 557 <i class="icon-comment icon-draft"></i>
558 <span id="comments-count">${0}</span>
558 <span id="drafts-count">${len(c.draft_comments)}</span>
559 559 </div>
560 560
561 561 <div class="right-sidebar-expanded-state pr-details-title">
562 <span class="sidebar-heading noselect">
562 <span style="padding-left: 2px">
563 <input name="select_all_drafts" type="checkbox" onclick="$('[name=submit_draft]').prop('checked', !$('[name=submit_draft]').prop('checked'))">
564 </span>
565 <span class="sidebar-heading noselect" onclick="refreshDraftComments(); return false">
563 566 <i class="icon-comment icon-draft"></i>
564 567 ${_('Drafts')}
565 568 </span>
569 <span class="block-right action_button last-item" onclick="submitDrafts(event)">${_('Submit')}</span>
566 570 </div>
567 571
568 572 <div id="drafts" class="right-sidebar-expanded-state pr-details-content reviewers">
569 ## members redering block
570
571
572 ???
573
574
575 ## end members redering block
576
573 % if c.draft_comments:
574 ${sidebar.comments_table(c.draft_comments, len(c.draft_comments), draft_comments=True)}
575 % else:
576 <table class="drafts-content-table">
577 <tr>
578 <td>
579 ${_('No TODOs yet')}
580 </td>
581 </tr>
582 </table>
583 % endif
577 584 </div>
578 585
579 586 </div>
@@ -705,7 +712,7 b''
705 712 % endif
706 713
707 714 ## TODOs
708 <div class="sidebar-element clear-both">
715 <div id="todosTable" class="sidebar-element clear-both">
709 716 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="TODOs">
710 717 <i class="icon-flag-filled"></i>
711 718 <span id="todos-count">${len(c.unresolved_comments)}</span>
@@ -739,7 +746,7 b''
739 746 % if c.unresolved_comments + c.resolved_comments:
740 747 ${sidebar.comments_table(c.unresolved_comments + c.resolved_comments, len(c.unresolved_comments), todo_comments=True)}
741 748 % else:
742 <table>
749 <table class="todos-content-table">
743 750 <tr>
744 751 <td>
745 752 ${_('No TODOs yet')}
@@ -752,7 +759,7 b''
752 759 </div>
753 760
754 761 ## COMMENTS
755 <div class="sidebar-element clear-both">
762 <div id="commentsTable" class="sidebar-element clear-both">
756 763 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="${_('Comments')}">
757 764 <i class="icon-comment" style="color: #949494"></i>
758 765 <span id="comments-count">${len(c.inline_comments_flat+c.comments)}</span>
@@ -790,7 +797,7 b''
790 797 % if c.inline_comments_flat + c.comments:
791 798 ${sidebar.comments_table(c.inline_comments_flat + c.comments, len(c.inline_comments_flat+c.comments))}
792 799 % else:
793 <table>
800 <table class="comments-content-table">
794 801 <tr>
795 802 <td>
796 803 ${_('No Comments yet')}
@@ -919,6 +926,23 b' window.setObserversData = ${c.pull_reque'
919 926 );
920 927 };
921 928
929 window.submitDrafts = function (event) {
930 var target = $(event.currentTarget);
931 var callback = function (result) {
932 target.removeAttr('onclick').html('saving...');
933 }
934 var draftIds = [];
935 $.each($('[name=submit_draft]:checked'), function (idx, val) {
936 draftIds.push(parseInt($(val).val()));
937 })
938 if (draftIds.length > 0) {
939 Rhodecode.comments.finalizeDrafts(draftIds, callback);
940 }
941 else {
942
943 }
944 }
945
922 946 window.closePullRequest = function (status) {
923 947 if (!confirm(_gettext('Are you sure to close this pull request without merging?'))) {
924 948 return false;
@@ -1026,7 +1050,6 b' window.setObserversData = ${c.pull_reque'
1026 1050 new ReviewerPresenceController(channel)
1027 1051 // register globally so inject comment logic can re-use it.
1028 1052 window.commentsController = commentsController;
1029
1030 1053 })
1031 1054 </script>
1032 1055
General Comments 0
You need to be logged in to leave comments. Login now