##// END OF EJS Templates
ui: navigation, fixed wrapping of new admin navigation items
marcink -
r3566:007450ec new-ui
parent child Browse files
Show More
@@ -1,42 +1,41 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Admin audit logs')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 ${h.form(None, id_="filter_form", method="get")}
13 13 <input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or ''}" placeholder="${_('filter...')}"/>
14 14 <input type='submit' value="${_('filter')}" class="btn" />
15 15 ${_('Audit logs')} - ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
16 16 ${h.end_form()}
17 17 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
18 18 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
19 19 </%def>
20 20
21 21 <%def name="menu_bar_nav()">
22 22 ${self.menu_items(active='admin')}
23 23 </%def>
24 24
25 <%def name="menu_bar_subnav()">
26 ${self.admin_menu(active='audit_logs')}
27 </%def>
28
25 29 <%def name="main()">
26 30 <div class="box">
27 <!-- box / title -->
28 <div class="title">
29 ${self.admin_menu()}
30 </div>
31 <!-- end box / title -->
32 31 <div class="table">
33 32 <div id="user_log">
34 33 <%include file="/admin/admin_log_base.mako" />
35 34 </div>
36 35 </div>
37 36 </div>
38 37
39 38 <script>
40 39 $('#j_filter').autoGrowInput();
41 40 </script>
42 41 </%def>
@@ -1,126 +1,127 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Authentication Settings')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 13 &raquo;
14 14 ${_('Authentication Plugins')}
15 15 </%def>
16 16
17 17 <%def name="menu_bar_nav()">
18 18 ${self.menu_items(active='admin')}
19 19 </%def>
20 20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='authentication')}
23 </%def>
24
21 25 <%def name="main()">
22 26
23 27 <div class="box">
24 <div class="title">
25 ${self.admin_menu()}
26 </div>
27 28
28 29 <div class='sidebar-col-wrapper'>
29 30
30 31 <div class="sidebar">
31 32 <ul class="nav nav-pills nav-stacked">
32 33 % for item in resource.get_root().get_nav_list():
33 34 <li ${'class=active' if item == resource else ''}>
34 35 <a href="${request.resource_path(item, route_name='auth_home')}">${item.display_name}</a>
35 36 </li>
36 37 % endfor
37 38 </ul>
38 39 </div>
39 40
40 41 <div class="main-content-full-width">
41 42 ${h.secure_form(request.resource_path(resource, route_name='auth_home'), request=request)}
42 43 <div class="panel panel-default">
43 44
44 45 <div class="panel-heading">
45 46 <h3 class="panel-title">${_("Enabled and Available Plugins")}</h3>
46 47 </div>
47 48
48 49 <div class="panel-body">
49 50
50 51
51 52 <div class="label">${_("Ordered Activated Plugins")}</div>
52 53 <div class="textarea text-area editor">
53 54 ${h.textarea('auth_plugins',cols=120,rows=20,class_="medium")}
54 55 </div>
55 56 <div class="field">
56 57 <p class="help-block pre-formatting">${_('List of plugins, separated by commas.'
57 58 '\nThe order of the plugins is also the order in which '
58 59 'RhodeCode Enterprise will try to authenticate a user.')}
59 60 </p>
60 61 </div>
61 62
62 63 <table class="rctable">
63 64 <th>${_('Activate')}</th>
64 65 <th>${_('Plugin Name')}</th>
65 66 <th>${_('Documentation')}</th>
66 67 <th>${_('Plugin ID')}</th>
67 68 <th>${_('Enabled')}</th>
68 69 %for plugin in available_plugins:
69 70 <tr class="${'inactive' if (not plugin.is_active() and plugin.get_id() in enabled_plugins) else ''}">
70 71 <td>
71 72 <span plugin_id="${plugin.get_id()}" class="toggle-plugin btn ${'btn-success' if plugin.get_id() in enabled_plugins else ''}">
72 73 ${_('activated') if plugin.get_id() in enabled_plugins else _('not active')}
73 74 </span>
74 75 </td>
75 76 <td>${plugin.get_display_name()}</td>
76 77 <td>
77 78 % if plugin.docs():
78 79 <a href="${plugin.docs()}">docs</a>
79 80 % endif
80 81 </td>
81 82 <td>${plugin.get_id()}</td>
82 83 <td>${h.bool2icon(plugin.is_active(),show_at_false=False)}</td>
83 84 </tr>
84 85 %endfor
85 86 </table>
86 87
87 88 <div class="buttons">
88 89 ${h.submit('save',_('Save'),class_="btn")}
89 90 </div>
90 91 </div>
91 92 </div>
92 93 ${h.end_form()}
93 94 </div>
94 95 </div>
95 96 </div>
96 97
97 98 <script>
98 99 $('.toggle-plugin').click(function(e){
99 100 var auth_plugins_input = $('#auth_plugins');
100 101 var elems = [];
101 102
102 103 $.each(auth_plugins_input.val().split(',') , function (index, element) {
103 104 if (element !== "") {
104 105 elems.push(element.strip())
105 106 }
106 107 });
107 108
108 109 var cur_button = e.currentTarget;
109 110 var plugin_id = $(cur_button).attr('plugin_id');
110 111 if($(cur_button).hasClass('btn-success')){
111 112 elems.splice(elems.indexOf(plugin_id), 1);
112 113 auth_plugins_input.val(elems.join(',\n'));
113 114 $(cur_button).removeClass('btn-success');
114 115 cur_button.innerHTML = _gettext('not active');
115 116 }
116 117 else{
117 118 if (elems.indexOf(plugin_id) === -1) {
118 119 elems.push(plugin_id);
119 120 }
120 121 auth_plugins_input.val(elems.join(',\n'));
121 122 $(cur_button).addClass('btn-success');
122 123 cur_button.innerHTML = _gettext('activated');
123 124 }
124 125 });
125 126 </script>
126 127 </%def>
@@ -1,42 +1,43 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Repositories defaults')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 13 &raquo;
14 14 ${_('Repositories defaults')}
15 15 </%def>
16 16
17 17 <%def name="menu_bar_nav()">
18 18 ${self.menu_items(active='admin')}
19 19 </%def>
20 20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='defaults')}
23 </%def>
24
21 25 <%def name="main()">
22 26 <div class="box">
23 <div class="title">
24 ${self.admin_menu()}
25 </div>
26 27
27 28 ##main
28 29 <div class="sidebar-col-wrapper">
29 30 <div class="sidebar">
30 31 <ul class="nav nav-pills nav-stacked">
31 32 <li class="${'active' if c.active=='repositories' else ''}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Repository')}</a></li>
32 33 </ul>
33 34 </div>
34 35
35 36 <div class="main-content-full-width">
36 37 <%include file="/admin/defaults/defaults_${c.active}.mako"/>
37 38 </div>
38 39
39 40 </div>
40 41 </div>
41 42
42 43 </%def>
@@ -1,42 +1,36 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%!
3 3 def inherit(context):
4 4 if context['c'].repo:
5 5 return "/admin/repos/repo_edit.mako"
6 6 elif context['c'].repo_group:
7 7 return "/admin/repo_groups/repo_group_edit.mako"
8 8 else:
9 9 return "/admin/integrations/global.mako"
10 10 %>
11 11 <%inherit file="${inherit(context)}" />
12 12
13 13 <%def name="title()">
14 14 ${_('Integrations Settings')}
15 15 %if c.rhodecode_name:
16 16 &middot; ${h.branding(c.rhodecode_name)}
17 17 %endif
18 18 </%def>
19 19
20 20 <%def name="breadcrumbs_links()">
21 21 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
22 22 &raquo;
23 23 ${_('Integrations')}
24 24 </%def>
25 25
26 26 <%def name="menu_bar_nav()">
27 27 %if c.repo:
28 28 ${self.menu_items(active='repositories')}
29 29 %else:
30 30 ${self.menu_items(active='admin')}
31 31 %endif
32 32 </%def>
33 33
34 <%def name="menu_bar_subnav()">
35 %if c.repo:
36 ${self.repo_menu(active='options')}
37 %endif
38 </%def>
39
40 34 <%def name="main_content()">
41 35 ${next.body()}
42 36 </%def>
@@ -1,51 +1,52 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 ${_('Settings administration')}
5 ${_('Integrations administration')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 13 &raquo;
14 14 ${_('Integrations')}
15 15 </%def>
16 16
17 17 <%def name="menu_bar_nav()">
18 18 ${self.menu_items(active='admin')}
19 19 </%def>
20 20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='integrations')}
23 </%def>
24
21 25 <%def name="side_bar_nav()">
22 26 <li class="active">
23 27 <a href="${h.route_path('global_integrations_home')}">Global</a>
24 28 </li>
25 29 </%def>
26 30
27 31 <%def name="main_content()">
28 32 <%include file="/admin/settings/settings_${c.active}.mako"/>
29 33 </%def>
30 34
31 35 <%def name="main()">
32 36 <div class="box">
33 <div class="title">
34 ${self.admin_menu()}
35 </div>
36 37
37 38 ##main
38 39 <div class='sidebar-col-wrapper'>
39 40 <div class="sidebar">
40 41 <ul class="nav nav-pills nav-stacked">
41 42 ${self.side_bar_nav()}
42 43 </ul>
43 44 </div>
44 45
45 46 <div class="main-content-auto-width">
46 47 ${self.main_content()}
47 48 </div>
48 49 </div>
49 50 </div>
50 51
51 52 </%def>
@@ -1,49 +1,50 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Settings administration')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 13 &raquo;
14 14 ${_('Settings')}
15 15 </%def>
16 16
17 17 <%def name="menu_bar_nav()">
18 18 ${self.menu_items(active='admin')}
19 19 </%def>
20 20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu()}
23 </%def>
24
21 25 <%def name="side_bar_nav()">
22 26
23 27 </%def>
24 28
25 29 <%def name="main_content()">
26 30 Hello Admin
27 31 </%def>
28 32
29 33 <%def name="main()">
30 34 <div class="box">
31 <div class="title">
32 ${self.admin_menu()}
33 </div>
34 35
35 36 ##main
36 37 <div class='sidebar-col-wrapper'>
37 38 <div class="sidebar">
38 39 <ul class="nav nav-pills nav-stacked">
39 40 ${self.side_bar_nav()}
40 41 </ul>
41 42 </div>
42 43
43 44 <div class="main-content-auto-width">
44 45 ${self.main_content()}
45 46 </div>
46 47 </div>
47 48 </div>
48 49
49 50 </%def> No newline at end of file
@@ -1,65 +1,65 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Permissions Administration')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 13 &raquo;
14 14 ${_('Permissions')}
15 15 </%def>
16 16
17 17 <%def name="menu_bar_nav()">
18 18 ${self.menu_items(active='admin')}
19 19 </%def>
20 20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='permissions')}
23 </%def>
21 24
22 25 <%def name="main()">
23 26 <div class="box">
24 <div class="title">
25 ${self.admin_menu()}
26 </div>
27 27
28 28 <div class="sidebar-col-wrapper scw-small">
29 29 ##main
30 30 <div class="sidebar">
31 31 <ul class="nav nav-pills nav-stacked">
32 32 <li class="${'active' if c.active=='application' else ''}">
33 33 <a href="${h.route_path('admin_permissions_application')}">${_('Application')}</a>
34 34 </li>
35 35 <li class="${'active' if c.active=='global' else ''}">
36 36 <a href="${h.route_path('admin_permissions_global')}">${_('Global')}</a>
37 37 </li>
38 38 <li class="${'active' if c.active=='objects' else ''}">
39 39 <a href="${h.route_path('admin_permissions_object')}">${_('Object')}</a>
40 40 </li>
41 41 <li class="${'active' if c.active=='branch' else ''}">
42 42 <a href="${h.route_path('admin_permissions_branch')}">${_('Branch')}</a>
43 43 </li>
44 44 <li class="${'active' if c.active=='ips' else ''}">
45 45 <a href="${h.route_path('admin_permissions_ips')}">${_('IP Whitelist')}</a>
46 46 </li>
47 47 <li class="${'active' if c.active=='auth_token_access' else ''}">
48 48 <a href="${h.route_path('admin_permissions_auth_token_access')}">${_('AuthToken Access')}</a>
49 49 </li>
50 50 <li class="${'active' if c.active=='ssh_keys' else ''}">
51 51 <a href="${h.route_path('admin_permissions_ssh_keys')}">${_('SSH Keys')}</a>
52 52 </li>
53 53 <li class="${'active' if c.active=='perms' else ''}">
54 54 <a href="${h.route_path('admin_permissions_overview')}">${_('Overview')}</a>
55 55 </li>
56 56 </ul>
57 57 </div>
58 58
59 59 <div class="main-content-full-width">
60 60 <%include file="/admin/permissions/permissions_${c.active}.mako"/>
61 61 </div>
62 62 </div>
63 63 </div>
64 64
65 65 </%def>
@@ -1,97 +1,101 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Repository groups administration')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 13 ${h.link_to(_('Admin'),h.route_path('admin_home'))} &raquo; <span id="repo_group_count">0</span> ${_('repository groups')}
14 14 </%def>
15 15
16 16 <%def name="menu_bar_nav()">
17 17 ${self.menu_items(active='admin')}
18 18 </%def>
19 19
20 <%def name="menu_bar_subnav()">
21 ${self.admin_menu(active='repository_groups')}
22 </%def>
23
20 24 <%def name="main()">
21 25 <div class="box">
22 26 <div class="title">
23 ${self.admin_menu()}
27
24 28 <ul class="links">
25 29 %if h.HasPermissionAny('hg.admin','hg.repogroup.create.true')():
26 30 <li>
27 31 <a href="${h.route_path('repo_group_new')}" class="btn btn-small btn-success">${_(u'Add Repository Group')}</a>
28 32 </li>
29 33 %endif
30 34 </ul>
31 35 </div>
32 36 <div id="repos_list_wrap">
33 37 <table id="group_list_table" class="display"></table>
34 38 </div>
35 39 </div>
36 40
37 41 <script>
38 42 $(document).ready(function() {
39 43
40 44 var get_datatable_count = function(){
41 45 var api = $('#group_list_table').dataTable().api();
42 46 $('#repo_group_count').text(api.page.info().recordsDisplay);
43 47 };
44 48
45 49 // repo group list
46 50 $('#group_list_table').DataTable({
47 51 data: ${c.data|n},
48 52 dom: 'rtp',
49 53 pageLength: ${c.visual.admin_grid_items},
50 54 order: [[ 0, "asc" ]],
51 55 columns: [
52 56 { data: {"_": "name",
53 57 "sort": "name_raw"}, title: "${_('Name')}", className: "td-componentname" },
54 58 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
55 59 { data: {"_": "desc",
56 60 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
57 61 { data: {"_": "last_change",
58 62 "sort": "last_change_raw",
59 63 "type": Number}, title: "${_('Last Change')}", className: "td-time" },
60 64 { data: {"_": "top_level_repos",
61 65 "sort": "top_level_repos"}, title: "${_('Number of top level repositories')}" },
62 66 { data: {"_": "owner",
63 67 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" },
64 68 { data: {"_": "action",
65 69 "sort": "action"}, title: "${_('Action')}", className: "td-action" }
66 70 ],
67 71 language: {
68 72 paginate: DEFAULT_GRID_PAGINATION,
69 73 emptyTable: _gettext("No repository groups available yet.")
70 74 },
71 75 "initComplete": function( settings, json ) {
72 76 get_datatable_count();
73 77 quick_repo_menu();
74 78 }
75 79 });
76 80
77 81 // update the counter when doing search
78 82 $('#group_list_table').on( 'search.dt', function (e,settings) {
79 83 get_datatable_count();
80 84 });
81 85
82 86 // filter, filter both grids
83 87 $('#q_filter').on( 'keyup', function () {
84 88
85 89 var repo_group_api = $('#group_list_table').dataTable().api();
86 90 repo_group_api
87 91 .columns(0)
88 92 .search(this.value)
89 93 .draw();
90 94 });
91 95
92 96 // refilter table if page load via back button
93 97 $("#q_filter").trigger('keyup');
94 98 });
95 99 </script>
96 100 </%def>
97 101
@@ -1,101 +1,104 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Repositories administration')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 13 ${h.link_to(_('Admin'),h.route_path('admin_home'))} &raquo; <span id="repo_count">0</span> ${_('repositories')}
14 14 </%def>
15 15
16 16 <%def name="menu_bar_nav()">
17 17 ${self.menu_items(active='admin')}
18 18 </%def>
19 19
20 <%def name="menu_bar_subnav()">
21 ${self.admin_menu(active='repositories')}
22 </%def>
23
20 24 <%def name="main()">
21 25 <div class="box">
22 26 <div class="title">
23 ${self.admin_menu()}
24 27 <ul class="links">
25 28 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
26 29 <li>
27 30 <a href="${h.route_path('repo_new')}" class="btn btn-small btn-success">${_(u'Add Repository')}</a>
28 31 </li>
29 32 %endif
30 33 </ul>
31 34 </div>
32 35 <div id="repos_list_wrap">
33 36 <table id="repo_list_table" class="display"></table>
34 37 </div>
35 38 </div>
36 39
37 40 <script>
38 41 $(document).ready(function() {
39 42
40 43 var get_datatable_count = function(){
41 44 var api = $('#repo_list_table').dataTable().api();
42 45 $('#repo_count').text(api.page.info().recordsDisplay);
43 46 };
44 47
45 48
46 49 // repo list
47 50 $('#repo_list_table').DataTable({
48 51 data: ${c.data|n},
49 52 dom: 'rtp',
50 53 pageLength: ${c.visual.admin_grid_items},
51 54 order: [[ 0, "asc" ]],
52 55 columns: [
53 56 { data: {"_": "name",
54 57 "sort": "name_raw"}, title: "${_('Name')}", className: "td-componentname" },
55 58 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
56 59 { data: {"_": "desc",
57 60 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
58 61 { data: {"_": "last_change",
59 62 "sort": "last_change_raw",
60 63 "type": Number}, title: "${_('Last Change')}", className: "td-time" },
61 64 { data: {"_": "last_changeset",
62 65 "sort": "last_changeset_raw",
63 66 "type": Number}, title: "${_('Commit')}", className: "td-commit" },
64 67 { data: {"_": "owner",
65 68 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" },
66 69 { data: {"_": "state",
67 70 "sort": "state"}, title: "${_('State')}", className: "td-tags td-state" },
68 71 { data: {"_": "action",
69 72 "sort": "action"}, title: "${_('Action')}", className: "td-action" }
70 73 ],
71 74 language: {
72 75 paginate: DEFAULT_GRID_PAGINATION,
73 76 emptyTable:_gettext("No repositories available yet.")
74 77 },
75 78 "initComplete": function( settings, json ) {
76 79 get_datatable_count();
77 80 quick_repo_menu();
78 81 }
79 82 });
80 83
81 84 // update the counter when doing search
82 85 $('#repo_list_table').on( 'search.dt', function (e,settings) {
83 86 get_datatable_count();
84 87 });
85 88
86 89 // filter, filter both grids
87 90 $('#q_filter').on( 'keyup', function () {
88 91 var repo_api = $('#repo_list_table').dataTable().api();
89 92 repo_api
90 93 .columns(0)
91 94 .search(this.value)
92 95 .draw();
93 96 });
94 97
95 98 // refilter table if page load via back button
96 99 $("#q_filter").trigger('keyup');
97 100 });
98 101
99 102 </script>
100 103
101 104 </%def>
@@ -1,53 +1,54 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Settings administration')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 13 &raquo;
14 14 ${_('Settings')}
15 15 </%def>
16
16 ##
17 17 <%def name="menu_bar_nav()">
18 18 ${self.menu_items(active='admin')}
19 19 </%def>
20 20
21 <%def name="menu_bar_subnav()">
22 ${self.admin_menu(active='settings')}
23 </%def>
24
21 25 <%def name="side_bar_nav()">
22 26 % for navitem in c.navlist:
23 27 <li class="${'active' if c.active in navitem.active_list else ''}">
24 28 <a href="${navitem.url}">${navitem.name}</a>
25 29 </li>
26 30 % endfor
27 31 </%def>
28 32
29 33 <%def name="main_content()">
30 34 <%include file="/admin/settings/settings_${c.active}.mako"/>
31 35 </%def>
32 36
33 37 <%def name="main()">
34 38 <div class="box">
35 <div class="title">
36 ${self.admin_menu()}
37 </div>
38 39
39 40 ##main
40 41 <div class='sidebar-col-wrapper'>
41 42 <div class="sidebar">
42 43 <ul class="nav nav-pills nav-stacked">
43 44 ${self.side_bar_nav()}
44 45 </ul>
45 46 </div>
46 47
47 48 <div class="main-content-auto-width">
48 49 ${self.main_content()}
49 50 </div>
50 51 </div>
51 52 </div>
52 53
53 54 </%def> No newline at end of file
@@ -1,115 +1,118 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('User groups administration')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 13 ${h.link_to(_('Admin'),h.route_path('admin_home'))} &raquo; <span id="user_group_count">0</span>
14 14 </%def>
15 15
16 16 <%def name="menu_bar_nav()">
17 17 ${self.menu_items(active='admin')}
18 18 </%def>
19 19
20 <%def name="menu_bar_subnav()">
21 ${self.admin_menu(active='user_groups')}
22 </%def>
23
20 24 <%def name="main()">
21 25 <div class="box">
22 26
23 27 <div class="title">
24 ${self.admin_menu()}
25 28 <ul class="links">
26 29 %if h.HasPermissionAny('hg.admin', 'hg.usergroup.create.true')():
27 30 <li>
28 31 <a href="${h.route_path('user_groups_new')}" class="btn btn-small btn-success">${_(u'Add User Group')}</a>
29 32 </li>
30 33 %endif
31 34 </ul>
32 35 </div>
33 36
34 37 <div id="repos_list_wrap">
35 38 <table id="user_group_list_table" class="display"></table>
36 39 </div>
37 40
38 41 </div>
39 42 <script>
40 43 $(document).ready(function() {
41 44 var $userGroupsListTable = $('#user_group_list_table');
42 45
43 46 // user list
44 47 $userGroupsListTable.DataTable({
45 48 processing: true,
46 49 serverSide: true,
47 50 ajax: {
48 51 "url": "${h.route_path('user_groups_data')}",
49 52 "dataSrc": function (json) {
50 53 var filteredCount = json.recordsFiltered;
51 54 var filteredInactiveCount = json.recordsFilteredInactive;
52 55 var totalInactive = json.recordsTotalInactive;
53 56 var total = json.recordsTotal;
54 57
55 58 var _text = _gettext(
56 59 "{0} ({1} inactive) of {2} user groups ({3} inactive)").format(
57 60 filteredCount, filteredInactiveCount, total, totalInactive);
58 61
59 62 if (total === filteredCount) {
60 63 _text = _gettext(
61 64 "{0} user groups ({1} inactive)").format(total, totalInactive);
62 65 }
63 66 $('#user_group_count').text(_text);
64 67 return json.data;
65 68 },
66 69 },
67 70
68 71 dom: 'rtp',
69 72 pageLength: ${c.visual.admin_grid_items},
70 73 order: [[ 0, "asc" ]],
71 74 columns: [
72 75 { data: {"_": "users_group_name",
73 76 "sort": "users_group_name"}, title: "${_('Name')}", className: "td-componentname" },
74 77 { data: {"_": "description",
75 78 "sort": "description"}, title: "${_('Description')}", className: "td-description" },
76 79 { data: {"_": "members",
77 80 "sort": "members"}, title: "${_('Members')}", className: "td-number" },
78 81 { data: {"_": "sync",
79 82 "sort": "sync"}, title: "${_('Sync')}", className: "td-sync" },
80 83 { data: {"_": "active",
81 84 "sort": "active"}, title: "${_('Active')}", className: "td-active" },
82 85 { data: {"_": "owner",
83 86 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" },
84 87 { data: {"_": "action",
85 88 "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false}
86 89 ],
87 90 language: {
88 91 paginate: DEFAULT_GRID_PAGINATION,
89 92 sProcessing: _gettext('loading...'),
90 93 emptyTable: _gettext("No user groups available yet.")
91 94 }
92 95 });
93 96
94 97 $userGroupsListTable.on('xhr.dt', function(e, settings, json, xhr){
95 98 $userGroupsListTable.css('opacity', 1);
96 99 });
97 100
98 101 $userGroupsListTable.on('preXhr.dt', function(e, settings, data){
99 102 $userGroupsListTable.css('opacity', 0.3);
100 103 });
101 104
102 105 // filter
103 106 $('#q_filter').on('keyup',
104 107 $.debounce(250, function() {
105 108 $('#user_group_list_table').DataTable().search(
106 109 $('#q_filter').val()
107 110 ).draw();
108 111 })
109 112 );
110 113
111 114 });
112 115
113 116 </script>
114 117
115 118 </%def>
@@ -1,123 +1,126 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Users administration')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
13 13 ${h.link_to(_('Admin'),h.route_path('admin_home'))} &raquo; <span id="user_count">0</span>
14 14 </%def>
15 15
16 16 <%def name="menu_bar_nav()">
17 17 ${self.menu_items(active='admin')}
18 18 </%def>
19 19
20 <%def name="menu_bar_subnav()">
21 ${self.admin_menu(active='users')}
22 </%def>
23
20 24 <%def name="main()">
21 25
22 26 <div class="box">
23 27
24 28 <div class="title">
25 ${self.admin_menu()}
26 29 <ul class="links">
27 30 <li>
28 31 <a href="${h.route_path('users_new')}" class="btn btn-small btn-success">${_(u'Add User')}</a>
29 32 </li>
30 33 </ul>
31 34 </div>
32 35
33 36 <div id="repos_list_wrap">
34 37 <table id="user_list_table" class="display"></table>
35 38 </div>
36 39 </div>
37 40
38 41 <script type="text/javascript">
39 42
40 43 $(document).ready(function() {
41 44 var $userListTable = $('#user_list_table');
42 45 // user list
43 46 $userListTable.DataTable({
44 47 processing: true,
45 48 serverSide: true,
46 49 ajax: {
47 50 "url": "${h.route_path('users_data')}",
48 51 "dataSrc": function ( json ) {
49 52 var filteredCount = json.recordsFiltered;
50 53 var filteredInactiveCount = json.recordsFilteredInactive;
51 54 var totalInactive = json.recordsTotalInactive;
52 55 var total = json.recordsTotal;
53 56
54 57 var _text = _gettext(
55 58 "{0} ({1} inactive) of {2} users ({3} inactive)").format(
56 59 filteredCount, filteredInactiveCount, total, totalInactive);
57 60
58 61 if(total === filteredCount){
59 62 _text = _gettext(
60 63 "{0} users ({1} inactive)").format(total, totalInactive);
61 64 }
62 65 $('#user_count').text(_text);
63 66 return json.data;
64 67 }
65 68 },
66 69 dom: 'rtp',
67 70 pageLength: ${c.visual.admin_grid_items},
68 71 order: [[ 0, "asc" ]],
69 72 columns: [
70 73 { data: {"_": "username",
71 74 "sort": "username"}, title: "${_('Username')}", className: "td-user" },
72 75 { data: {"_": "email",
73 76 "sort": "email"}, title: "${_('Email')}", className: "td-email" },
74 77 { data: {"_": "first_name",
75 78 "sort": "first_name"}, title: "${_('First Name')}", className: "td-user" },
76 79 { data: {"_": "last_name",
77 80 "sort": "last_name"}, title: "${_('Last Name')}", className: "td-user" },
78 81 { data: {"_": "last_activity",
79 82 "sort": "last_activity",
80 83 "type": Number}, title: "${_('Last activity')}", className: "td-time" },
81 84 { data: {"_": "active",
82 85 "sort": "active"}, title: "${_('Active')}", className: "td-active" },
83 86 { data: {"_": "admin",
84 87 "sort": "admin"}, title: "${_('Super admin')}", className: "td-admin" },
85 88 { data: {"_": "extern_type",
86 89 "sort": "extern_type"}, title: "${_('Auth type')}", className: "td-type" },
87 90 { data: {"_": "action",
88 91 "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false }
89 92 ],
90 93 language: {
91 94 paginate: DEFAULT_GRID_PAGINATION,
92 95 sProcessing: _gettext('loading...'),
93 96 emptyTable: _gettext("No users available yet.")
94 97 },
95 98
96 99 "createdRow": function ( row, data, index ) {
97 100 if (!data['active_raw']){
98 101 $(row).addClass('closed')
99 102 }
100 103 }
101 104 });
102 105
103 106 $userListTable.on('xhr.dt', function(e, settings, json, xhr){
104 107 $userListTable.css('opacity', 1);
105 108 });
106 109
107 110 $userListTable.on('preXhr.dt', function(e, settings, data){
108 111 $userListTable.css('opacity', 0.3);
109 112 });
110 113
111 114 // filter
112 115 $('#q_filter').on('keyup',
113 116 $.debounce(250, function() {
114 117 $userListTable.DataTable().search(
115 118 $('#q_filter').val()
116 119 ).draw();
117 120 })
118 121 );
119 122
120 123 });
121 124 </script>
122 125
123 126 </%def>
@@ -1,911 +1,918 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="root.mako"/>
3 3
4 4 <%include file="/ejs_templates/templates.html"/>
5 5
6 6 <div class="outerwrapper">
7 7 <!-- HEADER -->
8 8 <div class="header">
9 9 <div id="header-inner" class="wrapper">
10 10 <div id="logo">
11 11 <div class="logo-wrapper">
12 12 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
13 13 </div>
14 14 % if c.rhodecode_name:
15 15 <div class="branding">
16 16 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
17 17 </div>
18 18 % endif
19 19 </div>
20 20 <!-- MENU BAR NAV -->
21 21 ${self.menu_bar_nav()}
22 22 <!-- END MENU BAR NAV -->
23 23 </div>
24 24 </div>
25 25 ${self.menu_bar_subnav()}
26 26 <!-- END HEADER -->
27 27
28 28 <!-- CONTENT -->
29 29 <div id="content" class="wrapper">
30 30
31 31 <rhodecode-toast id="notifications"></rhodecode-toast>
32 32
33 33 <div class="main">
34 34 ${next.main()}
35 35 </div>
36 36 </div>
37 37 <!-- END CONTENT -->
38 38
39 39 </div>
40 40 <!-- FOOTER -->
41 41 <div id="footer">
42 42 <div id="footer-inner" class="title wrapper">
43 43 <div>
44 44 <p class="footer-link-right">
45 45 % if c.visual.show_version:
46 46 RhodeCode Enterprise ${c.rhodecode_version} ${c.rhodecode_edition}
47 47 % endif
48 48 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
49 49 % if c.visual.rhodecode_support_url:
50 50 <a href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a>
51 51 % endif
52 52 </p>
53 53 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
54 54 <p class="server-instance" style="display:${sid}">
55 55 ## display hidden instance ID if specially defined
56 56 % if c.rhodecode_instanceid:
57 57 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
58 58 % endif
59 59 </p>
60 60 </div>
61 61 </div>
62 62 </div>
63 63
64 64 <!-- END FOOTER -->
65 65
66 66 ### MAKO DEFS ###
67 67
68 68 <%def name="menu_bar_subnav()">
69 69 </%def>
70 70
71 71 <%def name="breadcrumbs(class_='breadcrumbs')">
72 72 <div class="${class_}">
73 73 ${self.breadcrumbs_links()}
74 74 </div>
75 75 </%def>
76 76
77 <%def name="admin_menu()">
78
77 <%def name="admin_menu(active=None)">
78 <div id="context-bar">
79 <div class="wrapper">
79 80 <ul id="context-pages" class="navigation horizontal-list">
80 81 <%
81 82 repositories=c.rhodecode_user.repositories_admin
82 83 repository_groups=c.rhodecode_user.repository_groups_admin
83 84 user_groups=c.rhodecode_user.user_groups_admin or h.HasPermissionAny('hg.usergroup.create.true')()
85 def is_active(selected):
86 if selected == active:
87 return "active"
84 88 %>
85 89 ## super admin case
86 90 % if c.rhodecode_user.is_admin:
87 <li><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
88 <li><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
89 <li><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
90 <li><a href="${h.route_path('users')}">${_('Users')}</a></li>
91 <li><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
92 <li><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
93 <li><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
94 <li><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
95 <li><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
96 <li><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
91 <li class="${is_active('audit_logs')}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
92 <li class="${is_active('repositories')}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
93 <li class="${is_active('repository_groups')}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
94 <li class="${is_active('users')}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
95 <li class="${is_active('user_groups')}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
96 <li class="${is_active('permissions')}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
97 <li class="${is_active('authentication')}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
98 <li class="${is_active('integrations')}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
99 <li class="${is_active('defaults')}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
100 <li class="${is_active('settings')}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
97 101
98 102 ## delegated admin
99 103 % elif repositories or repository_groups or user_groups:
100 104
101 105 %if repositories:
102 <li class="local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
106 <li class="${is_active('repositories')} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
103 107 %endif
104 108 %if repository_groups:
105 <li class="local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
109 <li class="${is_active('repository_groups')} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
106 110 %endif
107 111 %if user_groups:
108 <li class="local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
112 <li class="${is_active('user_groups')} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
109 113 %endif
110 114 % endif
111 115 </ul>
116 </div>
117 <div class="clear"></div>
118 </div>
112 119 </%def>
113 120
114 121
115 122 <%def name="dt_info_panel(elements)">
116 123 <dl class="dl-horizontal">
117 124 %for dt, dd, title, show_items in elements:
118 125 <dt>${dt}:</dt>
119 126 <dd title="${h.tooltip(title)}">
120 127 %if callable(dd):
121 128 ## allow lazy evaluation of elements
122 129 ${dd()}
123 130 %else:
124 131 ${dd}
125 132 %endif
126 133 %if show_items:
127 134 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
128 135 %endif
129 136 </dd>
130 137
131 138 %if show_items:
132 139 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
133 140 %for item in show_items:
134 141 <dt></dt>
135 142 <dd>${item}</dd>
136 143 %endfor
137 144 </div>
138 145 %endif
139 146
140 147 %endfor
141 148 </dl>
142 149 </%def>
143 150
144 151
145 152 <%def name="gravatar(email, size=16)">
146 153 <%
147 154 if (size > 16):
148 155 gravatar_class = 'gravatar gravatar-large'
149 156 else:
150 157 gravatar_class = 'gravatar'
151 158 %>
152 159 <%doc>
153 160 TODO: johbo: For now we serve double size images to make it smooth
154 161 for retina. This is how it worked until now. Should be replaced
155 162 with a better solution at some point.
156 163 </%doc>
157 164 <img class="${gravatar_class}" src="${h.gravatar_url(email, size * 2)}" height="${size}" width="${size}">
158 165 </%def>
159 166
160 167
161 168 <%def name="gravatar_with_user(contact, size=16, show_disabled=False)">
162 169 <% email = h.email_or_none(contact) %>
163 170 <div class="rc-user tooltip" title="${h.tooltip(h.author_string(email))}">
164 171 ${self.gravatar(email, size)}
165 172 <span class="${'user user-disabled' if show_disabled else 'user'}"> ${h.link_to_user(contact)}</span>
166 173 </div>
167 174 </%def>
168 175
169 176
170 177 <%def name="repo_page_title(repo_instance)">
171 178 <div class="title-content">
172 179 <div class="title-main">
173 180 ## SVN/HG/GIT icons
174 181 %if h.is_hg(repo_instance):
175 182 <i class="icon-hg"></i>
176 183 %endif
177 184 %if h.is_git(repo_instance):
178 185 <i class="icon-git"></i>
179 186 %endif
180 187 %if h.is_svn(repo_instance):
181 188 <i class="icon-svn"></i>
182 189 %endif
183 190
184 191 ## public/private
185 192 %if repo_instance.private:
186 193 <i class="icon-repo-private"></i>
187 194 %else:
188 195 <i class="icon-repo-public"></i>
189 196 %endif
190 197
191 198 ## repo name with group name
192 199 ${h.breadcrumb_repo_link(repo_instance)}
193 200
194 201 </div>
195 202
196 203 ## FORKED
197 204 %if repo_instance.fork:
198 205 <p>
199 206 <i class="icon-code-fork"></i> ${_('Fork of')}
200 207 ${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))}
201 208 </p>
202 209 %endif
203 210
204 211 ## IMPORTED FROM REMOTE
205 212 %if repo_instance.clone_uri:
206 213 <p>
207 214 <i class="icon-code-fork"></i> ${_('Clone from')}
208 215 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
209 216 </p>
210 217 %endif
211 218
212 219 ## LOCKING STATUS
213 220 %if repo_instance.locked[0]:
214 221 <p class="locking_locked">
215 222 <i class="icon-repo-lock"></i>
216 223 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
217 224 </p>
218 225 %elif repo_instance.enable_locking:
219 226 <p class="locking_unlocked">
220 227 <i class="icon-repo-unlock"></i>
221 228 ${_('Repository not locked. Pull repository to lock it.')}
222 229 </p>
223 230 %endif
224 231
225 232 </div>
226 233 </%def>
227 234
228 235 <%def name="repo_menu(active=None)">
229 236 <%
230 237 def is_active(selected):
231 238 if selected == active:
232 239 return "active"
233 240 %>
234 241
235 <!--- CONTEXT BAR -->
242 <!--- REPO CONTEXT BAR -->
236 243 <div id="context-bar">
237 244 <div class="wrapper">
238 245
239 246 <div class="title">
240 247 ${self.repo_page_title(c.rhodecode_db_repo)}
241 248 </div>
242 249
243 250 <ul id="context-pages" class="navigation horizontal-list">
244 251 <li class="${is_active('summary')}"><a class="menulink" href="${h.route_path('repo_summary', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
245 252 <li class="${is_active('changelog')}"><a class="menulink" href="${h.route_path('repo_changelog', repo_name=c.repo_name)}"><div class="menulabel">${_('Changelog')}</div></a></li>
246 253 <li class="${is_active('files')}"><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>
247 254 <li class="${is_active('compare')}"><a class="menulink" href="${h.route_path('repo_compare_select',repo_name=c.repo_name)}"><div class="menulabel">${_('Compare')}</div></a></li>
248 255
249 256 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
250 257 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
251 258 <li class="${is_active('showpullrequest')}">
252 259 <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)}">
253 260 %if c.repository_pull_requests:
254 261 <span class="pr_notifications">${c.repository_pull_requests}</span>
255 262 %endif
256 263 <div class="menulabel">${_('Pull Requests')}</div>
257 264 </a>
258 265 </li>
259 266 %endif
260 267
261 268 <li class="${is_active('options')}">
262 269 <a class="menulink dropdown">
263 270 <div class="menulabel">${_('Options')} <div class="show_more"></div></div>
264 271 </a>
265 272 <ul class="submenu">
266 273 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
267 274 <li><a href="${h.route_path('edit_repo',repo_name=c.repo_name)}">${_('Repository Settings')}</a></li>
268 275 %endif
269 276 %if c.rhodecode_db_repo.fork:
270 277 <li>
271 278 <a title="${h.tooltip(_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name))}"
272 279 href="${h.route_path('repo_compare',
273 280 repo_name=c.rhodecode_db_repo.fork.repo_name,
274 281 source_ref_type=c.rhodecode_db_repo.landing_rev[0],
275 282 source_ref=c.rhodecode_db_repo.landing_rev[1],
276 283 target_repo=c.repo_name,target_ref_type='branch' if request.GET.get('branch') else c.rhodecode_db_repo.landing_rev[0],
277 284 target_ref=request.GET.get('branch') or c.rhodecode_db_repo.landing_rev[1],
278 285 _query=dict(merge=1))}"
279 286 >
280 287 ${_('Compare fork')}
281 288 </a>
282 289 </li>
283 290 %endif
284 291
285 292 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking:
286 293 %if c.rhodecode_db_repo.locked[0]:
287 294 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock')}</a></li>
288 295 %else:
289 296 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock')}</a></li>
290 297 %endif
291 298 %endif
292 299 %if c.rhodecode_user.username != h.DEFAULT_USER:
293 300 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
294 301 <li><a href="${h.route_path('repo_fork_new',repo_name=c.repo_name)}">${_('Fork')}</a></li>
295 302 <li><a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a></li>
296 303 %endif
297 304 %endif
298 305 </ul>
299 306 </li>
300 307 </ul>
301 308 </div>
302 309 <div class="clear"></div>
303 310 </div>
304 311 % if c.rhodecode_db_repo.archived:
305 312 <div class="alert alert-warning text-center">
306 313 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
307 314 </div>
308 315 % endif
309 <!--- END CONTEXT BAR -->
316 <!--- REPO END CONTEXT BAR -->
310 317
311 318 </%def>
312 319
313 320 <%def name="repo_group_page_title(repo_group_instance)">
314 321 <div class="title-content">
315 322 <div class="title-main">
316 323 ## Repository Group icon
317 324 <i class="icon-folder-close"></i>
318 325
319 326 ## repo name with group name
320 327 ${h.breadcrumb_repo_group_link(repo_group_instance)}
321 328 </div>
322 329
323 330 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
324 331 <div class="repo-group-desc">
325 332 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
326 333 </div>
327 334
328 335 </div>
329 336 </%def>
330 337
331 338 <%def name="repo_group_menu(active=None)">
332 339 <%
333 340 def is_active(selected):
334 341 if selected == active:
335 342 return "active"
336 343
337 344 is_admin = h.HasPermissionAny('hg.admin')('can create repos index page')
338 345
339 346 gr_name = c.repo_group.group_name if c.repo_group else None
340 347 # create repositories with write permission on group is set to true
341 348 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
342 349 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
343 350 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
344 351
345 352 %>
346 353
347 <!--- CONTEXT BAR -->
354 <!--- REPO GROUP CONTEXT BAR -->
348 355 <div id="context-bar">
349 356 <div class="wrapper">
350 357 <ul id="context-pages" class="navigation horizontal-list">
351 358 <li class="${is_active('home')}"><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></li>
352 359
353 360 <li class="${is_active('options')}">
354 361 <a class="menulink dropdown">
355 362 <div class="menulabel">${_('Options')} <div class="show_more"></div></div>
356 363 </a>
357 364 <ul class="submenu">
358 365 %if is_admin or group_admin:
359 366 <li><a 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')}">${_('Group Settings')}</a></li>
360 367 %endif
361 368 %if is_admin or group_admin or (group_write and create_on_write):
362 369 <li><a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('Add Repository')}</a></li>
363 370 %endif
364 371 %if is_admin or group_admin:
365 372 <li><a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'Add Parent Group')}</a></li>
366 373 %endif
367 374 </ul>
368 375 </li>
369 376 </ul>
370 377 </div>
371 378 <div class="clear"></div>
372 379 </div>
373 380
374 <!--- END CONTEXT BAR -->
381 <!--- REPO GROUP CONTEXT BAR -->
375 382
376 383 </%def>
377 384
378 385
379 386 <%def name="usermenu(active=False)">
380 387 ## USER MENU
381 388 <li id="quick_login_li" class="${'active' if active else ''}">
382 389 % if c.rhodecode_user.username == h.DEFAULT_USER:
383 390 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
384 391 ${gravatar(c.rhodecode_user.email, 20)}
385 392 <span class="user">
386 393 <span>${_('Sign in')}</span>
387 394 </span>
388 395 </a>
389 396 % else:
390 397 ## logged in user
391 398 <a id="quick_login_link" class="menulink childs">
392 399 ${gravatar(c.rhodecode_user.email, 20)}
393 400 <span class="user">
394 401 <span class="menu_link_user">${c.rhodecode_user.username}</span>
395 402 <div class="show_more"></div>
396 403 </span>
397 404 </a>
398 405 ## subnav with menu for logged in user
399 406 <div class="user-menu submenu">
400 407 <div id="quick_login">
401 408 %if c.rhodecode_user.username != h.DEFAULT_USER:
402 409 <div class="">
403 410 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
404 411 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
405 412 <div class="email">${c.rhodecode_user.email}</div>
406 413 </div>
407 414 <div class="">
408 415 <ol class="links">
409 416 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
410 417 % if c.rhodecode_user.personal_repo_group:
411 418 <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>
412 419 % endif
413 420 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
414 421 ## bookmark-items
415 422 <li class="bookmark-items">
416 423 ${_('Bookmarks')}
417 424 <div class="pull-right">
418 425 <a href="${h.route_path('my_account_bookmarks')}">${_('Manage')}</a>
419 426 </div>
420 427 </li>
421 428 % if not c.bookmark_items:
422 429 <li>
423 430 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
424 431 </li>
425 432 % endif
426 433 % for item in c.bookmark_items:
427 434 <li>
428 435 % if item.repository:
429 436 <div>
430 437 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
431 438 <code>${item.position}</code>
432 439 % if item.repository.repo_type == 'hg':
433 440 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
434 441 % elif item.repository.repo_type == 'git':
435 442 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
436 443 % elif item.repository.repo_type == 'svn':
437 444 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
438 445 % endif
439 446 ${(item.title or h.shorter(item.repository.repo_name, 30))}
440 447 </a>
441 448 </div>
442 449 % elif item.repository_group:
443 450 <div>
444 451 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
445 452 <code>${item.position}</code>
446 453 <i class="icon-folder-close" title="${_('Repository group')}" style="font-size: 16px"></i>
447 454 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
448 455 </a>
449 456 </div>
450 457 % else:
451 458 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
452 459 <code>${item.position}</code>
453 460 ${item.title}
454 461 </a>
455 462 % endif
456 463 </li>
457 464 % endfor
458 465
459 466 <li class="logout">
460 467 ${h.secure_form(h.route_path('logout'), request=request)}
461 468 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
462 469 ${h.end_form()}
463 470 </li>
464 471 </ol>
465 472 </div>
466 473 %endif
467 474 </div>
468 475 </div>
469 476 ## unread counter
470 477 <div class="pill_container">
471 478 <a class="menu_link_notifications ${'empty' if c.unread_notifications == 0 else ''}" href="${h.route_path('notifications_show_all')}">${c.unread_notifications}</a>
472 479 </div>
473 480 % endif
474 481 </li>
475 482 </%def>
476 483
477 484 <%def name="menu_items(active=None)">
478 485 <%
479 486 def is_active(selected):
480 487 if selected == active:
481 488 return "active"
482 489 return ""
483 490 %>
484 491
485 492 <ul id="quick" class="main_nav navigation horizontal-list">
486 493 ## notice box for important system messages
487 494 <li style="display: none">
488 495 <a class="notice-box" href="#openNotice" onclick="showNoticeBox(); return false">
489 496 <div class="menulabel-notice" >
490 497 0
491 498 </div>
492 499 </a>
493 500 </li>
494 501
495 502 ## Main filter
496 503 <li>
497 504 <div class="menulabel main_filter_box">
498 505 <div class="main_filter_input_box">
499 506 <ul class="searchItems">
500 507
501 508 % if c.template_context['search_context']['repo_id']:
502 509 <li class="searchTag searchTagFilter searchTagHidable" >
503 510 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
504 511 <span class="tag">
505 512 This repo
506 513 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-delete"></i></a>
507 514 </span>
508 515 ##</a>
509 516 </li>
510 517 % elif c.template_context['search_context']['repo_group_id']:
511 518 <li class="searchTag searchTagFilter searchTagHidable">
512 519 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
513 520 <span class="tag">
514 521 This group
515 522 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-delete"></i></a>
516 523 </span>
517 524 ##</a>
518 525 </li>
519 526 % endif
520 527
521 528 <li class="searchTagInput">
522 529 <input class="main_filter_input" id="main_filter" size="15" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
523 530 </li>
524 531 <li class="searchTag searchTagHelp">
525 532 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
526 533 </li>
527 534 </ul>
528 535 </div>
529 536 </div>
530 537
531 538 <div id="main_filter_help" style="display: none">
532 539 - Use '/' key to quickly access this field.
533 540
534 541 - Enter a name of repository, or repository group for quick search.
535 542
536 543 - Prefix query to allow special search:
537 544
538 545 user:admin, to search for usernames, always global
539 546
540 547 user_group:devops, to search for user groups, always global
541 548
542 549 commit:efced4, to search for commits, scoped to repositories or groups
543 550
544 551 file:models.py, to search for file paths, scoped to repositories or groups
545 552
546 553 % if c.template_context['search_context']['repo_id']:
547 554 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>
548 555 % elif c.template_context['search_context']['repo_group_id']:
549 556 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>
550 557 % else:
551 558 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
552 559 % endif
553 560 </div>
554 561 </li>
555 562
556 563 ## ROOT MENU
557 564 <li class="${is_active('home')}">
558 565 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
559 566 <div class="menulabel">${_('Home')}</div>
560 567 </a>
561 568 </li>
562 569
563 570 %if c.rhodecode_user.username != h.DEFAULT_USER:
564 571 <li class="${is_active('journal')}">
565 572 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
566 573 <div class="menulabel">${_('Journal')}</div>
567 574 </a>
568 575 </li>
569 576 %else:
570 577 <li class="${is_active('journal')}">
571 578 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
572 579 <div class="menulabel">${_('Public journal')}</div>
573 580 </a>
574 581 </li>
575 582 %endif
576 583
577 584 <li class="${is_active('gists')}">
578 585 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
579 586 <div class="menulabel">${_('Gists')}</div>
580 587 </a>
581 588 </li>
582 589
583 590 <li class="${is_active('admin')}">
584 591 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
585 592 <div class="menulabel">${_('Admin')} </div>
586 593 </a>
587 594 </li>
588 595
589 596 ## render extra user menu
590 597 ${usermenu(active=(active=='my_account'))}
591 598
592 599 % if c.debug_style:
593 600 <li>
594 601 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
595 602 <div class="menulabel">${_('[Style]')}</div>
596 603 </a>
597 604 </li>
598 605 % endif
599 606 </ul>
600 607
601 608 <script type="text/javascript">
602 609 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
603 610
604 611 var formatRepoResult = function(result, container, query, escapeMarkup) {
605 612 return function(data, escapeMarkup) {
606 613 if (!data.repo_id){
607 614 return data.text; // optgroup text Repositories
608 615 }
609 616
610 617 var tmpl = '';
611 618 var repoType = data['repo_type'];
612 619 var repoName = data['text'];
613 620
614 621 if(data && data.type == 'repo'){
615 622 if(repoType === 'hg'){
616 623 tmpl += '<i class="icon-hg"></i> ';
617 624 }
618 625 else if(repoType === 'git'){
619 626 tmpl += '<i class="icon-git"></i> ';
620 627 }
621 628 else if(repoType === 'svn'){
622 629 tmpl += '<i class="icon-svn"></i> ';
623 630 }
624 631 if(data['private']){
625 632 tmpl += '<i class="icon-lock" ></i> ';
626 633 }
627 634 else if(visualShowPublicIcon){
628 635 tmpl += '<i class="icon-unlock-alt"></i> ';
629 636 }
630 637 }
631 638 tmpl += escapeMarkup(repoName);
632 639 return tmpl;
633 640
634 641 }(result, escapeMarkup);
635 642 };
636 643
637 644 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
638 645 return function(data, escapeMarkup) {
639 646 if (!data.repo_group_id){
640 647 return data.text; // optgroup text Repositories
641 648 }
642 649
643 650 var tmpl = '';
644 651 var repoGroupName = data['text'];
645 652
646 653 if(data){
647 654
648 655 tmpl += '<i class="icon-folder-close"></i> ';
649 656
650 657 }
651 658 tmpl += escapeMarkup(repoGroupName);
652 659 return tmpl;
653 660
654 661 }(result, escapeMarkup);
655 662 };
656 663
657 664 var escapeRegExChars = function (value) {
658 665 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
659 666 };
660 667
661 668 var getRepoIcon = function(repo_type) {
662 669 if (repo_type === 'hg') {
663 670 return '<i class="icon-hg"></i> ';
664 671 }
665 672 else if (repo_type === 'git') {
666 673 return '<i class="icon-git"></i> ';
667 674 }
668 675 else if (repo_type === 'svn') {
669 676 return '<i class="icon-svn"></i> ';
670 677 }
671 678 return ''
672 679 };
673 680
674 681 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
675 682
676 683 if (value.split(':').length === 2) {
677 684 value = value.split(':')[1]
678 685 }
679 686
680 687 var searchType = data['type'];
681 688 var valueDisplay = data['value_display'];
682 689
683 690 var pattern = '(' + escapeRegExChars(value) + ')';
684 691
685 692 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
686 693
687 694 // highlight match
688 695 if (searchType != 'text') {
689 696 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
690 697 }
691 698
692 699 var icon = '';
693 700
694 701 if (searchType === 'hint') {
695 702 icon += '<i class="icon-folder-close"></i> ';
696 703 }
697 704 // full text search
698 705 else if (searchType === 'search') {
699 706 icon += '<i class="icon-more"></i> ';
700 707 }
701 708 // repository
702 709 else if (searchType === 'repo') {
703 710
704 711 var repoIcon = getRepoIcon(data['repo_type']);
705 712 icon += repoIcon;
706 713
707 714 if (data['private']) {
708 715 icon += '<i class="icon-lock" ></i> ';
709 716 }
710 717 else if (visualShowPublicIcon) {
711 718 icon += '<i class="icon-unlock-alt"></i> ';
712 719 }
713 720 }
714 721 // repository groups
715 722 else if (searchType === 'repo_group') {
716 723 icon += '<i class="icon-folder-close"></i> ';
717 724 }
718 725 // user group
719 726 else if (searchType === 'user_group') {
720 727 icon += '<i class="icon-group"></i> ';
721 728 }
722 729 // user
723 730 else if (searchType === 'user') {
724 731 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
725 732 }
726 733 // commit
727 734 else if (searchType === 'commit') {
728 735 var repo_data = data['repo_data'];
729 736 var repoIcon = getRepoIcon(repo_data['repository_type']);
730 737 if (repoIcon) {
731 738 icon += repoIcon;
732 739 } else {
733 740 icon += '<i class="icon-tag"></i>';
734 741 }
735 742 }
736 743 // file
737 744 else if (searchType === 'file') {
738 745 var repo_data = data['repo_data'];
739 746 var repoIcon = getRepoIcon(repo_data['repository_type']);
740 747 if (repoIcon) {
741 748 icon += repoIcon;
742 749 } else {
743 750 icon += '<i class="icon-tag"></i>';
744 751 }
745 752 }
746 753 // generic text
747 754 else if (searchType === 'text') {
748 755 icon = '';
749 756 }
750 757
751 758 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
752 759 return tmpl.format(icon, valueDisplay);
753 760 };
754 761
755 762 var handleSelect = function(element, suggestion) {
756 763 if (suggestion.type === "hint") {
757 764 // we skip action
758 765 $('#main_filter').focus();
759 766 }
760 767 else if (suggestion.type === "text") {
761 768 // we skip action
762 769 $('#main_filter').focus();
763 770
764 771 } else {
765 772 window.location = suggestion['url'];
766 773 }
767 774 };
768 775
769 776 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
770 777 if (queryLowerCase.split(':').length === 2) {
771 778 queryLowerCase = queryLowerCase.split(':')[1]
772 779 }
773 780 if (suggestion.type === "text") {
774 781 // special case we don't want to "skip" display for
775 782 return true
776 783 }
777 784 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
778 785 };
779 786
780 787 var cleanContext = {
781 788 repo_view_type: null,
782 789
783 790 repo_id: null,
784 791 repo_name: "",
785 792
786 793 repo_group_id: null,
787 794 repo_group_name: null
788 795 };
789 796 var removeGoToFilter = function () {
790 797 $('.searchTagHidable').hide();
791 798 $('#main_filter').autocomplete(
792 799 'setOptions', {params:{search_context: cleanContext}});
793 800 };
794 801
795 802 $('#main_filter').autocomplete({
796 803 serviceUrl: pyroutes.url('goto_switcher_data'),
797 804 params: {
798 805 "search_context": templateContext.search_context
799 806 },
800 807 minChars:2,
801 808 maxHeight:400,
802 809 deferRequestBy: 300, //miliseconds
803 810 tabDisabled: true,
804 811 autoSelectFirst: false,
805 812 formatResult: autocompleteMainFilterFormatResult,
806 813 lookupFilter: autocompleteMainFilterResult,
807 814 onSelect: function (element, suggestion) {
808 815 handleSelect(element, suggestion);
809 816 return false;
810 817 },
811 818 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
812 819 if (jqXHR !== 'abort') {
813 820 alert("Error during search.\nError code: {0}".format(textStatus));
814 821 window.location = '';
815 822 }
816 823 }
817 824 });
818 825
819 826 showMainFilterBox = function () {
820 827 $('#main_filter_help').toggle();
821 828 };
822 829
823 830 $('#main_filter').on('keydown.autocomplete', function (e) {
824 831
825 832 var BACKSPACE = 8;
826 833 var el = $(e.currentTarget);
827 834 if(e.which === BACKSPACE){
828 835 var inputVal = el.val();
829 836 if (inputVal === ""){
830 837 removeGoToFilter()
831 838 }
832 839 }
833 840 });
834 841
835 842 </script>
836 843 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
837 844 </%def>
838 845
839 846 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
840 847 <div class="modal-dialog">
841 848 <div class="modal-content">
842 849 <div class="modal-header">
843 850 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
844 851 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
845 852 </div>
846 853 <div class="modal-body">
847 854 <div class="block-left">
848 855 <table class="keyboard-mappings">
849 856 <tbody>
850 857 <tr>
851 858 <th></th>
852 859 <th>${_('Site-wide shortcuts')}</th>
853 860 </tr>
854 861 <%
855 862 elems = [
856 863 ('/', 'Use quick search box'),
857 864 ('g h', 'Goto home page'),
858 865 ('g g', 'Goto my private gists page'),
859 866 ('g G', 'Goto my public gists page'),
860 867 ('g 0-9', 'Goto bookmarked items from 0-9'),
861 868 ('n r', 'New repository page'),
862 869 ('n g', 'New gist page'),
863 870 ]
864 871 %>
865 872 %for key, desc in elems:
866 873 <tr>
867 874 <td class="keys">
868 875 <span class="key tag">${key}</span>
869 876 </td>
870 877 <td>${desc}</td>
871 878 </tr>
872 879 %endfor
873 880 </tbody>
874 881 </table>
875 882 </div>
876 883 <div class="block-left">
877 884 <table class="keyboard-mappings">
878 885 <tbody>
879 886 <tr>
880 887 <th></th>
881 888 <th>${_('Repositories')}</th>
882 889 </tr>
883 890 <%
884 891 elems = [
885 892 ('g s', 'Goto summary page'),
886 893 ('g c', 'Goto changelog page'),
887 894 ('g f', 'Goto files page'),
888 895 ('g F', 'Goto files page with file search activated'),
889 896 ('g p', 'Goto pull requests page'),
890 897 ('g o', 'Goto repository settings'),
891 898 ('g O', 'Goto repository permissions settings'),
892 899 ]
893 900 %>
894 901 %for key, desc in elems:
895 902 <tr>
896 903 <td class="keys">
897 904 <span class="key tag">${key}</span>
898 905 </td>
899 906 <td>${desc}</td>
900 907 </tr>
901 908 %endfor
902 909 </tbody>
903 910 </table>
904 911 </div>
905 912 </div>
906 913 <div class="modal-footer">
907 914 </div>
908 915 </div><!-- /.modal-content -->
909 916 </div><!-- /.modal-dialog -->
910 917 </div><!-- /.modal -->
911 918
General Comments 0
You need to be logged in to leave comments. Login now