##// END OF EJS Templates
ui: added search icon and spinner when search is performing.
marcink -
r4095:e030f9fa default
parent child Browse files
Show More
@@ -1,822 +1,825 b''
1 1 // navigation.less
2 2 // For use in RhodeCode applications;
3 3 // see style guide documentation for guidelines.
4 4
5 5 // TOP MAIN DARK NAVIGATION
6 6
7 7 .header .main_nav.horizontal-list {
8 8 float: right;
9 9 color: @grey4;
10 10 > li {
11 11 a {
12 12 color: @grey4;
13 13 }
14 14 }
15 15 }
16 16
17 17 // HEADER NAVIGATION
18 18
19 19 .horizontal-list {
20 20 display: block;
21 21 margin: 0;
22 22 padding: 0;
23 23 -webkit-padding-start: 0;
24 24 text-align: left;
25 25 font-size: @navigation-fontsize;
26 26 color: @grey6;
27 27 z-index:10;
28 28
29 29 li {
30 30 line-height: 1em;
31 31 list-style-type: none;
32 32 margin: 0 20px 0 0;
33 33
34 34 a {
35 35 padding: 0 .5em;
36 36
37 37 &.menu_link_notifications {
38 38 .pill(7px,@rcblue);
39 39 display: inline;
40 40 margin: 0 7px 0 .7em;
41 41 font-size: @basefontsize;
42 42 color: white;
43 43
44 44 &.empty {
45 45 background-color: @grey4;
46 46 }
47 47
48 48 &:hover {
49 49 background-color: @rcdarkblue;
50 50 }
51 51 }
52 52 }
53 53 .pill_container {
54 54 margin: 1.25em 0px 0px 0px;
55 55 float: right;
56 56 }
57 57
58 58 &#quick_login_li {
59 59 &:hover {
60 60 color: @grey5;
61 61 }
62 62
63 63 a.menu_link_notifications {
64 64 color: white;
65 65 }
66 66
67 67 .user {
68 68 padding-bottom: 10px;
69 69 }
70 70 }
71 71
72 72 &:before { content: none; }
73 73
74 74 &:last-child {
75 75 .menulabel {
76 76 padding-right: 0;
77 77 border-right: none;
78 78
79 79 .show_more {
80 80 padding-right: 0;
81 81 }
82 82 }
83 83
84 84 &> a {
85 85 border-bottom: none;
86 86 }
87 87 }
88 88
89 89 &.open {
90 90
91 91 a {
92 92 color: white;
93 93 }
94 94 }
95 95
96 96 &:focus {
97 97 outline: none;
98 98 }
99 99
100 100 ul li {
101 101 display: block;
102 102
103 103 &:last-child> a {
104 104 border-bottom: none;
105 105 }
106 106
107 107 ul li:last-child a {
108 108 /* we don't expect more then 3 levels of submenu and the third
109 109 level can have different html structure */
110 110 border-bottom: none;
111 111 }
112 112 }
113 113 }
114 114
115 115 > li {
116 116 float: left;
117 117 display: block;
118 118 padding: 0;
119 119
120 120 > a,
121 121 &.has_select2 a {
122 122 display: block;
123 123 padding: 10px 0;
124 124 }
125 125
126 126 .menulabel {
127 127 line-height: 1em;
128 128 // for this specifically we do not use a variable
129 129 }
130 130
131 131 .menulink-counter {
132 132 border: 1px solid @grey2;
133 133 border-radius: @border-radius;
134 134 background: @grey7;
135 135 display: inline-block;
136 136 padding: 0px 4px;
137 137 text-align: center;
138 138 font-size: 12px;
139 139 }
140 140
141 141 .pr_notifications {
142 142 padding-left: .5em;
143 143 }
144 144
145 145 .pr_notifications + .menulabel {
146 146 display:inline;
147 147 padding-left: 0;
148 148 }
149 149
150 150 &:hover,
151 151 &.open,
152 152 &.active {
153 153 a {
154 154 color: @rcblue;
155 155 }
156 156 }
157 157 }
158 158
159 159 pre {
160 160 margin: 0;
161 161 padding: 0;
162 162 }
163 163
164 164 .select2-container,
165 165 .menulink.childs {
166 166 position: relative;
167 167 }
168 168
169 169 .menulink {
170 170 &.disabled {
171 171 color: @grey3;
172 172 cursor: default;
173 173 opacity: 0.5;
174 174 }
175 175 }
176 176
177 177 #quick_login {
178 178
179 179 li a {
180 180 padding: .5em 0;
181 181 border-bottom: none;
182 182 color: @grey2;
183 183
184 184 &:hover { color: @rcblue; }
185 185 }
186 186 }
187 187
188 188 #quick_login_link {
189 189 display: inline-block;
190 190
191 191 .gravatar {
192 192 border: 1px solid @grey5;
193 193 }
194 194
195 195 .gravatar-login {
196 196 height: 20px;
197 197 width: 20px;
198 198 margin: -8px 0;
199 199 padding: 0;
200 200 }
201 201
202 202 &:hover .user {
203 203 color: @grey6;
204 204 }
205 205 }
206 206 }
207 207 .header .horizontal-list {
208 208
209 209 li {
210 210
211 211 &#quick_login_li {
212 212 padding-left: .5em;
213 213 margin-right: 0px;
214 214
215 215 &:hover #quick_login_link {
216 216 color: inherit;
217 217 }
218 218
219 219 .menu_link_user {
220 220 padding: 0 2px;
221 221 }
222 222 }
223 223 list-style-type: none;
224 224 }
225 225
226 226 > li {
227 227
228 228 a {
229 229 padding: 18px 0 12px 0;
230 230 color: @nav-grey;
231 231
232 232 &.menu_link_notifications {
233 233 padding: 1px 8px;
234 234 }
235 235 }
236 236
237 237 &:hover,
238 238 &.open,
239 239 &.active {
240 240 .pill_container a {
241 241 // don't select text for the pill container, it has it' own
242 242 // hover behaviour
243 243 color: @nav-grey;
244 244 }
245 245 }
246 246
247 247 &:hover,
248 248 &.open,
249 249 &.active {
250 250 a {
251 251 color: @grey6;
252 252 }
253 253 }
254 254
255 255 .select2-dropdown-open a {
256 256 color: @grey6;
257 257 }
258 258
259 259 .repo-switcher {
260 260 padding-left: 0;
261 261
262 262 .menulabel {
263 263 padding-left: 0;
264 264 }
265 265 }
266 266 }
267 267
268 268 li ul li {
269 269 background-color:@grey2;
270 270
271 271 a {
272 272 padding: .5em 0;
273 273 border-bottom: @border-thickness solid @border-default-color;
274 274 color: @grey6;
275 275 }
276 276
277 277 &:last-child a, &.last a{
278 278 border-bottom: none;
279 279 }
280 280
281 281 &:hover {
282 282 background-color: @grey3;
283 283 }
284 284 }
285 285
286 286 .submenu {
287 287 margin-top: 5px;
288 288 }
289 289 }
290 290
291 291 // SUBMENUS
292 292 .navigation .submenu {
293 293 display: none;
294 294 }
295 295
296 296 .navigation li.open {
297 297 .submenu {
298 298 display: block;
299 299 }
300 300 }
301 301
302 302 .navigation li:last-child .submenu {
303 303 right: auto;
304 304 left: 0;
305 305 border: 1px solid @grey5;
306 306 background: @white;
307 307 box-shadow: @dropdown-shadow;
308 308 }
309 309
310 310 .submenu {
311 311 position: absolute;
312 312 top: 100%;
313 313 left: 0;
314 314 min-width: 180px;
315 315 margin: 2px 0 0;
316 316 padding: 0;
317 317 text-align: left;
318 318 font-family: @text-light;
319 319 border-radius: @border-radius;
320 320 z-index: 20;
321 321
322 322 li {
323 323 display: block;
324 324 margin: 0;
325 325 padding: 0 .5em;
326 326 line-height: 1em;
327 327 color: @grey3;
328 328 background-color: @white;
329 329 list-style-type: none;
330 330
331 331 a {
332 332 display: block;
333 333 width: 100%;
334 334 padding: .5em 0;
335 335 border-right: none;
336 336 border-bottom: @border-thickness solid white;
337 337 color: @grey3;
338 338 }
339 339
340 340 ul {
341 341 display: none;
342 342 position: absolute;
343 343 top: 0;
344 344 right: 100%;
345 345 padding: 0;
346 346 z-index: 30;
347 347 }
348 348 &:hover {
349 349 background-color: @grey7;
350 350 -webkit-transition: background .3s;
351 351 -moz-transition: background .3s;
352 352 -o-transition: background .3s;
353 353 transition: background .3s;
354 354
355 355 ul {
356 356 display: block;
357 357 }
358 358 }
359 359 }
360 360
361 361 }
362 362
363 363
364 364
365 365
366 366 // repo dropdown
367 367 .quick_repo_menu {
368 368 width: 15px;
369 369 text-align: center;
370 370 position: relative;
371 371 cursor: pointer;
372 372
373 373 div {
374 374 overflow: visible !important;
375 375 }
376 376
377 377 &.sorting {
378 378 cursor: auto;
379 379 }
380 380
381 381 &:hover {
382 382 .menu_items_container {
383 383 position: absolute;
384 384 display: block;
385 385 }
386 386 .menu_items {
387 387 display: block;
388 388 }
389 389 }
390 390
391 391 i {
392 392 margin: 0;
393 393 color: @grey4;
394 394 }
395 395
396 396 .menu_items_container {
397 397 position: absolute;
398 398 top: 0;
399 399 left: 100%;
400 400 margin: 0;
401 401 padding: 0;
402 402 list-style: none;
403 403 background-color: @grey6;
404 404 z-index: 999;
405 405 text-align: left;
406 406
407 407 a {
408 408 color: @grey2;
409 409 }
410 410
411 411 ul.menu_items {
412 412 margin: 0;
413 413 padding: 0;
414 414 }
415 415
416 416 li {
417 417 margin: 0;
418 418 padding: 0;
419 419 line-height: 1em;
420 420 list-style-type: none;
421 421
422 422 a {
423 423 display: block;
424 424 height: 16px;
425 425 padding: 8px; //must add up to td height (28px)
426 426 width: 120px; // set width
427 427
428 428 &:hover {
429 429 background-color: @grey5;
430 430 -webkit-transition: background .3s;
431 431 -moz-transition: background .3s;
432 432 -o-transition: background .3s;
433 433 transition: background .3s;
434 434 }
435 435 }
436 436 }
437 437 }
438 438 }
439 439
440 440
441 441 // new objects main action
442 442 .action-menu {
443 443 left: auto;
444 444 right: 0;
445 445 padding: 12px;
446 446 z-index: 999;
447 447 overflow: hidden;
448 448 background-color: #fff;
449 449 border: 1px solid @grey5;
450 450 color: @grey2;
451 451 box-shadow: @dropdown-shadow;
452 452
453 453 .submenu-title {
454 454 font-weight: bold;
455 455 }
456 456
457 457 .submenu-title:not(:first-of-type) {
458 458 padding-top: 10px;
459 459 }
460 460
461 461 &.submenu {
462 462 min-width: 200px;
463 463
464 464 ol {
465 465 padding:0;
466 466 }
467 467
468 468 li {
469 469 display: block;
470 470 margin: 0;
471 471 padding: .2em .5em;
472 472 line-height: 1em;
473 473
474 474 background-color: #fff;
475 475 list-style-type: none;
476 476
477 477 a {
478 478 padding: 4px;
479 479 color: @grey4 !important;
480 480 border-bottom: none;
481 481 }
482 482 }
483 483 li:not(.submenu-title) a:hover{
484 484 color: @grey2 !important;
485 485 }
486 486 }
487 487 }
488 488
489 489
490 490 // Header Repository Switcher
491 491 // Select2 Dropdown
492 492 #select2-drop.select2-drop.repo-switcher-dropdown {
493 493 width: auto !important;
494 494 margin-top: 5px;
495 495 padding: 1em 0;
496 496 text-align: left;
497 497 .border-radius-bottom(@border-radius);
498 498 border-color: transparent;
499 499 color: @grey6;
500 500 background-color: @grey2;
501 501
502 502 input {
503 503 min-width: 90%;
504 504 }
505 505
506 506 ul.select2-result-sub {
507 507
508 508 li {
509 509 line-height: 1em;
510 510
511 511 &:hover,
512 512 &.select2-highlighted {
513 513 background-color: @grey3;
514 514 }
515 515 }
516 516
517 517 &:before { content: none; }
518 518 }
519 519
520 520 ul.select2-results {
521 521 min-width: 200px;
522 522 margin: 0;
523 523 padding: 0;
524 524 list-style-type: none;
525 525 overflow-x: visible;
526 526 overflow-y: scroll;
527 527
528 528 li {
529 529 padding: 0 8px;
530 530 line-height: 1em;
531 531 color: @grey6;
532 532
533 533 &>.select2-result-label {
534 534 padding: 8px 0;
535 535 border-bottom: @border-thickness solid @grey3;
536 536 white-space: nowrap;
537 537 color: @grey5;
538 538 cursor: pointer;
539 539 }
540 540
541 541 &.select2-result-with-children {
542 542 margin: 0;
543 543 padding: 0;
544 544 }
545 545
546 546 &.select2-result-unselectable > .select2-result-label {
547 547 margin: 0 8px;
548 548 }
549 549
550 550 }
551 551 }
552 552
553 553 ul.select2-result-sub {
554 554 margin: 0;
555 555 padding: 0;
556 556
557 557 li {
558 558 display: block;
559 559 margin: 0;
560 560 border-right: none;
561 561 line-height: 1em;
562 562 font-family: @text-light;
563 563 color: @grey2;
564 564 list-style-type: none;
565 565
566 566 &:hover {
567 567 background-color: @grey3;
568 568 }
569 569 }
570 570 }
571 571 }
572 572
573 573
574 574 #context-bar {
575 575 display: block;
576 576 margin: 0 auto 20px 0;
577 577 padding: 0 @header-padding;
578 578 background-color: @grey7;
579 579 border-bottom: 1px solid @grey5;
580 580
581 581 .clear {
582 582 clear: both;
583 583 }
584 584 }
585 585
586 586 ul#context-pages {
587 587 li {
588 588 list-style-type: none;
589 589
590 590 a {
591 591 color: @grey2;
592 592
593 593 &:hover {
594 594 color: @grey1;
595 595 }
596 596 }
597 597
598 598 &.active {
599 599 // special case, non-variable color
600 600 border-bottom: 2px solid @rcblue;
601 601
602 602 a {
603 603 color: @rcblue;
604 604 }
605 605 }
606 606 }
607 607 }
608 608
609 609 // PAGINATION
610 610
611 611 .pagination {
612 612 border: @border-thickness solid @grey5;
613 613 color: @grey2;
614 614 box-shadow: @button-shadow;
615 615
616 616 .current {
617 617 color: @grey4;
618 618 }
619 619 }
620 620
621 621 .dataTables_processing {
622 622 text-align: center;
623 623 font-size: 1.1em;
624 624 position: relative;
625 625 top: 95px;
626 626 }
627 627
628 628 .dataTables_paginate,
629 629 .pagination-wh {
630 630 text-align: center;
631 631 display: inline-block;
632 632 border-left: 1px solid @grey5;
633 633 float: none;
634 634 overflow: hidden;
635 635 box-shadow: @button-shadow;
636 636
637 637 .paginate_button, .pager_curpage,
638 638 .pager_link, .pg-previous, .pg-next, .pager_dotdot {
639 639 display: inline-block;
640 640 padding: @menupadding/4 @menupadding;
641 641 border: 1px solid @grey5;
642 642 margin-left: -1px;
643 643 color: @grey2;
644 644 cursor: pointer;
645 645 float: left;
646 646 font-weight: 600;
647 647 white-space: nowrap;
648 648 vertical-align: middle;
649 649 user-select: none;
650 650 min-width: 15px;
651 651
652 652 &:hover {
653 653 color: @rcdarkblue;
654 654 }
655 655 }
656 656
657 657 .paginate_button.disabled,
658 658 .disabled {
659 659 color: @grey3;
660 660 cursor: default;
661 661 opacity: 0.5;
662 662 }
663 663
664 664 .paginate_button.current, .pager_curpage {
665 665 background: @rcblue;
666 666 border-color: @rcblue;
667 667 color: @white;
668 668 }
669 669
670 670 .ellipsis {
671 671 display: inline-block;
672 672 text-align: left;
673 673 padding: @menupadding/4 @menupadding;
674 674 border: 1px solid @grey5;
675 675 border-left: 0;
676 676 float: left;
677 677 }
678 678 }
679 679
680 680 // SIDEBAR
681 681
682 682 .sidebar {
683 683 .block-left;
684 684 clear: left;
685 685 max-width: @sidebar-width;
686 686 margin-right: @sidebarpadding;
687 687 padding-right: @sidebarpadding;
688 688 font-family: @text-regular;
689 689 color: @grey1;
690 690
691 691 .nav-pills {
692 692 margin: 0;
693 693 }
694 694
695 695 .nav {
696 696 list-style: none;
697 697 padding: 0;
698 698
699 699 li {
700 700 padding-bottom: @menupadding;
701 701 line-height: 1em;
702 702 color: @grey4;
703 703 list-style-type: none;
704 704
705 705 &.active a {
706 706 color: @grey2;
707 707 }
708 708
709 709 a {
710 710 color: @grey4;
711 711 }
712 712 }
713 713
714 714 }
715 715 }
716 716
717 717 .main_filter_help_box {
718 718 padding: 7px 7px;
719 719 display: inline-block;
720 720 vertical-align: top;
721 721 background: inherit;
722 722 position: absolute;
723 723 right: 0;
724 724 top: 9px;
725 725 }
726 726
727 727 .main_filter_input_box {
728 728 display: inline-block;
729 729
730 730 .searchItems {
731 731 display:flex;
732 732 background: @black;
733 733 padding: 0px;
734 734 border-radius: 3px;
735 735 border: 1px solid @black;
736 736
737 737 a {
738 738 border: none !important;
739 739 }
740 740 }
741 741
742 742 .searchTag {
743 743 line-height: 28px;
744 744 padding: 0 5px;
745 745
746 746 .tag {
747 747 color: @grey5;
748 748 border-color: @grey2;
749 749 background: @grey1;
750 750 }
751 751 }
752 752
753 753 .searchTagFilter {
754 754 background-color: @black !important;
755 755 margin-right: 0;
756 756 }
757
757 .searchTagIcon {
758 margin: 0;
759 background: @black !important;
760 }
758 761 .searchTagHelp {
759 762 background-color: @grey1 !important;
760 763 margin: 0;
761 764 }
762 765 .searchTagHelp:hover {
763 766 background-color: @grey1 !important;
764 767 }
765 768 .searchTagInput {
766 769 background-color: @grey1 !important;
767 770 margin-right: 0;
768 771 }
769 772 }
770 773
771 774 .main_filter_box {
772 775 margin: 9px 0 0 0;
773 776 }
774 777
775 778 #main_filter_help {
776 779 background: @grey1;
777 780 border: 1px solid black;
778 781 position: absolute;
779 782 white-space: pre;
780 783 z-index: 9999;
781 784 color: @nav-grey;
782 785 padding: 0 10px;
783 786 }
784 787
785 788 input {
786 789
787 790 &.main_filter_input {
788 791 padding: 5px 10px;
789 792 min-width: 340px;
790 793 color: @grey7;
791 794 background: @black;
792 795 min-height: 18px;
793 796 border: 0;
794 797
795 798 &:active {
796 799 color: @grey2 !important;
797 800 background: white !important;
798 801 }
799 802 &:focus {
800 803 color: @grey2 !important;
801 804 background: white !important;
802 805 }
803 806 }
804 807 }
805 808
806 809
807 810
808 811 .main_filter_input::placeholder {
809 812 color: @nav-grey;
810 813 opacity: 1;
811 814 }
812 815
813 816 .notice-box {
814 817 display:block !important;
815 818 padding: 9px 0 !important;
816 819 }
817 820
818 821 .menulabel-notice {
819 822 border: 1px solid @color5;
820 823 padding:7px 10px;
821 824 color: @color5;
822 825 }
@@ -1,1123 +1,1133 b''
1 1 ## -*- coding: utf-8 -*-
2 2
3 3 <%!
4 4 ## base64 filter e.g ${ example | base64 }
5 5 def base64(text):
6 6 import base64
7 7 from rhodecode.lib.helpers import safe_str
8 8 return base64.encodestring(safe_str(text))
9 9 %>
10 10
11 11 <%inherit file="root.mako"/>
12 12
13 13 <%include file="/ejs_templates/templates.html"/>
14 14
15 15 <div class="outerwrapper">
16 16 <!-- HEADER -->
17 17 <div class="header">
18 18 <div id="header-inner" class="wrapper">
19 19 <div id="logo">
20 20 <div class="logo-wrapper">
21 21 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
22 22 </div>
23 23 % if c.rhodecode_name:
24 24 <div class="branding">
25 25 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
26 26 </div>
27 27 % endif
28 28 </div>
29 29 <!-- MENU BAR NAV -->
30 30 ${self.menu_bar_nav()}
31 31 <!-- END MENU BAR NAV -->
32 32 </div>
33 33 </div>
34 34 ${self.menu_bar_subnav()}
35 35 <!-- END HEADER -->
36 36
37 37 <!-- CONTENT -->
38 38 <div id="content" class="wrapper">
39 39
40 40 <rhodecode-toast id="notifications"></rhodecode-toast>
41 41
42 42 <div class="main">
43 43 ${next.main()}
44 44 </div>
45 45 </div>
46 46 <!-- END CONTENT -->
47 47
48 48 </div>
49 49 <!-- FOOTER -->
50 50 <div id="footer">
51 51 <div id="footer-inner" class="title wrapper">
52 52 <div>
53 53 <p class="footer-link-right">
54 54 % if c.visual.show_version:
55 55 RhodeCode Enterprise ${c.rhodecode_version} ${c.rhodecode_edition}
56 56 % endif
57 57 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
58 58 % if c.visual.rhodecode_support_url:
59 59 <a href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a>
60 60 % endif
61 61 </p>
62 62 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
63 63 <p class="server-instance" style="display:${sid}">
64 64 ## display hidden instance ID if specially defined
65 65 % if c.rhodecode_instanceid:
66 66 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
67 67 % endif
68 68 </p>
69 69 </div>
70 70 </div>
71 71 </div>
72 72
73 73 <!-- END FOOTER -->
74 74
75 75 ### MAKO DEFS ###
76 76
77 77 <%def name="menu_bar_subnav()">
78 78 </%def>
79 79
80 80 <%def name="breadcrumbs(class_='breadcrumbs')">
81 81 <div class="${class_}">
82 82 ${self.breadcrumbs_links()}
83 83 </div>
84 84 </%def>
85 85
86 86 <%def name="admin_menu(active=None)">
87 87
88 88 <div id="context-bar">
89 89 <div class="wrapper">
90 90 <div class="title">
91 91 <div class="title-content">
92 92 <div class="title-main">
93 93 % if c.is_super_admin:
94 94 ${_('Super Admin Panel')}
95 95 % else:
96 96 ${_('Delegated Admin Panel')}
97 97 % endif
98 98 </div>
99 99 </div>
100 100 </div>
101 101
102 102 <ul id="context-pages" class="navigation horizontal-list">
103 103
104 104 ## super admin case
105 105 % if c.is_super_admin:
106 106 <li class="${h.is_active('audit_logs', active)}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
107 107 <li class="${h.is_active('repositories', active)}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
108 108 <li class="${h.is_active('repository_groups', active)}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
109 109 <li class="${h.is_active('users', active)}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
110 110 <li class="${h.is_active('user_groups', active)}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
111 111 <li class="${h.is_active('permissions', active)}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
112 112 <li class="${h.is_active('authentication', active)}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
113 113 <li class="${h.is_active('integrations', active)}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
114 114 <li class="${h.is_active('defaults', active)}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
115 115 <li class="${h.is_active('settings', active)}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
116 116
117 117 ## delegated admin
118 118 % elif c.is_delegated_admin:
119 119 <%
120 120 repositories=c.auth_user.repositories_admin or c.can_create_repo
121 121 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
122 122 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
123 123 %>
124 124
125 125 %if repositories:
126 126 <li class="${h.is_active('repositories', active)} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
127 127 %endif
128 128 %if repository_groups:
129 129 <li class="${h.is_active('repository_groups', active)} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
130 130 %endif
131 131 %if user_groups:
132 132 <li class="${h.is_active('user_groups', active)} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
133 133 %endif
134 134 % endif
135 135 </ul>
136 136
137 137 </div>
138 138 <div class="clear"></div>
139 139 </div>
140 140 </%def>
141 141
142 142 <%def name="dt_info_panel(elements)">
143 143 <dl class="dl-horizontal">
144 144 %for dt, dd, title, show_items in elements:
145 145 <dt>${dt}:</dt>
146 146 <dd title="${h.tooltip(title)}">
147 147 %if callable(dd):
148 148 ## allow lazy evaluation of elements
149 149 ${dd()}
150 150 %else:
151 151 ${dd}
152 152 %endif
153 153 %if show_items:
154 154 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
155 155 %endif
156 156 </dd>
157 157
158 158 %if show_items:
159 159 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
160 160 %for item in show_items:
161 161 <dt></dt>
162 162 <dd>${item}</dd>
163 163 %endfor
164 164 </div>
165 165 %endif
166 166
167 167 %endfor
168 168 </dl>
169 169 </%def>
170 170
171 171 <%def name="tr_info_entry(element)">
172 172 <% key, val, title, show_items = element %>
173 173
174 174 <tr>
175 175 <td style="vertical-align: top">${key}</td>
176 176 <td title="${h.tooltip(title)}">
177 177 %if callable(val):
178 178 ## allow lazy evaluation of elements
179 179 ${val()}
180 180 %else:
181 181 ${val}
182 182 %endif
183 183 %if show_items:
184 184 <div class="collapsable-content" data-toggle="item-${h.md5_safe(val)[:6]}-details" style="display: none">
185 185 % for item in show_items:
186 186 <dt></dt>
187 187 <dd>${item}</dd>
188 188 % endfor
189 189 </div>
190 190 %endif
191 191 </td>
192 192 <td style="vertical-align: top">
193 193 %if show_items:
194 194 <span class="btn-collapse" data-toggle="item-${h.md5_safe(val)[:6]}-details">${_('Show More')} </span>
195 195 %endif
196 196 </td>
197 197 </tr>
198 198
199 199 </%def>
200 200
201 201 <%def name="gravatar(email, size=16, tooltip=False, tooltip_alt=None, user=None)">
202 202 <%
203 203 if size > 16:
204 204 gravatar_class = ['gravatar','gravatar-large']
205 205 else:
206 206 gravatar_class = ['gravatar']
207 207
208 208 data_hovercard_url = ''
209 209 data_hovercard_alt = tooltip_alt.replace('<', '&lt;').replace('>', '&gt;') if tooltip_alt else ''
210 210
211 211 if tooltip:
212 212 gravatar_class += ['tooltip-hovercard']
213 213
214 214 if tooltip and user:
215 215 if user.username == h.DEFAULT_USER:
216 216 gravatar_class.pop(-1)
217 217 else:
218 218 data_hovercard_url = request.route_path('hovercard_user', user_id=getattr(user, 'user_id', ''))
219 219 gravatar_class = ' '.join(gravatar_class)
220 220
221 221 %>
222 222 <%doc>
223 223 TODO: johbo: For now we serve double size images to make it smooth
224 224 for retina. This is how it worked until now. Should be replaced
225 225 with a better solution at some point.
226 226 </%doc>
227 227
228 228 <img class="${gravatar_class}" height="${size}" width="${size}" data-hovercard-url="${data_hovercard_url}" data-hovercard-alt="${data_hovercard_alt}" src="${h.gravatar_url(email, size * 2)}" />
229 229 </%def>
230 230
231 231
232 232 <%def name="gravatar_with_user(contact, size=16, show_disabled=False, tooltip=False)">
233 233 <%
234 234 email = h.email_or_none(contact)
235 235 rc_user = h.discover_user(contact)
236 236 %>
237 237
238 238 <div class="rc-user">
239 239 ${self.gravatar(email, size, tooltip=tooltip, tooltip_alt=contact, user=rc_user)}
240 240 <span class="${('user user-disabled' if show_disabled else 'user')}"> ${h.link_to_user(rc_user or contact)}</span>
241 241 </div>
242 242 </%def>
243 243
244 244
245 245 <%def name="user_group_icon(user_group=None, size=16, tooltip=False)">
246 246 <%
247 247 if (size > 16):
248 248 gravatar_class = 'icon-user-group-alt'
249 249 else:
250 250 gravatar_class = 'icon-user-group-alt'
251 251
252 252 if tooltip:
253 253 gravatar_class += ' tooltip-hovercard'
254 254
255 255 data_hovercard_url = request.route_path('hovercard_user_group', user_group_id=user_group.users_group_id)
256 256 %>
257 257 <%doc>
258 258 TODO: johbo: For now we serve double size images to make it smooth
259 259 for retina. This is how it worked until now. Should be replaced
260 260 with a better solution at some point.
261 261 </%doc>
262 262
263 263 <i style="font-size: ${size}px" class="${gravatar_class} x-icon-size-${size}" data-hovercard-url="${data_hovercard_url}"></i>
264 264 </%def>
265 265
266 266 <%def name="repo_page_title(repo_instance)">
267 267 <div class="title-content repo-title">
268 268
269 269 <div class="title-main">
270 270 ## SVN/HG/GIT icons
271 271 %if h.is_hg(repo_instance):
272 272 <i class="icon-hg"></i>
273 273 %endif
274 274 %if h.is_git(repo_instance):
275 275 <i class="icon-git"></i>
276 276 %endif
277 277 %if h.is_svn(repo_instance):
278 278 <i class="icon-svn"></i>
279 279 %endif
280 280
281 281 ## public/private
282 282 %if repo_instance.private:
283 283 <i class="icon-repo-private"></i>
284 284 %else:
285 285 <i class="icon-repo-public"></i>
286 286 %endif
287 287
288 288 ## repo name with group name
289 289 ${h.breadcrumb_repo_link(repo_instance)}
290 290
291 291 ## Context Actions
292 292 <div class="pull-right">
293 293 %if c.rhodecode_user.username != h.DEFAULT_USER:
294 294 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_uid, _query=dict(auth_token=c.rhodecode_user.feed_token))}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
295 295
296 296 <a href="#WatchRepo" onclick="toggleFollowingRepo(this, templateContext.repo_id); return false" title="${_('Watch this Repository and actions on it in your personalized journal')}" class="btn btn-sm ${('watching' if c.repository_is_user_following else '')}">
297 297 % if c.repository_is_user_following:
298 298 <i class="icon-eye-off"></i>${_('Unwatch')}
299 299 % else:
300 300 <i class="icon-eye"></i>${_('Watch')}
301 301 % endif
302 302
303 303 </a>
304 304 %else:
305 305 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_uid)}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
306 306 %endif
307 307 </div>
308 308
309 309 </div>
310 310
311 311 ## FORKED
312 312 %if repo_instance.fork:
313 313 <p class="discreet">
314 314 <i class="icon-code-fork"></i> ${_('Fork of')}
315 315 ${h.link_to_if(c.has_origin_repo_read_perm,repo_instance.fork.repo_name, h.route_path('repo_summary', repo_name=repo_instance.fork.repo_name))}
316 316 </p>
317 317 %endif
318 318
319 319 ## IMPORTED FROM REMOTE
320 320 %if repo_instance.clone_uri:
321 321 <p class="discreet">
322 322 <i class="icon-code-fork"></i> ${_('Clone from')}
323 323 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
324 324 </p>
325 325 %endif
326 326
327 327 ## LOCKING STATUS
328 328 %if repo_instance.locked[0]:
329 329 <p class="locking_locked discreet">
330 330 <i class="icon-repo-lock"></i>
331 331 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
332 332 </p>
333 333 %elif repo_instance.enable_locking:
334 334 <p class="locking_unlocked discreet">
335 335 <i class="icon-repo-unlock"></i>
336 336 ${_('Repository not locked. Pull repository to lock it.')}
337 337 </p>
338 338 %endif
339 339
340 340 </div>
341 341 </%def>
342 342
343 343 <%def name="repo_menu(active=None)">
344 344 <%
345 345 ## determine if we have "any" option available
346 346 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
347 347 has_actions = can_lock
348 348
349 349 %>
350 350 % if c.rhodecode_db_repo.archived:
351 351 <div class="alert alert-warning text-center">
352 352 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
353 353 </div>
354 354 % endif
355 355
356 356 <!--- REPO CONTEXT BAR -->
357 357 <div id="context-bar">
358 358 <div class="wrapper">
359 359
360 360 <div class="title">
361 361 ${self.repo_page_title(c.rhodecode_db_repo)}
362 362 </div>
363 363
364 364 <ul id="context-pages" class="navigation horizontal-list">
365 365 <li class="${h.is_active('summary', active)}"><a class="menulink" href="${h.route_path('repo_summary', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
366 366 <li class="${h.is_active('commits', active)}"><a class="menulink" href="${h.route_path('repo_commits', repo_name=c.repo_name)}"><div class="menulabel">${_('Commits')}</div></a></li>
367 367 <li class="${h.is_active('files', active)}"><a class="menulink" href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.rhodecode_db_repo.landing_rev[1], f_path='')}"><div class="menulabel">${_('Files')}</div></a></li>
368 368 <li class="${h.is_active('compare', active)}"><a class="menulink" href="${h.route_path('repo_compare_select',repo_name=c.repo_name)}"><div class="menulabel">${_('Compare')}</div></a></li>
369 369
370 370 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
371 371 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
372 372 <li class="${h.is_active('showpullrequest', active)}">
373 373 <a class="menulink" href="${h.route_path('pullrequest_show_all', repo_name=c.repo_name)}" title="${h.tooltip(_('Show Pull Requests for %s') % c.repo_name)}">
374 374 <div class="menulabel">
375 375 ${_('Pull Requests')} <span class="menulink-counter">${c.repository_pull_requests}</span>
376 376 </div>
377 377 </a>
378 378 </li>
379 379 %endif
380 380
381 381 <li class="${h.is_active('artifacts', active)}">
382 382 <a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}">
383 383 <div class="menulabel">
384 384 ${_('Artifacts')} <span class="menulink-counter">${c.repository_artifacts}</span>
385 385 </div>
386 386 </a>
387 387 </li>
388 388
389 389 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
390 390 <li class="${h.is_active('settings', active)}"><a class="menulink" href="${h.route_path('edit_repo',repo_name=c.repo_name)}"><div class="menulabel">${_('Repository Settings')}</div></a></li>
391 391 %endif
392 392
393 393 <li class="${h.is_active('options', active)}">
394 394 % if has_actions:
395 395 <a class="menulink dropdown">
396 396 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
397 397 </a>
398 398 <ul class="submenu">
399 399 %if can_lock:
400 400 %if c.rhodecode_db_repo.locked[0]:
401 401 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock Repository')}</a></li>
402 402 %else:
403 403 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock Repository')}</a></li>
404 404 %endif
405 405 %endif
406 406 </ul>
407 407 % else:
408 408 <a class="menulink disabled">
409 409 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
410 410 </a>
411 411 % endif
412 412 </li>
413 413
414 414 </ul>
415 415 </div>
416 416 <div class="clear"></div>
417 417 </div>
418 418
419 419 <!--- REPO END CONTEXT BAR -->
420 420
421 421 </%def>
422 422
423 423 <%def name="repo_group_page_title(repo_group_instance)">
424 424 <div class="title-content">
425 425 <div class="title-main">
426 426 ## Repository Group icon
427 427 <i class="icon-repo-group"></i>
428 428
429 429 ## repo name with group name
430 430 ${h.breadcrumb_repo_group_link(repo_group_instance)}
431 431 </div>
432 432
433 433 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
434 434 <div class="repo-group-desc discreet">
435 435 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
436 436 </div>
437 437
438 438 </div>
439 439 </%def>
440 440
441 441
442 442 <%def name="repo_group_menu(active=None)">
443 443 <%
444 444 gr_name = c.repo_group.group_name if c.repo_group else None
445 445 # create repositories with write permission on group is set to true
446 446 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
447 447
448 448 %>
449 449
450 450
451 451 <!--- REPO GROUP CONTEXT BAR -->
452 452 <div id="context-bar">
453 453 <div class="wrapper">
454 454 <div class="title">
455 455 ${self.repo_group_page_title(c.repo_group)}
456 456 </div>
457 457
458 458 <ul id="context-pages" class="navigation horizontal-list">
459 459 <li class="${h.is_active('home', active)}">
460 460 <a class="menulink" href="${h.route_path('repo_group_home', repo_group_name=c.repo_group.group_name)}"><div class="menulabel">${_('Group Home')}</div></a>
461 461 </li>
462 462 % if c.is_super_admin or group_admin:
463 463 <li class="${h.is_active('settings', active)}">
464 464 <a class="menulink" href="${h.route_path('edit_repo_group',repo_group_name=c.repo_group.group_name)}" title="${_('You have admin right to this group, and can edit it')}"><div class="menulabel">${_('Group Settings')}</div></a>
465 465 </li>
466 466 % endif
467 467
468 468 </ul>
469 469 </div>
470 470 <div class="clear"></div>
471 471 </div>
472 472
473 473 <!--- REPO GROUP CONTEXT BAR -->
474 474
475 475 </%def>
476 476
477 477
478 478 <%def name="usermenu(active=False)">
479 479 <%
480 480 not_anonymous = c.rhodecode_user.username != h.DEFAULT_USER
481 481
482 482 gr_name = c.repo_group.group_name if (hasattr(c, 'repo_group') and c.repo_group) else None
483 483 # create repositories with write permission on group is set to true
484 484
485 485 can_fork = c.is_super_admin or h.HasPermissionAny('hg.fork.repository')()
486 486 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
487 487 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
488 488 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
489 489
490 490 can_create_repos = c.is_super_admin or c.can_create_repo
491 491 can_create_repo_groups = c.is_super_admin or c.can_create_repo_group
492 492
493 493 can_create_repos_in_group = c.is_super_admin or group_admin or (group_write and create_on_write)
494 494 can_create_repo_groups_in_group = c.is_super_admin or group_admin
495 495 %>
496 496
497 497 % if not_anonymous:
498 498 <%
499 499 default_target_group = dict()
500 500 if c.rhodecode_user.personal_repo_group:
501 501 default_target_group = dict(parent_group=c.rhodecode_user.personal_repo_group.group_id)
502 502 %>
503 503
504 504 ## create action
505 505 <li>
506 506 <a href="#create-actions" onclick="return false;" class="menulink childs">
507 507 <i class="tooltip icon-plus-circled" title="${_('Create')}"></i>
508 508 </a>
509 509
510 510 <div class="action-menu submenu">
511 511
512 512 <ol>
513 513 ## scope of within a repository
514 514 % if hasattr(c, 'rhodecode_db_repo') and c.rhodecode_db_repo:
515 515 <li class="submenu-title">${_('This Repository')}</li>
516 516 <li>
517 517 <a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a>
518 518 </li>
519 519 % if can_fork:
520 520 <li>
521 521 <a href="${h.route_path('repo_fork_new',repo_name=c.repo_name,_query=default_target_group)}">${_('Fork this repository')}</a>
522 522 </li>
523 523 % endif
524 524 % endif
525 525
526 526 ## scope of within repository groups
527 527 % if hasattr(c, 'repo_group') and c.repo_group and (can_create_repos_in_group or can_create_repo_groups_in_group):
528 528 <li class="submenu-title">${_('This Repository Group')}</li>
529 529
530 530 % if can_create_repos_in_group:
531 531 <li>
532 532 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('New Repository')}</a>
533 533 </li>
534 534 % endif
535 535
536 536 % if can_create_repo_groups_in_group:
537 537 <li>
538 538 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'New Repository Group')}</a>
539 539 </li>
540 540 % endif
541 541 % endif
542 542
543 543 ## personal group
544 544 % if c.rhodecode_user.personal_repo_group:
545 545 <li class="submenu-title">Personal Group</li>
546 546
547 547 <li>
548 548 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}" >${_('New Repository')} </a>
549 549 </li>
550 550
551 551 <li>
552 552 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}">${_('New Repository Group')} </a>
553 553 </li>
554 554 % endif
555 555
556 556 ## Global actions
557 557 <li class="submenu-title">RhodeCode</li>
558 558 % if can_create_repos:
559 559 <li>
560 560 <a href="${h.route_path('repo_new')}" >${_('New Repository')}</a>
561 561 </li>
562 562 % endif
563 563
564 564 % if can_create_repo_groups:
565 565 <li>
566 566 <a href="${h.route_path('repo_group_new')}" >${_(u'New Repository Group')}</a>
567 567 </li>
568 568 % endif
569 569
570 570 <li>
571 571 <a href="${h.route_path('gists_new')}">${_(u'New Gist')}</a>
572 572 </li>
573 573
574 574 </ol>
575 575
576 576 </div>
577 577 </li>
578 578
579 579 ## notifications
580 580 <li>
581 581 <a class="${('empty' if c.unread_notifications == 0 else '')}" href="${h.route_path('notifications_show_all')}">
582 582 ${c.unread_notifications}
583 583 </a>
584 584 </li>
585 585 % endif
586 586
587 587 ## USER MENU
588 588 <li id="quick_login_li" class="${'active' if active else ''}">
589 589 % if c.rhodecode_user.username == h.DEFAULT_USER:
590 590 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
591 591 ${gravatar(c.rhodecode_user.email, 20)}
592 592 <span class="user">
593 593 <span>${_('Sign in')}</span>
594 594 </span>
595 595 </a>
596 596 % else:
597 597 ## logged in user
598 598 <a id="quick_login_link" class="menulink childs">
599 599 ${gravatar(c.rhodecode_user.email, 20)}
600 600 <span class="user">
601 601 <span class="menu_link_user">${c.rhodecode_user.username}</span>
602 602 <div class="show_more"></div>
603 603 </span>
604 604 </a>
605 605 ## subnav with menu for logged in user
606 606 <div class="user-menu submenu">
607 607 <div id="quick_login">
608 608 %if c.rhodecode_user.username != h.DEFAULT_USER:
609 609 <div class="">
610 610 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
611 611 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
612 612 <div class="email">${c.rhodecode_user.email}</div>
613 613 </div>
614 614 <div class="">
615 615 <ol class="links">
616 616 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
617 617 % if c.rhodecode_user.personal_repo_group:
618 618 <li>${h.link_to(_(u'My personal group'), h.route_path('repo_group_home', repo_group_name=c.rhodecode_user.personal_repo_group.group_name))}</li>
619 619 % endif
620 620 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
621 621
622 622 % if c.debug_style:
623 623 <li>
624 624 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
625 625 <div class="menulabel">${_('[Style]')}</div>
626 626 </a>
627 627 </li>
628 628 % endif
629 629
630 630 ## bookmark-items
631 631 <li class="bookmark-items">
632 632 ${_('Bookmarks')}
633 633 <div class="pull-right">
634 634 <a href="${h.route_path('my_account_bookmarks')}">
635 635
636 636 <i class="icon-cog"></i>
637 637 </a>
638 638 </div>
639 639 </li>
640 640 % if not c.bookmark_items:
641 641 <li>
642 642 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
643 643 </li>
644 644 % endif
645 645 % for item in c.bookmark_items:
646 646 <li>
647 647 % if item.repository:
648 648 <div>
649 649 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
650 650 <code>${item.position}</code>
651 651 % if item.repository.repo_type == 'hg':
652 652 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
653 653 % elif item.repository.repo_type == 'git':
654 654 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
655 655 % elif item.repository.repo_type == 'svn':
656 656 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
657 657 % endif
658 658 ${(item.title or h.shorter(item.repository.repo_name, 30))}
659 659 </a>
660 660 </div>
661 661 % elif item.repository_group:
662 662 <div>
663 663 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
664 664 <code>${item.position}</code>
665 665 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
666 666 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
667 667 </a>
668 668 </div>
669 669 % else:
670 670 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
671 671 <code>${item.position}</code>
672 672 ${item.title}
673 673 </a>
674 674 % endif
675 675 </li>
676 676 % endfor
677 677
678 678 <li class="logout">
679 679 ${h.secure_form(h.route_path('logout'), request=request)}
680 680 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
681 681 ${h.end_form()}
682 682 </li>
683 683 </ol>
684 684 </div>
685 685 %endif
686 686 </div>
687 687 </div>
688 688
689 689 % endif
690 690 </li>
691 691 </%def>
692 692
693 693 <%def name="menu_items(active=None)">
694 694
695 695 <ul id="quick" class="main_nav navigation horizontal-list">
696 696 ## notice box for important system messages
697 697 <li style="display: none">
698 698 <a class="notice-box" href="#openNotice" onclick="return false">
699 699 <div class="menulabel-notice" >
700 700 0
701 701 </div>
702 702 </a>
703 703 </li>
704 704
705 705 ## Main filter
706 706 <li>
707 707 <div class="menulabel main_filter_box">
708 708 <div class="main_filter_input_box">
709 709 <ul class="searchItems">
710 710
711 <li class="searchTag searchTagIcon">
712 <i class="icon-search"></i>
713 </li>
714
711 715 % if c.template_context['search_context']['repo_id']:
712 716 <li class="searchTag searchTagFilter searchTagHidable" >
713 717 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
714 718 <span class="tag">
715 719 This repo
716 720 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
717 721 </span>
718 722 ##</a>
719 723 </li>
720 724 % elif c.template_context['search_context']['repo_group_id']:
721 725 <li class="searchTag searchTagFilter searchTagHidable">
722 726 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
723 727 <span class="tag">
724 728 This group
725 729 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
726 730 </span>
727 731 ##</a>
728 732 </li>
729 733 % endif
730 734
731 735 <li class="searchTagInput">
732 736 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
733 737 </li>
734 738 <li class="searchTag searchTagHelp">
735 739 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
736 740 </li>
737 741 </ul>
738 742 </div>
739 743 </div>
740 744
741 745 <div id="main_filter_help" style="display: none">
742 746 - Use '/' key to quickly access this field.
743 747
744 748 - Enter a name of repository, or repository group for quick search.
745 749
746 750 - Prefix query to allow special search:
747 751
748 752 user:admin, to search for usernames, always global
749 753
750 754 user_group:devops, to search for user groups, always global
751 755
752 756 commit:efced4, to search for commits, scoped to repositories or groups
753 757
754 758 file:models.py, to search for file paths, scoped to repositories or groups
755 759
756 760 % if c.template_context['search_context']['repo_id']:
757 761 For advanced full text search visit: <a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">repository search</a>
758 762 % elif c.template_context['search_context']['repo_group_id']:
759 763 For advanced full text search visit: <a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">repository group search</a>
760 764 % else:
761 765 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
762 766 % endif
763 767 </div>
764 768 </li>
765 769
766 770 ## ROOT MENU
767 771 <li class="${h.is_active('home', active)}">
768 772 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
769 773 <div class="menulabel">${_('Home')}</div>
770 774 </a>
771 775 </li>
772 776
773 777 %if c.rhodecode_user.username != h.DEFAULT_USER:
774 778 <li class="${h.is_active('journal', active)}">
775 779 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
776 780 <div class="menulabel">${_('Journal')}</div>
777 781 </a>
778 782 </li>
779 783 %else:
780 784 <li class="${h.is_active('journal', active)}">
781 785 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
782 786 <div class="menulabel">${_('Public journal')}</div>
783 787 </a>
784 788 </li>
785 789 %endif
786 790
787 791 <li class="${h.is_active('gists', active)}">
788 792 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
789 793 <div class="menulabel">${_('Gists')}</div>
790 794 </a>
791 795 </li>
792 796
793 797 % if c.is_super_admin or c.is_delegated_admin:
794 798 <li class="${h.is_active('admin', active)}">
795 799 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
796 800 <div class="menulabel">${_('Admin')} </div>
797 801 </a>
798 802 </li>
799 803 % endif
800 804
801 805 ## render extra user menu
802 806 ${usermenu(active=(active=='my_account'))}
803 807
804 808 </ul>
805 809
806 810 <script type="text/javascript">
807 811 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
808 812
809 813 var formatRepoResult = function(result, container, query, escapeMarkup) {
810 814 return function(data, escapeMarkup) {
811 815 if (!data.repo_id){
812 816 return data.text; // optgroup text Repositories
813 817 }
814 818
815 819 var tmpl = '';
816 820 var repoType = data['repo_type'];
817 821 var repoName = data['text'];
818 822
819 823 if(data && data.type == 'repo'){
820 824 if(repoType === 'hg'){
821 825 tmpl += '<i class="icon-hg"></i> ';
822 826 }
823 827 else if(repoType === 'git'){
824 828 tmpl += '<i class="icon-git"></i> ';
825 829 }
826 830 else if(repoType === 'svn'){
827 831 tmpl += '<i class="icon-svn"></i> ';
828 832 }
829 833 if(data['private']){
830 834 tmpl += '<i class="icon-lock" ></i> ';
831 835 }
832 836 else if(visualShowPublicIcon){
833 837 tmpl += '<i class="icon-unlock-alt"></i> ';
834 838 }
835 839 }
836 840 tmpl += escapeMarkup(repoName);
837 841 return tmpl;
838 842
839 843 }(result, escapeMarkup);
840 844 };
841 845
842 846 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
843 847 return function(data, escapeMarkup) {
844 848 if (!data.repo_group_id){
845 849 return data.text; // optgroup text Repositories
846 850 }
847 851
848 852 var tmpl = '';
849 853 var repoGroupName = data['text'];
850 854
851 855 if(data){
852 856
853 857 tmpl += '<i class="icon-repo-group"></i> ';
854 858
855 859 }
856 860 tmpl += escapeMarkup(repoGroupName);
857 861 return tmpl;
858 862
859 863 }(result, escapeMarkup);
860 864 };
861 865
862 866 var escapeRegExChars = function (value) {
863 867 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
864 868 };
865 869
866 870 var getRepoIcon = function(repo_type) {
867 871 if (repo_type === 'hg') {
868 872 return '<i class="icon-hg"></i> ';
869 873 }
870 874 else if (repo_type === 'git') {
871 875 return '<i class="icon-git"></i> ';
872 876 }
873 877 else if (repo_type === 'svn') {
874 878 return '<i class="icon-svn"></i> ';
875 879 }
876 880 return ''
877 881 };
878 882
879 883 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
880 884
881 885 if (value.split(':').length === 2) {
882 886 value = value.split(':')[1]
883 887 }
884 888
885 889 var searchType = data['type'];
886 890 var searchSubType = data['subtype'];
887 891 var valueDisplay = data['value_display'];
888 892
889 893 var pattern = '(' + escapeRegExChars(value) + ')';
890 894
891 895 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
892 896
893 897 // highlight match
894 898 if (searchType != 'text') {
895 899 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
896 900 }
897 901
898 902 var icon = '';
899 903
900 904 if (searchType === 'hint') {
901 905 icon += '<i class="icon-repo-group"></i> ';
902 906 }
903 907 // full text search/hints
904 908 else if (searchType === 'search') {
905 909 icon += '<i class="icon-more"></i> ';
906 910 if (searchSubType !== undefined && searchSubType == 'repo') {
907 911 valueDisplay += '<div class="pull-right tag">repository</div>';
908 912 }
909 913 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
910 914 valueDisplay += '<div class="pull-right tag">repo group</div>';
911 915 }
912 916 }
913 917 // repository
914 918 else if (searchType === 'repo') {
915 919
916 920 var repoIcon = getRepoIcon(data['repo_type']);
917 921 icon += repoIcon;
918 922
919 923 if (data['private']) {
920 924 icon += '<i class="icon-lock" ></i> ';
921 925 }
922 926 else if (visualShowPublicIcon) {
923 927 icon += '<i class="icon-unlock-alt"></i> ';
924 928 }
925 929 }
926 930 // repository groups
927 931 else if (searchType === 'repo_group') {
928 932 icon += '<i class="icon-repo-group"></i> ';
929 933 }
930 934 // user group
931 935 else if (searchType === 'user_group') {
932 936 icon += '<i class="icon-group"></i> ';
933 937 }
934 938 // user
935 939 else if (searchType === 'user') {
936 940 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
937 941 }
938 942 // commit
939 943 else if (searchType === 'commit') {
940 944 var repo_data = data['repo_data'];
941 945 var repoIcon = getRepoIcon(repo_data['repository_type']);
942 946 if (repoIcon) {
943 947 icon += repoIcon;
944 948 } else {
945 949 icon += '<i class="icon-tag"></i>';
946 950 }
947 951 }
948 952 // file
949 953 else if (searchType === 'file') {
950 954 var repo_data = data['repo_data'];
951 955 var repoIcon = getRepoIcon(repo_data['repository_type']);
952 956 if (repoIcon) {
953 957 icon += repoIcon;
954 958 } else {
955 959 icon += '<i class="icon-tag"></i>';
956 960 }
957 961 }
958 962 // generic text
959 963 else if (searchType === 'text') {
960 964 icon = '';
961 965 }
962 966
963 967 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
964 968 return tmpl.format(icon, valueDisplay);
965 969 };
966 970
967 971 var handleSelect = function(element, suggestion) {
968 972 if (suggestion.type === "hint") {
969 973 // we skip action
970 974 $('#main_filter').focus();
971 975 }
972 976 else if (suggestion.type === "text") {
973 977 // we skip action
974 978 $('#main_filter').focus();
975 979
976 980 } else {
977 981 window.location = suggestion['url'];
978 982 }
979 983 };
980 984
981 985 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
982 986 if (queryLowerCase.split(':').length === 2) {
983 987 queryLowerCase = queryLowerCase.split(':')[1]
984 988 }
985 989 if (suggestion.type === "text") {
986 990 // special case we don't want to "skip" display for
987 991 return true
988 992 }
989 993 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
990 994 };
991 995
992 996 var cleanContext = {
993 997 repo_view_type: null,
994 998
995 999 repo_id: null,
996 1000 repo_name: "",
997 1001
998 1002 repo_group_id: null,
999 1003 repo_group_name: null
1000 1004 };
1001 1005 var removeGoToFilter = function () {
1002 1006 $('.searchTagHidable').hide();
1003 1007 $('#main_filter').autocomplete(
1004 1008 'setOptions', {params:{search_context: cleanContext}});
1005 1009 };
1006 1010
1007 1011 $('#main_filter').autocomplete({
1008 1012 serviceUrl: pyroutes.url('goto_switcher_data'),
1009 1013 params: {
1010 1014 "search_context": templateContext.search_context
1011 1015 },
1012 1016 minChars:2,
1013 1017 maxHeight:400,
1014 1018 deferRequestBy: 300, //miliseconds
1015 1019 tabDisabled: true,
1016 1020 autoSelectFirst: false,
1017 1021 containerClass: 'autocomplete-qfilter-suggestions',
1018 1022 formatResult: autocompleteMainFilterFormatResult,
1019 1023 lookupFilter: autocompleteMainFilterResult,
1020 1024 onSelect: function (element, suggestion) {
1021 1025 handleSelect(element, suggestion);
1022 1026 return false;
1023 1027 },
1024 1028 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
1025 1029 if (jqXHR !== 'abort') {
1026 1030 alert("Error during search.\nError code: {0}".format(textStatus));
1027 1031 window.location = '';
1028 1032 }
1029 }
1033 },
1034 onSearchStart: function (params) {
1035 $('.searchTag.searchTagIcon').html('<i class="icon-spin animate-spin"></i>')
1036 },
1037 onSearchComplete: function (query, suggestions) {
1038 $('.searchTag.searchTagIcon').html('<i class="icon-search"></i>')
1039 },
1030 1040 });
1031 1041
1032 1042 showMainFilterBox = function () {
1033 1043 $('#main_filter_help').toggle();
1034 1044 };
1035 1045
1036 1046 $('#main_filter').on('keydown.autocomplete', function (e) {
1037 1047
1038 1048 var BACKSPACE = 8;
1039 1049 var el = $(e.currentTarget);
1040 1050 if(e.which === BACKSPACE){
1041 1051 var inputVal = el.val();
1042 1052 if (inputVal === ""){
1043 1053 removeGoToFilter()
1044 1054 }
1045 1055 }
1046 1056 });
1047 1057
1048 1058 </script>
1049 1059 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
1050 1060 </%def>
1051 1061
1052 1062 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
1053 1063 <div class="modal-dialog">
1054 1064 <div class="modal-content">
1055 1065 <div class="modal-header">
1056 1066 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
1057 1067 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
1058 1068 </div>
1059 1069 <div class="modal-body">
1060 1070 <div class="block-left">
1061 1071 <table class="keyboard-mappings">
1062 1072 <tbody>
1063 1073 <tr>
1064 1074 <th></th>
1065 1075 <th>${_('Site-wide shortcuts')}</th>
1066 1076 </tr>
1067 1077 <%
1068 1078 elems = [
1069 1079 ('/', 'Use quick search box'),
1070 1080 ('g h', 'Goto home page'),
1071 1081 ('g g', 'Goto my private gists page'),
1072 1082 ('g G', 'Goto my public gists page'),
1073 1083 ('g 0-9', 'Goto bookmarked items from 0-9'),
1074 1084 ('n r', 'New repository page'),
1075 1085 ('n g', 'New gist page'),
1076 1086 ]
1077 1087 %>
1078 1088 %for key, desc in elems:
1079 1089 <tr>
1080 1090 <td class="keys">
1081 1091 <span class="key tag">${key}</span>
1082 1092 </td>
1083 1093 <td>${desc}</td>
1084 1094 </tr>
1085 1095 %endfor
1086 1096 </tbody>
1087 1097 </table>
1088 1098 </div>
1089 1099 <div class="block-left">
1090 1100 <table class="keyboard-mappings">
1091 1101 <tbody>
1092 1102 <tr>
1093 1103 <th></th>
1094 1104 <th>${_('Repositories')}</th>
1095 1105 </tr>
1096 1106 <%
1097 1107 elems = [
1098 1108 ('g s', 'Goto summary page'),
1099 1109 ('g c', 'Goto changelog page'),
1100 1110 ('g f', 'Goto files page'),
1101 1111 ('g F', 'Goto files page with file search activated'),
1102 1112 ('g p', 'Goto pull requests page'),
1103 1113 ('g o', 'Goto repository settings'),
1104 1114 ('g O', 'Goto repository access permissions settings'),
1105 1115 ]
1106 1116 %>
1107 1117 %for key, desc in elems:
1108 1118 <tr>
1109 1119 <td class="keys">
1110 1120 <span class="key tag">${key}</span>
1111 1121 </td>
1112 1122 <td>${desc}</td>
1113 1123 </tr>
1114 1124 %endfor
1115 1125 </tbody>
1116 1126 </table>
1117 1127 </div>
1118 1128 </div>
1119 1129 <div class="modal-footer">
1120 1130 </div>
1121 1131 </div><!-- /.modal-content -->
1122 1132 </div><!-- /.modal-dialog -->
1123 1133 </div><!-- /.modal -->
General Comments 0
You need to be logged in to leave comments. Login now