##// END OF EJS Templates
Added editing of pull-request reviewers.
marcink -
r2614:3f50a5e8 beta
parent child Browse files
Show More
@@ -450,6 +450,11 b' def make_map(config):'
450 controller='pullrequests',
450 controller='pullrequests',
451 action='show', conditions=dict(function=check_repo,
451 action='show', conditions=dict(function=check_repo,
452 method=["GET"]))
452 method=["GET"]))
453 rmap.connect('pullrequest_update',
454 '/{repo_name:.*}/pull-request/{pull_request_id}',
455 controller='pullrequests',
456 action='update', conditions=dict(function=check_repo,
457 method=["PUT"]))
453
458
454 rmap.connect('pullrequest_show_all',
459 rmap.connect('pullrequest_show_all',
455 '/{repo_name:.*}/pull-request',
460 '/{repo_name:.*}/pull-request',
@@ -167,6 +167,19 b' class PullrequestsController(BaseRepoCon'
167 return redirect(url('pullrequest_show', repo_name=other_repo,
167 return redirect(url('pullrequest_show', repo_name=other_repo,
168 pull_request_id=pull_request.pull_request_id))
168 pull_request_id=pull_request.pull_request_id))
169
169
170 @NotAnonymous()
171 @jsonify
172 def update(self, repo_name, pull_request_id):
173 pull_request = PullRequest.get_or_404(pull_request_id)
174 if pull_request.is_closed():
175 raise HTTPForbidden()
176
177 reviewers_ids = map(int, filter(lambda v: v not in [None, ''],
178 request.POST.get('reviewers_ids', '').split(',')))
179 PullRequestModel().update_reviewers(pull_request_id, reviewers_ids)
180 Session.commit()
181 return True
182
170 def _load_compare_data(self, pull_request, enable_comments=True):
183 def _load_compare_data(self, pull_request, enable_comments=True):
171 """
184 """
172 Load context data needed for generating compare diff
185 Load context data needed for generating compare diff
@@ -337,4 +350,4 b' class PullrequestsController(BaseRepoCon'
337 Session().commit()
350 Session().commit()
338 return True
351 return True
339 else:
352 else:
340 raise HTTPForbidden() No newline at end of file
353 raise HTTPForbidden()
@@ -97,6 +97,34 b' class PullRequestModel(BaseModel):'
97
97
98 return new
98 return new
99
99
100 def update_reviewers(self, pull_request, reviewers_ids):
101 reviewers_ids = set(reviewers_ids)
102 pull_request = self.__get_pull_request(pull_request)
103 current_reviewers = PullRequestReviewers.query()\
104 .filter(PullRequestReviewers.pull_request==
105 pull_request)\
106 .all()
107 current_reviewers_ids = set([x.user.user_id for x in current_reviewers])
108
109 to_add = reviewers_ids.difference(current_reviewers_ids)
110 to_remove = current_reviewers_ids.difference(reviewers_ids)
111
112 log.debug("Adding %s reviewers" % to_add)
113 log.debug("Removing %s reviewers" % to_remove)
114
115 for uid in to_add:
116 _usr = self._get_user(uid)
117 reviewer = PullRequestReviewers(_usr, pull_request)
118 self.sa.add(reviewer)
119
120 for uid in to_remove:
121 reviewer = PullRequestReviewers.query()\
122 .filter(PullRequestReviewers.user_id==uid,
123 PullRequestReviewers.pull_request==pull_request)\
124 .scalar()
125 if reviewer:
126 self.sa.delete(reviewer)
127
100 def close_pull_request(self, pull_request):
128 def close_pull_request(self, pull_request):
101 pull_request = self.__get_pull_request(pull_request)
129 pull_request = self.__get_pull_request(pull_request)
102 pull_request.status = PullRequest.STATUS_CLOSED
130 pull_request.status = PullRequest.STATUS_CLOSED
@@ -501,6 +501,15 b' var deleteComment = function(comment_id)'
501 ajaxPOST(url,postData,success);
501 ajaxPOST(url,postData,success);
502 }
502 }
503
503
504 var updateReviewers = function(reviewers_ids){
505 var url = AJAX_UPDATE_PULLREQUEST;
506 var postData = {'_method':'put',
507 'reviewers_ids': reviewers_ids};
508 var success = function(o){
509 window.location.reload();
510 }
511 ajaxPOST(url,postData,success);
512 }
504
513
505 var createInlineAddButton = function(tr){
514 var createInlineAddButton = function(tr){
506
515
@@ -35,32 +35,9 b''
35 <div>${_('Created on')}: ${h.fmt_date(c.pull_request.created_on)}</div>
35 <div>${_('Created on')}: ${h.fmt_date(c.pull_request.created_on)}</div>
36 </div>
36 </div>
37
37
38 ## REVIEWERS
39 <div>
38 <div>
40 <div class="table" style="float:right;width:46%;clear:none">
41 <div id="body" class="diffblock">
42 <div style="white-space:pre-wrap;padding:5px">${_('Pull request reviewers')}</div>
43 </div>
44 <div style="border: 1px solid #CCC">
45 <div class="group_members_wrap">
46 <ul class="group_members">
47 %for user,status in c.pull_request_reviewers:
48 <li>
49 <div class="group_member">
50 <div style="float:left;padding:3px" class="tooltip" title="${h.tooltip(h.changeset_status_lbl(status[0][1].status if status else 'not_reviewed'))}">
51 <img src="${h.url(str('/images/icons/flag_status_%s.png' % (status[0][1].status if status else 'not_reviewed')))}"/>
52 </div>
53 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(user.email,20)}"/> </div>
54 <div style="float:left">${user.username}</div>
55 </div>
56 </li>
57 %endfor
58 </ul>
59 </div>
60 </div>
61 </div>
62 ##DIFF
39 ##DIFF
63 <div class="table" style="float:left;width:46%;clear:none">
40 <div class="table" style="float:left;clear:none">
64 <div id="body" class="diffblock">
41 <div id="body" class="diffblock">
65 <div style="white-space:pre-wrap;padding:5px">${_('Compare view')}</div>
42 <div style="white-space:pre-wrap;padding:5px">${_('Compare view')}</div>
66 </div>
43 </div>
@@ -81,12 +58,51 b''
81 </div>
58 </div>
82 </div>
59 </div>
83 </div>
60 </div>
61 ## REVIEWERS
62 <div style="float:left; border-left:1px dashed #eee">
63 <h4>${_('Pull request reviewers')}</h4>
64 <div id="reviewers" style="padding:0px 0px 0px 15px">
65 ## members goes here !
66 <div class="group_members_wrap">
67 <ul id="review_members" class="group_members">
68 %for member,status in c.pull_request_reviewers:
69 <li id="reviewer_${member.user_id}">
70 <div class="reviewers_member">
71 <div style="float:left;padding:0px 3px 0px 0px" class="tooltip" title="${h.tooltip(h.changeset_status_lbl(status[0][1].status if status else 'not_reviewed'))}">
72 <img src="${h.url(str('/images/icons/flag_status_%s.png' % (status[0][1].status if status else 'not_reviewed')))}"/>
73 </div>
74 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(member.email,14)}"/> </div>
75 <div style="float:left">${member.full_name} (${_('owner')})</div>
76 <input type="hidden" value="${member.user_id}" name="review_members" />
77 %if not c.pull_request.is_closed():
78 <span class="delete_icon action_button" onclick="removeReviewer(${member.user_id})"></span>
79 %endif
80 </div>
81 </li>
82 %endfor
83 </ul>
84 </div>
85 %if not c.pull_request.is_closed():
86 <div class='ac'>
87 <div class="reviewer_ac">
88 ${h.text('user', class_='yui-ac-input')}
89 <span class="help-block">${_('Add reviewer to this pull request.')}</span>
90 <div id="reviewers_container"></div>
91 </div>
92 <div style="padding:0px 10px">
93 <span id="update_pull_request" class="ui-btn xsmall">${_('save')}</span>
94 </div>
95 </div>
96 %endif
97 </div>
98 </div>
84 </div>
99 </div>
85 <script>
100 <script>
86 var _USERS_AC_DATA = ${c.users_array|n};
101 var _USERS_AC_DATA = ${c.users_array|n};
87 var _GROUPS_AC_DATA = ${c.users_groups_array|n};
102 var _GROUPS_AC_DATA = ${c.users_groups_array|n};
88 AJAX_COMMENT_URL = "${url('pullrequest_comment',repo_name=c.repo_name,pull_request_id=c.pull_request.pull_request_id)}";
103 AJAX_COMMENT_URL = "${url('pullrequest_comment',repo_name=c.repo_name,pull_request_id=c.pull_request.pull_request_id)}";
89 AJAX_COMMENT_DELETE_URL = "${url('pullrequest_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
104 AJAX_COMMENT_DELETE_URL = "${url('pullrequest_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
105 AJAX_UPDATE_PULLREQUEST = "${url('pullrequest_update',repo_name=c.repo_name,pull_request_id=c.pull_request.pull_request_id)}"
90 </script>
106 </script>
91
107
92 ## diff block
108 ## diff block
@@ -112,6 +128,7 b''
112
128
113 <script type="text/javascript">
129 <script type="text/javascript">
114 YUE.onDOMReady(function(){
130 YUE.onDOMReady(function(){
131 PullRequestAutoComplete('user', 'reviewers_container', _USERS_AC_DATA, _GROUPS_AC_DATA);
115
132
116 YUE.on(YUQ('.show-inline-comments'),'change',function(e){
133 YUE.on(YUQ('.show-inline-comments'),'change',function(e){
117 var show = 'none';
134 var show = 'none';
@@ -138,6 +155,17 b''
138 // inject comments into they proper positions
155 // inject comments into they proper positions
139 var file_comments = YUQ('.inline-comment-placeholder');
156 var file_comments = YUQ('.inline-comment-placeholder');
140 renderInlineComments(file_comments);
157 renderInlineComments(file_comments);
158
159 YUE.on(YUD.get('update_pull_request'),'click',function(e){
160
161 var reviewers_ids = [];
162 var ids = YUQ('#review_members input');
163 for(var i=0; i<ids.length;i++){
164 var id = ids[i].value
165 reviewers_ids.push(id);
166 }
167 updateReviewers(reviewers_ids);
168 })
141 })
169 })
142 </script>
170 </script>
143
171
General Comments 0
You need to be logged in to leave comments. Login now