##// END OF EJS Templates
pull-requests: added missing escapeMarkup.
marcink -
r2995:c4ee2d0b default
parent child Browse files
Show More
@@ -1,548 +1,548 b''
1 <%inherit file="/base/base.mako"/>
1 <%inherit file="/base/base.mako"/>
2 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
2 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${c.repo_name} ${_('New pull request')}
5 ${c.repo_name} ${_('New pull request')}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${_('New pull request')}
9 ${_('New pull request')}
10 </%def>
10 </%def>
11
11
12 <%def name="menu_bar_nav()">
12 <%def name="menu_bar_nav()">
13 ${self.menu_items(active='repositories')}
13 ${self.menu_items(active='repositories')}
14 </%def>
14 </%def>
15
15
16 <%def name="menu_bar_subnav()">
16 <%def name="menu_bar_subnav()">
17 ${self.repo_menu(active='showpullrequest')}
17 ${self.repo_menu(active='showpullrequest')}
18 </%def>
18 </%def>
19
19
20 <%def name="main()">
20 <%def name="main()">
21 <div class="box">
21 <div class="box">
22 <div class="title">
22 <div class="title">
23 ${self.repo_page_title(c.rhodecode_db_repo)}
23 ${self.repo_page_title(c.rhodecode_db_repo)}
24 </div>
24 </div>
25
25
26 ${h.secure_form(h.route_path('pullrequest_create', repo_name=c.repo_name, _query=request.GET.mixed()), id='pull_request_form', request=request)}
26 ${h.secure_form(h.route_path('pullrequest_create', repo_name=c.repo_name, _query=request.GET.mixed()), id='pull_request_form', request=request)}
27
27
28 ${self.breadcrumbs()}
28 ${self.breadcrumbs()}
29
29
30 <div class="box pr-summary">
30 <div class="box pr-summary">
31
31
32 <div class="summary-details block-left">
32 <div class="summary-details block-left">
33
33
34
34
35 <div class="pr-details-title">
35 <div class="pr-details-title">
36 ${_('Pull request summary')}
36 ${_('Pull request summary')}
37 </div>
37 </div>
38
38
39 <div class="form" style="padding-top: 10px">
39 <div class="form" style="padding-top: 10px">
40 <!-- fields -->
40 <!-- fields -->
41
41
42 <div class="fields" >
42 <div class="fields" >
43
43
44 <div class="field">
44 <div class="field">
45 <div class="label">
45 <div class="label">
46 <label for="pullrequest_title">${_('Title')}:</label>
46 <label for="pullrequest_title">${_('Title')}:</label>
47 </div>
47 </div>
48 <div class="input">
48 <div class="input">
49 ${h.text('pullrequest_title', c.default_title, class_="medium autogenerated-title")}
49 ${h.text('pullrequest_title', c.default_title, class_="medium autogenerated-title")}
50 </div>
50 </div>
51 </div>
51 </div>
52
52
53 <div class="field">
53 <div class="field">
54 <div class="label label-textarea">
54 <div class="label label-textarea">
55 <label for="pullrequest_desc">${_('Description')}:</label>
55 <label for="pullrequest_desc">${_('Description')}:</label>
56 </div>
56 </div>
57 <div class="textarea text-area editor">
57 <div class="textarea text-area editor">
58 <input id="pr-renderer-input" type="hidden" name="description_renderer" value="${c.visual.default_renderer}">
58 <input id="pr-renderer-input" type="hidden" name="description_renderer" value="${c.visual.default_renderer}">
59 ${dt.markup_form('pullrequest_desc')}
59 ${dt.markup_form('pullrequest_desc')}
60 </div>
60 </div>
61 </div>
61 </div>
62
62
63 <div class="field">
63 <div class="field">
64 <div class="label label-textarea">
64 <div class="label label-textarea">
65 <label for="commit_flow">${_('Commit flow')}:</label>
65 <label for="commit_flow">${_('Commit flow')}:</label>
66 </div>
66 </div>
67
67
68 ## TODO: johbo: Abusing the "content" class here to get the
68 ## TODO: johbo: Abusing the "content" class here to get the
69 ## desired effect. Should be replaced by a proper solution.
69 ## desired effect. Should be replaced by a proper solution.
70
70
71 ##ORG
71 ##ORG
72 <div class="content">
72 <div class="content">
73 <strong>${_('Source repository')}:</strong>
73 <strong>${_('Source repository')}:</strong>
74 ${c.rhodecode_db_repo.description}
74 ${c.rhodecode_db_repo.description}
75 </div>
75 </div>
76 <div class="content">
76 <div class="content">
77 ${h.hidden('source_repo')}
77 ${h.hidden('source_repo')}
78 ${h.hidden('source_ref')}
78 ${h.hidden('source_ref')}
79 </div>
79 </div>
80
80
81 ##OTHER, most Probably the PARENT OF THIS FORK
81 ##OTHER, most Probably the PARENT OF THIS FORK
82 <div class="content">
82 <div class="content">
83 ## filled with JS
83 ## filled with JS
84 <div id="target_repo_desc"></div>
84 <div id="target_repo_desc"></div>
85 </div>
85 </div>
86
86
87 <div class="content">
87 <div class="content">
88 ${h.hidden('target_repo')}
88 ${h.hidden('target_repo')}
89 ${h.hidden('target_ref')}
89 ${h.hidden('target_ref')}
90 <span id="target_ref_loading" style="display: none">
90 <span id="target_ref_loading" style="display: none">
91 ${_('Loading refs...')}
91 ${_('Loading refs...')}
92 </span>
92 </span>
93 </div>
93 </div>
94 </div>
94 </div>
95
95
96 <div class="field">
96 <div class="field">
97 <div class="label label-textarea">
97 <div class="label label-textarea">
98 <label for="pullrequest_submit"></label>
98 <label for="pullrequest_submit"></label>
99 </div>
99 </div>
100 <div class="input">
100 <div class="input">
101 <div class="pr-submit-button">
101 <div class="pr-submit-button">
102 <input id="pr_submit" class="btn" name="save" type="submit" value="${_('Submit Pull Request')}">
102 <input id="pr_submit" class="btn" name="save" type="submit" value="${_('Submit Pull Request')}">
103 </div>
103 </div>
104 <div id="pr_open_message"></div>
104 <div id="pr_open_message"></div>
105 </div>
105 </div>
106 </div>
106 </div>
107
107
108 <div class="pr-spacing-container"></div>
108 <div class="pr-spacing-container"></div>
109 </div>
109 </div>
110 </div>
110 </div>
111 </div>
111 </div>
112 <div>
112 <div>
113 ## AUTHOR
113 ## AUTHOR
114 <div class="reviewers-title block-right">
114 <div class="reviewers-title block-right">
115 <div class="pr-details-title">
115 <div class="pr-details-title">
116 ${_('Author of this pull request')}
116 ${_('Author of this pull request')}
117 </div>
117 </div>
118 </div>
118 </div>
119 <div class="block-right pr-details-content reviewers">
119 <div class="block-right pr-details-content reviewers">
120 <ul class="group_members">
120 <ul class="group_members">
121 <li>
121 <li>
122 ${self.gravatar_with_user(c.rhodecode_user.email, 16)}
122 ${self.gravatar_with_user(c.rhodecode_user.email, 16)}
123 </li>
123 </li>
124 </ul>
124 </ul>
125 </div>
125 </div>
126
126
127 ## REVIEW RULES
127 ## REVIEW RULES
128 <div id="review_rules" style="display: none" class="reviewers-title block-right">
128 <div id="review_rules" style="display: none" class="reviewers-title block-right">
129 <div class="pr-details-title">
129 <div class="pr-details-title">
130 ${_('Reviewer rules')}
130 ${_('Reviewer rules')}
131 </div>
131 </div>
132 <div class="pr-reviewer-rules">
132 <div class="pr-reviewer-rules">
133 ## review rules will be appended here, by default reviewers logic
133 ## review rules will be appended here, by default reviewers logic
134 </div>
134 </div>
135 </div>
135 </div>
136
136
137 ## REVIEWERS
137 ## REVIEWERS
138 <div class="reviewers-title block-right">
138 <div class="reviewers-title block-right">
139 <div class="pr-details-title">
139 <div class="pr-details-title">
140 ${_('Pull request reviewers')}
140 ${_('Pull request reviewers')}
141 <span class="calculate-reviewers"> - ${_('loading...')}</span>
141 <span class="calculate-reviewers"> - ${_('loading...')}</span>
142 </div>
142 </div>
143 </div>
143 </div>
144 <div id="reviewers" class="block-right pr-details-content reviewers">
144 <div id="reviewers" class="block-right pr-details-content reviewers">
145 ## members goes here, filled via JS based on initial selection !
145 ## members goes here, filled via JS based on initial selection !
146 <input type="hidden" name="__start__" value="review_members:sequence">
146 <input type="hidden" name="__start__" value="review_members:sequence">
147 <ul id="review_members" class="group_members"></ul>
147 <ul id="review_members" class="group_members"></ul>
148 <input type="hidden" name="__end__" value="review_members:sequence">
148 <input type="hidden" name="__end__" value="review_members:sequence">
149 <div id="add_reviewer_input" class='ac'>
149 <div id="add_reviewer_input" class='ac'>
150 <div class="reviewer_ac">
150 <div class="reviewer_ac">
151 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))}
151 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))}
152 <div id="reviewers_container"></div>
152 <div id="reviewers_container"></div>
153 </div>
153 </div>
154 </div>
154 </div>
155 </div>
155 </div>
156 </div>
156 </div>
157 </div>
157 </div>
158 <div class="box">
158 <div class="box">
159 <div>
159 <div>
160 ## overview pulled by ajax
160 ## overview pulled by ajax
161 <div id="pull_request_overview"></div>
161 <div id="pull_request_overview"></div>
162 </div>
162 </div>
163 </div>
163 </div>
164 ${h.end_form()}
164 ${h.end_form()}
165 </div>
165 </div>
166
166
167 <script type="text/javascript">
167 <script type="text/javascript">
168 $(function(){
168 $(function(){
169 var defaultSourceRepo = '${c.default_repo_data['source_repo_name']}';
169 var defaultSourceRepo = '${c.default_repo_data['source_repo_name']}';
170 var defaultSourceRepoData = ${c.default_repo_data['source_refs_json']|n};
170 var defaultSourceRepoData = ${c.default_repo_data['source_refs_json']|n};
171 var defaultTargetRepo = '${c.default_repo_data['target_repo_name']}';
171 var defaultTargetRepo = '${c.default_repo_data['target_repo_name']}';
172 var defaultTargetRepoData = ${c.default_repo_data['target_refs_json']|n};
172 var defaultTargetRepoData = ${c.default_repo_data['target_refs_json']|n};
173
173
174 var $pullRequestForm = $('#pull_request_form');
174 var $pullRequestForm = $('#pull_request_form');
175 var $pullRequestSubmit = $('#pr_submit', $pullRequestForm);
175 var $pullRequestSubmit = $('#pr_submit', $pullRequestForm);
176 var $sourceRepo = $('#source_repo', $pullRequestForm);
176 var $sourceRepo = $('#source_repo', $pullRequestForm);
177 var $targetRepo = $('#target_repo', $pullRequestForm);
177 var $targetRepo = $('#target_repo', $pullRequestForm);
178 var $sourceRef = $('#source_ref', $pullRequestForm);
178 var $sourceRef = $('#source_ref', $pullRequestForm);
179 var $targetRef = $('#target_ref', $pullRequestForm);
179 var $targetRef = $('#target_ref', $pullRequestForm);
180
180
181 var sourceRepo = function() { return $sourceRepo.eq(0).val() };
181 var sourceRepo = function() { return $sourceRepo.eq(0).val() };
182 var sourceRef = function() { return $sourceRef.eq(0).val().split(':') };
182 var sourceRef = function() { return $sourceRef.eq(0).val().split(':') };
183
183
184 var targetRepo = function() { return $targetRepo.eq(0).val() };
184 var targetRepo = function() { return $targetRepo.eq(0).val() };
185 var targetRef = function() { return $targetRef.eq(0).val().split(':') };
185 var targetRef = function() { return $targetRef.eq(0).val().split(':') };
186
186
187 var calculateContainerWidth = function() {
187 var calculateContainerWidth = function() {
188 var maxWidth = 0;
188 var maxWidth = 0;
189 var repoSelect2Containers = ['#source_repo', '#target_repo'];
189 var repoSelect2Containers = ['#source_repo', '#target_repo'];
190 $.each(repoSelect2Containers, function(idx, value) {
190 $.each(repoSelect2Containers, function(idx, value) {
191 $(value).select2('container').width('auto');
191 $(value).select2('container').width('auto');
192 var curWidth = $(value).select2('container').width();
192 var curWidth = $(value).select2('container').width();
193 if (maxWidth <= curWidth) {
193 if (maxWidth <= curWidth) {
194 maxWidth = curWidth;
194 maxWidth = curWidth;
195 }
195 }
196 $.each(repoSelect2Containers, function(idx, value) {
196 $.each(repoSelect2Containers, function(idx, value) {
197 $(value).select2('container').width(maxWidth + 10);
197 $(value).select2('container').width(maxWidth + 10);
198 });
198 });
199 });
199 });
200 };
200 };
201
201
202 var initRefSelection = function(selectedRef) {
202 var initRefSelection = function(selectedRef) {
203 return function(element, callback) {
203 return function(element, callback) {
204 // translate our select2 id into a text, it's a mapping to show
204 // translate our select2 id into a text, it's a mapping to show
205 // simple label when selecting by internal ID.
205 // simple label when selecting by internal ID.
206 var id, refData;
206 var id, refData;
207 if (selectedRef === undefined || selectedRef === null) {
207 if (selectedRef === undefined || selectedRef === null) {
208 id = element.val();
208 id = element.val();
209 refData = element.val().split(':');
209 refData = element.val().split(':');
210
210
211 if (refData.length !== 3){
211 if (refData.length !== 3){
212 refData = ["", "", ""]
212 refData = ["", "", ""]
213 }
213 }
214 } else {
214 } else {
215 id = selectedRef;
215 id = selectedRef;
216 refData = selectedRef.split(':');
216 refData = selectedRef.split(':');
217 }
217 }
218
218
219 var text = refData[1];
219 var text = refData[1];
220 if (refData[0] === 'rev') {
220 if (refData[0] === 'rev') {
221 text = text.substring(0, 12);
221 text = text.substring(0, 12);
222 }
222 }
223
223
224 var data = {id: id, text: text};
224 var data = {id: id, text: text};
225 callback(data);
225 callback(data);
226 };
226 };
227 };
227 };
228
228
229 var formatRefSelection = function(item) {
229 var formatRefSelection = function(data, container, escapeMarkup) {
230 var prefix = '';
230 var prefix = '';
231 var refData = item.id.split(':');
231 var refData = data.id.split(':');
232 if (refData[0] === 'branch') {
232 if (refData[0] === 'branch') {
233 prefix = '<i class="icon-branch"></i>';
233 prefix = '<i class="icon-branch"></i>';
234 }
234 }
235 else if (refData[0] === 'book') {
235 else if (refData[0] === 'book') {
236 prefix = '<i class="icon-bookmark"></i>';
236 prefix = '<i class="icon-bookmark"></i>';
237 }
237 }
238 else if (refData[0] === 'tag') {
238 else if (refData[0] === 'tag') {
239 prefix = '<i class="icon-tag"></i>';
239 prefix = '<i class="icon-tag"></i>';
240 }
240 }
241
241
242 var originalOption = item.element;
242 var originalOption = data.element;
243 return prefix + item.text;
243 return prefix + escapeMarkup(data.text);
244 };
244 };formatSelection:
245
245
246 // custom code mirror
246 // custom code mirror
247 var codeMirrorInstance = $('#pullrequest_desc').get(0).MarkupForm.cm;
247 var codeMirrorInstance = $('#pullrequest_desc').get(0).MarkupForm.cm;
248
248
249 reviewersController = new ReviewersController();
249 reviewersController = new ReviewersController();
250
250
251 var queryTargetRepo = function(self, query) {
251 var queryTargetRepo = function(self, query) {
252 // cache ALL results if query is empty
252 // cache ALL results if query is empty
253 var cacheKey = query.term || '__';
253 var cacheKey = query.term || '__';
254 var cachedData = self.cachedDataSource[cacheKey];
254 var cachedData = self.cachedDataSource[cacheKey];
255
255
256 if (cachedData) {
256 if (cachedData) {
257 query.callback({results: cachedData.results});
257 query.callback({results: cachedData.results});
258 } else {
258 } else {
259 $.ajax({
259 $.ajax({
260 url: pyroutes.url('pullrequest_repo_destinations', {'repo_name': templateContext.repo_name}),
260 url: pyroutes.url('pullrequest_repo_destinations', {'repo_name': templateContext.repo_name}),
261 data: {query: query.term},
261 data: {query: query.term},
262 dataType: 'json',
262 dataType: 'json',
263 type: 'GET',
263 type: 'GET',
264 success: function(data) {
264 success: function(data) {
265 self.cachedDataSource[cacheKey] = data;
265 self.cachedDataSource[cacheKey] = data;
266 query.callback({results: data.results});
266 query.callback({results: data.results});
267 },
267 },
268 error: function(data, textStatus, errorThrown) {
268 error: function(data, textStatus, errorThrown) {
269 alert(
269 alert(
270 "Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
270 "Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
271 }
271 }
272 });
272 });
273 }
273 }
274 };
274 };
275
275
276 var queryTargetRefs = function(initialData, query) {
276 var queryTargetRefs = function(initialData, query) {
277 var data = {results: []};
277 var data = {results: []};
278 // filter initialData
278 // filter initialData
279 $.each(initialData, function() {
279 $.each(initialData, function() {
280 var section = this.text;
280 var section = this.text;
281 var children = [];
281 var children = [];
282 $.each(this.children, function() {
282 $.each(this.children, function() {
283 if (query.term.length === 0 ||
283 if (query.term.length === 0 ||
284 this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ) {
284 this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ) {
285 children.push({'id': this.id, 'text': this.text})
285 children.push({'id': this.id, 'text': this.text})
286 }
286 }
287 });
287 });
288 data.results.push({'text': section, 'children': children})
288 data.results.push({'text': section, 'children': children})
289 });
289 });
290 query.callback({results: data.results});
290 query.callback({results: data.results});
291 };
291 };
292
292
293 var loadRepoRefDiffPreview = function() {
293 var loadRepoRefDiffPreview = function() {
294
294
295 var url_data = {
295 var url_data = {
296 'repo_name': targetRepo(),
296 'repo_name': targetRepo(),
297 'target_repo': sourceRepo(),
297 'target_repo': sourceRepo(),
298 'source_ref': targetRef()[2],
298 'source_ref': targetRef()[2],
299 'source_ref_type': 'rev',
299 'source_ref_type': 'rev',
300 'target_ref': sourceRef()[2],
300 'target_ref': sourceRef()[2],
301 'target_ref_type': 'rev',
301 'target_ref_type': 'rev',
302 'merge': true,
302 'merge': true,
303 '_': Date.now() // bypass browser caching
303 '_': Date.now() // bypass browser caching
304 }; // gather the source/target ref and repo here
304 }; // gather the source/target ref and repo here
305
305
306 if (sourceRef().length !== 3 || targetRef().length !== 3) {
306 if (sourceRef().length !== 3 || targetRef().length !== 3) {
307 prButtonLock(true, "${_('Please select source and target')}");
307 prButtonLock(true, "${_('Please select source and target')}");
308 return;
308 return;
309 }
309 }
310 var url = pyroutes.url('repo_compare', url_data);
310 var url = pyroutes.url('repo_compare', url_data);
311
311
312 // lock PR button, so we cannot send PR before it's calculated
312 // lock PR button, so we cannot send PR before it's calculated
313 prButtonLock(true, "${_('Loading compare ...')}", 'compare');
313 prButtonLock(true, "${_('Loading compare ...')}", 'compare');
314
314
315 if (loadRepoRefDiffPreview._currentRequest) {
315 if (loadRepoRefDiffPreview._currentRequest) {
316 loadRepoRefDiffPreview._currentRequest.abort();
316 loadRepoRefDiffPreview._currentRequest.abort();
317 }
317 }
318
318
319 loadRepoRefDiffPreview._currentRequest = $.get(url)
319 loadRepoRefDiffPreview._currentRequest = $.get(url)
320 .error(function(data, textStatus, errorThrown) {
320 .error(function(data, textStatus, errorThrown) {
321 if (textStatus !== 'abort') {
321 if (textStatus !== 'abort') {
322 alert(
322 alert(
323 "Error while processing request.\nError code {0} ({1}).".format(
323 "Error while processing request.\nError code {0} ({1}).".format(
324 data.status, data.statusText));
324 data.status, data.statusText));
325 }
325 }
326
326
327 })
327 })
328 .done(function(data) {
328 .done(function(data) {
329 loadRepoRefDiffPreview._currentRequest = null;
329 loadRepoRefDiffPreview._currentRequest = null;
330 $('#pull_request_overview').html(data);
330 $('#pull_request_overview').html(data);
331
331
332 var commitElements = $(data).find('tr[commit_id]');
332 var commitElements = $(data).find('tr[commit_id]');
333
333
334 var prTitleAndDesc = getTitleAndDescription(
334 var prTitleAndDesc = getTitleAndDescription(
335 sourceRef()[1], commitElements, 5);
335 sourceRef()[1], commitElements, 5);
336
336
337 var title = prTitleAndDesc[0];
337 var title = prTitleAndDesc[0];
338 var proposedDescription = prTitleAndDesc[1];
338 var proposedDescription = prTitleAndDesc[1];
339
339
340 var useGeneratedTitle = (
340 var useGeneratedTitle = (
341 $('#pullrequest_title').hasClass('autogenerated-title') ||
341 $('#pullrequest_title').hasClass('autogenerated-title') ||
342 $('#pullrequest_title').val() === "");
342 $('#pullrequest_title').val() === "");
343
343
344 if (title && useGeneratedTitle) {
344 if (title && useGeneratedTitle) {
345 // use generated title if we haven't specified our own
345 // use generated title if we haven't specified our own
346 $('#pullrequest_title').val(title);
346 $('#pullrequest_title').val(title);
347 $('#pullrequest_title').addClass('autogenerated-title');
347 $('#pullrequest_title').addClass('autogenerated-title');
348
348
349 }
349 }
350
350
351 var useGeneratedDescription = (
351 var useGeneratedDescription = (
352 !codeMirrorInstance._userDefinedValue ||
352 !codeMirrorInstance._userDefinedValue ||
353 codeMirrorInstance.getValue() === "");
353 codeMirrorInstance.getValue() === "");
354
354
355 if (proposedDescription && useGeneratedDescription) {
355 if (proposedDescription && useGeneratedDescription) {
356 // set proposed content, if we haven't defined our own,
356 // set proposed content, if we haven't defined our own,
357 // or we don't have description written
357 // or we don't have description written
358 codeMirrorInstance._userDefinedValue = false; // reset state
358 codeMirrorInstance._userDefinedValue = false; // reset state
359 codeMirrorInstance.setValue(proposedDescription);
359 codeMirrorInstance.setValue(proposedDescription);
360 }
360 }
361
361
362 // refresh our codeMirror so events kicks in and it's change aware
362 // refresh our codeMirror so events kicks in and it's change aware
363 codeMirrorInstance.refresh();
363 codeMirrorInstance.refresh();
364
364
365 var msg = '';
365 var msg = '';
366 if (commitElements.length === 1) {
366 if (commitElements.length === 1) {
367 msg = "${_ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 1)}";
367 msg = "${_ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 1)}";
368 } else {
368 } else {
369 msg = "${_ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 2)}";
369 msg = "${_ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 2)}";
370 }
370 }
371
371
372 msg += ' <a id="pull_request_overview_url" href="{0}" target="_blank">${_('Show detailed compare.')}</a>'.format(url);
372 msg += ' <a id="pull_request_overview_url" href="{0}" target="_blank">${_('Show detailed compare.')}</a>'.format(url);
373
373
374 if (commitElements.length) {
374 if (commitElements.length) {
375 var commitsLink = '<a href="#pull_request_overview"><strong>{0}</strong></a>'.format(commitElements.length);
375 var commitsLink = '<a href="#pull_request_overview"><strong>{0}</strong></a>'.format(commitElements.length);
376 prButtonLock(false, msg.replace('__COMMITS__', commitsLink), 'compare');
376 prButtonLock(false, msg.replace('__COMMITS__', commitsLink), 'compare');
377 }
377 }
378 else {
378 else {
379 prButtonLock(true, "${_('There are no commits to merge.')}", 'compare');
379 prButtonLock(true, "${_('There are no commits to merge.')}", 'compare');
380 }
380 }
381
381
382
382
383 });
383 });
384 };
384 };
385
385
386 var Select2Box = function(element, overrides) {
386 var Select2Box = function(element, overrides) {
387 var globalDefaults = {
387 var globalDefaults = {
388 dropdownAutoWidth: true,
388 dropdownAutoWidth: true,
389 containerCssClass: "drop-menu",
389 containerCssClass: "drop-menu",
390 dropdownCssClass: "drop-menu-dropdown"
390 dropdownCssClass: "drop-menu-dropdown"
391 };
391 };
392
392
393 var initSelect2 = function(defaultOptions) {
393 var initSelect2 = function(defaultOptions) {
394 var options = jQuery.extend(globalDefaults, defaultOptions, overrides);
394 var options = jQuery.extend(globalDefaults, defaultOptions, overrides);
395 element.select2(options);
395 element.select2(options);
396 };
396 };
397
397
398 return {
398 return {
399 initRef: function() {
399 initRef: function() {
400 var defaultOptions = {
400 var defaultOptions = {
401 minimumResultsForSearch: 5,
401 minimumResultsForSearch: 5,
402 formatSelection: formatRefSelection
402 formatSelection: formatRefSelection
403 };
403 };
404
404
405 initSelect2(defaultOptions);
405 initSelect2(defaultOptions);
406 },
406 },
407
407
408 initRepo: function(defaultValue, readOnly) {
408 initRepo: function(defaultValue, readOnly) {
409 var defaultOptions = {
409 var defaultOptions = {
410 initSelection : function (element, callback) {
410 initSelection : function (element, callback) {
411 var data = {id: defaultValue, text: defaultValue};
411 var data = {id: defaultValue, text: defaultValue};
412 callback(data);
412 callback(data);
413 }
413 }
414 };
414 };
415
415
416 initSelect2(defaultOptions);
416 initSelect2(defaultOptions);
417
417
418 element.select2('val', defaultSourceRepo);
418 element.select2('val', defaultSourceRepo);
419 if (readOnly === true) {
419 if (readOnly === true) {
420 element.select2('readonly', true);
420 element.select2('readonly', true);
421 }
421 }
422 }
422 }
423 };
423 };
424 };
424 };
425
425
426 var initTargetRefs = function(refsData, selectedRef) {
426 var initTargetRefs = function(refsData, selectedRef) {
427
427
428 Select2Box($targetRef, {
428 Select2Box($targetRef, {
429 placeholder: "${_('Select commit reference')}",
429 placeholder: "${_('Select commit reference')}",
430 query: function(query) {
430 query: function(query) {
431 queryTargetRefs(refsData, query);
431 queryTargetRefs(refsData, query);
432 },
432 },
433 initSelection : initRefSelection(selectedRef)
433 initSelection : initRefSelection(selectedRef)
434 }).initRef();
434 }).initRef();
435
435
436 if (!(selectedRef === undefined)) {
436 if (!(selectedRef === undefined)) {
437 $targetRef.select2('val', selectedRef);
437 $targetRef.select2('val', selectedRef);
438 }
438 }
439 };
439 };
440
440
441 var targetRepoChanged = function(repoData) {
441 var targetRepoChanged = function(repoData) {
442 // generate new DESC of target repo displayed next to select
442 // generate new DESC of target repo displayed next to select
443 var prLink = pyroutes.url('pullrequest_new', {'repo_name': repoData['name']});
443 var prLink = pyroutes.url('pullrequest_new', {'repo_name': repoData['name']});
444 $('#target_repo_desc').html(
444 $('#target_repo_desc').html(
445 "<strong>${_('Target repository')}</strong>: {0}. <a href=\"{1}\">Switch base, and use as source.</a>".format(repoData['description'], prLink)
445 "<strong>${_('Target repository')}</strong>: {0}. <a href=\"{1}\">Switch base, and use as source.</a>".format(repoData['description'], prLink)
446 );
446 );
447
447
448 // generate dynamic select2 for refs.
448 // generate dynamic select2 for refs.
449 initTargetRefs(repoData['refs']['select2_refs'],
449 initTargetRefs(repoData['refs']['select2_refs'],
450 repoData['refs']['selected_ref']);
450 repoData['refs']['selected_ref']);
451
451
452 };
452 };
453
453
454 var sourceRefSelect2 = Select2Box($sourceRef, {
454 var sourceRefSelect2 = Select2Box($sourceRef, {
455 placeholder: "${_('Select commit reference')}",
455 placeholder: "${_('Select commit reference')}",
456 query: function(query) {
456 query: function(query) {
457 var initialData = defaultSourceRepoData['refs']['select2_refs'];
457 var initialData = defaultSourceRepoData['refs']['select2_refs'];
458 queryTargetRefs(initialData, query)
458 queryTargetRefs(initialData, query)
459 },
459 },
460 initSelection: initRefSelection()
460 initSelection: initRefSelection()
461 }
461 }
462 );
462 );
463
463
464 var sourceRepoSelect2 = Select2Box($sourceRepo, {
464 var sourceRepoSelect2 = Select2Box($sourceRepo, {
465 query: function(query) {}
465 query: function(query) {}
466 });
466 });
467
467
468 var targetRepoSelect2 = Select2Box($targetRepo, {
468 var targetRepoSelect2 = Select2Box($targetRepo, {
469 cachedDataSource: {},
469 cachedDataSource: {},
470 query: $.debounce(250, function(query) {
470 query: $.debounce(250, function(query) {
471 queryTargetRepo(this, query);
471 queryTargetRepo(this, query);
472 }),
472 }),
473 formatResult: formatRepoResult
473 formatResult: formatRepoResult
474 });
474 });
475
475
476 sourceRefSelect2.initRef();
476 sourceRefSelect2.initRef();
477
477
478 sourceRepoSelect2.initRepo(defaultSourceRepo, true);
478 sourceRepoSelect2.initRepo(defaultSourceRepo, true);
479
479
480 targetRepoSelect2.initRepo(defaultTargetRepo, false);
480 targetRepoSelect2.initRepo(defaultTargetRepo, false);
481
481
482 $sourceRef.on('change', function(e){
482 $sourceRef.on('change', function(e){
483 loadRepoRefDiffPreview();
483 loadRepoRefDiffPreview();
484 reviewersController.loadDefaultReviewers(
484 reviewersController.loadDefaultReviewers(
485 sourceRepo(), sourceRef(), targetRepo(), targetRef());
485 sourceRepo(), sourceRef(), targetRepo(), targetRef());
486 });
486 });
487
487
488 $targetRef.on('change', function(e){
488 $targetRef.on('change', function(e){
489 loadRepoRefDiffPreview();
489 loadRepoRefDiffPreview();
490 reviewersController.loadDefaultReviewers(
490 reviewersController.loadDefaultReviewers(
491 sourceRepo(), sourceRef(), targetRepo(), targetRef());
491 sourceRepo(), sourceRef(), targetRepo(), targetRef());
492 });
492 });
493
493
494 $targetRepo.on('change', function(e){
494 $targetRepo.on('change', function(e){
495 var repoName = $(this).val();
495 var repoName = $(this).val();
496 calculateContainerWidth();
496 calculateContainerWidth();
497 $targetRef.select2('destroy');
497 $targetRef.select2('destroy');
498 $('#target_ref_loading').show();
498 $('#target_ref_loading').show();
499
499
500 $.ajax({
500 $.ajax({
501 url: pyroutes.url('pullrequest_repo_refs',
501 url: pyroutes.url('pullrequest_repo_refs',
502 {'repo_name': templateContext.repo_name, 'target_repo_name':repoName}),
502 {'repo_name': templateContext.repo_name, 'target_repo_name':repoName}),
503 data: {},
503 data: {},
504 dataType: 'json',
504 dataType: 'json',
505 type: 'GET',
505 type: 'GET',
506 success: function(data) {
506 success: function(data) {
507 $('#target_ref_loading').hide();
507 $('#target_ref_loading').hide();
508 targetRepoChanged(data);
508 targetRepoChanged(data);
509 loadRepoRefDiffPreview();
509 loadRepoRefDiffPreview();
510 },
510 },
511 error: function(data, textStatus, errorThrown) {
511 error: function(data, textStatus, errorThrown) {
512 alert("Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
512 alert("Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
513 }
513 }
514 })
514 })
515
515
516 });
516 });
517
517
518 $pullRequestForm.on('submit', function(e){
518 $pullRequestForm.on('submit', function(e){
519 // Flush changes into textarea
519 // Flush changes into textarea
520 codeMirrorInstance.save();
520 codeMirrorInstance.save();
521 prButtonLock(true, null, 'all');
521 prButtonLock(true, null, 'all');
522 });
522 });
523
523
524 prButtonLock(true, "${_('Please select source and target')}", 'all');
524 prButtonLock(true, "${_('Please select source and target')}", 'all');
525
525
526 // auto-load on init, the target refs select2
526 // auto-load on init, the target refs select2
527 calculateContainerWidth();
527 calculateContainerWidth();
528 targetRepoChanged(defaultTargetRepoData);
528 targetRepoChanged(defaultTargetRepoData);
529
529
530 $('#pullrequest_title').on('keyup', function(e){
530 $('#pullrequest_title').on('keyup', function(e){
531 $(this).removeClass('autogenerated-title');
531 $(this).removeClass('autogenerated-title');
532 });
532 });
533
533
534 % if c.default_source_ref:
534 % if c.default_source_ref:
535 // in case we have a pre-selected value, use it now
535 // in case we have a pre-selected value, use it now
536 $sourceRef.select2('val', '${c.default_source_ref}');
536 $sourceRef.select2('val', '${c.default_source_ref}');
537 // diff preview load
537 // diff preview load
538 loadRepoRefDiffPreview();
538 loadRepoRefDiffPreview();
539 // default reviewers
539 // default reviewers
540 reviewersController.loadDefaultReviewers(
540 reviewersController.loadDefaultReviewers(
541 sourceRepo(), sourceRef(), targetRepo(), targetRef());
541 sourceRepo(), sourceRef(), targetRepo(), targetRef());
542 % endif
542 % endif
543
543
544 ReviewerAutoComplete('#user');
544 ReviewerAutoComplete('#user');
545 });
545 });
546 </script>
546 </script>
547
547
548 </%def>
548 </%def>
General Comments 0
You need to be logged in to leave comments. Login now