##// END OF EJS Templates
feat: security tab in admin, routes and placeholder view for ee functionality
andverb -
r5518:3cd45018 default
parent child Browse files
Show More
@@ -0,0 +1,39 b''
1 # Copyright (C) 2010-2024 RhodeCode GmbH
2 #
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
6 #
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
11 #
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
19 import logging
20
21 from rhodecode.apps._base import BaseAppView
22 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
23
24 log = logging.getLogger(__name__)
25
26
27 class AdminSecurityView(BaseAppView):
28
29 def load_default_context(self):
30 c = self._get_local_tmpl_context()
31 return c
32
33 @LoginRequired()
34 @HasPermissionAllDecorator('hg.admin')
35 def security(self):
36 c = self.load_default_context()
37 c.active = 'security'
38 return self._get_template_context(c)
39
@@ -0,0 +1,40 b''
1 <%inherit file="/base/base.mako"/>
2
3 <%def name="title()">
4 ${_('Security Admin')}
5 %if c.rhodecode_name:
6 &middot; ${h.branding(c.rhodecode_name)}
7 %endif
8 </%def>
9
10 <%def name="breadcrumbs_links()"></%def>
11
12 <%def name="menu_bar_nav()">
13 ${self.menu_items(active='admin')}
14 </%def>
15
16 <%def name="menu_bar_subnav()">
17 ${self.admin_menu(active='security')}
18 </%def>
19
20 <%def name="main()">
21
22 <div class="box">
23
24 <div class="panel panel-default">
25 <div class="panel-heading">
26 <h3 class="panel-title">${_('Security Audit')}</h3>
27 </div>
28 <div class="panel-body">
29 <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4>
30 <p>
31 You can scan your repositories for exposed secrets, passwords, etc
32 </p>
33 </div>
34 </div>
35
36 </div>
37
38
39 </%def>
40
@@ -1,71 +1,71 b''
1 1 syntax: glob
2 2
3 3 *.egg
4 4 *.egg-info
5 5 *.idea
6 6 *.orig
7 7 *.pyc
8 8 *.sqlite-journal
9 9 *.swp
10 10 *.tox
11 11 *.DS_Store*
12 12 rhodecode/public/js/src/components/**/*.css
13 13
14 14 syntax: regexp
15 15
16 16 #.filename
17 17 ^\.settings$
18 18 ^\.project$
19 19 ^\.pydevproject$
20 20 ^\.coverage$
21 21 ^\.cache.*$
22 22 ^\.ruff_cache.*$
23 23 ^\.rhodecode$
24 24
25 25 ^rcextensions
26 26 ^.dev
27 27 ^._dev
28 28 ^build/
29 29 ^coverage\.xml$
30 30 ^data$
31 31 ^\.eggs/
32 32 ^configs/data$
33 33 ^dev.ini$
34 34 ^acceptance_tests/dev.*\.ini$
35 35 ^dist/
36 36 ^fabfile.py
37 37 ^htmlcov
38 38 ^junit\.xml$
39 39 ^node_modules/
40 40 ^node_binaries/
41 41 ^pylint.log$
42 42 ^rcextensions/
43 43 ^result$
44 44 ^rhodecode/public/css/style.css$
45 45 ^rhodecode/public/css/style-polymer.css$
46 46 ^rhodecode/public/css/style-ipython.css$
47 47 ^rhodecode/public/js/rhodecode-components.html$
48 48 ^rhodecode/public/js/rhodecode-components.js$
49 49 ^rhodecode/public/js/scripts.js$
50 50 ^rhodecode/public/js/scripts.min.js$
51 51 ^rhodecode/public/js/src/components/root-styles.gen.html$
52 52 ^rhodecode/public/js/vendors/webcomponentsjs/
53 53 ^rhodecode\.db$
54 54 ^rhodecode\.log$
55 55 ^rhodecode_dev\.log$
56 56 ^test\.db$
57
57 ^venv/
58 58
59 59 # ac-tests
60 60 ^acceptance_tests/\.cache.*$
61 61 ^acceptance_tests/externals
62 62 ^acceptance_tests/ghostdriver.log$
63 63 ^acceptance_tests/local(_.+)?\.ini$
64 64
65 65 # docs
66 66 ^docs/_build$
67 67 ^docs/result$
68 68 ^docs-internal/_build$
69 69
70 70 # Cythonized things
71 71 ^rhodecode/.*\.(c|so)$
@@ -1,1093 +1,1115 b''
1 1 # Copyright (C) 2016-2023 RhodeCode GmbH
2 2 #
3 3 # This program is free software: you can redistribute it and/or modify
4 4 # it under the terms of the GNU Affero General Public License, version 3
5 5 # (only), as published by the Free Software Foundation.
6 6 #
7 7 # This program is distributed in the hope that it will be useful,
8 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 # GNU General Public License for more details.
11 11 #
12 12 # You should have received a copy of the GNU Affero General Public License
13 13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 #
15 15 # This program is dual-licensed. If you wish to learn more about the
16 16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 18
19 19
20 20 from rhodecode.apps._base import ADMIN_PREFIX
21 21 from rhodecode.apps._base.navigation import includeme as nav_includeme
22 22 from rhodecode.apps.admin.views.main_views import AdminMainView
23 23
24 24
25 25 def admin_routes(config):
26 26 """
27 27 Admin prefixed routes
28 28 """
29 29 from rhodecode.apps.admin.views.audit_logs import AdminAuditLogsView
30 30 from rhodecode.apps.admin.views.artifacts import AdminArtifactsView
31 31 from rhodecode.apps.admin.views.automation import AdminAutomationView
32 32 from rhodecode.apps.admin.views.scheduler import AdminSchedulerView
33 33 from rhodecode.apps.admin.views.defaults import AdminDefaultSettingsView
34 34 from rhodecode.apps.admin.views.exception_tracker import ExceptionsTrackerView
35 35 from rhodecode.apps.admin.views.open_source_licenses import OpenSourceLicensesAdminSettingsView
36 36 from rhodecode.apps.admin.views.permissions import AdminPermissionsView
37 37 from rhodecode.apps.admin.views.process_management import AdminProcessManagementView
38 38 from rhodecode.apps.admin.views.repo_groups import AdminRepoGroupsView
39 39 from rhodecode.apps.admin.views.repositories import AdminReposView
40 40 from rhodecode.apps.admin.views.sessions import AdminSessionSettingsView
41 41 from rhodecode.apps.admin.views.settings import AdminSettingsView
42 42 from rhodecode.apps.admin.views.svn_config import AdminSvnConfigView
43 43 from rhodecode.apps.admin.views.system_info import AdminSystemInfoSettingsView
44 44 from rhodecode.apps.admin.views.user_groups import AdminUserGroupsView
45 45 from rhodecode.apps.admin.views.users import AdminUsersView, UsersView
46 from rhodecode.apps.admin.views.security import AdminSecurityView
47
48 # Security EE feature
49
50 config.add_route(
51 'admin_security',
52 pattern=ADMIN_PREFIX + '/security')
53 config.add_view(
54 AdminSecurityView,
55 attr='security' ,
56 route_name='admin_security', request_method='GET',
57 renderer='rhodecode:templates/admin/security/security.mako')
58
59 config.add_route(
60 name='admin_security_update',
61 pattern=ADMIN_PREFIX + '/security/update')
62 config.add_view(
63 AdminSecurityView,
64 attr='security_update',
65 route_name='admin_security_update', request_method='POST',
66 renderer='rhodecode:templates/admin/security/security.mako')
67
46 68
47 69 config.add_route(
48 70 name='admin_audit_logs',
49 71 pattern='/audit_logs')
50 72 config.add_view(
51 73 AdminAuditLogsView,
52 74 attr='admin_audit_logs',
53 75 route_name='admin_audit_logs', request_method='GET',
54 76 renderer='rhodecode:templates/admin/admin_audit_logs.mako')
55 77
56 78 config.add_route(
57 79 name='admin_audit_log_entry',
58 80 pattern='/audit_logs/{audit_log_id}')
59 81 config.add_view(
60 82 AdminAuditLogsView,
61 83 attr='admin_audit_log_entry',
62 84 route_name='admin_audit_log_entry', request_method='GET',
63 85 renderer='rhodecode:templates/admin/admin_audit_log_entry.mako')
64 86
65 87 # Artifacts EE feature
66 88 config.add_route(
67 89 'admin_artifacts',
68 90 pattern=ADMIN_PREFIX + '/artifacts')
69 91 config.add_route(
70 92 'admin_artifacts_show_all',
71 93 pattern=ADMIN_PREFIX + '/artifacts')
72 94 config.add_view(
73 95 AdminArtifactsView,
74 96 attr='artifacts',
75 97 route_name='admin_artifacts', request_method='GET',
76 98 renderer='rhodecode:templates/admin/artifacts/artifacts.mako')
77 99 config.add_view(
78 100 AdminArtifactsView,
79 101 attr='artifacts',
80 102 route_name='admin_artifacts_show_all', request_method='GET',
81 103 renderer='rhodecode:templates/admin/artifacts/artifacts.mako')
82 104
83 105 # EE views
84 106 config.add_route(
85 107 name='admin_artifacts_show_info',
86 108 pattern=ADMIN_PREFIX + '/artifacts/{uid}')
87 109 config.add_route(
88 110 name='admin_artifacts_delete',
89 111 pattern=ADMIN_PREFIX + '/artifacts/{uid}/delete')
90 112 config.add_route(
91 113 name='admin_artifacts_update',
92 114 pattern=ADMIN_PREFIX + '/artifacts/{uid}/update')
93 115
94 116 # Automation EE feature
95 117 config.add_route(
96 118 'admin_automation',
97 119 pattern=ADMIN_PREFIX + '/automation')
98 120 config.add_view(
99 121 AdminAutomationView,
100 122 attr='automation',
101 123 route_name='admin_automation', request_method='GET',
102 124 renderer='rhodecode:templates/admin/automation/automation.mako')
103 125
104 126 # Scheduler EE feature
105 127 config.add_route(
106 128 'admin_scheduler',
107 129 pattern=ADMIN_PREFIX + '/scheduler')
108 130 config.add_view(
109 131 AdminSchedulerView,
110 132 attr='scheduler',
111 133 route_name='admin_scheduler', request_method='GET',
112 134 renderer='rhodecode:templates/admin/scheduler/scheduler.mako')
113 135
114 136 config.add_route(
115 137 name='admin_settings_open_source',
116 138 pattern='/settings/open_source')
117 139 config.add_view(
118 140 OpenSourceLicensesAdminSettingsView,
119 141 attr='open_source_licenses',
120 142 route_name='admin_settings_open_source', request_method='GET',
121 143 renderer='rhodecode:templates/admin/settings/settings.mako')
122 144
123 145 config.add_route(
124 146 name='admin_settings_vcs_svn_generate_cfg',
125 147 pattern='/settings/vcs/svn_generate_cfg')
126 148 config.add_view(
127 149 AdminSvnConfigView,
128 150 attr='vcs_svn_generate_config',
129 151 route_name='admin_settings_vcs_svn_generate_cfg',
130 152 request_method='POST', renderer='json')
131 153
132 154 config.add_route(
133 155 name='admin_settings_system',
134 156 pattern='/settings/system')
135 157 config.add_view(
136 158 AdminSystemInfoSettingsView,
137 159 attr='settings_system_info',
138 160 route_name='admin_settings_system', request_method='GET',
139 161 renderer='rhodecode:templates/admin/settings/settings.mako')
140 162
141 163 config.add_route(
142 164 name='admin_settings_system_update',
143 165 pattern='/settings/system/updates')
144 166 config.add_view(
145 167 AdminSystemInfoSettingsView,
146 168 attr='settings_system_info_check_update',
147 169 route_name='admin_settings_system_update', request_method='GET',
148 170 renderer='rhodecode:templates/admin/settings/settings_system_update.mako')
149 171
150 172 config.add_route(
151 173 name='admin_settings_exception_tracker',
152 174 pattern='/settings/exceptions')
153 175 config.add_view(
154 176 ExceptionsTrackerView,
155 177 attr='browse_exceptions',
156 178 route_name='admin_settings_exception_tracker', request_method='GET',
157 179 renderer='rhodecode:templates/admin/settings/settings.mako')
158 180
159 181 config.add_route(
160 182 name='admin_settings_exception_tracker_delete_all',
161 183 pattern='/settings/exceptions_delete_all')
162 184 config.add_view(
163 185 ExceptionsTrackerView,
164 186 attr='exception_delete_all',
165 187 route_name='admin_settings_exception_tracker_delete_all', request_method='POST',
166 188 renderer='rhodecode:templates/admin/settings/settings.mako')
167 189
168 190 config.add_route(
169 191 name='admin_settings_exception_tracker_show',
170 192 pattern='/settings/exceptions/{exception_id}')
171 193 config.add_view(
172 194 ExceptionsTrackerView,
173 195 attr='exception_show',
174 196 route_name='admin_settings_exception_tracker_show', request_method='GET',
175 197 renderer='rhodecode:templates/admin/settings/settings.mako')
176 198
177 199 config.add_route(
178 200 name='admin_settings_exception_tracker_delete',
179 201 pattern='/settings/exceptions/{exception_id}/delete')
180 202 config.add_view(
181 203 ExceptionsTrackerView,
182 204 attr='exception_delete',
183 205 route_name='admin_settings_exception_tracker_delete', request_method='POST',
184 206 renderer='rhodecode:templates/admin/settings/settings.mako')
185 207
186 208 config.add_route(
187 209 name='admin_settings_sessions',
188 210 pattern='/settings/sessions')
189 211 config.add_view(
190 212 AdminSessionSettingsView,
191 213 attr='settings_sessions',
192 214 route_name='admin_settings_sessions', request_method='GET',
193 215 renderer='rhodecode:templates/admin/settings/settings.mako')
194 216
195 217 config.add_route(
196 218 name='admin_settings_sessions_cleanup',
197 219 pattern='/settings/sessions/cleanup')
198 220 config.add_view(
199 221 AdminSessionSettingsView,
200 222 attr='settings_sessions_cleanup',
201 223 route_name='admin_settings_sessions_cleanup', request_method='POST')
202 224
203 225 config.add_route(
204 226 name='admin_settings_process_management',
205 227 pattern='/settings/process_management')
206 228 config.add_view(
207 229 AdminProcessManagementView,
208 230 attr='process_management',
209 231 route_name='admin_settings_process_management', request_method='GET',
210 232 renderer='rhodecode:templates/admin/settings/settings.mako')
211 233
212 234 config.add_route(
213 235 name='admin_settings_process_management_data',
214 236 pattern='/settings/process_management/data')
215 237 config.add_view(
216 238 AdminProcessManagementView,
217 239 attr='process_management_data',
218 240 route_name='admin_settings_process_management_data', request_method='GET',
219 241 renderer='rhodecode:templates/admin/settings/settings_process_management_data.mako')
220 242
221 243 config.add_route(
222 244 name='admin_settings_process_management_signal',
223 245 pattern='/settings/process_management/signal')
224 246 config.add_view(
225 247 AdminProcessManagementView,
226 248 attr='process_management_signal',
227 249 route_name='admin_settings_process_management_signal',
228 250 request_method='POST', renderer='json_ext')
229 251
230 252 config.add_route(
231 253 name='admin_settings_process_management_master_signal',
232 254 pattern='/settings/process_management/master_signal')
233 255 config.add_view(
234 256 AdminProcessManagementView,
235 257 attr='process_management_master_signal',
236 258 route_name='admin_settings_process_management_master_signal',
237 259 request_method='POST', renderer='json_ext')
238 260
239 261 # default settings
240 262 config.add_route(
241 263 name='admin_defaults_repositories',
242 264 pattern='/defaults/repositories')
243 265 config.add_view(
244 266 AdminDefaultSettingsView,
245 267 attr='defaults_repository_show',
246 268 route_name='admin_defaults_repositories', request_method='GET',
247 269 renderer='rhodecode:templates/admin/defaults/defaults.mako')
248 270
249 271 config.add_route(
250 272 name='admin_defaults_repositories_update',
251 273 pattern='/defaults/repositories/update')
252 274 config.add_view(
253 275 AdminDefaultSettingsView,
254 276 attr='defaults_repository_update',
255 277 route_name='admin_defaults_repositories_update', request_method='POST',
256 278 renderer='rhodecode:templates/admin/defaults/defaults.mako')
257 279
258 280 # admin settings
259 281
260 282 config.add_route(
261 283 name='admin_settings',
262 284 pattern='/settings')
263 285 config.add_view(
264 286 AdminSettingsView,
265 287 attr='settings_global',
266 288 route_name='admin_settings', request_method='GET',
267 289 renderer='rhodecode:templates/admin/settings/settings.mako')
268 290
269 291 config.add_route(
270 292 name='admin_settings_update',
271 293 pattern='/settings/update')
272 294 config.add_view(
273 295 AdminSettingsView,
274 296 attr='settings_global_update',
275 297 route_name='admin_settings_update', request_method='POST',
276 298 renderer='rhodecode:templates/admin/settings/settings.mako')
277 299
278 300 config.add_route(
279 301 name='admin_settings_global',
280 302 pattern='/settings/global')
281 303 config.add_view(
282 304 AdminSettingsView,
283 305 attr='settings_global',
284 306 route_name='admin_settings_global', request_method='GET',
285 307 renderer='rhodecode:templates/admin/settings/settings.mako')
286 308
287 309 config.add_route(
288 310 name='admin_settings_global_update',
289 311 pattern='/settings/global/update')
290 312 config.add_view(
291 313 AdminSettingsView,
292 314 attr='settings_global_update',
293 315 route_name='admin_settings_global_update', request_method='POST',
294 316 renderer='rhodecode:templates/admin/settings/settings.mako')
295 317
296 318 config.add_route(
297 319 name='admin_settings_vcs',
298 320 pattern='/settings/vcs')
299 321 config.add_view(
300 322 AdminSettingsView,
301 323 attr='settings_vcs',
302 324 route_name='admin_settings_vcs', request_method='GET',
303 325 renderer='rhodecode:templates/admin/settings/settings.mako')
304 326
305 327 config.add_route(
306 328 name='admin_settings_vcs_update',
307 329 pattern='/settings/vcs/update')
308 330 config.add_view(
309 331 AdminSettingsView,
310 332 attr='settings_vcs_update',
311 333 route_name='admin_settings_vcs_update', request_method='POST',
312 334 renderer='rhodecode:templates/admin/settings/settings.mako')
313 335
314 336 config.add_route(
315 337 name='admin_settings_vcs_svn_pattern_delete',
316 338 pattern='/settings/vcs/svn_pattern_delete')
317 339 config.add_view(
318 340 AdminSettingsView,
319 341 attr='settings_vcs_delete_svn_pattern',
320 342 route_name='admin_settings_vcs_svn_pattern_delete', request_method='POST',
321 343 renderer='json_ext', xhr=True)
322 344
323 345 config.add_route(
324 346 name='admin_settings_mapping',
325 347 pattern='/settings/mapping')
326 348 config.add_view(
327 349 AdminSettingsView,
328 350 attr='settings_mapping',
329 351 route_name='admin_settings_mapping', request_method='GET',
330 352 renderer='rhodecode:templates/admin/settings/settings.mako')
331 353
332 354 config.add_route(
333 355 name='admin_settings_mapping_update',
334 356 pattern='/settings/mapping/update')
335 357 config.add_view(
336 358 AdminSettingsView,
337 359 attr='settings_mapping_update',
338 360 route_name='admin_settings_mapping_update', request_method='POST',
339 361 renderer='rhodecode:templates/admin/settings/settings.mako')
340 362
341 363 config.add_route(
342 364 name='admin_settings_visual',
343 365 pattern='/settings/visual')
344 366 config.add_view(
345 367 AdminSettingsView,
346 368 attr='settings_visual',
347 369 route_name='admin_settings_visual', request_method='GET',
348 370 renderer='rhodecode:templates/admin/settings/settings.mako')
349 371
350 372 config.add_route(
351 373 name='admin_settings_visual_update',
352 374 pattern='/settings/visual/update')
353 375 config.add_view(
354 376 AdminSettingsView,
355 377 attr='settings_visual_update',
356 378 route_name='admin_settings_visual_update', request_method='POST',
357 379 renderer='rhodecode:templates/admin/settings/settings.mako')
358 380
359 381 config.add_route(
360 382 name='admin_settings_issuetracker',
361 383 pattern='/settings/issue-tracker')
362 384 config.add_view(
363 385 AdminSettingsView,
364 386 attr='settings_issuetracker',
365 387 route_name='admin_settings_issuetracker', request_method='GET',
366 388 renderer='rhodecode:templates/admin/settings/settings.mako')
367 389
368 390 config.add_route(
369 391 name='admin_settings_issuetracker_update',
370 392 pattern='/settings/issue-tracker/update')
371 393 config.add_view(
372 394 AdminSettingsView,
373 395 attr='settings_issuetracker_update',
374 396 route_name='admin_settings_issuetracker_update', request_method='POST',
375 397 renderer='rhodecode:templates/admin/settings/settings.mako')
376 398
377 399 config.add_route(
378 400 name='admin_settings_issuetracker_test',
379 401 pattern='/settings/issue-tracker/test')
380 402 config.add_view(
381 403 AdminSettingsView,
382 404 attr='settings_issuetracker_test',
383 405 route_name='admin_settings_issuetracker_test', request_method='POST',
384 406 renderer='string', xhr=True)
385 407
386 408 config.add_route(
387 409 name='admin_settings_issuetracker_delete',
388 410 pattern='/settings/issue-tracker/delete')
389 411 config.add_view(
390 412 AdminSettingsView,
391 413 attr='settings_issuetracker_delete',
392 414 route_name='admin_settings_issuetracker_delete', request_method='POST',
393 415 renderer='json_ext', xhr=True)
394 416
395 417 config.add_route(
396 418 name='admin_settings_email',
397 419 pattern='/settings/email')
398 420 config.add_view(
399 421 AdminSettingsView,
400 422 attr='settings_email',
401 423 route_name='admin_settings_email', request_method='GET',
402 424 renderer='rhodecode:templates/admin/settings/settings.mako')
403 425
404 426 config.add_route(
405 427 name='admin_settings_email_update',
406 428 pattern='/settings/email/update')
407 429 config.add_view(
408 430 AdminSettingsView,
409 431 attr='settings_email_update',
410 432 route_name='admin_settings_email_update', request_method='POST',
411 433 renderer='rhodecode:templates/admin/settings/settings.mako')
412 434
413 435 config.add_route(
414 436 name='admin_settings_hooks',
415 437 pattern='/settings/hooks')
416 438 config.add_view(
417 439 AdminSettingsView,
418 440 attr='settings_hooks',
419 441 route_name='admin_settings_hooks', request_method='GET',
420 442 renderer='rhodecode:templates/admin/settings/settings.mako')
421 443
422 444 config.add_route(
423 445 name='admin_settings_hooks_update',
424 446 pattern='/settings/hooks/update')
425 447 config.add_view(
426 448 AdminSettingsView,
427 449 attr='settings_hooks_update',
428 450 route_name='admin_settings_hooks_update', request_method='POST',
429 451 renderer='rhodecode:templates/admin/settings/settings.mako')
430 452
431 453 config.add_route(
432 454 name='admin_settings_hooks_delete',
433 455 pattern='/settings/hooks/delete')
434 456 config.add_view(
435 457 AdminSettingsView,
436 458 attr='settings_hooks_update',
437 459 route_name='admin_settings_hooks_delete', request_method='POST',
438 460 renderer='rhodecode:templates/admin/settings/settings.mako')
439 461
440 462 config.add_route(
441 463 name='admin_settings_search',
442 464 pattern='/settings/search')
443 465 config.add_view(
444 466 AdminSettingsView,
445 467 attr='settings_search',
446 468 route_name='admin_settings_search', request_method='GET',
447 469 renderer='rhodecode:templates/admin/settings/settings.mako')
448 470
449 471 config.add_route(
450 472 name='admin_settings_labs',
451 473 pattern='/settings/labs')
452 474 config.add_view(
453 475 AdminSettingsView,
454 476 attr='settings_labs',
455 477 route_name='admin_settings_labs', request_method='GET',
456 478 renderer='rhodecode:templates/admin/settings/settings.mako')
457 479
458 480 config.add_route(
459 481 name='admin_settings_labs_update',
460 482 pattern='/settings/labs/update')
461 483 config.add_view(
462 484 AdminSettingsView,
463 485 attr='settings_labs_update',
464 486 route_name='admin_settings_labs_update', request_method='POST',
465 487 renderer='rhodecode:templates/admin/settings/settings.mako')
466 488
467 489 # global permissions
468 490
469 491 config.add_route(
470 492 name='admin_permissions_application',
471 493 pattern='/permissions/application')
472 494 config.add_view(
473 495 AdminPermissionsView,
474 496 attr='permissions_application',
475 497 route_name='admin_permissions_application', request_method='GET',
476 498 renderer='rhodecode:templates/admin/permissions/permissions.mako')
477 499
478 500 config.add_route(
479 501 name='admin_permissions_application_update',
480 502 pattern='/permissions/application/update')
481 503 config.add_view(
482 504 AdminPermissionsView,
483 505 attr='permissions_application_update',
484 506 route_name='admin_permissions_application_update', request_method='POST',
485 507 renderer='rhodecode:templates/admin/permissions/permissions.mako')
486 508
487 509 config.add_route(
488 510 name='admin_permissions_global',
489 511 pattern='/permissions/global')
490 512 config.add_view(
491 513 AdminPermissionsView,
492 514 attr='permissions_global',
493 515 route_name='admin_permissions_global', request_method='GET',
494 516 renderer='rhodecode:templates/admin/permissions/permissions.mako')
495 517
496 518 config.add_route(
497 519 name='admin_permissions_global_update',
498 520 pattern='/permissions/global/update')
499 521 config.add_view(
500 522 AdminPermissionsView,
501 523 attr='permissions_global_update',
502 524 route_name='admin_permissions_global_update', request_method='POST',
503 525 renderer='rhodecode:templates/admin/permissions/permissions.mako')
504 526
505 527 config.add_route(
506 528 name='admin_permissions_object',
507 529 pattern='/permissions/object')
508 530 config.add_view(
509 531 AdminPermissionsView,
510 532 attr='permissions_objects',
511 533 route_name='admin_permissions_object', request_method='GET',
512 534 renderer='rhodecode:templates/admin/permissions/permissions.mako')
513 535
514 536 config.add_route(
515 537 name='admin_permissions_object_update',
516 538 pattern='/permissions/object/update')
517 539 config.add_view(
518 540 AdminPermissionsView,
519 541 attr='permissions_objects_update',
520 542 route_name='admin_permissions_object_update', request_method='POST',
521 543 renderer='rhodecode:templates/admin/permissions/permissions.mako')
522 544
523 545 # Branch perms EE feature
524 546 config.add_route(
525 547 name='admin_permissions_branch',
526 548 pattern='/permissions/branch')
527 549 config.add_view(
528 550 AdminPermissionsView,
529 551 attr='permissions_branch',
530 552 route_name='admin_permissions_branch', request_method='GET',
531 553 renderer='rhodecode:templates/admin/permissions/permissions.mako')
532 554
533 555 config.add_route(
534 556 name='admin_permissions_ips',
535 557 pattern='/permissions/ips')
536 558 config.add_view(
537 559 AdminPermissionsView,
538 560 attr='permissions_ips',
539 561 route_name='admin_permissions_ips', request_method='GET',
540 562 renderer='rhodecode:templates/admin/permissions/permissions.mako')
541 563
542 564 config.add_route(
543 565 name='admin_permissions_overview',
544 566 pattern='/permissions/overview')
545 567 config.add_view(
546 568 AdminPermissionsView,
547 569 attr='permissions_overview',
548 570 route_name='admin_permissions_overview', request_method='GET',
549 571 renderer='rhodecode:templates/admin/permissions/permissions.mako')
550 572
551 573 config.add_route(
552 574 name='admin_permissions_auth_token_access',
553 575 pattern='/permissions/auth_token_access')
554 576 config.add_view(
555 577 AdminPermissionsView,
556 578 attr='auth_token_access',
557 579 route_name='admin_permissions_auth_token_access', request_method='GET',
558 580 renderer='rhodecode:templates/admin/permissions/permissions.mako')
559 581
560 582 config.add_route(
561 583 name='admin_permissions_ssh_keys',
562 584 pattern='/permissions/ssh_keys')
563 585 config.add_view(
564 586 AdminPermissionsView,
565 587 attr='ssh_keys',
566 588 route_name='admin_permissions_ssh_keys', request_method='GET',
567 589 renderer='rhodecode:templates/admin/permissions/permissions.mako')
568 590
569 591 config.add_route(
570 592 name='admin_permissions_ssh_keys_data',
571 593 pattern='/permissions/ssh_keys/data')
572 594 config.add_view(
573 595 AdminPermissionsView,
574 596 attr='ssh_keys_data',
575 597 route_name='admin_permissions_ssh_keys_data', request_method='GET',
576 598 renderer='json_ext', xhr=True)
577 599
578 600 config.add_route(
579 601 name='admin_permissions_ssh_keys_update',
580 602 pattern='/permissions/ssh_keys/update')
581 603 config.add_view(
582 604 AdminPermissionsView,
583 605 attr='ssh_keys_update',
584 606 route_name='admin_permissions_ssh_keys_update', request_method='POST',
585 607 renderer='rhodecode:templates/admin/permissions/permissions.mako')
586 608
587 609 # users admin
588 610 config.add_route(
589 611 name='users',
590 612 pattern='/users')
591 613 config.add_view(
592 614 AdminUsersView,
593 615 attr='users_list',
594 616 route_name='users', request_method='GET',
595 617 renderer='rhodecode:templates/admin/users/users.mako')
596 618
597 619 config.add_route(
598 620 name='users_data',
599 621 pattern='/users_data')
600 622 config.add_view(
601 623 AdminUsersView,
602 624 attr='users_list_data',
603 625 # renderer defined below
604 626 route_name='users_data', request_method='GET',
605 627 renderer='json_ext', xhr=True)
606 628
607 629 config.add_route(
608 630 name='users_create',
609 631 pattern='/users/create')
610 632 config.add_view(
611 633 AdminUsersView,
612 634 attr='users_create',
613 635 route_name='users_create', request_method='POST',
614 636 renderer='rhodecode:templates/admin/users/user_add.mako')
615 637
616 638 config.add_route(
617 639 name='users_new',
618 640 pattern='/users/new')
619 641 config.add_view(
620 642 AdminUsersView,
621 643 attr='users_new',
622 644 route_name='users_new', request_method='GET',
623 645 renderer='rhodecode:templates/admin/users/user_add.mako')
624 646
625 647 # user management
626 648 config.add_route(
627 649 name='user_edit',
628 650 pattern=r'/users/{user_id:\d+}/edit',
629 651 user_route=True)
630 652 config.add_view(
631 653 UsersView,
632 654 attr='user_edit',
633 655 route_name='user_edit', request_method='GET',
634 656 renderer='rhodecode:templates/admin/users/user_edit.mako')
635 657
636 658 config.add_route(
637 659 name='user_edit_advanced',
638 660 pattern=r'/users/{user_id:\d+}/edit/advanced',
639 661 user_route=True)
640 662 config.add_view(
641 663 UsersView,
642 664 attr='user_edit_advanced',
643 665 route_name='user_edit_advanced', request_method='GET',
644 666 renderer='rhodecode:templates/admin/users/user_edit.mako')
645 667
646 668 config.add_route(
647 669 name='user_edit_global_perms',
648 670 pattern=r'/users/{user_id:\d+}/edit/global_permissions',
649 671 user_route=True)
650 672 config.add_view(
651 673 UsersView,
652 674 attr='user_edit_global_perms',
653 675 route_name='user_edit_global_perms', request_method='GET',
654 676 renderer='rhodecode:templates/admin/users/user_edit.mako')
655 677
656 678 config.add_route(
657 679 name='user_edit_global_perms_update',
658 680 pattern=r'/users/{user_id:\d+}/edit/global_permissions/update',
659 681 user_route=True)
660 682 config.add_view(
661 683 UsersView,
662 684 attr='user_edit_global_perms_update',
663 685 route_name='user_edit_global_perms_update', request_method='POST',
664 686 renderer='rhodecode:templates/admin/users/user_edit.mako')
665 687
666 688 config.add_route(
667 689 name='user_update',
668 690 pattern=r'/users/{user_id:\d+}/update',
669 691 user_route=True)
670 692 config.add_view(
671 693 UsersView,
672 694 attr='user_update',
673 695 route_name='user_update', request_method='POST',
674 696 renderer='rhodecode:templates/admin/users/user_edit.mako')
675 697
676 698 config.add_route(
677 699 name='user_delete',
678 700 pattern=r'/users/{user_id:\d+}/delete',
679 701 user_route=True)
680 702 config.add_view(
681 703 UsersView,
682 704 attr='user_delete',
683 705 route_name='user_delete', request_method='POST',
684 706 renderer='rhodecode:templates/admin/users/user_edit.mako')
685 707
686 708 config.add_route(
687 709 name='user_enable_force_password_reset',
688 710 pattern=r'/users/{user_id:\d+}/password_reset_enable',
689 711 user_route=True)
690 712 config.add_view(
691 713 UsersView,
692 714 attr='user_enable_force_password_reset',
693 715 route_name='user_enable_force_password_reset', request_method='POST',
694 716 renderer='rhodecode:templates/admin/users/user_edit.mako')
695 717
696 718 config.add_route(
697 719 name='user_disable_force_password_reset',
698 720 pattern=r'/users/{user_id:\d+}/password_reset_disable',
699 721 user_route=True)
700 722 config.add_view(
701 723 UsersView,
702 724 attr='user_disable_force_password_reset',
703 725 route_name='user_disable_force_password_reset', request_method='POST',
704 726 renderer='rhodecode:templates/admin/users/user_edit.mako')
705 727
706 728 config.add_route(
707 729 name='user_create_personal_repo_group',
708 730 pattern=r'/users/{user_id:\d+}/create_repo_group',
709 731 user_route=True)
710 732 config.add_view(
711 733 UsersView,
712 734 attr='user_create_personal_repo_group',
713 735 route_name='user_create_personal_repo_group', request_method='POST',
714 736 renderer='rhodecode:templates/admin/users/user_edit.mako')
715 737
716 738 # user notice
717 739 config.add_route(
718 740 name='user_notice_dismiss',
719 741 pattern=r'/users/{user_id:\d+}/notice_dismiss',
720 742 user_route=True)
721 743 config.add_view(
722 744 UsersView,
723 745 attr='user_notice_dismiss',
724 746 route_name='user_notice_dismiss', request_method='POST',
725 747 renderer='json_ext', xhr=True)
726 748
727 749 # user auth tokens
728 750 config.add_route(
729 751 name='edit_user_auth_tokens',
730 752 pattern=r'/users/{user_id:\d+}/edit/auth_tokens',
731 753 user_route=True)
732 754 config.add_view(
733 755 UsersView,
734 756 attr='auth_tokens',
735 757 route_name='edit_user_auth_tokens', request_method='GET',
736 758 renderer='rhodecode:templates/admin/users/user_edit.mako')
737 759
738 760 config.add_route(
739 761 name='edit_user_auth_tokens_view',
740 762 pattern=r'/users/{user_id:\d+}/edit/auth_tokens/view',
741 763 user_route=True)
742 764 config.add_view(
743 765 UsersView,
744 766 attr='auth_tokens_view',
745 767 route_name='edit_user_auth_tokens_view', request_method='POST',
746 768 renderer='json_ext', xhr=True)
747 769
748 770 config.add_route(
749 771 name='edit_user_auth_tokens_add',
750 772 pattern=r'/users/{user_id:\d+}/edit/auth_tokens/new',
751 773 user_route=True)
752 774 config.add_view(
753 775 UsersView,
754 776 attr='auth_tokens_add',
755 777 route_name='edit_user_auth_tokens_add', request_method='POST')
756 778
757 779 config.add_route(
758 780 name='edit_user_auth_tokens_delete',
759 781 pattern=r'/users/{user_id:\d+}/edit/auth_tokens/delete',
760 782 user_route=True)
761 783 config.add_view(
762 784 UsersView,
763 785 attr='auth_tokens_delete',
764 786 route_name='edit_user_auth_tokens_delete', request_method='POST')
765 787
766 788 # user ssh keys
767 789 config.add_route(
768 790 name='edit_user_ssh_keys',
769 791 pattern=r'/users/{user_id:\d+}/edit/ssh_keys',
770 792 user_route=True)
771 793 config.add_view(
772 794 UsersView,
773 795 attr='ssh_keys',
774 796 route_name='edit_user_ssh_keys', request_method='GET',
775 797 renderer='rhodecode:templates/admin/users/user_edit.mako')
776 798
777 799 config.add_route(
778 800 name='edit_user_ssh_keys_generate_keypair',
779 801 pattern=r'/users/{user_id:\d+}/edit/ssh_keys/generate',
780 802 user_route=True)
781 803 config.add_view(
782 804 UsersView,
783 805 attr='ssh_keys_generate_keypair',
784 806 route_name='edit_user_ssh_keys_generate_keypair', request_method='GET',
785 807 renderer='rhodecode:templates/admin/users/user_edit.mako')
786 808
787 809 config.add_route(
788 810 name='edit_user_ssh_keys_add',
789 811 pattern=r'/users/{user_id:\d+}/edit/ssh_keys/new',
790 812 user_route=True)
791 813 config.add_view(
792 814 UsersView,
793 815 attr='ssh_keys_add',
794 816 route_name='edit_user_ssh_keys_add', request_method='POST')
795 817
796 818 config.add_route(
797 819 name='edit_user_ssh_keys_delete',
798 820 pattern=r'/users/{user_id:\d+}/edit/ssh_keys/delete',
799 821 user_route=True)
800 822 config.add_view(
801 823 UsersView,
802 824 attr='ssh_keys_delete',
803 825 route_name='edit_user_ssh_keys_delete', request_method='POST')
804 826
805 827 # user emails
806 828 config.add_route(
807 829 name='edit_user_emails',
808 830 pattern=r'/users/{user_id:\d+}/edit/emails',
809 831 user_route=True)
810 832 config.add_view(
811 833 UsersView,
812 834 attr='emails',
813 835 route_name='edit_user_emails', request_method='GET',
814 836 renderer='rhodecode:templates/admin/users/user_edit.mako')
815 837
816 838 config.add_route(
817 839 name='edit_user_emails_add',
818 840 pattern=r'/users/{user_id:\d+}/edit/emails/new',
819 841 user_route=True)
820 842 config.add_view(
821 843 UsersView,
822 844 attr='emails_add',
823 845 route_name='edit_user_emails_add', request_method='POST')
824 846
825 847 config.add_route(
826 848 name='edit_user_emails_delete',
827 849 pattern=r'/users/{user_id:\d+}/edit/emails/delete',
828 850 user_route=True)
829 851 config.add_view(
830 852 UsersView,
831 853 attr='emails_delete',
832 854 route_name='edit_user_emails_delete', request_method='POST')
833 855
834 856 # user IPs
835 857 config.add_route(
836 858 name='edit_user_ips',
837 859 pattern=r'/users/{user_id:\d+}/edit/ips',
838 860 user_route=True)
839 861 config.add_view(
840 862 UsersView,
841 863 attr='ips',
842 864 route_name='edit_user_ips', request_method='GET',
843 865 renderer='rhodecode:templates/admin/users/user_edit.mako')
844 866
845 867 config.add_route(
846 868 name='edit_user_ips_add',
847 869 pattern=r'/users/{user_id:\d+}/edit/ips/new',
848 870 user_route_with_default=True) # enabled for default user too
849 871 config.add_view(
850 872 UsersView,
851 873 attr='ips_add',
852 874 route_name='edit_user_ips_add', request_method='POST')
853 875
854 876 config.add_route(
855 877 name='edit_user_ips_delete',
856 878 pattern=r'/users/{user_id:\d+}/edit/ips/delete',
857 879 user_route_with_default=True) # enabled for default user too
858 880 config.add_view(
859 881 UsersView,
860 882 attr='ips_delete',
861 883 route_name='edit_user_ips_delete', request_method='POST')
862 884
863 885 # user perms
864 886 config.add_route(
865 887 name='edit_user_perms_summary',
866 888 pattern=r'/users/{user_id:\d+}/edit/permissions_summary',
867 889 user_route=True)
868 890 config.add_view(
869 891 UsersView,
870 892 attr='user_perms_summary',
871 893 route_name='edit_user_perms_summary', request_method='GET',
872 894 renderer='rhodecode:templates/admin/users/user_edit.mako')
873 895
874 896 config.add_route(
875 897 name='edit_user_perms_summary_json',
876 898 pattern=r'/users/{user_id:\d+}/edit/permissions_summary/json',
877 899 user_route=True)
878 900 config.add_view(
879 901 UsersView,
880 902 attr='user_perms_summary_json',
881 903 route_name='edit_user_perms_summary_json', request_method='GET',
882 904 renderer='json_ext')
883 905
884 906 # user user groups management
885 907 config.add_route(
886 908 name='edit_user_groups_management',
887 909 pattern=r'/users/{user_id:\d+}/edit/groups_management',
888 910 user_route=True)
889 911 config.add_view(
890 912 UsersView,
891 913 attr='groups_management',
892 914 route_name='edit_user_groups_management', request_method='GET',
893 915 renderer='rhodecode:templates/admin/users/user_edit.mako')
894 916
895 917 config.add_route(
896 918 name='edit_user_groups_management_updates',
897 919 pattern=r'/users/{user_id:\d+}/edit/edit_user_groups_management/updates',
898 920 user_route=True)
899 921 config.add_view(
900 922 UsersView,
901 923 attr='groups_management_updates',
902 924 route_name='edit_user_groups_management_updates', request_method='POST')
903 925
904 926 # user audit logs
905 927 config.add_route(
906 928 name='edit_user_audit_logs',
907 929 pattern=r'/users/{user_id:\d+}/edit/audit', user_route=True)
908 930 config.add_view(
909 931 UsersView,
910 932 attr='user_audit_logs',
911 933 route_name='edit_user_audit_logs', request_method='GET',
912 934 renderer='rhodecode:templates/admin/users/user_edit.mako')
913 935
914 936 config.add_route(
915 937 name='edit_user_audit_logs_download',
916 938 pattern=r'/users/{user_id:\d+}/edit/audit/download', user_route=True)
917 939 config.add_view(
918 940 UsersView,
919 941 attr='user_audit_logs_download',
920 942 route_name='edit_user_audit_logs_download', request_method='GET',
921 943 renderer='string')
922 944
923 945 # user caches
924 946 config.add_route(
925 947 name='edit_user_caches',
926 948 pattern=r'/users/{user_id:\d+}/edit/caches',
927 949 user_route=True)
928 950 config.add_view(
929 951 UsersView,
930 952 attr='user_caches',
931 953 route_name='edit_user_caches', request_method='GET',
932 954 renderer='rhodecode:templates/admin/users/user_edit.mako')
933 955
934 956 config.add_route(
935 957 name='edit_user_caches_update',
936 958 pattern=r'/users/{user_id:\d+}/edit/caches/update',
937 959 user_route=True)
938 960 config.add_view(
939 961 UsersView,
940 962 attr='user_caches_update',
941 963 route_name='edit_user_caches_update', request_method='POST')
942 964
943 965 # user-groups admin
944 966 config.add_route(
945 967 name='user_groups',
946 968 pattern='/user_groups')
947 969 config.add_view(
948 970 AdminUserGroupsView,
949 971 attr='user_groups_list',
950 972 route_name='user_groups', request_method='GET',
951 973 renderer='rhodecode:templates/admin/user_groups/user_groups.mako')
952 974
953 975 config.add_route(
954 976 name='user_groups_data',
955 977 pattern='/user_groups_data')
956 978 config.add_view(
957 979 AdminUserGroupsView,
958 980 attr='user_groups_list_data',
959 981 route_name='user_groups_data', request_method='GET',
960 982 renderer='json_ext', xhr=True)
961 983
962 984 config.add_route(
963 985 name='user_groups_new',
964 986 pattern='/user_groups/new')
965 987 config.add_view(
966 988 AdminUserGroupsView,
967 989 attr='user_groups_new',
968 990 route_name='user_groups_new', request_method='GET',
969 991 renderer='rhodecode:templates/admin/user_groups/user_group_add.mako')
970 992
971 993 config.add_route(
972 994 name='user_groups_create',
973 995 pattern='/user_groups/create')
974 996 config.add_view(
975 997 AdminUserGroupsView,
976 998 attr='user_groups_create',
977 999 route_name='user_groups_create', request_method='POST',
978 1000 renderer='rhodecode:templates/admin/user_groups/user_group_add.mako')
979 1001
980 1002 # repos admin
981 1003 config.add_route(
982 1004 name='repos',
983 1005 pattern='/repos')
984 1006 config.add_view(
985 1007 AdminReposView,
986 1008 attr='repository_list',
987 1009 route_name='repos', request_method='GET',
988 1010 renderer='rhodecode:templates/admin/repos/repos.mako')
989 1011
990 1012 config.add_route(
991 1013 name='repos_data',
992 1014 pattern='/repos_data')
993 1015 config.add_view(
994 1016 AdminReposView,
995 1017 attr='repository_list_data',
996 1018 route_name='repos_data', request_method='GET',
997 1019 renderer='json_ext', xhr=True)
998 1020
999 1021 config.add_route(
1000 1022 name='repo_new',
1001 1023 pattern='/repos/new')
1002 1024 config.add_view(
1003 1025 AdminReposView,
1004 1026 attr='repository_new',
1005 1027 route_name='repo_new', request_method='GET',
1006 1028 renderer='rhodecode:templates/admin/repos/repo_add.mako')
1007 1029
1008 1030 config.add_route(
1009 1031 name='repo_create',
1010 1032 pattern='/repos/create')
1011 1033 config.add_view(
1012 1034 AdminReposView,
1013 1035 attr='repository_create',
1014 1036 route_name='repo_create', request_method='POST',
1015 1037 renderer='rhodecode:templates/admin/repos/repos.mako')
1016 1038
1017 1039 # repo groups admin
1018 1040 config.add_route(
1019 1041 name='repo_groups',
1020 1042 pattern='/repo_groups')
1021 1043 config.add_view(
1022 1044 AdminRepoGroupsView,
1023 1045 attr='repo_group_list',
1024 1046 route_name='repo_groups', request_method='GET',
1025 1047 renderer='rhodecode:templates/admin/repo_groups/repo_groups.mako')
1026 1048
1027 1049 config.add_route(
1028 1050 name='repo_groups_data',
1029 1051 pattern='/repo_groups_data')
1030 1052 config.add_view(
1031 1053 AdminRepoGroupsView,
1032 1054 attr='repo_group_list_data',
1033 1055 route_name='repo_groups_data', request_method='GET',
1034 1056 renderer='json_ext', xhr=True)
1035 1057
1036 1058 config.add_route(
1037 1059 name='repo_group_new',
1038 1060 pattern='/repo_group/new')
1039 1061 config.add_view(
1040 1062 AdminRepoGroupsView,
1041 1063 attr='repo_group_new',
1042 1064 route_name='repo_group_new', request_method='GET',
1043 1065 renderer='rhodecode:templates/admin/repo_groups/repo_group_add.mako')
1044 1066
1045 1067 config.add_route(
1046 1068 name='repo_group_create',
1047 1069 pattern='/repo_group/create')
1048 1070 config.add_view(
1049 1071 AdminRepoGroupsView,
1050 1072 attr='repo_group_create',
1051 1073 route_name='repo_group_create', request_method='POST',
1052 1074 renderer='rhodecode:templates/admin/repo_groups/repo_group_add.mako')
1053 1075
1054 1076
1055 1077 def includeme(config):
1056 1078 # Create admin navigation registry and add it to the pyramid registry.
1057 1079 nav_includeme(config)
1058 1080
1059 1081 # main admin routes
1060 1082 config.add_route(
1061 1083 name='admin_home', pattern=ADMIN_PREFIX)
1062 1084 config.add_view(
1063 1085 AdminMainView,
1064 1086 attr='admin_main',
1065 1087 route_name='admin_home', request_method='GET',
1066 1088 renderer='rhodecode:templates/admin/main.mako')
1067 1089
1068 1090 # pr global redirect
1069 1091 config.add_route(
1070 1092 name='pull_requests_global_0', # backward compat
1071 1093 pattern=ADMIN_PREFIX + r'/pull_requests/{pull_request_id:\d+}')
1072 1094 config.add_view(
1073 1095 AdminMainView,
1074 1096 attr='pull_requests',
1075 1097 route_name='pull_requests_global_0', request_method='GET')
1076 1098
1077 1099 config.add_route(
1078 1100 name='pull_requests_global_1', # backward compat
1079 1101 pattern=ADMIN_PREFIX + r'/pull-requests/{pull_request_id:\d+}')
1080 1102 config.add_view(
1081 1103 AdminMainView,
1082 1104 attr='pull_requests',
1083 1105 route_name='pull_requests_global_1', request_method='GET')
1084 1106
1085 1107 config.add_route(
1086 1108 name='pull_requests_global',
1087 1109 pattern=ADMIN_PREFIX + r'/pull-request/{pull_request_id:\d+}')
1088 1110 config.add_view(
1089 1111 AdminMainView,
1090 1112 attr='pull_requests',
1091 1113 route_name='pull_requests_global', request_method='GET')
1092 1114
1093 1115 config.include(admin_routes, route_prefix=ADMIN_PREFIX)
@@ -1,1263 +1,1264 b''
1 1
2 2 <%!
3 3 from rhodecode.lib import html_filters
4 4 %>
5 5
6 6 <%inherit file="root.mako"/>
7 7
8 8 <%include file="/ejs_templates/templates.html"/>
9 9
10 10 <div class="outerwrapper">
11 11 <!-- HEADER -->
12 12 <div class="header">
13 13 <div id="header-inner" class="wrapper">
14 14 <div id="logo">
15 15 <div class="logo-wrapper">
16 16 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
17 17 </div>
18 18 % if c.rhodecode_name:
19 19 <div class="branding">
20 20 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
21 21 </div>
22 22 % endif
23 23 </div>
24 24 <!-- MENU BAR NAV -->
25 25 ${self.menu_bar_nav()}
26 26 <!-- END MENU BAR NAV -->
27 27 </div>
28 28 </div>
29 29 ${self.menu_bar_subnav()}
30 30 <!-- END HEADER -->
31 31
32 32 <!-- CONTENT -->
33 33 <div id="content" class="wrapper">
34 34
35 35 <rhodecode-toast id="notifications"></rhodecode-toast>
36 36
37 37 <div class="main">
38 38 ${next.main()}
39 39 </div>
40 40
41 41 </div>
42 42 <!-- END CONTENT -->
43 43
44 44 </div>
45 45
46 46 <!-- FOOTER -->
47 47 <div id="footer">
48 48 <div id="footer-inner" class="title wrapper">
49 49 <div>
50 50 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
51 51
52 52 <p class="footer-link-right">
53 53 <a class="grey-link-action" href="${h.route_path('home', _query={'showrcid': 1})}">
54 54 RhodeCode
55 55 % if c.visual.show_version:
56 56 ${c.rhodecode_version}
57 57 % endif
58 58 ${c.rhodecode_edition}
59 59 </a> |
60 60
61 61 % if c.visual.rhodecode_support_url:
62 62 <a class="grey-link-action" href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a> |
63 63 <a class="grey-link-action" href="https://docs.rhodecode.com" target="_blank">${_('Documentation')}</a>
64 64 % endif
65 65
66 66 </p>
67 67
68 68 <p class="server-instance" style="display:${sid}">
69 69 ## display hidden instance ID if specially defined
70 70 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
71 71 % if c.rhodecode_instanceid:
72 72 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
73 73 % endif
74 74 </p>
75 75 </div>
76 76 </div>
77 77 </div>
78 78
79 79 <!-- END FOOTER -->
80 80
81 81 ### MAKO DEFS ###
82 82
83 83 <%def name="menu_bar_subnav()">
84 84 </%def>
85 85
86 86 <%def name="breadcrumbs(class_='breadcrumbs')">
87 87 <div class="${class_}">
88 88 ${self.breadcrumbs_links()}
89 89 </div>
90 90 </%def>
91 91
92 92 <%def name="admin_menu(active=None)">
93 93
94 94 <div id="context-bar">
95 95 <div class="wrapper">
96 96 <div class="title">
97 97 <div class="title-content">
98 98 <div class="title-main">
99 99 % if c.is_super_admin:
100 100 ${_('Super-admin Panel')}
101 101 % else:
102 102 ${_('Delegated Admin Panel')}
103 103 % endif
104 104 </div>
105 105 </div>
106 106 </div>
107 107
108 108 <ul id="context-pages" class="navigation horizontal-list">
109 109
110 110 ## super-admin case (Top Menu)
111 111 % if c.is_super_admin:
112 112 <li class="${h.is_active('audit_logs', active)}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
113 113 <li class="${h.is_active('repositories', active)}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
114 114 <li class="${h.is_active('repository_groups', active)}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
115 115 <li class="${h.is_active('users', active)}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
116 116 <li class="${h.is_active('user_groups', active)}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
117 <li class="${h.is_active('security', active)}"><a href="${h.route_path('admin_security')}">${_('Security')}</a></li>
117 118 <li class="${h.is_active('artifacts', active)}"><a href="${h.route_path('admin_artifacts')}">${_('Artifacts')}</a></li>
118 119 <li class="${h.is_active('automation', active)}"><a href="${h.route_path('admin_automation')}">${_('Automation')}</a></li>
119 120 <li class="${h.is_active('scheduler', active)}"><a href="${h.route_path('admin_scheduler')}">${_('Scheduler')}</a></li>
120 121 <li class="${h.is_active('permissions', active)}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
121 122 <li class="${h.is_active('authentication', active)}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
122 123 <li class="${h.is_active('integrations', active)}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
123 124 <li class="${h.is_active('defaults', active)}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
124 125 <li class="${h.is_active('settings', active)}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
125 126
126 127 ## delegated admin
127 128 % elif c.is_delegated_admin:
128 129 <%
129 130 repositories=c.auth_user.repositories_admin or c.can_create_repo
130 131 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
131 132 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
132 133 %>
133 134
134 135 %if repositories:
135 136 <li class="${h.is_active('repositories', active)} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
136 137 %endif
137 138 %if repository_groups:
138 139 <li class="${h.is_active('repository_groups', active)} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
139 140 %endif
140 141 %if user_groups:
141 142 <li class="${h.is_active('user_groups', active)} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
142 143 %endif
143 144 % endif
144 145 </ul>
145 146
146 147 </div>
147 148 <div class="clear"></div>
148 149 </div>
149 150 </%def>
150 151
151 152 <%def name="dt_info_panel(elements)">
152 153 <dl class="dl-horizontal">
153 154 %for dt, dd, title, show_items in elements:
154 155 <dt>${dt}:</dt>
155 156 <dd title="${h.tooltip(title)}">
156 157 %if callable(dd):
157 158 ## allow lazy evaluation of elements
158 159 ${dd()}
159 160 %else:
160 161 ${dd}
161 162 %endif
162 163 %if show_items:
163 164 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
164 165 %endif
165 166 </dd>
166 167
167 168 %if show_items:
168 169 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
169 170 %for item in show_items:
170 171 <dt></dt>
171 172 <dd>${item}</dd>
172 173 %endfor
173 174 </div>
174 175 %endif
175 176
176 177 %endfor
177 178 </dl>
178 179 </%def>
179 180
180 181 <%def name="tr_info_entry(element)">
181 182 <% key, val, title, show_items = element %>
182 183
183 184 <tr>
184 185 <td style="vertical-align: top">${key}</td>
185 186 <td title="${h.tooltip(title)}">
186 187 %if callable(val):
187 188 ## allow lazy evaluation of elements
188 189 ${val()}
189 190 %else:
190 191 ${val}
191 192 %endif
192 193 %if show_items:
193 194 <div class="collapsable-content" data-toggle="item-${h.md5_safe(h.safe_str(val))[:6]}-details" style="display: none">
194 195 % for item in show_items:
195 196 <dt></dt>
196 197 <dd>${item}</dd>
197 198 % endfor
198 199 </div>
199 200 %endif
200 201 </td>
201 202 <td style="vertical-align: top">
202 203 %if show_items:
203 204 <span class="btn-collapse" data-toggle="item-${h.md5_safe(h.safe_str(val))[:6]}-details">${_('Show More')} </span>
204 205 %endif
205 206 </td>
206 207 </tr>
207 208
208 209 </%def>
209 210
210 211 <%def name="gravatar(email, size=16, tooltip=False, tooltip_alt=None, user=None, extra_class=None)">
211 212 <%
212 213 if size > 16:
213 214 gravatar_class = ['gravatar','gravatar-large']
214 215 else:
215 216 gravatar_class = ['gravatar']
216 217
217 218 data_hovercard_url = ''
218 219 data_hovercard_alt = tooltip_alt.replace('<', '&lt;').replace('>', '&gt;') if tooltip_alt else ''
219 220
220 221 if tooltip:
221 222 gravatar_class += ['tooltip-hovercard']
222 223 if extra_class:
223 224 gravatar_class += extra_class
224 225 if tooltip and user:
225 226 if user.username == h.DEFAULT_USER:
226 227 gravatar_class.pop(-1)
227 228 else:
228 229 data_hovercard_url = request.route_path('hovercard_user', user_id=getattr(user, 'user_id', ''))
229 230 gravatar_class = ' '.join(gravatar_class)
230 231
231 232 %>
232 233 <%doc>
233 234 TODO: johbo: For now we serve double size images to make it smooth
234 235 for retina. This is how it worked until now. Should be replaced
235 236 with a better solution at some point.
236 237 </%doc>
237 238
238 239 <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, request=request)}" />
239 240 </%def>
240 241
241 242
242 243 <%def name="gravatar_with_user(contact, size=16, show_disabled=False, tooltip=False, _class='rc-user')">
243 244 <%
244 245 email = h.email_or_none(contact)
245 246 rc_user = h.discover_user(contact)
246 247 %>
247 248
248 249 <div class="${_class}">
249 250 ${self.gravatar(email, size, tooltip=tooltip, tooltip_alt=contact, user=rc_user)}
250 251 <span class="${('user user-disabled' if show_disabled else 'user')}">
251 252 ${h.link_to_user(rc_user or contact)}
252 253 </span>
253 254 </div>
254 255 </%def>
255 256
256 257
257 258 <%def name="user_group_icon(user_group=None, size=16, tooltip=False)">
258 259 <%
259 260 if (size > 16):
260 261 gravatar_class = 'icon-user-group-alt'
261 262 else:
262 263 gravatar_class = 'icon-user-group-alt'
263 264
264 265 if tooltip:
265 266 gravatar_class += ' tooltip-hovercard'
266 267
267 268 data_hovercard_url = request.route_path('hovercard_user_group', user_group_id=user_group.users_group_id)
268 269 %>
269 270 <%doc>
270 271 TODO: johbo: For now we serve double size images to make it smooth
271 272 for retina. This is how it worked until now. Should be replaced
272 273 with a better solution at some point.
273 274 </%doc>
274 275
275 276 <i style="font-size: ${size}px" class="${gravatar_class} x-icon-size-${size}" data-hovercard-url="${data_hovercard_url}"></i>
276 277 </%def>
277 278
278 279 <%def name="repo_page_title(repo_instance)">
279 280 <div class="title-content repo-title">
280 281
281 282 <div class="title-main">
282 283 ## SVN/HG/GIT icons
283 284 %if h.is_hg(repo_instance):
284 285 <i class="icon-hg"></i>
285 286 %endif
286 287 %if h.is_git(repo_instance):
287 288 <i class="icon-git"></i>
288 289 %endif
289 290 %if h.is_svn(repo_instance):
290 291 <i class="icon-svn"></i>
291 292 %endif
292 293
293 294 ## public/private
294 295 %if repo_instance.private:
295 296 <i class="icon-repo-private"></i>
296 297 %else:
297 298 <i class="icon-repo-public"></i>
298 299 %endif
299 300
300 301 ## repo name with group name
301 302 ${h.breadcrumb_repo_link(repo_instance)}
302 303
303 304 ## Context Actions
304 305 <div class="pull-right">
305 306 %if c.rhodecode_user.username != h.DEFAULT_USER:
306 307 <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>
307 308
308 309 <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 '')}">
309 310 % if c.repository_is_user_following:
310 311 <i class="icon-eye-off"></i>${_('Unwatch')}
311 312 % else:
312 313 <i class="icon-eye"></i>${_('Watch')}
313 314 % endif
314 315
315 316 </a>
316 317 %else:
317 318 <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>
318 319 %endif
319 320 </div>
320 321
321 322 </div>
322 323
323 324 ## FORKED
324 325 %if repo_instance.fork:
325 326 <p class="discreet">
326 327 <i class="icon-code-fork"></i> ${_('Fork of')}
327 328 ${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))}
328 329 </p>
329 330 %endif
330 331
331 332 ## IMPORTED FROM REMOTE
332 333 %if repo_instance.clone_uri:
333 334 <p class="discreet">
334 335 <i class="icon-code-fork"></i> ${_('Clone from')}
335 336 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
336 337 </p>
337 338 %endif
338 339
339 340 ## LOCKING STATUS
340 341 %if repo_instance.locked[0]:
341 342 <p class="locking_locked discreet">
342 343 <i class="icon-repo-lock"></i>
343 344 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
344 345 </p>
345 346 %elif repo_instance.enable_locking:
346 347 <p class="locking_unlocked discreet">
347 348 ${_('Repository not locked. Pull repository to lock it.')}
348 349 </p>
349 350 %endif
350 351
351 352 </div>
352 353 </%def>
353 354
354 355 <%def name="repo_menu(active=None)">
355 356 <%
356 357 ## determine if we have "any" option available
357 358 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
358 359 has_actions = can_lock
359 360
360 361 %>
361 362 % if c.rhodecode_db_repo.archived:
362 363 <div class="alert alert-warning text-center">
363 364 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
364 365 </div>
365 366 % endif
366 367
367 368 <!--- REPO CONTEXT BAR -->
368 369 <div id="context-bar">
369 370 <div class="wrapper">
370 371
371 372 <div class="title">
372 373 ${self.repo_page_title(c.rhodecode_db_repo)}
373 374 </div>
374 375
375 376 <ul id="context-pages" class="navigation horizontal-list">
376 377 <li class="${h.is_active('summary', active)}"><a class="menulink" href="${h.route_path('repo_summary_explicit', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
377 378 <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>
378 379 <li class="${h.is_active('files', active)}"><a class="menulink" href="${h.repo_files_by_ref_url(c.repo_name, c.rhodecode_db_repo.repo_type, f_path='', ref_name=c.rhodecode_db_repo.landing_ref_name, commit_id='tip', query={'at':c.rhodecode_db_repo.landing_ref_name})}"><div class="menulabel">${_('Files')}</div></a></li>
379 380 <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>
380 381
381 382 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
382 383 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
383 384 <li class="${h.is_active('showpullrequest', active)}">
384 385 <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)}">
385 386 <div class="menulabel">
386 387 ${_('Pull Requests')} <span class="menulink-counter">${c.repository_pull_requests}</span>
387 388 </div>
388 389 </a>
389 390 </li>
390 391 %endif
391 392
392 393 <li class="${h.is_active('artifacts', active)}">
393 394 <a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}">
394 395 <div class="menulabel">
395 396 ${_('Artifacts')} <span class="menulink-counter">${c.repository_artifacts}</span>
396 397 </div>
397 398 </a>
398 399 </li>
399 400
400 401 %if not c.rhodecode_db_repo.archived and h.HasRepoPermissionAll('repository.admin')(c.repo_name):
401 402 <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>
402 403 %endif
403 404
404 405 <li class="${h.is_active('options', active)}">
405 406 % if has_actions:
406 407 <a class="menulink dropdown">
407 408 <div class="menulabel">${_('Quick Actions')}<div class="show_more"></div></div>
408 409 </a>
409 410 <ul class="submenu">
410 411 %if can_lock:
411 412 %if c.rhodecode_db_repo.locked[0]:
412 413 <li><a class="locking_del" href="${h.route_path('repo_settings_quick_actions',repo_name=c.repo_name, _query={'action': 'toggle-lock', 'set_unlock': 1})}">${_('Unlock Repository')}</a></li>
413 414 %else:
414 415 <li><a class="locking_add" href="${h.route_path('repo_settings_quick_actions',repo_name=c.repo_name, _query={'action': 'toggle-lock', 'set_lock': 1})}">${_('Lock Repository')}</a></li>
415 416 %endif
416 417 %endif
417 418 </ul>
418 419 % endif
419 420 </li>
420 421
421 422 </ul>
422 423 </div>
423 424 <div class="clear"></div>
424 425 </div>
425 426
426 427 <!--- REPO END CONTEXT BAR -->
427 428
428 429 </%def>
429 430
430 431 <%def name="repo_group_page_title(repo_group_instance)">
431 432 <div class="title-content">
432 433 <div class="title-main">
433 434 ## Repository Group icon
434 435 <i class="icon-repo-group"></i>
435 436
436 437 ## repo name with group name
437 438 ${h.breadcrumb_repo_group_link(repo_group_instance)}
438 439 </div>
439 440
440 441 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
441 442 <div class="repo-group-desc discreet">
442 443 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
443 444 </div>
444 445
445 446 </div>
446 447 </%def>
447 448
448 449
449 450 <%def name="repo_group_menu(active=None)">
450 451 <%
451 452 gr_name = c.repo_group.group_name if c.repo_group else None
452 453 # create repositories with write permission on group is set to true
453 454 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
454 455
455 456 %>
456 457
457 458
458 459 <!--- REPO GROUP CONTEXT BAR -->
459 460 <div id="context-bar">
460 461 <div class="wrapper">
461 462 <div class="title">
462 463 ${self.repo_group_page_title(c.repo_group)}
463 464 </div>
464 465
465 466 <ul id="context-pages" class="navigation horizontal-list">
466 467 <li class="${h.is_active('home', active)}">
467 468 <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>
468 469 </li>
469 470 % if c.is_super_admin or group_admin:
470 471 <li class="${h.is_active('settings', active)}">
471 472 <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>
472 473 </li>
473 474 % endif
474 475
475 476 </ul>
476 477 </div>
477 478 <div class="clear"></div>
478 479 </div>
479 480
480 481 <!--- REPO GROUP CONTEXT BAR -->
481 482
482 483 </%def>
483 484
484 485
485 486 <%def name="usermenu(active=False)">
486 487 <%
487 488 not_anonymous = c.rhodecode_user.username != h.DEFAULT_USER
488 489
489 490 gr_name = c.repo_group.group_name if (hasattr(c, 'repo_group') and c.repo_group) else None
490 491 # create repositories with write permission on group is set to true
491 492
492 493 can_fork = c.is_super_admin or h.HasPermissionAny('hg.fork.repository')()
493 494 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
494 495 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
495 496 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
496 497
497 498 can_create_repos = c.is_super_admin or c.can_create_repo
498 499 can_create_repo_groups = c.is_super_admin or c.can_create_repo_group
499 500
500 501 can_create_repos_in_group = c.is_super_admin or group_admin or (group_write and create_on_write)
501 502 can_create_repo_groups_in_group = c.is_super_admin or group_admin
502 503 %>
503 504
504 505 % if not_anonymous:
505 506 <%
506 507 default_target_group = dict()
507 508 if c.rhodecode_user.personal_repo_group:
508 509 default_target_group = dict(parent_group=c.rhodecode_user.personal_repo_group.group_id)
509 510 %>
510 511
511 512 ## create action
512 513 <li>
513 514 <a href="#create-actions" onclick="return false;" class="menulink childs">
514 515 <i class="icon-plus-circled"></i>
515 516 </a>
516 517
517 518 <div class="action-menu submenu">
518 519
519 520 <ol>
520 521 ## scope of within a repository
521 522 % if hasattr(c, 'rhodecode_db_repo') and c.rhodecode_db_repo:
522 523 <li class="submenu-title">${_('This Repository')}</li>
523 524 <li>
524 525 <a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a>
525 526 </li>
526 527 % if can_fork:
527 528 <li>
528 529 <a href="${h.route_path('repo_fork_new',repo_name=c.repo_name,_query=default_target_group)}">${_('Fork this repository')}</a>
529 530 </li>
530 531 % endif
531 532 % endif
532 533
533 534 ## scope of within repository groups
534 535 % if hasattr(c, 'repo_group') and c.repo_group and (can_create_repos_in_group or can_create_repo_groups_in_group):
535 536 <li class="submenu-title">${_('This Repository Group')}</li>
536 537
537 538 % if can_create_repos_in_group:
538 539 <li>
539 540 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('New Repository')}</a>
540 541 </li>
541 542 % endif
542 543
543 544 % if can_create_repo_groups_in_group:
544 545 <li>
545 546 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('New Repository Group')}</a>
546 547 </li>
547 548 % endif
548 549 % endif
549 550
550 551 ## personal group
551 552 % if c.rhodecode_user.personal_repo_group:
552 553 <li class="submenu-title">Personal Group</li>
553 554
554 555 <li>
555 556 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}" >${_('New Repository')} </a>
556 557 </li>
557 558
558 559 <li>
559 560 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}">${_('New Repository Group')} </a>
560 561 </li>
561 562 % endif
562 563
563 564 ## Global actions
564 565 <li class="submenu-title">RhodeCode</li>
565 566 % if can_create_repos:
566 567 <li>
567 568 <a href="${h.route_path('repo_new')}" >${_('New Repository')}</a>
568 569 </li>
569 570 % endif
570 571
571 572 % if can_create_repo_groups:
572 573 <li>
573 574 <a href="${h.route_path('repo_group_new')}" >${_('New Repository Group')}</a>
574 575 </li>
575 576 % endif
576 577
577 578 <li>
578 579 <a href="${h.route_path('gists_new')}">${_('New Gist')}</a>
579 580 </li>
580 581
581 582 </ol>
582 583
583 584 </div>
584 585 </li>
585 586
586 587 ## notifications
587 588 <li>
588 589 <a class="${('empty' if c.unread_notifications == 0 else '')}" href="${h.route_path('notifications_show_all')}">
589 590 ${c.unread_notifications}
590 591 </a>
591 592 </li>
592 593 % endif
593 594
594 595 ## USER MENU
595 596 <li id="quick_login_li" class="${'active' if active else ''}">
596 597 % if c.rhodecode_user.username == h.DEFAULT_USER:
597 598 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
598 599 ${gravatar(c.rhodecode_user.email, 20)}
599 600 <span class="user">
600 601 <span>${_('Sign in')}</span>
601 602 </span>
602 603 </a>
603 604 % else:
604 605 ## logged in user
605 606 <a id="quick_login_link" class="menulink childs">
606 607 ${gravatar(c.rhodecode_user.email, 20)}
607 608 <span class="user">
608 609 <span class="menu_link_user">${c.rhodecode_user.username}</span>
609 610 <div class="show_more"></div>
610 611 </span>
611 612 </a>
612 613 ## subnav with menu for logged in user
613 614 <div class="user-menu submenu">
614 615 <div id="quick_login">
615 616 %if c.rhodecode_user.username != h.DEFAULT_USER:
616 617 <div class="">
617 618 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
618 619 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
619 620 <div class="email">${c.rhodecode_user.email}</div>
620 621 </div>
621 622 <div class="">
622 623 <ol class="links">
623 624 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
624 625 % if c.rhodecode_user.personal_repo_group:
625 626 <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>
626 627 % endif
627 628 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
628 629
629 630 % if c.debug_style:
630 631 <li>
631 632 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
632 633 <div class="menulabel">${_('[Style]')}</div>
633 634 </a>
634 635 </li>
635 636 % endif
636 637
637 638 ## bookmark-items
638 639 <li class="bookmark-items">
639 640 ${_('Bookmarks')}
640 641 <div class="pull-right">
641 642 <a href="${h.route_path('my_account_bookmarks')}">
642 643
643 644 <i class="icon-cog"></i>
644 645 </a>
645 646 </div>
646 647 </li>
647 648 % if not c.bookmark_items:
648 649 <li>
649 650 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
650 651 </li>
651 652 % endif
652 653 % for item in c.bookmark_items:
653 654 <li>
654 655 % if item.repo_id:
655 656 <div>
656 657 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
657 658 <code>${item.position}</code>
658 659 % if item.repo_type == 'hg':
659 660 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
660 661 % elif item.repo_type == 'git':
661 662 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
662 663 % elif item.repo_type == 'svn':
663 664 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
664 665 % endif
665 666 ${(item.title or h.shorter(item.repo_name, 30))}
666 667 </a>
667 668 </div>
668 669 % elif item.group_id:
669 670 <div>
670 671 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
671 672 <code>${item.position}</code>
672 673 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
673 674 ${(item.title or h.shorter(item.group_name, 30))}
674 675 </a>
675 676 </div>
676 677 % else:
677 678 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
678 679 <code>${item.position}</code>
679 680 ${item.title}
680 681 </a>
681 682 % endif
682 683 </li>
683 684 % endfor
684 685
685 686 <li class="logout">
686 687 ${h.secure_form(h.route_path('logout'), request=request)}
687 688 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
688 689 ${h.end_form()}
689 690 </li>
690 691 </ol>
691 692 </div>
692 693 %endif
693 694 </div>
694 695 </div>
695 696
696 697 % endif
697 698 </li>
698 699 </%def>
699 700
700 701 <%def name="menu_items(active=None)">
701 702 <%
702 703 notice_messages, notice_level = c.rhodecode_user.get_notice_messages()
703 704 notice_display = 'none' if len(notice_messages) == 0 else ''
704 705 %>
705 706
706 707 <ul id="quick" class="main_nav navigation horizontal-list">
707 708 ## notice box for important system messages
708 709 <li style="display: ${notice_display}">
709 710 <a class="notice-box" href="#openNotice" onclick="$('.notice-messages-container').toggle(); return false">
710 711 <div class="menulabel-notice ${notice_level}" >
711 712 ${len(notice_messages)}
712 713 </div>
713 714 </a>
714 715 </li>
715 716 <div class="notice-messages-container" style="display: none">
716 717 <div class="notice-messages">
717 718 <table class="rctable">
718 719 % for notice in notice_messages:
719 720 <tr id="notice-message-${notice['msg_id']}" class="notice-message-${notice['level']}">
720 721 <td style="vertical-align: text-top; width: 20px">
721 722 <i class="tooltip icon-info notice-color-${notice['level']}" title="${notice['level']}"></i>
722 723 </td>
723 724 <td>
724 725 <span><i class="icon-plus-squared cursor-pointer" onclick="$('#notice-${notice['msg_id']}').toggle()"></i> </span>
725 726 ${notice['subject']}
726 727
727 728 <div id="notice-${notice['msg_id']}" style="display: none">
728 729 ${h.render(notice['body'], renderer='markdown')}
729 730 </div>
730 731 </td>
731 732 <td style="vertical-align: text-top; width: 35px;">
732 733 <a class="tooltip" title="${_('dismiss')}" href="#dismiss" onclick="dismissNotice(${notice['msg_id']});return false">
733 734 <i class="icon-remove icon-filled-red"></i>
734 735 </a>
735 736 </td>
736 737 </tr>
737 738
738 739 % endfor
739 740 </table>
740 741 </div>
741 742 </div>
742 743 ## Main filter
743 744 <li>
744 745 <div class="menulabel main_filter_box">
745 746 <div class="main_filter_input_box">
746 747 <ul class="searchItems">
747 748
748 749 <li class="searchTag searchTagIcon">
749 750 <i class="icon-search"></i>
750 751 </li>
751 752
752 753 % if c.template_context['search_context']['repo_id']:
753 754 <li class="searchTag searchTagFilter searchTagHidable" >
754 755 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
755 756 <span class="tag">
756 757 This repo
757 758 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
758 759 </span>
759 760 ##</a>
760 761 </li>
761 762 % elif c.template_context['search_context']['repo_group_id']:
762 763 <li class="searchTag searchTagFilter searchTagHidable">
763 764 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
764 765 <span class="tag">
765 766 This group
766 767 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
767 768 </span>
768 769 ##</a>
769 770 </li>
770 771 % endif
771 772
772 773 <li class="searchTagInput">
773 774 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
774 775 </li>
775 776 <li class="searchTag searchTagHelp">
776 777 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
777 778 </li>
778 779 </ul>
779 780 </div>
780 781 </div>
781 782
782 783 <div id="main_filter_help" style="display: none">
783 784 - Use '/' key to quickly access this field.
784 785
785 786 - Enter a name of repository, or repository group for quick search.
786 787
787 788 - Prefix query to allow special search:
788 789
789 790 <strong>user:</strong>admin, to search for usernames, always global
790 791
791 792 <strong>user_group:</strong>devops, to search for user groups, always global
792 793
793 794 <strong>pr:</strong>303, to search for pull request number, title, or description, always global
794 795
795 796 <strong>commit:</strong>efced4, to search for commits, scoped to repositories or groups
796 797
797 798 <strong>file:</strong>models.py, to search for file paths, scoped to repositories or groups
798 799
799 800 % if c.template_context['search_context']['repo_id']:
800 801 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>
801 802 % elif c.template_context['search_context']['repo_group_id']:
802 803 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>
803 804 % else:
804 805 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
805 806 % endif
806 807 </div>
807 808 </li>
808 809
809 810 ## ROOT MENU
810 811 <li class="${h.is_active('home', active)}">
811 812 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
812 813 <div class="menulabel">${_('Home')}</div>
813 814 </a>
814 815 </li>
815 816
816 817 %if c.rhodecode_user.username != h.DEFAULT_USER:
817 818 <li class="${h.is_active('journal', active)}">
818 819 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
819 820 <div class="menulabel">${_('Journal')}</div>
820 821 </a>
821 822 </li>
822 823 %else:
823 824 <li class="${h.is_active('journal', active)}">
824 825 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
825 826 <div class="menulabel">${_('Public journal')}</div>
826 827 </a>
827 828 </li>
828 829 %endif
829 830
830 831 <li class="${h.is_active('gists', active)}">
831 832 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
832 833 <div class="menulabel">${_('Gists')}</div>
833 834 </a>
834 835 </li>
835 836
836 837 % if c.is_super_admin or c.is_delegated_admin:
837 838 <li class="${h.is_active('admin', active)}">
838 839 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
839 840 <div class="menulabel">${_('Admin')} </div>
840 841 </a>
841 842 </li>
842 843 % endif
843 844
844 845 ## render extra user menu
845 846 ${usermenu(active=(active=='my_account'))}
846 847
847 848 </ul>
848 849
849 850 <script type="text/javascript">
850 851 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
851 852
852 853 var formatRepoResult = function(result, container, query, escapeMarkup) {
853 854 return function(data, escapeMarkup) {
854 855 if (!data.repo_id){
855 856 return data.text; // optgroup text Repositories
856 857 }
857 858
858 859 var tmpl = '';
859 860 var repoType = data['repo_type'];
860 861 var repoName = data['text'];
861 862
862 863 if(data && data.type == 'repo'){
863 864 if(repoType === 'hg'){
864 865 tmpl += '<i class="icon-hg"></i> ';
865 866 }
866 867 else if(repoType === 'git'){
867 868 tmpl += '<i class="icon-git"></i> ';
868 869 }
869 870 else if(repoType === 'svn'){
870 871 tmpl += '<i class="icon-svn"></i> ';
871 872 }
872 873 if(data['private']){
873 874 tmpl += '<i class="icon-lock" ></i> ';
874 875 }
875 876 else if(visualShowPublicIcon){
876 877 tmpl += '<i class="icon-unlock-alt"></i> ';
877 878 }
878 879 }
879 880 tmpl += escapeMarkup(repoName);
880 881 return tmpl;
881 882
882 883 }(result, escapeMarkup);
883 884 };
884 885
885 886 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
886 887 return function(data, escapeMarkup) {
887 888 if (!data.repo_group_id){
888 889 return data.text; // optgroup text Repositories
889 890 }
890 891
891 892 var tmpl = '';
892 893 var repoGroupName = data['text'];
893 894
894 895 if(data){
895 896
896 897 tmpl += '<i class="icon-repo-group"></i> ';
897 898
898 899 }
899 900 tmpl += escapeMarkup(repoGroupName);
900 901 return tmpl;
901 902
902 903 }(result, escapeMarkup);
903 904 };
904 905
905 906 var escapeRegExChars = function (value) {
906 907 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
907 908 };
908 909
909 910 var getRepoIcon = function(repo_type) {
910 911 if (repo_type === 'hg') {
911 912 return '<i class="icon-hg"></i> ';
912 913 }
913 914 else if (repo_type === 'git') {
914 915 return '<i class="icon-git"></i> ';
915 916 }
916 917 else if (repo_type === 'svn') {
917 918 return '<i class="icon-svn"></i> ';
918 919 }
919 920 return ''
920 921 };
921 922
922 923 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
923 924
924 925 if (value.split(':').length === 2) {
925 926 value = value.split(':')[1]
926 927 }
927 928
928 929 var searchType = data['type'];
929 930 var searchSubType = data['subtype'];
930 931 var valueDisplay = data['value_display'];
931 932 var valueIcon = data['value_icon'];
932 933
933 934 var pattern = '(' + escapeRegExChars(value) + ')';
934 935
935 936 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
936 937
937 938 // highlight match
938 939 if (searchType != 'text') {
939 940 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
940 941 }
941 942
942 943 var icon = '';
943 944
944 945 if (searchType === 'hint') {
945 946 icon += '<i class="icon-repo-group"></i> ';
946 947 }
947 948 // full text search/hints
948 949 else if (searchType === 'search') {
949 950 if (valueIcon === undefined) {
950 951 icon += '<i class="icon-more"></i> ';
951 952 } else {
952 953 icon += valueIcon + ' ';
953 954 }
954 955
955 956 if (searchSubType !== undefined && searchSubType == 'repo') {
956 957 valueDisplay += '<div class="pull-right tag">repository</div>';
957 958 }
958 959 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
959 960 valueDisplay += '<div class="pull-right tag">repo group</div>';
960 961 }
961 962 }
962 963 // repository
963 964 else if (searchType === 'repo') {
964 965
965 966 var repoIcon = getRepoIcon(data['repo_type']);
966 967 icon += repoIcon;
967 968
968 969 if (data['private']) {
969 970 icon += '<i class="icon-lock" ></i> ';
970 971 }
971 972 else if (visualShowPublicIcon) {
972 973 icon += '<i class="icon-unlock-alt"></i> ';
973 974 }
974 975 }
975 976 // repository groups
976 977 else if (searchType === 'repo_group') {
977 978 icon += '<i class="icon-repo-group"></i> ';
978 979 }
979 980 // user group
980 981 else if (searchType === 'user_group') {
981 982 icon += '<i class="icon-group"></i> ';
982 983 }
983 984 // user
984 985 else if (searchType === 'user') {
985 986 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
986 987 }
987 988 // pull request
988 989 else if (searchType === 'pull_request') {
989 990 icon += '<i class="icon-merge"></i> ';
990 991 }
991 992 // commit
992 993 else if (searchType === 'commit') {
993 994 var repo_data = data['repo_data'];
994 995 var repoIcon = getRepoIcon(repo_data['repository_type']);
995 996 if (repoIcon) {
996 997 icon += repoIcon;
997 998 } else {
998 999 icon += '<i class="icon-tag"></i>';
999 1000 }
1000 1001 }
1001 1002 // file
1002 1003 else if (searchType === 'file') {
1003 1004 var repo_data = data['repo_data'];
1004 1005 var repoIcon = getRepoIcon(repo_data['repository_type']);
1005 1006 if (repoIcon) {
1006 1007 icon += repoIcon;
1007 1008 } else {
1008 1009 icon += '<i class="icon-tag"></i>';
1009 1010 }
1010 1011 }
1011 1012 // generic text
1012 1013 else if (searchType === 'text') {
1013 1014 icon = '';
1014 1015 }
1015 1016
1016 1017 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
1017 1018 return tmpl.format(icon, valueDisplay);
1018 1019 };
1019 1020
1020 1021 var handleSelect = function(element, suggestion) {
1021 1022 if (suggestion.type === "hint") {
1022 1023 // we skip action
1023 1024 $('#main_filter').focus();
1024 1025 }
1025 1026 else if (suggestion.type === "text") {
1026 1027 // we skip action
1027 1028 $('#main_filter').focus();
1028 1029
1029 1030 } else {
1030 1031 window.location = suggestion['url'];
1031 1032 }
1032 1033 };
1033 1034
1034 1035 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
1035 1036 if (queryLowerCase.split(':').length === 2) {
1036 1037 queryLowerCase = queryLowerCase.split(':')[1]
1037 1038 }
1038 1039 if (suggestion.type === "text") {
1039 1040 // special case we don't want to "skip" display for
1040 1041 return true
1041 1042 }
1042 1043 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
1043 1044 };
1044 1045
1045 1046 var cleanContext = {
1046 1047 repo_view_type: null,
1047 1048
1048 1049 repo_id: null,
1049 1050 repo_name: "",
1050 1051
1051 1052 repo_group_id: null,
1052 1053 repo_group_name: null
1053 1054 };
1054 1055 var removeGoToFilter = function () {
1055 1056 $('.searchTagHidable').hide();
1056 1057 $('#main_filter').autocomplete(
1057 1058 'setOptions', {params:{search_context: cleanContext}});
1058 1059 };
1059 1060
1060 1061 $('#main_filter').autocomplete({
1061 1062 serviceUrl: pyroutes.url('goto_switcher_data'),
1062 1063 params: {
1063 1064 "search_context": templateContext.search_context
1064 1065 },
1065 1066 minChars:2,
1066 1067 maxHeight:400,
1067 1068 deferRequestBy: 300, //miliseconds
1068 1069 tabDisabled: true,
1069 1070 autoSelectFirst: false,
1070 1071 containerClass: 'autocomplete-qfilter-suggestions',
1071 1072 formatResult: autocompleteMainFilterFormatResult,
1072 1073 lookupFilter: autocompleteMainFilterResult,
1073 1074 onSelect: function (element, suggestion) {
1074 1075 handleSelect(element, suggestion);
1075 1076 return false;
1076 1077 },
1077 1078 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
1078 1079 if (jqXHR !== 'abort') {
1079 1080 var message = formatErrorMessage(jqXHR, textStatus, errorThrown);
1080 1081 SwalNoAnimation.fire({
1081 1082 icon: 'error',
1082 1083 title: _gettext('Error during search operation'),
1083 1084 html: '<span style="white-space: pre-line">{0}</span>'.format(message),
1084 1085 }).then(function(result) {
1085 1086 window.location.reload();
1086 1087 })
1087 1088 }
1088 1089 },
1089 1090 onSearchStart: function (params) {
1090 1091 $('.searchTag.searchTagIcon').html('<i class="icon-spin animate-spin"></i>')
1091 1092 },
1092 1093 onSearchComplete: function (query, suggestions) {
1093 1094 $('.searchTag.searchTagIcon').html('<i class="icon-search"></i>')
1094 1095 },
1095 1096 });
1096 1097
1097 1098 showMainFilterBox = function () {
1098 1099 $('#main_filter_help').toggle();
1099 1100 };
1100 1101
1101 1102 $('#main_filter').on('keydown.autocomplete', function (e) {
1102 1103
1103 1104 var BACKSPACE = 8;
1104 1105 var el = $(e.currentTarget);
1105 1106 if(e.which === BACKSPACE){
1106 1107 var inputVal = el.val();
1107 1108 if (inputVal === ""){
1108 1109 removeGoToFilter()
1109 1110 }
1110 1111 }
1111 1112 });
1112 1113
1113 1114 var dismissNotice = function(noticeId) {
1114 1115
1115 1116 var url = pyroutes.url('user_notice_dismiss',
1116 1117 {"user_id": templateContext.rhodecode_user.user_id});
1117 1118
1118 1119 var postData = {
1119 1120 'csrf_token': CSRF_TOKEN,
1120 1121 'notice_id': noticeId,
1121 1122 };
1122 1123
1123 1124 var success = function(response) {
1124 1125 $('#notice-message-' + noticeId).remove();
1125 1126 return false;
1126 1127 };
1127 1128 var failure = function(data, textStatus, xhr) {
1128 1129 alert("error processing request: " + textStatus);
1129 1130 return false;
1130 1131 };
1131 1132 ajaxPOST(url, postData, success, failure);
1132 1133 }
1133 1134
1134 1135 var hideLicenseWarning = function () {
1135 1136 var fingerprint = templateContext.session_attrs.license_fingerprint;
1136 1137 storeUserSessionAttr('rc_user_session_attr.hide_license_warning', fingerprint);
1137 1138 $('#notifications').hide();
1138 1139 }
1139 1140
1140 1141 var hideLicenseError = function () {
1141 1142 var fingerprint = templateContext.session_attrs.license_fingerprint;
1142 1143 storeUserSessionAttr('rc_user_session_attr.hide_license_error', fingerprint);
1143 1144 $('#notifications').hide();
1144 1145 }
1145 1146
1146 1147 </script>
1147 1148 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
1148 1149 </%def>
1149 1150
1150 1151 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
1151 1152 <div class="modal-dialog">
1152 1153 <div class="modal-content">
1153 1154 <div class="modal-header">
1154 1155 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
1155 1156 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
1156 1157 </div>
1157 1158 <div class="modal-body">
1158 1159 <div class="block-left">
1159 1160 <table class="keyboard-mappings">
1160 1161 <tbody>
1161 1162 <tr>
1162 1163 <th></th>
1163 1164 <th>${_('Site-wide shortcuts')}</th>
1164 1165 </tr>
1165 1166 <%
1166 1167 elems = [
1167 1168 ('/', 'Use quick search box'),
1168 1169 ('g h', 'Goto home page'),
1169 1170 ('g g', 'Goto my private gists page'),
1170 1171 ('g G', 'Goto my public gists page'),
1171 1172 ('g 0-9', 'Goto bookmarked items from 0-9'),
1172 1173 ('n r', 'New repository page'),
1173 1174 ('n g', 'New gist page'),
1174 1175 ]
1175 1176 %>
1176 1177 %for key, desc in elems:
1177 1178 <tr>
1178 1179 <td class="keys">
1179 1180 <span class="key tag">${key}</span>
1180 1181 </td>
1181 1182 <td>${desc}</td>
1182 1183 </tr>
1183 1184 %endfor
1184 1185 </tbody>
1185 1186 </table>
1186 1187 </div>
1187 1188 <div class="block-left">
1188 1189 <table class="keyboard-mappings">
1189 1190 <tbody>
1190 1191 <tr>
1191 1192 <th></th>
1192 1193 <th>${_('Repositories')}</th>
1193 1194 </tr>
1194 1195 <%
1195 1196 elems = [
1196 1197 ('g s', 'Goto summary page'),
1197 1198 ('g c', 'Goto changelog page'),
1198 1199 ('g f', 'Goto files page'),
1199 1200 ('g F', 'Goto files page with file search activated'),
1200 1201 ('g p', 'Goto pull requests page'),
1201 1202 ('g o', 'Goto repository settings'),
1202 1203 ('g O', 'Goto repository access permissions settings'),
1203 1204 ('t s', 'Toggle sidebar on some pages'),
1204 1205 ]
1205 1206 %>
1206 1207 %for key, desc in elems:
1207 1208 <tr>
1208 1209 <td class="keys">
1209 1210 <span class="key tag">${key}</span>
1210 1211 </td>
1211 1212 <td>${desc}</td>
1212 1213 </tr>
1213 1214 %endfor
1214 1215 </tbody>
1215 1216 </table>
1216 1217 </div>
1217 1218 </div>
1218 1219 <div class="modal-footer">
1219 1220 </div>
1220 1221 </div><!-- /.modal-content -->
1221 1222 </div><!-- /.modal-dialog -->
1222 1223 </div><!-- /.modal -->
1223 1224
1224 1225
1225 1226 <script type="text/javascript">
1226 1227 (function () {
1227 1228 "use sctrict";
1228 1229
1229 1230 // details block auto-hide menu
1230 1231 $(document).mouseup(function(e) {
1231 1232 var container = $('.details-inline-block');
1232 1233 if (!container.is(e.target) && container.has(e.target).length === 0) {
1233 1234 $('.details-inline-block[open]').removeAttr('open')
1234 1235 }
1235 1236 });
1236 1237
1237 1238 var $sideBar = $('.right-sidebar');
1238 1239 var expanded = $sideBar.hasClass('right-sidebar-expanded');
1239 1240 var sidebarState = templateContext.session_attrs.sidebarState;
1240 1241 var sidebarEnabled = $('aside.right-sidebar').get(0);
1241 1242
1242 1243 if (sidebarState === 'expanded') {
1243 1244 expanded = true
1244 1245 } else if (sidebarState === 'collapsed') {
1245 1246 expanded = false
1246 1247 }
1247 1248 if (sidebarEnabled) {
1248 1249 // show sidebar since it's hidden on load
1249 1250 $('.right-sidebar').show();
1250 1251
1251 1252 // init based on set initial class, or if defined user session attrs
1252 1253 if (expanded) {
1253 1254 window.expandSidebar();
1254 1255 window.updateStickyHeader();
1255 1256
1256 1257 } else {
1257 1258 window.collapseSidebar();
1258 1259 window.updateStickyHeader();
1259 1260 }
1260 1261 }
1261 1262 })()
1262 1263
1263 1264 </script>
General Comments 0
You need to be logged in to leave comments. Login now