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