##// END OF EJS Templates
pr-versioning: move version controller to dedicated PR file
marcink -
r1371:6a4c8be4 default
parent child Browse files
Show More
@@ -1,219 +1,342 b''
1 1 // # Copyright (C) 2010-2017 RhodeCode GmbH
2 2 // #
3 3 // # This program is free software: you can redistribute it and/or modify
4 4 // # it under the terms of the GNU Affero General Public License, version 3
5 5 // # (only), as published by the Free Software Foundation.
6 6 // #
7 7 // # This program is distributed in the hope that it will be useful,
8 8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 // # GNU General Public License for more details.
11 11 // #
12 12 // # You should have received a copy of the GNU Affero General Public License
13 13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 // #
15 15 // # This program is dual-licensed. If you wish to learn more about the
16 16 // # RhodeCode Enterprise Edition, including its added features, Support services,
17 17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18 18
19 19 /**
20 20 * Pull request reviewers
21 21 */
22 22 var removeReviewMember = function(reviewer_id, mark_delete){
23 23 var reviewer = $('#reviewer_{0}'.format(reviewer_id));
24 24
25 25 if(typeof(mark_delete) === undefined){
26 26 mark_delete = false;
27 27 }
28 28
29 29 if(mark_delete === true){
30 30 if (reviewer){
31 31 // mark as to-remove
32 32 var obj = $('#reviewer_{0}_name'.format(reviewer_id));
33 33 obj.addClass('to-delete');
34 34 // now delete the input
35 35 $('#reviewer_{0} input'.format(reviewer_id)).remove();
36 36 }
37 37 }
38 38 else{
39 39 $('#reviewer_{0}'.format(reviewer_id)).remove();
40 40 }
41 41 };
42 42
43 43 var addReviewMember = function(id, fname, lname, nname, gravatar_link, reasons) {
44 44 var members = $('#review_members').get(0);
45 45 var reasons_html = '';
46 46 var reasons_inputs = '';
47 47 var reasons = reasons || [];
48 48 if (reasons) {
49 49 for (var i = 0; i < reasons.length; i++) {
50 50 reasons_html += '<div class="reviewer_reason">- {0}</div>'.format(reasons[i]);
51 51 reasons_inputs += '<input type="hidden" name="reason" value="' + escapeHtml(reasons[i]) + '">';
52 52 }
53 53 }
54 54 var tmpl = '<li id="reviewer_{2}">'+
55 55 '<input type="hidden" name="__start__" value="reviewer:mapping">'+
56 56 '<div class="reviewer_status">'+
57 57 '<div class="flag_status not_reviewed pull-left reviewer_member_status"></div>'+
58 58 '</div>'+
59 59 '<img alt="gravatar" class="gravatar" src="{0}"/>'+
60 60 '<span class="reviewer_name user">{1}</span>'+
61 61 reasons_html +
62 62 '<input type="hidden" name="user_id" value="{2}">'+
63 63 '<input type="hidden" name="__start__" value="reasons:sequence">'+
64 64 '{3}'+
65 65 '<input type="hidden" name="__end__" value="reasons:sequence">'+
66 66 '<div class="reviewer_member_remove action_button" onclick="removeReviewMember({2})">' +
67 67 '<i class="icon-remove-sign"></i>'+
68 68 '</div>'+
69 69 '</div>'+
70 70 '<input type="hidden" name="__end__" value="reviewer:mapping">'+
71 71 '</li>' ;
72 72
73 73 var displayname = "{0} ({1} {2})".format(
74 74 nname, escapeHtml(fname), escapeHtml(lname));
75 75 var element = tmpl.format(gravatar_link,displayname,id,reasons_inputs);
76 76 // check if we don't have this ID already in
77 77 var ids = [];
78 78 var _els = $('#review_members li').toArray();
79 79 for (el in _els){
80 80 ids.push(_els[el].id)
81 81 }
82 82 if(ids.indexOf('reviewer_'+id) == -1){
83 83 // only add if it's not there
84 84 members.innerHTML += element;
85 85 }
86 86
87 87 };
88 88
89 89 var _updatePullRequest = function(repo_name, pull_request_id, postData) {
90 90 var url = pyroutes.url(
91 91 'pullrequest_update',
92 92 {"repo_name": repo_name, "pull_request_id": pull_request_id});
93 93 if (typeof postData === 'string' ) {
94 94 postData += '&csrf_token=' + CSRF_TOKEN;
95 95 } else {
96 96 postData.csrf_token = CSRF_TOKEN;
97 97 }
98 98 var success = function(o) {
99 99 window.location.reload();
100 100 };
101 101 ajaxPOST(url, postData, success);
102 102 };
103 103
104 104 var updateReviewers = function(reviewers_ids, repo_name, pull_request_id){
105 105 if (reviewers_ids === undefined){
106 106 var postData = '_method=put&' + $('#reviewers input').serialize();
107 107 _updatePullRequest(repo_name, pull_request_id, postData);
108 108 }
109 109 };
110 110
111 111 /**
112 112 * PULL REQUEST reject & close
113 113 */
114 114 var closePullRequest = function(repo_name, pull_request_id) {
115 115 var postData = {
116 116 '_method': 'put',
117 117 'close_pull_request': true};
118 118 _updatePullRequest(repo_name, pull_request_id, postData);
119 119 };
120 120
121 121 /**
122 122 * PULL REQUEST update commits
123 123 */
124 124 var updateCommits = function(repo_name, pull_request_id) {
125 125 var postData = {
126 126 '_method': 'put',
127 127 'update_commits': true};
128 128 _updatePullRequest(repo_name, pull_request_id, postData);
129 129 };
130 130
131 131
132 132 /**
133 133 * PULL REQUEST edit info
134 134 */
135 135 var editPullRequest = function(repo_name, pull_request_id, title, description) {
136 136 var url = pyroutes.url(
137 137 'pullrequest_update',
138 138 {"repo_name": repo_name, "pull_request_id": pull_request_id});
139 139
140 140 var postData = {
141 141 '_method': 'put',
142 142 'title': title,
143 143 'description': description,
144 144 'edit_pull_request': true,
145 145 'csrf_token': CSRF_TOKEN
146 146 };
147 147 var success = function(o) {
148 148 window.location.reload();
149 149 };
150 150 ajaxPOST(url, postData, success);
151 151 };
152 152
153 153 var initPullRequestsCodeMirror = function (textAreaId) {
154 154 var ta = $(textAreaId).get(0);
155 155 var initialHeight = '100px';
156 156
157 157 // default options
158 158 var codeMirrorOptions = {
159 159 mode: "text",
160 160 lineNumbers: false,
161 161 indentUnit: 4,
162 162 theme: 'rc-input'
163 163 };
164 164
165 165 var codeMirrorInstance = CodeMirror.fromTextArea(ta, codeMirrorOptions);
166 166 // marker for manually set description
167 167 codeMirrorInstance._userDefinedDesc = false;
168 168 codeMirrorInstance.setSize(null, initialHeight);
169 169 codeMirrorInstance.on("change", function(instance, changeObj) {
170 170 var height = initialHeight;
171 171 var lines = instance.lineCount();
172 172 if (lines > 6 && lines < 20) {
173 173 height = "auto"
174 174 }
175 175 else if (lines >= 20) {
176 176 height = 20 * 15;
177 177 }
178 178 instance.setSize(null, height);
179 179
180 180 // detect if the change was trigger by auto desc, or user input
181 181 changeOrigin = changeObj.origin;
182 182
183 183 if (changeOrigin === "setValue") {
184 184 cmLog.debug('Change triggered by setValue');
185 185 }
186 186 else {
187 187 cmLog.debug('user triggered change !');
188 188 // set special marker to indicate user has created an input.
189 189 instance._userDefinedDesc = true;
190 190 }
191 191
192 192 });
193 193
194 194 return codeMirrorInstance
195 195 };
196 196
197 197 /**
198 198 * Reviewer autocomplete
199 199 */
200 200 var ReviewerAutoComplete = function(input_id) {
201 201 $('#'+input_id).autocomplete({
202 202 serviceUrl: pyroutes.url('user_autocomplete_data'),
203 203 minChars:2,
204 204 maxHeight:400,
205 205 deferRequestBy: 300, //miliseconds
206 206 showNoSuggestionNotice: true,
207 207 tabDisabled: true,
208 208 autoSelectFirst: true,
209 209 formatResult: autocompleteFormatResult,
210 210 lookupFilter: autocompleteFilterResult,
211 211 onSelect: function(suggestion, data){
212 212 var msg = _gettext('added manually by "{0}"');
213 213 var reasons = [msg.format(templateContext.rhodecode_user.username)];
214 214 addReviewMember(data.id, data.first_name, data.last_name,
215 215 data.username, data.icon_link, reasons);
216 216 $('#'+input_id).val('');
217 217 }
218 218 });
219 219 };
220
221
222 VersionController = function () {
223 var self = this;
224 this.$verSource = $('input[name=ver_source]');
225 this.$verTarget = $('input[name=ver_target]');
226 this.$showVersionDiff = $('#show-version-diff');
227
228 this.adjustRadioSelectors = function (curNode) {
229 var getVal = function (item) {
230 if (item == 'latest') {
231 return Number.MAX_SAFE_INTEGER
232 }
233 else {
234 return parseInt(item)
235 }
236 };
237
238 var curVal = getVal($(curNode).val());
239 var cleared = false;
240
241 $.each(self.$verSource, function (index, value) {
242 var elVal = getVal($(value).val());
243
244 if (elVal > curVal) {
245 if ($(value).is(':checked')) {
246 cleared = true;
247 }
248 $(value).attr('disabled', 'disabled');
249 $(value).removeAttr('checked');
250 $(value).css({'opacity': 0.1});
251 }
252 else {
253 $(value).css({'opacity': 1});
254 $(value).removeAttr('disabled');
255 }
256 });
257
258 if (cleared) {
259 // if we unchecked an active, set the next one to same loc.
260 $(this.$verSource).filter('[value={0}]'.format(
261 curVal)).attr('checked', 'checked');
262 }
263
264 self.setLockAction(false,
265 $(curNode).data('verPos'),
266 $(this.$verSource).filter(':checked').data('verPos')
267 );
268 };
269
270
271 this.attachVersionListener = function () {
272 self.$verTarget.change(function (e) {
273 self.adjustRadioSelectors(this)
274 });
275 self.$verSource.change(function (e) {
276 self.adjustRadioSelectors(self.$verTarget.filter(':checked'))
277 });
278 };
279
280 this.init = function () {
281
282 var curNode = self.$verTarget.filter(':checked');
283 self.adjustRadioSelectors(curNode);
284 self.setLockAction(true);
285 self.attachVersionListener();
286
287 };
288
289 this.setLockAction = function (state, selectedVersion, otherVersion) {
290 var $showVersionDiff = this.$showVersionDiff;
291
292 if (state) {
293 $showVersionDiff.attr('disabled', 'disabled');
294 $showVersionDiff.addClass('disabled');
295 $showVersionDiff.html($showVersionDiff.data('labelTextLocked'));
296 }
297 else {
298 $showVersionDiff.removeAttr('disabled');
299 $showVersionDiff.removeClass('disabled');
300
301 if (selectedVersion == otherVersion) {
302 $showVersionDiff.html($showVersionDiff.data('labelTextShow'));
303 } else {
304 $showVersionDiff.html($showVersionDiff.data('labelTextDiff'));
305 }
306 }
307
308 };
309
310 this.showVersionDiff = function () {
311 var target = self.$verTarget.filter(':checked');
312 var source = self.$verSource.filter(':checked');
313
314 if (target.val() && source.val()) {
315 var params = {
316 'pull_request_id': templateContext.pull_request_data.pull_request_id,
317 'repo_name': templateContext.repo_name,
318 'version': target.val(),
319 'from_version': source.val()
320 };
321 window.location = pyroutes.url('pullrequest_show', params)
322 }
323
324 return false;
325 };
326
327 this.toggleVersionView = function (elem) {
328
329 if (this.$showVersionDiff.is(':visible')) {
330 $('.version-pr').hide();
331 this.$showVersionDiff.hide();
332 $(elem).html($(elem).data('toggleOn'))
333 } else {
334 $('.version-pr').show();
335 this.$showVersionDiff.show();
336 $(elem).html($(elem).data('toggleOff'))
337 }
338
339 return false
340 }
341
342 }; No newline at end of file
@@ -1,915 +1,796 b''
1 1 <%inherit file="/base/base.mako"/>
2 2 <%namespace name="base" file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('%s Pull Request #%s') % (c.repo_name, c.pull_request.pull_request_id)}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 <span id="pr-title">
13 13 ${c.pull_request.title}
14 14 %if c.pull_request.is_closed():
15 15 (${_('Closed')})
16 16 %endif
17 17 </span>
18 18 <div id="pr-title-edit" class="input" style="display: none;">
19 19 ${h.text('pullrequest_title', id_="pr-title-input", class_="large", value=c.pull_request.title)}
20 20 </div>
21 21 </%def>
22 22
23 23 <%def name="menu_bar_nav()">
24 24 ${self.menu_items(active='repositories')}
25 25 </%def>
26 26
27 27 <%def name="menu_bar_subnav()">
28 28 ${self.repo_menu(active='showpullrequest')}
29 29 </%def>
30 30
31 31 <%def name="main()">
32 32
33 33 <script type="text/javascript">
34 34 // TODO: marcink switch this to pyroutes
35 35 AJAX_COMMENT_DELETE_URL = "${url('pullrequest_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
36 36 templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
37 37 </script>
38 38 <div class="box">
39 39
40 40 <div class="title">
41 41 ${self.repo_page_title(c.rhodecode_db_repo)}
42 42 </div>
43 43
44 44 ${self.breadcrumbs()}
45 45
46 46 <div class="box pr-summary">
47 47
48 48 <div class="summary-details block-left">
49 49 <% summary = lambda n:{False:'summary-short'}.get(n) %>
50 50 <div class="pr-details-title">
51 51 <a href="${h.url('pull_requests_global', pull_request_id=c.pull_request.pull_request_id)}">${_('Pull request #%s') % c.pull_request.pull_request_id}</a> ${_('From')} ${h.format_date(c.pull_request.created_on)}
52 52 %if c.allowed_to_update:
53 53 <div id="delete_pullrequest" class="pull-right action_button ${'' if c.allowed_to_delete else 'disabled' }" style="clear:inherit;padding: 0">
54 54 % if c.allowed_to_delete:
55 55 ${h.secure_form(url('pullrequest_delete', repo_name=c.pull_request.target_repo.repo_name, pull_request_id=c.pull_request.pull_request_id),method='delete')}
56 56 ${h.submit('remove_%s' % c.pull_request.pull_request_id, _('Delete'),
57 57 class_="btn btn-link btn-danger",onclick="return confirm('"+_('Confirm to delete this pull request')+"');")}
58 58 ${h.end_form()}
59 59 % else:
60 60 ${_('Delete')}
61 61 % endif
62 62 </div>
63 63 <div id="open_edit_pullrequest" class="pull-right action_button">${_('Edit')}</div>
64 64 <div id="close_edit_pullrequest" class="pull-right action_button" style="display: none;padding: 0">${_('Cancel')}</div>
65 65 %endif
66 66 </div>
67 67
68 68 <div id="summary" class="fields pr-details-content">
69 69 <div class="field">
70 70 <div class="label-summary">
71 71 <label>${_('Origin')}:</label>
72 72 </div>
73 73 <div class="input">
74 74 <div class="pr-origininfo">
75 75 ## branch link is only valid if it is a branch
76 76 <span class="tag">
77 77 %if c.pull_request.source_ref_parts.type == 'branch':
78 78 <a href="${h.url('changelog_home', repo_name=c.pull_request.source_repo.repo_name, branch=c.pull_request.source_ref_parts.name)}">${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}</a>
79 79 %else:
80 80 ${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}
81 81 %endif
82 82 </span>
83 83 <span class="clone-url">
84 84 <a href="${h.url('summary_home', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.clone_url()}</a>
85 85 </span>
86 86 </div>
87 87 <div class="pr-pullinfo">
88 88 %if h.is_hg(c.pull_request.source_repo):
89 89 <input type="text" value="hg pull -r ${h.short_id(c.source_ref)} ${c.pull_request.source_repo.clone_url()}" readonly="readonly">
90 90 %elif h.is_git(c.pull_request.source_repo):
91 91 <input type="text" value="git pull ${c.pull_request.source_repo.clone_url()} ${c.pull_request.source_ref_parts.name}" readonly="readonly">
92 92 %endif
93 93 </div>
94 94 </div>
95 95 </div>
96 96 <div class="field">
97 97 <div class="label-summary">
98 98 <label>${_('Target')}:</label>
99 99 </div>
100 100 <div class="input">
101 101 <div class="pr-targetinfo">
102 102 ## branch link is only valid if it is a branch
103 103 <span class="tag">
104 104 %if c.pull_request.target_ref_parts.type == 'branch':
105 105 <a href="${h.url('changelog_home', repo_name=c.pull_request.target_repo.repo_name, branch=c.pull_request.target_ref_parts.name)}">${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}</a>
106 106 %else:
107 107 ${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}
108 108 %endif
109 109 </span>
110 110 <span class="clone-url">
111 111 <a href="${h.url('summary_home', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.clone_url()}</a>
112 112 </span>
113 113 </div>
114 114 </div>
115 115 </div>
116 116
117 117 ## Link to the shadow repository.
118 118 <div class="field">
119 119 <div class="label-summary">
120 120 <label>${_('Merge')}:</label>
121 121 </div>
122 122 <div class="input">
123 123 % if not c.pull_request.is_closed() and c.pull_request.shadow_merge_ref:
124 124 <div class="pr-mergeinfo">
125 125 %if h.is_hg(c.pull_request.target_repo):
126 126 <input type="text" value="hg clone -u ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly">
127 127 %elif h.is_git(c.pull_request.target_repo):
128 128 <input type="text" value="git clone --branch ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly">
129 129 %endif
130 130 </div>
131 131 % else:
132 132 <div class="">
133 133 ${_('Shadow repository data not available')}.
134 134 </div>
135 135 % endif
136 136 </div>
137 137 </div>
138 138
139 139 <div class="field">
140 140 <div class="label-summary">
141 141 <label>${_('Review')}:</label>
142 142 </div>
143 143 <div class="input">
144 144 %if c.pull_request_review_status:
145 145 <div class="${'flag_status %s' % c.pull_request_review_status} tooltip pull-left"></div>
146 146 <span class="changeset-status-lbl tooltip">
147 147 %if c.pull_request.is_closed():
148 148 ${_('Closed')},
149 149 %endif
150 150 ${h.commit_status_lbl(c.pull_request_review_status)}
151 151 </span>
152 152 - ${ungettext('calculated based on %s reviewer vote', 'calculated based on %s reviewers votes', len(c.pull_request_reviewers)) % len(c.pull_request_reviewers)}
153 153 %endif
154 154 </div>
155 155 </div>
156 156 <div class="field">
157 157 <div class="pr-description-label label-summary">
158 158 <label>${_('Description')}:</label>
159 159 </div>
160 160 <div id="pr-desc" class="input">
161 161 <div class="pr-description">${h.urlify_commit_message(c.pull_request.description, c.repo_name)}</div>
162 162 </div>
163 163 <div id="pr-desc-edit" class="input textarea editor" style="display: none;">
164 164 <textarea id="pr-description-input" size="30">${c.pull_request.description}</textarea>
165 165 </div>
166 166 </div>
167 167
168 168 <div class="field">
169 169 <div class="label-summary">
170 170 <label>${_('Versions')}:</label>
171 171 </div>
172 172
173 173 <% outdated_comm_count_ver = len(c.inline_versions[None]['outdated']) %>
174 174 <% general_outdated_comm_count_ver = len(c.comment_versions[None]['outdated']) %>
175 175
176 176 <div class="pr-versions">
177 177 % if c.show_version_changes:
178 178 <% outdated_comm_count_ver = len(c.inline_versions[c.at_version_num]['outdated']) %>
179 179 <% general_outdated_comm_count_ver = len(c.comment_versions[c.at_version_num]['outdated']) %>
180 180 <a id="show-pr-versions" class="input" onclick="return versionController.toggleVersionView(this)" href="#show-pr-versions"
181 181 data-toggle-on="${ungettext('{} version available for this pull request, show it.', '{} versions available for this pull request, show them.', len(c.versions)).format(len(c.versions))}"
182 182 data-toggle-off="${_('Hide all versions of this pull request')}">
183 183 ${ungettext('{} version available for this pull request, show it.', '{} versions available for this pull request, show them.', len(c.versions)).format(len(c.versions))}
184 184 </a>
185 185 <table>
186 186 ## SHOW ALL VERSIONS OF PR
187 187 <% ver_pr = None %>
188 188
189 189 % for data in reversed(list(enumerate(c.versions, 1))):
190 190 <% ver_pos = data[0] %>
191 191 <% ver = data[1] %>
192 192 <% ver_pr = ver.pull_request_version_id %>
193 193 <% display_row = '' if c.at_version and (c.at_version_num == ver_pr or c.from_version_num == ver_pr) else 'none' %>
194 194
195 195 <tr class="version-pr" style="display: ${display_row}">
196 196 <td>
197 197 <code>
198 198 <a href="${h.url.current(version=ver_pr or 'latest')}">v${ver_pos}</a>
199 199 </code>
200 200 </td>
201 201 <td>
202 202 <input ${'checked="checked"' if c.from_version_num == ver_pr else ''} class="compare-radio-button" type="radio" name="ver_source" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/>
203 203 <input ${'checked="checked"' if c.at_version_num == ver_pr else ''} class="compare-radio-button" type="radio" name="ver_target" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/>
204 204 </td>
205 205 <td>
206 206 <% review_status = c.review_versions[ver_pr].status if ver_pr in c.review_versions else 'not_reviewed' %>
207 207 <div class="${'flag_status %s' % review_status} tooltip pull-left" title="${_('Your review status at this version')}">
208 208 </div>
209 209 </td>
210 210 <td>
211 211 % if c.at_version_num != ver_pr:
212 212 <i class="icon-comment"></i>
213 213 <code class="tooltip" title="${_('Comment from pull request version {0}, general:{1} inline:{2}').format(ver_pos, len(c.comment_versions[ver_pr]['at']), len(c.inline_versions[ver_pr]['at']))}">
214 214 G:${len(c.comment_versions[ver_pr]['at'])} / I:${len(c.inline_versions[ver_pr]['at'])}
215 215 </code>
216 216 % endif
217 217 </td>
218 218 <td>
219 219 ##<code>${ver.source_ref_parts.commit_id[:6]}</code>
220 220 </td>
221 221 <td>
222 222 ${h.age_component(ver.updated_on)}
223 223 </td>
224 224 </tr>
225 225 % endfor
226 226
227 227 <tr>
228 228 <td colspan="6">
229 229 <button id="show-version-diff" onclick="return versionController.showVersionDiff()" class="btn btn-sm" style="display: none"
230 230 data-label-text-locked="${_('select versions to show changes')}"
231 231 data-label-text-diff="${_('show changes between versions')}"
232 232 data-label-text-show="${_('show pull request for this version')}"
233 233 >
234 234 ${_('select versions to show changes')}
235 235 </button>
236 236 </td>
237 237 </tr>
238 238
239 239 ## show comment/inline comments summary
240 240 <%def name="comments_summary()">
241 241 <tr>
242 242 <td colspan="6" class="comments-summary-td">
243 243
244 244 % if c.at_version:
245 245 <% inline_comm_count_ver = len(c.inline_versions[c.at_version_num]['display']) %>
246 246 <% general_comm_count_ver = len(c.comment_versions[c.at_version_num]['display']) %>
247 247 ${_('Comments at this version')}:
248 248 % else:
249 249 <% inline_comm_count_ver = len(c.inline_versions[c.at_version_num]['until']) %>
250 250 <% general_comm_count_ver = len(c.comment_versions[c.at_version_num]['until']) %>
251 251 ${_('Comments for this pull request')}:
252 252 % endif
253 253
254 254
255 255 %if general_comm_count_ver:
256 256 <a href="#comments">${_("%d General ") % general_comm_count_ver}</a>
257 257 %else:
258 258 ${_("%d General ") % general_comm_count_ver}
259 259 %endif
260 260
261 261 %if inline_comm_count_ver:
262 262 , <a href="#" onclick="return Rhodecode.comments.nextComment();" id="inline-comments-counter">${_("%d Inline") % inline_comm_count_ver}</a>
263 263 %else:
264 264 , ${_("%d Inline") % inline_comm_count_ver}
265 265 %endif
266 266
267 267 %if outdated_comm_count_ver:
268 268 , <a href="#" onclick="showOutdated(); Rhodecode.comments.nextOutdatedComment(); return false;">${_("%d Outdated") % outdated_comm_count_ver}</a>
269 269 <a href="#" class="showOutdatedComments" onclick="showOutdated(this); return false;"> | ${_('show outdated comments')}</a>
270 270 <a href="#" class="hideOutdatedComments" style="display: none" onclick="hideOutdated(this); return false;"> | ${_('hide outdated comments')}</a>
271 271 %else:
272 272 , ${_("%d Outdated") % outdated_comm_count_ver}
273 273 %endif
274 274 </td>
275 275 </tr>
276 276 </%def>
277 277 ${comments_summary()}
278 278 </table>
279 279 % else:
280 280 <div class="input">
281 281 ${_('Pull request versions not available')}.
282 282 </div>
283 283 <div>
284 284 <table>
285 285 ${comments_summary()}
286 286 </table>
287 287 </div>
288 288 % endif
289 289 </div>
290 290 </div>
291 291
292 292 <div id="pr-save" class="field" style="display: none;">
293 293 <div class="label-summary"></div>
294 294 <div class="input">
295 295 <span id="edit_pull_request" class="btn btn-small">${_('Save Changes')}</span>
296 296 </div>
297 297 </div>
298 298 </div>
299 299 </div>
300 300 <div>
301 301 ## AUTHOR
302 302 <div class="reviewers-title block-right">
303 303 <div class="pr-details-title">
304 304 ${_('Author')}
305 305 </div>
306 306 </div>
307 307 <div class="block-right pr-details-content reviewers">
308 308 <ul class="group_members">
309 309 <li>
310 310 ${self.gravatar_with_user(c.pull_request.author.email, 16)}
311 311 </li>
312 312 </ul>
313 313 </div>
314 314 ## REVIEWERS
315 315 <div class="reviewers-title block-right">
316 316 <div class="pr-details-title">
317 317 ${_('Pull request reviewers')}
318 318 %if c.allowed_to_update:
319 319 <span id="open_edit_reviewers" class="block-right action_button">${_('Edit')}</span>
320 320 <span id="close_edit_reviewers" class="block-right action_button" style="display: none;">${_('Close')}</span>
321 321 %endif
322 322 </div>
323 323 </div>
324 324 <div id="reviewers" class="block-right pr-details-content reviewers">
325 325 ## members goes here !
326 326 <input type="hidden" name="__start__" value="review_members:sequence">
327 327 <ul id="review_members" class="group_members">
328 328 %for member,reasons,status in c.pull_request_reviewers:
329 329 <li id="reviewer_${member.user_id}">
330 330 <div class="reviewers_member">
331 331 <div class="reviewer_status tooltip" title="${h.tooltip(h.commit_status_lbl(status[0][1].status if status else 'not_reviewed'))}">
332 332 <div class="${'flag_status %s' % (status[0][1].status if status else 'not_reviewed')} pull-left reviewer_member_status"></div>
333 333 </div>
334 334 <div id="reviewer_${member.user_id}_name" class="reviewer_name">
335 335 ${self.gravatar_with_user(member.email, 16)}
336 336 </div>
337 337 <input type="hidden" name="__start__" value="reviewer:mapping">
338 338 <input type="hidden" name="__start__" value="reasons:sequence">
339 339 %for reason in reasons:
340 340 <div class="reviewer_reason">- ${reason}</div>
341 341 <input type="hidden" name="reason" value="${reason}">
342 342
343 343 %endfor
344 344 <input type="hidden" name="__end__" value="reasons:sequence">
345 345 <input id="reviewer_${member.user_id}_input" type="hidden" value="${member.user_id}" name="user_id" />
346 346 <input type="hidden" name="__end__" value="reviewer:mapping">
347 347 %if c.allowed_to_update:
348 348 <div class="reviewer_member_remove action_button" onclick="removeReviewMember(${member.user_id}, true)" style="visibility: hidden;">
349 349 <i class="icon-remove-sign" ></i>
350 350 </div>
351 351 %endif
352 352 </div>
353 353 </li>
354 354 %endfor
355 355 </ul>
356 356 <input type="hidden" name="__end__" value="review_members:sequence">
357 357 %if not c.pull_request.is_closed():
358 358 <div id="add_reviewer_input" class='ac' style="display: none;">
359 359 %if c.allowed_to_update:
360 360 <div class="reviewer_ac">
361 361 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer'))}
362 362 <div id="reviewers_container"></div>
363 363 </div>
364 364 <div>
365 365 <span id="update_pull_request" class="btn btn-small">${_('Save Changes')}</span>
366 366 </div>
367 367 %endif
368 368 </div>
369 369 %endif
370 370 </div>
371 371 </div>
372 372 </div>
373 373 <div class="box">
374 374 ##DIFF
375 375 <div class="table" >
376 376 <div id="changeset_compare_view_content">
377 377 ##CS
378 378 % if c.missing_requirements:
379 379 <div class="box">
380 380 <div class="alert alert-warning">
381 381 <div>
382 382 <strong>${_('Missing requirements:')}</strong>
383 383 ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')}
384 384 </div>
385 385 </div>
386 386 </div>
387 387 % elif c.missing_commits:
388 388 <div class="box">
389 389 <div class="alert alert-warning">
390 390 <div>
391 391 <strong>${_('Missing commits')}:</strong>
392 392 ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')}
393 393 ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')}
394 394 </div>
395 395 </div>
396 396 </div>
397 397 % endif
398 398
399 399 <div class="compare_view_commits_title">
400 400 % if not c.compare_mode:
401 401
402 402 % if c.at_version_pos:
403 403 <h4>
404 404 ${_('Showing changes at v%d, commenting is disabled.') % c.at_version_pos}
405 405 </h4>
406 406 % endif
407 407
408 408 <div class="pull-left">
409 409 <div class="btn-group">
410 410 <a
411 411 class="btn"
412 412 href="#"
413 413 onclick="$('.compare_select').show();$('.compare_select_hidden').hide(); return false">
414 414 ${ungettext('Expand %s commit','Expand %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}
415 415 </a>
416 416 <a
417 417 class="btn"
418 418 href="#"
419 419 onclick="$('.compare_select').hide();$('.compare_select_hidden').show(); return false">
420 420 ${ungettext('Collapse %s commit','Collapse %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}
421 421 </a>
422 422 </div>
423 423 </div>
424 424
425 425 <div class="pull-right">
426 426 % if c.allowed_to_update and not c.pull_request.is_closed():
427 427 <a id="update_commits" class="btn btn-primary pull-right">${_('Update commits')}</a>
428 428 % else:
429 429 <a class="tooltip btn disabled pull-right" disabled="disabled" title="${_('Update is disabled for current view')}">${_('Update commits')}</a>
430 430 % endif
431 431
432 432 </div>
433 433 % endif
434 434 </div>
435 435
436 436 % if not c.missing_commits:
437 437 % if c.compare_mode:
438 438 % if c.at_version:
439 439 <h4>
440 440 ${_('Commits and changes between v{ver_from} and {ver_to} of this pull request, commenting is disabled').format(ver_from=c.from_version_pos, ver_to=c.at_version_pos if c.at_version_pos else 'latest')}:
441 441 </h4>
442 442
443 443 <div class="subtitle-compare">
444 444 ${_('commits added: {}, removed: {}').format(len(c.commit_changes_summary.added), len(c.commit_changes_summary.removed))}
445 445 </div>
446 446
447 447 <div class="container">
448 448 <table class="rctable compare_view_commits">
449 449 <tr>
450 450 <th></th>
451 451 <th>${_('Time')}</th>
452 452 <th>${_('Author')}</th>
453 453 <th>${_('Commit')}</th>
454 454 <th></th>
455 455 <th>${_('Description')}</th>
456 456 </tr>
457 457
458 458 % for c_type, commit in c.commit_changes:
459 459 % if c_type in ['a', 'r']:
460 460 <%
461 461 if c_type == 'a':
462 462 cc_title = _('Commit added in displayed changes')
463 463 elif c_type == 'r':
464 464 cc_title = _('Commit removed in displayed changes')
465 465 else:
466 466 cc_title = ''
467 467 %>
468 468 <tr id="row-${commit.raw_id}" commit_id="${commit.raw_id}" class="compare_select">
469 469 <td>
470 470 <div class="commit-change-indicator color-${c_type}-border">
471 471 <div class="commit-change-content color-${c_type} tooltip" title="${cc_title}">
472 472 ${c_type.upper()}
473 473 </div>
474 474 </div>
475 475 </td>
476 476 <td class="td-time">
477 477 ${h.age_component(commit.date)}
478 478 </td>
479 479 <td class="td-user">
480 480 ${base.gravatar_with_user(commit.author, 16)}
481 481 </td>
482 482 <td class="td-hash">
483 483 <code>
484 484 <a href="${h.url('changeset_home', repo_name=c.target_repo.repo_name, revision=commit.raw_id)}">
485 485 r${commit.revision}:${h.short_id(commit.raw_id)}
486 486 </a>
487 487 ${h.hidden('revisions', commit.raw_id)}
488 488 </code>
489 489 </td>
490 490 <td class="expand_commit" data-commit-id="${commit.raw_id}" title="${_( 'Expand commit message')}">
491 491 <div class="show_more_col">
492 492 <i class="show_more"></i>
493 493 </div>
494 494 </td>
495 495 <td class="mid td-description">
496 496 <div class="log-container truncate-wrap">
497 497 <div class="message truncate" id="c-${commit.raw_id}" data-message-raw="${commit.message}">
498 498 ${h.urlify_commit_message(commit.message, c.repo_name)}
499 499 </div>
500 500 </div>
501 501 </td>
502 502 </tr>
503 503 % endif
504 504 % endfor
505 505 </table>
506 506 </div>
507 507
508 508 <script>
509 509 $('.expand_commit').on('click',function(e){
510 510 var target_expand = $(this);
511 511 var cid = target_expand.data('commitId');
512 512
513 513 if (target_expand.hasClass('open')){
514 514 $('#c-'+cid).css({
515 515 'height': '1.5em',
516 516 'white-space': 'nowrap',
517 517 'text-overflow': 'ellipsis',
518 518 'overflow':'hidden'
519 519 });
520 520 target_expand.removeClass('open');
521 521 }
522 522 else {
523 523 $('#c-'+cid).css({
524 524 'height': 'auto',
525 525 'white-space': 'pre-line',
526 526 'text-overflow': 'initial',
527 527 'overflow':'visible'
528 528 });
529 529 target_expand.addClass('open');
530 530 }
531 531 });
532 532 </script>
533 533
534 534 % endif
535 535
536 536 % else:
537 537 <%include file="/compare/compare_commits.mako" />
538 538 % endif
539 539
540 540 <div class="cs_files">
541 541 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
542 542 ${cbdiffs.render_diffset_menu()}
543 543 ${cbdiffs.render_diffset(
544 544 c.diffset, use_comments=True,
545 545 collapse_when_files_over=30,
546 546 disable_new_comments=not c.allowed_to_comment,
547 547 deleted_files_comments=c.deleted_files_comments)}
548 548 </div>
549 549 % else:
550 550 ## skipping commits we need to clear the view for missing commits
551 551 <div style="clear:both;"></div>
552 552 % endif
553 553
554 554 </div>
555 555 </div>
556 556
557 557 ## template for inline comment form
558 558 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
559 559
560 560 ## render general comments
561 561
562 562 <div id="comment-tr-show">
563 563 <div class="comment">
564 564 % if general_outdated_comm_count_ver:
565 565 <div class="meta">
566 566 % if general_outdated_comm_count_ver == 1:
567 567 ${_('there is {num} general comment from older versions').format(num=general_outdated_comm_count_ver)},
568 568 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show it')}</a>
569 569 % else:
570 570 ${_('there are {num} general comments from older versions').format(num=general_outdated_comm_count_ver)},
571 571 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show them')}</a>
572 572 % endif
573 573 </div>
574 574 % endif
575 575 </div>
576 576 </div>
577 577
578 578 ${comment.generate_comments(c.comments, include_pull_request=True, is_pull_request=True)}
579 579
580 580 % if not c.pull_request.is_closed():
581 581 ## merge status, and merge action
582 582 <div class="pull-request-merge">
583 583 <%include file="/pullrequests/pullrequest_merge_checks.mako"/>
584 584 </div>
585 585
586 586 ## main comment form and it status
587 587 ${comment.comments(h.url('pullrequest_comment', repo_name=c.repo_name,
588 588 pull_request_id=c.pull_request.pull_request_id),
589 589 c.pull_request_review_status,
590 590 is_pull_request=True, change_status=c.allowed_to_change_status)}
591 591 %endif
592 592
593 593 <script type="text/javascript">
594 594 if (location.hash) {
595 595 var result = splitDelimitedHash(location.hash);
596 596 var line = $('html').find(result.loc);
597 597 // show hidden comments if we use location.hash
598 598 if (line.hasClass('comment-general')) {
599 599 $(line).show();
600 600 } else if (line.hasClass('comment-inline')) {
601 601 $(line).show();
602 602 var $cb = $(line).closest('.cb');
603 603 $cb.removeClass('cb-collapsed')
604 604 }
605 605 if (line.length > 0){
606 606 offsetScroll(line, 70);
607 607 }
608 608 }
609 609
610 VersionController = function() {
611 var self = this;
612 this.$verSource = $('input[name=ver_source]');
613 this.$verTarget = $('input[name=ver_target]');
614
615 this.adjustRadioSelectors = function (curNode) {
616 var getVal = function(item) {
617 if (item == 'latest'){
618 return Number.MAX_SAFE_INTEGER
619 }
620 else {
621 return parseInt(item)
622 }
623 };
624
625 var curVal = getVal($(curNode).val());
626 var cleared = false;
627
628 $.each(self.$verSource, function(index, value){
629 var elVal = getVal($(value).val());
630
631 if(elVal > curVal){
632 if ($(value).is(':checked')) {
633 cleared = true;
634 }
635 $(value).attr('disabled', 'disabled');
636 $(value).removeAttr('checked');
637 $(value).css({'opacity': 0.1});
638 }
639 else{
640 $(value).css({'opacity': 1});
641 $(value).removeAttr('disabled');
642 }
643 });
644
645 if (cleared) {
646 // if we unchecked an active, set the next one to same loc.
647 $(this.$verSource).filter('[value={0}]'.format(
648 curVal)).attr('checked', 'checked');
649 }
650
651 self.setLockAction(false,
652 $(curNode).data('verPos'),
653 $(this.$verSource).filter(':checked').data('verPos')
654 );
655 };
656
657
658 this.attachVersionListener = function () {
659 self.$verTarget.change(function(e){
660 self.adjustRadioSelectors(this)
661 });
662 self.$verSource.change(function(e){
663 self.adjustRadioSelectors(self.$verTarget.filter(':checked'))
664 });
665 };
666
667 this.init = function () {
668
669 var curNode = self.$verTarget.filter(':checked');
670 self.adjustRadioSelectors(curNode);
671 self.setLockAction(true);
672 self.attachVersionListener();
673
674 };
675
676 this.setLockAction = function (state, selectedVersion, otherVersion) {
677 if (state) {
678 $('#show-version-diff').attr('disabled', 'disabled');
679 $('#show-version-diff').addClass('disabled');
680 $('#show-version-diff').html($('#show-version-diff').data('labelTextLocked'));
681 }
682 else {
683 $('#show-version-diff').removeAttr('disabled');
684 $('#show-version-diff').removeClass('disabled');
685
686 if (selectedVersion == otherVersion) {
687 $('#show-version-diff').html($('#show-version-diff').data('labelTextShow'));
688 } else {
689 $('#show-version-diff').html($('#show-version-diff').data('labelTextDiff'));
690 }
691 }
692
693 };
694
695 this.showVersionDiff = function(){
696 var target = self.$verTarget.filter(':checked');
697 var source = self.$verSource.filter(':checked');
698
699 if (target.val() && source.val()) {
700 var params = {
701 'pull_request_id': ${c.pull_request.pull_request_id},
702 'repo_name': templateContext.repo_name,
703 'version': target.val(),
704 'from_version': source.val()
705 };
706 window.location = pyroutes.url('pullrequest_show', params)
707 }
708
709 return false;
710 };
711
712 this.toggleVersionView = function (elem) {
713
714 if ($('#show-version-diff').is(':visible')) {
715 $('.version-pr').hide();
716 $('#show-version-diff').hide();
717 $(elem).html($(elem).data('toggleOn'))
718 } else {
719 $('.version-pr').show();
720 $('#show-version-diff').show();
721 $(elem).html($(elem).data('toggleOff'))
722 }
723
724 return false
725 }
726
727 };
728
729 610 versionController = new VersionController();
730 611 versionController.init();
731 612
732 613
733 614 $(function(){
734 615 ReviewerAutoComplete('user');
735 616 // custom code mirror
736 617 var codeMirrorInstance = initPullRequestsCodeMirror('#pr-description-input');
737 618
738 619 var PRDetails = {
739 620 editButton: $('#open_edit_pullrequest'),
740 621 closeButton: $('#close_edit_pullrequest'),
741 622 deleteButton: $('#delete_pullrequest'),
742 623 viewFields: $('#pr-desc, #pr-title'),
743 624 editFields: $('#pr-desc-edit, #pr-title-edit, #pr-save'),
744 625
745 626 init: function() {
746 627 var that = this;
747 628 this.editButton.on('click', function(e) { that.edit(); });
748 629 this.closeButton.on('click', function(e) { that.view(); });
749 630 },
750 631
751 632 edit: function(event) {
752 633 this.viewFields.hide();
753 634 this.editButton.hide();
754 635 this.deleteButton.hide();
755 636 this.closeButton.show();
756 637 this.editFields.show();
757 638 codeMirrorInstance.refresh();
758 639 },
759 640
760 641 view: function(event) {
761 642 this.editButton.show();
762 643 this.deleteButton.show();
763 644 this.editFields.hide();
764 645 this.closeButton.hide();
765 646 this.viewFields.show();
766 647 }
767 648 };
768 649
769 650 var ReviewersPanel = {
770 651 editButton: $('#open_edit_reviewers'),
771 652 closeButton: $('#close_edit_reviewers'),
772 653 addButton: $('#add_reviewer_input'),
773 654 removeButtons: $('.reviewer_member_remove'),
774 655
775 656 init: function() {
776 657 var that = this;
777 658 this.editButton.on('click', function(e) { that.edit(); });
778 659 this.closeButton.on('click', function(e) { that.close(); });
779 660 },
780 661
781 662 edit: function(event) {
782 663 this.editButton.hide();
783 664 this.closeButton.show();
784 665 this.addButton.show();
785 666 this.removeButtons.css('visibility', 'visible');
786 667 },
787 668
788 669 close: function(event) {
789 670 this.editButton.show();
790 671 this.closeButton.hide();
791 672 this.addButton.hide();
792 673 this.removeButtons.css('visibility', 'hidden');
793 674 }
794 675 };
795 676
796 677 PRDetails.init();
797 678 ReviewersPanel.init();
798 679
799 680 showOutdated = function(self){
800 681 $('.comment-inline.comment-outdated').show();
801 682 $('.filediff-outdated').show();
802 683 $('.showOutdatedComments').hide();
803 684 $('.hideOutdatedComments').show();
804 685 };
805 686
806 687 hideOutdated = function(self){
807 688 $('.comment-inline.comment-outdated').hide();
808 689 $('.filediff-outdated').hide();
809 690 $('.hideOutdatedComments').hide();
810 691 $('.showOutdatedComments').show();
811 692 };
812 693
813 694 refreshMergeChecks = function(){
814 695 var loadUrl = "${h.url.current(merge_checks=1)}";
815 696 $('.pull-request-merge').css('opacity', 0.3);
816 697 $('.pull-request-merge').load(
817 698 loadUrl,function() {
818 699 $('.pull-request-merge').css('opacity', 1);
819 700 }
820 701 );
821 702 };
822 703
823 704 $('#show-outdated-comments').on('click', function(e){
824 705 var button = $(this);
825 706 var outdated = $('.comment-outdated');
826 707
827 708 if (button.html() === "(Show)") {
828 709 button.html("(Hide)");
829 710 outdated.show();
830 711 } else {
831 712 button.html("(Show)");
832 713 outdated.hide();
833 714 }
834 715 });
835 716
836 717 $('.show-inline-comments').on('change', function(e){
837 718 var show = 'none';
838 719 var target = e.currentTarget;
839 720 if(target.checked){
840 721 show = ''
841 722 }
842 723 var boxid = $(target).attr('id_for');
843 724 var comments = $('#{0} .inline-comments'.format(boxid));
844 725 var fn_display = function(idx){
845 726 $(this).css('display', show);
846 727 };
847 728 $(comments).each(fn_display);
848 729 var btns = $('#{0} .inline-comments-button'.format(boxid));
849 730 $(btns).each(fn_display);
850 731 });
851 732
852 733 $('#merge_pull_request_form').submit(function() {
853 734 if (!$('#merge_pull_request').attr('disabled')) {
854 735 $('#merge_pull_request').attr('disabled', 'disabled');
855 736 }
856 737 return true;
857 738 });
858 739
859 740 $('#edit_pull_request').on('click', function(e){
860 741 var title = $('#pr-title-input').val();
861 742 var description = codeMirrorInstance.getValue();
862 743 editPullRequest(
863 744 "${c.repo_name}", "${c.pull_request.pull_request_id}",
864 745 title, description);
865 746 });
866 747
867 748 $('#update_pull_request').on('click', function(e){
868 749 updateReviewers(undefined, "${c.repo_name}", "${c.pull_request.pull_request_id}");
869 750 });
870 751
871 752 $('#update_commits').on('click', function(e){
872 753 var isDisabled = !$(e.currentTarget).attr('disabled');
873 754 $(e.currentTarget).text(_gettext('Updating...'));
874 755 $(e.currentTarget).attr('disabled', 'disabled');
875 756 if(isDisabled){
876 757 updateCommits("${c.repo_name}", "${c.pull_request.pull_request_id}");
877 758 }
878 759
879 760 });
880 761 // fixing issue with caches on firefox
881 762 $('#update_commits').removeAttr("disabled");
882 763
883 764 $('#close_pull_request').on('click', function(e){
884 765 closePullRequest("${c.repo_name}", "${c.pull_request.pull_request_id}");
885 766 });
886 767
887 768 $('.show-inline-comments').on('click', function(e){
888 769 var boxid = $(this).attr('data-comment-id');
889 770 var button = $(this);
890 771
891 772 if(button.hasClass("comments-visible")) {
892 773 $('#{0} .inline-comments'.format(boxid)).each(function(index){
893 774 $(this).hide();
894 775 });
895 776 button.removeClass("comments-visible");
896 777 } else {
897 778 $('#{0} .inline-comments'.format(boxid)).each(function(index){
898 779 $(this).show();
899 780 });
900 781 button.addClass("comments-visible");
901 782 }
902 783 });
903 784
904 785 // register submit callback on commentForm form to track TODOs
905 786 window.commentFormGlobalSubmitSuccessCallback = function(){
906 787 refreshMergeChecks();
907 788 };
908 789
909 790 })
910 791 </script>
911 792
912 793 </div>
913 794 </div>
914 795
915 796 </%def>
General Comments 0
You need to be logged in to leave comments. Login now