##// END OF EJS Templates
users/user-groups: added context of what we're editing....
marcink -
r4232:60646747 stable
parent child Browse files
Show More
@@ -1,85 +1,89 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <%
3 <%
4 elems = [
4 elems = [
5 (_('User Group ID'), c.user_group.users_group_id, '', ''),
5 (_('User Group ID'), c.user_group.users_group_id, '', ''),
6 (_('Owner'), lambda:base.gravatar_with_user(c.user_group.user.email), '', ''),
6 (_('Owner'), lambda:base.gravatar_with_user(c.user_group.user.email), '', ''),
7 (_('Created on'), h.format_date(c.user_group.created_on), '', '',),
7 (_('Created on'), h.format_date(c.user_group.created_on), '', '',),
8
8
9 (_('Members'), len(c.group_members_obj),'', [x for x in c.group_members_obj]),
9 (_('Members'), len(c.group_members_obj),'', [x for x in c.group_members_obj]),
10 (_('Automatic member sync'), 'Yes' if c.user_group.group_data.get('extern_type') else 'No', '', '',),
10 (_('Automatic member sync'), 'Yes' if c.user_group.group_data.get('extern_type') else 'No', '', '',),
11
11
12 (_('Assigned to repositories'), len(c.group_to_repos),'', [x for x in c.group_to_repos]),
12 (_('Assigned to repositories'), len(c.group_to_repos),'', [x for x in c.group_to_repos]),
13 (_('Assigned to repo groups'), len(c.group_to_repo_groups), '', [x for x in c.group_to_repo_groups]),
13 (_('Assigned to repo groups'), len(c.group_to_repo_groups), '', [x for x in c.group_to_repo_groups]),
14
14
15 (_('Assigned to review rules'), len(c.group_to_review_rules), '', [x for x in c.group_to_review_rules]),
15 (_('Assigned to review rules'), len(c.group_to_review_rules), '', [x for x in c.group_to_review_rules]),
16 ]
16 ]
17 %>
17 %>
18
18
19 <div class="panel panel-default">
19 <div class="panel panel-default">
20 <div class="panel-heading">
20 <div class="panel-heading">
21 <h3 class="panel-title">${_('User Group: %s') % c.user_group.users_group_name}</h3>
21 <h3 class="panel-title">
22 <i class="icon-user-group" title="${_('User group')}"></i>
23 ${h.link_to_group(c.user_group.users_group_name)}
24 - ${_('Advanced')}
25 </h3>
22 </div>
26 </div>
23 <div class="panel-body">
27 <div class="panel-body">
24 ${base.dt_info_panel(elems)}
28 ${base.dt_info_panel(elems)}
25 </div>
29 </div>
26
30
27 </div>
31 </div>
28
32
29 <div class="panel panel-default">
33 <div class="panel panel-default">
30 <div class="panel-heading">
34 <div class="panel-heading">
31 <h3 class="panel-title">${_('Group members sync')}</h3>
35 <h3 class="panel-title">${_('Group members sync')}</h3>
32 </div>
36 </div>
33 <div class="panel-body">
37 <div class="panel-body">
34 <% sync_type = c.user_group.group_data.get('extern_type') %>
38 <% sync_type = c.user_group.group_data.get('extern_type') %>
35
39
36 % if sync_type:
40 % if sync_type:
37 <p>
41 <p>
38 ${_('This group is set to be automatically synchronised.')}<br/>
42 ${_('This group is set to be automatically synchronised.')}<br/>
39 ${_('This group synchronization was set by')}: <strong>${sync_type}</strong>
43 ${_('This group synchronization was set by')}: <strong>${sync_type}</strong>
40 </p>
44 </p>
41 % else:
45 % else:
42 <p>
46 <p>
43 ${_('This group is not set to be automatically synchronised')}
47 ${_('This group is not set to be automatically synchronised')}
44 </p>
48 </p>
45 % endif
49 % endif
46
50
47 <div>
51 <div>
48 ${h.secure_form(h.route_path('edit_user_group_advanced_sync', user_group_id=c.user_group.users_group_id), request=request)}
52 ${h.secure_form(h.route_path('edit_user_group_advanced_sync', user_group_id=c.user_group.users_group_id), request=request)}
49 <div class="field">
53 <div class="field">
50 <button class="btn btn-default" type="submit">
54 <button class="btn btn-default" type="submit">
51 %if sync_type:
55 %if sync_type:
52 ${_('Disable synchronization')}
56 ${_('Disable synchronization')}
53 %else:
57 %else:
54 ${_('Enable synchronization')}
58 ${_('Enable synchronization')}
55 %endif
59 %endif
56 </button>
60 </button>
57 </div>
61 </div>
58 <div class="field">
62 <div class="field">
59 <span class="help-block">
63 <span class="help-block">
60 ${_('Users will be added or removed from this group when they authenticate with RhodeCode system, based on LDAP group membership. '
64 ${_('Users will be added or removed from this group when they authenticate with RhodeCode system, based on LDAP group membership. '
61 'This requires `LDAP+User group` authentication plugin to be configured and enabled. (EE only feature)')}
65 'This requires `LDAP+User group` authentication plugin to be configured and enabled. (EE only feature)')}
62 </span>
66 </span>
63 </div>
67 </div>
64 ${h.end_form()}
68 ${h.end_form()}
65 </div>
69 </div>
66
70
67 </div>
71 </div>
68 </div>
72 </div>
69
73
70
74
71 <div class="panel panel-danger">
75 <div class="panel panel-danger">
72 <div class="panel-heading">
76 <div class="panel-heading">
73 <h3 class="panel-title">${_('Delete User Group')}</h3>
77 <h3 class="panel-title">${_('Delete User Group')}</h3>
74 </div>
78 </div>
75 <div class="panel-body">
79 <div class="panel-body">
76 ${h.secure_form(h.route_path('user_groups_delete', user_group_id=c.user_group.users_group_id), request=request)}
80 ${h.secure_form(h.route_path('user_groups_delete', user_group_id=c.user_group.users_group_id), request=request)}
77 ${h.hidden('force', 1)}
81 ${h.hidden('force', 1)}
78 <button class="btn btn-small btn-danger" type="submit"
82 <button class="btn btn-small btn-danger" type="submit"
79 onclick="return confirm('${_('Confirm to delete user group `%(ugroup)s` with all permission assignments') % {'ugroup': c.user_group.users_group_name}}');">
83 onclick="return confirm('${_('Confirm to delete user group `%(ugroup)s` with all permission assignments') % {'ugroup': c.user_group.users_group_name}}');">
80 <i class="icon-remove"></i>
84 <i class="icon-remove"></i>
81 ${_('Delete This User Group')}
85 ${_('Delete This User Group')}
82 </button>
86 </button>
83 ${h.end_form()}
87 ${h.end_form()}
84 </div>
88 </div>
85 </div>
89 </div>
@@ -1,217 +1,221 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('User Group Permissions')}</h3>
5 <h3 class="panel-title">
6 <i class="icon-user-group" title="${_('User group')}"></i>
7 ${h.link_to_group(c.user_group.users_group_name)}
8 - ${_('Access Permissions')}
9 </h3>
6 </div>
10 </div>
7 <div class="panel-body">
11 <div class="panel-body">
8 ${h.secure_form(h.route_path('edit_user_group_perms_update', user_group_id=c.user_group.users_group_id), request=request)}
12 ${h.secure_form(h.route_path('edit_user_group_perms_update', user_group_id=c.user_group.users_group_id), request=request)}
9 <table id="permissions_manage" class="rctable permissions">
13 <table id="permissions_manage" class="rctable permissions">
10 <tr>
14 <tr>
11 <th class="td-radio">${_('None')}</th>
15 <th class="td-radio">${_('None')}</th>
12 <th class="td-radio">${_('Read')}</th>
16 <th class="td-radio">${_('Read')}</th>
13 <th class="td-radio">${_('Write')}</th>
17 <th class="td-radio">${_('Write')}</th>
14 <th class="td-radio">${_('Admin')}</th>
18 <th class="td-radio">${_('Admin')}</th>
15 <th>${_('User/User Group')}</th>
19 <th>${_('User/User Group')}</th>
16 <th class="td-action"></th>
20 <th class="td-action"></th>
17 <th class="td-action"></th>
21 <th class="td-action"></th>
18 </tr>
22 </tr>
19 ## USERS
23 ## USERS
20 %for _user in c.user_group.permissions():
24 %for _user in c.user_group.permissions():
21 ## super admin/owner row
25 ## super admin/owner row
22 %if getattr(_user, 'admin_row', None) or getattr(_user, 'owner_row', None):
26 %if getattr(_user, 'admin_row', None) or getattr(_user, 'owner_row', None):
23 <tr class="perm_admin_row">
27 <tr class="perm_admin_row">
24 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.none', disabled="disabled")}</td>
28 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.none', disabled="disabled")}</td>
25 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.read', disabled="disabled")}</td>
29 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.read', disabled="disabled")}</td>
26 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.write', disabled="disabled")}</td>
30 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.write', disabled="disabled")}</td>
27 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.admin', 'repository.admin', disabled="disabled")}</td>
31 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.admin', 'repository.admin', disabled="disabled")}</td>
28 <td class="td-user">
32 <td class="td-user">
29 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
33 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
30 <span class="user">
34 <span class="user">
31 ${h.link_to_user(_user.username)}
35 ${h.link_to_user(_user.username)}
32 %if getattr(_user, 'admin_row', None):
36 %if getattr(_user, 'admin_row', None):
33 (${_('super-admin')})
37 (${_('super-admin')})
34 %endif
38 %endif
35 %if getattr(_user, 'owner_row', None):
39 %if getattr(_user, 'owner_row', None):
36 (${_('owner')})
40 (${_('owner')})
37 %endif
41 %endif
38 </span>
42 </span>
39 </td>
43 </td>
40 <td></td>
44 <td></td>
41 <td class="quick_repo_menu">
45 <td class="quick_repo_menu">
42 % if c.rhodecode_user.is_admin:
46 % if c.rhodecode_user.is_admin:
43 <i class="icon-more"></i>
47 <i class="icon-more"></i>
44 <div class="menu_items_container" style="display: none;">
48 <div class="menu_items_container" style="display: none;">
45 <ul class="menu_items">
49 <ul class="menu_items">
46 <li>
50 <li>
47 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='user-groups-permissions'))}
51 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='user-groups-permissions'))}
48 </li>
52 </li>
49 </ul>
53 </ul>
50 </div>
54 </div>
51 % endif
55 % endif
52 </td>
56 </td>
53 </tr>
57 </tr>
54 %else:
58 %else:
55 ##forbid revoking permission from yourself, except if you're an super admin
59 ##forbid revoking permission from yourself, except if you're an super admin
56 <tr>
60 <tr>
57 %if c.rhodecode_user.user_id != _user.user_id or c.rhodecode_user.is_admin:
61 %if c.rhodecode_user.user_id != _user.user_id or c.rhodecode_user.is_admin:
58 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.none')}</td>
62 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.none')}</td>
59 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.read')}</td>
63 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.read')}</td>
60 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.write')}</td>
64 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.write')}</td>
61 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.admin')}</td>
65 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.admin')}</td>
62 <td class="td-user">
66 <td class="td-user">
63 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
67 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
64 <span class="user">
68 <span class="user">
65 % if _user.username == h.DEFAULT_USER:
69 % if _user.username == h.DEFAULT_USER:
66 ${h.DEFAULT_USER}
70 ${h.DEFAULT_USER}
67 % if _user.active:
71 % if _user.active:
68 <span class="user-perm-help-text"> - ${_('permission for other logged in and anonymous users')}</span>
72 <span class="user-perm-help-text"> - ${_('permission for other logged in and anonymous users')}</span>
69 % else:
73 % else:
70 <span class="user-perm-help-text"> - ${_('permission for other logged in users')}</span>
74 <span class="user-perm-help-text"> - ${_('permission for other logged in users')}</span>
71 % endif
75 % endif
72 % else:
76 % else:
73 ${h.link_to_user(_user.username)}
77 ${h.link_to_user(_user.username)}
74 %if getattr(_user, 'duplicate_perm', None):
78 %if getattr(_user, 'duplicate_perm', None):
75 (${_('inactive duplicate')})
79 (${_('inactive duplicate')})
76 %endif
80 %endif
77 % endif
81 % endif
78 </span>
82 </span>
79 </td>
83 </td>
80 <td class="td-action">
84 <td class="td-action">
81 %if _user.username != h.DEFAULT_USER:
85 %if _user.username != h.DEFAULT_USER:
82 <span class="btn btn-link btn-danger revoke_perm"
86 <span class="btn btn-link btn-danger revoke_perm"
83 member="${_user.user_id}" member_type="user">
87 member="${_user.user_id}" member_type="user">
84 ${_('Remove')}
88 ${_('Remove')}
85 </span>
89 </span>
86 %endif
90 %endif
87 </td>
91 </td>
88 <td class="quick_repo_menu">
92 <td class="quick_repo_menu">
89 % if c.rhodecode_user.is_admin:
93 % if c.rhodecode_user.is_admin:
90 <i class="icon-more"></i>
94 <i class="icon-more"></i>
91 <div class="menu_items_container" style="display: none;">
95 <div class="menu_items_container" style="display: none;">
92 <ul class="menu_items">
96 <ul class="menu_items">
93 <li>
97 <li>
94 % if _user.username == h.DEFAULT_USER:
98 % if _user.username == h.DEFAULT_USER:
95 ${h.link_to('show permissions', h.route_path('admin_permissions_overview', _anchor='user-groups-permissions'))}
99 ${h.link_to('show permissions', h.route_path('admin_permissions_overview', _anchor='user-groups-permissions'))}
96 % else:
100 % else:
97 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='user-groups-permissions'))}
101 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='user-groups-permissions'))}
98 % endif
102 % endif
99 </li>
103 </li>
100 </ul>
104 </ul>
101 </div>
105 </div>
102 % endif
106 % endif
103 </td>
107 </td>
104 %else:
108 %else:
105 ## special case for currently logged-in user permissions, we make sure he cannot take his own permissions
109 ## special case for currently logged-in user permissions, we make sure he cannot take his own permissions
106 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.none', disabled="disabled")}</td>
110 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.none', disabled="disabled")}</td>
107 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.read', disabled="disabled")}</td>
111 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.read', disabled="disabled")}</td>
108 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.write', disabled="disabled")}</td>
112 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.write', disabled="disabled")}</td>
109 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.admin', disabled="disabled")}</td>
113 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.admin', disabled="disabled")}</td>
110 <td class="td-user">
114 <td class="td-user">
111 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
115 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
112 <span class="user">
116 <span class="user">
113 % if _user.username == h.DEFAULT_USER:
117 % if _user.username == h.DEFAULT_USER:
114 ${h.DEFAULT_USER}
118 ${h.DEFAULT_USER}
115 % if _user.active:
119 % if _user.active:
116 <span class="user-perm-help-text"> - ${_('permission for other logged in and anonymous users')}</span>
120 <span class="user-perm-help-text"> - ${_('permission for other logged in and anonymous users')}</span>
117 % else:
121 % else:
118 <span class="user-perm-help-text"> - ${_('permission for other logged in users')}</span>
122 <span class="user-perm-help-text"> - ${_('permission for other logged in users')}</span>
119 % endif
123 % endif
120 % else:
124 % else:
121 ${h.link_to_user(_user.username)}
125 ${h.link_to_user(_user.username)}
122 %if getattr(_user, 'duplicate_perm', None):
126 %if getattr(_user, 'duplicate_perm', None):
123 (${_('inactive duplicate')})
127 (${_('inactive duplicate')})
124 %endif
128 %endif
125 % endif
129 % endif
126 <span class="user-perm-help-text">(${_('delegated admin')})</span>
130 <span class="user-perm-help-text">(${_('delegated admin')})</span>
127 </span>
131 </span>
128 </td>
132 </td>
129 <td></td>
133 <td></td>
130 <td class="quick_repo_menu">
134 <td class="quick_repo_menu">
131 % if c.rhodecode_user.is_admin:
135 % if c.rhodecode_user.is_admin:
132 <i class="icon-more"></i>
136 <i class="icon-more"></i>
133 <div class="menu_items_container" style="display: none;">
137 <div class="menu_items_container" style="display: none;">
134 <ul class="menu_items">
138 <ul class="menu_items">
135 <li>
139 <li>
136 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='user-groups-permissions'))}
140 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='user-groups-permissions'))}
137 </li>
141 </li>
138 </ul>
142 </ul>
139 </div>
143 </div>
140 % endif
144 % endif
141 </td>
145 </td>
142 %endif
146 %endif
143 </tr>
147 </tr>
144 %endif
148 %endif
145 %endfor
149 %endfor
146
150
147 ## USER GROUPS
151 ## USER GROUPS
148 %for _user_group in c.user_group.permission_user_groups(with_members=True):
152 %for _user_group in c.user_group.permission_user_groups(with_members=True):
149 <tr>
153 <tr>
150 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.none')}</td>
154 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.none')}</td>
151 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.read')}</td>
155 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.read')}</td>
152 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.write')}</td>
156 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.write')}</td>
153 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.admin')}</td>
157 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.admin')}</td>
154 <td class="td-user">
158 <td class="td-user">
155 <i class="icon-user-group"></i>
159 <i class="icon-user-group"></i>
156 %if c.is_super_admin:
160 %if c.is_super_admin:
157 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
161 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
158 ${_user_group.users_group_name}
162 ${_user_group.users_group_name}
159 </a>
163 </a>
160 %else:
164 %else:
161 ${h.link_to_group(_user_group.users_group_name)}
165 ${h.link_to_group(_user_group.users_group_name)}
162 %endif
166 %endif
163 (${_('members')}: ${len(_user_group.members)})
167 (${_('members')}: ${len(_user_group.members)})
164 </td>
168 </td>
165 <td class="td-action">
169 <td class="td-action">
166 <span class="btn btn-link btn-danger revoke_perm"
170 <span class="btn btn-link btn-danger revoke_perm"
167 member="${_user_group.users_group_id}" member_type="user_group">
171 member="${_user_group.users_group_id}" member_type="user_group">
168 ${_('Remove')}
172 ${_('Remove')}
169 </span>
173 </span>
170 </td>
174 </td>
171 <td class="quick_repo_menu">
175 <td class="quick_repo_menu">
172 % if c.rhodecode_user.is_admin:
176 % if c.rhodecode_user.is_admin:
173 <i class="icon-more"></i>
177 <i class="icon-more"></i>
174 <div class="menu_items_container" style="display: none;">
178 <div class="menu_items_container" style="display: none;">
175 <ul class="menu_items">
179 <ul class="menu_items">
176 <li>
180 <li>
177 ${h.link_to('show permissions', h.route_path('edit_user_group_perms_summary', user_group_id=_user_group.users_group_id, _anchor='user-groups-permissions'))}
181 ${h.link_to('show permissions', h.route_path('edit_user_group_perms_summary', user_group_id=_user_group.users_group_id, _anchor='user-groups-permissions'))}
178 </li>
182 </li>
179 </ul>
183 </ul>
180 </div>
184 </div>
181 % endif
185 % endif
182 </td>
186 </td>
183 </tr>
187 </tr>
184 %endfor
188 %endfor
185 <tr class="new_members" id="add_perm_input"></tr>
189 <tr class="new_members" id="add_perm_input"></tr>
186 <tr>
190 <tr>
187 <td></td>
191 <td></td>
188 <td></td>
192 <td></td>
189 <td></td>
193 <td></td>
190 <td></td>
194 <td></td>
191 <td></td>
195 <td></td>
192 <td>
196 <td>
193 <span id="add_perm" class="link">
197 <span id="add_perm" class="link">
194 ${_('Add user/user group')}
198 ${_('Add user/user group')}
195 </span>
199 </span>
196 </td>
200 </td>
197 <td></td>
201 <td></td>
198 </tr>
202 </tr>
199 </table>
203 </table>
200
204
201 <div class="buttons">
205 <div class="buttons">
202 ${h.submit('save',_('Save'),class_="btn btn-primary")}
206 ${h.submit('save',_('Save'),class_="btn btn-primary")}
203 ${h.reset('reset',_('Reset'),class_="btn btn-danger")}
207 ${h.reset('reset',_('Reset'),class_="btn btn-danger")}
204 </div>
208 </div>
205 ${h.end_form()}
209 ${h.end_form()}
206 </div>
210 </div>
207 </div>
211 </div>
208
212
209 <script type="text/javascript">
213 <script type="text/javascript">
210 $('#add_perm').on('click', function(e){
214 $('#add_perm').on('click', function(e){
211 addNewPermInput($(this), 'usergroup');
215 addNewPermInput($(this), 'usergroup');
212 });
216 });
213 $('.revoke_perm').on('click', function(e){
217 $('.revoke_perm').on('click', function(e){
214 markRevokePermInput($(this), 'usergroup');
218 markRevokePermInput($(this), 'usergroup');
215 });
219 });
216 quick_repo_menu()
220 quick_repo_menu()
217 </script>
221 </script>
@@ -1,186 +1,190 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%namespace name="base" file="/base/base.mako"/>
2 <%namespace name="base" file="/base/base.mako"/>
3
3
4 <div class="panel panel-default">
4 <div class="panel panel-default">
5 <div class="panel-heading">
5 <div class="panel-heading">
6 <h3 class="panel-title">${_('User Group: %s') % c.user_group.users_group_name}</h3>
6 <h3 class="panel-title">
7 <i class="icon-user-group" title="${_('User group')}"></i>
8 ${h.link_to_group(c.user_group.users_group_name)}
9 - ${_('Settings')}
10 </h3>
7 </div>
11 </div>
8 <div class="panel-body">
12 <div class="panel-body">
9 ${h.secure_form(h.route_path('user_groups_update', user_group_id=c.user_group.users_group_id), id='edit_user_group', request=request)}
13 ${h.secure_form(h.route_path('user_groups_update', user_group_id=c.user_group.users_group_id), id='edit_user_group', request=request)}
10 <div class="form">
14 <div class="form">
11 <!-- fields -->
15 <!-- fields -->
12 <div class="fields">
16 <div class="fields">
13 <div class="field">
17 <div class="field">
14 <div class="label">
18 <div class="label">
15 <label for="users_group_name">${_('Group name')}:</label>
19 <label for="users_group_name">${_('Group name')}:</label>
16 </div>
20 </div>
17 <div class="input">
21 <div class="input">
18 ${h.text('users_group_name',class_='medium')}
22 ${h.text('users_group_name',class_='medium')}
19 </div>
23 </div>
20 </div>
24 </div>
21
25
22 <div class="field badged-field">
26 <div class="field badged-field">
23 <div class="label">
27 <div class="label">
24 <label for="user">${_('Owner')}:</label>
28 <label for="user">${_('Owner')}:</label>
25 </div>
29 </div>
26 <div class="input">
30 <div class="input">
27 <div class="badge-input-container">
31 <div class="badge-input-container">
28 <div class="user-badge">
32 <div class="user-badge">
29 ${base.gravatar_with_user(c.user_group.user.email, show_disabled=not c.user_group.user.active)}
33 ${base.gravatar_with_user(c.user_group.user.email, show_disabled=not c.user_group.user.active)}
30 </div>
34 </div>
31 <div class="badge-input-wrap">
35 <div class="badge-input-wrap">
32 ${h.text('user', class_="medium", autocomplete="off")}
36 ${h.text('user', class_="medium", autocomplete="off")}
33 </div>
37 </div>
34 </div>
38 </div>
35 <form:error name="user"/>
39 <form:error name="user"/>
36 <p class="help-block">${_('Change owner of this user group.')}</p>
40 <p class="help-block">${_('Change owner of this user group.')}</p>
37 </div>
41 </div>
38 </div>
42 </div>
39
43
40 <div class="field">
44 <div class="field">
41 <div class="label label-textarea">
45 <div class="label label-textarea">
42 <label for="user_group_description">${_('Description')}:</label>
46 <label for="user_group_description">${_('Description')}:</label>
43 </div>
47 </div>
44 <div class="textarea textarea-small editor">
48 <div class="textarea textarea-small editor">
45 ${h.textarea('user_group_description',cols=23,rows=5,class_="medium")}
49 ${h.textarea('user_group_description',cols=23,rows=5,class_="medium")}
46 <span class="help-block">${_('Short, optional description for this user group.')}</span>
50 <span class="help-block">${_('Short, optional description for this user group.')}</span>
47 </div>
51 </div>
48 </div>
52 </div>
49 <div class="field">
53 <div class="field">
50 <div class="label label-checkbox">
54 <div class="label label-checkbox">
51 <label for="users_group_active">${_('Active')}:</label>
55 <label for="users_group_active">${_('Active')}:</label>
52 </div>
56 </div>
53 <div class="checkboxes">
57 <div class="checkboxes">
54 ${h.checkbox('users_group_active',value=True)}
58 ${h.checkbox('users_group_active',value=True)}
55 </div>
59 </div>
56 </div>
60 </div>
57
61
58 <div class="field">
62 <div class="field">
59 <div class="label label-checkbox">
63 <div class="label label-checkbox">
60 <label for="users_group_active">${_('Add members')}:</label>
64 <label for="users_group_active">${_('Add members')}:</label>
61 </div>
65 </div>
62 <div class="input">
66 <div class="input">
63 ${h.text('user_group_add_members', placeholder="user/usergroup", class_="medium")}
67 ${h.text('user_group_add_members', placeholder="user/usergroup", class_="medium")}
64 </div>
68 </div>
65 </div>
69 </div>
66
70
67 <input type="hidden" name="__start__" value="user_group_members:sequence"/>
71 <input type="hidden" name="__start__" value="user_group_members:sequence"/>
68 <table id="group_members_placeholder" class="rctable group_members">
72 <table id="group_members_placeholder" class="rctable group_members">
69 <tr>
73 <tr>
70 <th>${_('Username')}</th>
74 <th>${_('Username')}</th>
71 <th>${_('Action')}</th>
75 <th>${_('Action')}</th>
72 </tr>
76 </tr>
73
77
74 % if c.group_members_obj:
78 % if c.group_members_obj:
75 % for user in c.group_members_obj:
79 % for user in c.group_members_obj:
76 <tr>
80 <tr>
77 <td id="member_user_${user.user_id}" class="td-author">
81 <td id="member_user_${user.user_id}" class="td-author">
78 <div class="group_member">
82 <div class="group_member">
79 ${base.gravatar(user.email, 16, user=user, tooltip=True)}
83 ${base.gravatar(user.email, 16, user=user, tooltip=True)}
80 <span class="username user">${h.link_to(h.person(user), h.route_path('user_edit',user_id=user.user_id))}</span>
84 <span class="username user">${h.link_to(h.person(user), h.route_path('user_edit',user_id=user.user_id))}</span>
81 <input type="hidden" name="__start__" value="member:mapping">
85 <input type="hidden" name="__start__" value="member:mapping">
82 <input type="hidden" name="member_user_id" value="${user.user_id}">
86 <input type="hidden" name="member_user_id" value="${user.user_id}">
83 <input type="hidden" name="type" value="existing" id="member_${user.user_id}">
87 <input type="hidden" name="type" value="existing" id="member_${user.user_id}">
84 <input type="hidden" name="__end__" value="member:mapping">
88 <input type="hidden" name="__end__" value="member:mapping">
85 </div>
89 </div>
86 </td>
90 </td>
87 <td class="">
91 <td class="">
88 <div class="usergroup_member_remove action_button" onclick="removeUserGroupMember(${user.user_id}, true)" style="visibility: visible;">
92 <div class="usergroup_member_remove action_button" onclick="removeUserGroupMember(${user.user_id}, true)" style="visibility: visible;">
89 <i class="icon-remove"></i>
93 <i class="icon-remove"></i>
90 </div>
94 </div>
91 </td>
95 </td>
92 </tr>
96 </tr>
93 % endfor
97 % endfor
94
98
95 % else:
99 % else:
96 <tr><td colspan="2">${_('No members yet')}</td></tr>
100 <tr><td colspan="2">${_('No members yet')}</td></tr>
97 % endif
101 % endif
98 </table>
102 </table>
99 <input type="hidden" name="__end__" value="user_group_members:sequence"/>
103 <input type="hidden" name="__end__" value="user_group_members:sequence"/>
100
104
101 <div class="buttons">
105 <div class="buttons">
102 ${h.submit('Save',_('Save'),class_="btn")}
106 ${h.submit('Save',_('Save'),class_="btn")}
103 </div>
107 </div>
104 </div>
108 </div>
105 </div>
109 </div>
106 ${h.end_form()}
110 ${h.end_form()}
107 </div>
111 </div>
108 </div>
112 </div>
109 <script>
113 <script>
110 $(document).ready(function(){
114 $(document).ready(function(){
111 $("#group_parent_id").select2({
115 $("#group_parent_id").select2({
112 'containerCssClass': "drop-menu",
116 'containerCssClass': "drop-menu",
113 'dropdownCssClass': "drop-menu-dropdown",
117 'dropdownCssClass': "drop-menu-dropdown",
114 'dropdownAutoWidth': true
118 'dropdownAutoWidth': true
115 });
119 });
116
120
117 removeUserGroupMember = function(userId){
121 removeUserGroupMember = function(userId){
118 $('#member_'+userId).val('remove');
122 $('#member_'+userId).val('remove');
119 $('#member_user_'+userId).addClass('to-delete');
123 $('#member_user_'+userId).addClass('to-delete');
120 };
124 };
121
125
122 $('#user_group_add_members').autocomplete({
126 $('#user_group_add_members').autocomplete({
123 serviceUrl: pyroutes.url('user_autocomplete_data'),
127 serviceUrl: pyroutes.url('user_autocomplete_data'),
124 minChars:2,
128 minChars:2,
125 maxHeight:400,
129 maxHeight:400,
126 width:300,
130 width:300,
127 deferRequestBy: 300, //miliseconds
131 deferRequestBy: 300, //miliseconds
128 showNoSuggestionNotice: true,
132 showNoSuggestionNotice: true,
129 params: { user_groups:true },
133 params: { user_groups:true },
130 formatResult: autocompleteFormatResult,
134 formatResult: autocompleteFormatResult,
131 lookupFilter: autocompleteFilterResult,
135 lookupFilter: autocompleteFilterResult,
132 onSelect: function(element, suggestion){
136 onSelect: function(element, suggestion){
133
137
134 function addMember(user, fromUserGroup) {
138 function addMember(user, fromUserGroup) {
135 var gravatar = user.icon_link;
139 var gravatar = user.icon_link;
136 var username = user.value_display;
140 var username = user.value_display;
137 var userLink = pyroutes.url('user_edit', {"user_id": user.id});
141 var userLink = pyroutes.url('user_edit', {"user_id": user.id});
138 var uid = user.id;
142 var uid = user.id;
139
143
140 if (fromUserGroup) {
144 if (fromUserGroup) {
141 username = username +" "+ _gettext('(from usergroup {0})'.format(fromUserGroup))
145 username = username +" "+ _gettext('(from usergroup {0})'.format(fromUserGroup))
142 }
146 }
143
147
144 var elem = $(
148 var elem = $(
145 ('<tr>'+
149 ('<tr>'+
146 '<td id="member_user_{6}" class="td-author td-author-new-entry">'+
150 '<td id="member_user_{6}" class="td-author td-author-new-entry">'+
147 '<div class="group_member">'+
151 '<div class="group_member">'+
148 '<img class="gravatar" src="{0}" height="16" width="16">'+
152 '<img class="gravatar" src="{0}" height="16" width="16">'+
149 '<span class="username user"><a href="{1}">{2}</a></span>'+
153 '<span class="username user"><a href="{1}">{2}</a></span>'+
150 '<input type="hidden" name="__start__" value="member:mapping">'+
154 '<input type="hidden" name="__start__" value="member:mapping">'+
151 '<input type="hidden" name="member_user_id" value="{3}">'+
155 '<input type="hidden" name="member_user_id" value="{3}">'+
152 '<input type="hidden" name="type" value="new" id="member_{4}">'+
156 '<input type="hidden" name="type" value="new" id="member_{4}">'+
153 '<input type="hidden" name="__end__" value="member:mapping">'+
157 '<input type="hidden" name="__end__" value="member:mapping">'+
154 '</div>'+
158 '</div>'+
155 '</td>'+
159 '</td>'+
156 '<td class="td-author-new-entry">'+
160 '<td class="td-author-new-entry">'+
157 '<div class="usergroup_member_remove action_button" onclick="removeUserGroupMember({5}, true)" style="visibility: visible;">'+
161 '<div class="usergroup_member_remove action_button" onclick="removeUserGroupMember({5}, true)" style="visibility: visible;">'+
158 '<i class="icon-remove"></i>'+
162 '<i class="icon-remove"></i>'+
159 '</div>'+
163 '</div>'+
160 '</td>'+
164 '</td>'+
161 '</tr>').format(gravatar, userLink, username,
165 '</tr>').format(gravatar, userLink, username,
162 uid, uid, uid, uid)
166 uid, uid, uid, uid)
163 );
167 );
164 $('#group_members_placeholder').append(elem)
168 $('#group_members_placeholder').append(elem)
165 }
169 }
166
170
167 if (suggestion.value_type == 'user_group') {
171 if (suggestion.value_type == 'user_group') {
168 $.getJSON(
172 $.getJSON(
169 pyroutes.url('user_group_members_data',
173 pyroutes.url('user_group_members_data',
170 {'user_group_id': suggestion.id}),
174 {'user_group_id': suggestion.id}),
171 function(data) {
175 function(data) {
172 $.each(data.members, function(idx, user) {
176 $.each(data.members, function(idx, user) {
173 addMember(user, suggestion.value)
177 addMember(user, suggestion.value)
174 });
178 });
175 }
179 }
176 );
180 );
177 } else if (suggestion.value_type == 'user') {
181 } else if (suggestion.value_type == 'user') {
178 addMember(suggestion, null);
182 addMember(suggestion, null);
179 }
183 }
180 }
184 }
181 });
185 });
182
186
183
187
184 UsersAutoComplete('user', '${c.rhodecode_user.user_id}');
188 UsersAutoComplete('user', '${c.rhodecode_user.user_id}');
185 })
189 })
186 </script>
190 </script>
@@ -1,195 +1,198 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <%
3 <%
4 elems = [
4 elems = [
5 (_('User ID'), c.user.user_id, '', ''),
5 (_('User ID'), c.user.user_id, '', ''),
6 (_('Created on'), h.format_date(c.user.created_on), '', ''),
6 (_('Created on'), h.format_date(c.user.created_on), '', ''),
7 (_('Source of Record'), c.user.extern_type, '', ''),
7 (_('Source of Record'), c.user.extern_type, '', ''),
8
8
9 (_('Last login'), c.user.last_login or '-', '', ''),
9 (_('Last login'), c.user.last_login or '-', '', ''),
10 (_('Last activity'), c.user.last_activity, '', ''),
10 (_('Last activity'), c.user.last_activity, '', ''),
11
11
12 (_('Repositories'), len(c.user.repositories), '', [x.repo_name for x in c.user.repositories]),
12 (_('Repositories'), len(c.user.repositories), '', [x.repo_name for x in c.user.repositories]),
13 (_('Repository groups'), len(c.user.repository_groups), '', [x.group_name for x in c.user.repository_groups]),
13 (_('Repository groups'), len(c.user.repository_groups), '', [x.group_name for x in c.user.repository_groups]),
14 (_('User groups'), len(c.user.user_groups), '', [x.users_group_name for x in c.user.user_groups]),
14 (_('User groups'), len(c.user.user_groups), '', [x.users_group_name for x in c.user.user_groups]),
15
15
16 (_('Owned Artifacts'), len(c.user.artifacts), '', [x.file_uid for x in c.user.artifacts]),
16 (_('Owned Artifacts'), len(c.user.artifacts), '', [x.file_uid for x in c.user.artifacts]),
17
17
18 (_('Reviewer of pull requests'), len(c.user.reviewer_pull_requests), '', ['Pull Request #{}'.format(x.pull_request.pull_request_id) for x in c.user.reviewer_pull_requests]),
18 (_('Reviewer of pull requests'), len(c.user.reviewer_pull_requests), '', ['Pull Request #{}'.format(x.pull_request.pull_request_id) for x in c.user.reviewer_pull_requests]),
19 (_('Assigned to review rules'), len(c.user_to_review_rules), '', [x for x in c.user_to_review_rules]),
19 (_('Assigned to review rules'), len(c.user_to_review_rules), '', [x for x in c.user_to_review_rules]),
20
20
21 (_('Member of User groups'), len(c.user.group_member), '', [x.users_group.users_group_name for x in c.user.group_member]),
21 (_('Member of User groups'), len(c.user.group_member), '', [x.users_group.users_group_name for x in c.user.group_member]),
22 (_('Force password change'), c.user.user_data.get('force_password_change', 'False'), '', ''),
22 (_('Force password change'), c.user.user_data.get('force_password_change', 'False'), '', ''),
23 ]
23 ]
24 %>
24 %>
25
25
26 <div class="panel panel-default">
26 <div class="panel panel-default">
27 <div class="panel-heading">
27 <div class="panel-heading">
28 <h3 class="panel-title">${_('User: {}').format(c.user.username)}</h3>
28 <h3 class="panel-title">
29 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
30 &nbsp;- ${_('Access Permissions')}
31 </h3>
29 </div>
32 </div>
30 <div class="panel-body">
33 <div class="panel-body">
31 <table class="rctable">
34 <table class="rctable">
32 <tr>
35 <tr>
33 <th>Name</th>
36 <th>Name</th>
34 <th>Value</th>
37 <th>Value</th>
35 <th>Action</th>
38 <th>Action</th>
36 </tr>
39 </tr>
37 % for elem in elems:
40 % for elem in elems:
38 ${base.tr_info_entry(elem)}
41 ${base.tr_info_entry(elem)}
39 % endfor
42 % endfor
40 </table>
43 </table>
41 </div>
44 </div>
42 </div>
45 </div>
43
46
44 <div class="panel panel-default">
47 <div class="panel panel-default">
45 <div class="panel-heading">
48 <div class="panel-heading">
46 <h3 class="panel-title">${_('Force Password Reset')}</h3>
49 <h3 class="panel-title">${_('Force Password Reset')}</h3>
47 </div>
50 </div>
48 <div class="panel-body">
51 <div class="panel-body">
49 ${h.secure_form(h.route_path('user_disable_force_password_reset', user_id=c.user.user_id), request=request)}
52 ${h.secure_form(h.route_path('user_disable_force_password_reset', user_id=c.user.user_id), request=request)}
50 <div class="field">
53 <div class="field">
51 <button class="btn btn-default" type="submit">
54 <button class="btn btn-default" type="submit">
52 <i class="icon-unlock"></i> ${_('Disable forced password reset')}
55 <i class="icon-unlock"></i> ${_('Disable forced password reset')}
53 </button>
56 </button>
54 </div>
57 </div>
55 <div class="field">
58 <div class="field">
56 <span class="help-block">
59 <span class="help-block">
57 ${_("Clear the forced password change flag.")}
60 ${_("Clear the forced password change flag.")}
58 </span>
61 </span>
59 </div>
62 </div>
60 ${h.end_form()}
63 ${h.end_form()}
61
64
62 ${h.secure_form(h.route_path('user_enable_force_password_reset', user_id=c.user.user_id), request=request)}
65 ${h.secure_form(h.route_path('user_enable_force_password_reset', user_id=c.user.user_id), request=request)}
63 <div class="field">
66 <div class="field">
64 <button class="btn btn-default" type="submit" onclick="return confirm('${_('Confirm to enable forced password change')}');">
67 <button class="btn btn-default" type="submit" onclick="return confirm('${_('Confirm to enable forced password change')}');">
65 <i class="icon-lock"></i> ${_('Enable forced password reset')}
68 <i class="icon-lock"></i> ${_('Enable forced password reset')}
66 </button>
69 </button>
67 </div>
70 </div>
68 <div class="field">
71 <div class="field">
69 <span class="help-block">
72 <span class="help-block">
70 ${_("When this is enabled user will have to change they password when they next use RhodeCode system. This will also forbid vcs operations until someone makes a password change in the web interface")}
73 ${_("When this is enabled user will have to change they password when they next use RhodeCode system. This will also forbid vcs operations until someone makes a password change in the web interface")}
71 </span>
74 </span>
72 </div>
75 </div>
73 ${h.end_form()}
76 ${h.end_form()}
74
77
75 </div>
78 </div>
76 </div>
79 </div>
77
80
78 <div class="panel panel-default">
81 <div class="panel panel-default">
79 <div class="panel-heading">
82 <div class="panel-heading">
80 <h3 class="panel-title">${_('Personal Repository Group')}</h3>
83 <h3 class="panel-title">${_('Personal Repository Group')}</h3>
81 </div>
84 </div>
82 <div class="panel-body">
85 <div class="panel-body">
83 ${h.secure_form(h.route_path('user_create_personal_repo_group', user_id=c.user.user_id), request=request)}
86 ${h.secure_form(h.route_path('user_create_personal_repo_group', user_id=c.user.user_id), request=request)}
84
87
85 %if c.personal_repo_group:
88 %if c.personal_repo_group:
86 <div class="panel-body-title-text">${_('Users personal repository group')} : ${h.link_to(c.personal_repo_group.group_name, h.route_path('repo_group_home', repo_group_name=c.personal_repo_group.group_name))}</div>
89 <div class="panel-body-title-text">${_('Users personal repository group')} : ${h.link_to(c.personal_repo_group.group_name, h.route_path('repo_group_home', repo_group_name=c.personal_repo_group.group_name))}</div>
87 %else:
90 %else:
88 <div class="panel-body-title-text">
91 <div class="panel-body-title-text">
89 ${_('This user currently does not have a personal repository group')}
92 ${_('This user currently does not have a personal repository group')}
90 <br/>
93 <br/>
91 ${_('New group will be created at: `/%(path)s`') % {'path': c.personal_repo_group_name}}
94 ${_('New group will be created at: `/%(path)s`') % {'path': c.personal_repo_group_name}}
92 </div>
95 </div>
93 %endif
96 %endif
94 <button class="btn btn-default" type="submit" ${'disabled="disabled"' if c.personal_repo_group else ''}>
97 <button class="btn btn-default" type="submit" ${'disabled="disabled"' if c.personal_repo_group else ''}>
95 <i class="icon-repo-group"></i>
98 <i class="icon-repo-group"></i>
96 ${_('Create personal repository group')}
99 ${_('Create personal repository group')}
97 </button>
100 </button>
98 ${h.end_form()}
101 ${h.end_form()}
99 </div>
102 </div>
100 </div>
103 </div>
101
104
102
105
103 <div class="panel panel-danger">
106 <div class="panel panel-danger">
104 <div class="panel-heading">
107 <div class="panel-heading">
105 <h3 class="panel-title">${_('Delete User')}</h3>
108 <h3 class="panel-title">${_('Delete User')}</h3>
106 </div>
109 </div>
107 <div class="panel-body">
110 <div class="panel-body">
108 ${h.secure_form(h.route_path('user_delete', user_id=c.user.user_id), request=request)}
111 ${h.secure_form(h.route_path('user_delete', user_id=c.user.user_id), request=request)}
109
112
110 <table class="display rctable">
113 <table class="display rctable">
111 <tr>
114 <tr>
112 <td>
115 <td>
113 ${_ungettext('This user owns %s repository.', 'This user owns %s repositories.', len(c.user.repositories)) % len(c.user.repositories)}
116 ${_ungettext('This user owns %s repository.', 'This user owns %s repositories.', len(c.user.repositories)) % len(c.user.repositories)}
114 </td>
117 </td>
115 <td>
118 <td>
116 <input type="radio" id="user_repos_1" name="user_repos" value="detach" checked="checked" ${'disabled=1' if len(c.user.repositories) == 0 else ''} /> <label for="user_repos_1">${_('Detach repositories')}</label>
119 <input type="radio" id="user_repos_1" name="user_repos" value="detach" checked="checked" ${'disabled=1' if len(c.user.repositories) == 0 else ''} /> <label for="user_repos_1">${_('Detach repositories')}</label>
117 </td>
120 </td>
118 <td>
121 <td>
119 <input type="radio" id="user_repos_2" name="user_repos" value="delete" ${'disabled=1' if len(c.user.repositories) == 0 else ''} /> <label for="user_repos_2">${_('Delete repositories')}</label>
122 <input type="radio" id="user_repos_2" name="user_repos" value="delete" ${'disabled=1' if len(c.user.repositories) == 0 else ''} /> <label for="user_repos_2">${_('Delete repositories')}</label>
120 </td>
123 </td>
121 </tr>
124 </tr>
122
125
123 <tr>
126 <tr>
124 <td>
127 <td>
125 ${_ungettext('This user owns %s repository group.', 'This user owns %s repository groups.', len(c.user.repository_groups)) % len(c.user.repository_groups)}
128 ${_ungettext('This user owns %s repository group.', 'This user owns %s repository groups.', len(c.user.repository_groups)) % len(c.user.repository_groups)}
126 </td>
129 </td>
127 <td>
130 <td>
128 <input type="radio" id="user_repo_groups_1" name="user_repo_groups" value="detach" checked="checked" ${'disabled=1' if len(c.user.repository_groups) == 0 else ''} /> <label for="user_repo_groups_1">${_('Detach repository groups')}</label>
131 <input type="radio" id="user_repo_groups_1" name="user_repo_groups" value="detach" checked="checked" ${'disabled=1' if len(c.user.repository_groups) == 0 else ''} /> <label for="user_repo_groups_1">${_('Detach repository groups')}</label>
129 </td>
132 </td>
130 <td>
133 <td>
131 <input type="radio" id="user_repo_groups_2" name="user_repo_groups" value="delete" ${'disabled=1' if len(c.user.repository_groups) == 0 else ''}/> <label for="user_repo_groups_2">${_('Delete repositories')}</label>
134 <input type="radio" id="user_repo_groups_2" name="user_repo_groups" value="delete" ${'disabled=1' if len(c.user.repository_groups) == 0 else ''}/> <label for="user_repo_groups_2">${_('Delete repositories')}</label>
132 </td>
135 </td>
133 </tr>
136 </tr>
134
137
135 <tr>
138 <tr>
136 <td>
139 <td>
137 ${_ungettext('This user owns %s user group.', 'This user owns %s user groups.', len(c.user.user_groups)) % len(c.user.user_groups)}
140 ${_ungettext('This user owns %s user group.', 'This user owns %s user groups.', len(c.user.user_groups)) % len(c.user.user_groups)}
138 </td>
141 </td>
139 <td>
142 <td>
140 <input type="radio" id="user_user_groups_1" name="user_user_groups" value="detach" checked="checked" ${'disabled=1' if len(c.user.user_groups) == 0 else ''}/> <label for="user_user_groups_1">${_('Detach user groups')}</label>
143 <input type="radio" id="user_user_groups_1" name="user_user_groups" value="detach" checked="checked" ${'disabled=1' if len(c.user.user_groups) == 0 else ''}/> <label for="user_user_groups_1">${_('Detach user groups')}</label>
141 </td>
144 </td>
142 <td>
145 <td>
143 <input type="radio" id="user_user_groups_2" name="user_user_groups" value="delete" ${'disabled=1' if len(c.user.user_groups) == 0 else ''}/> <label for="user_user_groups_2">${_('Delete repositories')}</label>
146 <input type="radio" id="user_user_groups_2" name="user_user_groups" value="delete" ${'disabled=1' if len(c.user.user_groups) == 0 else ''}/> <label for="user_user_groups_2">${_('Delete repositories')}</label>
144 </td>
147 </td>
145 </tr>
148 </tr>
146
149
147 <tr>
150 <tr>
148 <td>
151 <td>
149 ${_ungettext('This user owns %s artifact.', 'This user owns %s artifacts.', len(c.user.artifacts)) % len(c.user.artifacts)}
152 ${_ungettext('This user owns %s artifact.', 'This user owns %s artifacts.', len(c.user.artifacts)) % len(c.user.artifacts)}
150 </td>
153 </td>
151 <td>
154 <td>
152 <input type="radio" id="user_artifacts_1" name="user_artifacts" value="detach" checked="checked" ${'disabled=1' if len(c.user.artifacts) == 0 else ''}/> <label for="user_artifacts_1">${_('Detach Artifacts')}</label>
155 <input type="radio" id="user_artifacts_1" name="user_artifacts" value="detach" checked="checked" ${'disabled=1' if len(c.user.artifacts) == 0 else ''}/> <label for="user_artifacts_1">${_('Detach Artifacts')}</label>
153 </td>
156 </td>
154 <td>
157 <td>
155 <input type="radio" id="user_artifacts_2" name="user_artifacts" value="delete" ${'disabled=1' if len(c.user.artifacts) == 0 else ''}/> <label for="user_artifacts_2">${_('Delete Artifacts')}</label>
158 <input type="radio" id="user_artifacts_2" name="user_artifacts" value="delete" ${'disabled=1' if len(c.user.artifacts) == 0 else ''}/> <label for="user_artifacts_2">${_('Delete Artifacts')}</label>
156 </td>
159 </td>
157 </tr>
160 </tr>
158
161
159 </table>
162 </table>
160 <div style="margin: 0 0 20px 0" class="fake-space"></div>
163 <div style="margin: 0 0 20px 0" class="fake-space"></div>
161 <div class="pull-left">
164 <div class="pull-left">
162 % if len(c.user.repositories) > 0 or len(c.user.repository_groups) > 0 or len(c.user.user_groups) > 0:
165 % if len(c.user.repositories) > 0 or len(c.user.repository_groups) > 0 or len(c.user.user_groups) > 0:
163 % endif
166 % endif
164
167
165 <span style="padding: 0 5px 0 0">${_('New owner for detached objects')}:</span>
168 <span style="padding: 0 5px 0 0">${_('New owner for detached objects')}:</span>
166 <div class="pull-right">${base.gravatar_with_user(c.first_admin.email, 16)}</div>
169 <div class="pull-right">${base.gravatar_with_user(c.first_admin.email, 16)}</div>
167 </div>
170 </div>
168 <div style="clear: both">
171 <div style="clear: both">
169
172
170 <div>
173 <div>
171 <p class="help-block">
174 <p class="help-block">
172 ${_("When selecting the detach option, the depending objects owned by this user will be assigned to the above user.")}
175 ${_("When selecting the detach option, the depending objects owned by this user will be assigned to the above user.")}
173 <br/>
176 <br/>
174 ${_("The delete option will delete the user and all his owned objects!")}
177 ${_("The delete option will delete the user and all his owned objects!")}
175 </p>
178 </p>
176 </div>
179 </div>
177
180
178 % if c.can_delete_user_message:
181 % if c.can_delete_user_message:
179 <p class="pre-formatting">${c.can_delete_user_message}</p>
182 <p class="pre-formatting">${c.can_delete_user_message}</p>
180 % endif
183 % endif
181 </div>
184 </div>
182
185
183 <div style="margin: 0 0 20px 0" class="fake-space"></div>
186 <div style="margin: 0 0 20px 0" class="fake-space"></div>
184
187
185 <div class="field">
188 <div class="field">
186 <button class="btn btn-small btn-danger" type="submit"
189 <button class="btn btn-small btn-danger" type="submit"
187 onclick="return confirm('${_('Confirm to delete this user: %s') % c.user.username}');"
190 onclick="return confirm('${_('Confirm to delete this user: %s') % c.user.username}');"
188 ${"disabled" if not c.can_delete_user else ""}>
191 ${"disabled" if not c.can_delete_user else ""}>
189 ${_('Delete this user')}
192 ${_('Delete this user')}
190 </button>
193 </button>
191 </div>
194 </div>
192
195
193 ${h.end_form()}
196 ${h.end_form()}
194 </div>
197 </div>
195 </div>
198 </div>
@@ -1,25 +1,27 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%namespace name="base" file="/base/base.mako"/>
2 <%namespace name="base" file="/base/base.mako"/>
3
3
4
4
5 <div class="panel panel-default">
5 <div class="panel panel-default">
6 <div class="panel-heading">
6 <div class="panel-heading">
7 <h3 class="panel-title">${_('User Audit Logs')} -
7 <h3 class="panel-title">
8 ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
8 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
9 &nbsp;- ${_('Audit Logs')}
10 (${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)})
9 </h3>
11 </h3>
10 <a href="${h.route_path('edit_user_audit_logs_download', user_id=c.user.user_id)}" class="panel-edit">${_('Download as JSON')}</a>
12 <a href="${h.route_path('edit_user_audit_logs_download', user_id=c.user.user_id)}" class="panel-edit">${_('Download as JSON')}</a>
11 </div>
13 </div>
12 <div class="panel-body">
14 <div class="panel-body">
13
15
14 ${h.form(None, id_="filter_form", method="get")}
16 ${h.form(None, id_="filter_form", method="get")}
15 <input class="q_filter_box ${'' if c.filter_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.filter_term or ''}" placeholder="${_('audit filter...')}"/>
17 <input class="q_filter_box ${'' if c.filter_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.filter_term or ''}" placeholder="${_('audit filter...')}"/>
16 <input type='submit' value="${_('filter')}" class="btn" />
18 <input type='submit' value="${_('filter')}" class="btn" />
17 ${h.end_form()}
19 ${h.end_form()}
18
20
19 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
21 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
20 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
22 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
21
23
22 <%include file="/admin/admin_log_base.mako" />
24 <%include file="/admin/admin_log_base.mako" />
23
25
24 </div>
26 </div>
25 </div>
27 </div>
@@ -1,191 +1,196 b''
1 <%namespace name="base" file="/base/base.mako"/>
2
1 <div class="panel panel-default">
3 <div class="panel panel-default">
2 <div class="panel-heading">
4 <div class="panel-heading">
3 <h3 class="panel-title">${_('Authentication Tokens')}</h3>
5 <h3 class="panel-title">
6 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
7 &nbsp;- ${_('Authentication Tokens')}
8 </h3>
4 </div>
9 </div>
5 <div class="panel-body">
10 <div class="panel-body">
6 <div class="apikeys_wrap">
11 <div class="apikeys_wrap">
7 <p>
12 <p>
8 ${_('Authentication tokens can be used to interact with the API, or VCS-over-http. '
13 ${_('Authentication tokens can be used to interact with the API, or VCS-over-http. '
9 'Each token can have a role. Token with a role can be used only in given context, '
14 'Each token can have a role. Token with a role can be used only in given context, '
10 'e.g. VCS tokens can be used together with the authtoken auth plugin for git/hg/svn operations only.')}
15 'e.g. VCS tokens can be used together with the authtoken auth plugin for git/hg/svn operations only.')}
11 </p>
16 </p>
12 <table class="rctable auth_tokens">
17 <table class="rctable auth_tokens">
13 <tr>
18 <tr>
14 <th>${_('Token')}</th>
19 <th>${_('Token')}</th>
15 <th>${_('Description')}</th>
20 <th>${_('Description')}</th>
16 <th>${_('Role')}</th>
21 <th>${_('Role')}</th>
17 <th>${_('Repository Scope')}</th>
22 <th>${_('Repository Scope')}</th>
18 <th>${_('Expiration')}</th>
23 <th>${_('Expiration')}</th>
19 <th>${_('Action')}</th>
24 <th>${_('Action')}</th>
20 </tr>
25 </tr>
21 %if c.user_auth_tokens:
26 %if c.user_auth_tokens:
22 %for auth_token in c.user_auth_tokens:
27 %for auth_token in c.user_auth_tokens:
23 <tr class="${('expired' if auth_token.expired else '')}">
28 <tr class="${('expired' if auth_token.expired else '')}">
24 <td class="truncate-wrap td-authtoken">
29 <td class="truncate-wrap td-authtoken">
25 <div class="user_auth_tokens truncate autoexpand">
30 <div class="user_auth_tokens truncate autoexpand">
26 <code>${auth_token.api_key}</code>
31 <code>${auth_token.api_key}</code>
27 </div>
32 </div>
28 </td>
33 </td>
29 <td class="td-wrap">${auth_token.description}</td>
34 <td class="td-wrap">${auth_token.description}</td>
30 <td class="td-tags">
35 <td class="td-tags">
31 <span class="tag disabled">${auth_token.role_humanized}</span>
36 <span class="tag disabled">${auth_token.role_humanized}</span>
32 </td>
37 </td>
33 <td class="td">${auth_token.scope_humanized}</td>
38 <td class="td">${auth_token.scope_humanized}</td>
34 <td class="td-exp">
39 <td class="td-exp">
35 %if auth_token.expires == -1:
40 %if auth_token.expires == -1:
36 ${_('never')}
41 ${_('never')}
37 %else:
42 %else:
38 %if auth_token.expired:
43 %if auth_token.expired:
39 <span style="text-decoration: line-through">${h.age_component(h.time_to_utcdatetime(auth_token.expires))}</span>
44 <span style="text-decoration: line-through">${h.age_component(h.time_to_utcdatetime(auth_token.expires))}</span>
40 %else:
45 %else:
41 ${h.age_component(h.time_to_utcdatetime(auth_token.expires))}
46 ${h.age_component(h.time_to_utcdatetime(auth_token.expires))}
42 %endif
47 %endif
43 %endif
48 %endif
44 </td>
49 </td>
45 <td class="td-action">
50 <td class="td-action">
46 ${h.secure_form(h.route_path('edit_user_auth_tokens_delete', user_id=c.user.user_id), request=request)}
51 ${h.secure_form(h.route_path('edit_user_auth_tokens_delete', user_id=c.user.user_id), request=request)}
47 ${h.hidden('del_auth_token', auth_token.user_api_key_id)}
52 ${h.hidden('del_auth_token', auth_token.user_api_key_id)}
48 <button class="btn btn-link btn-danger" type="submit"
53 <button class="btn btn-link btn-danger" type="submit"
49 onclick="return confirm('${_('Confirm to remove this auth token: %s') % auth_token.token_obfuscated}');">
54 onclick="return confirm('${_('Confirm to remove this auth token: %s') % auth_token.token_obfuscated}');">
50 ${_('Delete')}
55 ${_('Delete')}
51 </button>
56 </button>
52 ${h.end_form()}
57 ${h.end_form()}
53 </td>
58 </td>
54 </tr>
59 </tr>
55 %endfor
60 %endfor
56 %else:
61 %else:
57 <tr><td><div class="ip">${_('No additional auth tokens specified')}</div></td></tr>
62 <tr><td><div class="ip">${_('No additional auth tokens specified')}</div></td></tr>
58 %endif
63 %endif
59 </table>
64 </table>
60 </div>
65 </div>
61
66
62 <div class="user_auth_tokens">
67 <div class="user_auth_tokens">
63 ${h.secure_form(h.route_path('edit_user_auth_tokens_add', user_id=c.user.user_id), request=request)}
68 ${h.secure_form(h.route_path('edit_user_auth_tokens_add', user_id=c.user.user_id), request=request)}
64 <div class="form form-vertical">
69 <div class="form form-vertical">
65 <!-- fields -->
70 <!-- fields -->
66 <div class="fields">
71 <div class="fields">
67 <div class="field">
72 <div class="field">
68 <div class="label">
73 <div class="label">
69 <label for="new_email">${_('New authentication token')}:</label>
74 <label for="new_email">${_('New authentication token')}:</label>
70 </div>
75 </div>
71 <div class="input">
76 <div class="input">
72 ${h.text('description', class_='medium', placeholder=_('Description'))}
77 ${h.text('description', class_='medium', placeholder=_('Description'))}
73 ${h.hidden('lifetime')}
78 ${h.hidden('lifetime')}
74 ${h.select('role', '', c.role_options)}
79 ${h.select('role', '', c.role_options)}
75
80
76 % if c.allow_scoped_tokens:
81 % if c.allow_scoped_tokens:
77 ${h.hidden('scope_repo_id')}
82 ${h.hidden('scope_repo_id')}
78 % else:
83 % else:
79 ${h.select('scope_repo_id_disabled', '', ['Scopes available in EE edition'], disabled='disabled')}
84 ${h.select('scope_repo_id_disabled', '', ['Scopes available in EE edition'], disabled='disabled')}
80 % endif
85 % endif
81 </div>
86 </div>
82 <p class="help-block">
87 <p class="help-block">
83 ${_('Repository scope works only with tokens with VCS type.')}
88 ${_('Repository scope works only with tokens with VCS type.')}
84 </p>
89 </p>
85 </div>
90 </div>
86 <div class="buttons">
91 <div class="buttons">
87 ${h.submit('save',_('Add'),class_="btn")}
92 ${h.submit('save',_('Add'),class_="btn")}
88 ${h.reset('reset',_('Reset'),class_="btn")}
93 ${h.reset('reset',_('Reset'),class_="btn")}
89 </div>
94 </div>
90 </div>
95 </div>
91 </div>
96 </div>
92 ${h.end_form()}
97 ${h.end_form()}
93 </div>
98 </div>
94 </div>
99 </div>
95 </div>
100 </div>
96
101
97 <script>
102 <script>
98
103
99 $(document).ready(function(){
104 $(document).ready(function(){
100
105
101 var select2Options = {
106 var select2Options = {
102 'containerCssClass': "drop-menu",
107 'containerCssClass': "drop-menu",
103 'dropdownCssClass': "drop-menu-dropdown",
108 'dropdownCssClass': "drop-menu-dropdown",
104 'dropdownAutoWidth': true
109 'dropdownAutoWidth': true
105 };
110 };
106 $("#role").select2(select2Options);
111 $("#role").select2(select2Options);
107
112
108 var preloadData = {
113 var preloadData = {
109 results: [
114 results: [
110 % for entry in c.lifetime_values:
115 % for entry in c.lifetime_values:
111 {id:${entry[0]}, text:"${entry[1]}"}${'' if loop.last else ','}
116 {id:${entry[0]}, text:"${entry[1]}"}${'' if loop.last else ','}
112 % endfor
117 % endfor
113 ]
118 ]
114 };
119 };
115
120
116 $("#lifetime").select2({
121 $("#lifetime").select2({
117 containerCssClass: "drop-menu",
122 containerCssClass: "drop-menu",
118 dropdownCssClass: "drop-menu-dropdown",
123 dropdownCssClass: "drop-menu-dropdown",
119 dropdownAutoWidth: true,
124 dropdownAutoWidth: true,
120 data: preloadData,
125 data: preloadData,
121 placeholder: "${_('Select or enter expiration date')}",
126 placeholder: "${_('Select or enter expiration date')}",
122 query: function(query) {
127 query: function(query) {
123 feedLifetimeOptions(query, preloadData);
128 feedLifetimeOptions(query, preloadData);
124 }
129 }
125 });
130 });
126
131
127
132
128 var repoFilter = function(data) {
133 var repoFilter = function(data) {
129 var results = [];
134 var results = [];
130
135
131 if (!data.results[0]) {
136 if (!data.results[0]) {
132 return data
137 return data
133 }
138 }
134
139
135 $.each(data.results[0].children, function() {
140 $.each(data.results[0].children, function() {
136 // replace name to ID for submision
141 // replace name to ID for submision
137 this.id = this.repo_id;
142 this.id = this.repo_id;
138 results.push(this);
143 results.push(this);
139 });
144 });
140
145
141 data.results[0].children = results;
146 data.results[0].children = results;
142 return data;
147 return data;
143 };
148 };
144
149
145 $("#scope_repo_id_disabled").select2(select2Options);
150 $("#scope_repo_id_disabled").select2(select2Options);
146
151
147 var selectVcsScope = function() {
152 var selectVcsScope = function() {
148 // select vcs scope and disable input
153 // select vcs scope and disable input
149 $("#role").select2("val", "${c.role_vcs}").trigger('change');
154 $("#role").select2("val", "${c.role_vcs}").trigger('change');
150 $("#role").select2("readonly", true)
155 $("#role").select2("readonly", true)
151 };
156 };
152
157
153 $("#scope_repo_id").select2({
158 $("#scope_repo_id").select2({
154 cachedDataSource: {},
159 cachedDataSource: {},
155 minimumInputLength: 2,
160 minimumInputLength: 2,
156 placeholder: "${_('repository scope')}",
161 placeholder: "${_('repository scope')}",
157 dropdownAutoWidth: true,
162 dropdownAutoWidth: true,
158 containerCssClass: "drop-menu",
163 containerCssClass: "drop-menu",
159 dropdownCssClass: "drop-menu-dropdown",
164 dropdownCssClass: "drop-menu-dropdown",
160 formatResult: formatRepoResult,
165 formatResult: formatRepoResult,
161 query: $.debounce(250, function(query){
166 query: $.debounce(250, function(query){
162 self = this;
167 self = this;
163 var cacheKey = query.term;
168 var cacheKey = query.term;
164 var cachedData = self.cachedDataSource[cacheKey];
169 var cachedData = self.cachedDataSource[cacheKey];
165
170
166 if (cachedData) {
171 if (cachedData) {
167 query.callback({results: cachedData.results});
172 query.callback({results: cachedData.results});
168 } else {
173 } else {
169 $.ajax({
174 $.ajax({
170 url: pyroutes.url('repo_list_data'),
175 url: pyroutes.url('repo_list_data'),
171 data: {'query': query.term},
176 data: {'query': query.term},
172 dataType: 'json',
177 dataType: 'json',
173 type: 'GET',
178 type: 'GET',
174 success: function(data) {
179 success: function(data) {
175 data = repoFilter(data);
180 data = repoFilter(data);
176 self.cachedDataSource[cacheKey] = data;
181 self.cachedDataSource[cacheKey] = data;
177 query.callback({results: data.results});
182 query.callback({results: data.results});
178 },
183 },
179 error: function(data, textStatus, errorThrown) {
184 error: function(data, textStatus, errorThrown) {
180 alert("Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
185 alert("Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
181 }
186 }
182 })
187 })
183 }
188 }
184 })
189 })
185 });
190 });
186 $("#scope_repo_id").on('select2-selecting', function(e){
191 $("#scope_repo_id").on('select2-selecting', function(e){
187 selectVcsScope()
192 selectVcsScope()
188 });
193 });
189
194
190 });
195 });
191 </script>
196 </script>
@@ -1,41 +1,44 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('Caches')}</h3>
5 <h3 class="panel-title">
6 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
7 &nbsp;- ${_('Caches')}
8 </h3>
6 </div>
9 </div>
7 <div class="panel-body">
10 <div class="panel-body">
8 <p>
11 <p>
9 Cache keys used for storing cached values of user permissions and authentication plugin cache.
12 Cache keys used for storing cached values of user permissions and authentication plugin cache.
10 Invalidating the cache will remove those entries.
13 Invalidating the cache will remove those entries.
11 </p>
14 </p>
12
15
13 <pre>
16 <pre>
14 region: ${c.region.name}
17 region: ${c.region.name}
15 backend: ${c.region.actual_backend.__class__}
18 backend: ${c.region.actual_backend.__class__}
16 store: ${c.region.actual_backend.get_store()}
19 store: ${c.region.actual_backend.get_store()}
17
20
18 % if c.user_keys:
21 % if c.user_keys:
19 ${len(c.user_keys)} <a href="#showKeys" onclick="$('#show-keys').toggle()">${_('Show all')}</a>
22 ${len(c.user_keys)} <a href="#showKeys" onclick="$('#show-keys').toggle()">${_('Show all')}</a>
20 <span id="show-keys" style="display: none">
23 <span id="show-keys" style="display: none">
21 % for k in c.user_keys:
24 % for k in c.user_keys:
22 - ${k}
25 - ${k}
23 % endfor
26 % endfor
24 </span>
27 </span>
25 % else:
28 % else:
26 NO KEYS FOUND
29 NO KEYS FOUND
27 % endif
30 % endif
28 </pre>
31 </pre>
29 <p></p>
32 <p></p>
30 ${h.secure_form(h.route_path('edit_user_caches_update', user_id=c.user.user_id), request=request)}
33 ${h.secure_form(h.route_path('edit_user_caches_update', user_id=c.user.user_id), request=request)}
31 <div class="form">
34 <div class="form">
32 <div class="fields">
35 <div class="fields">
33 ${h.submit('reset_cache_%s' % c.user.user_id, _('Invalidate user cache'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to invalidate user cache')+"');")}
36 ${h.submit('reset_cache_%s' % c.user.user_id, _('Invalidate user cache'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to invalidate user cache')+"');")}
34 </div>
37 </div>
35 </div>
38 </div>
36 ${h.end_form()}
39 ${h.end_form()}
37
40
38 </div>
41 </div>
39 </div>
42 </div>
40
43
41
44
@@ -1,71 +1,74 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('Additional Email Addresses')}</h3>
5 <h3 class="panel-title">
6 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
7 &nbsp;- ${_('Additional Email Addresses')}
8 </h3>
6 </div>
9 </div>
7 <div class="panel-body">
10 <div class="panel-body">
8 <div class="emails_wrap">
11 <div class="emails_wrap">
9 <table class="rctable account_emails useremails">
12 <table class="rctable account_emails useremails">
10 <tr>
13 <tr>
11 <td class="td-user">
14 <td class="td-user">
12 ${base.gravatar(c.user.email, 16)}
15 ${base.gravatar(c.user.email, 16)}
13 <span class="user email">${c.user.email}</span>
16 <span class="user email">${c.user.email}</span>
14 </td>
17 </td>
15 <td class="td-tags">
18 <td class="td-tags">
16 <span class="tag">${_('Primary')}</span>
19 <span class="tag">${_('Primary')}</span>
17 </td>
20 </td>
18 </tr>
21 </tr>
19 %if c.user_email_map:
22 %if c.user_email_map:
20 %for em in c.user_email_map:
23 %for em in c.user_email_map:
21 <tr>
24 <tr>
22 <td class="td-user">
25 <td class="td-user">
23 ${base.gravatar(em.email, 16)}
26 ${base.gravatar(em.email, 16)}
24 <span class="user email">${em.email}</span>
27 <span class="user email">${em.email}</span>
25 </td>
28 </td>
26 <td class="td-action">
29 <td class="td-action">
27 ${h.secure_form(h.route_path('edit_user_emails_delete', user_id=c.user.user_id), request=request)}
30 ${h.secure_form(h.route_path('edit_user_emails_delete', user_id=c.user.user_id), request=request)}
28 ${h.hidden('del_email_id', em.email_id)}
31 ${h.hidden('del_email_id', em.email_id)}
29 <button class="btn btn-link btn-danger" type="submit"
32 <button class="btn btn-link btn-danger" type="submit"
30 onclick="return confirm('${_('Confirm to delete this email: %s') % em.email}');">
33 onclick="return confirm('${_('Confirm to delete this email: %s') % em.email}');">
31 ${_('Delete')}
34 ${_('Delete')}
32 </button>
35 </button>
33 ${h.end_form()}
36 ${h.end_form()}
34 </td>
37 </td>
35 </tr>
38 </tr>
36 %endfor
39 %endfor
37 %else:
40 %else:
38 <tr class="noborder">
41 <tr class="noborder">
39 <td colspan="3">
42 <td colspan="3">
40 <div class="td-email">
43 <div class="td-email">
41 ${_('No additional emails specified')}
44 ${_('No additional emails specified')}
42 </div>
45 </div>
43 </td>
46 </td>
44 </tr>
47 </tr>
45 %endif
48 %endif
46 </table>
49 </table>
47 </div>
50 </div>
48
51
49 ${h.secure_form(h.route_path('edit_user_emails_add', user_id=c.user.user_id), request=request)}
52 ${h.secure_form(h.route_path('edit_user_emails_add', user_id=c.user.user_id), request=request)}
50 <div class="form">
53 <div class="form">
51 <!-- fields -->
54 <!-- fields -->
52 <div class="fields">
55 <div class="fields">
53 <div class="field">
56 <div class="field">
54 <div class="label">
57 <div class="label">
55 <label for="new_email">${_('New email address')}:</label>
58 <label for="new_email">${_('New email address')}:</label>
56 </div>
59 </div>
57 <div class="input">
60 <div class="input">
58 ${h.text('new_email', class_='medium')}
61 ${h.text('new_email', class_='medium')}
59 </div>
62 </div>
60 </div>
63 </div>
61 <div class="buttons">
64 <div class="buttons">
62 ${h.submit('save',_('Add'),class_="btn btn-small")}
65 ${h.submit('save',_('Add'),class_="btn btn-small")}
63 ${h.reset('reset',_('Reset'),class_="btn btn-small")}
66 ${h.reset('reset',_('Reset'),class_="btn btn-small")}
64 </div>
67 </div>
65 </div>
68 </div>
66 </div>
69 </div>
67 ${h.end_form()}
70 ${h.end_form()}
68 </div>
71 </div>
69 </div>
72 </div>
70
73
71
74
@@ -1,147 +1,150 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2 <%namespace name="base" file="/base/base.mako"/>
3
3
4 <div class="panel panel-default">
4 <div class="panel panel-default">
5 <div class="panel-heading">
5 <div class="panel-heading">
6 <h3 class="panel-title">${_('User groups administration')}</h3>
6 <h3 class="panel-title">
7 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
8 &nbsp;- ${_('User groups administration')}
9 </h3>
7 </div>
10 </div>
8 <div class="panel-body">
11 <div class="panel-body">
9 <div class="fields">
12 <div class="fields">
10 <div class="field">
13 <div class="field">
11 <div class="label label-checkbox">
14 <div class="label label-checkbox">
12 <label for="users_group_active">${_('Add `%s` to user group') % c.user.username}:</label>
15 <label for="users_group_active">${_('Add `%s` to user group') % c.user.username}:</label>
13 </div>
16 </div>
14 <div class="input">
17 <div class="input">
15 ${h.text('add_user_to_group', placeholder="user group name", class_="medium")}
18 ${h.text('add_user_to_group', placeholder="user group name", class_="medium")}
16 </div>
19 </div>
17
20
18 </div>
21 </div>
19 </div>
22 </div>
20
23
21 <div class="groups_management">
24 <div class="groups_management">
22 ${h.secure_form(h.route_path('edit_user_groups_management_updates', user_id=c.user.user_id), request=request)}
25 ${h.secure_form(h.route_path('edit_user_groups_management_updates', user_id=c.user.user_id), request=request)}
23 <div id="repos_list_wrap">
26 <div id="repos_list_wrap">
24 <table id="user_group_list_table" class="display"></table>
27 <table id="user_group_list_table" class="display"></table>
25 </div>
28 </div>
26 <div class="buttons">
29 <div class="buttons">
27 ${h.submit('save',_('Save'),class_="btn")}
30 ${h.submit('save',_('Save'),class_="btn")}
28 </div>
31 </div>
29 ${h.end_form()}
32 ${h.end_form()}
30 </div>
33 </div>
31 </div>
34 </div>
32 </div>
35 </div>
33 <script>
36 <script>
34 var api;
37 var api;
35 $(document).ready(function() {
38 $(document).ready(function() {
36
39
37 var get_datatable_count = function(){
40 var get_datatable_count = function(){
38 $('#user_group_count').text(api.page.info().recordsDisplay);
41 $('#user_group_count').text(api.page.info().recordsDisplay);
39 };
42 };
40
43
41 $('#user_group_list_table').on('click', 'a.editor_remove', function (e) {
44 $('#user_group_list_table').on('click', 'a.editor_remove', function (e) {
42 e.preventDefault();
45 e.preventDefault();
43 var row = api.row($(this).closest('tr'));
46 var row = api.row($(this).closest('tr'));
44 row.remove().draw();
47 row.remove().draw();
45 } );
48 } );
46
49
47 $('#user_group_list_table').DataTable({
50 $('#user_group_list_table').DataTable({
48 data: ${c.groups|n},
51 data: ${c.groups|n},
49 dom: 'rtp',
52 dom: 'rtp',
50 pageLength: ${c.visual.admin_grid_items},
53 pageLength: ${c.visual.admin_grid_items},
51 order: [[ 0, "asc" ]],
54 order: [[ 0, "asc" ]],
52 columns: [
55 columns: [
53 { data: {"_": "group_name",
56 { data: {"_": "group_name",
54 "sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," ,
57 "sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," ,
55 render: function (data,type,full,meta)
58 render: function (data,type,full,meta)
56 {return '<div><i class="icon-user-group" title="User group">'+data+'</i></div>'}},
59 {return '<div><i class="icon-user-group" title="User group">'+data+'</i></div>'}},
57
60
58 { data: {"_": "group_description",
61 { data: {"_": "group_description",
59 "sort": "group_description"}, title: "${_('Description')}", className: "td-description" },
62 "sort": "group_description"}, title: "${_('Description')}", className: "td-description" },
60 { data: {"_": "users_group_id"}, className: "td-user",
63 { data: {"_": "users_group_id"}, className: "td-user",
61 render: function (data,type,full,meta)
64 render: function (data,type,full,meta)
62 {return '<input type="hidden" name="users_group_id" value="'+data+'">'}},
65 {return '<input type="hidden" name="users_group_id" value="'+data+'">'}},
63 { data: {"_": "active",
66 { data: {"_": "active",
64 "sort": "active"}, title: "${_('Active')}", className: "td-active"},
67 "sort": "active"}, title: "${_('Active')}", className: "td-active"},
65 { data: {"_": "owner_data"}, title: "${_('Owner')}", className: "td-user",
68 { data: {"_": "owner_data"}, title: "${_('Owner')}", className: "td-user",
66 render: function (data,type,full,meta)
69 render: function (data,type,full,meta)
67 {return '<div class="rc-user tooltip">'+
70 {return '<div class="rc-user tooltip">'+
68 '<img class="gravatar" src="'+ data.owner_icon +'" height="16" width="16">'+
71 '<img class="gravatar" src="'+ data.owner_icon +'" height="16" width="16">'+
69 data.owner +'</div>'
72 data.owner +'</div>'
70 }
73 }
71 },
74 },
72 { data: null,
75 { data: null,
73 title: "${_('Action')}",
76 title: "${_('Action')}",
74 className: "td-action",
77 className: "td-action",
75 defaultContent: '-'
78 defaultContent: '-'
76 }
79 }
77 ],
80 ],
78 language: {
81 language: {
79 paginate: DEFAULT_GRID_PAGINATION,
82 paginate: DEFAULT_GRID_PAGINATION,
80 emptyTable: _gettext("No user groups available yet.")
83 emptyTable: _gettext("No user groups available yet.")
81 },
84 },
82 "initComplete": function( settings, json ) {
85 "initComplete": function( settings, json ) {
83 var data_grid = $('#user_group_list_table').dataTable();
86 var data_grid = $('#user_group_list_table').dataTable();
84 api = data_grid.api();
87 api = data_grid.api();
85 get_datatable_count();
88 get_datatable_count();
86 }
89 }
87 });
90 });
88
91
89 // update the counter when doing search
92 // update the counter when doing search
90 $('#user_group_list_table').on( 'search.dt', function (e,settings) {
93 $('#user_group_list_table').on( 'search.dt', function (e,settings) {
91 get_datatable_count();
94 get_datatable_count();
92 });
95 });
93
96
94 // filter, filter both grids
97 // filter, filter both grids
95 $('#q_filter').on( 'keyup', function () {
98 $('#q_filter').on( 'keyup', function () {
96 var user_api = $('#user_group_list_table').dataTable().api();
99 var user_api = $('#user_group_list_table').dataTable().api();
97 user_api
100 user_api
98 .columns(0)
101 .columns(0)
99 .search(this.value)
102 .search(this.value)
100 .draw();
103 .draw();
101 });
104 });
102
105
103 // refilter table if page load via back button
106 // refilter table if page load via back button
104 $("#q_filter").trigger('keyup');
107 $("#q_filter").trigger('keyup');
105
108
106 });
109 });
107
110
108 $('#language').select2({
111 $('#language').select2({
109 'containerCssClass': "drop-menu",
112 'containerCssClass': "drop-menu",
110 'dropdownCssClass': "drop-menu-dropdown",
113 'dropdownCssClass': "drop-menu-dropdown",
111 'dropdownAutoWidth': true
114 'dropdownAutoWidth': true
112 });
115 });
113
116
114
117
115
118
116 $(document).ready(function(){
119 $(document).ready(function(){
117 $("#group_parent_id").select2({
120 $("#group_parent_id").select2({
118 'containerCssClass': "drop-menu",
121 'containerCssClass': "drop-menu",
119 'dropdownCssClass': "drop-menu-dropdown",
122 'dropdownCssClass': "drop-menu-dropdown",
120 'dropdownAutoWidth': true
123 'dropdownAutoWidth': true
121 });
124 });
122
125
123 $('#add_user_to_group').autocomplete({
126 $('#add_user_to_group').autocomplete({
124 serviceUrl: pyroutes.url('user_group_autocomplete_data'),
127 serviceUrl: pyroutes.url('user_group_autocomplete_data'),
125 minChars:2,
128 minChars:2,
126 maxHeight:400,
129 maxHeight:400,
127 width:300,
130 width:300,
128 deferRequestBy: 300, //miliseconds
131 deferRequestBy: 300, //miliseconds
129 showNoSuggestionNotice: true,
132 showNoSuggestionNotice: true,
130 params: { user_groups:true },
133 params: { user_groups:true },
131 formatResult: autocompleteFormatResult,
134 formatResult: autocompleteFormatResult,
132 lookupFilter: autocompleteFilterResult,
135 lookupFilter: autocompleteFilterResult,
133 onSelect: function(element, suggestion){
136 onSelect: function(element, suggestion){
134 var owner = {owner_icon: suggestion.owner_icon, owner:suggestion.owner};
137 var owner = {owner_icon: suggestion.owner_icon, owner:suggestion.owner};
135 api.row.add(
138 api.row.add(
136 {"active": suggestion.active,
139 {"active": suggestion.active,
137 "owner_data": owner,
140 "owner_data": owner,
138 "users_group_id": suggestion.id,
141 "users_group_id": suggestion.id,
139 "group_description": suggestion.description,
142 "group_description": suggestion.description,
140 "group_name": suggestion.value}).draw();
143 "group_name": suggestion.value}).draw();
141 }
144 }
142 });
145 });
143 })
146 })
144
147
145 </script>
148 </script>
146
149
147
150
@@ -1,78 +1,83 b''
1 <%namespace name="base" file="/base/base.mako"/>
2
1 <div class="panel panel-default">
3 <div class="panel panel-default">
2 <div class="panel-heading">
4 <div class="panel-heading">
3 <h3 class="panel-title">${_('Custom IP Whitelist')}</h3>
5 <h3 class="panel-title">
6 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
7 &nbsp;- ${_('Custom IP Whitelist')}
8 </h3>
4 </div>
9 </div>
5 <div class="panel-body">
10 <div class="panel-body">
6 <div class="ips_wrap">
11 <div class="ips_wrap">
7 <h5>${_('Current IP address')}: <code>${c.rhodecode_user.ip_addr}</code></h5>
12 <h5>${_('Current IP address')}: <code>${c.rhodecode_user.ip_addr}</code></h5>
8 <table class="rctable ip-whitelist">
13 <table class="rctable ip-whitelist">
9 <tr>
14 <tr>
10 <th>${_('IP Address')}</th>
15 <th>${_('IP Address')}</th>
11 <th>${_('IP Range')}</th>
16 <th>${_('IP Range')}</th>
12 <th>${_('Description')}</th>
17 <th>${_('Description')}</th>
13 <th></th>
18 <th></th>
14 </tr>
19 </tr>
15 %if c.default_user_ip_map and c.inherit_default_ips:
20 %if c.default_user_ip_map and c.inherit_default_ips:
16 %for ip in c.default_user_ip_map:
21 %for ip in c.default_user_ip_map:
17 <tr>
22 <tr>
18 <td class="td-ip"><div class="ip">${ip.ip_addr}</div></td>
23 <td class="td-ip"><div class="ip">${ip.ip_addr}</div></td>
19 <td class="td-iprange"><div class="ip">${h.ip_range(ip.ip_addr)}</div></td>
24 <td class="td-iprange"><div class="ip">${h.ip_range(ip.ip_addr)}</div></td>
20 <td class="td-description">${h.literal(_('Inherited from %s') % h.link_to('*default*',h.route_path('admin_permissions_ips')))}</td>
25 <td class="td-description">${h.literal(_('Inherited from %s') % h.link_to('*default*',h.route_path('admin_permissions_ips')))}</td>
21 <td></td>
26 <td></td>
22 </tr>
27 </tr>
23 %endfor
28 %endfor
24 %endif
29 %endif
25
30
26 %if c.user_ip_map:
31 %if c.user_ip_map:
27 %for ip in c.user_ip_map:
32 %for ip in c.user_ip_map:
28 <tr>
33 <tr>
29 <td class="td-ip"><div class="ip">${ip.ip_addr}</div></td>
34 <td class="td-ip"><div class="ip">${ip.ip_addr}</div></td>
30 <td class="td-iprange"><div class="ip">${h.ip_range(ip.ip_addr)}</div></td>
35 <td class="td-iprange"><div class="ip">${h.ip_range(ip.ip_addr)}</div></td>
31 <td class="td-description"><div class="ip">${ip.description}</div></td>
36 <td class="td-description"><div class="ip">${ip.description}</div></td>
32 <td class="td-action">
37 <td class="td-action">
33 ${h.secure_form(h.route_path('edit_user_ips_delete', user_id=c.user.user_id), request=request)}
38 ${h.secure_form(h.route_path('edit_user_ips_delete', user_id=c.user.user_id), request=request)}
34 ${h.hidden('del_ip_id', ip.ip_id)}
39 ${h.hidden('del_ip_id', ip.ip_id)}
35 ${h.submit('remove_', _('Delete'),id="remove_ip_%s" % ip.ip_id,
40 ${h.submit('remove_', _('Delete'),id="remove_ip_%s" % ip.ip_id,
36 class_="btn btn-link btn-danger", onclick="return confirm('"+_('Confirm to delete this ip: %s') % ip.ip_addr+"');")}
41 class_="btn btn-link btn-danger", onclick="return confirm('"+_('Confirm to delete this ip: %s') % ip.ip_addr+"');")}
37 ${h.end_form()}
42 ${h.end_form()}
38 </td>
43 </td>
39 </tr>
44 </tr>
40 %endfor
45 %endfor
41 %endif
46 %endif
42 %if not c.default_user_ip_map and not c.user_ip_map:
47 %if not c.default_user_ip_map and not c.user_ip_map:
43 <tr>
48 <tr>
44 <td><h2 class="ip">${_('All IP addresses are allowed')}</h2></td>
49 <td><h2 class="ip">${_('All IP addresses are allowed')}</h2></td>
45 <td></td>
50 <td></td>
46 <td></td>
51 <td></td>
47 <td></td>
52 <td></td>
48 </tr>
53 </tr>
49 %endif
54 %endif
50 </table>
55 </table>
51 </div>
56 </div>
52
57
53 <div>
58 <div>
54 ${h.secure_form(h.route_path('edit_user_ips_add', user_id=c.user.user_id), request=request)}
59 ${h.secure_form(h.route_path('edit_user_ips_add', user_id=c.user.user_id), request=request)}
55 <div class="form">
60 <div class="form">
56 <!-- fields -->
61 <!-- fields -->
57 <div class="fields">
62 <div class="fields">
58 <div class="field">
63 <div class="field">
59 <div class="label">
64 <div class="label">
60 <label for="new_ip">${_('New IP Address')}:</label>
65 <label for="new_ip">${_('New IP Address')}:</label>
61 </div>
66 </div>
62 <div class="input">
67 <div class="input">
63 ${h.text('new_ip')} ${h.text('description', placeholder=_('Description...'))}
68 ${h.text('new_ip')} ${h.text('description', placeholder=_('Description...'))}
64 <span class="help-block pre-formatting">${_('Enter comma separated list of ip addresses like 10.0.0.1,10.0.0.2.\n'
69 <span class="help-block pre-formatting">${_('Enter comma separated list of ip addresses like 10.0.0.1,10.0.0.2.\n'
65 'Use a ip address with a mask 127.0.0.1/24, to create a network match pattern.\n'
70 'Use a ip address with a mask 127.0.0.1/24, to create a network match pattern.\n'
66 'To specify multiple entries on an address range use 127.0.0.1-127.0.0.10 syntax')}</span>
71 'To specify multiple entries on an address range use 127.0.0.1-127.0.0.10 syntax')}</span>
67 </div>
72 </div>
68 </div>
73 </div>
69 <div class="buttons">
74 <div class="buttons">
70 ${h.submit('save',_('Add'),class_="btn btn-small")}
75 ${h.submit('save',_('Add'),class_="btn btn-small")}
71 ${h.reset('reset',_('Reset'),class_="btn btn-small")}
76 ${h.reset('reset',_('Reset'),class_="btn btn-small")}
72 </div>
77 </div>
73 </div>
78 </div>
74 </div>
79 </div>
75 ${h.end_form()}
80 ${h.end_form()}
76 </div>
81 </div>
77 </div>
82 </div>
78 </div>
83 </div>
@@ -1,161 +1,164 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <div class="panel panel-default user-profile">
3 <div class="panel panel-default user-profile">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('User Profile')}</h3>
5 <h3 class="panel-title">
6 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
7 &nbsp;- ${_('User Profile')}
8 </h3>
6 </div>
9 </div>
7 <div class="panel-body">
10 <div class="panel-body">
8 <div class="user-profile-content">
11 <div class="user-profile-content">
9 ${h.secure_form(h.route_path('user_update', user_id=c.user.user_id), class_='form', request=request)}
12 ${h.secure_form(h.route_path('user_update', user_id=c.user.user_id), class_='form', request=request)}
10 <% readonly = None %>
13 <% readonly = None %>
11 <% disabled = "" %>
14 <% disabled = "" %>
12 %if c.extern_type != 'rhodecode':
15 %if c.extern_type != 'rhodecode':
13 <% readonly = "readonly" %>
16 <% readonly = "readonly" %>
14 <% disabled = " disabled" %>
17 <% disabled = " disabled" %>
15 <div class="alert-warning" style="margin:0px 0px 20px 0px; padding: 10px">
18 <div class="alert-warning" style="margin:0px 0px 20px 0px; padding: 10px">
16 <strong>${_('This user was created from external source (%s). Editing some of the settings is limited.' % c.extern_type)}</strong>
19 <strong>${_('This user was created from external source (%s). Editing some of the settings is limited.' % c.extern_type)}</strong>
17 </div>
20 </div>
18 %endif
21 %endif
19 <div class="form">
22 <div class="form">
20 <div class="fields">
23 <div class="fields">
21 <div class="field">
24 <div class="field">
22 <div class="label photo">
25 <div class="label photo">
23 ${_('Photo')}:
26 ${_('Photo')}:
24 </div>
27 </div>
25 <div class="input profile">
28 <div class="input profile">
26 %if c.visual.use_gravatar:
29 %if c.visual.use_gravatar:
27 ${base.gravatar(c.user.email, 100)}
30 ${base.gravatar(c.user.email, 100)}
28 <p class="help-block">${_('Change the avatar at')} <a href="http://gravatar.com">gravatar.com</a>.</p>
31 <p class="help-block">${_('Change the avatar at')} <a href="http://gravatar.com">gravatar.com</a>.</p>
29 %else:
32 %else:
30 ${base.gravatar(c.user.email, 100)}
33 ${base.gravatar(c.user.email, 100)}
31 %endif
34 %endif
32 </div>
35 </div>
33 </div>
36 </div>
34 <div class="field">
37 <div class="field">
35 <div class="label">
38 <div class="label">
36 ${_('Username')}:
39 ${_('Username')}:
37 </div>
40 </div>
38 <div class="input">
41 <div class="input">
39 ${h.text('username', class_='%s medium' % disabled, readonly=readonly)}
42 ${h.text('username', class_='%s medium' % disabled, readonly=readonly)}
40 </div>
43 </div>
41 </div>
44 </div>
42 <div class="field">
45 <div class="field">
43 <div class="label">
46 <div class="label">
44 <label for="name">${_('First Name')}:</label>
47 <label for="name">${_('First Name')}:</label>
45 </div>
48 </div>
46 <div class="input">
49 <div class="input">
47 ${h.text('firstname', class_="medium")}
50 ${h.text('firstname', class_="medium")}
48 </div>
51 </div>
49 </div>
52 </div>
50
53
51 <div class="field">
54 <div class="field">
52 <div class="label">
55 <div class="label">
53 <label for="lastname">${_('Last Name')}:</label>
56 <label for="lastname">${_('Last Name')}:</label>
54 </div>
57 </div>
55 <div class="input">
58 <div class="input">
56 ${h.text('lastname', class_="medium")}
59 ${h.text('lastname', class_="medium")}
57 </div>
60 </div>
58 </div>
61 </div>
59
62
60 <div class="field">
63 <div class="field">
61 <div class="label">
64 <div class="label">
62 <label for="email">${_('Email')}:</label>
65 <label for="email">${_('Email')}:</label>
63 </div>
66 </div>
64 <div class="input">
67 <div class="input">
65 ## we should be able to edit email !
68 ## we should be able to edit email !
66 ${h.text('email', class_="medium")}
69 ${h.text('email', class_="medium")}
67 </div>
70 </div>
68 </div>
71 </div>
69 <div class="field">
72 <div class="field">
70 <div class="label">
73 <div class="label">
71 <label for="description">${_('Description')}:</label>
74 <label for="description">${_('Description')}:</label>
72 </div>
75 </div>
73 <div class="input textarea editor">
76 <div class="input textarea editor">
74 ${h.textarea('description', rows=10, class_="medium")}
77 ${h.textarea('description', rows=10, class_="medium")}
75 <% metatags_url = h.literal('''<a href="#metatagsShow" onclick="$('#meta-tags-desc').toggle();return false">meta-tags</a>''') %>
78 <% metatags_url = h.literal('''<a href="#metatagsShow" onclick="$('#meta-tags-desc').toggle();return false">meta-tags</a>''') %>
76 <span class="help-block">${_('Plain text format with support of {metatags}.').format(metatags=metatags_url)|n}</span>
79 <span class="help-block">${_('Plain text format with support of {metatags}.').format(metatags=metatags_url)|n}</span>
77 <span id="meta-tags-desc" style="display: none">
80 <span id="meta-tags-desc" style="display: none">
78 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
81 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
79 ${dt.metatags_help()}
82 ${dt.metatags_help()}
80 </span>
83 </span>
81 </div>
84 </div>
82 </div>
85 </div>
83 <div class="field">
86 <div class="field">
84 <div class="label">
87 <div class="label">
85 ${_('New Password')}:
88 ${_('New Password')}:
86 </div>
89 </div>
87 <div class="input">
90 <div class="input">
88 ${h.password('new_password',class_='%s medium' % disabled,autocomplete="off",readonly=readonly)}
91 ${h.password('new_password',class_='%s medium' % disabled,autocomplete="off",readonly=readonly)}
89 </div>
92 </div>
90 </div>
93 </div>
91 <div class="field">
94 <div class="field">
92 <div class="label">
95 <div class="label">
93 ${_('New Password Confirmation')}:
96 ${_('New Password Confirmation')}:
94 </div>
97 </div>
95 <div class="input">
98 <div class="input">
96 ${h.password('password_confirmation',class_="%s medium" % disabled,autocomplete="off",readonly=readonly)}
99 ${h.password('password_confirmation',class_="%s medium" % disabled,autocomplete="off",readonly=readonly)}
97 </div>
100 </div>
98 </div>
101 </div>
99 <div class="field">
102 <div class="field">
100 <div class="label-text">
103 <div class="label-text">
101 ${_('Active')}:
104 ${_('Active')}:
102 </div>
105 </div>
103 <div class="input user-checkbox">
106 <div class="input user-checkbox">
104 ${h.checkbox('active',value=True)}
107 ${h.checkbox('active',value=True)}
105 </div>
108 </div>
106 </div>
109 </div>
107 <div class="field">
110 <div class="field">
108 <div class="label-text">
111 <div class="label-text">
109 ${_('Super-admin')}:
112 ${_('Super-admin')}:
110 </div>
113 </div>
111 <div class="input user-checkbox">
114 <div class="input user-checkbox">
112 ${h.checkbox('admin',value=True)}
115 ${h.checkbox('admin',value=True)}
113 </div>
116 </div>
114 </div>
117 </div>
115 <div class="field">
118 <div class="field">
116 <div class="label-text">
119 <div class="label-text">
117 ${_('Authentication type')}:
120 ${_('Authentication type')}:
118 </div>
121 </div>
119 <div class="input">
122 <div class="input">
120 ${h.select('extern_type', c.extern_type, c.allowed_extern_types)}
123 ${h.select('extern_type', c.extern_type, c.allowed_extern_types)}
121 <p class="help-block">${_('When user was created using an external source. He is bound to authentication using this method.')}</p>
124 <p class="help-block">${_('When user was created using an external source. He is bound to authentication using this method.')}</p>
122 </div>
125 </div>
123 </div>
126 </div>
124 <div class="field">
127 <div class="field">
125 <div class="label-text">
128 <div class="label-text">
126 ${_('Name in Source of Record')}:
129 ${_('Name in Source of Record')}:
127 </div>
130 </div>
128 <div class="input">
131 <div class="input">
129 <p>${c.extern_name}</p>
132 <p>${c.extern_name}</p>
130 ${h.hidden('extern_name', readonly="readonly")}
133 ${h.hidden('extern_name', readonly="readonly")}
131 </div>
134 </div>
132 </div>
135 </div>
133 <div class="field">
136 <div class="field">
134 <div class="label">
137 <div class="label">
135 ${_('Language')}:
138 ${_('Language')}:
136 </div>
139 </div>
137 <div class="input">
140 <div class="input">
138 ## allowed_languages is defined in the users.py
141 ## allowed_languages is defined in the users.py
139 ## c.language comes from base.py as a default language
142 ## c.language comes from base.py as a default language
140 ${h.select('language', c.language, c.allowed_languages)}
143 ${h.select('language', c.language, c.allowed_languages)}
141 <p class="help-block">${h.literal(_('User interface language. Help translate %(rc_link)s into your language.') % {'rc_link': h.link_to('RhodeCode Enterprise', h.route_url('rhodecode_translations'))})}</p>
144 <p class="help-block">${h.literal(_('User interface language. Help translate %(rc_link)s into your language.') % {'rc_link': h.link_to('RhodeCode Enterprise', h.route_url('rhodecode_translations'))})}</p>
142 </div>
145 </div>
143 </div>
146 </div>
144 <div class="buttons">
147 <div class="buttons">
145 ${h.submit('save', _('Save'), class_="btn")}
148 ${h.submit('save', _('Save'), class_="btn")}
146 ${h.reset('reset', _('Reset'), class_="btn")}
149 ${h.reset('reset', _('Reset'), class_="btn")}
147 </div>
150 </div>
148 </div>
151 </div>
149 </div>
152 </div>
150 ${h.end_form()}
153 ${h.end_form()}
151 </div>
154 </div>
152 </div>
155 </div>
153 </div>
156 </div>
154
157
155 <script>
158 <script>
156 $('#language').select2({
159 $('#language').select2({
157 'containerCssClass': "drop-menu",
160 'containerCssClass': "drop-menu",
158 'dropdownCssClass': "drop-menu-dropdown",
161 'dropdownCssClass': "drop-menu-dropdown",
159 'dropdownAutoWidth': true
162 'dropdownAutoWidth': true
160 });
163 });
161 </script>
164 </script>
@@ -1,85 +1,90 b''
1 <%namespace name="base" file="/base/base.mako"/>
2
1 <div class="panel panel-default">
3 <div class="panel panel-default">
2 <div class="panel-heading">
4 <div class="panel-heading">
3 <h3 class="panel-title">${_('SSH Keys')}</h3>
5 <h3 class="panel-title">
6 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
7 &nbsp;- ${_('SSH Keys')}
8 </h3>
4 </div>
9 </div>
5 <div class="panel-body">
10 <div class="panel-body">
6 <div class="sshkeys_wrap">
11 <div class="sshkeys_wrap">
7 <table class="rctable ssh_keys">
12 <table class="rctable ssh_keys">
8 <tr>
13 <tr>
9 <th>${_('Fingerprint')}</th>
14 <th>${_('Fingerprint')}</th>
10 <th>${_('Description')}</th>
15 <th>${_('Description')}</th>
11 <th>${_('Created on')}</th>
16 <th>${_('Created on')}</th>
12 <th>${_('Accessed on')}</th>
17 <th>${_('Accessed on')}</th>
13 <th>${_('Action')}</th>
18 <th>${_('Action')}</th>
14 </tr>
19 </tr>
15 %if c.user_ssh_keys:
20 %if c.user_ssh_keys:
16 %for ssh_key in c.user_ssh_keys:
21 %for ssh_key in c.user_ssh_keys:
17 <tr class="">
22 <tr class="">
18 <td class="">
23 <td class="">
19 <code>${ssh_key.ssh_key_fingerprint}</code>
24 <code>${ssh_key.ssh_key_fingerprint}</code>
20 </td>
25 </td>
21 <td class="td-wrap">${ssh_key.description}</td>
26 <td class="td-wrap">${ssh_key.description}</td>
22 <td class="td-tags">${h.format_date(ssh_key.created_on)}</td>
27 <td class="td-tags">${h.format_date(ssh_key.created_on)}</td>
23 <td class="td-tags">${h.format_date(ssh_key.accessed_on)}</td>
28 <td class="td-tags">${h.format_date(ssh_key.accessed_on)}</td>
24
29
25 <td class="td-action">
30 <td class="td-action">
26 ${h.secure_form(h.route_path('edit_user_ssh_keys_delete', user_id=c.user.user_id), request=request)}
31 ${h.secure_form(h.route_path('edit_user_ssh_keys_delete', user_id=c.user.user_id), request=request)}
27 ${h.hidden('del_ssh_key', ssh_key.ssh_key_id)}
32 ${h.hidden('del_ssh_key', ssh_key.ssh_key_id)}
28 <button class="btn btn-link btn-danger" type="submit"
33 <button class="btn btn-link btn-danger" type="submit"
29 onclick="return confirm('${_('Confirm to remove ssh key %s') % ssh_key.ssh_key_fingerprint}');">
34 onclick="return confirm('${_('Confirm to remove ssh key %s') % ssh_key.ssh_key_fingerprint}');">
30 ${_('Delete')}
35 ${_('Delete')}
31 </button>
36 </button>
32 ${h.end_form()}
37 ${h.end_form()}
33 </td>
38 </td>
34 </tr>
39 </tr>
35 %endfor
40 %endfor
36 %else:
41 %else:
37 <tr><td><div class="ip">${_('No additional ssh keys specified')}</div></td></tr>
42 <tr><td><div class="ip">${_('No additional ssh keys specified')}</div></td></tr>
38 %endif
43 %endif
39 </table>
44 </table>
40 </div>
45 </div>
41
46
42 <div class="user_ssh_keys">
47 <div class="user_ssh_keys">
43 ${h.secure_form(h.route_path('edit_user_ssh_keys_add', user_id=c.user.user_id), request=request)}
48 ${h.secure_form(h.route_path('edit_user_ssh_keys_add', user_id=c.user.user_id), request=request)}
44 <div class="form form-vertical">
49 <div class="form form-vertical">
45 <!-- fields -->
50 <!-- fields -->
46 <div class="fields">
51 <div class="fields">
47 <div class="field">
52 <div class="field">
48 <div class="label">
53 <div class="label">
49 <label for="new_email">${_('New ssh key')}:</label>
54 <label for="new_email">${_('New ssh key')}:</label>
50 </div>
55 </div>
51 <div class="input">
56 <div class="input">
52 ${h.text('description', class_='medium', placeholder=_('Description'))}
57 ${h.text('description', class_='medium', placeholder=_('Description'))}
53 % if c.ssh_key_generator_enabled:
58 % if c.ssh_key_generator_enabled:
54 <a href="${h.route_path('edit_user_ssh_keys_generate_keypair', user_id=c.user.user_id)}">${_('Generate random RSA key')}</a>
59 <a href="${h.route_path('edit_user_ssh_keys_generate_keypair', user_id=c.user.user_id)}">${_('Generate random RSA key')}</a>
55 % endif
60 % endif
56 </div>
61 </div>
57 </div>
62 </div>
58
63
59 <div class="field">
64 <div class="field">
60 <div class="textarea text-area editor">
65 <div class="textarea text-area editor">
61 ${h.textarea('key_data',c.default_key, size=30, placeholder=_("Public key, begins with 'ssh-rsa', 'ssh-dss', 'ssh-ed25519', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', or 'ecdsa-sha2-nistp521'"))}
66 ${h.textarea('key_data',c.default_key, size=30, placeholder=_("Public key, begins with 'ssh-rsa', 'ssh-dss', 'ssh-ed25519', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', or 'ecdsa-sha2-nistp521'"))}
62 </div>
67 </div>
63 </div>
68 </div>
64
69
65 <div class="buttons">
70 <div class="buttons">
66 ${h.submit('save',_('Add'),class_="btn")}
71 ${h.submit('save',_('Add'),class_="btn")}
67 ${h.reset('reset',_('Reset'),class_="btn")}
72 ${h.reset('reset',_('Reset'),class_="btn")}
68 </div>
73 </div>
69 % if c.default_key:
74 % if c.default_key:
70 ${_('Click add to use this generate SSH key')}
75 ${_('Click add to use this generate SSH key')}
71 % endif
76 % endif
72 </div>
77 </div>
73 </div>
78 </div>
74 ${h.end_form()}
79 ${h.end_form()}
75 </div>
80 </div>
76 </div>
81 </div>
77 </div>
82 </div>
78
83
79 <script>
84 <script>
80
85
81 $(document).ready(function(){
86 $(document).ready(function(){
82
87
83
88
84 });
89 });
85 </script>
90 </script>
@@ -1,58 +1,63 b''
1 <%namespace name="base" file="/base/base.mako"/>
2
1 <div class="panel panel-default">
3 <div class="panel panel-default">
2 <div class="panel-heading">
4 <div class="panel-heading">
3 <h3 class="panel-title">${_('New SSH Key generation')}</h3>
5 <h3 class="panel-title">
6 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
7 &nbsp;- ${_('New SSH Key generation')}
8 </h3>
4 </div>
9 </div>
5 <div class="panel-body">
10 <div class="panel-body">
6 %if c.ssh_enabled and c.ssh_key_generator_enabled:
11 %if c.ssh_enabled and c.ssh_key_generator_enabled:
7 <p>
12 <p>
8 ${_('Below is a 2048 bit generated SSH RSA key.')}<br/>
13 ${_('Below is a 2048 bit generated SSH RSA key.')}<br/>
9 ${_('If You wish to use it to access RhodeCode via the SSH please save the private key and click `Use this generated key` at the bottom.')}
14 ${_('If You wish to use it to access RhodeCode via the SSH please save the private key and click `Use this generated key` at the bottom.')}
10 </p>
15 </p>
11 <h4>${_('Private key')}</h4>
16 <h4>${_('Private key')}</h4>
12 <pre>
17 <pre>
13 # Save the below content as
18 # Save the below content as
14 # Windows: /Users/{username}/.ssh/id_rsa_rhodecode_access_priv.key
19 # Windows: /Users/{username}/.ssh/id_rsa_rhodecode_access_priv.key
15 # macOS: /Users/{yourname}/.ssh/id_rsa_rhodecode_access_priv.key
20 # macOS: /Users/{yourname}/.ssh/id_rsa_rhodecode_access_priv.key
16 # Linux: /home/{username}/.ssh/id_rsa_rhodecode_access_priv.key
21 # Linux: /home/{username}/.ssh/id_rsa_rhodecode_access_priv.key
17
22
18 # Change permissions to 0600 to make it secure, and usable.
23 # Change permissions to 0600 to make it secure, and usable.
19 e.g chmod 0600 /home/{username}/.ssh/id_rsa_rhodecode_access_priv.key
24 e.g chmod 0600 /home/{username}/.ssh/id_rsa_rhodecode_access_priv.key
20 </pre>
25 </pre>
21
26
22 <div>
27 <div>
23 <textarea style="height: 300px">${c.private}</textarea>
28 <textarea style="height: 300px">${c.private}</textarea>
24 </div>
29 </div>
25 <br/>
30 <br/>
26
31
27 <h4>${_('Public key')}</h4>
32 <h4>${_('Public key')}</h4>
28 <pre>
33 <pre>
29 # Save the below content as
34 # Save the below content as
30 # Windows: /Users/{username}/.ssh/id_rsa_rhodecode_access_pub.key
35 # Windows: /Users/{username}/.ssh/id_rsa_rhodecode_access_pub.key
31 # macOS: /Users/{yourname}/.ssh/id_rsa_rhodecode_access_pub.key
36 # macOS: /Users/{yourname}/.ssh/id_rsa_rhodecode_access_pub.key
32 # Linux: /home/{username}/.ssh/id_rsa_rhodecode_access_pub.key
37 # Linux: /home/{username}/.ssh/id_rsa_rhodecode_access_pub.key
33 </pre>
38 </pre>
34
39
35 <input type="text" value="${c.public}" class="large text" size="100"/>
40 <input type="text" value="${c.public}" class="large text" size="100"/>
36 <p>
41 <p>
37 % if hasattr(c, 'target_form_url'):
42 % if hasattr(c, 'target_form_url'):
38 <a href="${c.target_form_url}">${_('Use this generated key')}.</a>
43 <a href="${c.target_form_url}">${_('Use this generated key')}.</a>
39 % else:
44 % else:
40 <a href="${h.route_path('edit_user_ssh_keys', user_id=c.user.user_id, _query=dict(default_key=c.public))}">${_('Use this generated key')}.</a>
45 <a href="${h.route_path('edit_user_ssh_keys', user_id=c.user.user_id, _query=dict(default_key=c.public))}">${_('Use this generated key')}.</a>
41 % endif
46 % endif
42 ${_('Confirmation required on the next screen')}.
47 ${_('Confirmation required on the next screen')}.
43 </p>
48 </p>
44 % else:
49 % else:
45 <h2>
50 <h2>
46 ${_('SSH key generator has been disabled.')}
51 ${_('SSH key generator has been disabled.')}
47 </h2>
52 </h2>
48 % endif
53 % endif
49 </div>
54 </div>
50 </div>
55 </div>
51
56
52 <script>
57 <script>
53
58
54 $(document).ready(function(){
59 $(document).ready(function(){
55
60
56
61
57 });
62 });
58 </script>
63 </script>
@@ -1,1136 +1,1136 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 <%!
3 <%!
4 ## base64 filter e.g ${ example | base64 }
4 ## base64 filter e.g ${ example | base64 }
5 def base64(text):
5 def base64(text):
6 import base64
6 import base64
7 from rhodecode.lib.helpers import safe_str
7 from rhodecode.lib.helpers import safe_str
8 return base64.encodestring(safe_str(text))
8 return base64.encodestring(safe_str(text))
9 %>
9 %>
10
10
11 <%inherit file="root.mako"/>
11 <%inherit file="root.mako"/>
12
12
13 <%include file="/ejs_templates/templates.html"/>
13 <%include file="/ejs_templates/templates.html"/>
14
14
15 <div class="outerwrapper">
15 <div class="outerwrapper">
16 <!-- HEADER -->
16 <!-- HEADER -->
17 <div class="header">
17 <div class="header">
18 <div id="header-inner" class="wrapper">
18 <div id="header-inner" class="wrapper">
19 <div id="logo">
19 <div id="logo">
20 <div class="logo-wrapper">
20 <div class="logo-wrapper">
21 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
21 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
22 </div>
22 </div>
23 % if c.rhodecode_name:
23 % if c.rhodecode_name:
24 <div class="branding">
24 <div class="branding">
25 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
25 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
26 </div>
26 </div>
27 % endif
27 % endif
28 </div>
28 </div>
29 <!-- MENU BAR NAV -->
29 <!-- MENU BAR NAV -->
30 ${self.menu_bar_nav()}
30 ${self.menu_bar_nav()}
31 <!-- END MENU BAR NAV -->
31 <!-- END MENU BAR NAV -->
32 </div>
32 </div>
33 </div>
33 </div>
34 ${self.menu_bar_subnav()}
34 ${self.menu_bar_subnav()}
35 <!-- END HEADER -->
35 <!-- END HEADER -->
36
36
37 <!-- CONTENT -->
37 <!-- CONTENT -->
38 <div id="content" class="wrapper">
38 <div id="content" class="wrapper">
39
39
40 <rhodecode-toast id="notifications"></rhodecode-toast>
40 <rhodecode-toast id="notifications"></rhodecode-toast>
41
41
42 <div class="main">
42 <div class="main">
43 ${next.main()}
43 ${next.main()}
44 </div>
44 </div>
45 </div>
45 </div>
46 <!-- END CONTENT -->
46 <!-- END CONTENT -->
47
47
48 </div>
48 </div>
49 <!-- FOOTER -->
49 <!-- FOOTER -->
50 <div id="footer">
50 <div id="footer">
51 <div id="footer-inner" class="title wrapper">
51 <div id="footer-inner" class="title wrapper">
52 <div>
52 <div>
53 <p class="footer-link-right">
53 <p class="footer-link-right">
54 % if c.visual.show_version:
54 % if c.visual.show_version:
55 RhodeCode Enterprise ${c.rhodecode_version} ${c.rhodecode_edition}
55 RhodeCode Enterprise ${c.rhodecode_version} ${c.rhodecode_edition}
56 % endif
56 % endif
57 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
57 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
58 % if c.visual.rhodecode_support_url:
58 % if c.visual.rhodecode_support_url:
59 <a href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a>
59 <a href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a>
60 % endif
60 % endif
61 </p>
61 </p>
62 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
62 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
63 <p class="server-instance" style="display:${sid}">
63 <p class="server-instance" style="display:${sid}">
64 ## display hidden instance ID if specially defined
64 ## display hidden instance ID if specially defined
65 % if c.rhodecode_instanceid:
65 % if c.rhodecode_instanceid:
66 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
66 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
67 % endif
67 % endif
68 </p>
68 </p>
69 </div>
69 </div>
70 </div>
70 </div>
71 </div>
71 </div>
72
72
73 <!-- END FOOTER -->
73 <!-- END FOOTER -->
74
74
75 ### MAKO DEFS ###
75 ### MAKO DEFS ###
76
76
77 <%def name="menu_bar_subnav()">
77 <%def name="menu_bar_subnav()">
78 </%def>
78 </%def>
79
79
80 <%def name="breadcrumbs(class_='breadcrumbs')">
80 <%def name="breadcrumbs(class_='breadcrumbs')">
81 <div class="${class_}">
81 <div class="${class_}">
82 ${self.breadcrumbs_links()}
82 ${self.breadcrumbs_links()}
83 </div>
83 </div>
84 </%def>
84 </%def>
85
85
86 <%def name="admin_menu(active=None)">
86 <%def name="admin_menu(active=None)">
87
87
88 <div id="context-bar">
88 <div id="context-bar">
89 <div class="wrapper">
89 <div class="wrapper">
90 <div class="title">
90 <div class="title">
91 <div class="title-content">
91 <div class="title-content">
92 <div class="title-main">
92 <div class="title-main">
93 % if c.is_super_admin:
93 % if c.is_super_admin:
94 ${_('Super-admin Panel')}
94 ${_('Super-admin Panel')}
95 % else:
95 % else:
96 ${_('Delegated Admin Panel')}
96 ${_('Delegated Admin Panel')}
97 % endif
97 % endif
98 </div>
98 </div>
99 </div>
99 </div>
100 </div>
100 </div>
101
101
102 <ul id="context-pages" class="navigation horizontal-list">
102 <ul id="context-pages" class="navigation horizontal-list">
103
103
104 ## super-admin case
104 ## super-admin case
105 % if c.is_super_admin:
105 % if c.is_super_admin:
106 <li class="${h.is_active('audit_logs', active)}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
106 <li class="${h.is_active('audit_logs', active)}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
107 <li class="${h.is_active('repositories', active)}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
107 <li class="${h.is_active('repositories', active)}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
108 <li class="${h.is_active('repository_groups', active)}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
108 <li class="${h.is_active('repository_groups', active)}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
109 <li class="${h.is_active('users', active)}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
109 <li class="${h.is_active('users', active)}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
110 <li class="${h.is_active('user_groups', active)}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
110 <li class="${h.is_active('user_groups', active)}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
111 <li class="${h.is_active('permissions', active)}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
111 <li class="${h.is_active('permissions', active)}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
112 <li class="${h.is_active('authentication', active)}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
112 <li class="${h.is_active('authentication', active)}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
113 <li class="${h.is_active('integrations', active)}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
113 <li class="${h.is_active('integrations', active)}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
114 <li class="${h.is_active('defaults', active)}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
114 <li class="${h.is_active('defaults', active)}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
115 <li class="${h.is_active('settings', active)}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
115 <li class="${h.is_active('settings', active)}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
116
116
117 ## delegated admin
117 ## delegated admin
118 % elif c.is_delegated_admin:
118 % elif c.is_delegated_admin:
119 <%
119 <%
120 repositories=c.auth_user.repositories_admin or c.can_create_repo
120 repositories=c.auth_user.repositories_admin or c.can_create_repo
121 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
121 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
122 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
122 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
123 %>
123 %>
124
124
125 %if repositories:
125 %if repositories:
126 <li class="${h.is_active('repositories', active)} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
126 <li class="${h.is_active('repositories', active)} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
127 %endif
127 %endif
128 %if repository_groups:
128 %if repository_groups:
129 <li class="${h.is_active('repository_groups', active)} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
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 %endif
130 %endif
131 %if user_groups:
131 %if user_groups:
132 <li class="${h.is_active('user_groups', active)} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
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 %endif
133 %endif
134 % endif
134 % endif
135 </ul>
135 </ul>
136
136
137 </div>
137 </div>
138 <div class="clear"></div>
138 <div class="clear"></div>
139 </div>
139 </div>
140 </%def>
140 </%def>
141
141
142 <%def name="dt_info_panel(elements)">
142 <%def name="dt_info_panel(elements)">
143 <dl class="dl-horizontal">
143 <dl class="dl-horizontal">
144 %for dt, dd, title, show_items in elements:
144 %for dt, dd, title, show_items in elements:
145 <dt>${dt}:</dt>
145 <dt>${dt}:</dt>
146 <dd title="${h.tooltip(title)}">
146 <dd title="${h.tooltip(title)}">
147 %if callable(dd):
147 %if callable(dd):
148 ## allow lazy evaluation of elements
148 ## allow lazy evaluation of elements
149 ${dd()}
149 ${dd()}
150 %else:
150 %else:
151 ${dd}
151 ${dd}
152 %endif
152 %endif
153 %if show_items:
153 %if show_items:
154 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
154 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
155 %endif
155 %endif
156 </dd>
156 </dd>
157
157
158 %if show_items:
158 %if show_items:
159 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
159 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
160 %for item in show_items:
160 %for item in show_items:
161 <dt></dt>
161 <dt></dt>
162 <dd>${item}</dd>
162 <dd>${item}</dd>
163 %endfor
163 %endfor
164 </div>
164 </div>
165 %endif
165 %endif
166
166
167 %endfor
167 %endfor
168 </dl>
168 </dl>
169 </%def>
169 </%def>
170
170
171 <%def name="tr_info_entry(element)">
171 <%def name="tr_info_entry(element)">
172 <% key, val, title, show_items = element %>
172 <% key, val, title, show_items = element %>
173
173
174 <tr>
174 <tr>
175 <td style="vertical-align: top">${key}</td>
175 <td style="vertical-align: top">${key}</td>
176 <td title="${h.tooltip(title)}">
176 <td title="${h.tooltip(title)}">
177 %if callable(val):
177 %if callable(val):
178 ## allow lazy evaluation of elements
178 ## allow lazy evaluation of elements
179 ${val()}
179 ${val()}
180 %else:
180 %else:
181 ${val}
181 ${val}
182 %endif
182 %endif
183 %if show_items:
183 %if show_items:
184 <div class="collapsable-content" data-toggle="item-${h.md5_safe(val)[:6]}-details" style="display: none">
184 <div class="collapsable-content" data-toggle="item-${h.md5_safe(val)[:6]}-details" style="display: none">
185 % for item in show_items:
185 % for item in show_items:
186 <dt></dt>
186 <dt></dt>
187 <dd>${item}</dd>
187 <dd>${item}</dd>
188 % endfor
188 % endfor
189 </div>
189 </div>
190 %endif
190 %endif
191 </td>
191 </td>
192 <td style="vertical-align: top">
192 <td style="vertical-align: top">
193 %if show_items:
193 %if show_items:
194 <span class="btn-collapse" data-toggle="item-${h.md5_safe(val)[:6]}-details">${_('Show More')} </span>
194 <span class="btn-collapse" data-toggle="item-${h.md5_safe(val)[:6]}-details">${_('Show More')} </span>
195 %endif
195 %endif
196 </td>
196 </td>
197 </tr>
197 </tr>
198
198
199 </%def>
199 </%def>
200
200
201 <%def name="gravatar(email, size=16, tooltip=False, tooltip_alt=None, user=None, extra_class=None)">
201 <%def name="gravatar(email, size=16, tooltip=False, tooltip_alt=None, user=None, extra_class=None)">
202 <%
202 <%
203 if size > 16:
203 if size > 16:
204 gravatar_class = ['gravatar','gravatar-large']
204 gravatar_class = ['gravatar','gravatar-large']
205 else:
205 else:
206 gravatar_class = ['gravatar']
206 gravatar_class = ['gravatar']
207
207
208 data_hovercard_url = ''
208 data_hovercard_url = ''
209 data_hovercard_alt = tooltip_alt.replace('<', '&lt;').replace('>', '&gt;') if tooltip_alt else ''
209 data_hovercard_alt = tooltip_alt.replace('<', '&lt;').replace('>', '&gt;') if tooltip_alt else ''
210
210
211 if tooltip:
211 if tooltip:
212 gravatar_class += ['tooltip-hovercard']
212 gravatar_class += ['tooltip-hovercard']
213 if extra_class:
213 if extra_class:
214 gravatar_class += extra_class
214 gravatar_class += extra_class
215 if tooltip and user:
215 if tooltip and user:
216 if user.username == h.DEFAULT_USER:
216 if user.username == h.DEFAULT_USER:
217 gravatar_class.pop(-1)
217 gravatar_class.pop(-1)
218 else:
218 else:
219 data_hovercard_url = request.route_path('hovercard_user', user_id=getattr(user, 'user_id', ''))
219 data_hovercard_url = request.route_path('hovercard_user', user_id=getattr(user, 'user_id', ''))
220 gravatar_class = ' '.join(gravatar_class)
220 gravatar_class = ' '.join(gravatar_class)
221
221
222 %>
222 %>
223 <%doc>
223 <%doc>
224 TODO: johbo: For now we serve double size images to make it smooth
224 TODO: johbo: For now we serve double size images to make it smooth
225 for retina. This is how it worked until now. Should be replaced
225 for retina. This is how it worked until now. Should be replaced
226 with a better solution at some point.
226 with a better solution at some point.
227 </%doc>
227 </%doc>
228
228
229 <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 <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)}" />
230 </%def>
230 </%def>
231
231
232
232
233 <%def name="gravatar_with_user(contact, size=16, show_disabled=False, tooltip=False)">
233 <%def name="gravatar_with_user(contact, size=16, show_disabled=False, tooltip=False, _class='rc-user')">
234 <%
234 <%
235 email = h.email_or_none(contact)
235 email = h.email_or_none(contact)
236 rc_user = h.discover_user(contact)
236 rc_user = h.discover_user(contact)
237 %>
237 %>
238
238
239 <div class="rc-user">
239 <div class="${_class}">
240 ${self.gravatar(email, size, tooltip=tooltip, tooltip_alt=contact, user=rc_user)}
240 ${self.gravatar(email, size, tooltip=tooltip, tooltip_alt=contact, user=rc_user)}
241 <span class="${('user user-disabled' if show_disabled else 'user')}"> ${h.link_to_user(rc_user or contact)}</span>
241 <span class="${('user user-disabled' if show_disabled else 'user')}"> ${h.link_to_user(rc_user or contact)}</span>
242 </div>
242 </div>
243 </%def>
243 </%def>
244
244
245
245
246 <%def name="user_group_icon(user_group=None, size=16, tooltip=False)">
246 <%def name="user_group_icon(user_group=None, size=16, tooltip=False)">
247 <%
247 <%
248 if (size > 16):
248 if (size > 16):
249 gravatar_class = 'icon-user-group-alt'
249 gravatar_class = 'icon-user-group-alt'
250 else:
250 else:
251 gravatar_class = 'icon-user-group-alt'
251 gravatar_class = 'icon-user-group-alt'
252
252
253 if tooltip:
253 if tooltip:
254 gravatar_class += ' tooltip-hovercard'
254 gravatar_class += ' tooltip-hovercard'
255
255
256 data_hovercard_url = request.route_path('hovercard_user_group', user_group_id=user_group.users_group_id)
256 data_hovercard_url = request.route_path('hovercard_user_group', user_group_id=user_group.users_group_id)
257 %>
257 %>
258 <%doc>
258 <%doc>
259 TODO: johbo: For now we serve double size images to make it smooth
259 TODO: johbo: For now we serve double size images to make it smooth
260 for retina. This is how it worked until now. Should be replaced
260 for retina. This is how it worked until now. Should be replaced
261 with a better solution at some point.
261 with a better solution at some point.
262 </%doc>
262 </%doc>
263
263
264 <i style="font-size: ${size}px" class="${gravatar_class} x-icon-size-${size}" data-hovercard-url="${data_hovercard_url}"></i>
264 <i style="font-size: ${size}px" class="${gravatar_class} x-icon-size-${size}" data-hovercard-url="${data_hovercard_url}"></i>
265 </%def>
265 </%def>
266
266
267 <%def name="repo_page_title(repo_instance)">
267 <%def name="repo_page_title(repo_instance)">
268 <div class="title-content repo-title">
268 <div class="title-content repo-title">
269
269
270 <div class="title-main">
270 <div class="title-main">
271 ## SVN/HG/GIT icons
271 ## SVN/HG/GIT icons
272 %if h.is_hg(repo_instance):
272 %if h.is_hg(repo_instance):
273 <i class="icon-hg"></i>
273 <i class="icon-hg"></i>
274 %endif
274 %endif
275 %if h.is_git(repo_instance):
275 %if h.is_git(repo_instance):
276 <i class="icon-git"></i>
276 <i class="icon-git"></i>
277 %endif
277 %endif
278 %if h.is_svn(repo_instance):
278 %if h.is_svn(repo_instance):
279 <i class="icon-svn"></i>
279 <i class="icon-svn"></i>
280 %endif
280 %endif
281
281
282 ## public/private
282 ## public/private
283 %if repo_instance.private:
283 %if repo_instance.private:
284 <i class="icon-repo-private"></i>
284 <i class="icon-repo-private"></i>
285 %else:
285 %else:
286 <i class="icon-repo-public"></i>
286 <i class="icon-repo-public"></i>
287 %endif
287 %endif
288
288
289 ## repo name with group name
289 ## repo name with group name
290 ${h.breadcrumb_repo_link(repo_instance)}
290 ${h.breadcrumb_repo_link(repo_instance)}
291
291
292 ## Context Actions
292 ## Context Actions
293 <div class="pull-right">
293 <div class="pull-right">
294 %if c.rhodecode_user.username != h.DEFAULT_USER:
294 %if c.rhodecode_user.username != h.DEFAULT_USER:
295 <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 <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>
296
296
297 <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 <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 '')}">
298 % if c.repository_is_user_following:
298 % if c.repository_is_user_following:
299 <i class="icon-eye-off"></i>${_('Unwatch')}
299 <i class="icon-eye-off"></i>${_('Unwatch')}
300 % else:
300 % else:
301 <i class="icon-eye"></i>${_('Watch')}
301 <i class="icon-eye"></i>${_('Watch')}
302 % endif
302 % endif
303
303
304 </a>
304 </a>
305 %else:
305 %else:
306 <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 <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>
307 %endif
307 %endif
308 </div>
308 </div>
309
309
310 </div>
310 </div>
311
311
312 ## FORKED
312 ## FORKED
313 %if repo_instance.fork:
313 %if repo_instance.fork:
314 <p class="discreet">
314 <p class="discreet">
315 <i class="icon-code-fork"></i> ${_('Fork of')}
315 <i class="icon-code-fork"></i> ${_('Fork of')}
316 ${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 ${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))}
317 </p>
317 </p>
318 %endif
318 %endif
319
319
320 ## IMPORTED FROM REMOTE
320 ## IMPORTED FROM REMOTE
321 %if repo_instance.clone_uri:
321 %if repo_instance.clone_uri:
322 <p class="discreet">
322 <p class="discreet">
323 <i class="icon-code-fork"></i> ${_('Clone from')}
323 <i class="icon-code-fork"></i> ${_('Clone from')}
324 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
324 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
325 </p>
325 </p>
326 %endif
326 %endif
327
327
328 ## LOCKING STATUS
328 ## LOCKING STATUS
329 %if repo_instance.locked[0]:
329 %if repo_instance.locked[0]:
330 <p class="locking_locked discreet">
330 <p class="locking_locked discreet">
331 <i class="icon-repo-lock"></i>
331 <i class="icon-repo-lock"></i>
332 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
332 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
333 </p>
333 </p>
334 %elif repo_instance.enable_locking:
334 %elif repo_instance.enable_locking:
335 <p class="locking_unlocked discreet">
335 <p class="locking_unlocked discreet">
336 <i class="icon-repo-unlock"></i>
336 <i class="icon-repo-unlock"></i>
337 ${_('Repository not locked. Pull repository to lock it.')}
337 ${_('Repository not locked. Pull repository to lock it.')}
338 </p>
338 </p>
339 %endif
339 %endif
340
340
341 </div>
341 </div>
342 </%def>
342 </%def>
343
343
344 <%def name="repo_menu(active=None)">
344 <%def name="repo_menu(active=None)">
345 <%
345 <%
346 ## determine if we have "any" option available
346 ## determine if we have "any" option available
347 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
347 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
348 has_actions = can_lock
348 has_actions = can_lock
349
349
350 %>
350 %>
351 % if c.rhodecode_db_repo.archived:
351 % if c.rhodecode_db_repo.archived:
352 <div class="alert alert-warning text-center">
352 <div class="alert alert-warning text-center">
353 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
353 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
354 </div>
354 </div>
355 % endif
355 % endif
356
356
357 <!--- REPO CONTEXT BAR -->
357 <!--- REPO CONTEXT BAR -->
358 <div id="context-bar">
358 <div id="context-bar">
359 <div class="wrapper">
359 <div class="wrapper">
360
360
361 <div class="title">
361 <div class="title">
362 ${self.repo_page_title(c.rhodecode_db_repo)}
362 ${self.repo_page_title(c.rhodecode_db_repo)}
363 </div>
363 </div>
364
364
365 <ul id="context-pages" class="navigation horizontal-list">
365 <ul id="context-pages" class="navigation horizontal-list">
366 <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 <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>
367 <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 <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>
368 <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 <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>
369 <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 <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>
370
370
371 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
371 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
372 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
372 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
373 <li class="${h.is_active('showpullrequest', active)}">
373 <li class="${h.is_active('showpullrequest', active)}">
374 <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 <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)}">
375 <div class="menulabel">
375 <div class="menulabel">
376 ${_('Pull Requests')} <span class="menulink-counter">${c.repository_pull_requests}</span>
376 ${_('Pull Requests')} <span class="menulink-counter">${c.repository_pull_requests}</span>
377 </div>
377 </div>
378 </a>
378 </a>
379 </li>
379 </li>
380 %endif
380 %endif
381
381
382 <li class="${h.is_active('artifacts', active)}">
382 <li class="${h.is_active('artifacts', active)}">
383 <a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}">
383 <a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}">
384 <div class="menulabel">
384 <div class="menulabel">
385 ${_('Artifacts')} <span class="menulink-counter">${c.repository_artifacts}</span>
385 ${_('Artifacts')} <span class="menulink-counter">${c.repository_artifacts}</span>
386 </div>
386 </div>
387 </a>
387 </a>
388 </li>
388 </li>
389
389
390 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
390 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
391 <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 <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>
392 %endif
392 %endif
393
393
394 <li class="${h.is_active('options', active)}">
394 <li class="${h.is_active('options', active)}">
395 % if has_actions:
395 % if has_actions:
396 <a class="menulink dropdown">
396 <a class="menulink dropdown">
397 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
397 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
398 </a>
398 </a>
399 <ul class="submenu">
399 <ul class="submenu">
400 %if can_lock:
400 %if can_lock:
401 %if c.rhodecode_db_repo.locked[0]:
401 %if c.rhodecode_db_repo.locked[0]:
402 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock Repository')}</a></li>
402 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock Repository')}</a></li>
403 %else:
403 %else:
404 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock Repository')}</a></li>
404 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock Repository')}</a></li>
405 %endif
405 %endif
406 %endif
406 %endif
407 </ul>
407 </ul>
408 % endif
408 % endif
409 </li>
409 </li>
410
410
411 </ul>
411 </ul>
412 </div>
412 </div>
413 <div class="clear"></div>
413 <div class="clear"></div>
414 </div>
414 </div>
415
415
416 <!--- REPO END CONTEXT BAR -->
416 <!--- REPO END CONTEXT BAR -->
417
417
418 </%def>
418 </%def>
419
419
420 <%def name="repo_group_page_title(repo_group_instance)">
420 <%def name="repo_group_page_title(repo_group_instance)">
421 <div class="title-content">
421 <div class="title-content">
422 <div class="title-main">
422 <div class="title-main">
423 ## Repository Group icon
423 ## Repository Group icon
424 <i class="icon-repo-group"></i>
424 <i class="icon-repo-group"></i>
425
425
426 ## repo name with group name
426 ## repo name with group name
427 ${h.breadcrumb_repo_group_link(repo_group_instance)}
427 ${h.breadcrumb_repo_group_link(repo_group_instance)}
428 </div>
428 </div>
429
429
430 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
430 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
431 <div class="repo-group-desc discreet">
431 <div class="repo-group-desc discreet">
432 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
432 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
433 </div>
433 </div>
434
434
435 </div>
435 </div>
436 </%def>
436 </%def>
437
437
438
438
439 <%def name="repo_group_menu(active=None)">
439 <%def name="repo_group_menu(active=None)">
440 <%
440 <%
441 gr_name = c.repo_group.group_name if c.repo_group else None
441 gr_name = c.repo_group.group_name if c.repo_group else None
442 # create repositories with write permission on group is set to true
442 # create repositories with write permission on group is set to true
443 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
443 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
444
444
445 %>
445 %>
446
446
447
447
448 <!--- REPO GROUP CONTEXT BAR -->
448 <!--- REPO GROUP CONTEXT BAR -->
449 <div id="context-bar">
449 <div id="context-bar">
450 <div class="wrapper">
450 <div class="wrapper">
451 <div class="title">
451 <div class="title">
452 ${self.repo_group_page_title(c.repo_group)}
452 ${self.repo_group_page_title(c.repo_group)}
453 </div>
453 </div>
454
454
455 <ul id="context-pages" class="navigation horizontal-list">
455 <ul id="context-pages" class="navigation horizontal-list">
456 <li class="${h.is_active('home', active)}">
456 <li class="${h.is_active('home', active)}">
457 <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>
457 <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>
458 </li>
458 </li>
459 % if c.is_super_admin or group_admin:
459 % if c.is_super_admin or group_admin:
460 <li class="${h.is_active('settings', active)}">
460 <li class="${h.is_active('settings', active)}">
461 <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>
461 <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>
462 </li>
462 </li>
463 % endif
463 % endif
464
464
465 </ul>
465 </ul>
466 </div>
466 </div>
467 <div class="clear"></div>
467 <div class="clear"></div>
468 </div>
468 </div>
469
469
470 <!--- REPO GROUP CONTEXT BAR -->
470 <!--- REPO GROUP CONTEXT BAR -->
471
471
472 </%def>
472 </%def>
473
473
474
474
475 <%def name="usermenu(active=False)">
475 <%def name="usermenu(active=False)">
476 <%
476 <%
477 not_anonymous = c.rhodecode_user.username != h.DEFAULT_USER
477 not_anonymous = c.rhodecode_user.username != h.DEFAULT_USER
478
478
479 gr_name = c.repo_group.group_name if (hasattr(c, 'repo_group') and c.repo_group) else None
479 gr_name = c.repo_group.group_name if (hasattr(c, 'repo_group') and c.repo_group) else None
480 # create repositories with write permission on group is set to true
480 # create repositories with write permission on group is set to true
481
481
482 can_fork = c.is_super_admin or h.HasPermissionAny('hg.fork.repository')()
482 can_fork = c.is_super_admin or h.HasPermissionAny('hg.fork.repository')()
483 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
483 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
484 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
484 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
485 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
485 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
486
486
487 can_create_repos = c.is_super_admin or c.can_create_repo
487 can_create_repos = c.is_super_admin or c.can_create_repo
488 can_create_repo_groups = c.is_super_admin or c.can_create_repo_group
488 can_create_repo_groups = c.is_super_admin or c.can_create_repo_group
489
489
490 can_create_repos_in_group = c.is_super_admin or group_admin or (group_write and create_on_write)
490 can_create_repos_in_group = c.is_super_admin or group_admin or (group_write and create_on_write)
491 can_create_repo_groups_in_group = c.is_super_admin or group_admin
491 can_create_repo_groups_in_group = c.is_super_admin or group_admin
492 %>
492 %>
493
493
494 % if not_anonymous:
494 % if not_anonymous:
495 <%
495 <%
496 default_target_group = dict()
496 default_target_group = dict()
497 if c.rhodecode_user.personal_repo_group:
497 if c.rhodecode_user.personal_repo_group:
498 default_target_group = dict(parent_group=c.rhodecode_user.personal_repo_group.group_id)
498 default_target_group = dict(parent_group=c.rhodecode_user.personal_repo_group.group_id)
499 %>
499 %>
500
500
501 ## create action
501 ## create action
502 <li>
502 <li>
503 <a href="#create-actions" onclick="return false;" class="menulink childs">
503 <a href="#create-actions" onclick="return false;" class="menulink childs">
504 <i class="tooltip icon-plus-circled" title="${_('Create')}"></i>
504 <i class="tooltip icon-plus-circled" title="${_('Create')}"></i>
505 </a>
505 </a>
506
506
507 <div class="action-menu submenu">
507 <div class="action-menu submenu">
508
508
509 <ol>
509 <ol>
510 ## scope of within a repository
510 ## scope of within a repository
511 % if hasattr(c, 'rhodecode_db_repo') and c.rhodecode_db_repo:
511 % if hasattr(c, 'rhodecode_db_repo') and c.rhodecode_db_repo:
512 <li class="submenu-title">${_('This Repository')}</li>
512 <li class="submenu-title">${_('This Repository')}</li>
513 <li>
513 <li>
514 <a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a>
514 <a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a>
515 </li>
515 </li>
516 % if can_fork:
516 % if can_fork:
517 <li>
517 <li>
518 <a href="${h.route_path('repo_fork_new',repo_name=c.repo_name,_query=default_target_group)}">${_('Fork this repository')}</a>
518 <a href="${h.route_path('repo_fork_new',repo_name=c.repo_name,_query=default_target_group)}">${_('Fork this repository')}</a>
519 </li>
519 </li>
520 % endif
520 % endif
521 % endif
521 % endif
522
522
523 ## scope of within repository groups
523 ## scope of within repository groups
524 % if hasattr(c, 'repo_group') and c.repo_group and (can_create_repos_in_group or can_create_repo_groups_in_group):
524 % if hasattr(c, 'repo_group') and c.repo_group and (can_create_repos_in_group or can_create_repo_groups_in_group):
525 <li class="submenu-title">${_('This Repository Group')}</li>
525 <li class="submenu-title">${_('This Repository Group')}</li>
526
526
527 % if can_create_repos_in_group:
527 % if can_create_repos_in_group:
528 <li>
528 <li>
529 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('New Repository')}</a>
529 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('New Repository')}</a>
530 </li>
530 </li>
531 % endif
531 % endif
532
532
533 % if can_create_repo_groups_in_group:
533 % if can_create_repo_groups_in_group:
534 <li>
534 <li>
535 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'New Repository Group')}</a>
535 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'New Repository Group')}</a>
536 </li>
536 </li>
537 % endif
537 % endif
538 % endif
538 % endif
539
539
540 ## personal group
540 ## personal group
541 % if c.rhodecode_user.personal_repo_group:
541 % if c.rhodecode_user.personal_repo_group:
542 <li class="submenu-title">Personal Group</li>
542 <li class="submenu-title">Personal Group</li>
543
543
544 <li>
544 <li>
545 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}" >${_('New Repository')} </a>
545 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}" >${_('New Repository')} </a>
546 </li>
546 </li>
547
547
548 <li>
548 <li>
549 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}">${_('New Repository Group')} </a>
549 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}">${_('New Repository Group')} </a>
550 </li>
550 </li>
551 % endif
551 % endif
552
552
553 ## Global actions
553 ## Global actions
554 <li class="submenu-title">RhodeCode</li>
554 <li class="submenu-title">RhodeCode</li>
555 % if can_create_repos:
555 % if can_create_repos:
556 <li>
556 <li>
557 <a href="${h.route_path('repo_new')}" >${_('New Repository')}</a>
557 <a href="${h.route_path('repo_new')}" >${_('New Repository')}</a>
558 </li>
558 </li>
559 % endif
559 % endif
560
560
561 % if can_create_repo_groups:
561 % if can_create_repo_groups:
562 <li>
562 <li>
563 <a href="${h.route_path('repo_group_new')}" >${_(u'New Repository Group')}</a>
563 <a href="${h.route_path('repo_group_new')}" >${_(u'New Repository Group')}</a>
564 </li>
564 </li>
565 % endif
565 % endif
566
566
567 <li>
567 <li>
568 <a href="${h.route_path('gists_new')}">${_(u'New Gist')}</a>
568 <a href="${h.route_path('gists_new')}">${_(u'New Gist')}</a>
569 </li>
569 </li>
570
570
571 </ol>
571 </ol>
572
572
573 </div>
573 </div>
574 </li>
574 </li>
575
575
576 ## notifications
576 ## notifications
577 <li>
577 <li>
578 <a class="${('empty' if c.unread_notifications == 0 else '')}" href="${h.route_path('notifications_show_all')}">
578 <a class="${('empty' if c.unread_notifications == 0 else '')}" href="${h.route_path('notifications_show_all')}">
579 ${c.unread_notifications}
579 ${c.unread_notifications}
580 </a>
580 </a>
581 </li>
581 </li>
582 % endif
582 % endif
583
583
584 ## USER MENU
584 ## USER MENU
585 <li id="quick_login_li" class="${'active' if active else ''}">
585 <li id="quick_login_li" class="${'active' if active else ''}">
586 % if c.rhodecode_user.username == h.DEFAULT_USER:
586 % if c.rhodecode_user.username == h.DEFAULT_USER:
587 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
587 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
588 ${gravatar(c.rhodecode_user.email, 20)}
588 ${gravatar(c.rhodecode_user.email, 20)}
589 <span class="user">
589 <span class="user">
590 <span>${_('Sign in')}</span>
590 <span>${_('Sign in')}</span>
591 </span>
591 </span>
592 </a>
592 </a>
593 % else:
593 % else:
594 ## logged in user
594 ## logged in user
595 <a id="quick_login_link" class="menulink childs">
595 <a id="quick_login_link" class="menulink childs">
596 ${gravatar(c.rhodecode_user.email, 20)}
596 ${gravatar(c.rhodecode_user.email, 20)}
597 <span class="user">
597 <span class="user">
598 <span class="menu_link_user">${c.rhodecode_user.username}</span>
598 <span class="menu_link_user">${c.rhodecode_user.username}</span>
599 <div class="show_more"></div>
599 <div class="show_more"></div>
600 </span>
600 </span>
601 </a>
601 </a>
602 ## subnav with menu for logged in user
602 ## subnav with menu for logged in user
603 <div class="user-menu submenu">
603 <div class="user-menu submenu">
604 <div id="quick_login">
604 <div id="quick_login">
605 %if c.rhodecode_user.username != h.DEFAULT_USER:
605 %if c.rhodecode_user.username != h.DEFAULT_USER:
606 <div class="">
606 <div class="">
607 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
607 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
608 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
608 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
609 <div class="email">${c.rhodecode_user.email}</div>
609 <div class="email">${c.rhodecode_user.email}</div>
610 </div>
610 </div>
611 <div class="">
611 <div class="">
612 <ol class="links">
612 <ol class="links">
613 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
613 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
614 % if c.rhodecode_user.personal_repo_group:
614 % if c.rhodecode_user.personal_repo_group:
615 <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>
615 <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>
616 % endif
616 % endif
617 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
617 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
618
618
619 % if c.debug_style:
619 % if c.debug_style:
620 <li>
620 <li>
621 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
621 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
622 <div class="menulabel">${_('[Style]')}</div>
622 <div class="menulabel">${_('[Style]')}</div>
623 </a>
623 </a>
624 </li>
624 </li>
625 % endif
625 % endif
626
626
627 ## bookmark-items
627 ## bookmark-items
628 <li class="bookmark-items">
628 <li class="bookmark-items">
629 ${_('Bookmarks')}
629 ${_('Bookmarks')}
630 <div class="pull-right">
630 <div class="pull-right">
631 <a href="${h.route_path('my_account_bookmarks')}">
631 <a href="${h.route_path('my_account_bookmarks')}">
632
632
633 <i class="icon-cog"></i>
633 <i class="icon-cog"></i>
634 </a>
634 </a>
635 </div>
635 </div>
636 </li>
636 </li>
637 % if not c.bookmark_items:
637 % if not c.bookmark_items:
638 <li>
638 <li>
639 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
639 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
640 </li>
640 </li>
641 % endif
641 % endif
642 % for item in c.bookmark_items:
642 % for item in c.bookmark_items:
643 <li>
643 <li>
644 % if item.repository:
644 % if item.repository:
645 <div>
645 <div>
646 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
646 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
647 <code>${item.position}</code>
647 <code>${item.position}</code>
648 % if item.repository.repo_type == 'hg':
648 % if item.repository.repo_type == 'hg':
649 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
649 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
650 % elif item.repository.repo_type == 'git':
650 % elif item.repository.repo_type == 'git':
651 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
651 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
652 % elif item.repository.repo_type == 'svn':
652 % elif item.repository.repo_type == 'svn':
653 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
653 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
654 % endif
654 % endif
655 ${(item.title or h.shorter(item.repository.repo_name, 30))}
655 ${(item.title or h.shorter(item.repository.repo_name, 30))}
656 </a>
656 </a>
657 </div>
657 </div>
658 % elif item.repository_group:
658 % elif item.repository_group:
659 <div>
659 <div>
660 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
660 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
661 <code>${item.position}</code>
661 <code>${item.position}</code>
662 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
662 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
663 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
663 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
664 </a>
664 </a>
665 </div>
665 </div>
666 % else:
666 % else:
667 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
667 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
668 <code>${item.position}</code>
668 <code>${item.position}</code>
669 ${item.title}
669 ${item.title}
670 </a>
670 </a>
671 % endif
671 % endif
672 </li>
672 </li>
673 % endfor
673 % endfor
674
674
675 <li class="logout">
675 <li class="logout">
676 ${h.secure_form(h.route_path('logout'), request=request)}
676 ${h.secure_form(h.route_path('logout'), request=request)}
677 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
677 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
678 ${h.end_form()}
678 ${h.end_form()}
679 </li>
679 </li>
680 </ol>
680 </ol>
681 </div>
681 </div>
682 %endif
682 %endif
683 </div>
683 </div>
684 </div>
684 </div>
685
685
686 % endif
686 % endif
687 </li>
687 </li>
688 </%def>
688 </%def>
689
689
690 <%def name="menu_items(active=None)">
690 <%def name="menu_items(active=None)">
691
691
692 <ul id="quick" class="main_nav navigation horizontal-list">
692 <ul id="quick" class="main_nav navigation horizontal-list">
693 ## notice box for important system messages
693 ## notice box for important system messages
694 <li style="display: none">
694 <li style="display: none">
695 <a class="notice-box" href="#openNotice" onclick="return false">
695 <a class="notice-box" href="#openNotice" onclick="return false">
696 <div class="menulabel-notice" >
696 <div class="menulabel-notice" >
697 0
697 0
698 </div>
698 </div>
699 </a>
699 </a>
700 </li>
700 </li>
701
701
702 ## Main filter
702 ## Main filter
703 <li>
703 <li>
704 <div class="menulabel main_filter_box">
704 <div class="menulabel main_filter_box">
705 <div class="main_filter_input_box">
705 <div class="main_filter_input_box">
706 <ul class="searchItems">
706 <ul class="searchItems">
707
707
708 <li class="searchTag searchTagIcon">
708 <li class="searchTag searchTagIcon">
709 <i class="icon-search"></i>
709 <i class="icon-search"></i>
710 </li>
710 </li>
711
711
712 % if c.template_context['search_context']['repo_id']:
712 % if c.template_context['search_context']['repo_id']:
713 <li class="searchTag searchTagFilter searchTagHidable" >
713 <li class="searchTag searchTagFilter searchTagHidable" >
714 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
714 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
715 <span class="tag">
715 <span class="tag">
716 This repo
716 This repo
717 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
717 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
718 </span>
718 </span>
719 ##</a>
719 ##</a>
720 </li>
720 </li>
721 % elif c.template_context['search_context']['repo_group_id']:
721 % elif c.template_context['search_context']['repo_group_id']:
722 <li class="searchTag searchTagFilter searchTagHidable">
722 <li class="searchTag searchTagFilter searchTagHidable">
723 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
723 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
724 <span class="tag">
724 <span class="tag">
725 This group
725 This group
726 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
726 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
727 </span>
727 </span>
728 ##</a>
728 ##</a>
729 </li>
729 </li>
730 % endif
730 % endif
731
731
732 <li class="searchTagInput">
732 <li class="searchTagInput">
733 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
733 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
734 </li>
734 </li>
735 <li class="searchTag searchTagHelp">
735 <li class="searchTag searchTagHelp">
736 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
736 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
737 </li>
737 </li>
738 </ul>
738 </ul>
739 </div>
739 </div>
740 </div>
740 </div>
741
741
742 <div id="main_filter_help" style="display: none">
742 <div id="main_filter_help" style="display: none">
743 - Use '/' key to quickly access this field.
743 - Use '/' key to quickly access this field.
744
744
745 - Enter a name of repository, or repository group for quick search.
745 - Enter a name of repository, or repository group for quick search.
746
746
747 - Prefix query to allow special search:
747 - Prefix query to allow special search:
748
748
749 user:admin, to search for usernames, always global
749 user:admin, to search for usernames, always global
750
750
751 user_group:devops, to search for user groups, always global
751 user_group:devops, to search for user groups, always global
752
752
753 commit:efced4, to search for commits, scoped to repositories or groups
753 commit:efced4, to search for commits, scoped to repositories or groups
754
754
755 file:models.py, to search for file paths, scoped to repositories or groups
755 file:models.py, to search for file paths, scoped to repositories or groups
756
756
757 % if c.template_context['search_context']['repo_id']:
757 % if c.template_context['search_context']['repo_id']:
758 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 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>
759 % elif c.template_context['search_context']['repo_group_id']:
759 % elif c.template_context['search_context']['repo_group_id']:
760 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 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>
761 % else:
761 % else:
762 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
762 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
763 % endif
763 % endif
764 </div>
764 </div>
765 </li>
765 </li>
766
766
767 ## ROOT MENU
767 ## ROOT MENU
768 <li class="${h.is_active('home', active)}">
768 <li class="${h.is_active('home', active)}">
769 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
769 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
770 <div class="menulabel">${_('Home')}</div>
770 <div class="menulabel">${_('Home')}</div>
771 </a>
771 </a>
772 </li>
772 </li>
773
773
774 %if c.rhodecode_user.username != h.DEFAULT_USER:
774 %if c.rhodecode_user.username != h.DEFAULT_USER:
775 <li class="${h.is_active('journal', active)}">
775 <li class="${h.is_active('journal', active)}">
776 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
776 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
777 <div class="menulabel">${_('Journal')}</div>
777 <div class="menulabel">${_('Journal')}</div>
778 </a>
778 </a>
779 </li>
779 </li>
780 %else:
780 %else:
781 <li class="${h.is_active('journal', active)}">
781 <li class="${h.is_active('journal', active)}">
782 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
782 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
783 <div class="menulabel">${_('Public journal')}</div>
783 <div class="menulabel">${_('Public journal')}</div>
784 </a>
784 </a>
785 </li>
785 </li>
786 %endif
786 %endif
787
787
788 <li class="${h.is_active('gists', active)}">
788 <li class="${h.is_active('gists', active)}">
789 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
789 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
790 <div class="menulabel">${_('Gists')}</div>
790 <div class="menulabel">${_('Gists')}</div>
791 </a>
791 </a>
792 </li>
792 </li>
793
793
794 % if c.is_super_admin or c.is_delegated_admin:
794 % if c.is_super_admin or c.is_delegated_admin:
795 <li class="${h.is_active('admin', active)}">
795 <li class="${h.is_active('admin', active)}">
796 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
796 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
797 <div class="menulabel">${_('Admin')} </div>
797 <div class="menulabel">${_('Admin')} </div>
798 </a>
798 </a>
799 </li>
799 </li>
800 % endif
800 % endif
801
801
802 ## render extra user menu
802 ## render extra user menu
803 ${usermenu(active=(active=='my_account'))}
803 ${usermenu(active=(active=='my_account'))}
804
804
805 </ul>
805 </ul>
806
806
807 <script type="text/javascript">
807 <script type="text/javascript">
808 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
808 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
809
809
810 var formatRepoResult = function(result, container, query, escapeMarkup) {
810 var formatRepoResult = function(result, container, query, escapeMarkup) {
811 return function(data, escapeMarkup) {
811 return function(data, escapeMarkup) {
812 if (!data.repo_id){
812 if (!data.repo_id){
813 return data.text; // optgroup text Repositories
813 return data.text; // optgroup text Repositories
814 }
814 }
815
815
816 var tmpl = '';
816 var tmpl = '';
817 var repoType = data['repo_type'];
817 var repoType = data['repo_type'];
818 var repoName = data['text'];
818 var repoName = data['text'];
819
819
820 if(data && data.type == 'repo'){
820 if(data && data.type == 'repo'){
821 if(repoType === 'hg'){
821 if(repoType === 'hg'){
822 tmpl += '<i class="icon-hg"></i> ';
822 tmpl += '<i class="icon-hg"></i> ';
823 }
823 }
824 else if(repoType === 'git'){
824 else if(repoType === 'git'){
825 tmpl += '<i class="icon-git"></i> ';
825 tmpl += '<i class="icon-git"></i> ';
826 }
826 }
827 else if(repoType === 'svn'){
827 else if(repoType === 'svn'){
828 tmpl += '<i class="icon-svn"></i> ';
828 tmpl += '<i class="icon-svn"></i> ';
829 }
829 }
830 if(data['private']){
830 if(data['private']){
831 tmpl += '<i class="icon-lock" ></i> ';
831 tmpl += '<i class="icon-lock" ></i> ';
832 }
832 }
833 else if(visualShowPublicIcon){
833 else if(visualShowPublicIcon){
834 tmpl += '<i class="icon-unlock-alt"></i> ';
834 tmpl += '<i class="icon-unlock-alt"></i> ';
835 }
835 }
836 }
836 }
837 tmpl += escapeMarkup(repoName);
837 tmpl += escapeMarkup(repoName);
838 return tmpl;
838 return tmpl;
839
839
840 }(result, escapeMarkup);
840 }(result, escapeMarkup);
841 };
841 };
842
842
843 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
843 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
844 return function(data, escapeMarkup) {
844 return function(data, escapeMarkup) {
845 if (!data.repo_group_id){
845 if (!data.repo_group_id){
846 return data.text; // optgroup text Repositories
846 return data.text; // optgroup text Repositories
847 }
847 }
848
848
849 var tmpl = '';
849 var tmpl = '';
850 var repoGroupName = data['text'];
850 var repoGroupName = data['text'];
851
851
852 if(data){
852 if(data){
853
853
854 tmpl += '<i class="icon-repo-group"></i> ';
854 tmpl += '<i class="icon-repo-group"></i> ';
855
855
856 }
856 }
857 tmpl += escapeMarkup(repoGroupName);
857 tmpl += escapeMarkup(repoGroupName);
858 return tmpl;
858 return tmpl;
859
859
860 }(result, escapeMarkup);
860 }(result, escapeMarkup);
861 };
861 };
862
862
863 var escapeRegExChars = function (value) {
863 var escapeRegExChars = function (value) {
864 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
864 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
865 };
865 };
866
866
867 var getRepoIcon = function(repo_type) {
867 var getRepoIcon = function(repo_type) {
868 if (repo_type === 'hg') {
868 if (repo_type === 'hg') {
869 return '<i class="icon-hg"></i> ';
869 return '<i class="icon-hg"></i> ';
870 }
870 }
871 else if (repo_type === 'git') {
871 else if (repo_type === 'git') {
872 return '<i class="icon-git"></i> ';
872 return '<i class="icon-git"></i> ';
873 }
873 }
874 else if (repo_type === 'svn') {
874 else if (repo_type === 'svn') {
875 return '<i class="icon-svn"></i> ';
875 return '<i class="icon-svn"></i> ';
876 }
876 }
877 return ''
877 return ''
878 };
878 };
879
879
880 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
880 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
881
881
882 if (value.split(':').length === 2) {
882 if (value.split(':').length === 2) {
883 value = value.split(':')[1]
883 value = value.split(':')[1]
884 }
884 }
885
885
886 var searchType = data['type'];
886 var searchType = data['type'];
887 var searchSubType = data['subtype'];
887 var searchSubType = data['subtype'];
888 var valueDisplay = data['value_display'];
888 var valueDisplay = data['value_display'];
889 var valueIcon = data['value_icon'];
889 var valueIcon = data['value_icon'];
890
890
891 var pattern = '(' + escapeRegExChars(value) + ')';
891 var pattern = '(' + escapeRegExChars(value) + ')';
892
892
893 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
893 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
894
894
895 // highlight match
895 // highlight match
896 if (searchType != 'text') {
896 if (searchType != 'text') {
897 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
897 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
898 }
898 }
899
899
900 var icon = '';
900 var icon = '';
901
901
902 if (searchType === 'hint') {
902 if (searchType === 'hint') {
903 icon += '<i class="icon-repo-group"></i> ';
903 icon += '<i class="icon-repo-group"></i> ';
904 }
904 }
905 // full text search/hints
905 // full text search/hints
906 else if (searchType === 'search') {
906 else if (searchType === 'search') {
907 if (valueIcon === undefined) {
907 if (valueIcon === undefined) {
908 icon += '<i class="icon-more"></i> ';
908 icon += '<i class="icon-more"></i> ';
909 } else {
909 } else {
910 icon += valueIcon + ' ';
910 icon += valueIcon + ' ';
911 }
911 }
912
912
913 if (searchSubType !== undefined && searchSubType == 'repo') {
913 if (searchSubType !== undefined && searchSubType == 'repo') {
914 valueDisplay += '<div class="pull-right tag">repository</div>';
914 valueDisplay += '<div class="pull-right tag">repository</div>';
915 }
915 }
916 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
916 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
917 valueDisplay += '<div class="pull-right tag">repo group</div>';
917 valueDisplay += '<div class="pull-right tag">repo group</div>';
918 }
918 }
919 }
919 }
920 // repository
920 // repository
921 else if (searchType === 'repo') {
921 else if (searchType === 'repo') {
922
922
923 var repoIcon = getRepoIcon(data['repo_type']);
923 var repoIcon = getRepoIcon(data['repo_type']);
924 icon += repoIcon;
924 icon += repoIcon;
925
925
926 if (data['private']) {
926 if (data['private']) {
927 icon += '<i class="icon-lock" ></i> ';
927 icon += '<i class="icon-lock" ></i> ';
928 }
928 }
929 else if (visualShowPublicIcon) {
929 else if (visualShowPublicIcon) {
930 icon += '<i class="icon-unlock-alt"></i> ';
930 icon += '<i class="icon-unlock-alt"></i> ';
931 }
931 }
932 }
932 }
933 // repository groups
933 // repository groups
934 else if (searchType === 'repo_group') {
934 else if (searchType === 'repo_group') {
935 icon += '<i class="icon-repo-group"></i> ';
935 icon += '<i class="icon-repo-group"></i> ';
936 }
936 }
937 // user group
937 // user group
938 else if (searchType === 'user_group') {
938 else if (searchType === 'user_group') {
939 icon += '<i class="icon-group"></i> ';
939 icon += '<i class="icon-group"></i> ';
940 }
940 }
941 // user
941 // user
942 else if (searchType === 'user') {
942 else if (searchType === 'user') {
943 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
943 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
944 }
944 }
945 // commit
945 // commit
946 else if (searchType === 'commit') {
946 else if (searchType === 'commit') {
947 var repo_data = data['repo_data'];
947 var repo_data = data['repo_data'];
948 var repoIcon = getRepoIcon(repo_data['repository_type']);
948 var repoIcon = getRepoIcon(repo_data['repository_type']);
949 if (repoIcon) {
949 if (repoIcon) {
950 icon += repoIcon;
950 icon += repoIcon;
951 } else {
951 } else {
952 icon += '<i class="icon-tag"></i>';
952 icon += '<i class="icon-tag"></i>';
953 }
953 }
954 }
954 }
955 // file
955 // file
956 else if (searchType === 'file') {
956 else if (searchType === 'file') {
957 var repo_data = data['repo_data'];
957 var repo_data = data['repo_data'];
958 var repoIcon = getRepoIcon(repo_data['repository_type']);
958 var repoIcon = getRepoIcon(repo_data['repository_type']);
959 if (repoIcon) {
959 if (repoIcon) {
960 icon += repoIcon;
960 icon += repoIcon;
961 } else {
961 } else {
962 icon += '<i class="icon-tag"></i>';
962 icon += '<i class="icon-tag"></i>';
963 }
963 }
964 }
964 }
965 // generic text
965 // generic text
966 else if (searchType === 'text') {
966 else if (searchType === 'text') {
967 icon = '';
967 icon = '';
968 }
968 }
969
969
970 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
970 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
971 return tmpl.format(icon, valueDisplay);
971 return tmpl.format(icon, valueDisplay);
972 };
972 };
973
973
974 var handleSelect = function(element, suggestion) {
974 var handleSelect = function(element, suggestion) {
975 if (suggestion.type === "hint") {
975 if (suggestion.type === "hint") {
976 // we skip action
976 // we skip action
977 $('#main_filter').focus();
977 $('#main_filter').focus();
978 }
978 }
979 else if (suggestion.type === "text") {
979 else if (suggestion.type === "text") {
980 // we skip action
980 // we skip action
981 $('#main_filter').focus();
981 $('#main_filter').focus();
982
982
983 } else {
983 } else {
984 window.location = suggestion['url'];
984 window.location = suggestion['url'];
985 }
985 }
986 };
986 };
987
987
988 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
988 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
989 if (queryLowerCase.split(':').length === 2) {
989 if (queryLowerCase.split(':').length === 2) {
990 queryLowerCase = queryLowerCase.split(':')[1]
990 queryLowerCase = queryLowerCase.split(':')[1]
991 }
991 }
992 if (suggestion.type === "text") {
992 if (suggestion.type === "text") {
993 // special case we don't want to "skip" display for
993 // special case we don't want to "skip" display for
994 return true
994 return true
995 }
995 }
996 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
996 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
997 };
997 };
998
998
999 var cleanContext = {
999 var cleanContext = {
1000 repo_view_type: null,
1000 repo_view_type: null,
1001
1001
1002 repo_id: null,
1002 repo_id: null,
1003 repo_name: "",
1003 repo_name: "",
1004
1004
1005 repo_group_id: null,
1005 repo_group_id: null,
1006 repo_group_name: null
1006 repo_group_name: null
1007 };
1007 };
1008 var removeGoToFilter = function () {
1008 var removeGoToFilter = function () {
1009 $('.searchTagHidable').hide();
1009 $('.searchTagHidable').hide();
1010 $('#main_filter').autocomplete(
1010 $('#main_filter').autocomplete(
1011 'setOptions', {params:{search_context: cleanContext}});
1011 'setOptions', {params:{search_context: cleanContext}});
1012 };
1012 };
1013
1013
1014 $('#main_filter').autocomplete({
1014 $('#main_filter').autocomplete({
1015 serviceUrl: pyroutes.url('goto_switcher_data'),
1015 serviceUrl: pyroutes.url('goto_switcher_data'),
1016 params: {
1016 params: {
1017 "search_context": templateContext.search_context
1017 "search_context": templateContext.search_context
1018 },
1018 },
1019 minChars:2,
1019 minChars:2,
1020 maxHeight:400,
1020 maxHeight:400,
1021 deferRequestBy: 300, //miliseconds
1021 deferRequestBy: 300, //miliseconds
1022 tabDisabled: true,
1022 tabDisabled: true,
1023 autoSelectFirst: false,
1023 autoSelectFirst: false,
1024 containerClass: 'autocomplete-qfilter-suggestions',
1024 containerClass: 'autocomplete-qfilter-suggestions',
1025 formatResult: autocompleteMainFilterFormatResult,
1025 formatResult: autocompleteMainFilterFormatResult,
1026 lookupFilter: autocompleteMainFilterResult,
1026 lookupFilter: autocompleteMainFilterResult,
1027 onSelect: function (element, suggestion) {
1027 onSelect: function (element, suggestion) {
1028 handleSelect(element, suggestion);
1028 handleSelect(element, suggestion);
1029 return false;
1029 return false;
1030 },
1030 },
1031 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
1031 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
1032 if (jqXHR !== 'abort') {
1032 if (jqXHR !== 'abort') {
1033 alert("Error during search.\nError code: {0}".format(textStatus));
1033 alert("Error during search.\nError code: {0}".format(textStatus));
1034 window.location = '';
1034 window.location = '';
1035 }
1035 }
1036 },
1036 },
1037 onSearchStart: function (params) {
1037 onSearchStart: function (params) {
1038 $('.searchTag.searchTagIcon').html('<i class="icon-spin animate-spin"></i>')
1038 $('.searchTag.searchTagIcon').html('<i class="icon-spin animate-spin"></i>')
1039 },
1039 },
1040 onSearchComplete: function (query, suggestions) {
1040 onSearchComplete: function (query, suggestions) {
1041 $('.searchTag.searchTagIcon').html('<i class="icon-search"></i>')
1041 $('.searchTag.searchTagIcon').html('<i class="icon-search"></i>')
1042 },
1042 },
1043 });
1043 });
1044
1044
1045 showMainFilterBox = function () {
1045 showMainFilterBox = function () {
1046 $('#main_filter_help').toggle();
1046 $('#main_filter_help').toggle();
1047 };
1047 };
1048
1048
1049 $('#main_filter').on('keydown.autocomplete', function (e) {
1049 $('#main_filter').on('keydown.autocomplete', function (e) {
1050
1050
1051 var BACKSPACE = 8;
1051 var BACKSPACE = 8;
1052 var el = $(e.currentTarget);
1052 var el = $(e.currentTarget);
1053 if(e.which === BACKSPACE){
1053 if(e.which === BACKSPACE){
1054 var inputVal = el.val();
1054 var inputVal = el.val();
1055 if (inputVal === ""){
1055 if (inputVal === ""){
1056 removeGoToFilter()
1056 removeGoToFilter()
1057 }
1057 }
1058 }
1058 }
1059 });
1059 });
1060
1060
1061 </script>
1061 </script>
1062 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
1062 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
1063 </%def>
1063 </%def>
1064
1064
1065 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
1065 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
1066 <div class="modal-dialog">
1066 <div class="modal-dialog">
1067 <div class="modal-content">
1067 <div class="modal-content">
1068 <div class="modal-header">
1068 <div class="modal-header">
1069 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
1069 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
1070 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
1070 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
1071 </div>
1071 </div>
1072 <div class="modal-body">
1072 <div class="modal-body">
1073 <div class="block-left">
1073 <div class="block-left">
1074 <table class="keyboard-mappings">
1074 <table class="keyboard-mappings">
1075 <tbody>
1075 <tbody>
1076 <tr>
1076 <tr>
1077 <th></th>
1077 <th></th>
1078 <th>${_('Site-wide shortcuts')}</th>
1078 <th>${_('Site-wide shortcuts')}</th>
1079 </tr>
1079 </tr>
1080 <%
1080 <%
1081 elems = [
1081 elems = [
1082 ('/', 'Use quick search box'),
1082 ('/', 'Use quick search box'),
1083 ('g h', 'Goto home page'),
1083 ('g h', 'Goto home page'),
1084 ('g g', 'Goto my private gists page'),
1084 ('g g', 'Goto my private gists page'),
1085 ('g G', 'Goto my public gists page'),
1085 ('g G', 'Goto my public gists page'),
1086 ('g 0-9', 'Goto bookmarked items from 0-9'),
1086 ('g 0-9', 'Goto bookmarked items from 0-9'),
1087 ('n r', 'New repository page'),
1087 ('n r', 'New repository page'),
1088 ('n g', 'New gist page'),
1088 ('n g', 'New gist page'),
1089 ]
1089 ]
1090 %>
1090 %>
1091 %for key, desc in elems:
1091 %for key, desc in elems:
1092 <tr>
1092 <tr>
1093 <td class="keys">
1093 <td class="keys">
1094 <span class="key tag">${key}</span>
1094 <span class="key tag">${key}</span>
1095 </td>
1095 </td>
1096 <td>${desc}</td>
1096 <td>${desc}</td>
1097 </tr>
1097 </tr>
1098 %endfor
1098 %endfor
1099 </tbody>
1099 </tbody>
1100 </table>
1100 </table>
1101 </div>
1101 </div>
1102 <div class="block-left">
1102 <div class="block-left">
1103 <table class="keyboard-mappings">
1103 <table class="keyboard-mappings">
1104 <tbody>
1104 <tbody>
1105 <tr>
1105 <tr>
1106 <th></th>
1106 <th></th>
1107 <th>${_('Repositories')}</th>
1107 <th>${_('Repositories')}</th>
1108 </tr>
1108 </tr>
1109 <%
1109 <%
1110 elems = [
1110 elems = [
1111 ('g s', 'Goto summary page'),
1111 ('g s', 'Goto summary page'),
1112 ('g c', 'Goto changelog page'),
1112 ('g c', 'Goto changelog page'),
1113 ('g f', 'Goto files page'),
1113 ('g f', 'Goto files page'),
1114 ('g F', 'Goto files page with file search activated'),
1114 ('g F', 'Goto files page with file search activated'),
1115 ('g p', 'Goto pull requests page'),
1115 ('g p', 'Goto pull requests page'),
1116 ('g o', 'Goto repository settings'),
1116 ('g o', 'Goto repository settings'),
1117 ('g O', 'Goto repository access permissions settings'),
1117 ('g O', 'Goto repository access permissions settings'),
1118 ]
1118 ]
1119 %>
1119 %>
1120 %for key, desc in elems:
1120 %for key, desc in elems:
1121 <tr>
1121 <tr>
1122 <td class="keys">
1122 <td class="keys">
1123 <span class="key tag">${key}</span>
1123 <span class="key tag">${key}</span>
1124 </td>
1124 </td>
1125 <td>${desc}</td>
1125 <td>${desc}</td>
1126 </tr>
1126 </tr>
1127 %endfor
1127 %endfor
1128 </tbody>
1128 </tbody>
1129 </table>
1129 </table>
1130 </div>
1130 </div>
1131 </div>
1131 </div>
1132 <div class="modal-footer">
1132 <div class="modal-footer">
1133 </div>
1133 </div>
1134 </div><!-- /.modal-content -->
1134 </div><!-- /.modal-content -->
1135 </div><!-- /.modal-dialog -->
1135 </div><!-- /.modal-dialog -->
1136 </div><!-- /.modal -->
1136 </div><!-- /.modal -->
General Comments 0
You need to be logged in to leave comments. Login now