##// END OF EJS Templates
ui: added secondary action instead of two buttons on files page....
dan -
r4449:5be9b639 default
parent child Browse files
Show More
@@ -1,527 +1,527 b''
1 1
2 2
3 3 //BUTTONS
4 4 button,
5 5 .btn,
6 6 input[type="button"] {
7 7 -webkit-appearance: none;
8 8 display: inline-block;
9 9 margin: 0 @padding/3 0 0;
10 10 padding: @button-padding;
11 11 text-align: center;
12 12 font-size: @basefontsize;
13 13 line-height: 1em;
14 14 font-family: @text-light;
15 15 text-decoration: none;
16 16 text-shadow: none;
17 17 color: @grey2;
18 18 background-color: white;
19 19 background-image: none;
20 20 border: none;
21 21 .border ( @border-thickness-buttons, @grey5 );
22 22 .border-radius (@border-radius);
23 23 cursor: pointer;
24 24 white-space: nowrap;
25 25 -webkit-transition: background .3s,color .3s;
26 26 -moz-transition: background .3s,color .3s;
27 27 -o-transition: background .3s,color .3s;
28 28 transition: background .3s,color .3s;
29 29 box-shadow: @button-shadow;
30 30 -webkit-box-shadow: @button-shadow;
31 31
32 32
33 33
34 34 a {
35 35 display: block;
36 36 margin: 0;
37 37 padding: 0;
38 38 color: inherit;
39 39 text-decoration: none;
40 40
41 41 &:hover {
42 42 text-decoration: none;
43 43 }
44 44 }
45 45
46 46 &:focus,
47 47 &:active {
48 48 outline:none;
49 49 }
50 50
51 51 &:hover {
52 52 color: @rcdarkblue;
53 53 background-color: @grey6;
54 54
55 55 }
56 56
57 57 &.btn-active {
58 58 color: @rcdarkblue;
59 59 background-color: @grey6;
60 60 }
61 61
62 62 .icon-remove {
63 63 display: none;
64 64 }
65 65
66 66 //disabled buttons
67 67 //last; overrides any other styles
68 68 &:disabled {
69 69 opacity: .7;
70 70 cursor: auto;
71 71 background-color: white;
72 72 color: @grey4;
73 73 text-shadow: none;
74 74 }
75 75
76 76 &.no-margin {
77 77 margin: 0 0 0 0;
78 78 }
79 79
80 80
81 81
82 82 }
83 83
84 84
85 85 .btn-default {
86 86 border: @border-thickness solid @grey5;
87 87 background-image: none;
88 88 color: @grey2;
89 89
90 90 a {
91 91 color: @grey2;
92 92 }
93 93
94 94 &:hover,
95 95 &.active {
96 96 color: @rcdarkblue;
97 97 background-color: @white;
98 98 .border ( @border-thickness, @grey4 );
99 99
100 100 a {
101 101 color: @grey2;
102 102 }
103 103 }
104 104 &:disabled {
105 105 .border ( @border-thickness-buttons, @grey5 );
106 106 background-color: transparent;
107 107 }
108 108 &.btn-active {
109 109 color: @rcdarkblue;
110 110 background-color: @white;
111 111 .border ( @border-thickness, @rcdarkblue );
112 112 }
113 113 }
114 114
115 115 .btn-primary,
116 116 .btn-small, /* TODO: anderson: remove .btn-small to not mix with the new btn-sm */
117 117 .btn-success {
118 118 .border ( @border-thickness, @rcblue );
119 119 background-color: @rcblue;
120 120 color: white;
121 121
122 122 a {
123 123 color: white;
124 124 }
125 125
126 126 &:hover,
127 127 &.active {
128 128 .border ( @border-thickness, @rcdarkblue );
129 129 color: white;
130 130 background-color: @rcdarkblue;
131 131
132 132 a {
133 133 color: white;
134 134 }
135 135 }
136 136 &:disabled {
137 137 background-color: @rcblue;
138 138 }
139 139 }
140 140
141 141 .btn-secondary {
142 142 &:extend(.btn-default);
143 143
144 144 background-color: white;
145 145
146 146 &:focus {
147 147 outline: 0;
148 148 }
149 149
150 150 &:hover {
151 151 &:extend(.btn-default:hover);
152 152 }
153 153
154 154 &.btn-link {
155 155 &:extend(.btn-link);
156 156 color: @rcblue;
157 157 }
158 158
159 159 &:disabled {
160 160 color: @rcblue;
161 161 background-color: white;
162 162 }
163 163 }
164 164
165 165 .btn-warning,
166 166 .btn-danger,
167 167 .revoke_perm,
168 168 .btn-x,
169 169 .form .action_button.btn-x {
170 170 .border ( @border-thickness, @alert2 );
171 171 background-color: white;
172 172 color: @alert2;
173 173
174 174 a {
175 175 color: @alert2;
176 176 }
177 177
178 178 &:hover,
179 179 &.active {
180 180 .border ( @border-thickness, @alert2 );
181 181 color: white;
182 182 background-color: @alert2;
183 183
184 184 a {
185 185 color: white;
186 186 }
187 187 }
188 188
189 189 i {
190 190 display:none;
191 191 }
192 192
193 193 &:disabled {
194 194 background-color: white;
195 195 color: @alert2;
196 196 }
197 197 }
198 198
199 199 .btn-approved-status {
200 200 .border ( @border-thickness, @alert1 );
201 201 background-color: white;
202 202 color: @alert1;
203 203
204 204 }
205 205
206 206 .btn-rejected-status {
207 207 .border ( @border-thickness, @alert2 );
208 208 background-color: white;
209 209 color: @alert2;
210 210 }
211 211
212 212 .btn-sm,
213 213 .btn-mini,
214 214 .field-sm .btn {
215 215 padding: @padding/3;
216 216 }
217 217
218 218 .btn-xs {
219 219 padding: @padding/4;
220 220 }
221 221
222 222 .btn-lg {
223 223 padding: @padding * 1.2;
224 224 }
225 225
226 226 .btn-group {
227 227 display: inline-block;
228 228 .btn {
229 229 float: left;
230 230 margin: 0 0 0 0;
231 231 // first item
232 232 &:first-of-type:not(:last-of-type) {
233 233 border-radius: @border-radius 0 0 @border-radius;
234 234
235 235 }
236 236 // middle elements
237 237 &:not(:first-of-type):not(:last-of-type) {
238 238 border-radius: 0;
239 239 border-left-width: 0;
240 240 border-right-width: 0;
241 241 }
242 242 // last item
243 243 &:last-of-type:not(:first-of-type) {
244 244 border-radius: 0 @border-radius @border-radius 0;
245 245 }
246 246
247 247 &:only-child {
248 248 border-radius: @border-radius;
249 249 }
250 250 }
251 251
252 252 }
253 253
254 254
255 255 .btn-group-actions {
256 256 position: relative;
257 257 z-index: 100;
258 258
259 259 &:not(.open) .btn-action-switcher-container {
260 260 display: none;
261 261 }
262 262 }
263 263
264 264
265 265 .btn-action-switcher-container{
266 266 position: absolute;
267 top: 30px;
268 left: -82px;
267 top: 100%;
268 right: 0;
269 269 }
270 270
271 271 .btn-action-switcher {
272 272 display: block;
273 273 position: relative;
274 274 z-index: 300;
275 min-width: 240px;
276 max-width: 500px;
275 max-width: 600px;
277 276 margin-top: 4px;
278 277 margin-bottom: 24px;
279 278 font-size: 14px;
280 279 font-weight: 400;
281 280 padding: 8px 0;
282 281 background-color: #fff;
283 282 border: 1px solid @grey4;
284 283 border-radius: 3px;
285 284 box-shadow: @dropdown-shadow;
285 overflow: auto;
286 286
287 287 li {
288 288 display: block;
289 289 text-align: left;
290 290 list-style: none;
291 291 padding: 5px 10px;
292 292 }
293 293
294 294 li .action-help-block {
295 295 font-size: 10px;
296 296 line-height: normal;
297 297 color: @grey4;
298 298 }
299 299
300 300 }
301 301
302 302 .btn-link {
303 303 background: transparent;
304 304 border: none;
305 305 padding: 0;
306 306 color: @rcblue;
307 307
308 308 &:hover {
309 309 background: transparent;
310 310 border: none;
311 311 color: @rcdarkblue;
312 312 }
313 313
314 314 //disabled buttons
315 315 //last; overrides any other styles
316 316 &:disabled {
317 317 opacity: .7;
318 318 cursor: auto;
319 319 background-color: white;
320 320 color: @grey4;
321 321 text-shadow: none;
322 322 }
323 323
324 324 // TODO: johbo: Check if we can avoid this, indicates that the structure
325 325 // is not yet good.
326 326 // lisa: The button CSS reflects the button HTML; both need a cleanup.
327 327 &.btn-danger {
328 328 color: @alert2;
329 329
330 330 &:hover {
331 331 color: darken(@alert2,30%);
332 332 }
333 333
334 334 &:disabled {
335 335 color: @alert2;
336 336 }
337 337 }
338 338 }
339 339
340 340 .btn-social {
341 341 &:extend(.btn-default);
342 342 margin: 5px 5px 5px 0px;
343 343 min-width: 160px;
344 344 }
345 345
346 346 // TODO: johbo: check these exceptions
347 347
348 348 .links {
349 349
350 350 .btn + .btn {
351 351 margin-top: @padding;
352 352 }
353 353 }
354 354
355 355
356 356 .action_button {
357 357 display:inline;
358 358 margin: 0;
359 359 padding: 0 1em 0 0;
360 360 font-size: inherit;
361 361 color: @rcblue;
362 362 border: none;
363 363 border-radius: 0;
364 364 background-color: transparent;
365 365
366 366 &.last-item {
367 367 border: none;
368 368 padding: 0 0 0 0;
369 369 }
370 370
371 371 &:last-child {
372 372 border: none;
373 373 padding: 0 0 0 0;
374 374 }
375 375
376 376 &:hover {
377 377 color: @rcdarkblue;
378 378 background-color: transparent;
379 379 border: none;
380 380 }
381 381 .noselect
382 382 }
383 383
384 384 .grid_delete {
385 385 .action_button {
386 386 border: none;
387 387 }
388 388 }
389 389
390 390
391 391 // TODO: johbo: Form button tweaks, check if we can use the classes instead
392 392 input[type="submit"] {
393 393 &:extend(.btn-primary);
394 394
395 395 &:focus {
396 396 outline: 0;
397 397 }
398 398
399 399 &:hover {
400 400 &:extend(.btn-primary:hover);
401 401 }
402 402
403 403 &.btn-link {
404 404 &:extend(.btn-link);
405 405 color: @rcblue;
406 406
407 407 &:disabled {
408 408 color: @rcblue;
409 409 background-color: transparent;
410 410 }
411 411 }
412 412
413 413 &:disabled {
414 414 .border ( @border-thickness-buttons, @rcblue );
415 415 background-color: @rcblue;
416 416 color: white;
417 417 opacity: 0.5;
418 418 }
419 419 }
420 420
421 421 input[type="reset"] {
422 422 &:extend(.btn-default);
423 423
424 424 // TODO: johbo: Check if this tweak can be avoided.
425 425 background: transparent;
426 426
427 427 &:focus {
428 428 outline: 0;
429 429 }
430 430
431 431 &:hover {
432 432 &:extend(.btn-default:hover);
433 433 }
434 434
435 435 &.btn-link {
436 436 &:extend(.btn-link);
437 437 color: @rcblue;
438 438
439 439 &:disabled {
440 440 border: none;
441 441 }
442 442 }
443 443
444 444 &:disabled {
445 445 .border ( @border-thickness-buttons, @rcblue );
446 446 background-color: white;
447 447 color: @rcblue;
448 448 }
449 449 }
450 450
451 451 input[type="submit"],
452 452 input[type="reset"] {
453 453 &.btn-danger {
454 454 &:extend(.btn-danger);
455 455
456 456 &:focus {
457 457 outline: 0;
458 458 }
459 459
460 460 &:hover {
461 461 &:extend(.btn-danger:hover);
462 462 }
463 463
464 464 &.btn-link {
465 465 &:extend(.btn-link);
466 466 color: @alert2;
467 467
468 468 &:hover {
469 469 color: darken(@alert2,30%);
470 470 }
471 471 }
472 472
473 473 &:disabled {
474 474 color: @alert2;
475 475 background-color: white;
476 476 }
477 477 }
478 478 &.btn-danger-action {
479 479 .border ( @border-thickness, @alert2 );
480 480 background-color: @alert2;
481 481 color: white;
482 482
483 483 a {
484 484 color: white;
485 485 }
486 486
487 487 &:hover {
488 488 background-color: darken(@alert2,20%);
489 489 }
490 490
491 491 &.active {
492 492 .border ( @border-thickness, @alert2 );
493 493 color: white;
494 494 background-color: @alert2;
495 495
496 496 a {
497 497 color: white;
498 498 }
499 499 }
500 500
501 501 &:disabled {
502 502 background-color: white;
503 503 color: @alert2;
504 504 }
505 505 }
506 506 }
507 507
508 508
509 509 .button-links {
510 510 float: left;
511 511 display: inline;
512 512 margin: 0;
513 513 padding-left: 0;
514 514 list-style: none;
515 515 text-align: right;
516 516
517 517 li {
518 518
519 519
520 520 }
521 521
522 522 li.active {
523 523 background-color: @grey6;
524 524 .border ( @border-thickness, @grey4 );
525 525 }
526 526
527 527 }
@@ -1,84 +1,100 b''
1 1
2 2 <div id="codeblock" class="browserblock">
3 3 <div class="browser-header">
4 4 <div class="browser-nav">
5 5
6 6 <div class="info_box">
7 7
8 8 <div class="info_box_elem previous">
9 9 <a id="prev_commit_link" data-commit-id="${c.prev_commit.raw_id}" class=" ${('disabled' if c.url_prev == '#' else '')}" href="${c.url_prev}" title="${_('Previous commit')}"><i class="icon-left"></i></a>
10 10 </div>
11 11
12 12 ${h.hidden('refs_filter')}
13 13
14 14 <div class="info_box_elem next">
15 15 <a id="next_commit_link" data-commit-id="${c.next_commit.raw_id}" class=" ${('disabled' if c.url_next == '#' else '')}" href="${c.url_next}" title="${_('Next commit')}"><i class="icon-right"></i></a>
16 16 </div>
17 17 </div>
18 18
19 19 % if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
20 <div>
21 <a class="btn btn-primary new-file" href="${h.route_path('repo_files_upload_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
22 ${_('Upload File')}
23 </a>
24 <a class="btn btn-primary new-file" href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
25 ${_('Add File')}
26 </a>
27 </div>
20
21 <div class="new-file">
22 <div class="btn-group btn-group-actions">
23 <a class="btn btn-primary no-margin" href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
24 ${_('Add File')}
25 </a>
26
27 <a class="tooltip btn btn-primary" style="margin-left: -1px" data-toggle="dropdown" aria-pressed="false" role="button" title="${_('more options')}">
28 <i class="icon-down"></i>
29 </a>
30
31 <div class="btn-action-switcher-container">
32 <ul class="btn-action-switcher" role="menu" style="min-width: 200px">
33 <li>
34 <a class="action_button" href="${h.route_path('repo_files_upload_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}">
35 <i class="icon-upload"></i>
36 ${_('Upload File')}
37 </a>
38 </li>
39 </ul>
40 </div>
41 </div>
42 </div>
43
28 44 % endif
29 45
30 46 % if c.enable_downloads:
31 47 <% at_path = '{}'.format(request.GET.get('at') or c.commit.raw_id[:6]) %>
32 48 <div class="btn btn-default new-file">
33 49 % if c.f_path == '/':
34 50 <a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id))}">
35 51 ${_('Download full tree ZIP')}
36 52 </a>
37 53 % else:
38 54 <a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id), _query={'at_path':c.f_path})}">
39 55 ${_('Download this tree ZIP')}
40 56 </a>
41 57 % endif
42 58 </div>
43 59 % endif
44 60
45 61 <div class="files-quick-filter">
46 62 <ul class="files-filter-box">
47 63 <li class="files-filter-box-path">
48 64 <i class="icon-search"></i>
49 65 </li>
50 66 <li class="files-filter-box-input">
51 67 <input onkeydown="NodeFilter.initFilter(event)" class="init" type="text" placeholder="Quick filter" name="filter" size="25" id="node_filter" autocomplete="off">
52 68 </li>
53 69 </ul>
54 70 </div>
55 71 </div>
56 72
57 73 </div>
58 74
59 75 ## file tree is computed from caches, and filled in
60 76 <div id="file-tree">
61 77 ${c.file_tree |n}
62 78 </div>
63 79
64 80 %if c.readme_data:
65 81 <div id="readme" class="anchor">
66 82 <div class="box">
67 83 <div class="readme-title" title="${h.tooltip(_('Readme file from commit %s:%s') % (c.rhodecode_db_repo.landing_ref_type, c.rhodecode_db_repo.landing_ref_name))}">
68 84 <div>
69 85 <i class="icon-file-text"></i>
70 86 <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.landing_ref_name,f_path=c.readme_file)}">
71 87 ${c.readme_file}
72 88 </a>
73 89 </div>
74 90 </div>
75 91 <div class="readme codeblock">
76 92 <div class="readme_box">
77 93 ${c.readme_data|n}
78 94 </div>
79 95 </div>
80 96 </div>
81 97 </div>
82 98 %endif
83 99
84 100 </div>
@@ -1,211 +1,211 b''
1 1 <%inherit file="/base/base.mako"/>
2 2
3 3 <%def name="title()">
4 4 ${_('{} Files Upload').format(c.repo_name)}
5 5 %if c.rhodecode_name:
6 6 &middot; ${h.branding(c.rhodecode_name)}
7 7 %endif
8 8 </%def>
9 9
10 10 <%def name="menu_bar_nav()">
11 11 ${self.menu_items(active='repositories')}
12 12 </%def>
13 13
14 14 <%def name="breadcrumbs_links()"></%def>
15 15
16 16 <%def name="menu_bar_subnav()">
17 17 ${self.repo_menu(active='files')}
18 18 </%def>
19 19
20 20 <%def name="main()">
21 21
22 22 <div class="box">
23 23 ## Template for uploads
24 24 <div style="display: none" id="tpl-dropzone">
25 25 <div class="dz-preview dz-file-preview">
26 26 <div class="dz-details">
27 27
28 28 <div class="dz-filename">
29 29 <span data-dz-name></span>
30 30 </div>
31 31 <div class="dz-filename-size">
32 32 <span class="dz-size" data-dz-size></span>
33 33
34 34 </div>
35 35
36 36 <div class="dz-sending" style="display: none">${_('Uploading...')}</div>
37 37 <div class="dz-response" style="display: none">
38 38 ${_('Uploaded')} 100%
39 39 </div>
40 40
41 41 </div>
42 42 <div class="dz-progress">
43 43 <span class="dz-upload" data-dz-uploadprogress></span>
44 44 </div>
45 45
46 46 <div class="dz-error-message">
47 47 </div>
48 48 </div>
49 49 </div>
50 50
51 51 <div class="edit-file-title">
52 52 <span class="title-heading">${_('Upload new file')} @ <code>${h.show_id(c.commit)}</code></span>
53 53 % if c.commit.branch:
54 54 <span class="tag branchtag">
55 55 <i class="icon-branch"></i> ${c.commit.branch}
56 56 </span>
57 57 % endif
58 58 </div>
59 59
60 60 <% form_url = h.route_path('repo_files_upload_file', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path) %>
61 61 ##${h.secure_form(form_url, id='eform', enctype="multipart/form-data", request=request)}
62 62 <div class="edit-file-fieldset">
63 63 <div class="path-items">
64 <ul>
64 <ul class="tooltip" title="Repository path to store uploaded files. To change it, navigate to different path and click upload from there.">
65 65 <li class="breadcrumb-path">
66 66 <div>
67 67 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path='')}"><i class="icon-home"></i></a> /
68 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path)}">${c.f_path}</a> ${('/' if c.f_path else '')}
68 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path)}">${c.f_path}</a>${('/' if c.f_path else '')}
69 69 </div>
70 70 </li>
71 71 <li class="location-path">
72 72
73 73 </li>
74 74 </ul>
75 75 </div>
76 76
77 77 </div>
78 78
79 79 <div class="upload-form table">
80 80 <div>
81 81
82 <div class="dropzone-wrapper" id="file-uploader">
82 <div class="dropzone-wrapper" id="file-uploader" style="border: none; padding: 40px 0">
83 83 <div class="dropzone-pure">
84 84 <div class="dz-message">
85 85 <i class="icon-upload" style="font-size:36px"></i></br>
86 86 ${_("Drag'n Drop files here or")} <span class="link">${_('Choose your files')}</span>.<br>
87 87 </div>
88 88 </div>
89 89
90 90 </div>
91 91 </div>
92 92
93 93 </div>
94 94
95 95 <div class="upload-form edit-file-fieldset">
96 96 <div class="fieldset">
97 97 <div class="message">
98 98 <textarea id="commit" name="message" placeholder="${c.default_message}"></textarea>
99 99 </div>
100 100 </div>
101 101 <div class="pull-left">
102 102 ${h.submit('commit_btn',_('Commit changes'), class_="btn btn-small btn-success")}
103 103 </div>
104 104 </div>
105 105 ##${h.end_form()}
106 106
107 107 <div class="file-upload-transaction-wrapper" style="display: none">
108 108 <div class="file-upload-transaction">
109 109 <h3>${_('Committing...')}</h3>
110 110 <p>${_('Please wait while the files are being uploaded')}</p>
111 111 <p class="error" style="display: none">
112 112
113 113 </p>
114 114 <i class="icon-spin animate-spin"></i>
115 115 <p></p>
116 116 </div>
117 117 </div>
118 118
119 119 </div>
120 120
121 121 <script type="text/javascript">
122 122
123 123 $(document).ready(function () {
124 124
125 125 //see: https://www.dropzonejs.com/#configuration
126 126 myDropzone = new Dropzone("div#file-uploader", {
127 127 url: "${form_url}",
128 128 headers: {"X-CSRF-Token": CSRF_TOKEN},
129 129 paramName: function () {
130 130 return "files_upload"
131 131 }, // The name that will be used to transfer the file
132 132 parallelUploads: 20,
133 133 maxFiles: 20,
134 134 uploadMultiple: true,
135 135 //chunking: true, // use chunking transfer, not supported at the moment
136 136 //maxFilesize: 2, // in MBs
137 137 autoProcessQueue: false, // if false queue will not be processed automatically.
138 138 createImageThumbnails: false,
139 139 previewTemplate: document.querySelector('#tpl-dropzone').innerHTML,
140 140 accept: function (file, done) {
141 141 done();
142 142 },
143 143 init: function () {
144 144 this.on("addedfile", function (file) {
145 145
146 146 });
147 147
148 148 this.on("sending", function (file, xhr, formData) {
149 149 formData.append("message", $('#commit').val());
150 150 $(file.previewElement).find('.dz-sending').show();
151 151 });
152 152
153 153 this.on("success", function (file, response) {
154 154 $(file.previewElement).find('.dz-sending').hide();
155 155 $(file.previewElement).find('.dz-response').show();
156 156
157 157 if (response.error !== null) {
158 158 $('.file-upload-transaction-wrapper .error').html('ERROR: {0}'.format(response.error));
159 159 $('.file-upload-transaction-wrapper .error').show();
160 160 $('.file-upload-transaction-wrapper i').hide()
161 161 }
162 162
163 163 var redirect_url = response.redirect_url || '/';
164 164 window.location = redirect_url
165 165
166 166 });
167 167
168 168 this.on("error", function (file, errorMessage, xhr) {
169 169 var error = null;
170 170
171 171 if (xhr !== undefined){
172 172 var httpStatus = xhr.status + " " + xhr.statusText;
173 173 if (xhr !== undefined && xhr.status >= 500) {
174 174 error = httpStatus;
175 175 }
176 176 }
177 177
178 178 if (error === null) {
179 179 error = errorMessage.error || errorMessage || httpStatus;
180 180 }
181 181
182 182 $(file.previewElement).find('.dz-error-message').html('ERROR: {0}'.format(error));
183 183 });
184 184 }
185 185 });
186 186
187 187 $('#commit_btn').on('click', function(e) {
188 188 e.preventDefault();
189 189 var button = $(this);
190 190 if (button.hasClass('clicked')) {
191 191 button.attr('disabled', true);
192 192 } else {
193 193 button.addClass('clicked');
194 194 }
195 195
196 196 var files = myDropzone.getQueuedFiles();
197 197 if (files.length === 0) {
198 198 alert("Missing files");
199 199 e.preventDefault();
200 200 }
201 201
202 202 $('.upload-form').hide();
203 203 $('.file-upload-transaction-wrapper').show();
204 204 myDropzone.processQueue();
205 205
206 206 });
207 207
208 208 });
209 209
210 210 </script>
211 211 </%def>
@@ -1,921 +1,921 b''
1 1 <%inherit file="/base/base.mako"/>
2 2 <%namespace name="base" file="/base/base.mako"/>
3 3 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
4 4
5 5 <%def name="title()">
6 6 ${_('{} Pull Request !{}').format(c.repo_name, c.pull_request.pull_request_id)}
7 7 %if c.rhodecode_name:
8 8 &middot; ${h.branding(c.rhodecode_name)}
9 9 %endif
10 10 </%def>
11 11
12 12 <%def name="breadcrumbs_links()">
13 13
14 14 </%def>
15 15
16 16 <%def name="menu_bar_nav()">
17 17 ${self.menu_items(active='repositories')}
18 18 </%def>
19 19
20 20 <%def name="menu_bar_subnav()">
21 21 ${self.repo_menu(active='showpullrequest')}
22 22 </%def>
23 23
24 24 <%def name="main()">
25 25
26 26 <script type="text/javascript">
27 27 // TODO: marcink switch this to pyroutes
28 28 AJAX_COMMENT_DELETE_URL = "${h.route_path('pullrequest_comment_delete',repo_name=c.repo_name,pull_request_id=c.pull_request.pull_request_id,comment_id='__COMMENT_ID__')}";
29 29 templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
30 30 </script>
31 31
32 32 <div class="box">
33 33
34 34 <div class="box pr-summary">
35 35
36 36 <div class="summary-details block-left">
37 37 <div id="pr-title">
38 38 % if c.pull_request.is_closed():
39 39 <span class="pr-title-closed-tag tag">${_('Closed')}</span>
40 40 % endif
41 41 <input class="pr-title-input large disabled" disabled="disabled" name="pullrequest_title" type="text" value="${c.pull_request.title}">
42 42 </div>
43 43 <div id="pr-title-edit" class="input" style="display: none;">
44 44 <input class="pr-title-input large" id="pr-title-input" name="pullrequest_title" type="text" value="${c.pull_request.title}">
45 45 </div>
46 46
47 47 <% summary = lambda n:{False:'summary-short'}.get(n) %>
48 48 <div class="pr-details-title">
49 49 <div class="pull-left">
50 50 <a href="${h.route_path('pull_requests_global', pull_request_id=c.pull_request.pull_request_id)}">${_('Pull request !{}').format(c.pull_request.pull_request_id)}</a>
51 51 ${_('Created on')}
52 52 <span class="tooltip" title="${_('Last updated on')} ${h.format_date(c.pull_request.updated_on)}">${h.format_date(c.pull_request.created_on)},</span>
53 53 <span class="pr-details-title-author-pref">${_('by')}</span>
54 54 </div>
55 55
56 56 <div class="pull-left">
57 57 ${self.gravatar_with_user(c.pull_request.author.email, 16, tooltip=True)}
58 58 </div>
59 59
60 60 %if c.allowed_to_update:
61 61 <div class="pull-right">
62 62 <div id="edit_pull_request" class="action_button pr-save" style="display: none;">${_('Update title & description')}</div>
63 63 <div id="delete_pullrequest" class="action_button pr-save ${('' if c.allowed_to_delete else 'disabled' )}" style="display: none;">
64 64 % if c.allowed_to_delete:
65 65 ${h.secure_form(h.route_path('pullrequest_delete', repo_name=c.pull_request.target_repo.repo_name, pull_request_id=c.pull_request.pull_request_id), request=request)}
66 66 <input class="btn btn-link btn-danger no-margin" id="remove_${c.pull_request.pull_request_id}" name="remove_${c.pull_request.pull_request_id}"
67 67 onclick="submitConfirm(event, this, _gettext('Confirm to delete this pull request'), _gettext('Delete'), '${'!{}'.format(c.pull_request.pull_request_id)}')"
68 68 type="submit" value="${_('Delete pull request')}">
69 69 ${h.end_form()}
70 70 % else:
71 71 <span class="tooltip" title="${_('Not allowed to delete this pull request')}">${_('Delete pull request')}</span>
72 72 % endif
73 73 </div>
74 74 <div id="open_edit_pullrequest" class="action_button">${_('Edit')}</div>
75 75 <div id="close_edit_pullrequest" class="action_button" style="display: none;">${_('Cancel')}</div>
76 76 </div>
77 77
78 78 %endif
79 79 </div>
80 80
81 81 <div id="pr-desc" class="input" title="${_('Rendered using {} renderer').format(c.renderer)}">
82 82 ${h.render(c.pull_request.description, renderer=c.renderer, repo_name=c.repo_name)}
83 83 </div>
84 84
85 85 <div id="pr-desc-edit" class="input textarea" style="display: none;">
86 86 <input id="pr-renderer-input" type="hidden" name="description_renderer" value="${c.visual.default_renderer}">
87 87 ${dt.markup_form('pr-description-input', form_text=c.pull_request.description)}
88 88 </div>
89 89
90 90 <div id="summary" class="fields pr-details-content">
91 91
92 92 ## review
93 93 <div class="field">
94 94 <div class="label-pr-detail">
95 95 <label>${_('Review status')}:</label>
96 96 </div>
97 97 <div class="input">
98 98 %if c.pull_request_review_status:
99 99 <div class="tag status-tag-${c.pull_request_review_status}">
100 100 <i class="icon-circle review-status-${c.pull_request_review_status}"></i>
101 101 <span class="changeset-status-lbl">
102 102 %if c.pull_request.is_closed():
103 103 ${_('Closed')},
104 104 %endif
105 105
106 106 ${h.commit_status_lbl(c.pull_request_review_status)}
107 107
108 108 </span>
109 109 </div>
110 110 - ${_ungettext('calculated based on {} reviewer vote', 'calculated based on {} reviewers votes', len(c.pull_request_reviewers)).format(len(c.pull_request_reviewers))}
111 111 %endif
112 112 </div>
113 113 </div>
114 114
115 115 ## source
116 116 <div class="field">
117 117 <div class="label-pr-detail">
118 118 <label>${_('Commit flow')}:</label>
119 119 </div>
120 120 <div class="input">
121 121 <div class="pr-commit-flow">
122 122 ## Source
123 123 %if c.pull_request.source_ref_parts.type == 'branch':
124 124 <a href="${h.route_path('repo_commits', repo_name=c.pull_request.source_repo.repo_name, _query=dict(branch=c.pull_request.source_ref_parts.name))}"><code class="pr-source-info">${c.pull_request.source_ref_parts.type}:${c.pull_request.source_ref_parts.name}</code></a>
125 125 %else:
126 126 <code class="pr-source-info">${'{}:{}'.format(c.pull_request.source_ref_parts.type, c.pull_request.source_ref_parts.name)}</code>
127 127 %endif
128 128 ${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.repo_name}</a>
129 129 &rarr;
130 130 ## Target
131 131 %if c.pull_request.target_ref_parts.type == 'branch':
132 132 <a href="${h.route_path('repo_commits', repo_name=c.pull_request.target_repo.repo_name, _query=dict(branch=c.pull_request.target_ref_parts.name))}"><code class="pr-target-info">${c.pull_request.target_ref_parts.type}:${c.pull_request.target_ref_parts.name}</code></a>
133 133 %else:
134 134 <code class="pr-target-info">${'{}:{}'.format(c.pull_request.target_ref_parts.type, c.pull_request.target_ref_parts.name)}</code>
135 135 %endif
136 136
137 137 ${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.repo_name}</a>
138 138
139 139 <a class="source-details-action" href="#expand-source-details" onclick="return versionController.toggleElement(this, '.source-details')" data-toggle-on='<i class="icon-angle-down">more details</i>' data-toggle-off='<i class="icon-angle-up">less details</i>'>
140 140 <i class="icon-angle-down">more details</i>
141 141 </a>
142 142
143 143 </div>
144 144
145 145 <div class="source-details" style="display: none">
146 146
147 147 <ul>
148 148
149 149 ## common ancestor
150 150 <li>
151 151 ${_('Common ancestor')}:
152 152 % if c.ancestor_commit:
153 153 <a href="${h.route_path('repo_commit', repo_name=c.target_repo.repo_name, commit_id=c.ancestor_commit.raw_id)}">${h.show_id(c.ancestor_commit)}</a>
154 154 % else:
155 155 ${_('not available')}
156 156 % endif
157 157 </li>
158 158
159 159 ## pull url
160 160 <li>
161 161 %if h.is_hg(c.pull_request.source_repo):
162 162 <% clone_url = 'hg pull -r {} {}'.format(h.short_id(c.source_ref), c.pull_request.source_repo.clone_url()) %>
163 163 %elif h.is_git(c.pull_request.source_repo):
164 164 <% clone_url = 'git pull {} {}'.format(c.pull_request.source_repo.clone_url(), c.pull_request.source_ref_parts.name) %>
165 165 %endif
166 166
167 167 <span>${_('Pull changes from source')}</span>: <input type="text" class="input-monospace pr-pullinfo" value="${clone_url}" readonly="readonly">
168 168 <i class="tooltip icon-clipboard clipboard-action pull-right pr-pullinfo-copy" data-clipboard-text="${clone_url}" title="${_('Copy the pull url')}"></i>
169 169 </li>
170 170
171 171 ## Shadow repo
172 172 <li>
173 173 % if not c.pull_request.is_closed() and c.pull_request.shadow_merge_ref:
174 174 %if h.is_hg(c.pull_request.target_repo):
175 175 <% clone_url = 'hg clone --update {} {} pull-request-{}'.format(c.pull_request.shadow_merge_ref.name, c.shadow_clone_url, c.pull_request.pull_request_id) %>
176 176 %elif h.is_git(c.pull_request.target_repo):
177 177 <% clone_url = 'git clone --branch {} {} pull-request-{}'.format(c.pull_request.shadow_merge_ref.name, c.shadow_clone_url, c.pull_request.pull_request_id) %>
178 178 %endif
179 179
180 180 <span class="tooltip" title="${_('Clone repository in its merged state using shadow repository')}">${_('Clone from shadow repository')}</span>: <input type="text" class="input-monospace pr-mergeinfo" value="${clone_url}" readonly="readonly">
181 181 <i class="tooltip icon-clipboard clipboard-action pull-right pr-mergeinfo-copy" data-clipboard-text="${clone_url}" title="${_('Copy the clone url')}"></i>
182 182
183 183 % else:
184 184 <div class="">
185 185 ${_('Shadow repository data not available')}.
186 186 </div>
187 187 % endif
188 188 </li>
189 189
190 190 </ul>
191 191
192 192 </div>
193 193
194 194 </div>
195 195
196 196 </div>
197 197
198 198 ## versions
199 199 <div class="field">
200 200 <div class="label-pr-detail">
201 201 <label>${_('Versions')}:</label>
202 202 </div>
203 203
204 204 <% outdated_comm_count_ver = len(c.inline_versions[None]['outdated']) %>
205 205 <% general_outdated_comm_count_ver = len(c.comment_versions[None]['outdated']) %>
206 206
207 207 <div class="pr-versions">
208 208 % if c.show_version_changes:
209 209 <% outdated_comm_count_ver = len(c.inline_versions[c.at_version_num]['outdated']) %>
210 210 <% general_outdated_comm_count_ver = len(c.comment_versions[c.at_version_num]['outdated']) %>
211 211 ${_ungettext('{} version available for this pull request, ', '{} versions available for this pull request, ', len(c.versions)).format(len(c.versions))}
212 212 <a id="show-pr-versions" onclick="return versionController.toggleVersionView(this)" href="#show-pr-versions"
213 213 data-toggle-on="${_('show versions')}."
214 214 data-toggle-off="${_('hide versions')}.">
215 215 ${_('show versions')}.
216 216 </a>
217 217 <table>
218 218 ## SHOW ALL VERSIONS OF PR
219 219 <% ver_pr = None %>
220 220
221 221 % for data in reversed(list(enumerate(c.versions, 1))):
222 222 <% ver_pos = data[0] %>
223 223 <% ver = data[1] %>
224 224 <% ver_pr = ver.pull_request_version_id %>
225 225 <% display_row = '' if c.at_version and (c.at_version_num == ver_pr or c.from_version_num == ver_pr) else 'none' %>
226 226
227 227 <tr class="version-pr" style="display: ${display_row}">
228 228 <td>
229 229 <code>
230 230 <a href="${request.current_route_path(_query=dict(version=ver_pr or 'latest'))}">v${ver_pos}</a>
231 231 </code>
232 232 </td>
233 233 <td>
234 234 <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}"/>
235 235 <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}"/>
236 236 </td>
237 237 <td>
238 238 <% review_status = c.review_versions[ver_pr].status if ver_pr in c.review_versions else 'not_reviewed' %>
239 239 <i class="tooltip icon-circle review-status-${review_status}" title="${_('Your review status at this version')}"></i>
240 240
241 241 </td>
242 242 <td>
243 243 % if c.at_version_num != ver_pr:
244 244 <i class="tooltip icon-comment" title="${_('Comments from pull request version v{0}').format(ver_pos)}"></i>
245 245 <code>
246 246 General:${len(c.comment_versions[ver_pr]['at'])} / Inline:${len(c.inline_versions[ver_pr]['at'])}
247 247 </code>
248 248 % endif
249 249 </td>
250 250 <td>
251 251 ##<code>${ver.source_ref_parts.commit_id[:6]}</code>
252 252 </td>
253 253 <td>
254 254 <code>${h.age_component(ver.updated_on, time_is_local=True, tooltip=False)}</code>
255 255 </td>
256 256 </tr>
257 257 % endfor
258 258
259 259 <tr>
260 260 <td colspan="6">
261 261 <button id="show-version-diff" onclick="return versionController.showVersionDiff()" class="btn btn-sm" style="display: none"
262 262 data-label-text-locked="${_('select versions to show changes')}"
263 263 data-label-text-diff="${_('show changes between versions')}"
264 264 data-label-text-show="${_('show pull request for this version')}"
265 265 >
266 266 ${_('select versions to show changes')}
267 267 </button>
268 268 </td>
269 269 </tr>
270 270 </table>
271 271 % else:
272 272 <div>
273 273 ${_('Pull request versions not available')}.
274 274 </div>
275 275 % endif
276 276 </div>
277 277 </div>
278 278
279 279 </div>
280 280
281 281 </div>
282 282
283 283 ## REVIEW RULES
284 284 <div id="review_rules" style="display: none" class="reviewers-title block-right">
285 285 <div class="pr-details-title">
286 286 ${_('Reviewer rules')}
287 287 %if c.allowed_to_update:
288 288 <span id="close_edit_reviewers" class="block-right action_button last-item" style="display: none;">${_('Close')}</span>
289 289 %endif
290 290 </div>
291 291 <div class="pr-reviewer-rules">
292 292 ## review rules will be appended here, by default reviewers logic
293 293 </div>
294 294 <input id="review_data" type="hidden" name="review_data" value="">
295 295 </div>
296 296
297 297 ## REVIEWERS
298 298 <div class="reviewers-title first-panel block-right">
299 299 <div class="pr-details-title">
300 300 ${_('Pull request reviewers')}
301 301 %if c.allowed_to_update:
302 302 <span id="open_edit_reviewers" class="block-right action_button last-item">${_('Edit')}</span>
303 303 %endif
304 304 </div>
305 305 </div>
306 306 <div id="reviewers" class="block-right pr-details-content reviewers">
307 307
308 308 ## members redering block
309 309 <input type="hidden" name="__start__" value="review_members:sequence">
310 310 <ul id="review_members" class="group_members">
311 311
312 312 % for review_obj, member, reasons, mandatory, status in c.pull_request_reviewers:
313 313 <script>
314 314 var member = ${h.json.dumps(h.reviewer_as_json(member, reasons=reasons, mandatory=mandatory, user_group=review_obj.rule_user_group_data()))|n};
315 315 var status = "${(status[0][1].status if status else 'not_reviewed')}";
316 316 var status_lbl = "${h.commit_status_lbl(status[0][1].status if status else 'not_reviewed')}";
317 317 var allowed_to_update = ${h.json.dumps(c.allowed_to_update)};
318 318
319 319 var entry = renderTemplate('reviewMemberEntry', {
320 320 'member': member,
321 321 'mandatory': member.mandatory,
322 322 'reasons': member.reasons,
323 323 'allowed_to_update': allowed_to_update,
324 324 'review_status': status,
325 325 'review_status_label': status_lbl,
326 326 'user_group': member.user_group,
327 327 'create': false
328 328 });
329 329 $('#review_members').append(entry)
330 330 </script>
331 331
332 332 % endfor
333 333
334 334 </ul>
335 335
336 336 <input type="hidden" name="__end__" value="review_members:sequence">
337 337 ## end members redering block
338 338
339 339 %if not c.pull_request.is_closed():
340 340 <div id="add_reviewer" class="ac" style="display: none;">
341 341 %if c.allowed_to_update:
342 342 % if not c.forbid_adding_reviewers:
343 343 <div id="add_reviewer_input" class="reviewer_ac">
344 344 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))}
345 345 <div id="reviewers_container"></div>
346 346 </div>
347 347 % endif
348 348 <div class="pull-right">
349 349 <button id="update_pull_request" class="btn btn-small no-margin">${_('Save Changes')}</button>
350 350 </div>
351 351 %endif
352 352 </div>
353 353 %endif
354 354 </div>
355 355
356 356 ## TODOs will be listed here
357 357 <div class="reviewers-title block-right">
358 358 <div class="pr-details-title">
359 359 ## Only show unresolved, that is only what matters
360 360 TODO Comments - ${len(c.unresolved_comments)} / ${(len(c.unresolved_comments) + len(c.resolved_comments))}
361 361
362 362 % if not c.at_version:
363 363 % if c.resolved_comments:
364 364 <span class="block-right action_button last-item noselect" onclick="$('.unresolved-todo-text').toggle(); return versionController.toggleElement(this, '.unresolved-todo');" data-toggle-on="Show resolved" data-toggle-off="Hide resolved">Show resolved</span>
365 365 % else:
366 366 <span class="block-right last-item noselect">Show resolved</span>
367 367 % endif
368 368 % endif
369 369 </div>
370 370 </div>
371 371 <div class="block-right pr-details-content reviewers">
372 372
373 373 <table class="todo-table">
374 374 <%
375 375 def sorter(entry):
376 376 user_id = entry.author.user_id
377 377 resolved = '1' if entry.resolved else '0'
378 378 if user_id == c.rhodecode_user.user_id:
379 379 # own comments first
380 380 user_id = 0
381 381 return '{}_{}_{}'.format(resolved, user_id, str(entry.comment_id).zfill(100))
382 382 %>
383 383
384 384 % if c.at_version:
385 385 <tr>
386 386 <td class="unresolved-todo-text">${_('unresolved TODOs unavailable in this view')}.</td>
387 387 </tr>
388 388 % else:
389 389 % for todo_comment in sorted(c.unresolved_comments + c.resolved_comments, key=sorter):
390 390 <% resolved = todo_comment.resolved %>
391 391 % if inline:
392 392 <% outdated_at_ver = todo_comment.outdated_at_version(getattr(c, 'at_version_num', None)) %>
393 393 % else:
394 394 <% outdated_at_ver = todo_comment.older_than_version(getattr(c, 'at_version_num', None)) %>
395 395 % endif
396 396
397 397 <tr ${('class="unresolved-todo" style="display: none"' if resolved else '') |n}>
398 398
399 399 <td class="td-todo-number">
400 400 % if resolved:
401 401 <a class="permalink todo-resolved tooltip" title="${_('Resolved by comment #{}').format(todo_comment.resolved.comment_id)}" href="#comment-${todo_comment.comment_id}" onclick="return Rhodecode.comments.scrollToComment($('#comment-${todo_comment.comment_id}'), 0, ${h.json.dumps(outdated_at_ver)})">
402 402 <i class="icon-flag-filled"></i> ${todo_comment.comment_id}</a>
403 403 % else:
404 404 <a class="permalink" href="#comment-${todo_comment.comment_id}" onclick="return Rhodecode.comments.scrollToComment($('#comment-${todo_comment.comment_id}'), 0, ${h.json.dumps(outdated_at_ver)})">
405 405 <i class="icon-flag-filled"></i> ${todo_comment.comment_id}</a>
406 406 % endif
407 407 </td>
408 408 <td class="td-todo-gravatar">
409 409 ${base.gravatar(todo_comment.author.email, 16, user=todo_comment.author, tooltip=True, extra_class=['no-margin'])}
410 410 </td>
411 411 <td class="todo-comment-text-wrapper">
412 412 <div class="todo-comment-text">
413 413 <code>${h.chop_at_smart(todo_comment.text, '\n', suffix_if_chopped='...')}</code>
414 414 </div>
415 415 </td>
416 416
417 417 </tr>
418 418 % endfor
419 419
420 420 % if len(c.unresolved_comments) == 0:
421 421 <tr>
422 422 <td class="unresolved-todo-text">${_('No unresolved TODOs')}.</td>
423 423 </tr>
424 424 % endif
425 425
426 426 % endif
427 427
428 428 </table>
429 429
430 430 </div>
431 431 </div>
432 432
433 433 </div>
434 434
435 435 <div class="box">
436 436
437 437 % if c.state_progressing:
438 438
439 439 <h2 style="text-align: center">
440 440 ${_('Cannot show diff when pull request state is changing. Current progress state')}: <span class="tag tag-merge-state-${c.pull_request.state}">${c.pull_request.state}</span>
441 441
442 442 % if c.is_super_admin:
443 443 <br/>
444 444 If you think this is an error try <a href="${h.current_route_path(request, force_state='created')}">forced state reset</a> to <span class="tag tag-merge-state-created">created</span> state.
445 445 % endif
446 446 </h2>
447 447
448 448 % else:
449 449
450 450 ## Diffs rendered here
451 451 <div class="table" >
452 452 <div id="changeset_compare_view_content">
453 453 ##CS
454 454 % if c.missing_requirements:
455 455 <div class="box">
456 456 <div class="alert alert-warning">
457 457 <div>
458 458 <strong>${_('Missing requirements:')}</strong>
459 459 ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')}
460 460 </div>
461 461 </div>
462 462 </div>
463 463 % elif c.missing_commits:
464 464 <div class="box">
465 465 <div class="alert alert-warning">
466 466 <div>
467 467 <strong>${_('Missing commits')}:</strong>
468 468 ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')}
469 469 ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')}
470 470 ${_('Consider doing a {force_refresh_url} in case you think this is an error.').format(force_refresh_url=h.link_to('force refresh', h.current_route_path(request, force_refresh='1')))|n}
471 471 </div>
472 472 </div>
473 473 </div>
474 474 % elif c.pr_merge_source_commit.changed and not c.pull_request.is_closed():
475 475 <div class="box">
476 476 <div class="alert alert-info">
477 477 <div>
478 478 <strong>${_('There are new changes for `{}:{}` in source repository, please consider updating this pull request.').format(c.pr_merge_source_commit.ref_spec.type, c.pr_merge_source_commit.ref_spec.name)}</strong>
479 479 </div>
480 480 </div>
481 481 </div>
482 482 % endif
483 483
484 484 <div class="compare_view_commits_title">
485 485 % if not c.compare_mode:
486 486
487 487 % if c.at_version_pos:
488 488 <h4>
489 489 ${_('Showing changes at v%d, commenting is disabled.') % c.at_version_pos}
490 490 </h4>
491 491 % endif
492 492
493 493 <div class="pull-left">
494 494 <div class="btn-group">
495 495 <a class="${('collapsed' if c.collapse_all_commits else '')}" href="#expand-commits" onclick="toggleCommitExpand(this); return false" data-toggle-commits-cnt=${len(c.commit_ranges)} >
496 496 % if c.collapse_all_commits:
497 497 <i class="icon-plus-squared-alt icon-no-margin"></i>
498 498 ${_ungettext('Expand {} commit', 'Expand {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))}
499 499 % else:
500 500 <i class="icon-minus-squared-alt icon-no-margin"></i>
501 501 ${_ungettext('Collapse {} commit', 'Collapse {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))}
502 502 % endif
503 503 </a>
504 504 </div>
505 505 </div>
506 506
507 507 <div class="pull-right">
508 508 % if c.allowed_to_update and not c.pull_request.is_closed():
509 509
510 510 <div class="btn-group btn-group-actions">
511 511 <a id="update_commits" class="btn btn-primary no-margin" onclick="updateController.updateCommits(this); return false">
512 512 ${_('Update commits')}
513 513 </a>
514 514
515 515 <a id="update_commits_switcher" class="tooltip btn btn-primary" style="margin-left: -1px" data-toggle="dropdown" aria-pressed="false" role="button" title="${_('more update options')}">
516 516 <i class="icon-down"></i>
517 517 </a>
518 518
519 519 <div class="btn-action-switcher-container" id="update-commits-switcher">
520 <ul class="btn-action-switcher" role="menu">
520 <ul class="btn-action-switcher" role="menu" style="min-width: 300px;">
521 521 <li>
522 522 <a href="#forceUpdate" onclick="updateController.forceUpdateCommits(this); return false">
523 523 ${_('Force update commits')}
524 524 </a>
525 525 <div class="action-help-block">
526 526 ${_('Update commits and force refresh this pull request.')}
527 527 </div>
528 528 </li>
529 529 </ul>
530 530 </div>
531 531 </div>
532 532
533 533 % else:
534 534 <a class="tooltip btn disabled pull-right" disabled="disabled" title="${_('Update is disabled for current view')}">${_('Update commits')}</a>
535 535 % endif
536 536
537 537 </div>
538 538 % endif
539 539 </div>
540 540
541 541 % if not c.missing_commits:
542 542 % if c.compare_mode:
543 543 % if c.at_version:
544 544 <h4>
545 545 ${_('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')}:
546 546 </h4>
547 547
548 548 <div class="subtitle-compare">
549 549 ${_('commits added: {}, removed: {}').format(len(c.commit_changes_summary.added), len(c.commit_changes_summary.removed))}
550 550 </div>
551 551
552 552 <div class="container">
553 553 <table class="rctable compare_view_commits">
554 554 <tr>
555 555 <th></th>
556 556 <th>${_('Time')}</th>
557 557 <th>${_('Author')}</th>
558 558 <th>${_('Commit')}</th>
559 559 <th></th>
560 560 <th>${_('Description')}</th>
561 561 </tr>
562 562
563 563 % for c_type, commit in c.commit_changes:
564 564 % if c_type in ['a', 'r']:
565 565 <%
566 566 if c_type == 'a':
567 567 cc_title = _('Commit added in displayed changes')
568 568 elif c_type == 'r':
569 569 cc_title = _('Commit removed in displayed changes')
570 570 else:
571 571 cc_title = ''
572 572 %>
573 573 <tr id="row-${commit.raw_id}" commit_id="${commit.raw_id}" class="compare_select">
574 574 <td>
575 575 <div class="commit-change-indicator color-${c_type}-border">
576 576 <div class="commit-change-content color-${c_type} tooltip" title="${h.tooltip(cc_title)}">
577 577 ${c_type.upper()}
578 578 </div>
579 579 </div>
580 580 </td>
581 581 <td class="td-time">
582 582 ${h.age_component(commit.date)}
583 583 </td>
584 584 <td class="td-user">
585 585 ${base.gravatar_with_user(commit.author, 16, tooltip=True)}
586 586 </td>
587 587 <td class="td-hash">
588 588 <code>
589 589 <a href="${h.route_path('repo_commit', repo_name=c.target_repo.repo_name, commit_id=commit.raw_id)}">
590 590 r${commit.idx}:${h.short_id(commit.raw_id)}
591 591 </a>
592 592 ${h.hidden('revisions', commit.raw_id)}
593 593 </code>
594 594 </td>
595 595 <td class="td-message expand_commit" data-commit-id="${commit.raw_id}" title="${_( 'Expand commit message')}" onclick="commitsController.expandCommit(this); return false">
596 596 <i class="icon-expand-linked"></i>
597 597 </td>
598 598 <td class="mid td-description">
599 599 <div class="log-container truncate-wrap">
600 600 <div class="message truncate" id="c-${commit.raw_id}" data-message-raw="${commit.message}">${h.urlify_commit_message(commit.message, c.repo_name)}</div>
601 601 </div>
602 602 </td>
603 603 </tr>
604 604 % endif
605 605 % endfor
606 606 </table>
607 607 </div>
608 608
609 609 % endif
610 610
611 611 % else:
612 612 <%include file="/compare/compare_commits.mako" />
613 613 % endif
614 614
615 615 <div class="cs_files">
616 616 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
617 617 % if c.at_version:
618 618 <% c.inline_cnt = len(c.inline_versions[c.at_version_num]['display']) %>
619 619 <% c.comments = c.comment_versions[c.at_version_num]['display'] %>
620 620 % else:
621 621 <% c.inline_cnt = len(c.inline_versions[c.at_version_num]['until']) %>
622 622 <% c.comments = c.comment_versions[c.at_version_num]['until'] %>
623 623 % endif
624 624
625 625 <%
626 626 pr_menu_data = {
627 627 'outdated_comm_count_ver': outdated_comm_count_ver,
628 628 'pull_request': c.pull_request
629 629 }
630 630 %>
631 631
632 632 ${cbdiffs.render_diffset_menu(c.diffset, range_diff_on=c.range_diff_on, pull_request_menu=pr_menu_data)}
633 633
634 634 % if c.range_diff_on:
635 635 % for commit in c.commit_ranges:
636 636 ${cbdiffs.render_diffset(
637 637 c.changes[commit.raw_id],
638 638 commit=commit, use_comments=True,
639 639 collapse_when_files_over=5,
640 640 disable_new_comments=True,
641 641 deleted_files_comments=c.deleted_files_comments,
642 642 inline_comments=c.inline_comments,
643 643 pull_request_menu=pr_menu_data, show_todos=False)}
644 644 % endfor
645 645 % else:
646 646 ${cbdiffs.render_diffset(
647 647 c.diffset, use_comments=True,
648 648 collapse_when_files_over=30,
649 649 disable_new_comments=not c.allowed_to_comment,
650 650 deleted_files_comments=c.deleted_files_comments,
651 651 inline_comments=c.inline_comments,
652 652 pull_request_menu=pr_menu_data, show_todos=False)}
653 653 % endif
654 654
655 655 </div>
656 656 % else:
657 657 ## skipping commits we need to clear the view for missing commits
658 658 <div style="clear:both;"></div>
659 659 % endif
660 660
661 661 </div>
662 662 </div>
663 663
664 664 ## template for inline comment form
665 665 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
666 666
667 667 ## comments heading with count
668 668 <div class="comments-heading">
669 669 <i class="icon-comment"></i>
670 670 ${_('Comments')} ${len(c.comments)}
671 671 </div>
672 672
673 673 ## render general comments
674 674 <div id="comment-tr-show">
675 675 % if general_outdated_comm_count_ver:
676 676 <div class="info-box">
677 677 % if general_outdated_comm_count_ver == 1:
678 678 ${_('there is {num} general comment from older versions').format(num=general_outdated_comm_count_ver)},
679 679 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show it')}</a>
680 680 % else:
681 681 ${_('there are {num} general comments from older versions').format(num=general_outdated_comm_count_ver)},
682 682 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show them')}</a>
683 683 % endif
684 684 </div>
685 685 % endif
686 686 </div>
687 687
688 688 ${comment.generate_comments(c.comments, include_pull_request=True, is_pull_request=True)}
689 689
690 690 % if not c.pull_request.is_closed():
691 691 ## main comment form and it status
692 692 ${comment.comments(h.route_path('pullrequest_comment_create', repo_name=c.repo_name,
693 693 pull_request_id=c.pull_request.pull_request_id),
694 694 c.pull_request_review_status,
695 695 is_pull_request=True, change_status=c.allowed_to_change_status)}
696 696
697 697 ## merge status, and merge action
698 698 <div class="pull-request-merge">
699 699 <%include file="/pullrequests/pullrequest_merge_checks.mako"/>
700 700 </div>
701 701
702 702 %endif
703 703
704 704 % endif
705 705 </div>
706 706
707 707 <script type="text/javascript">
708 708
709 709 versionController = new VersionController();
710 710 versionController.init();
711 711
712 712 reviewersController = new ReviewersController();
713 713 commitsController = new CommitsController();
714 714
715 715 updateController = new UpdatePrController();
716 716
717 717 $(function () {
718 718
719 719 // custom code mirror
720 720 var codeMirrorInstance = $('#pr-description-input').get(0).MarkupForm.cm;
721 721
722 722 var PRDetails = {
723 723 editButton: $('#open_edit_pullrequest'),
724 724 closeButton: $('#close_edit_pullrequest'),
725 725 deleteButton: $('#delete_pullrequest'),
726 726 viewFields: $('#pr-desc, #pr-title'),
727 727 editFields: $('#pr-desc-edit, #pr-title-edit, .pr-save'),
728 728
729 729 init: function () {
730 730 var that = this;
731 731 this.editButton.on('click', function (e) {
732 732 that.edit();
733 733 });
734 734 this.closeButton.on('click', function (e) {
735 735 that.view();
736 736 });
737 737 },
738 738
739 739 edit: function (event) {
740 740 this.viewFields.hide();
741 741 this.editButton.hide();
742 742 this.deleteButton.hide();
743 743 this.closeButton.show();
744 744 this.editFields.show();
745 745 codeMirrorInstance.refresh();
746 746 },
747 747
748 748 view: function (event) {
749 749 this.editButton.show();
750 750 this.deleteButton.show();
751 751 this.editFields.hide();
752 752 this.closeButton.hide();
753 753 this.viewFields.show();
754 754 }
755 755 };
756 756
757 757 var ReviewersPanel = {
758 758 editButton: $('#open_edit_reviewers'),
759 759 closeButton: $('#close_edit_reviewers'),
760 760 addButton: $('#add_reviewer'),
761 761 removeButtons: $('.reviewer_member_remove,.reviewer_member_mandatory_remove'),
762 762
763 763 init: function () {
764 764 var self = this;
765 765 this.editButton.on('click', function (e) {
766 766 self.edit();
767 767 });
768 768 this.closeButton.on('click', function (e) {
769 769 self.close();
770 770 });
771 771 },
772 772
773 773 edit: function (event) {
774 774 this.editButton.hide();
775 775 this.closeButton.show();
776 776 this.addButton.show();
777 777 this.removeButtons.css('visibility', 'visible');
778 778 // review rules
779 779 reviewersController.loadReviewRules(
780 780 ${c.pull_request.reviewer_data_json | n});
781 781 },
782 782
783 783 close: function (event) {
784 784 this.editButton.show();
785 785 this.closeButton.hide();
786 786 this.addButton.hide();
787 787 this.removeButtons.css('visibility', 'hidden');
788 788 // hide review rules
789 789 reviewersController.hideReviewRules()
790 790 }
791 791 };
792 792
793 793 PRDetails.init();
794 794 ReviewersPanel.init();
795 795
796 796 showOutdated = function (self) {
797 797 $('.comment-inline.comment-outdated').show();
798 798 $('.filediff-outdated').show();
799 799 $('.showOutdatedComments').hide();
800 800 $('.hideOutdatedComments').show();
801 801 };
802 802
803 803 hideOutdated = function (self) {
804 804 $('.comment-inline.comment-outdated').hide();
805 805 $('.filediff-outdated').hide();
806 806 $('.hideOutdatedComments').hide();
807 807 $('.showOutdatedComments').show();
808 808 };
809 809
810 810 refreshMergeChecks = function () {
811 811 var loadUrl = "${request.current_route_path(_query=dict(merge_checks=1))}";
812 812 $('.pull-request-merge').css('opacity', 0.3);
813 813 $('.action-buttons-extra').css('opacity', 0.3);
814 814
815 815 $('.pull-request-merge').load(
816 816 loadUrl, function () {
817 817 $('.pull-request-merge').css('opacity', 1);
818 818
819 819 $('.action-buttons-extra').css('opacity', 1);
820 820 }
821 821 );
822 822 };
823 823
824 824 closePullRequest = function (status) {
825 825 if (!confirm(_gettext('Are you sure to close this pull request without merging?'))) {
826 826 return false;
827 827 }
828 828 // inject closing flag
829 829 $('.action-buttons-extra').append('<input type="hidden" class="close-pr-input" id="close_pull_request" value="1">');
830 830 $(generalCommentForm.statusChange).select2("val", status).trigger('change');
831 831 $(generalCommentForm.submitForm).submit();
832 832 };
833 833
834 834 $('#show-outdated-comments').on('click', function (e) {
835 835 var button = $(this);
836 836 var outdated = $('.comment-outdated');
837 837
838 838 if (button.html() === "(Show)") {
839 839 button.html("(Hide)");
840 840 outdated.show();
841 841 } else {
842 842 button.html("(Show)");
843 843 outdated.hide();
844 844 }
845 845 });
846 846
847 847 $('.show-inline-comments').on('change', function (e) {
848 848 var show = 'none';
849 849 var target = e.currentTarget;
850 850 if (target.checked) {
851 851 show = ''
852 852 }
853 853 var boxid = $(target).attr('id_for');
854 854 var comments = $('#{0} .inline-comments'.format(boxid));
855 855 var fn_display = function (idx) {
856 856 $(this).css('display', show);
857 857 };
858 858 $(comments).each(fn_display);
859 859 var btns = $('#{0} .inline-comments-button'.format(boxid));
860 860 $(btns).each(fn_display);
861 861 });
862 862
863 863 $('#merge_pull_request_form').submit(function () {
864 864 if (!$('#merge_pull_request').attr('disabled')) {
865 865 $('#merge_pull_request').attr('disabled', 'disabled');
866 866 }
867 867 return true;
868 868 });
869 869
870 870 $('#edit_pull_request').on('click', function (e) {
871 871 var title = $('#pr-title-input').val();
872 872 var description = codeMirrorInstance.getValue();
873 873 var renderer = $('#pr-renderer-input').val();
874 874 editPullRequest(
875 875 "${c.repo_name}", "${c.pull_request.pull_request_id}",
876 876 title, description, renderer);
877 877 });
878 878
879 879 $('#update_pull_request').on('click', function (e) {
880 880 $(this).attr('disabled', 'disabled');
881 881 $(this).addClass('disabled');
882 882 $(this).html(_gettext('Saving...'));
883 883 reviewersController.updateReviewers(
884 884 "${c.repo_name}", "${c.pull_request.pull_request_id}");
885 885 });
886 886
887 887
888 888 // fixing issue with caches on firefox
889 889 $('#update_commits').removeAttr("disabled");
890 890
891 891 $('.show-inline-comments').on('click', function (e) {
892 892 var boxid = $(this).attr('data-comment-id');
893 893 var button = $(this);
894 894
895 895 if (button.hasClass("comments-visible")) {
896 896 $('#{0} .inline-comments'.format(boxid)).each(function (index) {
897 897 $(this).hide();
898 898 });
899 899 button.removeClass("comments-visible");
900 900 } else {
901 901 $('#{0} .inline-comments'.format(boxid)).each(function (index) {
902 902 $(this).show();
903 903 });
904 904 button.addClass("comments-visible");
905 905 }
906 906 });
907 907
908 908 // register submit callback on commentForm form to track TODOs
909 909 window.commentFormGlobalSubmitSuccessCallback = function () {
910 910 refreshMergeChecks();
911 911 };
912 912
913 913 ReviewerAutoComplete('#user');
914 914
915 915 })
916 916
917 917 </script>
918 918
919 919 </div>
920 920
921 921 </%def>
General Comments 0
You need to be logged in to leave comments. Login now