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