##// END OF EJS Templates
templates: removed utf8 marker for python3 migration
super-admin -
r5037:bd722d6e default
parent child Browse files
Show More
@@ -1,115 +1,114 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2 <%namespace name="base" file="/base/base.mako"/>
4 3
5 4 <%def name="title()">
6 5 ${_('Admin audit log entry')}
7 6 %if c.rhodecode_name:
8 7 &middot; ${h.branding(c.rhodecode_name)}
9 8 %endif
10 9 </%def>
11 10
12 11 <%def name="breadcrumbs_links()"></%def>
13 12
14 13 <%def name="menu_bar_nav()">
15 14 ${self.menu_items(active='admin')}
16 15 </%def>
17 16
18 17 <%def name="menu_bar_subnav()">
19 18 ${self.admin_menu(active='audit_logs')}
20 19 </%def>
21 20
22 21 <%def name="main()">
23 22 <div class="box">
24 23
25 24 <div class="title">
26 25 ${_('Audit long entry')} ${c.audit_log_entry.entry_id}
27 26 </div>
28 27
29 28 <div class="table">
30 29 <div id="user_log">
31 30 <table class="rctable audit-log">
32 31 <tr>
33 32 <td>
34 33 ${_('User')}:
35 34 </td>
36 35 <td>
37 36 %if c.audit_log_entry.user is not None:
38 37 ${base.gravatar_with_user(c.audit_log_entry.user.email)}
39 38 %else:
40 39 ${c.audit_log_entry.username}
41 40 %endif
42 41 </td>
43 42 </tr>
44 43 <tr>
45 44 <td>
46 45 ${_('Date')}:
47 46 </td>
48 47 <td>
49 48 ${h.format_date(c.audit_log_entry.action_date)}
50 49 </td>
51 50 </tr>
52 51 <tr>
53 52 <td>
54 53 ${_('IP')}:
55 54 </td>
56 55 <td>
57 56 ${c.audit_log_entry.user_ip}
58 57 </td>
59 58 </tr>
60 59
61 60 <tr>
62 61 <td>
63 62 ${_('Action')}:
64 63 </td>
65 64 <td>
66 65 % if c.audit_log_entry.version == c.audit_log_entry.VERSION_1:
67 66 ${h.action_parser(request, l)[0]()}
68 67 % else:
69 68 ${h.literal(c.audit_log_entry.action)}
70 69 % endif
71 70
72 71 <div class="journal_action_params">
73 72 % if c.audit_log_entry.version == c.audit_log_entry.VERSION_1:
74 73 ${h.literal(h.action_parser(request, l)[1]())}
75 74 % endif
76 75 </div>
77 76 </td>
78 77 </tr>
79 78 <tr>
80 79 <td>
81 80 ${_('Action Data')}:
82 81 </td>
83 82 <td class="td-journalaction">
84 83 % if c.audit_log_entry.version == c.audit_log_entry.VERSION_2:
85 84 <div>
86 85 <pre>${h.formatted_str_json(c.audit_log_entry.action_data)}</pre>
87 86 </div>
88 87 % else:
89 88 <pre title="${_('data not available for v1 entries type')}">-</pre>
90 89 % endif
91 90 </td>
92 91 </tr>
93 92 <tr>
94 93 <td>
95 94 ${_('Repository')}:
96 95 </td>
97 96 <td class="td-journalaction">
98 97 %if c.audit_log_entry.repository is not None:
99 98 ${h.link_to(c.audit_log_entry.repository.repo_name, h.route_path('repo_summary',repo_name=c.audit_log_entry.repository.repo_name))}
100 99 %else:
101 100 ${c.audit_log_entry.repository_name or '-'}
102 101 %endif
103 102 </td>
104 103 </tr>
105 104
106 105 </table>
107 106
108 107 </div>
109 108 </div>
110 109 </div>
111 110
112 111 <script>
113 112 $('#j_filter').autoGrowInput();
114 113 </script>
115 114 </%def>
@@ -1,43 +1,42 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Admin audit logs')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='admin')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.admin_menu(active='audit_logs')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21 <div class="box">
23 22 <div class="title">
24 23 ${h.form(None, id_="filter_form", method="get")}
25 24 <input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or ''}" placeholder="${_('filter...')}"/>
26 25 <input type='submit' value="${_('filter')}" class="btn" />
27 26 ${_('Audit logs')} - ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
28 27 ${h.end_form()}
29 28 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
30 29 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
31 30 </div>
32 31
33 32 <div class="table">
34 33 <div id="user_log">
35 34 <%include file="/admin/admin_log_base.mako" />
36 35 </div>
37 36 </div>
38 37 </div>
39 38
40 39 <script>
41 40 $('#j_filter').autoGrowInput();
42 41 </script>
43 42 </%def>
@@ -1,39 +1,38 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Artifacts Admin')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='admin')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.admin_menu(active='artifacts')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21
23 22 <div class="box">
24 23
25 24 <div class="panel panel-default">
26 25 <div class="panel-heading">
27 26 <h3 class="panel-title">${_('Artifacts Administration.')}</h3>
28 27 </div>
29 28 <div class="panel-body">
30 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>
31 30
32 31 </div>
33 32 </div>
34 33
35 34 </div>
36 35
37 36
38 37 </%def>
39 38
@@ -1,123 +1,122 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Authentication Settings')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='admin')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.admin_menu(active='authentication')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21
23 22 <div class="box">
24 23
25 24 <div class='sidebar-col-wrapper'>
26 25
27 26 <div class="sidebar">
28 27 <ul class="nav nav-pills nav-stacked">
29 28 % for item in resource.get_root().get_nav_list():
30 29 <li ${('class=active' if item == resource else '')}>
31 30 <a href="${request.resource_path(item, route_name='auth_home')}">${item.display_name}</a>
32 31 </li>
33 32 % endfor
34 33 </ul>
35 34 </div>
36 35
37 36 <div class="main-content-full-width">
38 37 ${h.secure_form(request.resource_path(resource, route_name='auth_home'), request=request)}
39 38 <div class="panel panel-default">
40 39
41 40 <div class="panel-heading">
42 41 <h3 class="panel-title">${_("Enabled and Available Plugins")}</h3>
43 42 </div>
44 43
45 44 <div class="panel-body">
46 45
47 46
48 47 <div class="label">${_("Ordered Activated Plugins")}</div>
49 48 <div class="textarea text-area editor">
50 49 ${h.textarea('auth_plugins',cols=120,rows=20,class_="medium")}
51 50 </div>
52 51 <div class="field">
53 52 <p class="help-block pre-formatting">${_('List of plugins, separated by commas.'
54 53 '\nThe order of the plugins is also the order in which '
55 54 'RhodeCode Enterprise will try to authenticate a user.')}
56 55 </p>
57 56 </div>
58 57
59 58 <table class="rctable">
60 59 <th>${_('Activate')}</th>
61 60 <th>${_('Plugin Name')}</th>
62 61 <th>${_('Documentation')}</th>
63 62 <th>${_('Plugin ID')}</th>
64 63 <th>${_('Enabled')}</th>
65 64 %for plugin in available_plugins:
66 65 <tr class="${('inactive' if (not plugin.is_active() and plugin.get_id() in enabled_plugins) else '')}">
67 66 <td>
68 67 <span plugin_id="${plugin.get_id()}" class="toggle-plugin btn ${('btn-success' if plugin.get_id() in enabled_plugins else '')}">
69 68 ${(_('activated') if plugin.get_id() in enabled_plugins else _('not active'))}
70 69 </span>
71 70 </td>
72 71 <td>${plugin.get_display_name()}</td>
73 72 <td>
74 73 % if plugin.docs():
75 74 <a href="${plugin.docs()}">docs</a>
76 75 % endif
77 76 </td>
78 77 <td>${plugin.get_id()}</td>
79 78 <td>${h.bool2icon(plugin.is_active(),show_at_false=False)}</td>
80 79 </tr>
81 80 %endfor
82 81 </table>
83 82
84 83 <div class="buttons">
85 84 ${h.submit('save',_('Save'),class_="btn")}
86 85 </div>
87 86 </div>
88 87 </div>
89 88 ${h.end_form()}
90 89 </div>
91 90 </div>
92 91 </div>
93 92
94 93 <script>
95 94 $('.toggle-plugin').click(function(e){
96 95 var auth_plugins_input = $('#auth_plugins');
97 96 var elems = [];
98 97
99 98 $.each(auth_plugins_input.val().split(',') , function (index, element) {
100 99 if (element !== "") {
101 100 elems.push(element.strip())
102 101 }
103 102 });
104 103
105 104 var cur_button = e.currentTarget;
106 105 var plugin_id = $(cur_button).attr('plugin_id');
107 106 if($(cur_button).hasClass('btn-success')){
108 107 elems.splice(elems.indexOf(plugin_id), 1);
109 108 auth_plugins_input.val(elems.join(',\n'));
110 109 $(cur_button).removeClass('btn-success');
111 110 cur_button.innerHTML = _gettext('not active');
112 111 }
113 112 else{
114 113 if (elems.indexOf(plugin_id) === -1) {
115 114 elems.push(plugin_id);
116 115 }
117 116 auth_plugins_input.val(elems.join(',\n'));
118 117 $(cur_button).addClass('btn-success');
119 118 cur_button.innerHTML = _gettext('activated');
120 119 }
121 120 });
122 121 </script>
123 122 </%def>
@@ -1,135 +1,134 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Authentication Settings')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 12 &raquo;
14 13 ${h.link_to(_('Authentication Plugins'),request.resource_path(resource.__parent__, route_name='auth_home'))}
15 14 &raquo;
16 15 ${resource.display_name}
17 16 </%def>
18 17
19 18 <%def name="menu_bar_nav()">
20 19 ${self.menu_items(active='admin')}
21 20 </%def>
22 21
23 22 <%def name="menu_bar_subnav()">
24 23 ${self.admin_menu(active='authentication')}
25 24 </%def>
26 25
27 26 <%def name="main()">
28 27
29 28 <div class="box">
30 29
31 30 <div class='sidebar-col-wrapper'>
32 31
33 32 <div class="sidebar">
34 33 <ul class="nav nav-pills nav-stacked">
35 34 % for item in resource.get_root().get_nav_list():
36 35 <li ${('class=active' if item == resource else '')}>
37 36 <a href="${request.resource_path(item, route_name='auth_home')}">${item.display_name}</a>
38 37 </li>
39 38 % endfor
40 39 </ul>
41 40 </div>
42 41
43 42 <div class="main-content-full-width">
44 43 <div class="panel panel-default">
45 44 <div class="panel-heading">
46 45 <h3 class="panel-title">${_('Plugin')}: ${resource.display_name}</h3>
47 46 </div>
48 47 <div class="panel-body">
49 48 <div class="plugin_form">
50 49 <div class="fields">
51 50 ${h.secure_form(request.resource_path(resource, route_name='auth_home'), request=request)}
52 51 <div class="form">
53 52
54 53 %for node in plugin.get_settings_schema():
55 54 <%
56 55 label_to_type = {'label-checkbox': 'bool', 'label-textarea': 'textarea'}
57 56 %>
58 57
59 58 <div class="field">
60 59 <div class="label ${label_to_type.get(node.widget)}"><label for="${node.name}">${node.title}</label></div>
61 60 <div class="input">
62 61 %if node.widget in ["string", "int", "unicode"]:
63 62 ${h.text(node.name, defaults.get(node.name), class_="large")}
64 63 %elif node.widget == "password":
65 64 ${h.password(node.name, defaults.get(node.name), class_="large")}
66 65 %elif node.widget == "bool":
67 66 <div class="checkbox">${h.checkbox(node.name, True, checked=defaults.get(node.name))}</div>
68 67 %elif node.widget == "select":
69 68 ${h.select(node.name, defaults.get(node.name), node.validator.choices, class_="select2AuthSetting")}
70 69 %elif node.widget == "select_with_labels":
71 70 ${h.select(node.name, defaults.get(node.name), node.choices, class_="select2AuthSetting")}
72 71 %elif node.widget == "textarea":
73 72 <div class="textarea" style="margin-left: 0px">${h.textarea(node.name, defaults.get(node.name), rows=10)}</div>
74 73 %elif node.widget == "readonly":
75 74 ${node.default}
76 75 %else:
77 76 This field is of type ${node.typ}, which cannot be displayed. Must be one of [string|int|bool|select].
78 77 %endif
79 78
80 79 %if node.name in errors:
81 80 <span class="error-message">${errors.get(node.name)}</span>
82 81 <br />
83 82 %endif
84 83 <p class="help-block pre-formatting">${node.description}</p>
85 84 </div>
86 85 </div>
87 86 %endfor
88 87
89 88 ## Allow derived templates to add something below the form
90 89 ## input fields
91 90 %if hasattr(next, 'below_form_fields'):
92 91 ${next.below_form_fields()}
93 92 %endif
94 93
95 94 <div class="buttons">
96 95 ${h.submit('save',_('Save'),class_="btn")}
97 96 </div>
98 97
99 98 </div>
100 99 ${h.end_form()}
101 100 </div>
102 101 </div>
103 102
104 103 % if request.GET.get('schema'):
105 104 ## this is for development and creation of example configurations for documentation
106 105 <pre>
107 106 % for node in plugin.get_settings_schema():
108 107 *option*: `${node.name}` => `${defaults.get(node.name)}`${'\n # '.join(['']+node.description.splitlines())}
109 108
110 109 % endfor
111 110 </pre>
112 111
113 112 % endif
114 113
115 114 </div>
116 115 </div>
117 116 </div>
118 117
119 118 </div>
120 119 </div>
121 120
122 121
123 122 <script>
124 123 $(document).ready(function() {
125 124 var select2Options = {
126 125 containerCssClass: 'drop-menu',
127 126 dropdownCssClass: 'drop-menu-dropdown',
128 127 dropdownAutoWidth: true,
129 128 minimumResultsForSearch: -1
130 129 };
131 130 $('.select2AuthSetting').select2(select2Options);
132 131
133 132 });
134 133 </script>
135 134 </%def>
@@ -1,43 +1,42 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Repositories defaults')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 12 &raquo;
14 13 ${_('Repositories defaults')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_nav()">
18 17 ${self.menu_items(active='admin')}
19 18 </%def>
20 19
21 20 <%def name="menu_bar_subnav()">
22 21 ${self.admin_menu(active='defaults')}
23 22 </%def>
24 23
25 24 <%def name="main()">
26 25 <div class="box">
27 26
28 27 ##main
29 28 <div class="sidebar-col-wrapper">
30 29 <div class="sidebar">
31 30 <ul class="nav nav-pills nav-stacked">
32 31 <li class="${h.is_active('repositories', c.active)}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Repository')}</a></li>
33 32 </ul>
34 33 </div>
35 34
36 35 <div class="main-content-full-width">
37 36 <%include file="/admin/defaults/defaults_${c.active}.mako"/>
38 37 </div>
39 38
40 39 </div>
41 40 </div>
42 41
43 42 </%def>
@@ -1,137 +1,136 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Edit Gist')} &middot; ${c.gist.gist_access_id}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='gists')}
15 14 </%def>
16 15
17 16 <%def name="main()">
18 17 <div class="box">
19 18 <!-- box / title -->
20 19 <div class="title">
21 20
22 21 </div>
23 22
24 23 <div class="table">
25 24 <div id="files_data">
26 25 ${h.secure_form(h.route_path('gist_update', gist_id=c.gist.gist_access_id), id='eform', request=request)}
27 26 <div>
28 27 <input type="hidden" value="${c.file_last_commit.raw_id}" name="parent_hash">
29 28 <div>
30 29 <span class="gist-gravatar">
31 30 ${self.gravatar(h.email_or_none(c.rhodecode_user.full_contact), 30)}
32 31 </span>
33 32 <label for='lifetime'>${_('Gist lifetime')}</label>
34 33 ${h.dropdownmenu('lifetime', '0', c.lifetime_options)}
35 34
36 35 <label for='gist_acl_level'>${_('Gist access level')}</label>
37 36 ${h.dropdownmenu('gist_acl_level', c.gist.acl_level, c.acl_options)}
38 37
39 38 <textarea style="margin-top: 5px; border-color: #dbd9da" id="description" name="description"
40 39 placeholder="${_('Gist description ...')}">${c.gist.gist_description}</textarea>
41 40 </div>
42 41 </div>
43 42
44 43 ## peppercorn schema
45 44 <input type="hidden" name="__start__" value="nodes:sequence"/>
46 45 % for cnt, file in enumerate(c.files):
47 46 <input type="hidden" name="__start__" value="file:mapping"/>
48 47 <div id="codeblock" class="codeblock" >
49 48 <div class="code-header">
50 49 <div class="form">
51 50 <div class="fields">
52 51 <input type="hidden" name="filename_org" value="${file.path}" >
53 52 <input id="filename_${h.FID('f',file.path)}" name="filename" size="30" type="text" value="${file.path}">
54 53 ${h.dropdownmenu('mimetype' ,'plain',[('plain',_('plain'))],enable_filter=True, id='mimetype_'+h.FID('f',file.path))}
55 54 </div>
56 55 </div>
57 56 </div>
58 57 <div class="editor_container">
59 58 <pre id="editor_pre"></pre>
60 59 <textarea id="editor_${h.FID('f',file.path)}" name="content" >${file.content}</textarea>
61 60 </div>
62 61 </div>
63 62 <input type="hidden" name="__end__" />
64 63
65 64 ## dynamic edit box.
66 65 <script type="text/javascript">
67 66 $(document).ready(function(){
68 67 var myCodeMirror = initCodeMirror(
69 68 "editor_${h.FID('f',file.path)}", '');
70 69
71 70 var modes_select = $("#mimetype_${h.FID('f',file.path)}");
72 71 fillCodeMirrorOptions(modes_select);
73 72
74 73 // try to detect the mode based on the file we edit
75 74 var mimetype = "${file.mimetype}";
76 75 var detected_mode = detectCodeMirrorMode(
77 76 "${file.path}", mimetype);
78 77
79 78 if(detected_mode){
80 79 $(modes_select).select2("val", mimetype);
81 80 $(modes_select).change();
82 81 setCodeMirrorMode(myCodeMirror, detected_mode);
83 82 }
84 83
85 84 var filename_selector = "#filename_${h.FID('f',file.path)}";
86 85 // on change of select field set mode
87 86 setCodeMirrorModeFromSelect(
88 87 modes_select, filename_selector, myCodeMirror, null);
89 88
90 89 // on entering the new filename set mode, from given extension
91 90 setCodeMirrorModeFromInput(
92 91 modes_select, filename_selector, myCodeMirror, null);
93 92 });
94 93 </script>
95 94 %endfor
96 95 <input type="hidden" name="__end__" />
97 96
98 97 <div class="pull-left">
99 98 ${h.submit('update',_('Update Gist'),class_="btn btn-success")}
100 99 <a class="btn" href="${h.route_path('gist_show', gist_id=c.gist.gist_access_id)}">${_('Cancel')}</a>
101 100 </div>
102 101 ${h.end_form()}
103 102 </div>
104 103 </div>
105 104
106 105 </div>
107 106 <script>
108 107 $('#update').on('click', function(e){
109 108 e.preventDefault();
110 109
111 110 $(this).val('Updating...');
112 111 $(this).attr('disabled', 'disabled');
113 112 // check for newer version.
114 113 $.ajax({
115 114 url: "${h.route_path('gist_edit_check_revision', gist_id=c.gist.gist_access_id)}",
116 115 data: {
117 116 'revision': '${c.file_last_commit.raw_id}'
118 117 },
119 118 dataType: 'json',
120 119 type: 'GET',
121 120 success: function(data) {
122 121 if(data.success === false){
123 122 message = '${h.literal(_('Gist was updated since you started editing. Copy your changes and click %(here)s to reload the new version.')
124 123 % {'here': h.link_to('here', h.route_path('gist_edit', gist_id=c.gist.gist_access_id))})}'
125 124 alertMessage = [{"message": {
126 125 "message": message, "force": "true", "level": "warning"}}];
127 126 $.Topic('/notifications').publish(alertMessage[0]);
128 127 }
129 128 else{
130 129 $('#eform').submit();
131 130 }
132 131 }
133 132 });
134 133 })
135 134
136 135 </script>
137 136 </%def>
@@ -1,147 +1,146 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 %if c.show_private:
6 5 ${_('Private Gists for user {}').format(c.rhodecode_user.username)}
7 6 %elif c.show_public:
8 7 ${_('Public Gists for user {}').format(c.rhodecode_user.username)}
9 8 %else:
10 9 ${_('Public Gists')}
11 10 %endif
12 11 %if c.rhodecode_name:
13 12 &middot; ${h.branding(c.rhodecode_name)}
14 13 %endif
15 14 </%def>
16 15
17 16 <%def name="breadcrumbs_links()"></%def>
18 17
19 18 <%def name="menu_bar_nav()">
20 19 ${self.menu_items(active='gists')}
21 20 </%def>
22 21
23 22 <%def name="main()">
24 23
25 24 <div class="box">
26 25 <div class="title">
27 26
28 27 <ul class="button-links">
29 28 % if c.is_super_admin:
30 29 <li><a class="btn ${h.is_active('all', c.active)}" href="${h.route_path('gists_show', _query={'all': 1})}">${_('All gists')}</a></li>
31 30 %endif
32 31 <li><a class="btn ${h.is_active('public', c.active)}" href="${h.route_path('gists_show')}">${_('All public')}</a></li>
33 32 %if c.rhodecode_user.username != h.DEFAULT_USER:
34 33 <li><a class="btn ${h.is_active('my_all', c.active)}" href="${h.route_path('gists_show', _query={'public':1, 'private': 1})}">${_('My gists')}</a></li>
35 34 <li><a class="btn ${h.is_active('my_private', c.active)}" href="${h.route_path('gists_show', _query={'private': 1})}">${_('My private')}</a></li>
36 35 <li><a class="btn ${h.is_active('my_public', c.active)}" href="${h.route_path('gists_show', _query={'public': 1})}">${_('My public')}</a></li>
37 36 %endif
38 37 </ul>
39 38
40 39 % if c.rhodecode_user.username != h.DEFAULT_USER:
41 40 <div class="pull-right">
42 41 <a class="btn btn-primary" href="${h.route_path('gists_new')}" >
43 42 ${_(u'Create New Gist')}
44 43 </a>
45 44 </div>
46 45 % endif
47 46
48 47 <div class="grid-quick-filter">
49 48 <ul class="grid-filter-box">
50 49 <li class="grid-filter-box-icon">
51 50 <i class="icon-search"></i>
52 51 </li>
53 52 <li class="grid-filter-box-input">
54 53 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
55 54 </li>
56 55 </ul>
57 56 </div>
58 57
59 58 </div>
60 59
61 60 <div class="main-content-full-width">
62 61 <div id="repos_list_wrap">
63 62 <table id="gist_list_table" class="display"></table>
64 63 </div>
65 64 </div>
66 65
67 66 </div>
68 67
69 68 <script type="text/javascript">
70 69 $(document).ready(function() {
71 70
72 71 var get_datatable_count = function(){
73 72 var api = $('#gist_list_table').dataTable().api();
74 73 $('#gists_count').text(api.page.info().recordsDisplay);
75 74 };
76 75
77 76
78 77 // custom filter that filters by access_id, description or author
79 78 $.fn.dataTable.ext.search.push(
80 79 function( settings, data, dataIndex ) {
81 80 var query = $('#q_filter').val();
82 81 var author = data[0].strip();
83 82 var access_id = data[2].strip();
84 83 var description = data[3].strip();
85 84
86 85 var query_str = (access_id + " " + author + " " + description).toLowerCase();
87 86
88 87 if(query_str.indexOf(query.toLowerCase()) !== -1){
89 88 return true;
90 89 }
91 90 return false;
92 91 }
93 92 );
94 93
95 94 // gists list
96 95 $('#gist_list_table').DataTable({
97 96 data: ${c.data|n},
98 97 dom: 'rtp',
99 98 pageLength: ${c.visual.dashboard_items},
100 99 order: [[ 4, "desc" ]],
101 100 columns: [
102 101 { data: {"_": "author",
103 102 "sort": "author_raw"}, title: "${_("Author")}", width: "250px", className: "td-user" },
104 103 { data: {"_": "type",
105 104 "sort": "type"}, title: "${_("Type")}", width: "100px", className: "td-gist-type" },
106 105 { data: {"_": "access_id",
107 106 "sort": "access_id"}, title: "${_("Name")}", width:"150px", className: "td-componentname" },
108 107 { data: {"_": "description",
109 108 "sort": "description"}, title: "${_("Description")}", width: "250px", className: "td-description" },
110 109 { data: {"_": "created_on",
111 110 "sort": "created_on_raw"}, title: "${_("Created on")}", className: "td-time" },
112 111 { data: {"_": "expires",
113 112 "sort": "expires"}, title: "${_("Expires")}", width: "200px", className: "td-expire" }
114 113 ],
115 114 language: {
116 115 paginate: DEFAULT_GRID_PAGINATION,
117 116 emptyTable: _gettext("No gists available yet.")
118 117 },
119 118 "initComplete": function( settings, json ) {
120 119 timeagoActivate();
121 120 tooltipActivate();
122 121 get_datatable_count();
123 122 }
124 123 });
125 124
126 125 // update the counter when things change
127 126 $('#gist_list_table').on('draw.dt', function() {
128 127 timeagoActivate();
129 128 tooltipActivate();
130 129 get_datatable_count();
131 130 });
132 131
133 132 // filter, filter both grids
134 133 $('#q_filter').on( 'keyup', function () {
135 134 var repo_api = $('#gist_list_table').dataTable().api();
136 135 repo_api
137 136 .draw();
138 137 });
139 138
140 139 // refilter table if page load via back button
141 140 $("#q_filter").trigger('keyup');
142 141
143 142 });
144 143
145 144 </script>
146 145 </%def>
147 146
@@ -1,112 +1,111 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('New Gist')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='gists')}
15 14 </%def>
16 15
17 16 <%def name="main()">
18 17 <div class="box">
19 18 <!-- box / title -->
20 19 <div class="title">
21 20
22 21 </div>
23 22
24 23 <div class="table">
25 24 <div id="files_data">
26 25 ${h.secure_form(h.route_path('gists_create'), id='eform', request=request)}
27 26 <div>
28 27 <span class="gist-gravatar">
29 28 ${self.gravatar(c.rhodecode_user.email, 30)}
30 29 </span>
31 30 <label for='gistid'>${_('Gist id')}</label>
32 31 ${h.text('gistid', placeholder=_('Auto generated'))}
33 32
34 33 <label for='lifetime'>${_('Gist lifetime')}</label>
35 34 ${h.dropdownmenu('lifetime', '', c.lifetime_options)}
36 35
37 36 <label for='acl_level'>${_('Private Gist access level')}</label>
38 37 ${h.dropdownmenu('gist_acl_level', '', c.acl_options)}
39 38
40 39 <textarea style="margin-top: 5px; border-color: #dbd9da" id="description" name="description" placeholder="${_('Gist description ...')}"></textarea>
41 40 </div>
42 41
43 42 <div id="codeblock" class="codeblock">
44 43 <div class="code-header">
45 44 <div class="form">
46 45 <div class="fields">
47 46 ${h.text('filename', size=30, placeholder=_('name gist file...'))}
48 47 ${h.dropdownmenu('mimetype','plain',[('plain',_('plain'))],enable_filter=True)}
49 48 </div>
50 49 </div>
51 50 </div>
52 51
53 52 <div id="editor_container">
54 53 <div id="editor_pre"></div>
55 54 <textarea id="editor" name="content" ></textarea>
56 55 </div>
57 56 </div>
58 57
59 58 <div class="pull-left">
60 59 <div class="pull-right">
61 60 ${h.submit('create',_('Create Gist'),class_="btn")}
62 61 </div>
63 62 <div class="rcform-element pull-right">
64 63 <div class="fields gist-type-fields">
65 64 <fieldset>
66 65 <div class="gist-type-fields-wrapper">
67 66
68 67 <input type="radio" id="private_gist" checked="" name="gist_type" value="private" onchange="setGistId('private')">
69 68 <label for="private_gist">${_('Private Gist')}</label>
70 69 <span class="tooltip label" title="${_('Private Gists are not listed and only accessible through their secret url.')}">${_('Private Gist')}</span>
71 70
72 71 <input type="radio" id="public_gist" name="gist_type" value="public" onchange="setGistId('public')">
73 72 <label for="public_gist">${_('Public Gist')}</label>
74 73 <span class="tooltip label" title="${_('Public Gists are accessible to anyone and listed in Gists page.')}">${_('Public Gist')}</span>
75 74 </div>
76 75 </fieldset>
77 76 </div>
78 77 </div>
79 78
80 79 </div>
81 80 ${h.end_form()}
82 81 </div>
83 82 </div>
84 83
85 84 </div>
86 85
87 86 <script type="text/javascript">
88 87 var myCodeMirror = initCodeMirror('editor', '');
89 88
90 89 var modes_select = $('#mimetype');
91 90 fillCodeMirrorOptions(modes_select);
92 91
93 92 var filename_selector = '#filename';
94 93 // on change of select field set mode
95 94 setCodeMirrorModeFromSelect(
96 95 modes_select, filename_selector, myCodeMirror, null);
97 96
98 97 // on entering the new filename set mode, from given extension
99 98 setCodeMirrorModeFromInput(
100 99 modes_select, filename_selector, myCodeMirror, null);
101 100
102 101 setGistId = function(gistType) {
103 102 if (gistType === 'private') {
104 103 $('#gistid').removeAttr('disabled');
105 104 }
106 105 else {
107 106 $('#gistid').val('');
108 107 $('#gistid').attr('disabled', 'disabled')
109 108 }
110 109 }
111 110 </script>
112 111 </%def>
@@ -1,113 +1,112 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
4 3
5 4 <%def name="robots()">
6 5 %if c.gist.gist_type != 'public':
7 6 <meta name="robots" content="noindex, nofollow">
8 7 %else:
9 8 ${parent.robots()}
10 9 %endif
11 10 </%def>
12 11
13 12 <%def name="title()">
14 13 ${_('Gist')} &middot; ${c.gist.gist_access_id}
15 14 %if c.rhodecode_name:
16 15 &middot; ${h.branding(c.rhodecode_name)}
17 16 %endif
18 17 </%def>
19 18
20 19 <%def name="breadcrumbs_links()">
21 20 ${_('Gist')} &middot; ${c.gist.gist_access_id}
22 21 </%def>
23 22
24 23 <%def name="menu_bar_nav()">
25 24 ${self.menu_items(active='gists')}
26 25 </%def>
27 26
28 27 <%def name="main()">
29 28 <div class="box">
30 29 <!-- box / title -->
31 30
32 31 <div class="table">
33 32 <div id="files_data">
34 33 <div id="codeblock" class="codeblock">
35 34 <div class="code-header">
36 35 <div class="gist_url">
37 36 <div class="pull-left">
38 37 <code>
39 38 ${dt.gist_type(c.gist.gist_type)}
40 39 <span class="tag disabled">${c.gist.gist_access_id}</span>
41 40 ${c.gist.gist_url()} <span class="icon-clipboard clipboard-action" data-clipboard-text="${c.gist.gist_url()}" title="${_('Copy the url')}"></span>
42 41 </code>
43 42 </div>
44 43
45 44 <div class="pull-right buttons">
46 45 ## only owner should see that
47 46 <a href="#copySource" onclick="return false;" class="btn btn-mini icon-clipboard no-grey clipboard-action" data-clipboard-text="${c.files[0].content}">${_('Copy content')}</a>
48 47
49 48 %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id:
50 49 ${h.link_to(_('Edit'), h.route_path('gist_edit', gist_id=c.gist.gist_access_id), class_="btn btn-mini")}
51 50 %endif
52 51 ${h.link_to(_('Show as Raw'), h.route_path('gist_show_formatted', gist_id=c.gist.gist_access_id, revision='tip', format='raw'), class_="btn btn-mini")}
53 52
54 53 %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id:
55 54 <div class="pull-right remove_gist">
56 55 ${h.secure_form(h.route_path('gist_delete', gist_id=c.gist.gist_access_id), request=request)}
57 56 <input class="btn btn-mini btn-danger" id="remove_gist" name="remove_gist"
58 57 onclick="submitConfirm(event, this, _gettext('Confirm to delete this gist'), _gettext('Delete'), '${c.gist.gist_access_id}')"
59 58 type="submit" value="${_('Delete')}"
60 59 >
61 60 ${h.end_form()}
62 61 </div>
63 62 %endif
64 63 </div>
65 64 </div>
66 65
67 66 <div class="gist-desc">
68 67 <code>${c.gist.gist_description}</code>
69 68 </div>
70 69
71 70 <div class="author">
72 71 <div title="${h.tooltip(c.file_last_commit.author)}">
73 72 ${self.gravatar_with_user(c.file_last_commit.author, 16, tooltip=True)} - ${_('created')} ${h.age_component(c.file_last_commit.date)},
74 73 ${_('expires')}:
75 74 %if c.gist.gist_expires == -1:
76 75 ${_('never')}
77 76 %else:
78 77 ${h.age_component(h.time_to_utcdatetime(c.gist.gist_expires))}
79 78 %endif
80 79 </span>
81 80 </div>
82 81
83 82 </div>
84 83 <div class="commit">${h.urlify_commit_message(c.file_last_commit.message, None)}</div>
85 84 </div>
86 85
87 86 ## iterate over the files
88 87 % for gist_file in c.files:
89 88 <% renderer = c.render and h.renderer_from_filename(gist_file.path, exclude=['.txt', '.TXT'])%>
90 89 <!--
91 90 <div id="${h.FID('G', gist_file.path)}" class="stats" >
92 91 <a href="${c.gist.gist_url()}">¶</a>
93 92 <b >${gist_file.path}</b>
94 93 <div>
95 94 ${h.link_to(_('Show as raw'), h.route_path('gist_show_formatted_path', gist_id=c.gist.gist_access_id, revision=gist_file.commit.raw_id, format='raw', f_path=gist_file.path), class_="btn btn-mini")}
96 95 </div>
97 96 </div>
98 97 -->
99 98 <div class="code-body textarea text-area editor">
100 99 %if renderer:
101 100 ${h.render(gist_file.content, renderer=renderer)}
102 101 %else:
103 102 ${h.pygmentize(gist_file,linenos=True,anchorlinenos=True,lineanchors='L',cssclass="code-highlight")}
104 103 %endif
105 104 </div>
106 105 %endfor
107 106 </div>
108 107 </div>
109 108 </div>
110 109
111 110
112 111 </div>
113 112 </%def>
@@ -1,36 +1,35 b''
1 ## -*- coding: utf-8 -*-
2 1 <%!
3 2 def inherit(context):
4 3 if context['c'].repo:
5 4 return "/admin/repos/repo_edit.mako"
6 5 elif context['c'].repo_group:
7 6 return "/admin/repo_groups/repo_group_edit.mako"
8 7 else:
9 8 return "/admin/integrations/global.mako"
10 9 %>
11 10 <%inherit file="${inherit(context)}" />
12 11
13 12 <%def name="title()">
14 13 ${_('Integrations Settings')}
15 14 %if c.rhodecode_name:
16 15 &middot; ${h.branding(c.rhodecode_name)}
17 16 %endif
18 17 </%def>
19 18
20 19 <%def name="breadcrumbs_links()">
21 20 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
22 21 &raquo;
23 22 ${_('Integrations')}
24 23 </%def>
25 24
26 25 <%def name="menu_bar_nav()">
27 26 %if c.repo:
28 27 ${self.menu_items(active='repositories')}
29 28 %else:
30 29 ${self.menu_items(active='admin')}
31 30 %endif
32 31 </%def>
33 32
34 33 <%def name="main_content()">
35 34 ${next.body()}
36 35 </%def>
@@ -1,69 +1,68 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2
4 3 <%def name="breadcrumbs_links()">
5 4 %if c.repo:
6 5 ${h.link_to('Settings',h.route_path('edit_repo', repo_name=c.repo.repo_name))}
7 6 &raquo;
8 7 ${h.link_to(_('Integrations'),request.route_url(route_name='repo_integrations_home', repo_name=c.repo.repo_name))}
9 8 &raquo;
10 9 ${h.link_to(c.current_IntegrationType.display_name,
11 10 request.route_url(route_name='repo_integrations_list',
12 11 repo_name=c.repo.repo_name,
13 12 integration=c.current_IntegrationType.key))}
14 13 %elif c.repo_group:
15 14 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
16 15 &raquo;
17 16 ${h.link_to(_('Repository Groups'),h.route_path('repo_groups'))}
18 17 &raquo;
19 18 ${h.link_to(c.repo_group.group_name,h.route_path('edit_repo_group', repo_group_name=c.repo_group.group_name))}
20 19 &raquo;
21 20 ${h.link_to(_('Integrations'),request.route_url(route_name='repo_group_integrations_home', repo_group_name=c.repo_group.group_name))}
22 21 &raquo;
23 22 ${h.link_to(c.current_IntegrationType.display_name,
24 23 request.route_url(route_name='repo_group_integrations_list',
25 24 repo_group_name=c.repo_group.group_name,
26 25 integration=c.current_IntegrationType.key))}
27 26 %else:
28 27 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
29 28 &raquo;
30 29 ${h.link_to(_('Settings'),h.route_path('admin_settings'))}
31 30 &raquo;
32 31 ${h.link_to(_('Integrations'),request.route_url(route_name='global_integrations_home'))}
33 32 &raquo;
34 33 ${h.link_to(c.current_IntegrationType.display_name,
35 34 request.route_url(route_name='global_integrations_list',
36 35 integration=c.current_IntegrationType.key))}
37 36 %endif
38 37
39 38 %if c.integration:
40 39 &raquo;
41 40 ${c.integration.name}
42 41 %elif c.current_IntegrationType:
43 42 &raquo;
44 43 ${c.current_IntegrationType.display_name}
45 44 %endif
46 45 </%def>
47 46
48 47 <style>
49 48 .control-inputs.item-options, .control-inputs.item-settings {
50 49 float: left;
51 50 width: 100%;
52 51 }
53 52 </style>
54 53 <div class="panel panel-default">
55 54 <div class="panel-heading">
56 55 <h2 class="panel-title">
57 56 %if c.integration:
58 57 ${c.current_IntegrationType.display_name} - ${c.integration.name}
59 58 %else:
60 59 ${_('Create New %(integration_type)s Integration') % {
61 60 'integration_type': c.current_IntegrationType.display_name
62 61 }}
63 62 %endif
64 63 </h2>
65 64 </div>
66 65 <div class="panel-body">
67 66 ${c.form.render() | n}
68 67 </div>
69 68 </div>
@@ -1,52 +1,51 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Integrations administration')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 12 &raquo;
14 13 ${_('Integrations')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_nav()">
18 17 ${self.menu_items(active='admin')}
19 18 </%def>
20 19
21 20 <%def name="menu_bar_subnav()">
22 21 ${self.admin_menu(active='integrations')}
23 22 </%def>
24 23
25 24 <%def name="side_bar_nav()">
26 25 <li class="active">
27 26 <a href="${h.route_path('global_integrations_home')}">Global</a>
28 27 </li>
29 28 </%def>
30 29
31 30 <%def name="main_content()">
32 31 <%include file="/admin/settings/settings_${c.active}.mako"/>
33 32 </%def>
34 33
35 34 <%def name="main()">
36 35 <div class="box">
37 36
38 37 ##main
39 38 <div class='sidebar-col-wrapper'>
40 39 <div class="sidebar">
41 40 <ul class="nav nav-pills nav-stacked">
42 41 ${self.side_bar_nav()}
43 42 </ul>
44 43 </div>
45 44
46 45 <div class="main-content-auto-width">
47 46 ${self.main_content()}
48 47 </div>
49 48 </div>
50 49 </div>
51 50
52 51 </%def>
@@ -1,220 +1,219 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2
4 3 <%def name="breadcrumbs_links()">
5 4 %if c.repo:
6 5 ${h.link_to('Settings',h.route_path('edit_repo', repo_name=c.repo.repo_name))}
7 6 %elif c.repo_group:
8 7 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
9 8 &raquo;
10 9 ${h.link_to(_('Repository Groups'),h.route_path('repo_groups'))}
11 10 &raquo;
12 11 ${h.link_to(c.repo_group.group_name,h.route_path('edit_repo_group', repo_group_name=c.repo_group.group_name))}
13 12 %else:
14 13 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
15 14 &raquo;
16 15 ${h.link_to(_('Settings'),h.route_path('admin_settings'))}
17 16 %endif
18 17 %if c.current_IntegrationType:
19 18 &raquo;
20 19 %if c.repo:
21 20 ${h.link_to(_('Integrations'),
22 21 request.route_path(route_name='repo_integrations_home',
23 22 repo_name=c.repo.repo_name))}
24 23 %elif c.repo_group:
25 24 ${h.link_to(_('Integrations'),
26 25 request.route_path(route_name='repo_group_integrations_home',
27 26 repo_group_name=c.repo_group.group_name))}
28 27 %else:
29 28 ${h.link_to(_('Integrations'),
30 29 request.route_path(route_name='global_integrations_home'))}
31 30 %endif
32 31 &raquo;
33 32 ${c.current_IntegrationType.display_name}
34 33 %else:
35 34 &raquo;
36 35 ${_('Integrations')}
37 36 %endif
38 37 </%def>
39 38
40 39 <div class="panel panel-default">
41 40 <div class="panel-heading">
42 41 <h3 class="panel-title">
43 42 %if c.repo:
44 43 ${_('Current Integrations for Repository: {repo_name}').format(repo_name=c.repo.repo_name)}
45 44 %elif c.repo_group:
46 45 ${_('Repository Group Integrations: {}').format(c.repo_group.group_name)}</h3>
47 46 %else:
48 47 ${_('Current Integrations')}
49 48 %endif
50 49 </h3>
51 50 </div>
52 51 <div class="panel-body">
53 52
54 53 <%
55 54 integration_type = c.current_IntegrationType and c.current_IntegrationType.display_name or ''
56 55
57 56 if c.repo:
58 57 create_url = h.route_path('repo_integrations_new', repo_name=c.repo.repo_name)
59 58 elif c.repo_group:
60 59 create_url = h.route_path('repo_group_integrations_new', repo_group_name=c.repo_group.group_name)
61 60 else:
62 61 create_url = h.route_path('global_integrations_new')
63 62 %>
64 63 <p class="pull-right">
65 64 <a href="${create_url}" class="btn btn-small btn-success">${_(u'Create new integration')}</a>
66 65 </p>
67 66
68 67 <table class="rctable integrations">
69 68 <thead>
70 69 <tr>
71 70 <th><a href="?sort=enabled:${c.rev_sort_dir}">${_('Enabled')}</a></th>
72 71 <th><a href="?sort=name:${c.rev_sort_dir}">${_('Name')}</a></th>
73 72 <th colspan="2"><a href="?sort=integration_type:${c.rev_sort_dir}">${_('Type')}</a></th>
74 73 <th><a href="?sort=scope:${c.rev_sort_dir}">${_('Scope')}</a></th>
75 74 <th>${_('Actions')}</th>
76 75 <th></th>
77 76 </tr>
78 77 </thead>
79 78 <tbody>
80 79 %if not c.integrations_list:
81 80 <tr>
82 81 <td colspan="7">
83 82
84 83 %if c.repo:
85 84 ${_('No {type} integrations for repo {repo} exist yet.').format(type=integration_type, repo=c.repo.repo_name)}
86 85 %elif c.repo_group:
87 86 ${_('No {type} integrations for repogroup {repogroup} exist yet.').format(type=integration_type, repogroup=c.repo_group.group_name)}
88 87 %else:
89 88 ${_('No {type} integrations exist yet.').format(type=integration_type)}
90 89 %endif
91 90
92 91 %if c.current_IntegrationType:
93 92 <%
94 93 if c.repo:
95 94 create_url = h.route_path('repo_integrations_create', repo_name=c.repo.repo_name, integration=c.current_IntegrationType.key)
96 95 elif c.repo_group:
97 96 create_url = h.route_path('repo_group_integrations_create', repo_group_name=c.repo_group.group_name, integration=c.current_IntegrationType.key)
98 97 else:
99 98 create_url = h.route_path('global_integrations_create', integration=c.current_IntegrationType.key)
100 99 %>
101 100 %endif
102 101
103 102 <a href="${create_url}">${_(u'Create one')}</a>
104 103 </td>
105 104 </tr>
106 105 %endif
107 106 %for IntegrationType, integration in c.integrations_list:
108 107 <tr id="integration_${integration.integration_id}">
109 108 <td class="td-enabled">
110 109 <div class="pull-left">
111 110 ${h.bool2icon(integration.enabled)}
112 111 </div>
113 112 </td>
114 113 <td class="td-description">
115 114 ${integration.name}
116 115 </td>
117 116 <td class="td-icon">
118 117 %if integration.integration_type in c.available_integrations:
119 118 <div class="integration-icon">
120 119 ${c.available_integrations[integration.integration_type].icon()|n}
121 120 </div>
122 121 %else:
123 122 ?
124 123 %endif
125 124 </td>
126 125 <td class="td-type">
127 126 ${integration.integration_type}
128 127 </td>
129 128 <td class="td-scope">
130 129 %if integration.repo:
131 130 <a href="${h.route_path('repo_summary', repo_name=integration.repo.repo_name)}">
132 131 ${_('repo')}:${integration.repo.repo_name}
133 132 </a>
134 133 %elif integration.repo_group:
135 134 <a href="${h.route_path('repo_group_home', repo_group_name=integration.repo_group.group_name)}">
136 135 ${_('repogroup')}:${integration.repo_group.group_name}
137 136 %if integration.child_repos_only:
138 137 ${_('child repos only')}
139 138 %else:
140 139 ${_('cascade to all')}
141 140 %endif
142 141 </a>
143 142 %else:
144 143 %if integration.child_repos_only:
145 144 ${_('top level repos only')}
146 145 %else:
147 146 ${_('global')}
148 147 %endif
149 148 </td>
150 149 %endif
151 150 <td class="td-action">
152 151 %if not IntegrationType:
153 152 ${_('unknown integration')}
154 153 %else:
155 154 <%
156 155 if c.repo:
157 156 edit_url = request.route_path('repo_integrations_edit',
158 157 repo_name=c.repo.repo_name,
159 158 integration=integration.integration_type,
160 159 integration_id=integration.integration_id)
161 160 elif c.repo_group:
162 161 edit_url = request.route_path('repo_group_integrations_edit',
163 162 repo_group_name=c.repo_group.group_name,
164 163 integration=integration.integration_type,
165 164 integration_id=integration.integration_id)
166 165 else:
167 166 edit_url = request.route_path('global_integrations_edit',
168 167 integration=integration.integration_type,
169 168 integration_id=integration.integration_id)
170 169 %>
171 170 <div class="grid_edit">
172 171 <a href="${edit_url}">${_('Edit')}</a>
173 172 </div>
174 173 <div class="grid_delete">
175 174 <a href="${edit_url}"
176 175 class="btn btn-link btn-danger delete_integration_entry"
177 176 data-desc="${integration.name}"
178 177 data-uid="${integration.integration_id}">
179 178 ${_('Delete')}
180 179 </a>
181 180 </div>
182 181 %endif
183 182 </td>
184 183 </tr>
185 184 %endfor
186 185 <tr id="last-row"></tr>
187 186 </tbody>
188 187 </table>
189 188 <div class="integrations-paginator">
190 189 <div class="pagination-wh pagination-left">
191 190 ${c.integrations_list.render()}
192 191 </div>
193 192 </div>
194 193 </div>
195 194 </div>
196 195 <script type="text/javascript">
197 196 var delete_integration = function(entry) {
198 197 if (confirm("Confirm to remove this integration: "+$(entry).data('desc'))) {
199 198 var request = $.ajax({
200 199 type: "POST",
201 200 url: $(entry).attr('href'),
202 201 data: {
203 202 'delete': 'delete',
204 203 'csrf_token': CSRF_TOKEN
205 204 },
206 205 success: function(){
207 206 location.reload();
208 207 },
209 208 error: function(data, textStatus, errorThrown){
210 209 alert("Error while deleting entry.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(entry)[0].url));
211 210 }
212 211 });
213 212 };
214 213 };
215 214
216 215 $('.delete_integration_entry').on('click', function(e){
217 216 e.preventDefault();
218 217 delete_integration(this);
219 218 });
220 219 </script> No newline at end of file
@@ -1,60 +1,59 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="widgets" file="/widgets.mako"/>
4 3
5 4 <%def name="breadcrumbs_links()">
6 5 %if c.repo:
7 6 ${_('Settings')}
8 7 %elif c.repo_group:
9 8 ${_('Settings')}
10 9 %else:
11 10 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 11 &raquo;
13 12 ${h.link_to(_('Settings'),h.route_path('admin_settings'))}
14 13 &raquo;
15 14 ${h.link_to(_('Integrations'),request.route_url(route_name='global_integrations_home'))}
16 15 %endif
17 16 &raquo;
18 17 ${_('Create new integration')}
19 18 </%def>
20 19 <%widgets:panel class_='integrations'>
21 20 <%def name="title()">
22 21 %if c.repo:
23 22 ${_('Create New Integration for repository: {repo_name}').format(repo_name=c.repo.repo_name)}
24 23 %elif c.repo_group:
25 24 ${_('Create New Integration for repository group: {repo_group_name}').format(repo_group_name=c.repo_group.group_name)}
26 25 %else:
27 26 ${_('Create New Global Integration')}
28 27 %endif
29 28 </%def>
30 29
31 30 %for integration, IntegrationObject in c.available_integrations.items():
32 31 <%
33 32 if c.repo:
34 33 create_url = request.route_path('repo_integrations_create',
35 34 repo_name=c.repo.repo_name,
36 35 integration=integration)
37 36 elif c.repo_group:
38 37 create_url = request.route_path('repo_group_integrations_create',
39 38 repo_group_name=c.repo_group.group_name,
40 39 integration=integration)
41 40 else:
42 41 create_url = request.route_path('global_integrations_create',
43 42 integration=integration)
44 43 if IntegrationObject.is_dummy:
45 44 create_url = request.current_route_path()
46 45 %>
47 46 <a href="${create_url}" class="integration-box ${'dummy-integration' if IntegrationObject.is_dummy else ''}">
48 47 <%widgets:panel>
49 48 <h2>
50 49 <div class="integration-icon">
51 50 ${IntegrationObject.icon()|n}
52 51 </div>
53 52 ${IntegrationObject.display_name}
54 53 </h2>
55 54 ${IntegrationObject.description or _('No description available')}
56 55 </%widgets:panel>
57 56 </a>
58 57 %endfor
59 58 <div style="clear:both"></div>
60 59 </%widgets:panel>
@@ -1,68 +1,67 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Settings administration')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='admin')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.admin_menu()}
19 18 </%def>
20 19
21 20 <%def name="side_bar_nav()">
22 21
23 22 </%def>
24 23
25 24 <%def name="main_content()">
26 25 <h2>${_('Administration area')}</h2>
27 26
28 27 <table class="rctable">
29 28 <tr>
30 29 <td>${_('Repositories under administration')}</td>
31 30 <td class="delegated-admin-repos">${len(c.auth_user.repositories_admin)}</td>
32 31 <td>
33 32 % if c.can_create_repo:
34 33 <a href="${h.route_path('repo_new')}" class="">${_('Add Repository')}</a>
35 34 % endif
36 35 </td>
37 36 </tr>
38 37 <tr>
39 38 <td>${_('Repository groups under administration')}</td>
40 39 <td class="delegated-admin-repo-groups">${len(c.auth_user.repository_groups_admin)}</td>
41 40 <td>
42 41 % if c.can_create_repo_group:
43 42 <a href="${h.route_path('repo_group_new')}" class="">${_(u'Add Repository Group')}</a>
44 43 % endif
45 44 </td>
46 45 </tr>
47 46 <tr>
48 47 <td>${_('User groups under administration')}</td>
49 48 <td class="delegated-admin-user-groups">${len(c.auth_user.user_groups_admin)}</td>
50 49 <td>
51 50 % if c.can_create_user_group:
52 51 <a href="${h.route_path('user_groups_new')}" class="">${_(u'Add User Group')}</a>
53 52 % endif
54 53 </td>
55 54 </tr>
56 55 </table>
57 56 </%def>
58 57
59 58 <%def name="main()">
60 59 <div class="box">
61 60
62 61 ##main
63 62 <div class="main-content-auto-width">
64 63 ${self.main_content()}
65 64 </div>
66 65 </div>
67 66
68 67 </%def> No newline at end of file
@@ -1,57 +1,56 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('My account')} ${c.rhodecode_user.username}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${_('My Account')}
13 12 </%def>
14 13
15 14 <%def name="menu_bar_nav()">
16 15 ${self.menu_items(active='my_account')}
17 16 </%def>
18 17
19 18 <%def name="main()">
20 19 <div class="box">
21 20 <div class="title">
22 21 ${self.breadcrumbs()}
23 22 </div>
24 23
25 24 <div class="sidebar-col-wrapper scw-small">
26 25 ##main
27 26 <div class="sidebar">
28 27 <ul class="nav nav-pills nav-stacked">
29 28 <li class="${h.is_active(['profile', 'profile_edit'], c.active)}"><a href="${h.route_path('my_account_profile')}">${_('Profile')}</a></li>
30 29 <li class="${h.is_active('emails', c.active)}"><a href="${h.route_path('my_account_emails')}">${_('Emails')}</a></li>
31 30 <li class="${h.is_active('password', c.active)}"><a href="${h.route_path('my_account_password')}">${_('Password')}</a></li>
32 31 <li class="${h.is_active('bookmarks', c.active)}"><a href="${h.route_path('my_account_bookmarks')}">${_('Bookmarks')}</a></li>
33 32 <li class="${h.is_active('auth_tokens', c.active)}"><a href="${h.route_path('my_account_auth_tokens')}">${_('Auth Tokens')}</a></li>
34 33 <li class="${h.is_active(['ssh_keys', 'ssh_keys_generate'], c.active)}"><a href="${h.route_path('my_account_ssh_keys')}">${_('SSH Keys')}</a></li>
35 34 <li class="${h.is_active('user_group_membership', c.active)}"><a href="${h.route_path('my_account_user_group_membership')}">${_('User Group Membership')}</a></li>
36 35
37 36 ## TODO: Find a better integration of oauth/saml views into navigation.
38 37 <% my_account_external_url = h.route_path_or_none('my_account_external_identity') %>
39 38 % if my_account_external_url:
40 39 <li class="${h.is_active('external_identity', c.active)}"><a href="${my_account_external_url}">${_('External Identities')}</a></li>
41 40 % endif
42 41
43 42 <li class="${h.is_active('repos', c.active)}"><a href="${h.route_path('my_account_repos')}">${_('Owned Repositories')}</a></li>
44 43 <li class="${h.is_active('watched', c.active)}"><a href="${h.route_path('my_account_watched')}">${_('Watched Repositories')}</a></li>
45 44 <li class="${h.is_active('pullrequests', c.active)}"><a href="${h.route_path('my_account_pullrequests')}">${_('Pull Requests')}</a></li>
46 45 <li class="${h.is_active('perms', c.active)}"><a href="${h.route_path('my_account_perms')}">${_('Permissions')}</a></li>
47 46 <li class="${h.is_active('my_notifications', c.active)}"><a href="${h.route_path('my_account_notifications')}">${_('Live Notifications')}</a></li>
48 47 </ul>
49 48 </div>
50 49
51 50 <div class="main-content-full-width">
52 51 <%include file="/admin/my_account/my_account_${c.active}.mako"/>
53 52 </div>
54 53 </div>
55 54 </div>
56 55
57 56 </%def>
@@ -1,75 +1,74 b''
1 ## -*- coding: utf-8 -*-
2 1
3 2 <div class="panel panel-default">
4 3 <div class="panel-heading">
5 4 <h3 class="panel-title">${_('User Group Membership')}</h3>
6 5 </div>
7 6
8 7 <div class="panel-body">
9 8 <div class="groups_management">
10 9 <div id="repos_list_wrap">
11 10 <table id="user_group_list_table" class="display"></table>
12 11 </div>
13 12 </div>
14 13 </div>
15 14 </div>
16 15
17 16
18 17 <script>
19 18 var api;
20 19 $(document).ready(function() {
21 20
22 21 var get_datatable_count = function(){
23 22 $('#user_group_count').text(api.page.info().recordsDisplay);
24 23 };
25 24
26 25 $('#user_group_list_table').on('click', 'a.editor_remove', function (e) {
27 26 e.preventDefault();
28 27 var row = api.row($(this).closest('tr'));
29 28 row.remove().draw();
30 29 } );
31 30
32 31 $('#user_group_list_table').DataTable({
33 32 data: ${c.user_groups|n},
34 33 dom: 'rtp',
35 34 pageLength: ${c.visual.admin_grid_items},
36 35 order: [[ 0, "asc" ]],
37 36 columns: [
38 37 { data: {"_": "group_name",
39 38 "sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," ,
40 39 render: function (data,type,full,meta)
41 40 {return '<div><i class="icon-user-group" title="User group">'+data+'</i></div>'}},
42 41
43 42 { data: {"_": "group_description",
44 43 "sort": "group_description"}, title: "${_('Description')}", className: "td-description" },
45 44 { data: {"_": "users_group_id"}, className: "td-user",
46 45 render: function (data,type,full,meta)
47 46 {return '<input type="hidden" name="users_group_id" value="'+data+'">'}},
48 47 { data: {"_": "active",
49 48 "sort": "active"}, title: "${_('Active')}", className: "td-active"},
50 49 { data: {"_": "owner_data"}, title: "${_('Owner')}", className: "td-user",
51 50 render: function (data,type,full,meta)
52 51 {return '<div class="rc-user tooltip">'+
53 52 '<img class="gravatar" src="'+ data.owner_icon +'" height="16" width="16">'+
54 53 data.owner +'</div>'
55 54 }
56 55 }
57 56 ],
58 57 language: {
59 58 paginate: DEFAULT_GRID_PAGINATION,
60 59 emptyTable: _gettext("No user groups available yet.")
61 60 },
62 61 "initComplete": function( settings, json ) {
63 62 var data_grid = $('#user_group_list_table').dataTable();
64 63 api = data_grid.api();
65 64 get_datatable_count();
66 65 }
67 66 });
68 67
69 68 // update the counter when doing search
70 69 $('#user_group_list_table').on( 'search.dt', function (e,settings) {
71 70 get_datatable_count();
72 71 });
73 72
74 73 });
75 74 </script> No newline at end of file
@@ -1,52 +1,51 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Show notification')} ${c.rhodecode_user.username}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${h.link_to(_('My Notifications'), h.route_path('notifications_show_all'))}
13 12 &raquo;
14 13 ${_('Show notification')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_nav()">
18 17 ${self.menu_items(active='admin')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21 <div class="box">
23 22 <!-- box / title -->
24 23 <div class="title">
25 24 ${self.breadcrumbs()}
26 25 </div>
27 26 <div class="table">
28 27 <div id="notification_${c.notification.notification_id}" class="main-content-full">
29 28 <div class="notification-header">
30 29 <div class="pull-left">
31 30 ${self.gravatar(c.notification.created_by_user.email, 30)}
32 31 </div>
33 32 <div class="desc pull-left">
34 33 ${h.notification_description(c.notification, request)}
35 34 </div>
36 35 <div class="delete-notifications">
37 36 <span class="delete-notification tooltip" title="${_('Delete')}" onclick="deleteNotification(${c.notification.notification_id}, [function(){window.location=pyroutes.url('notifications_show_all')}])" class="delete-notification action"><i class="icon-delete" ></i></span>
38 37 </div>
39 38 </div>
40 39 <div class="notification-body">
41 40 <div class="notification-subject">
42 41 <h3>${_('Subject')}: ${c.notification.subject}</h3>
43 42 </div>
44 43 %if c.notification.body:
45 44 ${h.render(c.notification.body, renderer=c.visual.default_renderer, mentions=True)}
46 45 %endif
47 46 </div>
48 47 </div>
49 48 </div>
50 49 </div>
51 50
52 51 </%def>
@@ -1,67 +1,66 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('My Notifications')} ${c.rhodecode_user.username}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='my_account')}
15 14 </%def>
16 15
17 16 <%def name="main()">
18 17 <div class="box">
19 18 <div class="title">
20 19 ${_('My Notifications')}
21 20
22 21 <div class="notifications_buttons">
23 22 %if c.notifications:
24 23 <button id='mark_all_read' class="btn btn-default" type="submit">
25 24 ${_('Mark all as read')}
26 25 </button>
27 26 %else:
28 27 <button class="btn btn-default" type="submit" disabled="disabled">
29 28 ${_('Mark all as read')}
30 29 </button>
31 30 %endif
32 31 </div>
33 32 </div>
34 33
35 34 <div class="sidebar-col-wrapper scw-small">
36 35 ##main
37 36 <div class="sidebar">
38 37 <ul class="nav nav-pills nav-stacked">
39 38 <li id='unread' class="${'active' if c.current_filter=='unread' else ''}"><a href="${h.route_path('notifications_show_all', _query=dict(type=c.unread_type))}">${_('Unread')} (${c.unread_count})</a></li>
40 39 <li id='all' class="${'active' if c.current_filter=='all' else ''}"><a href="${h.route_path('notifications_show_all', _query=dict(type=c.all_type))}">${_('All')}</a></li>
41 40 <li id='comment' class="${'active' if c.current_filter=='comment' else ''}"><a href="${h.route_path('notifications_show_all', _query=dict(type=c.comment_type))}">${_('Comments')}</a></li>
42 41 <li id='pull_request' class="${'active' if c.current_filter=='pull_request' else ''}"><a href="${h.route_path('notifications_show_all', _query=dict(type=c.pull_request_type))}">${_('Pull Requests')}</a></li>
43 42 </ul>
44 43 </div>
45 44
46 45 <div class="main-content-full-width">
47 46 <%include file='notifications_data.mako'/>
48 47 </div>
49 48 </div>
50 49 </div>
51 50
52 51 <script type="text/javascript">
53 52
54 53 $('#mark_all_read').on('click',function(e){
55 54 //set notifications as read
56 55 var url = "${h.route_path('notifications_mark_all_read', _query=request.GET.mixed())}";
57 56 $.post(url, {'csrf_token': CSRF_TOKEN}).
58 57 done(function(data){
59 58 window.location = "${request.current_route_path(_query=request.GET.mixed())}";
60 59 })
61 60 .fail(function(data, textStatus, errorThrown){
62 61 alert("Error while saving notifications.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
63 62 });
64 63 });
65 64
66 65 </script>
67 66 </%def>
@@ -1,65 +1,64 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Permissions Administration')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 12 &raquo;
14 13 ${_('Permissions')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_nav()">
18 17 ${self.menu_items(active='admin')}
19 18 </%def>
20 19
21 20 <%def name="menu_bar_subnav()">
22 21 ${self.admin_menu(active='permissions')}
23 22 </%def>
24 23
25 24 <%def name="main()">
26 25 <div class="box">
27 26
28 27 <div class="sidebar-col-wrapper scw-small">
29 28 ##main
30 29 <div class="sidebar">
31 30 <ul class="nav nav-pills nav-stacked">
32 31 <li class="${h.is_active('application', c.active)}">
33 32 <a href="${h.route_path('admin_permissions_application')}">${_('Application')}</a>
34 33 </li>
35 34 <li class="${h.is_active('global', c.active)}">
36 35 <a href="${h.route_path('admin_permissions_global')}">${_('Global')}</a>
37 36 </li>
38 37 <li class="${h.is_active('objects', c.active)}">
39 38 <a href="${h.route_path('admin_permissions_object')}">${_('Object')}</a>
40 39 </li>
41 40 <li class="${h.is_active('branch', c.active)}">
42 41 <a href="${h.route_path('admin_permissions_branch')}">${_('Branch')}</a>
43 42 </li>
44 43 <li class="${h.is_active('ips', c.active)}">
45 44 <a href="${h.route_path('admin_permissions_ips')}">${_('IP Whitelist')}</a>
46 45 </li>
47 46 <li class="${h.is_active('auth_token_access', c.active)}">
48 47 <a href="${h.route_path('admin_permissions_auth_token_access')}">${_('AuthToken Access')}</a>
49 48 </li>
50 49 <li class="${h.is_active('ssh_keys', c.active)}">
51 50 <a href="${h.route_path('admin_permissions_ssh_keys')}">${_('SSH Keys')}</a>
52 51 </li>
53 52 <li class="${h.is_active('perms', c.active)}">
54 53 <a href="${h.route_path('admin_permissions_overview')}">${_('Overview')}</a>
55 54 </li>
56 55 </ul>
57 56 </div>
58 57
59 58 <div class="main-content-full-width">
60 59 <%include file="/admin/permissions/permissions_${c.active}.mako"/>
61 60 </div>
62 61 </div>
63 62 </div>
64 63
65 64 </%def>
@@ -1,122 +1,121 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Add repository group')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 12 &raquo;
14 13 ${h.link_to(_('Repository groups'),h.route_path('repo_groups'))}
15 14 &raquo;
16 15 ${_('Add Repository Group')}
17 16 </%def>
18 17
19 18 <%def name="menu_bar_nav()">
20 19 ${self.menu_items(active='admin')}
21 20 </%def>
22 21
23 22 <%def name="menu_bar_subnav()">
24 23 ${self.admin_menu(active='repository_groups')}
25 24 </%def>
26 25
27 26 <%def name="main()">
28 27 <div class="box">
29 28 ${h.secure_form(h.route_path('repo_group_create'), request=request)}
30 29 <div class="form">
31 30 <!-- fields -->
32 31 <div class="fields">
33 32 <div class="field">
34 33 <div class="label">
35 34 <label for="group_name">${_('Group name')}:</label>
36 35 </div>
37 36 <div class="input">
38 37 ${h.text('group_name', class_="medium")}
39 38 </div>
40 39 </div>
41 40
42 41 <div class="field">
43 42 <div class="label">
44 43 <label for="group_parent_id">${_('Repository group')}:</label>
45 44 </div>
46 45 <div class="select">
47 46 ${h.select('group_parent_id', request.GET.get('parent_group'),c.repo_groups,class_="medium")}
48 47 % if c.personal_repo_group:
49 48 <a class="btn" href="#" id="select_my_group" data-personal-group-id="${c.personal_repo_group.group_id}">
50 49 ${_('Select my personal group ({})').format(c.personal_repo_group.group_name)}
51 50 </a>
52 51 % endif
53 52 </div>
54 53 </div>
55 54
56 55 <div class="field">
57 56 <div class="label">
58 57 <label for="group_description">${_('Description')}:</label>
59 58 </div>
60 59 <div class="textarea editor">
61 60 ${h.textarea('group_description',cols=23,rows=5,class_="medium")}
62 61 <% metatags_url = h.literal('''<a href="#metatagsShow" onclick="$('#meta-tags-desc').toggle();return false">meta-tags</a>''') %>
63 62 <span class="help-block">
64 63 % if c.visual.stylify_metatags:
65 64 ${_('Plain text format with {metatags} support.').format(metatags=metatags_url)|n}
66 65 % else:
67 66 ${_('Plain text format.')}
68 67 % endif
69 68 </span>
70 69 <span id="meta-tags-desc" style="display: none">
71 70 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
72 71 ${dt.metatags_help()}
73 72 </span>
74 73 </div>
75 74 </div>
76 75
77 76 <div id="copy_perms" class="field">
78 77 <div class="label label-checkbox">
79 78 <label for="group_copy_permissions">${_('Copy Parent Group Permissions')}:</label>
80 79 </div>
81 80 <div class="checkboxes">
82 81 ${h.checkbox('group_copy_permissions', value="True", checked="checked")}
83 82 <span class="help-block">${_('Copy permissions from parent repository group.')}</span>
84 83 </div>
85 84 </div>
86 85
87 86 <div class="buttons">
88 87 ${h.submit('save',_('Create Repository Group'),class_="btn")}
89 88 </div>
90 89 </div>
91 90 </div>
92 91 ${h.end_form()}
93 92 </div>
94 93 <script>
95 94 $(document).ready(function(){
96 95 var setCopyPermsOption = function(group_val){
97 96 if(group_val !== "-1"){
98 97 $('#copy_perms').show()
99 98 }
100 99 else{
101 100 $('#copy_perms').hide();
102 101 }
103 102 };
104 103 $("#group_parent_id").select2({
105 104 'containerCssClass': "drop-menu",
106 105 'dropdownCssClass': "drop-menu-dropdown",
107 106 'dropdownAutoWidth': true
108 107 });
109 108 setCopyPermsOption($('#group_parent_id').val());
110 109 $("#group_parent_id").on("change", function(e) {
111 110 setCopyPermsOption(e.val)
112 111 });
113 112 $('#group_name').focus();
114 113
115 114 $('#select_my_group').on('click', function(e){
116 115 e.preventDefault();
117 116 $("#group_parent_id").val($(this).data('personalGroupId')).trigger("change");
118 117 })
119 118
120 119 })
121 120 </script>
122 121 </%def>
@@ -1,44 +1,43 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('%s repository group settings') % c.repo_group.name}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="menu_bar_nav()">
12 11 ${self.menu_items(active='admin')}
13 12 </%def>
14 13
15 14 <%def name="menu_bar_subnav()">
16 15 ${self.repo_group_menu(active='settings')}
17 16 </%def>
18 17
19 18 <%def name="main_content()">
20 19 <%include file="/admin/repo_groups/repo_group_edit_${c.active}.mako"/>
21 20 </%def>
22 21
23 22 <%def name="main()">
24 23
25 24 <div class="box">
26 25 <div class="sidebar-col-wrapper">
27 26 ##main
28 27 <div class="sidebar">
29 28 <ul class="nav nav-pills nav-stacked">
30 29 <li class="${h.is_active('settings', c.active)}"><a href="${h.route_path('edit_repo_group', repo_group_name=c.repo_group.group_name)}">${_('Settings')}</a></li>
31 30 <li class="${h.is_active('permissions', c.active)}"><a href="${h.route_path('edit_repo_group_perms', repo_group_name=c.repo_group.group_name)}">${_('Access Permissions')}</a></li>
32 31 <li class="${h.is_active('advanced', c.active)}"><a href="${h.route_path('edit_repo_group_advanced', repo_group_name=c.repo_group.group_name)}">${_('Advanced')}</a></li>
33 32 <li class="${h.is_active('integrations', c.active)}"><a href="${h.route_path('repo_group_integrations_home', repo_group_name=c.repo_group.group_name)}">${_('Integrations')}</a></li>
34 33 </ul>
35 34 </div>
36 35
37 36 <div class="main-content-full-width">
38 37 ${self.main_content()}
39 38 </div>
40 39
41 40 </div>
42 41 </div>
43 42
44 43 </%def>
@@ -1,89 +1,88 b''
1 ## -*- coding: utf-8 -*-
2 1 <%namespace name="base" file="/base/base.mako"/>
3 2
4 3 <div class="panel panel-default">
5 4 <div class="panel-heading">
6 5 <h3 class="panel-title">${_('Repository Group Settings: {}').format(c.repo_group.name)}</h3>
7 6 </div>
8 7 <div class="panel-body">
9 8 ${h.secure_form(h.route_path('edit_repo_group', repo_group_name=c.repo_group.group_name), request=request)}
10 9 <div class="form">
11 10 <!-- fields -->
12 11 <div class="fields">
13 12 <div class="field">
14 13 <div class="label">
15 14 <label for="group_name">${_('Group name')}:</label>
16 15 </div>
17 16 <div class="input">
18 17 ${c.form['repo_group_name'].render(css_class='medium', oid='group_name')|n}
19 18 ${c.form.render_error(request, c.form['repo_group_name'])|n}
20 19 </div>
21 20 </div>
22 21
23 22 <div class="field">
24 23 <div class="label">
25 24 <label for="repo_group">${_('Repository group')}:</label>
26 25 </div>
27 26 <div class="select">
28 27 ${c.form['repo_group'].render(css_class='medium', oid='repo_group')|n}
29 28 ${c.form.render_error(request, c.form['repo_group'])|n}
30 29
31 30 <p class="help-block">${_('Optional select a parent group to move this repository group into.')}</p>
32 31 </div>
33 32 </div>
34 33
35 34 <div class="field badged-field">
36 35 <div class="label">
37 36 <label for="repo_group_owner">${_('Owner')}:</label>
38 37 </div>
39 38 <div class="input">
40 39 <div class="badge-input-container">
41 40 <div class="user-badge">
42 41 ${base.gravatar(c.repo_group.user.email, user=c.repo_group.user, tooltip=True)}
43 42 </div>
44 43 <div class="badge-input-wrap">
45 44 ${c.form['repo_group_owner'].render(css_class='medium', oid='repo_group_owner')|n}
46 45 </div>
47 46 </div>
48 47 ${c.form.render_error(request, c.form['repo_group_owner'])|n}
49 48 <p class="help-block">${_('Change owner of this repository group.')}</p>
50 49 </div>
51 50 </div>
52 51
53 52 <div class="field">
54 53 <div class="label label-textarea">
55 54 <label for="repo_group_description">${_('Description')}:</label>
56 55 </div>
57 56 <div class="textarea text-area editor">
58 57 ${c.form['repo_group_description'].render(css_class='medium', oid='repo_group_description')|n}
59 58 ${c.form.render_error(request, c.form['repo_group_description'])|n}
60 59
61 60 <% metatags_url = h.literal('''<a href="#metatagsShow" onclick="$('#meta-tags-desc').toggle();return false">meta-tags</a>''') %>
62 61 <span class="help-block">
63 62 % if c.visual.stylify_metatags:
64 63 ${_('Plain text format with {metatags} support.').format(metatags=metatags_url)|n}
65 64 % else:
66 65 ${_('Plain text format.')}
67 66 % endif
68 67 </span>
69 68 <span id="meta-tags-desc" style="display: none">
70 69 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
71 70 ${dt.metatags_help()}
72 71 </span>
73 72 </div>
74 73 </div>
75 74
76 75 <div class="buttons">
77 76 ${h.submit('save',_('Save'),class_="btn")}
78 77 ${h.reset('reset',_('Reset'),class_="btn")}
79 78 </div>
80 79 </div>
81 80 </div>
82 81 ${h.end_form()}
83 82 </div>
84 83 </div>
85 84 <script>
86 85 $(document).ready(function(){
87 86 UsersAutoComplete('repo_group_owner', '${c.rhodecode_user.user_id}');
88 87 })
89 88 </script>
@@ -1,117 +1,116 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Repository groups administration')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='admin')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.admin_menu(active='repository_groups')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21 <div class="box">
23 22
24 23 <div class="title">
25 24 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
26 25 <span id="repo_group_count"></span>
27 26
28 27 <ul class="links">
29 28 %if c.can_create_repo_group:
30 29 <li>
31 30 <a href="${h.route_path('repo_group_new')}" class="btn btn-small btn-success">${_(u'Add Repository Group')}</a>
32 31 </li>
33 32 %endif
34 33 </ul>
35 34 </div>
36 35 <div id="repos_list_wrap">
37 36 <table id="group_list_table" class="display"></table>
38 37 </div>
39 38 </div>
40 39
41 40 <script>
42 41 $(document).ready(function() {
43 42 var $repoGroupsListTable = $('#group_list_table');
44 43
45 44 // repo group list
46 45 $repoGroupsListTable.DataTable({
47 46 processing: true,
48 47 serverSide: true,
49 48 ajax: {
50 49 "url": "${h.route_path('repo_groups_data')}",
51 50 "dataSrc": function (json) {
52 51 var filteredCount = json.recordsFiltered;
53 52 var filteredInactiveCount = json.recordsFilteredInactive;
54 53 var totalInactive = json.recordsTotalInactive;
55 54 var total = json.recordsTotal;
56 55
57 56 var _text = _gettext(
58 57 "{0} of {1} repository groups").format(
59 58 filteredCount, total);
60 59
61 60 if (total === filteredCount) {
62 61 _text = _gettext("{0} repository groups").format(total);
63 62 }
64 63 $('#repo_group_count').text(_text);
65 64 return json.data;
66 65 },
67 66 },
68 67
69 68 dom: 'rtp',
70 69 pageLength: ${c.visual.admin_grid_items},
71 70 order: [[ 0, "asc" ]],
72 71 columns: [
73 72 { data: {"_": "name",
74 73 "sort": "name"}, title: "${_('Name')}", className: "td-componentname" },
75 74 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
76 75 { data: {"_": "desc",
77 76 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
78 77 { data: {"_": "last_change",
79 78 "sort": "last_change",
80 79 "type": Number}, title: "${_('Last Change')}", className: "td-time" },
81 80 { data: {"_": "top_level_repos",
82 81 "sort": "top_level_repos"}, title: "${_('Number of top level repositories')}" },
83 82 { data: {"_": "owner",
84 83 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" },
85 84 { data: {"_": "action",
86 85 "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false }
87 86 ],
88 87 language: {
89 88 paginate: DEFAULT_GRID_PAGINATION,
90 89 sProcessing: _gettext('loading...'),
91 90 emptyTable: _gettext("No repository groups available yet.")
92 91 },
93 92 });
94 93
95 94 $repoGroupsListTable.on('xhr.dt', function(e, settings, json, xhr){
96 95 $repoGroupsListTable.css('opacity', 1);
97 96 });
98 97
99 98 $repoGroupsListTable.on('preXhr.dt', function(e, settings, data){
100 99 $repoGroupsListTable.css('opacity', 0.3);
101 100 });
102 101
103 102 // filter
104 103 $('#q_filter').on('keyup',
105 104 $.debounce(250, function() {
106 105 $repoGroupsListTable.DataTable().search(
107 106 $('#q_filter').val()
108 107 ).draw();
109 108 })
110 109 );
111 110
112 111 });
113 112
114 113 </script>
115 114
116 115 </%def>
117 116
@@ -1,37 +1,36 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Add repository')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 %if c.rhodecode_user.is_admin:
13 12 ${h.link_to(_('Admin'), h.route_path('admin_home'))}
14 13 &raquo;
15 14 ${h.link_to(_('Repositories'), h.route_path('repos'))}
16 15 %else:
17 16 ${_('Admin')}
18 17 &raquo;
19 18 ${_('Repositories')}
20 19 %endif
21 20 &raquo;
22 21 ${_('Add Repository')}
23 22 </%def>
24 23
25 24 <%def name="menu_bar_nav()">
26 25 ${self.menu_items(active='admin')}
27 26 </%def>
28 27
29 28 <%def name="menu_bar_subnav()">
30 29 ${self.admin_menu(active='repositories')}
31 30 </%def>
32 31
33 32 <%def name="main()">
34 33 <div class="box">
35 34 <%include file="repo_add_base.mako"/>
36 35 </div>
37 36 </%def>
@@ -1,169 +1,168 b''
1 ## -*- coding: utf-8 -*-
2 1
3 2 ${h.secure_form(h.route_path('repo_create'), request=request)}
4 3 <div class="form">
5 4 <!-- fields -->
6 5 <div class="fields">
7 6 <div class="field">
8 7 <div class="label">
9 8 <label for="repo_name">${_('Repository name')}:</label>
10 9 </div>
11 10 <div class="input">
12 11 ${h.text('repo_name', class_="medium")}
13 12 <div class="info-block">
14 13 <a id="remote_clone_toggle" href="#">${_('Import Existing Repository ?')}</a>
15 14 </div>
16 15 %if not c.rhodecode_user.is_admin:
17 16 ${h.hidden('user_created',True)}
18 17 %endif
19 18 </div>
20 19 </div>
21 20 <div id="remote_clone" class="field" style="display: none;">
22 21 <div class="label">
23 22 <label for="clone_uri">${_('Clone from')}:</label>
24 23 </div>
25 24 <div class="input">
26 25 ${h.text('clone_uri', class_="medium")}
27 26 <span class="help-block">
28 27 <pre>
29 28 - The repository must be accessible over http:// or https://
30 29 - For Git projects it's recommended appending .git to the end of clone url.
31 30 - Make sure to select proper repository type from the below selector before importing it.
32 31 - If your HTTP[S] repository is not publicly accessible,
33 32 add authentication information to the URL: https://username:password@server.company.com/repo-name.
34 33 - The Git LFS/Mercurial Largefiles objects will not be imported.
35 34 - For very large repositories, it's recommended to manually copy them into the
36 35 RhodeCode <a href="${h.route_path('admin_settings_vcs', _anchor='vcs-storage-options')}">storage location</a> and run <a href="${h.route_path('admin_settings_mapping')}">Remap and Rescan</a>.
37 36 </pre>
38 37 </span>
39 38 </div>
40 39 </div>
41 40 <div class="field">
42 41 <div class="label">
43 42 <label for="repo_group">${_('Repository group')}:</label>
44 43 </div>
45 44 <div class="select">
46 45 ${h.select('repo_group',request.GET.get('parent_group'),c.repo_groups,class_="medium")}
47 46 % if c.personal_repo_group:
48 47 <a class="btn" href="#" id="select_my_group" data-personal-group-id="${c.personal_repo_group.group_id}">
49 48 ${_('Select my personal group ({})').format(c.personal_repo_group.group_name)}
50 49 </a>
51 50 % endif
52 51 <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
53 52 </div>
54 53 </div>
55 54
56 55 <div class="field">
57 56 <div class="label">
58 57 <label for="repo_type">${_('Type')}:</label>
59 58 </div>
60 59 <div class="fields repo-type-radio">
61 60
62 61
63 62 % for backend in c.backends:
64 63 % if loop.index == 0:
65 64 <input id="repo_type_${backend}" name="repo_type" type="radio" value="${backend}" checked="checked"/>
66 65 % else:
67 66 <input id="repo_type_${backend}" name="repo_type" type="radio" value="${backend}" />
68 67 % endif
69 68
70 69 <label for="repo_type_${backend}">
71 70 <i class="icon-${backend}" style="font-size: 16px"></i>
72 71 ${backend.upper()}
73 72 </label>
74 73
75 74 % endfor
76 75
77 76
78 77 <span class="help-block">${_('Set the type of repository to create.')}</span>
79 78 </div>
80 79 </div>
81 80 <div class="field">
82 81 <div class="label">
83 82 <label for="repo_description">${_('Description')}:</label>
84 83 </div>
85 84 <div class="textarea editor">
86 85 ${h.textarea('repo_description',cols=23,rows=5,class_="medium")}
87 86 <% metatags_url = h.literal('''<a href="#metatagsShow" onclick="$('#meta-tags-desc').toggle();return false">meta-tags</a>''') %>
88 87 <span class="help-block">
89 88 % if c.visual.stylify_metatags:
90 89 ${_('Plain text format with {metatags} support.').format(metatags=metatags_url)|n}
91 90 % else:
92 91 ${_('Plain text format.')}
93 92 % endif
94 93 ${_('Add a README file for longer descriptions')}
95 94 </span>
96 95 <span id="meta-tags-desc" style="display: none">
97 96 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
98 97 ${dt.metatags_help()}
99 98 </span>
100 99 </div>
101 100 </div>
102 101 <div id="copy_perms" class="field">
103 102 <div class="label label-checkbox">
104 103 <label for="repo_copy_permissions">${_('Copy Parent Group Permissions')}:</label>
105 104 </div>
106 105 <div class="checkboxes">
107 106 ${h.checkbox('repo_copy_permissions', value="True", checked="checked")}
108 107 <span class="help-block">${_('Copy permissions from parent repository group.')}</span>
109 108 </div>
110 109 </div>
111 110 <div class="field">
112 111 <div class="label label-checkbox">
113 112 <label for="repo_private">${_('Private Repository')}:</label>
114 113 </div>
115 114 <div class="checkboxes">
116 115 ${h.checkbox('repo_private',value="True")}
117 116 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
118 117 </div>
119 118 </div>
120 119 <div class="buttons">
121 120 ${h.submit('save',_('Create Repository'),class_="btn")}
122 121 </div>
123 122 </div>
124 123 </div>
125 124 <script>
126 125 $(document).ready(function(){
127 126 var setCopyPermsOption = function(group_val){
128 127 if(group_val != "-1"){
129 128 $('#copy_perms').show()
130 129 }
131 130 else{
132 131 $('#copy_perms').hide();
133 132 }
134 133 };
135 134
136 135 $('#remote_clone_toggle').on('click', function(e){
137 136 $('#remote_clone').show();
138 137 e.preventDefault();
139 138 });
140 139
141 140 if($('#remote_clone input').hasClass('error')){
142 141 $('#remote_clone').show();
143 142 }
144 143 if($('#remote_clone input').val()){
145 144 $('#remote_clone').show();
146 145 }
147 146
148 147 $("#repo_group").select2({
149 148 'containerCssClass': "drop-menu",
150 149 'dropdownCssClass': "drop-menu-dropdown",
151 150 'dropdownAutoWidth': true,
152 151 'width': "resolve"
153 152 });
154 153
155 154 setCopyPermsOption($('#repo_group').val());
156 155 $("#repo_group").on("change", function(e) {
157 156 setCopyPermsOption(e.val)
158 157 });
159 158
160 159 $('#repo_name').focus();
161 160
162 161 $('#select_my_group').on('click', function(e){
163 162 e.preventDefault();
164 163 $("#repo_group").val($(this).data('personalGroupId')).trigger("change");
165 164 })
166 165
167 166 })
168 167 </script>
169 168 ${h.end_form()}
@@ -1,80 +1,79 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('{} Creating repository').format(c.repo_name)}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${_('Creating repository')} ${c.repo_name}
13 12 </%def>
14 13
15 14 <%def name="menu_bar_nav()">
16 15 ${self.menu_items(active='repositories')}
17 16 </%def>
18 17 <%def name="main()">
19 18 <div class="box">
20 19 <!-- box / title -->
21 20 <div class="title">
22 21 ${self.breadcrumbs()}
23 22 </div>
24 23
25 24 <div id="progress-message">
26 25 ${_('Repository "%(repo_name)s" is being created, you will be redirected when this process is finished.' % {'repo_name':c.repo_name})}
27 26 </div>
28 27
29 28 <div id="progress">
30 29 <div class="progress progress-striped active">
31 30 <div class="progress-bar progress-bar" role="progressbar"
32 31 aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
33 32 </div>
34 33 </div>
35 34 </div>
36 35 </div>
37 36
38 37 <script>
39 38 (function worker() {
40 39 var skipCheck = false;
41 40 var url = "${h.route_path('repo_creating_check', repo_name=c.repo_name, _query=dict(task_id=c.task_id))}";
42 41 $.ajax({
43 42 url: url,
44 43 timeout: 60*1000, // sets timeout to 60 seconds
45 44 complete: function(resp) {
46 45 if (resp.status === 200) {
47 46 var jsonResponse = resp.responseJSON;
48 47
49 48 if (jsonResponse === undefined) {
50 49 setTimeout(function () {
51 50 // we might have a backend problem, try dashboard again
52 51 window.location = "${h.route_path('repo_summary', repo_name = c.repo_name)}";
53 52 }, 3000);
54 53 } else {
55 54 if (skipCheck || jsonResponse.result === true) {
56 55 // success, means go to dashboard
57 56 window.location = "${h.route_path('repo_summary', repo_name = c.repo_name)}";
58 57 } else {
59 58 // Schedule the next request when the current one's complete
60 59 setTimeout(worker, 1000);
61 60 }
62 61 }
63 62 }
64 63 else {
65 64 var currentUrl = "${h.current_route_path(request)}";
66 65 var message = _gettext('Fetching repository state failed. Error code: {0} {1}. Try <a href="{2}">refreshing</a> this page.').format(resp.status, resp.statusText, currentUrl);
67 66 var payload = {
68 67 message: {
69 68 message: message,
70 69 level: 'error',
71 70 force: true
72 71 }
73 72 };
74 73 $.Topic('/notifications').publish(payload);
75 74 }
76 75 }
77 76 });
78 77 })();
79 78 </script>
80 79 </%def>
@@ -1,104 +1,103 b''
1 ## -*- coding: utf-8 -*-
2 1 ##
3 2 ## See also repo_settings.html
4 3 ##
5 4 <%inherit file="/base/base.mako"/>
6 5
7 6 <%def name="title()">
8 7 ${_('{} repository settings').format(c.rhodecode_db_repo.repo_name)}
9 8 %if c.rhodecode_name:
10 9 &middot; ${h.branding(c.rhodecode_name)}
11 10 %endif
12 11 </%def>
13 12
14 13 <%def name="breadcrumbs_links()">
15 14 ${_('Settings')}
16 15 </%def>
17 16
18 17 <%def name="menu_bar_nav()">
19 18 ${self.menu_items(active='repositories')}
20 19 </%def>
21 20
22 21 <%def name="menu_bar_subnav()">
23 22 ${self.repo_menu(active='settings')}
24 23 </%def>
25 24
26 25 <%def name="main_content()">
27 26 % if hasattr(c, 'repo_edit_template'):
28 27 <%include file="${c.repo_edit_template}"/>
29 28 % else:
30 29 <%include file="/admin/repos/repo_edit_${c.active}.mako"/>
31 30 % endif
32 31 </%def>
33 32
34 33
35 34 <%def name="main()">
36 35 <div class="box">
37 36
38 37 <div class="sidebar-col-wrapper scw-small">
39 38 <div class="sidebar">
40 39 <ul class="nav nav-pills nav-stacked">
41 40 <li class="${h.is_active('settings', c.active)}">
42 41 <a href="${h.route_path('edit_repo', repo_name=c.repo_name)}">${_('Settings')}</a>
43 42 </li>
44 43 <li class="${h.is_active('permissions', c.active)}">
45 44 <a href="${h.route_path('edit_repo_perms', repo_name=c.repo_name)}">${_('Access Permissions')}</a>
46 45 </li>
47 46 <li class="${h.is_active('permissions_branch', c.active)}">
48 47 <a href="${h.route_path('edit_repo_perms_branch', repo_name=c.repo_name)}">${_('Branch Permissions')}</a>
49 48 </li>
50 49 <li class="${h.is_active('advanced', c.active)}">
51 50 <a href="${h.route_path('edit_repo_advanced', repo_name=c.repo_name)}">${_('Advanced')}</a>
52 51 </li>
53 52 <li class="${h.is_active('vcs', c.active)}">
54 53 <a href="${h.route_path('edit_repo_vcs', repo_name=c.repo_name)}">${_('VCS')}</a>
55 54 </li>
56 55 <li class="${h.is_active('fields', c.active)}">
57 56 <a href="${h.route_path('edit_repo_fields', repo_name=c.repo_name)}">${_('Extra Fields')}</a>
58 57 </li>
59 58 <li class="${h.is_active('issuetracker', c.active)}">
60 59 <a href="${h.route_path('edit_repo_issuetracker', repo_name=c.repo_name)}">${_('Issue Tracker')}</a>
61 60 </li>
62 61 <li class="${h.is_active('caches', c.active)}">
63 62 <a href="${h.route_path('edit_repo_caches', repo_name=c.repo_name)}">${_('Caches')}</a>
64 63 </li>
65 64 %if c.rhodecode_db_repo.repo_type != 'svn':
66 65 <li class="${h.is_active('remote', c.active)}">
67 66 <a href="${h.route_path('edit_repo_remote', repo_name=c.repo_name)}">${_('Remote sync')}</a>
68 67 </li>
69 68 %endif
70 69 <li class="${h.is_active('statistics', c.active)}">
71 70 <a href="${h.route_path('edit_repo_statistics', repo_name=c.repo_name)}">${_('Statistics')}</a>
72 71 </li>
73 72 <li class="${h.is_active('integrations', c.active)}">
74 73 <a href="${h.route_path('repo_integrations_home', repo_name=c.repo_name)}">${_('Integrations')}</a>
75 74 </li>
76 75 %if c.rhodecode_db_repo.repo_type != 'svn':
77 76 <li class="${h.is_active('reviewers', c.active)}">
78 77 <a href="${h.route_path('repo_reviewers', repo_name=c.repo_name)}">${_('Reviewer Rules')}</a>
79 78 </li>
80 79 %endif
81 80 <li class="${h.is_active('automation', c.active)}">
82 81 <a href="${h.route_path('repo_automation', repo_name=c.repo_name)}">${_('Automation')}</a>
83 82 </li>
84 83 <li class="${h.is_active('maintenance', c.active)}">
85 84 <a href="${h.route_path('edit_repo_maintenance', repo_name=c.repo_name)}">${_('Maintenance')}</a>
86 85 </li>
87 86 <li class="${h.is_active('strip', c.active)}">
88 87 <a href="${h.route_path('edit_repo_strip', repo_name=c.repo_name)}">${_('Strip')}</a>
89 88 </li>
90 89 <li class="${h.is_active('audit', c.active)}">
91 90 <a href="${h.route_path('edit_repo_audit_logs', repo_name=c.repo_name)}">${_('Audit logs')}</a>
92 91 </li>
93 92
94 93 </ul>
95 94 </div>
96 95
97 96 <div class="main-content-full-width">
98 97 ${self.main_content()}
99 98 </div>
100 99
101 100 </div>
102 101 </div>
103 102
104 103 </%def> No newline at end of file
@@ -1,24 +1,23 b''
1 ## -*- coding: utf-8 -*-
2 1 <%namespace name="base" file="/base/base.mako"/>
3 2
4 3
5 4 <div class="panel panel-default">
6 5 <div class="panel-heading">
7 6 <h3 class="panel-title">${_('Repository Audit Logs')} -
8 7 ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)}
9 8 </h3>
10 9 </div>
11 10 <div class="panel-body">
12 11
13 12 ${h.form(None, id_="filter_form", method="get")}
14 13 <input class="q_filter_box ${'' if c.filter_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.filter_term or ''}" placeholder="${_('audit filter...')}"/>
15 14 <input type='submit' value="${_('filter')}" class="btn" />
16 15 ${h.end_form()}
17 16
18 17 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
19 18 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
20 19
21 20 <%include file="/admin/admin_log_base.mako" />
22 21
23 22 </div>
24 23 </div>
@@ -1,337 +1,336 b''
1 ## -*- coding: utf-8 -*-
2 1 <%namespace name="base" file="/base/base.mako"/>
3 2
4 3 <div class="panel panel-default">
5 4 <div class="panel-heading">
6 5 <h3 class="panel-title">${_('Settings for Repository: %s') % c.rhodecode_db_repo.repo_name}</h3>
7 6 </div>
8 7 <div class="panel-body">
9 8 ${h.secure_form(h.route_path('edit_repo', repo_name=c.rhodecode_db_repo.repo_name), request=request)}
10 9 <div class="form">
11 10 <!-- fields -->
12 11 <div class="fields">
13 12
14 13 <div class="field">
15 14 <div class="label">
16 15 <label for="repo_name">${_('Name')}:</label>
17 16 </div>
18 17 <div class="input">
19 18 ${c.form['repo_name'].render(css_class='medium', oid='repo_name')|n}
20 19 ${c.form.render_error(request, c.form['repo_name'])|n}
21 20
22 21 <p class="help-block">${_('permalink id')}: `_${c.rhodecode_db_repo.repo_id}` <span><a href="#" onclick="$('#clone_id').toggle();return false">${_('what is that ?')}</a></span></p>
23 22 <p id="clone_id" style="display:none;">
24 23 ${_('URL by id')}: `${c.rhodecode_db_repo.clone_url(with_id=True)}` <br/>
25 24 ${_('''In case this repository is renamed or moved into another group the repository url changes.
26 25 Using above url guarantees that this repository will always be accessible under such url.
27 26 Useful for CI systems, or any other cases that you need to hardcode the url into 3rd party service.''')}</p>
28 27 </div>
29 28 </div>
30 29
31 30 <div class="field">
32 31 <div class="label">
33 32 <label for="repo_group">${_('Repository group')}:</label>
34 33 </div>
35 34 <div class="select">
36 35 ${c.form['repo_group'].render(css_class='medium', oid='repo_group')|n}
37 36 ${c.form.render_error(request, c.form['repo_group'])|n}
38 37
39 38 % if c.personal_repo_group:
40 39 <a class="btn" href="#" data-personal-group-name="${c.personal_repo_group.group_name}" data-personal-group-id="${c.personal_repo_group.group_id}" onclick="selectMyGroup(this); return false">
41 40 ${_('Select my personal group (`%(repo_group_name)s`)') % {'repo_group_name': c.personal_repo_group.group_name}}
42 41 </a>
43 42 % endif
44 43 <p class="help-block">${_('Optional select a group to put this repository into.')}</p>
45 44 </div>
46 45 </div>
47 46
48 47 % if c.rhodecode_db_repo.repo_type != 'svn':
49 48 <% sync_link = h.literal(h.link_to('remote sync', h.route_path('edit_repo_remote', repo_name=c.repo_name))) %>
50 49 <div class="field">
51 50 <div class="label">
52 51 <label for="clone_uri">${_('Remote pull uri')}:</label>
53 52 </div>
54 53 <div class="input">
55 54 %if c.rhodecode_db_repo.clone_uri:
56 55 ## display, if we don't have any errors
57 56 % if not c.form['repo_clone_uri'].error:
58 57 <div id="clone_uri_hidden" class='text-as-placeholder'>
59 58 <span id="clone_uri_hidden_value">${c.rhodecode_db_repo.clone_uri_hidden}</span>
60 59 <span class="link" id="edit_clone_uri">${_('edit')}</span>
61 60 </div>
62 61 % endif
63 62
64 63 ## alter field
65 64 <div id="alter_clone_uri" style="${'' if c.form['repo_clone_uri'].error else 'display: none'}">
66 65 ${c.form['repo_clone_uri'].render(css_class='medium', oid='clone_uri', placeholder=_('enter new value, or leave empty to remove'))|n}
67 66 ${c.form.render_error(request, c.form['repo_clone_uri'])|n}
68 67 % if c.form['repo_clone_uri'].error:
69 68 ## we got error from form subit, means we modify the url
70 69 ${h.hidden('repo_clone_uri_change', 'MOD')}
71 70 % else:
72 71 ${h.hidden('repo_clone_uri_change', 'OLD')}
73 72 % endif
74 73
75 74 % if not c.form['repo_clone_uri'].error:
76 75 <span class="link" id="cancel_edit_clone_uri">${_('cancel')}</span>
77 76 % endif
78 77
79 78 </div>
80 79 %else:
81 80 ## not set yet, display form to set it
82 81 ${c.form['repo_clone_uri'].render(css_class='medium', oid='clone_uri')|n}
83 82 ${c.form.render_error(request, c.form['repo_clone_uri'])|n}
84 83 ${h.hidden('repo_clone_uri_change', 'NEW')}
85 84 %endif
86 85 <p id="alter_clone_uri_help_block" class="help-block">
87 86 ${_('http[s] url where from repository was imported. This field can used for doing {sync_link}.').format(sync_link=sync_link)|n} <br/>
88 87 ${_('This field is stored encrypted inside Database, a format of http://user:password@server.com/repo_name can be used and will be hidden from display.')}
89 88 </p>
90 89 </div>
91 90 </div>
92 91 <div class="field">
93 92 <div class="label">
94 93 <label for="push_uri">${_('Remote push uri')}:</label>
95 94 </div>
96 95 <div class="input">
97 96 %if c.rhodecode_db_repo.push_uri:
98 97 ## display, if we don't have any errors
99 98 % if not c.form['repo_push_uri'].error:
100 99 <div id="push_uri_hidden" class='text-as-placeholder'>
101 100 <span id="push_uri_hidden_value">${c.rhodecode_db_repo.push_uri_hidden}</span>
102 101 <span class="link" id="edit_push_uri">${_('edit')}</span>
103 102 </div>
104 103 % endif
105 104
106 105 ## alter field
107 106 <div id="alter_push_uri" style="${'' if c.form['repo_push_uri'].error else 'display: none'}">
108 107 ${c.form['repo_push_uri'].render(css_class='medium', oid='push_uri', placeholder=_('enter new value, or leave empty to remove'))|n}
109 108 ${c.form.render_error(request, c.form['repo_push_uri'])|n}
110 109 % if c.form['repo_push_uri'].error:
111 110 ## we got error from form subit, means we modify the url
112 111 ${h.hidden('repo_push_uri_change', 'MOD')}
113 112 % else:
114 113 ${h.hidden('repo_push_uri_change', 'OLD')}
115 114 % endif
116 115
117 116 % if not c.form['repo_push_uri'].error:
118 117 <span class="link" id="cancel_edit_push_uri">${_('cancel')}</span>
119 118 % endif
120 119
121 120 </div>
122 121 %else:
123 122 ## not set yet, display form to set it
124 123 ${c.form['repo_push_uri'].render(css_class='medium', oid='push_uri')|n}
125 124 ${c.form.render_error(request, c.form['repo_push_uri'])|n}
126 125 ${h.hidden('repo_push_uri_change', 'NEW')}
127 126 %endif
128 127 <p id="alter_push_uri_help_block" class="help-block">
129 128 ${_('http[s] url to sync data back. This field can used for doing {sync_link}.').format(sync_link=sync_link)|n} <br/>
130 129 ${_('This field is stored encrypted inside Database, a format of http://user:password@server.com/repo_name can be used and will be hidden from display.')}
131 130 </p>
132 131 </div>
133 132 </div>
134 133 % else:
135 134 ${h.hidden('repo_clone_uri', '')}
136 135 ${h.hidden('repo_push_uri', '')}
137 136 % endif
138 137
139 138 <div class="field">
140 139 <div class="label">
141 140 <label for="repo_landing_commit_ref">${_('Landing commit')}:</label>
142 141 </div>
143 142 <div class="select">
144 143 ${c.form['repo_landing_commit_ref'].render(css_class='medium', oid='repo_landing_commit_ref')|n}
145 144 ${c.form.render_error(request, c.form['repo_landing_commit_ref'])|n}
146 145 <p class="help-block">${_('The default commit for file pages, downloads, full text search index, and README generation.')}</p>
147 146 </div>
148 147 </div>
149 148
150 149 <div class="field badged-field">
151 150 <div class="label">
152 151 <label for="repo_owner">${_('Owner')}:</label>
153 152 </div>
154 153 <div class="input">
155 154 <div class="badge-input-container">
156 155 <div class="user-badge">
157 156 ${base.gravatar(c.rhodecode_db_repo.user.email or c.rhodecode_db_repo.user.username, user=c.rhodecode_db_repo.user, tooltip=True)}
158 157 </div>
159 158 <div class="badge-input-wrap">
160 159 ${c.form['repo_owner'].render(css_class='medium', oid='repo_owner')|n}
161 160 </div>
162 161 </div>
163 162 ${c.form.render_error(request, c.form['repo_owner'])|n}
164 163 <p class="help-block">${_('Change owner of this repository.')}</p>
165 164 </div>
166 165 </div>
167 166
168 167 <div class="field">
169 168 <div class="label label-textarea">
170 169 <label for="repo_description">${_('Description')}:</label>
171 170 </div>
172 171 <div class="textarea text-area editor">
173 172 ${c.form['repo_description'].render(css_class='medium', oid='repo_description')|n}
174 173 ${c.form.render_error(request, c.form['repo_description'])|n}
175 174
176 175 <% metatags_url = h.literal('''<a href="#metatagsShow" onclick="$('#meta-tags-desc').toggle();return false">meta-tags</a>''') %>
177 176 <span class="help-block">
178 177 % if c.visual.stylify_metatags:
179 178 ${_('Plain text format with {metatags} support.').format(metatags=metatags_url)|n}
180 179 % else:
181 180 ${_('Plain text format.')}
182 181 % endif
183 182 ${_('Add a README file for longer descriptions')}
184 183 </span>
185 184 <span id="meta-tags-desc" style="display: none">
186 185 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
187 186 ${dt.metatags_help()}
188 187 </span>
189 188 </div>
190 189 </div>
191 190
192 191 <div class="field">
193 192 <div class="label label-checkbox">
194 193 <label for="${c.form['repo_private'].oid}">${_('Private repository')}:</label>
195 194 </div>
196 195 <div class="checkboxes">
197 196 ${c.form['repo_private'].render(css_class='medium')|n}
198 197 ${c.form.render_error(request, c.form['repo_private'])|n}
199 198 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
200 199 </div>
201 200 </div>
202 201 <div class="field">
203 202 <div class="label label-checkbox">
204 203 <label for="${c.form['repo_enable_statistics'].oid}">${_('Enable statistics')}:</label>
205 204 </div>
206 205 <div class="checkboxes">
207 206 ${c.form['repo_enable_statistics'].render(css_class='medium')|n}
208 207 ${c.form.render_error(request, c.form['repo_enable_statistics'])|n}
209 208 <span class="help-block">${_('Enable statistics window on summary page.')}</span>
210 209 </div>
211 210 </div>
212 211 <div class="field">
213 212 <div class="label label-checkbox">
214 213 <label for="${c.form['repo_enable_downloads'].oid}">${_('Enable downloads')}:</label>
215 214 </div>
216 215 <div class="checkboxes">
217 216 ${c.form['repo_enable_downloads'].render(css_class='medium')|n}
218 217 ${c.form.render_error(request, c.form['repo_enable_downloads'])|n}
219 218 <span class="help-block">${_('Enable download menu on summary page.')}</span>
220 219 </div>
221 220 </div>
222 221 <div class="field">
223 222 <div class="label label-checkbox">
224 223 <label for="${c.form['repo_enable_locking'].oid}">${_('Enable automatic locking')}:</label>
225 224 </div>
226 225 <div class="checkboxes">
227 226 ${c.form['repo_enable_locking'].render(css_class='medium')|n}
228 227 ${c.form.render_error(request, c.form['repo_enable_locking'])|n}
229 228 <span class="help-block">${_('Enable automatic locking on repository. Pulling from this repository creates a lock that can be released by pushing back by the same user')}</span>
230 229 </div>
231 230 </div>
232 231
233 232 %if c.visual.repository_fields:
234 233 ## EXTRA FIELDS
235 234 %for field in c.repo_fields:
236 235 <div class="field">
237 236 <div class="label">
238 237 <label for="${field.field_key_prefixed}">${(field.field_label or field.field_key)}:</label>
239 238 </div>
240 239 <div class="input input-medium">
241 240 ${h.text(field.field_key_prefixed, field.field_value, class_='medium')}
242 241 <span class="help-block">
243 242 key: ${field.field_key};
244 243 ${field.field_desc}
245 244 </span>
246 245 </div>
247 246 </div>
248 247 %endfor
249 248 %endif
250 249 <div class="buttons">
251 250 ${h.submit('save',_('Save'),class_="btn")}
252 251 ${h.reset('reset',_('Reset'),class_="btn")}
253 252 </div>
254 253 </div>
255 254 </div>
256 255 ${h.end_form()}
257 256 </div>
258 257 </div>
259 258
260 259 <script>
261 260 $(document).ready(function () {
262 261 var cloneUrl = function (
263 262 alterButton, editButton, cancelEditButton,
264 263 hiddenUrl, hiddenUrlValue, input, helpBlock, changedFlag) {
265 264
266 265 var originalText = helpBlock.html();
267 266 var obfuscatedUrl = hiddenUrlValue.html();
268 267
269 268 var edit = function(e) {
270 269 alterButton.show();
271 270 editButton.hide();
272 271 hiddenUrl.hide();
273 272
274 273 //add the old value next to input for verification
275 274 helpBlock.html("(" + obfuscatedUrl + ")" + "<br\>" + originalText);
276 275 changedFlag.val('MOD');
277 276 };
278 277
279 278 var cancelEdit = function(e) {
280 279 alterButton.hide();
281 280 editButton.show();
282 281 hiddenUrl.show();
283 282
284 283 helpBlock.html(originalText);
285 284 changedFlag.val('OLD');
286 285 input.val('');
287 286 };
288 287
289 288 var initEvents = function() {
290 289 editButton.on('click', edit);
291 290 cancelEditButton.on('click', cancelEdit);
292 291 };
293 292
294 293 var setInitialState = function() {
295 294 if (input.hasClass('error')) {
296 295 alterButton.show();
297 296 editButton.hide();
298 297 hiddenUrl.hide();
299 298 }
300 299 };
301 300
302 301 setInitialState();
303 302 initEvents();
304 303 };
305 304
306 305
307 306 var alterButton = $('#alter_clone_uri');
308 307 var editButton = $('#edit_clone_uri');
309 308 var cancelEditButton = $('#cancel_edit_clone_uri');
310 309 var hiddenUrl = $('#clone_uri_hidden');
311 310 var hiddenUrlValue = $('#clone_uri_hidden_value');
312 311 var input = $('#clone_uri');
313 312 var helpBlock = $('#alter_clone_uri_help_block');
314 313 var changedFlag = $('#repo_clone_uri_change');
315 314 cloneUrl(
316 315 alterButton, editButton, cancelEditButton, hiddenUrl,
317 316 hiddenUrlValue, input, helpBlock, changedFlag);
318 317
319 318 var alterButton = $('#alter_push_uri');
320 319 var editButton = $('#edit_push_uri');
321 320 var cancelEditButton = $('#cancel_edit_push_uri');
322 321 var hiddenUrl = $('#push_uri_hidden');
323 322 var hiddenUrlValue = $('#push_uri_hidden_value');
324 323 var input = $('#push_uri');
325 324 var helpBlock = $('#alter_push_uri_help_block');
326 325 var changedFlag = $('#repo_push_uri_change');
327 326 cloneUrl(
328 327 alterButton, editButton, cancelEditButton, hiddenUrl,
329 328 hiddenUrlValue, input, helpBlock, changedFlag);
330 329
331 330 selectMyGroup = function(element) {
332 331 $("#repo_group").val($(element).data('personalGroupId')).trigger("change");
333 332 };
334 333
335 334 UsersAutoComplete('repo_owner', '${c.rhodecode_user.user_id}');
336 335 });
337 336 </script>
@@ -1,149 +1,148 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Repositories administration')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='admin')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.admin_menu(active='repositories')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21 <div class="box">
23 22
24 23 <div class="title">
25 24 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
26 25 <span id="repo_count"></span>
27 26
28 27 <ul class="links">
29 28 %if c.can_create_repo:
30 29 <li>
31 30 <a href="${h.route_path('repo_new')}" class="btn btn-small btn-success">${_(u'Add Repository')}</a>
32 31 </li>
33 32 %endif
34 33 </ul>
35 34 </div>
36 35 <div id="repos_list_wrap">
37 36 <table id="repo_list_table" class="display"></table>
38 37 </div>
39 38
40 39 </div>
41 40
42 41 <script>
43 42 $(document).ready(function() {
44 43 var $repoListTable = $('#repo_list_table');
45 44
46 45 // repo list
47 46 $repoListTable.DataTable({
48 47 processing: true,
49 48 serverSide: true,
50 49 ajax: {
51 50 "url": "${h.route_path('repos_data')}",
52 51 "dataSrc": function (json) {
53 52 var filteredCount = json.recordsFiltered;
54 53 var total = json.recordsTotal;
55 54
56 55 var _text = _gettext(
57 56 "{0} of {1} repositories").format(
58 57 filteredCount, total);
59 58
60 59 if (total === filteredCount) {
61 60 _text = _gettext("{0} repositories").format(total);
62 61 }
63 62 $('#repo_count').text(_text);
64 63
65 64 return json.data;
66 65 },
67 66 },
68 67 dom: 'rtp',
69 68 pageLength: ${c.visual.admin_grid_items},
70 69 order: [[ 0, "asc" ]],
71 70 columns: [
72 71 {
73 72 data: {
74 73 "_": "name",
75 74 "sort": "name"
76 75 }, title: "${_('Name')}", className: "td-componentname"
77 76 },
78 77 {
79 78 data: 'menu', "bSortable": false, className: "quick_repo_menu"},
80 79 {
81 80 data: {
82 81 "_": "desc",
83 82 "sort": "desc"
84 83 }, title: "${_('Description')}", className: "td-description"
85 84 },
86 85 {
87 86 data: {
88 87 "_": "last_change",
89 88 "sort": "last_change",
90 89 "type": Number
91 90 }, title: "${_('Last Change')}", className: "td-time"
92 91 },
93 92 {
94 93 data: {
95 94 "_": "last_changeset",
96 95 "sort": "last_changeset_raw",
97 96 "type": Number
98 97 }, title: "${_('Commit')}", className: "td-commit", orderable: false
99 98 },
100 99 {
101 100 data: {
102 101 "_": "owner",
103 102 "sort": "owner"
104 103 }, title: "${_('Owner')}", className: "td-user"
105 104 },
106 105 {
107 106 data: {
108 107 "_": "state",
109 108 "sort": "state"
110 109 }, title: "${_('State')}", className: "td-tags td-state"
111 110 },
112 111 {
113 112 data: {
114 113 "_": "action",
115 114 "sort": "action"
116 115 }, title: "${_('Action')}", className: "td-action", orderable: false
117 116 }
118 117 ],
119 118 language: {
120 119 paginate: DEFAULT_GRID_PAGINATION,
121 120 sProcessing: _gettext('loading...'),
122 121 emptyTable:_gettext("No repositories present.")
123 122 },
124 123 "initComplete": function( settings, json ) {
125 124 quick_repo_menu();
126 125 }
127 126 });
128 127
129 128 $repoListTable.on('xhr.dt', function(e, settings, json, xhr){
130 129 $repoListTable.css('opacity', 1);
131 130 });
132 131
133 132 $repoListTable.on('preXhr.dt', function(e, settings, data){
134 133 $repoListTable.css('opacity', 0.3);
135 134 });
136 135
137 136 $('#q_filter').on('keyup',
138 137 $.debounce(250, function() {
139 138 $repoListTable.DataTable().search(
140 139 $('#q_filter').val()
141 140 ).draw();
142 141 })
143 142 );
144 143
145 144 });
146 145
147 146 </script>
148 147
149 148 </%def>
@@ -1,54 +1,53 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Settings administration')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 12 &raquo;
14 13 ${_('Settings')}
15 14 </%def>
16 15 ##
17 16 <%def name="menu_bar_nav()">
18 17 ${self.menu_items(active='admin')}
19 18 </%def>
20 19
21 20 <%def name="menu_bar_subnav()">
22 21 ${self.admin_menu(active='settings')}
23 22 </%def>
24 23
25 24 <%def name="side_bar_nav()">
26 25 % for navitem in c.navlist:
27 26 <li class="${h.is_active(navitem.active_list, c.active)}">
28 27 <a href="${navitem.url}">${navitem.name}</a>
29 28 </li>
30 29 % endfor
31 30 </%def>
32 31
33 32 <%def name="main_content()">
34 33 <%include file="/admin/settings/settings_${c.active}.mako"/>
35 34 </%def>
36 35
37 36 <%def name="main()">
38 37 <div class="box">
39 38
40 39 ##main
41 40 <div class='sidebar-col-wrapper'>
42 41 <div class="sidebar">
43 42 <ul class="nav nav-pills nav-stacked">
44 43 ${self.side_bar_nav()}
45 44 </ul>
46 45 </div>
47 46
48 47 <div class="main-content-auto-width">
49 48 ${self.main_content()}
50 49 </div>
51 50 </div>
52 51 </div>
53 52
54 53 </%def> No newline at end of file
@@ -1,26 +1,25 b''
1 ## -*- coding: utf-8 -*-
2 1 ## upgrade block rendered afte on-click check
3 2
4 3 <div class="alert ${'alert-warning' if c.should_upgrade else 'alert-success'}">
5 4 <p>
6 5 %if c.should_upgrade:
7 6 A <b>new version</b> is available:
8 7 %if c.latest_data.get('title'):
9 8 <b>${h.literal(c.latest_data['title'])}</b>
10 9 %else:
11 10 <b>${c.latest_ver}</b>
12 11 %endif
13 12 %else:
14 13 This instance is already running the <b>latest</b> stable version ${c.latest_ver}.
15 14 %endif
16 15 </p>
17 16
18 17 % if c.should_upgrade and c.important_notices:
19 18 <div>Important notes for this release:</div>
20 19 <ul>
21 20 % for notice in c.important_notices:
22 21 <li>- ${notice}</li>
23 22 % endfor
24 23 </ul>
25 24 % endif
26 25 </div>
@@ -1,71 +1,70 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Add user group')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9 <%def name="breadcrumbs_links()">
11 10 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 11 &raquo;
13 12 ${h.link_to(_('User groups'),h.route_path('user_groups'))}
14 13 &raquo;
15 14 ${_('Add User Group')}
16 15 </%def>
17 16
18 17 <%def name="menu_bar_nav()">
19 18 ${self.menu_items(active='admin')}
20 19 </%def>
21 20
22 21 <%def name="menu_bar_subnav()">
23 22 ${self.admin_menu(active='user_groups')}
24 23 </%def>
25 24
26 25 <%def name="main()">
27 26 <div class="box main-content">
28 27 ${h.secure_form(h.route_path('user_groups_create'), request=request)}
29 28 <div class="form">
30 29 <!-- fields -->
31 30 <div class="fields">
32 31 <div class="field">
33 32 <div class="label">
34 33 <label for="users_group_name">${_('Group name')}:</label>
35 34 </div>
36 35 <div class="input">
37 36 ${h.text('users_group_name', class_='medium')}
38 37 </div>
39 38 </div>
40 39 <div class="field">
41 40 <div class="label">
42 41 <label for="user_group_description">${_('Description')}:</label>
43 42 </div>
44 43 <div class="textarea editor">
45 44 ${h.textarea('user_group_description')}
46 45 <span class="help-block">${_('Short, optional description for this user group.')}</span>
47 46 </div>
48 47 </div>
49 48 <div class="field">
50 49 <div class="label">
51 50 <label for="users_group_active">${_('Active')}:</label>
52 51 </div>
53 52 <div class="checkboxes">
54 53 ${h.checkbox('users_group_active',value=True, checked='checked')}
55 54 </div>
56 55 </div>
57 56
58 57 <div class="buttons">
59 58 ${h.submit('save',_('Create User Group'),class_="btn")}
60 59 </div>
61 60 </div>
62 61 </div>
63 62 ${h.end_form()}
64 63 </div>
65 64 </%def>
66 65
67 66 <script>
68 67 $(document).ready(function(){
69 68 $('#users_group_name').focus();
70 69 })
71 70 </script>
@@ -1,47 +1,46 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('{} user group settings').format(c.user_group.users_group_name)}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 12 &raquo;
14 13 ${h.link_to(_('User Groups'),h.route_path('user_groups'))}
15 14 &raquo;
16 15 ${c.user_group.users_group_name}
17 16 </%def>
18 17
19 18 <%def name="menu_bar_nav()">
20 19 ${self.menu_items(active='admin')}
21 20 </%def>
22 21
23 22 <%def name="menu_bar_subnav()">
24 23 ${self.admin_menu(active='user_groups')}
25 24 </%def>
26 25
27 26 <%def name="main()">
28 27 <div class="box">
29 28
30 29 ##main
31 30 <div class="sidebar-col-wrapper">
32 31 <div class="sidebar">
33 32 <ul class="nav nav-pills nav-stacked">
34 33 <li class="${h.is_active('settings', c.active)}"><a href="${h.route_path('edit_user_group', user_group_id=c.user_group.users_group_id)}">${_('Settings')}</a></li>
35 34 <li class="${h.is_active('perms', c.active)}"><a href="${h.route_path('edit_user_group_perms', user_group_id=c.user_group.users_group_id)}">${_('Permissions')}</a></li>
36 35 <li class="${h.is_active('advanced', c.active)}"><a href="${h.route_path('edit_user_group_advanced', user_group_id=c.user_group.users_group_id)}">${_('Advanced')}</a></li>
37 36 <li class="${h.is_active('global_perms', c.active)}"><a href="${h.route_path('edit_user_group_global_perms', user_group_id=c.user_group.users_group_id)}">${_('Global permissions')}</a></li>
38 37 <li class="${h.is_active('perms_summary', c.active)}"><a href="${h.route_path('edit_user_group_perms_summary', user_group_id=c.user_group.users_group_id)}">${_('Permissions summary')}</a></li>
39 38 </ul>
40 39 </div>
41 40
42 41 <div class="main-content-full-width">
43 42 <%include file="/admin/user_groups/user_group_edit_${c.active}.mako"/>
44 43 </div>
45 44 </div>
46 45 </div>
47 46 </%def>
@@ -1,191 +1,190 b''
1 ## -*- coding: utf-8 -*-
2 1 <%namespace name="base" file="/base/base.mako"/>
3 2
4 3 <div class="panel panel-default">
5 4 <div class="panel-heading">
6 5 <h3 class="panel-title">
7 6 <i class="icon-user-group" title="${_('User group')}"></i>
8 7 ${h.link_to_group(c.user_group.users_group_name)}
9 8 - ${_('Settings')}
10 9 </h3>
11 10 </div>
12 11 <div class="panel-body">
13 12 ${h.secure_form(h.route_path('user_groups_update', user_group_id=c.user_group.users_group_id), id='edit_user_group', request=request)}
14 13 <div class="form">
15 14 <!-- fields -->
16 15 <div class="fields">
17 16 <div class="field">
18 17 <div class="label">
19 18 <label for="users_group_name">${_('Group name')}:</label>
20 19 </div>
21 20 <div class="input">
22 21 ${h.text('users_group_name',class_='medium')}
23 22 </div>
24 23 </div>
25 24
26 25 <div class="field badged-field">
27 26 <div class="label">
28 27 <label for="user">${_('Owner')}:</label>
29 28 </div>
30 29 <div class="input">
31 30 <div class="badge-input-container">
32 31 <div class="user-badge">
33 32 ${base.gravatar(c.user_group.user.email, user=c.user_group.user, tooltip=True)}
34 33 </div>
35 34 <div class="badge-input-wrap">
36 35 ${h.text('user', class_="medium", autocomplete="off")}
37 36 </div>
38 37 </div>
39 38 <form:error name="user"/>
40 39 <p class="help-block">${_('Change owner of this user group.')}</p>
41 40 </div>
42 41 </div>
43 42
44 43 <div class="field">
45 44 <div class="label label-textarea">
46 45 <label for="user_group_description">${_('Description')}:</label>
47 46 </div>
48 47 <div class="textarea textarea-small editor">
49 48 ${h.textarea('user_group_description',cols=23,rows=5,class_="medium")}
50 49 <span class="help-block">${_('Short, optional description for this user group.')}</span>
51 50 </div>
52 51 </div>
53 52 <div class="field">
54 53 <div class="label label-checkbox">
55 54 <label for="users_group_active">${_('Active')}:</label>
56 55 </div>
57 56 <div class="checkboxes">
58 57 ${h.checkbox('users_group_active',value=True)}
59 58 </div>
60 59 </div>
61 60
62 61 <div class="field">
63 62 <div class="label label-checkbox">
64 63 <label for="users_group_active">${_('Add members')}:</label>
65 64 </div>
66 65 <div class="input">
67 66 ${h.text('user_group_add_members', placeholder="user/usergroup", class_="medium")}
68 67 </div>
69 68 </div>
70 69
71 70 <input type="hidden" name="__start__" value="user_group_members:sequence"/>
72 71 <table id="group_members_placeholder" class="rctable group_members">
73 72 <tr>
74 73 <th>${_('Username')}</th>
75 74 <th>${_('Action')}</th>
76 75 </tr>
77 76
78 77 % if c.group_members_obj:
79 78 % for user in c.group_members_obj:
80 79 <tr>
81 80 <td id="member_user_${user.user_id}" class="td-author">
82 81 <div class="group_member">
83 82 ${base.gravatar(user.email, 16, user=user, tooltip=True)}
84 83 <span class="username user">${h.link_to(h.person(user), h.route_path('user_edit',user_id=user.user_id))}</span>
85 84 <input type="hidden" name="__start__" value="member:mapping">
86 85 <input type="hidden" name="member_user_id" value="${user.user_id}">
87 86 <input type="hidden" name="type" value="existing" id="member_${user.user_id}">
88 87 <input type="hidden" name="__end__" value="member:mapping">
89 88 </div>
90 89 </td>
91 90 <td class="">
92 91 <div class="usergroup_member_remove action_button" onclick="removeUserGroupMember(${user.user_id}, true)" style="visibility: visible;">
93 92 <i class="icon-remove"></i>
94 93 </div>
95 94 </td>
96 95 </tr>
97 96 % endfor
98 97
99 98 % else:
100 99 <tr><td colspan="2">${_('No members yet')}</td></tr>
101 100 % endif
102 101 </table>
103 102 <input type="hidden" name="__end__" value="user_group_members:sequence"/>
104 103
105 104 <div class="buttons">
106 105 ${h.submit('Save',_('Save'),class_="btn")}
107 106 </div>
108 107 </div>
109 108 </div>
110 109 ${h.end_form()}
111 110 </div>
112 111 </div>
113 112 <script>
114 113 $(document).ready(function(){
115 114 $("#group_parent_id").select2({
116 115 'containerCssClass': "drop-menu",
117 116 'dropdownCssClass': "drop-menu-dropdown",
118 117 'dropdownAutoWidth': true
119 118 });
120 119
121 120 removeUserGroupMember = function(userId){
122 121 $('#member_'+userId).val('remove');
123 122 $('#member_user_'+userId).addClass('to-delete');
124 123 };
125 124
126 125 $('#user_group_add_members').autocomplete({
127 126 serviceUrl: pyroutes.url('user_autocomplete_data'),
128 127 minChars:2,
129 128 maxHeight:400,
130 129 width:300,
131 130 deferRequestBy: 300, //miliseconds
132 131 showNoSuggestionNotice: true,
133 132 params: { user_groups:true },
134 133 formatResult: autocompleteFormatResult,
135 134 lookupFilter: autocompleteFilterResult,
136 135 onSelect: function(element, suggestion){
137 136
138 137 function addMember(user, fromUserGroup) {
139 138 var gravatar = user.icon_link;
140 139 var username = user.value_display;
141 140 var userLink = pyroutes.url('user_edit', {"user_id": user.id});
142 141 var uid = user.id;
143 142
144 143 if (fromUserGroup) {
145 144 username = username +" "+ _gettext('(from usergroup {0})'.format(fromUserGroup))
146 145 }
147 146
148 147 var elem = $(
149 148 ('<tr>'+
150 149 '<td id="member_user_{6}" class="td-author td-author-new-entry">'+
151 150 '<div class="group_member">'+
152 151 '<img class="gravatar" src="{0}" height="16" width="16">'+
153 152 '<span class="username user"><a href="{1}">{2}</a></span>'+
154 153 '<input type="hidden" name="__start__" value="member:mapping">'+
155 154 '<input type="hidden" name="member_user_id" value="{3}">'+
156 155 '<input type="hidden" name="type" value="new" id="member_{4}">'+
157 156 '<input type="hidden" name="__end__" value="member:mapping">'+
158 157 '</div>'+
159 158 '</td>'+
160 159 '<td class="td-author-new-entry">'+
161 160 '<div class="usergroup_member_remove action_button" onclick="removeUserGroupMember({5}, true)" style="visibility: visible;">'+
162 161 '<i class="icon-remove"></i>'+
163 162 '</div>'+
164 163 '</td>'+
165 164 '</tr>').format(gravatar, userLink, username,
166 165 uid, uid, uid, uid)
167 166 );
168 167 $('#group_members_placeholder').append(elem)
169 168 }
170 169
171 170 if (suggestion.value_type == 'user_group') {
172 171 $.getJSON(
173 172 pyroutes.url('user_group_members_data',
174 173 {'user_group_id': suggestion.id}),
175 174 function(data) {
176 175 $.each(data.members, function(idx, user) {
177 176 addMember(user, suggestion.value)
178 177 });
179 178 }
180 179 );
181 180 } else if (suggestion.value_type == 'user') {
182 181 addMember(suggestion, null);
183 182 }
184 183 $('#user_group_add_members').val('')
185 184 }
186 185 });
187 186
188 187
189 188 UsersAutoComplete('user', '${c.rhodecode_user.user_id}');
190 189 })
191 190 </script>
@@ -1,118 +1,117 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('User groups administration')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='admin')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.admin_menu(active='user_groups')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21 <div class="box">
23 22
24 23 <div class="title">
25 24 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
26 25 <span id="user_group_count">0</span>
27 26
28 27 <ul class="links">
29 28 %if c.can_create_user_group:
30 29 <li>
31 30 <a href="${h.route_path('user_groups_new')}" class="btn btn-small btn-success">${_(u'Add User Group')}</a>
32 31 </li>
33 32 %endif
34 33 </ul>
35 34 </div>
36 35
37 36 <div id="repos_list_wrap">
38 37 <table id="user_group_list_table" class="display"></table>
39 38 </div>
40 39
41 40 </div>
42 41 <script>
43 42 $(document).ready(function() {
44 43 var $userGroupsListTable = $('#user_group_list_table');
45 44
46 45 // user list
47 46 $userGroupsListTable.DataTable({
48 47 processing: true,
49 48 serverSide: true,
50 49 ajax: {
51 50 "url": "${h.route_path('user_groups_data')}",
52 51 "dataSrc": function (json) {
53 52 var filteredCount = json.recordsFiltered;
54 53 var filteredInactiveCount = json.recordsFilteredInactive;
55 54 var totalInactive = json.recordsTotalInactive;
56 55 var total = json.recordsTotal;
57 56
58 57 var _text = _gettext(
59 58 "{0} ({1} inactive) of {2} user groups ({3} inactive)").format(
60 59 filteredCount, filteredInactiveCount, total, totalInactive);
61 60
62 61 if (total === filteredCount) {
63 62 _text = _gettext(
64 63 "{0} user groups ({1} inactive)").format(total, totalInactive);
65 64 }
66 65 $('#user_group_count').text(_text);
67 66 return json.data;
68 67 },
69 68 },
70 69
71 70 dom: 'rtp',
72 71 pageLength: ${c.visual.admin_grid_items},
73 72 order: [[ 0, "asc" ]],
74 73 columns: [
75 74 { data: {"_": "users_group_name",
76 75 "sort": "users_group_name"}, title: "${_('Name')}", className: "td-componentname" },
77 76 { data: {"_": "description",
78 77 "sort": "description"}, title: "${_('Description')}", className: "td-description" },
79 78 { data: {"_": "members",
80 79 "sort": "members"}, title: "${_('Members')}", className: "td-number" },
81 80 { data: {"_": "sync",
82 81 "sort": "sync"}, title: "${_('Sync')}", className: "td-sync" },
83 82 { data: {"_": "active",
84 83 "sort": "active"}, title: "${_('Active')}", className: "td-active" },
85 84 { data: {"_": "owner",
86 85 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" },
87 86 { data: {"_": "action",
88 87 "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false}
89 88 ],
90 89 language: {
91 90 paginate: DEFAULT_GRID_PAGINATION,
92 91 sProcessing: _gettext('loading...'),
93 92 emptyTable: _gettext("No user groups available yet.")
94 93 }
95 94 });
96 95
97 96 $userGroupsListTable.on('xhr.dt', function(e, settings, json, xhr){
98 97 $userGroupsListTable.css('opacity', 1);
99 98 });
100 99
101 100 $userGroupsListTable.on('preXhr.dt', function(e, settings, data){
102 101 $userGroupsListTable.css('opacity', 0.3);
103 102 });
104 103
105 104 // filter
106 105 $('#q_filter').on('keyup',
107 106 $.debounce(250, function() {
108 107 $userGroupsListTable.DataTable().search(
109 108 $('#q_filter').val()
110 109 ).draw();
111 110 })
112 111 );
113 112
114 113 });
115 114
116 115 </script>
117 116
118 117 </%def>
@@ -1,147 +1,146 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Add user')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9 <%def name="breadcrumbs_links()">
11 10 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 11 &raquo;
13 12 ${h.link_to(_('Users'),h.route_path('users'))}
14 13 &raquo;
15 14 ${_('Add User')}
16 15 </%def>
17 16
18 17 <%def name="menu_bar_nav()">
19 18 ${self.menu_items(active='admin')}
20 19 </%def>
21 20
22 21 <%def name="main()">
23 22 <div class="box">
24 23 <!-- box / title -->
25 24 <div class="title">
26 25 ${self.breadcrumbs()}
27 26 </div>
28 27 <!-- end box / title -->
29 28 ${h.secure_form(h.route_path('users_create'), request=request)}
30 29 <div class="form">
31 30 <!-- fields -->
32 31 <div class="fields">
33 32 <div class="field">
34 33 <div class="label">
35 34 <label for="username">${_('Username')}:</label>
36 35 </div>
37 36 <div class="input">
38 37 ${h.text('username', class_='medium')}
39 38 </div>
40 39 </div>
41 40
42 41 <div class="field">
43 42 <div class="label">
44 43 <label for="password">${_('Password')}:</label>
45 44 </div>
46 45 <div class="input">
47 46 ${h.password('password', class_='medium')}
48 47 </div>
49 48 </div>
50 49
51 50 <div class="field">
52 51 <div class="label">
53 52 <label for="password_confirmation">${_('Password confirmation')}:</label>
54 53 </div>
55 54 <div class="input">
56 55 ${h.password('password_confirmation',autocomplete="off", class_='medium')}
57 56 <div class="info-block">
58 57 <a id="generate_password" href="#">
59 58 <i class="icon-lock"></i> ${_('Generate password')}
60 59 </a>
61 60 <span id="generate_password_preview"></span>
62 61 </div>
63 62 </div>
64 63 </div>
65 64
66 65 <div class="field">
67 66 <div class="label">
68 67 <label for="firstname">${_('First Name')}:</label>
69 68 </div>
70 69 <div class="input">
71 70 ${h.text('firstname', class_='medium')}
72 71 </div>
73 72 </div>
74 73
75 74 <div class="field">
76 75 <div class="label">
77 76 <label for="lastname">${_('Last Name')}:</label>
78 77 </div>
79 78 <div class="input">
80 79 ${h.text('lastname', class_='medium')}
81 80 </div>
82 81 </div>
83 82
84 83 <div class="field">
85 84 <div class="label">
86 85 <label for="email">${_('Email')}:</label>
87 86 </div>
88 87 <div class="input">
89 88 ${h.text('email', class_='medium')}
90 89 ${h.hidden('extern_name', c.default_extern_type)}
91 90 ${h.hidden('extern_type', c.default_extern_type)}
92 91 </div>
93 92 </div>
94 93
95 94 <div class="field">
96 95 <div class="label label-checkbox">
97 96 <label for="active">${_('Active')}:</label>
98 97 </div>
99 98 <div class="checkboxes">
100 99 ${h.checkbox('active',value=True,checked='checked')}
101 100 </div>
102 101 </div>
103 102
104 103 <div class="field">
105 104 <div class="label label-checkbox">
106 105 <label for="password_change">${_('Password change')}:</label>
107 106 </div>
108 107 <div class="checkboxes">
109 108 ${h.checkbox('password_change',value=True)}
110 109 <span class="help-block">${_('Force user to change his password on the next login')}</span>
111 110 </div>
112 111 </div>
113 112
114 113 <div class="field">
115 114 <div class="label label-checkbox">
116 115 <label for="create_repo_group">${_('Add personal repository group')}:</label>
117 116 </div>
118 117 <div class="checkboxes">
119 118 ${h.checkbox('create_repo_group',value=True, checked=c.default_create_repo_group)}
120 119 <span class="help-block">
121 120 ${_('New group will be created at: `/{path}`').format(path=c.personal_repo_group_name)}<br/>
122 121 ${_('User will be automatically set as this group owner.')}
123 122 </span>
124 123 </div>
125 124 </div>
126 125
127 126 <div class="buttons">
128 127 ${h.submit('save',_('Create User'),class_="btn")}
129 128 </div>
130 129 </div>
131 130 </div>
132 131 ${h.end_form()}
133 132 </div>
134 133 <script>
135 134 $(document).ready(function(){
136 135 $('#username').focus();
137 136
138 137 $('#generate_password').on('click', function(e){
139 138 var tmpl = "(${_('generated password:')} {0})";
140 139 var new_passwd = generatePassword(12);
141 140 $('#generate_password_preview').html(tmpl.format(new_passwd));
142 141 $('#password').val(new_passwd);
143 142 $('#password_confirmation').val(new_passwd);
144 143 })
145 144 })
146 145 </script>
147 146 </%def>
@@ -1,59 +1,58 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('{} user settings').format(c.user.username)}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()">
12 11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 12 &raquo;
14 13 ${h.link_to(_('Users'),h.route_path('users'))}
15 14 &raquo;
16 15 </%def>
17 16
18 17 <%def name="menu_bar_nav()">
19 18 ${self.menu_items(active='admin')}
20 19 </%def>
21 20
22 21 <%def name="menu_bar_subnav()">
23 22 ${self.admin_menu(active='users')}
24 23 </%def>
25 24
26 25
27 26 <%def name="main()">
28 27 <div class="box user_settings">
29 28 % if not c.user.active:
30 29 <div class="alert alert-warning text-center" style="margin: 0 0 15px 0">
31 30 <strong>${_('This user is set as non-active and disabled.')}</strong>
32 31 </div>
33 32 % endif
34 33
35 34 ##main
36 35 <div class="sidebar-col-wrapper">
37 36 <div class="sidebar">
38 37 <ul class="nav nav-pills nav-stacked">
39 38 <li class="${h.is_active('profile', c.active)}"><a href="${h.route_path('user_edit', user_id=c.user.user_id)}">${_('User Profile')}</a></li>
40 39 <li class="${h.is_active('auth_tokens', c.active)}"><a href="${h.route_path('edit_user_auth_tokens', user_id=c.user.user_id)}">${_('Auth tokens')}</a></li>
41 40 <li class="${h.is_active(['ssh_keys','ssh_keys_generate'], c.active)}"><a href="${h.route_path('edit_user_ssh_keys', user_id=c.user.user_id)}">${_('SSH Keys')}</a></li>
42 41 <li class="${h.is_active('advanced', c.active)}"><a href="${h.route_path('user_edit_advanced', user_id=c.user.user_id)}">${_('Advanced')}</a></li>
43 42 <li class="${h.is_active('global_perms', c.active)}"><a href="${h.route_path('user_edit_global_perms', user_id=c.user.user_id)}">${_('Global permissions')}</a></li>
44 43 <li class="${h.is_active('perms_summary', c.active)}"><a href="${h.route_path('edit_user_perms_summary', user_id=c.user.user_id)}">${_('Permissions summary')}</a></li>
45 44 <li class="${h.is_active('emails', c.active)}"><a href="${h.route_path('edit_user_emails', user_id=c.user.user_id)}">${_('Emails')}</a></li>
46 45 <li class="${h.is_active('ips', c.active)}"><a href="${h.route_path('edit_user_ips', user_id=c.user.user_id)}">${_('Ip Whitelist')}</a></li>
47 46 <li class="${h.is_active('groups', c.active)}"><a href="${h.route_path('edit_user_groups_management', user_id=c.user.user_id)}">${_('User Groups Management')}</a></li>
48 47 <li class="${h.is_active('audit', c.active)}"><a href="${h.route_path('edit_user_audit_logs', user_id=c.user.user_id)}">${_('Audit logs')}</a></li>
49 48 <li class="${h.is_active('caches', c.active)}"><a href="${h.route_path('edit_user_caches', user_id=c.user.user_id)}">${_('Caches')}</a></li>
50 49 </ul>
51 50 </div>
52 51
53 52 <div class="main-content-full-width">
54 53 <%include file="/admin/users/user_edit_${c.active}.mako"/>
55 54 </div>
56 55 </div>
57 56 </div>
58 57
59 58 </%def>
@@ -1,27 +1,26 b''
1 ## -*- coding: utf-8 -*-
2 1 <%namespace name="base" file="/base/base.mako"/>
3 2
4 3
5 4 <div class="panel panel-default">
6 5 <div class="panel-heading">
7 6 <h3 class="panel-title">
8 7 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
9 8 &nbsp;- ${_('Audit Logs')}
10 9 (${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)})
11 10 </h3>
12 11 <a href="${h.route_path('edit_user_audit_logs_download', user_id=c.user.user_id)}" class="panel-edit">${_('Download as JSON')}</a>
13 12 </div>
14 13 <div class="panel-body">
15 14
16 15 ${h.form(None, id_="filter_form", method="get")}
17 16 <input class="q_filter_box ${'' if c.filter_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.filter_term or ''}" placeholder="${_('audit filter...')}"/>
18 17 <input type='submit' value="${_('filter')}" class="btn" />
19 18 ${h.end_form()}
20 19
21 20 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
22 21 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
23 22
24 23 <%include file="/admin/admin_log_base.mako" />
25 24
26 25 </div>
27 26 </div>
@@ -1,150 +1,149 b''
1 ## -*- coding: utf-8 -*-
2 1 <%namespace name="base" file="/base/base.mako"/>
3 2
4 3 <div class="panel panel-default">
5 4 <div class="panel-heading">
6 5 <h3 class="panel-title">
7 6 ${base.gravatar_with_user(c.user.username, 16, tooltip=False, _class='pull-left')}
8 7 &nbsp;- ${_('User groups administration')}
9 8 </h3>
10 9 </div>
11 10 <div class="panel-body">
12 11 <div class="fields">
13 12 <div class="field">
14 13 <div class="label label-checkbox">
15 14 <label for="users_group_active">${_('Add user to user group')}:</label>
16 15 </div>
17 16 <div class="input">
18 17 ${h.text('add_user_to_group', placeholder="user group name", class_="medium")}
19 18 </div>
20 19
21 20 </div>
22 21 </div>
23 22
24 23 <div class="groups_management">
25 24 ${h.secure_form(h.route_path('edit_user_groups_management_updates', user_id=c.user.user_id), request=request)}
26 25 <div id="repos_list_wrap">
27 26 <table id="user_group_list_table" class="display"></table>
28 27 </div>
29 28 <div class="buttons">
30 29 ${h.submit('save',_('Save'),class_="btn")}
31 30 </div>
32 31 ${h.end_form()}
33 32 </div>
34 33 </div>
35 34 </div>
36 35 <script>
37 36 var api;
38 37 $(document).ready(function() {
39 38
40 39 var get_datatable_count = function(){
41 40 $('#user_group_count').text(api.page.info().recordsDisplay);
42 41 };
43 42
44 43 $('#user_group_list_table').on('click', 'a.editor_remove', function (e) {
45 44 e.preventDefault();
46 45 var row = api.row($(this).closest('tr'));
47 46 row.remove().draw();
48 47 } );
49 48
50 49 $('#user_group_list_table').DataTable({
51 50 data: ${c.groups|n},
52 51 dom: 'rtp',
53 52 pageLength: ${c.visual.admin_grid_items},
54 53 order: [[ 0, "asc" ]],
55 54 columns: [
56 55 { data: {"_": "group_name",
57 56 "sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," ,
58 57 render: function (data,type,full,meta)
59 58 {return '<div><i class="icon-user-group" title="User group">'+data+'</i></div>'}},
60 59
61 60 { data: {"_": "group_description",
62 61 "sort": "group_description"}, title: "${_('Description')}", className: "td-description" },
63 62 { data: {"_": "users_group_id"}, className: "td-user",
64 63 render: function (data,type,full,meta)
65 64 {return '<input type="hidden" name="users_group_id" value="'+data+'">'}},
66 65 { data: {"_": "active",
67 66 "sort": "active"}, title: "${_('Active')}", className: "td-active"},
68 67 { data: {"_": "owner_data"}, title: "${_('Owner')}", className: "td-user",
69 68 render: function (data,type,full,meta)
70 69 {return '<div class="rc-user tooltip">'+
71 70 '<img class="gravatar" src="'+ data.owner_icon +'" height="16" width="16">'+
72 71 data.owner +'</div>'
73 72 }
74 73 },
75 74 { data: null,
76 75 title: "${_('Action')}",
77 76 className: "td-action",
78 77 defaultContent: '-'
79 78 }
80 79 ],
81 80 language: {
82 81 paginate: DEFAULT_GRID_PAGINATION,
83 82 emptyTable: _gettext("No user groups available yet.")
84 83 },
85 84 "initComplete": function( settings, json ) {
86 85 var data_grid = $('#user_group_list_table').dataTable();
87 86 api = data_grid.api();
88 87 get_datatable_count();
89 88 }
90 89 });
91 90
92 91 // update the counter when doing search
93 92 $('#user_group_list_table').on( 'search.dt', function (e,settings) {
94 93 get_datatable_count();
95 94 });
96 95
97 96 // filter, filter both grids
98 97 $('#q_filter').on( 'keyup', function () {
99 98 var user_api = $('#user_group_list_table').dataTable().api();
100 99 user_api
101 100 .columns(0)
102 101 .search(this.value)
103 102 .draw();
104 103 });
105 104
106 105 // refilter table if page load via back button
107 106 $("#q_filter").trigger('keyup');
108 107
109 108 });
110 109
111 110 $('#language').select2({
112 111 'containerCssClass': "drop-menu",
113 112 'dropdownCssClass': "drop-menu-dropdown",
114 113 'dropdownAutoWidth': true
115 114 });
116 115
117 116
118 117
119 118 $(document).ready(function(){
120 119 $("#group_parent_id").select2({
121 120 'containerCssClass': "drop-menu",
122 121 'dropdownCssClass': "drop-menu-dropdown",
123 122 'dropdownAutoWidth': true
124 123 });
125 124
126 125 $('#add_user_to_group').autocomplete({
127 126 serviceUrl: pyroutes.url('user_group_autocomplete_data'),
128 127 minChars:2,
129 128 maxHeight:400,
130 129 width:300,
131 130 deferRequestBy: 300, //miliseconds
132 131 showNoSuggestionNotice: true,
133 132 params: { user_groups:true },
134 133 formatResult: autocompleteFormatResult,
135 134 lookupFilter: autocompleteFilterResult,
136 135 onSelect: function(element, suggestion){
137 136 var owner = {owner_icon: suggestion.owner_icon, owner:suggestion.owner};
138 137 api.row.add(
139 138 {"active": suggestion.active,
140 139 "owner_data": owner,
141 140 "users_group_id": suggestion.id,
142 141 "group_description": suggestion.description,
143 142 "group_name": suggestion.value}).draw();
144 143 }
145 144 });
146 145 })
147 146
148 147 </script>
149 148
150 149
@@ -1,126 +1,125 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Users administration')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='admin')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.admin_menu(active='users')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21
23 22 <div class="box">
24 23
25 24 <div class="title">
26 25 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
27 26 <span id="user_count">0</span>
28 27
29 28 <ul class="links">
30 29 <li>
31 30 <a href="${h.route_path('users_new')}" class="btn btn-small btn-success">${_(u'Add User')}</a>
32 31 </li>
33 32 </ul>
34 33 </div>
35 34
36 35 <div id="repos_list_wrap">
37 36 <table id="user_list_table" class="display"></table>
38 37 </div>
39 38 </div>
40 39
41 40 <script type="text/javascript">
42 41
43 42 $(document).ready(function() {
44 43 var $userListTable = $('#user_list_table');
45 44 // user list
46 45 $userListTable.DataTable({
47 46 processing: true,
48 47 serverSide: true,
49 48 ajax: {
50 49 "url": "${h.route_path('users_data')}",
51 50 "dataSrc": function ( json ) {
52 51 var filteredCount = json.recordsFiltered;
53 52 var filteredInactiveCount = json.recordsFilteredInactive;
54 53 var totalInactive = json.recordsTotalInactive;
55 54 var total = json.recordsTotal;
56 55
57 56 var _text = _gettext(
58 57 "{0} ({1} inactive) of {2} users ({3} inactive)").format(
59 58 filteredCount, filteredInactiveCount, total, totalInactive);
60 59
61 60 if(total === filteredCount){
62 61 _text = _gettext(
63 62 "{0} users ({1} inactive)").format(total, totalInactive);
64 63 }
65 64 $('#user_count').text(_text);
66 65 return json.data;
67 66 }
68 67 },
69 68 dom: 'rtp',
70 69 pageLength: ${c.visual.admin_grid_items},
71 70 order: [[ 0, "asc" ]],
72 71 columns: [
73 72 { data: {"_": "username",
74 73 "sort": "username"}, title: "${_('Username')}", className: "td-user" },
75 74 { data: {"_": "email",
76 75 "sort": "email"}, title: "${_('Email')}", className: "td-email" },
77 76 { data: {"_": "first_name",
78 77 "sort": "first_name"}, title: "${_('First Name')}", className: "td-user" },
79 78 { data: {"_": "last_name",
80 79 "sort": "last_name"}, title: "${_('Last Name')}", className: "td-user" },
81 80 { data: {"_": "last_activity",
82 81 "sort": "last_activity",
83 82 "type": Number}, title: "${_('Last activity')}", className: "td-time" },
84 83 { data: {"_": "active",
85 84 "sort": "active"}, title: "${_('Active')}", className: "td-active" },
86 85 { data: {"_": "admin",
87 86 "sort": "admin"}, title: "${_('Super-admin')}", className: "td-admin" },
88 87 { data: {"_": "extern_type",
89 88 "sort": "extern_type"}, title: "${_('Auth type')}", className: "td-type" },
90 89 { data: {"_": "action",
91 90 "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false }
92 91 ],
93 92 language: {
94 93 paginate: DEFAULT_GRID_PAGINATION,
95 94 sProcessing: _gettext('loading...'),
96 95 emptyTable: _gettext("No users available yet.")
97 96 },
98 97
99 98 "createdRow": function ( row, data, index ) {
100 99 if (!data['active_raw']){
101 100 $(row).addClass('closed')
102 101 }
103 102 }
104 103 });
105 104
106 105 $userListTable.on('xhr.dt', function(e, settings, json, xhr){
107 106 $userListTable.css('opacity', 1);
108 107 });
109 108
110 109 $userListTable.on('preXhr.dt', function(e, settings, data){
111 110 $userListTable.css('opacity', 0.3);
112 111 });
113 112
114 113 // filter
115 114 $('#q_filter').on('keyup',
116 115 $.debounce(250, function() {
117 116 $userListTable.DataTable().search(
118 117 $('#q_filter').val()
119 118 ).draw();
120 119 })
121 120 );
122 121
123 122 });
124 123 </script>
125 124
126 125 </%def>
@@ -1,28 +1,27 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('{} Artifacts').format(c.repo_name)}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='repositories')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.repo_menu(active='artifacts')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21 <div class="box">
23 22
24 23 <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>
25 24 ##<img style="width: 100%; height: 100%" src="${h.asset('images/ee_features/repo_artifacts.png')}"/>
26 25 </div>
27 26
28 27 </%def>
@@ -1,1263 +1,1262 b''
1 ## -*- coding: utf-8 -*-
2 1
3 2 <%!
4 3 from rhodecode.lib import html_filters
5 4 %>
6 5
7 6 <%inherit file="root.mako"/>
8 7
9 8 <%include file="/ejs_templates/templates.html"/>
10 9
11 10 <div class="outerwrapper">
12 11 <!-- HEADER -->
13 12 <div class="header">
14 13 <div id="header-inner" class="wrapper">
15 14 <div id="logo">
16 15 <div class="logo-wrapper">
17 16 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
18 17 </div>
19 18 % if c.rhodecode_name:
20 19 <div class="branding">
21 20 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
22 21 </div>
23 22 % endif
24 23 </div>
25 24 <!-- MENU BAR NAV -->
26 25 ${self.menu_bar_nav()}
27 26 <!-- END MENU BAR NAV -->
28 27 </div>
29 28 </div>
30 29 ${self.menu_bar_subnav()}
31 30 <!-- END HEADER -->
32 31
33 32 <!-- CONTENT -->
34 33 <div id="content" class="wrapper">
35 34
36 35 <rhodecode-toast id="notifications"></rhodecode-toast>
37 36
38 37 <div class="main">
39 38 ${next.main()}
40 39 </div>
41 40
42 41 </div>
43 42 <!-- END CONTENT -->
44 43
45 44 </div>
46 45
47 46 <!-- FOOTER -->
48 47 <div id="footer">
49 48 <div id="footer-inner" class="title wrapper">
50 49 <div>
51 50 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
52 51
53 52 <p class="footer-link-right">
54 53 <a class="grey-link-action" href="${h.route_path('home', _query={'showrcid': 1})}">
55 54 RhodeCode
56 55 % if c.visual.show_version:
57 56 ${c.rhodecode_version}
58 57 % endif
59 58 ${c.rhodecode_edition}
60 59 </a> |
61 60
62 61 % if c.visual.rhodecode_support_url:
63 62 <a class="grey-link-action" href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a> |
64 63 <a class="grey-link-action" href="https://docs.rhodecode.com" target="_blank">${_('Documentation')}</a>
65 64 % endif
66 65
67 66 </p>
68 67
69 68 <p class="server-instance" style="display:${sid}">
70 69 ## display hidden instance ID if specially defined
71 70 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
72 71 % if c.rhodecode_instanceid:
73 72 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
74 73 % endif
75 74 </p>
76 75 </div>
77 76 </div>
78 77 </div>
79 78
80 79 <!-- END FOOTER -->
81 80
82 81 ### MAKO DEFS ###
83 82
84 83 <%def name="menu_bar_subnav()">
85 84 </%def>
86 85
87 86 <%def name="breadcrumbs(class_='breadcrumbs')">
88 87 <div class="${class_}">
89 88 ${self.breadcrumbs_links()}
90 89 </div>
91 90 </%def>
92 91
93 92 <%def name="admin_menu(active=None)">
94 93
95 94 <div id="context-bar">
96 95 <div class="wrapper">
97 96 <div class="title">
98 97 <div class="title-content">
99 98 <div class="title-main">
100 99 % if c.is_super_admin:
101 100 ${_('Super-admin Panel')}
102 101 % else:
103 102 ${_('Delegated Admin Panel')}
104 103 % endif
105 104 </div>
106 105 </div>
107 106 </div>
108 107
109 108 <ul id="context-pages" class="navigation horizontal-list">
110 109
111 110 ## super-admin case
112 111 % if c.is_super_admin:
113 112 <li class="${h.is_active('audit_logs', active)}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
114 113 <li class="${h.is_active('repositories', active)}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
115 114 <li class="${h.is_active('repository_groups', active)}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
116 115 <li class="${h.is_active('users', active)}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
117 116 <li class="${h.is_active('user_groups', active)}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
118 117 <li class="${h.is_active('artifacts', active)}"><a href="${h.route_path('admin_artifacts')}">${_('Artifacts')}</a></li>
119 118 <li class="${h.is_active('permissions', active)}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
120 119 <li class="${h.is_active('authentication', active)}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
121 120 <li class="${h.is_active('integrations', active)}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
122 121 <li class="${h.is_active('defaults', active)}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
123 122 <li class="${h.is_active('settings', active)}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
124 123
125 124 ## delegated admin
126 125 % elif c.is_delegated_admin:
127 126 <%
128 127 repositories=c.auth_user.repositories_admin or c.can_create_repo
129 128 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
130 129 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
131 130 %>
132 131
133 132 %if repositories:
134 133 <li class="${h.is_active('repositories', active)} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
135 134 %endif
136 135 %if repository_groups:
137 136 <li class="${h.is_active('repository_groups', active)} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
138 137 %endif
139 138 %if user_groups:
140 139 <li class="${h.is_active('user_groups', active)} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
141 140 %endif
142 141 % endif
143 142 </ul>
144 143
145 144 </div>
146 145 <div class="clear"></div>
147 146 </div>
148 147 </%def>
149 148
150 149 <%def name="dt_info_panel(elements)">
151 150 <dl class="dl-horizontal">
152 151 %for dt, dd, title, show_items in elements:
153 152 <dt>${dt}:</dt>
154 153 <dd title="${h.tooltip(title)}">
155 154 %if callable(dd):
156 155 ## allow lazy evaluation of elements
157 156 ${dd()}
158 157 %else:
159 158 ${dd}
160 159 %endif
161 160 %if show_items:
162 161 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
163 162 %endif
164 163 </dd>
165 164
166 165 %if show_items:
167 166 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
168 167 %for item in show_items:
169 168 <dt></dt>
170 169 <dd>${item}</dd>
171 170 %endfor
172 171 </div>
173 172 %endif
174 173
175 174 %endfor
176 175 </dl>
177 176 </%def>
178 177
179 178 <%def name="tr_info_entry(element)">
180 179 <% key, val, title, show_items = element %>
181 180
182 181 <tr>
183 182 <td style="vertical-align: top">${key}</td>
184 183 <td title="${h.tooltip(title)}">
185 184 %if callable(val):
186 185 ## allow lazy evaluation of elements
187 186 ${val()}
188 187 %else:
189 188 ${val}
190 189 %endif
191 190 %if show_items:
192 191 <div class="collapsable-content" data-toggle="item-${h.md5_safe(h.safe_str(val))[:6]}-details" style="display: none">
193 192 % for item in show_items:
194 193 <dt></dt>
195 194 <dd>${item}</dd>
196 195 % endfor
197 196 </div>
198 197 %endif
199 198 </td>
200 199 <td style="vertical-align: top">
201 200 %if show_items:
202 201 <span class="btn-collapse" data-toggle="item-${h.md5_safe(h.safe_str(val))[:6]}-details">${_('Show More')} </span>
203 202 %endif
204 203 </td>
205 204 </tr>
206 205
207 206 </%def>
208 207
209 208 <%def name="gravatar(email, size=16, tooltip=False, tooltip_alt=None, user=None, extra_class=None)">
210 209 <%
211 210 if size > 16:
212 211 gravatar_class = ['gravatar','gravatar-large']
213 212 else:
214 213 gravatar_class = ['gravatar']
215 214
216 215 data_hovercard_url = ''
217 216 data_hovercard_alt = tooltip_alt.replace('<', '&lt;').replace('>', '&gt;') if tooltip_alt else ''
218 217
219 218 if tooltip:
220 219 gravatar_class += ['tooltip-hovercard']
221 220 if extra_class:
222 221 gravatar_class += extra_class
223 222 if tooltip and user:
224 223 if user.username == h.DEFAULT_USER:
225 224 gravatar_class.pop(-1)
226 225 else:
227 226 data_hovercard_url = request.route_path('hovercard_user', user_id=getattr(user, 'user_id', ''))
228 227 gravatar_class = ' '.join(gravatar_class)
229 228
230 229 %>
231 230 <%doc>
232 231 TODO: johbo: For now we serve double size images to make it smooth
233 232 for retina. This is how it worked until now. Should be replaced
234 233 with a better solution at some point.
235 234 </%doc>
236 235
237 236 <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)}" />
238 237 </%def>
239 238
240 239
241 240 <%def name="gravatar_with_user(contact, size=16, show_disabled=False, tooltip=False, _class='rc-user')">
242 241 <%
243 242 email = h.email_or_none(contact)
244 243 rc_user = h.discover_user(contact)
245 244 %>
246 245
247 246 <div class="${_class}">
248 247 ${self.gravatar(email, size, tooltip=tooltip, tooltip_alt=contact, user=rc_user)}
249 248 <span class="${('user user-disabled' if show_disabled else 'user')}">
250 249 ${h.link_to_user(rc_user or contact)}
251 250 </span>
252 251 </div>
253 252 </%def>
254 253
255 254
256 255 <%def name="user_group_icon(user_group=None, size=16, tooltip=False)">
257 256 <%
258 257 if (size > 16):
259 258 gravatar_class = 'icon-user-group-alt'
260 259 else:
261 260 gravatar_class = 'icon-user-group-alt'
262 261
263 262 if tooltip:
264 263 gravatar_class += ' tooltip-hovercard'
265 264
266 265 data_hovercard_url = request.route_path('hovercard_user_group', user_group_id=user_group.users_group_id)
267 266 %>
268 267 <%doc>
269 268 TODO: johbo: For now we serve double size images to make it smooth
270 269 for retina. This is how it worked until now. Should be replaced
271 270 with a better solution at some point.
272 271 </%doc>
273 272
274 273 <i style="font-size: ${size}px" class="${gravatar_class} x-icon-size-${size}" data-hovercard-url="${data_hovercard_url}"></i>
275 274 </%def>
276 275
277 276 <%def name="repo_page_title(repo_instance)">
278 277 <div class="title-content repo-title">
279 278
280 279 <div class="title-main">
281 280 ## SVN/HG/GIT icons
282 281 %if h.is_hg(repo_instance):
283 282 <i class="icon-hg"></i>
284 283 %endif
285 284 %if h.is_git(repo_instance):
286 285 <i class="icon-git"></i>
287 286 %endif
288 287 %if h.is_svn(repo_instance):
289 288 <i class="icon-svn"></i>
290 289 %endif
291 290
292 291 ## public/private
293 292 %if repo_instance.private:
294 293 <i class="icon-repo-private"></i>
295 294 %else:
296 295 <i class="icon-repo-public"></i>
297 296 %endif
298 297
299 298 ## repo name with group name
300 299 ${h.breadcrumb_repo_link(repo_instance)}
301 300
302 301 ## Context Actions
303 302 <div class="pull-right">
304 303 %if c.rhodecode_user.username != h.DEFAULT_USER:
305 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>
306 305
307 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 '')}">
308 307 % if c.repository_is_user_following:
309 308 <i class="icon-eye-off"></i>${_('Unwatch')}
310 309 % else:
311 310 <i class="icon-eye"></i>${_('Watch')}
312 311 % endif
313 312
314 313 </a>
315 314 %else:
316 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>
317 316 %endif
318 317 </div>
319 318
320 319 </div>
321 320
322 321 ## FORKED
323 322 %if repo_instance.fork:
324 323 <p class="discreet">
325 324 <i class="icon-code-fork"></i> ${_('Fork of')}
326 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))}
327 326 </p>
328 327 %endif
329 328
330 329 ## IMPORTED FROM REMOTE
331 330 %if repo_instance.clone_uri:
332 331 <p class="discreet">
333 332 <i class="icon-code-fork"></i> ${_('Clone from')}
334 333 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
335 334 </p>
336 335 %endif
337 336
338 337 ## LOCKING STATUS
339 338 %if repo_instance.locked[0]:
340 339 <p class="locking_locked discreet">
341 340 <i class="icon-repo-lock"></i>
342 341 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
343 342 </p>
344 343 %elif repo_instance.enable_locking:
345 344 <p class="locking_unlocked discreet">
346 345 <i class="icon-repo-unlock"></i>
347 346 ${_('Repository not locked. Pull repository to lock it.')}
348 347 </p>
349 348 %endif
350 349
351 350 </div>
352 351 </%def>
353 352
354 353 <%def name="repo_menu(active=None)">
355 354 <%
356 355 ## determine if we have "any" option available
357 356 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
358 357 has_actions = can_lock
359 358
360 359 %>
361 360 % if c.rhodecode_db_repo.archived:
362 361 <div class="alert alert-warning text-center">
363 362 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
364 363 </div>
365 364 % endif
366 365
367 366 <!--- REPO CONTEXT BAR -->
368 367 <div id="context-bar">
369 368 <div class="wrapper">
370 369
371 370 <div class="title">
372 371 ${self.repo_page_title(c.rhodecode_db_repo)}
373 372 </div>
374 373
375 374 <ul id="context-pages" class="navigation horizontal-list">
376 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>
377 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>
378 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>
379 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>
380 379
381 380 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
382 381 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
383 382 <li class="${h.is_active('showpullrequest', active)}">
384 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)}">
385 384 <div class="menulabel">
386 385 ${_('Pull Requests')} <span class="menulink-counter">${c.repository_pull_requests}</span>
387 386 </div>
388 387 </a>
389 388 </li>
390 389 %endif
391 390
392 391 <li class="${h.is_active('artifacts', active)}">
393 392 <a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}">
394 393 <div class="menulabel">
395 394 ${_('Artifacts')} <span class="menulink-counter">${c.repository_artifacts}</span>
396 395 </div>
397 396 </a>
398 397 </li>
399 398
400 399 %if not c.rhodecode_db_repo.archived and h.HasRepoPermissionAll('repository.admin')(c.repo_name):
401 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>
402 401 %endif
403 402
404 403 <li class="${h.is_active('options', active)}">
405 404 % if has_actions:
406 405 <a class="menulink dropdown">
407 406 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
408 407 </a>
409 408 <ul class="submenu">
410 409 %if can_lock:
411 410 %if c.rhodecode_db_repo.locked[0]:
412 411 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock Repository')}</a></li>
413 412 %else:
414 413 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock Repository')}</a></li>
415 414 %endif
416 415 %endif
417 416 </ul>
418 417 % endif
419 418 </li>
420 419
421 420 </ul>
422 421 </div>
423 422 <div class="clear"></div>
424 423 </div>
425 424
426 425 <!--- REPO END CONTEXT BAR -->
427 426
428 427 </%def>
429 428
430 429 <%def name="repo_group_page_title(repo_group_instance)">
431 430 <div class="title-content">
432 431 <div class="title-main">
433 432 ## Repository Group icon
434 433 <i class="icon-repo-group"></i>
435 434
436 435 ## repo name with group name
437 436 ${h.breadcrumb_repo_group_link(repo_group_instance)}
438 437 </div>
439 438
440 439 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
441 440 <div class="repo-group-desc discreet">
442 441 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
443 442 </div>
444 443
445 444 </div>
446 445 </%def>
447 446
448 447
449 448 <%def name="repo_group_menu(active=None)">
450 449 <%
451 450 gr_name = c.repo_group.group_name if c.repo_group else None
452 451 # create repositories with write permission on group is set to true
453 452 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
454 453
455 454 %>
456 455
457 456
458 457 <!--- REPO GROUP CONTEXT BAR -->
459 458 <div id="context-bar">
460 459 <div class="wrapper">
461 460 <div class="title">
462 461 ${self.repo_group_page_title(c.repo_group)}
463 462 </div>
464 463
465 464 <ul id="context-pages" class="navigation horizontal-list">
466 465 <li class="${h.is_active('home', active)}">
467 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>
468 467 </li>
469 468 % if c.is_super_admin or group_admin:
470 469 <li class="${h.is_active('settings', active)}">
471 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>
472 471 </li>
473 472 % endif
474 473
475 474 </ul>
476 475 </div>
477 476 <div class="clear"></div>
478 477 </div>
479 478
480 479 <!--- REPO GROUP CONTEXT BAR -->
481 480
482 481 </%def>
483 482
484 483
485 484 <%def name="usermenu(active=False)">
486 485 <%
487 486 not_anonymous = c.rhodecode_user.username != h.DEFAULT_USER
488 487
489 488 gr_name = c.repo_group.group_name if (hasattr(c, 'repo_group') and c.repo_group) else None
490 489 # create repositories with write permission on group is set to true
491 490
492 491 can_fork = c.is_super_admin or h.HasPermissionAny('hg.fork.repository')()
493 492 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
494 493 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
495 494 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
496 495
497 496 can_create_repos = c.is_super_admin or c.can_create_repo
498 497 can_create_repo_groups = c.is_super_admin or c.can_create_repo_group
499 498
500 499 can_create_repos_in_group = c.is_super_admin or group_admin or (group_write and create_on_write)
501 500 can_create_repo_groups_in_group = c.is_super_admin or group_admin
502 501 %>
503 502
504 503 % if not_anonymous:
505 504 <%
506 505 default_target_group = dict()
507 506 if c.rhodecode_user.personal_repo_group:
508 507 default_target_group = dict(parent_group=c.rhodecode_user.personal_repo_group.group_id)
509 508 %>
510 509
511 510 ## create action
512 511 <li>
513 512 <a href="#create-actions" onclick="return false;" class="menulink childs">
514 513 <i class="icon-plus-circled"></i>
515 514 </a>
516 515
517 516 <div class="action-menu submenu">
518 517
519 518 <ol>
520 519 ## scope of within a repository
521 520 % if hasattr(c, 'rhodecode_db_repo') and c.rhodecode_db_repo:
522 521 <li class="submenu-title">${_('This Repository')}</li>
523 522 <li>
524 523 <a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a>
525 524 </li>
526 525 % if can_fork:
527 526 <li>
528 527 <a href="${h.route_path('repo_fork_new',repo_name=c.repo_name,_query=default_target_group)}">${_('Fork this repository')}</a>
529 528 </li>
530 529 % endif
531 530 % endif
532 531
533 532 ## scope of within repository groups
534 533 % if hasattr(c, 'repo_group') and c.repo_group and (can_create_repos_in_group or can_create_repo_groups_in_group):
535 534 <li class="submenu-title">${_('This Repository Group')}</li>
536 535
537 536 % if can_create_repos_in_group:
538 537 <li>
539 538 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('New Repository')}</a>
540 539 </li>
541 540 % endif
542 541
543 542 % if can_create_repo_groups_in_group:
544 543 <li>
545 544 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'New Repository Group')}</a>
546 545 </li>
547 546 % endif
548 547 % endif
549 548
550 549 ## personal group
551 550 % if c.rhodecode_user.personal_repo_group:
552 551 <li class="submenu-title">Personal Group</li>
553 552
554 553 <li>
555 554 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}" >${_('New Repository')} </a>
556 555 </li>
557 556
558 557 <li>
559 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>
560 559 </li>
561 560 % endif
562 561
563 562 ## Global actions
564 563 <li class="submenu-title">RhodeCode</li>
565 564 % if can_create_repos:
566 565 <li>
567 566 <a href="${h.route_path('repo_new')}" >${_('New Repository')}</a>
568 567 </li>
569 568 % endif
570 569
571 570 % if can_create_repo_groups:
572 571 <li>
573 572 <a href="${h.route_path('repo_group_new')}" >${_(u'New Repository Group')}</a>
574 573 </li>
575 574 % endif
576 575
577 576 <li>
578 577 <a href="${h.route_path('gists_new')}">${_(u'New Gist')}</a>
579 578 </li>
580 579
581 580 </ol>
582 581
583 582 </div>
584 583 </li>
585 584
586 585 ## notifications
587 586 <li>
588 587 <a class="${('empty' if c.unread_notifications == 0 else '')}" href="${h.route_path('notifications_show_all')}">
589 588 ${c.unread_notifications}
590 589 </a>
591 590 </li>
592 591 % endif
593 592
594 593 ## USER MENU
595 594 <li id="quick_login_li" class="${'active' if active else ''}">
596 595 % if c.rhodecode_user.username == h.DEFAULT_USER:
597 596 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
598 597 ${gravatar(c.rhodecode_user.email, 20)}
599 598 <span class="user">
600 599 <span>${_('Sign in')}</span>
601 600 </span>
602 601 </a>
603 602 % else:
604 603 ## logged in user
605 604 <a id="quick_login_link" class="menulink childs">
606 605 ${gravatar(c.rhodecode_user.email, 20)}
607 606 <span class="user">
608 607 <span class="menu_link_user">${c.rhodecode_user.username}</span>
609 608 <div class="show_more"></div>
610 609 </span>
611 610 </a>
612 611 ## subnav with menu for logged in user
613 612 <div class="user-menu submenu">
614 613 <div id="quick_login">
615 614 %if c.rhodecode_user.username != h.DEFAULT_USER:
616 615 <div class="">
617 616 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
618 617 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
619 618 <div class="email">${c.rhodecode_user.email}</div>
620 619 </div>
621 620 <div class="">
622 621 <ol class="links">
623 622 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
624 623 % if c.rhodecode_user.personal_repo_group:
625 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>
626 625 % endif
627 626 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
628 627
629 628 % if c.debug_style:
630 629 <li>
631 630 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
632 631 <div class="menulabel">${_('[Style]')}</div>
633 632 </a>
634 633 </li>
635 634 % endif
636 635
637 636 ## bookmark-items
638 637 <li class="bookmark-items">
639 638 ${_('Bookmarks')}
640 639 <div class="pull-right">
641 640 <a href="${h.route_path('my_account_bookmarks')}">
642 641
643 642 <i class="icon-cog"></i>
644 643 </a>
645 644 </div>
646 645 </li>
647 646 % if not c.bookmark_items:
648 647 <li>
649 648 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
650 649 </li>
651 650 % endif
652 651 % for item in c.bookmark_items:
653 652 <li>
654 653 % if item.repository:
655 654 <div>
656 655 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
657 656 <code>${item.position}</code>
658 657 % if item.repository.repo_type == 'hg':
659 658 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
660 659 % elif item.repository.repo_type == 'git':
661 660 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
662 661 % elif item.repository.repo_type == 'svn':
663 662 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
664 663 % endif
665 664 ${(item.title or h.shorter(item.repository.repo_name, 30))}
666 665 </a>
667 666 </div>
668 667 % elif item.repository_group:
669 668 <div>
670 669 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
671 670 <code>${item.position}</code>
672 671 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
673 672 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
674 673 </a>
675 674 </div>
676 675 % else:
677 676 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
678 677 <code>${item.position}</code>
679 678 ${item.title}
680 679 </a>
681 680 % endif
682 681 </li>
683 682 % endfor
684 683
685 684 <li class="logout">
686 685 ${h.secure_form(h.route_path('logout'), request=request)}
687 686 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
688 687 ${h.end_form()}
689 688 </li>
690 689 </ol>
691 690 </div>
692 691 %endif
693 692 </div>
694 693 </div>
695 694
696 695 % endif
697 696 </li>
698 697 </%def>
699 698
700 699 <%def name="menu_items(active=None)">
701 700 <%
702 701 notice_messages, notice_level = c.rhodecode_user.get_notice_messages()
703 702 notice_display = 'none' if len(notice_messages) == 0 else ''
704 703 %>
705 704
706 705 <ul id="quick" class="main_nav navigation horizontal-list">
707 706 ## notice box for important system messages
708 707 <li style="display: ${notice_display}">
709 708 <a class="notice-box" href="#openNotice" onclick="$('.notice-messages-container').toggle(); return false">
710 709 <div class="menulabel-notice ${notice_level}" >
711 710 ${len(notice_messages)}
712 711 </div>
713 712 </a>
714 713 </li>
715 714 <div class="notice-messages-container" style="display: none">
716 715 <div class="notice-messages">
717 716 <table class="rctable">
718 717 % for notice in notice_messages:
719 718 <tr id="notice-message-${notice['msg_id']}" class="notice-message-${notice['level']}">
720 719 <td style="vertical-align: text-top; width: 20px">
721 720 <i class="tooltip icon-info notice-color-${notice['level']}" title="${notice['level']}"></i>
722 721 </td>
723 722 <td>
724 723 <span><i class="icon-plus-squared cursor-pointer" onclick="$('#notice-${notice['msg_id']}').toggle()"></i> </span>
725 724 ${notice['subject']}
726 725
727 726 <div id="notice-${notice['msg_id']}" style="display: none">
728 727 ${h.render(notice['body'], renderer='markdown')}
729 728 </div>
730 729 </td>
731 730 <td style="vertical-align: text-top; width: 35px;">
732 731 <a class="tooltip" title="${_('dismiss')}" href="#dismiss" onclick="dismissNotice(${notice['msg_id']});return false">
733 732 <i class="icon-remove icon-filled-red"></i>
734 733 </a>
735 734 </td>
736 735 </tr>
737 736
738 737 % endfor
739 738 </table>
740 739 </div>
741 740 </div>
742 741 ## Main filter
743 742 <li>
744 743 <div class="menulabel main_filter_box">
745 744 <div class="main_filter_input_box">
746 745 <ul class="searchItems">
747 746
748 747 <li class="searchTag searchTagIcon">
749 748 <i class="icon-search"></i>
750 749 </li>
751 750
752 751 % if c.template_context['search_context']['repo_id']:
753 752 <li class="searchTag searchTagFilter searchTagHidable" >
754 753 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
755 754 <span class="tag">
756 755 This repo
757 756 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
758 757 </span>
759 758 ##</a>
760 759 </li>
761 760 % elif c.template_context['search_context']['repo_group_id']:
762 761 <li class="searchTag searchTagFilter searchTagHidable">
763 762 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
764 763 <span class="tag">
765 764 This group
766 765 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
767 766 </span>
768 767 ##</a>
769 768 </li>
770 769 % endif
771 770
772 771 <li class="searchTagInput">
773 772 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
774 773 </li>
775 774 <li class="searchTag searchTagHelp">
776 775 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
777 776 </li>
778 777 </ul>
779 778 </div>
780 779 </div>
781 780
782 781 <div id="main_filter_help" style="display: none">
783 782 - Use '/' key to quickly access this field.
784 783
785 784 - Enter a name of repository, or repository group for quick search.
786 785
787 786 - Prefix query to allow special search:
788 787
789 788 <strong>user:</strong>admin, to search for usernames, always global
790 789
791 790 <strong>user_group:</strong>devops, to search for user groups, always global
792 791
793 792 <strong>pr:</strong>303, to search for pull request number, title, or description, always global
794 793
795 794 <strong>commit:</strong>efced4, to search for commits, scoped to repositories or groups
796 795
797 796 <strong>file:</strong>models.py, to search for file paths, scoped to repositories or groups
798 797
799 798 % if c.template_context['search_context']['repo_id']:
800 799 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 800 % elif c.template_context['search_context']['repo_group_id']:
802 801 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 802 % else:
804 803 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
805 804 % endif
806 805 </div>
807 806 </li>
808 807
809 808 ## ROOT MENU
810 809 <li class="${h.is_active('home', active)}">
811 810 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
812 811 <div class="menulabel">${_('Home')}</div>
813 812 </a>
814 813 </li>
815 814
816 815 %if c.rhodecode_user.username != h.DEFAULT_USER:
817 816 <li class="${h.is_active('journal', active)}">
818 817 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
819 818 <div class="menulabel">${_('Journal')}</div>
820 819 </a>
821 820 </li>
822 821 %else:
823 822 <li class="${h.is_active('journal', active)}">
824 823 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
825 824 <div class="menulabel">${_('Public journal')}</div>
826 825 </a>
827 826 </li>
828 827 %endif
829 828
830 829 <li class="${h.is_active('gists', active)}">
831 830 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
832 831 <div class="menulabel">${_('Gists')}</div>
833 832 </a>
834 833 </li>
835 834
836 835 % if c.is_super_admin or c.is_delegated_admin:
837 836 <li class="${h.is_active('admin', active)}">
838 837 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
839 838 <div class="menulabel">${_('Admin')} </div>
840 839 </a>
841 840 </li>
842 841 % endif
843 842
844 843 ## render extra user menu
845 844 ${usermenu(active=(active=='my_account'))}
846 845
847 846 </ul>
848 847
849 848 <script type="text/javascript">
850 849 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
851 850
852 851 var formatRepoResult = function(result, container, query, escapeMarkup) {
853 852 return function(data, escapeMarkup) {
854 853 if (!data.repo_id){
855 854 return data.text; // optgroup text Repositories
856 855 }
857 856
858 857 var tmpl = '';
859 858 var repoType = data['repo_type'];
860 859 var repoName = data['text'];
861 860
862 861 if(data && data.type == 'repo'){
863 862 if(repoType === 'hg'){
864 863 tmpl += '<i class="icon-hg"></i> ';
865 864 }
866 865 else if(repoType === 'git'){
867 866 tmpl += '<i class="icon-git"></i> ';
868 867 }
869 868 else if(repoType === 'svn'){
870 869 tmpl += '<i class="icon-svn"></i> ';
871 870 }
872 871 if(data['private']){
873 872 tmpl += '<i class="icon-lock" ></i> ';
874 873 }
875 874 else if(visualShowPublicIcon){
876 875 tmpl += '<i class="icon-unlock-alt"></i> ';
877 876 }
878 877 }
879 878 tmpl += escapeMarkup(repoName);
880 879 return tmpl;
881 880
882 881 }(result, escapeMarkup);
883 882 };
884 883
885 884 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
886 885 return function(data, escapeMarkup) {
887 886 if (!data.repo_group_id){
888 887 return data.text; // optgroup text Repositories
889 888 }
890 889
891 890 var tmpl = '';
892 891 var repoGroupName = data['text'];
893 892
894 893 if(data){
895 894
896 895 tmpl += '<i class="icon-repo-group"></i> ';
897 896
898 897 }
899 898 tmpl += escapeMarkup(repoGroupName);
900 899 return tmpl;
901 900
902 901 }(result, escapeMarkup);
903 902 };
904 903
905 904 var escapeRegExChars = function (value) {
906 905 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
907 906 };
908 907
909 908 var getRepoIcon = function(repo_type) {
910 909 if (repo_type === 'hg') {
911 910 return '<i class="icon-hg"></i> ';
912 911 }
913 912 else if (repo_type === 'git') {
914 913 return '<i class="icon-git"></i> ';
915 914 }
916 915 else if (repo_type === 'svn') {
917 916 return '<i class="icon-svn"></i> ';
918 917 }
919 918 return ''
920 919 };
921 920
922 921 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
923 922
924 923 if (value.split(':').length === 2) {
925 924 value = value.split(':')[1]
926 925 }
927 926
928 927 var searchType = data['type'];
929 928 var searchSubType = data['subtype'];
930 929 var valueDisplay = data['value_display'];
931 930 var valueIcon = data['value_icon'];
932 931
933 932 var pattern = '(' + escapeRegExChars(value) + ')';
934 933
935 934 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
936 935
937 936 // highlight match
938 937 if (searchType != 'text') {
939 938 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
940 939 }
941 940
942 941 var icon = '';
943 942
944 943 if (searchType === 'hint') {
945 944 icon += '<i class="icon-repo-group"></i> ';
946 945 }
947 946 // full text search/hints
948 947 else if (searchType === 'search') {
949 948 if (valueIcon === undefined) {
950 949 icon += '<i class="icon-more"></i> ';
951 950 } else {
952 951 icon += valueIcon + ' ';
953 952 }
954 953
955 954 if (searchSubType !== undefined && searchSubType == 'repo') {
956 955 valueDisplay += '<div class="pull-right tag">repository</div>';
957 956 }
958 957 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
959 958 valueDisplay += '<div class="pull-right tag">repo group</div>';
960 959 }
961 960 }
962 961 // repository
963 962 else if (searchType === 'repo') {
964 963
965 964 var repoIcon = getRepoIcon(data['repo_type']);
966 965 icon += repoIcon;
967 966
968 967 if (data['private']) {
969 968 icon += '<i class="icon-lock" ></i> ';
970 969 }
971 970 else if (visualShowPublicIcon) {
972 971 icon += '<i class="icon-unlock-alt"></i> ';
973 972 }
974 973 }
975 974 // repository groups
976 975 else if (searchType === 'repo_group') {
977 976 icon += '<i class="icon-repo-group"></i> ';
978 977 }
979 978 // user group
980 979 else if (searchType === 'user_group') {
981 980 icon += '<i class="icon-group"></i> ';
982 981 }
983 982 // user
984 983 else if (searchType === 'user') {
985 984 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
986 985 }
987 986 // pull request
988 987 else if (searchType === 'pull_request') {
989 988 icon += '<i class="icon-merge"></i> ';
990 989 }
991 990 // commit
992 991 else if (searchType === 'commit') {
993 992 var repo_data = data['repo_data'];
994 993 var repoIcon = getRepoIcon(repo_data['repository_type']);
995 994 if (repoIcon) {
996 995 icon += repoIcon;
997 996 } else {
998 997 icon += '<i class="icon-tag"></i>';
999 998 }
1000 999 }
1001 1000 // file
1002 1001 else if (searchType === 'file') {
1003 1002 var repo_data = data['repo_data'];
1004 1003 var repoIcon = getRepoIcon(repo_data['repository_type']);
1005 1004 if (repoIcon) {
1006 1005 icon += repoIcon;
1007 1006 } else {
1008 1007 icon += '<i class="icon-tag"></i>';
1009 1008 }
1010 1009 }
1011 1010 // generic text
1012 1011 else if (searchType === 'text') {
1013 1012 icon = '';
1014 1013 }
1015 1014
1016 1015 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
1017 1016 return tmpl.format(icon, valueDisplay);
1018 1017 };
1019 1018
1020 1019 var handleSelect = function(element, suggestion) {
1021 1020 if (suggestion.type === "hint") {
1022 1021 // we skip action
1023 1022 $('#main_filter').focus();
1024 1023 }
1025 1024 else if (suggestion.type === "text") {
1026 1025 // we skip action
1027 1026 $('#main_filter').focus();
1028 1027
1029 1028 } else {
1030 1029 window.location = suggestion['url'];
1031 1030 }
1032 1031 };
1033 1032
1034 1033 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
1035 1034 if (queryLowerCase.split(':').length === 2) {
1036 1035 queryLowerCase = queryLowerCase.split(':')[1]
1037 1036 }
1038 1037 if (suggestion.type === "text") {
1039 1038 // special case we don't want to "skip" display for
1040 1039 return true
1041 1040 }
1042 1041 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
1043 1042 };
1044 1043
1045 1044 var cleanContext = {
1046 1045 repo_view_type: null,
1047 1046
1048 1047 repo_id: null,
1049 1048 repo_name: "",
1050 1049
1051 1050 repo_group_id: null,
1052 1051 repo_group_name: null
1053 1052 };
1054 1053 var removeGoToFilter = function () {
1055 1054 $('.searchTagHidable').hide();
1056 1055 $('#main_filter').autocomplete(
1057 1056 'setOptions', {params:{search_context: cleanContext}});
1058 1057 };
1059 1058
1060 1059 $('#main_filter').autocomplete({
1061 1060 serviceUrl: pyroutes.url('goto_switcher_data'),
1062 1061 params: {
1063 1062 "search_context": templateContext.search_context
1064 1063 },
1065 1064 minChars:2,
1066 1065 maxHeight:400,
1067 1066 deferRequestBy: 300, //miliseconds
1068 1067 tabDisabled: true,
1069 1068 autoSelectFirst: false,
1070 1069 containerClass: 'autocomplete-qfilter-suggestions',
1071 1070 formatResult: autocompleteMainFilterFormatResult,
1072 1071 lookupFilter: autocompleteMainFilterResult,
1073 1072 onSelect: function (element, suggestion) {
1074 1073 handleSelect(element, suggestion);
1075 1074 return false;
1076 1075 },
1077 1076 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
1078 1077 if (jqXHR !== 'abort') {
1079 1078 var message = formatErrorMessage(jqXHR, textStatus, errorThrown);
1080 1079 SwalNoAnimation.fire({
1081 1080 icon: 'error',
1082 1081 title: _gettext('Error during search operation'),
1083 1082 html: '<span style="white-space: pre-line">{0}</span>'.format(message),
1084 1083 }).then(function(result) {
1085 1084 window.location.reload();
1086 1085 })
1087 1086 }
1088 1087 },
1089 1088 onSearchStart: function (params) {
1090 1089 $('.searchTag.searchTagIcon').html('<i class="icon-spin animate-spin"></i>')
1091 1090 },
1092 1091 onSearchComplete: function (query, suggestions) {
1093 1092 $('.searchTag.searchTagIcon').html('<i class="icon-search"></i>')
1094 1093 },
1095 1094 });
1096 1095
1097 1096 showMainFilterBox = function () {
1098 1097 $('#main_filter_help').toggle();
1099 1098 };
1100 1099
1101 1100 $('#main_filter').on('keydown.autocomplete', function (e) {
1102 1101
1103 1102 var BACKSPACE = 8;
1104 1103 var el = $(e.currentTarget);
1105 1104 if(e.which === BACKSPACE){
1106 1105 var inputVal = el.val();
1107 1106 if (inputVal === ""){
1108 1107 removeGoToFilter()
1109 1108 }
1110 1109 }
1111 1110 });
1112 1111
1113 1112 var dismissNotice = function(noticeId) {
1114 1113
1115 1114 var url = pyroutes.url('user_notice_dismiss',
1116 1115 {"user_id": templateContext.rhodecode_user.user_id});
1117 1116
1118 1117 var postData = {
1119 1118 'csrf_token': CSRF_TOKEN,
1120 1119 'notice_id': noticeId,
1121 1120 };
1122 1121
1123 1122 var success = function(response) {
1124 1123 $('#notice-message-' + noticeId).remove();
1125 1124 return false;
1126 1125 };
1127 1126 var failure = function(data, textStatus, xhr) {
1128 1127 alert("error processing request: " + textStatus);
1129 1128 return false;
1130 1129 };
1131 1130 ajaxPOST(url, postData, success, failure);
1132 1131 }
1133 1132
1134 1133 var hideLicenseWarning = function () {
1135 1134 var fingerprint = templateContext.session_attrs.license_fingerprint;
1136 1135 storeUserSessionAttr('rc_user_session_attr.hide_license_warning', fingerprint);
1137 1136 $('#notifications').hide();
1138 1137 }
1139 1138
1140 1139 var hideLicenseError = function () {
1141 1140 var fingerprint = templateContext.session_attrs.license_fingerprint;
1142 1141 storeUserSessionAttr('rc_user_session_attr.hide_license_error', fingerprint);
1143 1142 $('#notifications').hide();
1144 1143 }
1145 1144
1146 1145 </script>
1147 1146 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
1148 1147 </%def>
1149 1148
1150 1149 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
1151 1150 <div class="modal-dialog">
1152 1151 <div class="modal-content">
1153 1152 <div class="modal-header">
1154 1153 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
1155 1154 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
1156 1155 </div>
1157 1156 <div class="modal-body">
1158 1157 <div class="block-left">
1159 1158 <table class="keyboard-mappings">
1160 1159 <tbody>
1161 1160 <tr>
1162 1161 <th></th>
1163 1162 <th>${_('Site-wide shortcuts')}</th>
1164 1163 </tr>
1165 1164 <%
1166 1165 elems = [
1167 1166 ('/', 'Use quick search box'),
1168 1167 ('g h', 'Goto home page'),
1169 1168 ('g g', 'Goto my private gists page'),
1170 1169 ('g G', 'Goto my public gists page'),
1171 1170 ('g 0-9', 'Goto bookmarked items from 0-9'),
1172 1171 ('n r', 'New repository page'),
1173 1172 ('n g', 'New gist page'),
1174 1173 ]
1175 1174 %>
1176 1175 %for key, desc in elems:
1177 1176 <tr>
1178 1177 <td class="keys">
1179 1178 <span class="key tag">${key}</span>
1180 1179 </td>
1181 1180 <td>${desc}</td>
1182 1181 </tr>
1183 1182 %endfor
1184 1183 </tbody>
1185 1184 </table>
1186 1185 </div>
1187 1186 <div class="block-left">
1188 1187 <table class="keyboard-mappings">
1189 1188 <tbody>
1190 1189 <tr>
1191 1190 <th></th>
1192 1191 <th>${_('Repositories')}</th>
1193 1192 </tr>
1194 1193 <%
1195 1194 elems = [
1196 1195 ('g s', 'Goto summary page'),
1197 1196 ('g c', 'Goto changelog page'),
1198 1197 ('g f', 'Goto files page'),
1199 1198 ('g F', 'Goto files page with file search activated'),
1200 1199 ('g p', 'Goto pull requests page'),
1201 1200 ('g o', 'Goto repository settings'),
1202 1201 ('g O', 'Goto repository access permissions settings'),
1203 1202 ('t s', 'Toggle sidebar on some pages'),
1204 1203 ]
1205 1204 %>
1206 1205 %for key, desc in elems:
1207 1206 <tr>
1208 1207 <td class="keys">
1209 1208 <span class="key tag">${key}</span>
1210 1209 </td>
1211 1210 <td>${desc}</td>
1212 1211 </tr>
1213 1212 %endfor
1214 1213 </tbody>
1215 1214 </table>
1216 1215 </div>
1217 1216 </div>
1218 1217 <div class="modal-footer">
1219 1218 </div>
1220 1219 </div><!-- /.modal-content -->
1221 1220 </div><!-- /.modal-dialog -->
1222 1221 </div><!-- /.modal -->
1223 1222
1224 1223
1225 1224 <script type="text/javascript">
1226 1225 (function () {
1227 1226 "use sctrict";
1228 1227
1229 1228 // details block auto-hide menu
1230 1229 $(document).mouseup(function(e) {
1231 1230 var container = $('.details-inline-block');
1232 1231 if (!container.is(e.target) && container.has(e.target).length === 0) {
1233 1232 $('.details-inline-block[open]').removeAttr('open')
1234 1233 }
1235 1234 });
1236 1235
1237 1236 var $sideBar = $('.right-sidebar');
1238 1237 var expanded = $sideBar.hasClass('right-sidebar-expanded');
1239 1238 var sidebarState = templateContext.session_attrs.sidebarState;
1240 1239 var sidebarEnabled = $('aside.right-sidebar').get(0);
1241 1240
1242 1241 if (sidebarState === 'expanded') {
1243 1242 expanded = true
1244 1243 } else if (sidebarState === 'collapsed') {
1245 1244 expanded = false
1246 1245 }
1247 1246 if (sidebarEnabled) {
1248 1247 // show sidebar since it's hidden on load
1249 1248 $('.right-sidebar').show();
1250 1249
1251 1250 // init based on set initial class, or if defined user session attrs
1252 1251 if (expanded) {
1253 1252 window.expandSidebar();
1254 1253 window.updateStickyHeader();
1255 1254
1256 1255 } else {
1257 1256 window.collapseSidebar();
1258 1257 window.updateStickyHeader();
1259 1258 }
1260 1259 }
1261 1260 })()
1262 1261
1263 1262 </script>
@@ -1,166 +1,165 b''
1 ## -*- coding: utf-8 -*-
2 1 <!DOCTYPE html>
3 2
4 3 <%
5 4 c.template_context['repo_name'] = getattr(c, 'repo_name', '')
6 5 go_import_header = ''
7 6 if hasattr(c, 'rhodecode_db_repo'):
8 7 c.template_context['repo_type'] = c.rhodecode_db_repo.repo_type
9 8 c.template_context['repo_landing_commit'] = c.rhodecode_db_repo.landing_ref_name
10 9 c.template_context['repo_id'] = c.rhodecode_db_repo.repo_id
11 10 c.template_context['repo_view_type'] = h.get_repo_view_type(request)
12 11
13 12 if getattr(c, 'repo_group', None):
14 13 c.template_context['repo_group_id'] = c.repo_group.group_id
15 14 c.template_context['repo_group_name'] = c.repo_group.group_name
16 15
17 16 if getattr(c, 'rhodecode_user', None) and c.rhodecode_user.user_id:
18 17 c.template_context['rhodecode_user']['user_id'] = c.rhodecode_user.user_id
19 18 c.template_context['rhodecode_user']['username'] = c.rhodecode_user.username
20 19 c.template_context['rhodecode_user']['email'] = c.rhodecode_user.email
21 20 c.template_context['rhodecode_user']['notification_status'] = c.rhodecode_user.get_instance().user_data.get('notification_status', True)
22 21 c.template_context['rhodecode_user']['first_name'] = c.rhodecode_user.first_name
23 22 c.template_context['rhodecode_user']['last_name'] = c.rhodecode_user.last_name
24 23
25 24 c.template_context['visual']['default_renderer'] = h.get_visual_attr(c, 'default_renderer')
26 25 c.template_context['default_user'] = {
27 26 'username': h.DEFAULT_USER,
28 27 'user_id': 1
29 28 }
30 29 c.template_context['search_context'] = {
31 30 'repo_group_id': c.template_context.get('repo_group_id'),
32 31 'repo_group_name': c.template_context.get('repo_group_name'),
33 32 'repo_id': c.template_context.get('repo_id'),
34 33 'repo_name': c.template_context.get('repo_name'),
35 34 'repo_view_type': c.template_context.get('repo_view_type'),
36 35 }
37 36
38 37 c.template_context['attachment_store'] = {
39 38 'max_file_size_mb': 10,
40 39 'image_ext': ["png", "jpg", "gif", "jpeg"]
41 40 }
42 41
43 42 %>
44 43 <html xmlns="http://www.w3.org/1999/xhtml">
45 44 <head>
46 45 <title>${self.title()}</title>
47 46 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
48 47
49 48 ${h.go_import_header(request, getattr(c, 'rhodecode_db_repo', None))}
50 49
51 50 % if 'safari' in (request.user_agent or '').lower():
52 51 <meta name="referrer" content="origin">
53 52 % else:
54 53 <meta name="referrer" content="origin-when-cross-origin">
55 54 % endif
56 55
57 56 <%def name="robots()">
58 57 <meta name="robots" content="index, nofollow"/>
59 58 </%def>
60 59 ${self.robots()}
61 60 <link rel="icon" href="${h.asset('images/favicon.ico', ver=c.rhodecode_version_hash)}" sizes="16x16 32x32" type="image/png" />
62 61 <script src="${h.asset('js/vendors/webcomponentsjs/custom-elements-es5-adapter.js', ver=c.rhodecode_version_hash)}"></script>
63 62 <script src="${h.asset('js/vendors/webcomponentsjs/webcomponents-bundle.js', ver=c.rhodecode_version_hash)}"></script>
64 63
65 64 ## CSS definitions
66 65 <%def name="css()">
67 66 <link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/>
68 67 ## EXTRA FOR CSS
69 68 ${self.css_extra()}
70 69 </%def>
71 70 ## CSS EXTRA - optionally inject some extra CSS stuff needed for specific websites
72 71 <%def name="css_extra()">
73 72 </%def>
74 73
75 74 ${self.css()}
76 75
77 76 ## JAVASCRIPT
78 77 <%def name="js()">
79 78
80 79 <script src="${h.asset('js/rhodecode/i18n/%s.js' % c.language, ver=c.rhodecode_version_hash)}"></script>
81 80 <script type="text/javascript">
82 81 // register templateContext to pass template variables to JS
83 82 var templateContext = ${h.str_json(c.template_context)|n};
84 83
85 84 var APPLICATION_URL = "${h.route_path('home').rstrip('/')}";
86 85 var APPLICATION_PLUGINS = [];
87 86 var ASSET_URL = "${h.asset('')}";
88 87 var DEFAULT_RENDERER = "${h.get_visual_attr(c, 'default_renderer')}";
89 88 var CSRF_TOKEN = "${getattr(c, 'csrf_token', '')}";
90 89
91 90 var APPENLIGHT = {
92 91 enabled: ${'true' if getattr(c, 'appenlight_enabled', False) else 'false'},
93 92 key: '${getattr(c, "appenlight_api_public_key", "")}',
94 93 % if getattr(c, 'appenlight_server_url', None):
95 94 serverUrl: '${getattr(c, "appenlight_server_url", "")}',
96 95 % endif
97 96 requestInfo: {
98 97 % if getattr(c, 'rhodecode_user', None):
99 98 ip: '${c.rhodecode_user.ip_addr}',
100 99 username: '${c.rhodecode_user.username}'
101 100 % endif
102 101 },
103 102 tags: {
104 103 rhodecode_version: '${c.rhodecode_version}',
105 104 rhodecode_edition: '${c.rhodecode_edition}'
106 105 }
107 106 };
108 107
109 108 </script>
110 109 <%include file="/base/plugins_base.mako"/>
111 110 <!--[if lt IE 9]>
112 111 <script language="javascript" type="text/javascript" src="${h.asset('js/src/excanvas.min.js')}"></script>
113 112 <![endif]-->
114 113 <script language="javascript" type="text/javascript" src="${h.asset('js/rhodecode/routes.js', ver=c.rhodecode_version_hash)}"></script>
115 114 <script> var alertMessagePayloads = ${h.flash.json_alerts(request=request)|n}; </script>
116 115 ## avoide escaping the %N
117 116 <script language="javascript" type="text/javascript" src="${h.asset('js/scripts.min.js', ver=c.rhodecode_version_hash)}"></script>
118 117 <script>CodeMirror.modeURL = "${h.asset('') + 'js/mode/%N/%N.js?ver='+c.rhodecode_version_hash}";</script>
119 118
120 119
121 120 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
122 121 ${self.js_extra()}
123 122
124 123 <script type="text/javascript">
125 124 Rhodecode = (function() {
126 125 function _Rhodecode() {
127 126 this.comments = new CommentsController();
128 127 }
129 128 return new _Rhodecode();
130 129 })();
131 130
132 131 $(document).ready(function(){
133 132 show_more_event();
134 133 timeagoActivate();
135 134 tooltipActivate();
136 135 clipboardActivate();
137 136 })
138 137 </script>
139 138
140 139 </%def>
141 140
142 141 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
143 142 <%def name="js_extra()"></%def>
144 143 ${self.js()}
145 144
146 145 <%def name="head_extra()"></%def>
147 146 ${self.head_extra()}
148 147 ## extra stuff
149 148 %if c.pre_code:
150 149 ${c.pre_code|n}
151 150 %endif
152 151 </head>
153 152 <body id="body">
154 153 <noscript>
155 154 <div class="noscript-error">
156 155 ${_('Please enable JavaScript to use RhodeCode Enterprise')}
157 156 </div>
158 157 </noscript>
159 158
160 159 ${next.body()}
161 160 %if c.post_code:
162 161 ${c.post_code|n}
163 162 %endif
164 163 <rhodecode-app></rhodecode-app>
165 164 </body>
166 165 </html>
@@ -1,119 +1,118 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2 <%namespace name="components" file="/summary/components.mako"/>
4 3
5 4 <%def name="title()">
6 5 ${_('{} Bookmarks').format(c.repo_name)}
7 6 %if c.rhodecode_name:
8 7 &middot; ${h.branding(c.rhodecode_name)}
9 8 %endif
10 9 </%def>
11 10
12 11 <%def name="breadcrumbs_links()"></%def>
13 12
14 13 <%def name="menu_bar_nav()">
15 14 ${self.menu_items(active='repositories')}
16 15 </%def>
17 16
18 17 <%def name="menu_bar_subnav()">
19 18 ${self.repo_menu(active='summary')}
20 19 </%def>
21 20
22 21 <%def name="main()">
23 22 <div id="repo-summary" class="summary">
24 23 ${components.summary_detail(breadcrumbs_links=self.breadcrumbs_links(), show_downloads=False, simplified=True)}
25 24 </div>
26 25
27 26 <div class="box">
28 27 <div class="title">
29 28
30 29 %if c.has_references:
31 30 <ul class="links">
32 31 <li>
33 32 <input type="submit" id="compare_action" class="btn" disabled="disabled" value="${_('Compare Selected Bookmarks')}">
34 33 </li>
35 34 </ul>
36 35 %endif
37 36 %if c.has_references:
38 37 <div class="grid-quick-filter">
39 38 <ul class="grid-filter-box">
40 39 <li class="grid-filter-box-icon">
41 40 <i class="icon-search"></i>
42 41 </li>
43 42 <li class="grid-filter-box-input">
44 43 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
45 44 </li>
46 45 </ul>
47 46 </div>
48 47 <div id="obj_count">0</div>
49 48 %endif
50 49 </div>
51 50
52 51 <table id="obj_list_table" class="rctable table-bordered"></table>
53 52 </div>
54 53
55 54
56 55 <script type="text/javascript">
57 56 $(document).ready(function() {
58 57
59 58 var get_datatable_count = function(){
60 59 var api = $('#obj_list_table').dataTable().api();
61 60 var total = api.page.info().recordsDisplay
62 61 var _text = _ngettext('{0} bookmark', '{0} bookmarks', total).format(total);
63 62 $('#obj_count').text(_text);
64 63 };
65 64
66 65 // object list
67 66 $('#obj_list_table').DataTable({
68 67 data: ${c.data | n},
69 68 dom: 'rtp',
70 69 pageLength: ${c.visual.dashboard_items},
71 70 order: [[ 0, "asc" ]],
72 71 columns: [
73 72 { data: {"_": "name",
74 73 "sort": "name_raw"}, title: "${_('Name')}", className: "td-tags" },
75 74 { data: {"_": "date",
76 75 "sort": "date_raw"}, title: "${_('Date')}", className: "td-time" },
77 76 { data: {"_": "author",
78 77 "sort": "author"}, title: "${_('Author')}", className: "td-user" },
79 78 { data: {"_": "commit",
80 79 "sort": "commit_raw",
81 80 "type": Number}, title: "${_('Commit')}", className: "td-hash" },
82 81 { data: {"_": "compare",
83 82 "sort": "compare"}, title: "${_('Compare')}", className: "td-compare" }
84 83 ],
85 84 language: {
86 85 paginate: DEFAULT_GRID_PAGINATION,
87 86 emptyTable: _gettext("No bookmarks available yet.")
88 87 },
89 88 "initComplete": function(settings, json) {
90 89 get_datatable_count();
91 90 timeagoActivate();
92 91 tooltipActivate();
93 92 compare_radio_buttons("${c.repo_name}", 'book');
94 93 }
95 94 });
96 95
97 96 // update when things change
98 97 $('#obj_list_table').on('draw.dt', function() {
99 98 get_datatable_count();
100 99 timeagoActivate();
101 100 tooltipActivate();
102 101 });
103 102
104 103 // filter, filter both grids
105 104 $('#q_filter').on('keyup', function() {
106 105 var obj_api = $('#obj_list_table').dataTable().api();
107 106 obj_api
108 107 .columns(0)
109 108 .search(this.value)
110 109 .draw();
111 110 });
112 111
113 112 // refilter table if page load via back button
114 113 $("#q_filter").trigger('keyup');
115 114
116 115 });
117 116
118 117 </script>
119 118 </%def>
@@ -1,118 +1,117 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2 <%namespace name="components" file="/summary/components.mako"/>
4 3
5 4 <%def name="title()">
6 5 ${_('{} Branches').format(c.repo_name)}
7 6 %if c.rhodecode_name:
8 7 &middot; ${h.branding(c.rhodecode_name)}
9 8 %endif
10 9 </%def>
11 10
12 11 <%def name="breadcrumbs_links()"></%def>
13 12
14 13 <%def name="menu_bar_nav()">
15 14 ${self.menu_items(active='repositories')}
16 15 </%def>
17 16
18 17 <%def name="menu_bar_subnav()">
19 18 ${self.repo_menu(active='summary')}
20 19 </%def>
21 20
22 21 <%def name="main()">
23 22 <div id="repo-summary" class="summary">
24 23 ${components.summary_detail(breadcrumbs_links=self.breadcrumbs_links(), show_downloads=False, simplified=True)}
25 24 </div>
26 25
27 26 <div class="box">
28 27 <div class="title">
29 28
30 29 %if c.has_references:
31 30 <ul class="links">
32 31 <li>
33 32 <input type="submit" id="compare_action" class="btn" disabled="disabled" value="${_('Compare Selected Branches')}"/>
34 33 </li>
35 34 </ul>
36 35 %endif
37 36 %if c.has_references:
38 37 <div class="grid-quick-filter">
39 38 <ul class="grid-filter-box">
40 39 <li class="grid-filter-box-icon">
41 40 <i class="icon-search"></i>
42 41 </li>
43 42 <li class="grid-filter-box-input">
44 43 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
45 44 </li>
46 45 </ul>
47 46 </div>
48 47 <div id="obj_count">0</div>
49 48 %endif
50 49 </div>
51 50 <table id="obj_list_table" class="rctable table-bordered"></table>
52 51 </div>
53 52
54 53 <script type="text/javascript">
55 54 $(document).ready(function() {
56 55
57 56 var get_datatable_count = function(){
58 57 var api = $('#obj_list_table').dataTable().api();
59 58 var total = api.page.info().recordsDisplay
60 59 var _text = _ngettext('{0} branch', '{0} branches', total).format(total);
61 60
62 61 $('#obj_count').text(_text);
63 62 };
64 63
65 64 // object list
66 65 $('#obj_list_table').DataTable({
67 66 data: ${c.data|n},
68 67 dom: 'rtp',
69 68 pageLength: ${c.visual.dashboard_items},
70 69 order: [[ 0, "asc" ]],
71 70 columns: [
72 71 { data: {"_": "name",
73 72 "sort": "name_raw"}, title: "${_('Name')}", className: "td-tags" },
74 73 { data: {"_": "date",
75 74 "sort": "date_raw"}, title: "${_('Date')}", className: "td-time" },
76 75 { data: {"_": "author",
77 76 "sort": "author"}, title: "${_('Author')}", className: "td-user" },
78 77 { data: {"_": "commit",
79 78 "sort": "commit_raw",
80 79 "type": Number}, title: "${_('Commit')}", className: "td-hash" },
81 80 { data: {"_": "compare",
82 81 "sort": "compare"}, title: "${_('Compare')}", className: "td-compare" }
83 82 ],
84 83 language: {
85 84 paginate: DEFAULT_GRID_PAGINATION,
86 85 emptyTable: _gettext("No branches available yet.")
87 86 },
88 87 "initComplete": function( settings, json ) {
89 88 get_datatable_count();
90 89 timeagoActivate();
91 90 tooltipActivate();
92 91 compare_radio_buttons("${c.repo_name}", 'branch');
93 92 }
94 93 });
95 94
96 95 // update when things change
97 96 $('#obj_list_table').on('draw.dt', function() {
98 97 get_datatable_count();
99 98 timeagoActivate();
100 99 tooltipActivate();
101 100 });
102 101
103 102 // filter, filter both grids
104 103 $('#q_filter').on( 'keyup', function () {
105 104 var obj_api = $('#obj_list_table').dataTable().api();
106 105 obj_api
107 106 .columns(0)
108 107 .search(this.value)
109 108 .draw();
110 109 });
111 110
112 111 // refilter table if page load via back button
113 112 $("#q_filter").trigger('keyup');
114 113
115 114 });
116 115
117 116 </script>
118 117 </%def>
@@ -1,435 +1,434 b''
1 ## -*- coding: utf-8 -*-
2 1
3 2 <%inherit file="/base/base.mako"/>
4 3 <%namespace name="base" file="/base/base.mako"/>
5 4 <%namespace name="diff_block" file="/changeset/diff_block.mako"/>
6 5 <%namespace name="file_base" file="/files/base.mako"/>
7 6 <%namespace name="sidebar" file="/base/sidebar.mako"/>
8 7
9 8
10 9 <%def name="title()">
11 10 ${_('{} Commit').format(c.repo_name)} - ${h.show_id(c.commit)}
12 11 %if c.rhodecode_name:
13 12 &middot; ${h.branding(c.rhodecode_name)}
14 13 %endif
15 14 </%def>
16 15
17 16 <%def name="menu_bar_nav()">
18 17 ${self.menu_items(active='repositories')}
19 18 </%def>
20 19
21 20 <%def name="menu_bar_subnav()">
22 21 ${self.repo_menu(active='commits')}
23 22 </%def>
24 23
25 24 <%def name="main()">
26 25 <script type="text/javascript">
27 26 templateContext.commit_data.commit_id = "${c.commit.raw_id}";
28 27 </script>
29 28
30 29 <div class="box">
31 30
32 31 <div class="summary">
33 32
34 33 <div class="fieldset">
35 34 <div class="left-content">
36 35 <%
37 36 rc_user = h.discover_user(c.commit.author_email)
38 37 %>
39 38 <div class="left-content-avatar">
40 39 ${base.gravatar(c.commit.author_email, 30, tooltip=(True if rc_user else False), user=rc_user)}
41 40 </div>
42 41
43 42 <div class="left-content-message">
44 43 <div class="fieldset collapsable-content no-hide" data-toggle="summary-details">
45 44 <div class="commit truncate-wrap">${h.urlify_commit_message(h.chop_at_smart(c.commit.message, '\n', suffix_if_chopped='...'), c.repo_name)}</div>
46 45 </div>
47 46
48 47 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none">
49 48 <div class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
50 49 </div>
51 50
52 51 <div class="fieldset" data-toggle="summary-details">
53 52 <div class="">
54 53 <table>
55 54 <tr class="file_author">
56 55
57 56 <td>
58 57 <span class="user commit-author">${h.link_to_user(rc_user or c.commit.author)}</span>
59 58 <span class="commit-date">- ${h.age_component(c.commit.date)}</span>
60 59 </td>
61 60
62 61 <td>
63 62 ## second cell for consistency with files
64 63 </td>
65 64 </tr>
66 65 </table>
67 66 </div>
68 67 </div>
69 68
70 69 </div>
71 70 </div>
72 71
73 72 <div class="right-content">
74 73
75 74 <div data-toggle="summary-details">
76 75 <div class="tags tags-main">
77 76 <code><a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.commit.raw_id)}">${h.show_id(c.commit)}</a></code>
78 77 <i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${c.commit.raw_id}" title="${_('Copy the full commit id')}"></i>
79 78 ${file_base.refs(c.commit)}
80 79
81 80
82 81 ## phase
83 82 % if hasattr(c.commit, 'phase') and getattr(c.commit, 'phase') != 'public':
84 83 <span class="tag phase-${c.commit.phase} tooltip" title="${_('Commit phase')}">
85 84 <i class="icon-info"></i>${c.commit.phase}
86 85 </span>
87 86 % endif
88 87
89 88 ## obsolete commits
90 89 % if getattr(c.commit, 'obsolete', False):
91 90 <span class="tag obsolete-${c.commit.obsolete} tooltip" title="${_('Evolve State')}">
92 91 ${_('obsolete')}
93 92 </span>
94 93 % endif
95 94
96 95 ## hidden commits
97 96 % if getattr(c.commit, 'hidden', False):
98 97 <span class="tag hidden-${c.commit.hidden} tooltip" title="${_('Evolve State')}">
99 98 ${_('hidden')}
100 99 </span>
101 100 % endif
102 101 </div>
103 102
104 103 <span id="parent_link" class="tag tagtag">
105 104 <a href="#parentCommit" title="${_('Parent Commit')}"><i class="icon-left icon-no-margin"></i>${_('parent')}</a>
106 105 </span>
107 106
108 107 <span id="child_link" class="tag tagtag">
109 108 <a href="#childCommit" title="${_('Child Commit')}">${_('child')}<i class="icon-right icon-no-margin"></i></a>
110 109 </span>
111 110 <span class="tag tooltip" title="${_('Browse files at this commit')}">
112 111 <i class="icon-code"></i>
113 112 <a href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path='')}">${_('Browse files')}</a>
114 113 </span>
115 114
116 115 </div>
117 116
118 117 </div>
119 118 </div>
120 119
121 120 <div class="fieldset collapsable-content" data-toggle="summary-details" style="display: none;">
122 121 <div class="left-label-summary">
123 122 <p>${_('Diff options')}:</p>
124 123 <div class="right-label-summary">
125 124 <div class="diff-actions">
126 125 <a href="${h.route_path('repo_commit_raw',repo_name=c.repo_name,commit_id=c.commit.raw_id)}">
127 126 ${_('Raw Diff')}
128 127 </a>
129 128 |
130 129 <a href="${h.route_path('repo_commit_patch',repo_name=c.repo_name,commit_id=c.commit.raw_id)}">
131 130 ${_('Patch Diff')}
132 131 </a>
133 132 |
134 133 <a href="${h.route_path('repo_commit_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,_query=dict(diff='download'))}">
135 134 ${_('Download Diff')}
136 135 </a>
137 136 </div>
138 137 </div>
139 138 </div>
140 139 </div>
141 140
142 141 <div class="clear-fix"></div>
143 142
144 143 <div class="btn-collapse" data-toggle="summary-details">
145 144 ${_('Show More')}
146 145 </div>
147 146
148 147 </div>
149 148
150 149 <div class="cs_files">
151 150 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
152 151 ${cbdiffs.render_diffset_menu(c.changes[c.commit.raw_id], commit=c.commit)}
153 152 ${cbdiffs.render_diffset(
154 153 c.changes[c.commit.raw_id], commit=c.commit, use_comments=True,
155 154 inline_comments=c.inline_comments,
156 155 show_todos=False)}
157 156 </div>
158 157
159 158 ## template for inline comment form
160 159 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
161 160
162 161 ## comments heading with count
163 162 <div class="comments-heading">
164 163 <i class="icon-comment"></i>
165 164 ${_('General Comments')} ${len(c.comments)}
166 165 </div>
167 166
168 167 ## render comments
169 168 ${comment.generate_comments(c.comments)}
170 169
171 170 ## main comment form and it status
172 171 ${comment.comments(h.route_path('repo_commit_comment_create', repo_name=c.repo_name, commit_id=c.commit.raw_id),
173 172 h.commit_status(c.rhodecode_db_repo, c.commit.raw_id))}
174 173 </div>
175 174
176 175 ### NAV SIDEBAR
177 176 <aside class="right-sidebar right-sidebar-expanded" id="commit-nav-sticky" style="display: none">
178 177 <div class="sidenav navbar__inner" >
179 178 ## TOGGLE
180 179 <div class="sidebar-toggle" onclick="toggleSidebar(); return false">
181 180 <a href="#toggleSidebar" class="grey-link-action">
182 181
183 182 </a>
184 183 </div>
185 184
186 185 ## CONTENT
187 186 <div class="sidebar-content">
188 187
189 188 ## RULES SUMMARY/RULES
190 189 <div class="sidebar-element clear-both">
191 190 <% vote_title = _ungettext(
192 191 'Status calculated based on votes from {} reviewer',
193 192 'Status calculated based on votes from {} reviewers', c.reviewers_count).format(c.reviewers_count)
194 193 %>
195 194
196 195 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="${vote_title}">
197 196 <i class="icon-circle review-status-${c.commit_review_status}"></i>
198 197 ${c.reviewers_count}
199 198 </div>
200 199 </div>
201 200
202 201 ## REVIEWERS
203 202 <div class="right-sidebar-expanded-state pr-details-title">
204 203 <span class="tooltip sidebar-heading" title="${vote_title}">
205 204 <i class="icon-circle review-status-${c.commit_review_status}"></i>
206 205 ${_('Reviewers')}
207 206 </span>
208 207 </div>
209 208
210 209 <div id="reviewers" class="right-sidebar-expanded-state pr-details-content reviewers">
211 210
212 211 <table id="review_members" class="group_members">
213 212 ## This content is loaded via JS and ReviewersPanel
214 213 </table>
215 214
216 215 </div>
217 216
218 217 ## TODOs
219 218 <div class="sidebar-element clear-both">
220 219 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="TODOs">
221 220 <i class="icon-flag-filled"></i>
222 221 <span id="todos-count">${len(c.unresolved_comments)}</span>
223 222 </div>
224 223
225 224 <div class="right-sidebar-expanded-state pr-details-title">
226 225 ## Only show unresolved, that is only what matters
227 226 <span class="sidebar-heading noselect" onclick="refreshTODOs(); return false">
228 227 <i class="icon-flag-filled"></i>
229 228 TODOs
230 229 </span>
231 230
232 231 % if c.resolved_comments:
233 232 <span class="block-right action_button last-item noselect" onclick="$('.unresolved-todo-text').toggle(); return toggleElement(this, '.resolved-todo');" data-toggle-on="Show resolved" data-toggle-off="Hide resolved">Show resolved</span>
234 233 % else:
235 234 <span class="block-right last-item noselect">Show resolved</span>
236 235 % endif
237 236
238 237 </div>
239 238
240 239 <div class="right-sidebar-expanded-state pr-details-content">
241 240 % if c.unresolved_comments + c.resolved_comments:
242 241 ${sidebar.comments_table(c.unresolved_comments + c.resolved_comments, len(c.unresolved_comments), todo_comments=True, is_pr=False)}
243 242 % else:
244 243 <table>
245 244 <tr>
246 245 <td>
247 246 ${_('No TODOs yet')}
248 247 </td>
249 248 </tr>
250 249 </table>
251 250 % endif
252 251 </div>
253 252 </div>
254 253
255 254 ## COMMENTS
256 255 <div class="sidebar-element clear-both">
257 256 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="${_('Comments')}">
258 257 <i class="icon-comment" style="color: #949494"></i>
259 258 <span id="comments-count">${len(c.inline_comments_flat+c.comments)}</span>
260 259 <span class="display-none" id="general-comments-count">${len(c.comments)}</span>
261 260 <span class="display-none" id="inline-comments-count">${len(c.inline_comments_flat)}</span>
262 261 </div>
263 262
264 263 <div class="right-sidebar-expanded-state pr-details-title">
265 264 <span class="sidebar-heading noselect" onclick="refreshComments(); return false">
266 265 <i class="icon-comment" style="color: #949494"></i>
267 266 ${_('Comments')}
268 267 </span>
269 268
270 269 </div>
271 270
272 271 <div class="right-sidebar-expanded-state pr-details-content">
273 272 % if c.inline_comments_flat + c.comments:
274 273 ${sidebar.comments_table(c.inline_comments_flat + c.comments, len(c.inline_comments_flat+c.comments), is_pr=False)}
275 274 % else:
276 275 <table>
277 276 <tr>
278 277 <td>
279 278 ${_('No Comments yet')}
280 279 </td>
281 280 </tr>
282 281 </table>
283 282 % endif
284 283 </div>
285 284
286 285 </div>
287 286
288 287 </div>
289 288
290 289 </div>
291 290 </aside>
292 291
293 292 ## FORM FOR MAKING JS ACTION AS CHANGESET COMMENTS
294 293 <script type="text/javascript">
295 294 window.setReviewersData = ${c.commit_set_reviewers_data_json | n};
296 295
297 296 $(document).ready(function () {
298 297 var boxmax = parseInt($('#trimmed_message_box').css('max-height'), 10);
299 298
300 299 if ($('#trimmed_message_box').height() === boxmax) {
301 300 $('#message_expand').show();
302 301 }
303 302
304 303 $('#message_expand').on('click', function (e) {
305 304 $('#trimmed_message_box').css('max-height', 'none');
306 305 $(this).hide();
307 306 });
308 307
309 308 $('.show-inline-comments').on('click', function (e) {
310 309 var boxid = $(this).attr('data-comment-id');
311 310 var button = $(this);
312 311
313 312 if (button.hasClass("comments-visible")) {
314 313 $('#{0} .inline-comments'.format(boxid)).each(function (index) {
315 314 $(this).hide();
316 315 });
317 316 button.removeClass("comments-visible");
318 317 } else {
319 318 $('#{0} .inline-comments'.format(boxid)).each(function (index) {
320 319 $(this).show();
321 320 });
322 321 button.addClass("comments-visible");
323 322 }
324 323 });
325 324
326 325 // next links
327 326 $('#child_link').on('click', function (e) {
328 327 // fetch via ajax what is going to be the next link, if we have
329 328 // >1 links show them to user to choose
330 329 if (!$('#child_link').hasClass('disabled')) {
331 330 $.ajax({
332 331 url: '${h.route_path('repo_commit_children',repo_name=c.repo_name, commit_id=c.commit.raw_id)}',
333 332 success: function (data) {
334 333 if (data.results.length === 0) {
335 334 $('#child_link').html("${_('No Child Commits')}").addClass('disabled');
336 335 }
337 336 if (data.results.length === 1) {
338 337 var commit = data.results[0];
339 338 window.location = pyroutes.url('repo_commit', {
340 339 'repo_name': '${c.repo_name}',
341 340 'commit_id': commit.raw_id
342 341 });
343 342 } else if (data.results.length === 2) {
344 343 $('#child_link').addClass('disabled');
345 344 $('#child_link').addClass('double');
346 345
347 346 var _html = '';
348 347 _html += '<a title="__title__" href="__url__"><span class="tag branchtag"><i class="icon-code-fork"></i>__branch__</span> __rev__</a> '
349 348 .replace('__branch__', data.results[0].branch)
350 349 .replace('__rev__', 'r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0, 6)))
351 350 .replace('__title__', data.results[0].message)
352 351 .replace('__url__', pyroutes.url('repo_commit', {
353 352 'repo_name': '${c.repo_name}',
354 353 'commit_id': data.results[0].raw_id
355 354 }));
356 355 _html += ' | ';
357 356 _html += '<a title="__title__" href="__url__"><span class="tag branchtag"><i class="icon-code-fork"></i>__branch__</span> __rev__</a> '
358 357 .replace('__branch__', data.results[1].branch)
359 358 .replace('__rev__', 'r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0, 6)))
360 359 .replace('__title__', data.results[1].message)
361 360 .replace('__url__', pyroutes.url('repo_commit', {
362 361 'repo_name': '${c.repo_name}',
363 362 'commit_id': data.results[1].raw_id
364 363 }));
365 364 $('#child_link').html(_html);
366 365 }
367 366 }
368 367 });
369 368 e.preventDefault();
370 369 }
371 370 });
372 371
373 372 // prev links
374 373 $('#parent_link').on('click', function (e) {
375 374 // fetch via ajax what is going to be the next link, if we have
376 375 // >1 links show them to user to choose
377 376 if (!$('#parent_link').hasClass('disabled')) {
378 377 $.ajax({
379 378 url: '${h.route_path("repo_commit_parents",repo_name=c.repo_name, commit_id=c.commit.raw_id)}',
380 379 success: function (data) {
381 380 if (data.results.length === 0) {
382 381 $('#parent_link').html('${_('No Parent Commits')}').addClass('disabled');
383 382 }
384 383 if (data.results.length === 1) {
385 384 var commit = data.results[0];
386 385 window.location = pyroutes.url('repo_commit', {
387 386 'repo_name': '${c.repo_name}',
388 387 'commit_id': commit.raw_id
389 388 });
390 389 } else if (data.results.length === 2) {
391 390 $('#parent_link').addClass('disabled');
392 391 $('#parent_link').addClass('double');
393 392
394 393 var _html = '';
395 394 _html += '<a title="__title__" href="__url__"><span class="tag branchtag"><i class="icon-code-fork"></i>__branch__</span> __rev__</a>'
396 395 .replace('__branch__', data.results[0].branch)
397 396 .replace('__rev__', 'r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0, 6)))
398 397 .replace('__title__', data.results[0].message)
399 398 .replace('__url__', pyroutes.url('repo_commit', {
400 399 'repo_name': '${c.repo_name}',
401 400 'commit_id': data.results[0].raw_id
402 401 }));
403 402 _html += ' | ';
404 403 _html += '<a title="__title__" href="__url__"><span class="tag branchtag"><i class="icon-code-fork"></i>__branch__</span> __rev__</a>'
405 404 .replace('__branch__', data.results[1].branch)
406 405 .replace('__rev__', 'r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0, 6)))
407 406 .replace('__title__', data.results[1].message)
408 407 .replace('__url__', pyroutes.url('repo_commit', {
409 408 'repo_name': '${c.repo_name}',
410 409 'commit_id': data.results[1].raw_id
411 410 }));
412 411 $('#parent_link').html(_html);
413 412 }
414 413 }
415 414 });
416 415 e.preventDefault();
417 416 }
418 417 });
419 418
420 419 // browse tree @ revision
421 420 $('#files_link').on('click', function (e) {
422 421 window.location = '${h.route_path('repo_files:default_path',repo_name=c.repo_name, commit_id=c.commit.raw_id)}';
423 422 e.preventDefault();
424 423 });
425 424
426 425 reviewersController = new ReviewersController();
427 426 ReviewersPanel.init(reviewersController, null, setReviewersData);
428 427
429 428 var channel = '${c.commit_broadcast_channel}';
430 429 new ReviewerPresenceController(channel)
431 430
432 431 })
433 432 </script>
434 433
435 434 </%def>
@@ -1,557 +1,556 b''
1 ## -*- coding: utf-8 -*-
2 1 ## usage:
3 2 ## <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
4 3 ## ${comment.comment_block(comment)}
5 4 ##
6 5 <%namespace name="base" file="/base/base.mako"/>
7 6
8 7 <%!
9 8 from rhodecode.lib import html_filters
10 9 %>
11 10
12 11
13 12 <%def name="comment_block(comment, inline=False, active_pattern_entries=None, is_new=False)">
14 13
15 14 <%
16 15 from rhodecode.model.comment import CommentsModel
17 16 comment_model = CommentsModel()
18 17
19 18 comment_ver = comment.get_index_version(getattr(c, 'versions', []))
20 19 latest_ver = len(getattr(c, 'versions', []))
21 20 visible_for_user = True
22 21 if comment.draft:
23 22 visible_for_user = comment.user_id == c.rhodecode_user.user_id
24 23 %>
25 24
26 25 % if inline:
27 26 <% outdated_at_ver = comment.outdated_at_version(c.at_version_num) %>
28 27 % else:
29 28 <% outdated_at_ver = comment.older_than_version(c.at_version_num) %>
30 29 % endif
31 30
32 31 % if visible_for_user:
33 32 <div class="comment
34 33 ${'comment-inline' if inline else 'comment-general'}
35 34 ${'comment-outdated' if outdated_at_ver else 'comment-current'}"
36 35 id="comment-${comment.comment_id}"
37 36 line="${comment.line_no}"
38 37 data-comment-id="${comment.comment_id}"
39 38 data-comment-type="${comment.comment_type}"
40 39 data-comment-draft=${h.str_json(comment.draft)}
41 40 data-comment-renderer="${comment.renderer}"
42 41 data-comment-text="${comment.text | html_filters.base64,n}"
43 42 data-comment-f-path="${comment.f_path}"
44 43 data-comment-line-no="${comment.line_no}"
45 44 data-comment-inline=${h.str_json(inline)}
46 45 style="${'display: none;' if outdated_at_ver else ''}">
47 46
48 47 <div class="meta">
49 48 <div class="comment-type-label">
50 49 % if comment.draft:
51 50 <div class="tooltip comment-draft" title="${_('Draft comments are only visible to the author until submitted')}.">
52 51 DRAFT
53 52 </div>
54 53 % elif is_new:
55 54 <div class="tooltip comment-new" title="${_('This comment was added while you browsed this page')}.">
56 55 NEW
57 56 </div>
58 57 % endif
59 58
60 59 <div class="comment-label ${comment.comment_type or 'note'}" id="comment-label-${comment.comment_id}">
61 60
62 61 ## TODO COMMENT
63 62 % if comment.comment_type == 'todo':
64 63 % if comment.resolved:
65 64 <div class="resolved tooltip" title="${_('Resolved by comment #{}').format(comment.resolved.comment_id)}">
66 65 <i class="icon-flag-filled"></i>
67 66 <a href="#comment-${comment.resolved.comment_id}">${comment.comment_type}</a>
68 67 </div>
69 68 % else:
70 69 <div class="resolved tooltip" style="display: none">
71 70 <span>${comment.comment_type}</span>
72 71 </div>
73 72 <div class="resolve tooltip" onclick="return Rhodecode.comments.createResolutionComment(${comment.comment_id});" title="${_('Click to create resolution comment.')}">
74 73 <i class="icon-flag-filled"></i>
75 74 ${comment.comment_type}
76 75 </div>
77 76 % endif
78 77 ## NOTE COMMENT
79 78 % else:
80 79 ## RESOLVED NOTE
81 80 % if comment.resolved_comment:
82 81 <div class="tooltip" title="${_('This comment resolves TODO #{}').format(comment.resolved_comment.comment_id)}">
83 82 fix
84 83 <a href="#comment-${comment.resolved_comment.comment_id}" onclick="Rhodecode.comments.scrollToComment($('#comment-${comment.resolved_comment.comment_id}'), 0, ${h.str_json(comment.resolved_comment.outdated)})">
85 84 <span style="text-decoration: line-through">#${comment.resolved_comment.comment_id}</span>
86 85 </a>
87 86 </div>
88 87 ## STATUS CHANGE NOTE
89 88 % elif not comment.is_inline and comment.status_change:
90 89 <%
91 90 if comment.pull_request:
92 91 status_change_title = 'Status of review for pull request !{}'.format(comment.pull_request.pull_request_id)
93 92 else:
94 93 status_change_title = 'Status of review for commit {}'.format(h.short_id(comment.commit_id))
95 94 %>
96 95
97 96 <i class="icon-circle review-status-${comment.review_status}"></i>
98 97 <div class="changeset-status-lbl tooltip" title="${status_change_title}">
99 98 ${comment.review_status_lbl}
100 99 </div>
101 100 % else:
102 101 <div>
103 102 <i class="icon-comment"></i>
104 103 ${(comment.comment_type or 'note')}
105 104 </div>
106 105 % endif
107 106 % endif
108 107
109 108 </div>
110 109 </div>
111 110 ## NOTE 0 and .. => because we disable it for now until UI ready
112 111 % if 0 and comment.status_change:
113 112 <div class="pull-left">
114 113 <span class="tag authortag tooltip" title="${_('Status from pull request.')}">
115 114 <a href="${h.route_path('pullrequest_show',repo_name=comment.pull_request.target_repo.repo_name,pull_request_id=comment.pull_request.pull_request_id)}">
116 115 ${'!{}'.format(comment.pull_request.pull_request_id)}
117 116 </a>
118 117 </span>
119 118 </div>
120 119 % endif
121 120 ## Since only author can see drafts, we don't show it
122 121 % if not comment.draft:
123 122 <div class="author ${'author-inline' if inline else 'author-general'}">
124 123 ${base.gravatar_with_user(comment.author.email, 16, tooltip=True)}
125 124 </div>
126 125 % endif
127 126
128 127 <div class="date">
129 128 ${h.age_component(comment.modified_at, time_is_local=True)}
130 129 </div>
131 130
132 131 % if comment.pull_request and comment.pull_request.author.user_id == comment.author.user_id:
133 132 <span class="tag authortag tooltip" title="${_('Pull request author')}">
134 133 ${_('author')}
135 134 </span>
136 135 % endif
137 136
138 137 <%
139 138 comment_version_selector = 'comment_versions_{}'.format(comment.comment_id)
140 139 %>
141 140
142 141 % if comment.history:
143 142 <div class="date">
144 143
145 144 <input id="${comment_version_selector}" name="${comment_version_selector}"
146 145 type="hidden"
147 146 data-last-version="${comment.history[-1].version}">
148 147
149 148 <script type="text/javascript">
150 149
151 150 var preLoadVersionData = [
152 151 % for comment_history in comment.history:
153 152 {
154 153 id: ${comment_history.comment_history_id},
155 154 text: 'v${comment_history.version}',
156 155 action: function () {
157 156 Rhodecode.comments.showVersion(
158 157 "${comment.comment_id}",
159 158 "${comment_history.comment_history_id}"
160 159 )
161 160 },
162 161 comment_version: "${comment_history.version}",
163 162 comment_author_username: "${comment_history.author.username}",
164 163 comment_author_gravatar: "${h.gravatar_url(comment_history.author.email, 16)}",
165 164 comment_created_on: '${h.age_component(comment_history.created_on, time_is_local=True)}',
166 165 },
167 166 % endfor
168 167 ]
169 168 initVersionSelector("#${comment_version_selector}", {results: preLoadVersionData});
170 169
171 170 </script>
172 171
173 172 </div>
174 173 % else:
175 174 <div class="date" style="display: none">
176 175 <input id="${comment_version_selector}" name="${comment_version_selector}"
177 176 type="hidden"
178 177 data-last-version="0">
179 178 </div>
180 179 %endif
181 180
182 181 <div class="comment-links-block">
183 182
184 183 % if inline:
185 184 <a class="pr-version-inline" href="${request.current_route_path(_query=dict(version=comment.pull_request_version_id), _anchor='comment-{}'.format(comment.comment_id))}">
186 185 % if outdated_at_ver:
187 186 <strong class="comment-outdated-label">outdated</strong> <code class="tooltip pr-version-num" title="${_('Outdated comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}">${'v{}'.format(comment_ver)}</code>
188 187 <code class="action-divider">|</code>
189 188 % elif comment_ver:
190 189 <code class="tooltip pr-version-num" title="${_('Comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}">${'v{}'.format(comment_ver)}</code>
191 190 <code class="action-divider">|</code>
192 191 % endif
193 192 </a>
194 193 % else:
195 194 % if comment_ver:
196 195
197 196 % if comment.outdated:
198 197 <a class="pr-version"
199 198 href="?version=${comment.pull_request_version_id}#comment-${comment.comment_id}"
200 199 >
201 200 ${_('Outdated comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}
202 201 </a>
203 202 <code class="action-divider">|</code>
204 203 % else:
205 204 <a class="tooltip pr-version"
206 205 title="${_('Comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}"
207 206 href="${h.route_path('pullrequest_show',repo_name=comment.pull_request.target_repo.repo_name,pull_request_id=comment.pull_request.pull_request_id, version=comment.pull_request_version_id)}"
208 207 >
209 208 <code class="pr-version-num">${'v{}'.format(comment_ver)}</code>
210 209 </a>
211 210 <code class="action-divider">|</code>
212 211 % endif
213 212
214 213 % endif
215 214 % endif
216 215
217 216 <details class="details-reset details-inline-block">
218 217 <summary class="noselect"><i class="icon-options cursor-pointer"></i></summary>
219 218 <details-menu class="details-dropdown">
220 219
221 220 <div class="dropdown-item">
222 221 ${_('Comment')} #${comment.comment_id}
223 222 <span class="pull-right icon-clipboard clipboard-action" data-clipboard-text="${comment_model.get_url(comment,request, permalink=True, anchor='comment-{}'.format(comment.comment_id))}" title="${_('Copy permalink')}"></span>
224 223 </div>
225 224
226 225 ## show delete comment if it's not a PR (regular comments) or it's PR that is not closed
227 226 ## only super-admin, repo admin OR comment owner can delete, also hide delete if currently viewed comment is outdated
228 227 %if not outdated_at_ver and (not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed())):
229 228 ## permissions to delete
230 229 %if comment.immutable is False and (c.is_super_admin or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or comment.author.user_id == c.rhodecode_user.user_id):
231 230 <div class="dropdown-divider"></div>
232 231 <div class="dropdown-item">
233 232 <a onclick="return Rhodecode.comments.editComment(this, '${comment.line_no}', '${comment.f_path}');" class="btn btn-link btn-sm edit-comment">${_('Edit')}</a>
234 233 </div>
235 234 <div class="dropdown-item">
236 235 <a onclick="return Rhodecode.comments.deleteComment(this);" class="btn btn-link btn-sm btn-danger delete-comment">${_('Delete')}</a>
237 236 </div>
238 237 ## Only available in EE edition
239 238 % if comment.draft and c.rhodecode_edition_id == 'EE':
240 239 <div class="dropdown-item">
241 240 <a onclick="return Rhodecode.comments.finalizeDrafts([${comment.comment_id}]);" class="btn btn-link btn-sm finalize-draft-comment">${_('Submit draft')}</a>
242 241 </div>
243 242 % endif
244 243 %else:
245 244 <div class="dropdown-divider"></div>
246 245 <div class="dropdown-item">
247 246 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Edit')}</a>
248 247 </div>
249 248 <div class="dropdown-item">
250 249 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Delete')}</a>
251 250 </div>
252 251 %endif
253 252 %else:
254 253 <div class="dropdown-divider"></div>
255 254 <div class="dropdown-item">
256 255 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Edit')}</a>
257 256 </div>
258 257 <div class="dropdown-item">
259 258 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Delete')}</a>
260 259 </div>
261 260 %endif
262 261 </details-menu>
263 262 </details>
264 263
265 264 <code class="action-divider">|</code>
266 265 % if outdated_at_ver:
267 266 <a onclick="return Rhodecode.comments.prevOutdatedComment(this);" class="tooltip prev-comment" title="${_('Jump to the previous outdated comment')}"> <i class="icon-angle-left"></i> </a>
268 267 <a onclick="return Rhodecode.comments.nextOutdatedComment(this);" class="tooltip next-comment" title="${_('Jump to the next outdated comment')}"> <i class="icon-angle-right"></i></a>
269 268 % else:
270 269 <a onclick="return Rhodecode.comments.prevComment(this);" class="tooltip prev-comment" title="${_('Jump to the previous comment')}"> <i class="icon-angle-left"></i></a>
271 270 <a onclick="return Rhodecode.comments.nextComment(this);" class="tooltip next-comment" title="${_('Jump to the next comment')}"> <i class="icon-angle-right"></i></a>
272 271 % endif
273 272
274 273 </div>
275 274 </div>
276 275 <div class="text">
277 276 ${h.render(comment.text, renderer=comment.renderer, mentions=True, repo_name=getattr(c, 'repo_name', None), active_pattern_entries=active_pattern_entries)}
278 277 </div>
279 278
280 279 </div>
281 280 % endif
282 281 </%def>
283 282
284 283 ## generate main comments
285 284 <%def name="generate_comments(comments, include_pull_request=False, is_pull_request=False)">
286 285 <%
287 286 active_pattern_entries = h.get_active_pattern_entries(getattr(c, 'repo_name', None))
288 287 %>
289 288
290 289 <div class="general-comments" id="comments">
291 290 %for comment in comments:
292 291 <div id="comment-tr-${comment.comment_id}">
293 292 ## only render comments that are not from pull request, or from
294 293 ## pull request and a status change
295 294 %if not comment.pull_request or (comment.pull_request and comment.status_change) or include_pull_request:
296 295 ${comment_block(comment, active_pattern_entries=active_pattern_entries)}
297 296 %endif
298 297 </div>
299 298 %endfor
300 299 ## to anchor ajax comments
301 300 <div id="injected_page_comments"></div>
302 301 </div>
303 302 </%def>
304 303
305 304
306 305 <%def name="comments(post_url, cur_status, is_pull_request=False, is_compare=False, change_status=True, form_extras=None)">
307 306
308 307 <div class="comments">
309 308 <%
310 309 if is_pull_request:
311 310 placeholder = _('Leave a comment on this Pull Request.')
312 311 elif is_compare:
313 312 placeholder = _('Leave a comment on {} commits in this range.').format(len(form_extras))
314 313 else:
315 314 placeholder = _('Leave a comment on this Commit.')
316 315 %>
317 316
318 317 % if c.rhodecode_user.username != h.DEFAULT_USER:
319 318 <div class="js-template" id="cb-comment-general-form-template">
320 319 ## template generated for injection
321 320 ${comment_form(form_type='general', review_statuses=c.commit_statuses, form_extras=form_extras)}
322 321 </div>
323 322
324 323 <div id="cb-comment-general-form-placeholder" class="comment-form ac">
325 324 ## inject form here
326 325 </div>
327 326 <script type="text/javascript">
328 327 var resolvesCommentId = null;
329 328 var generalCommentForm = Rhodecode.comments.createGeneralComment(
330 329 'general', "${placeholder}", resolvesCommentId);
331 330
332 331 // set custom success callback on rangeCommit
333 332 % if is_compare:
334 333 generalCommentForm.setHandleFormSubmit(function(o) {
335 334 var self = generalCommentForm;
336 335
337 336 var text = self.cm.getValue();
338 337 var status = self.getCommentStatus();
339 338 var commentType = self.getCommentType();
340 339 var isDraft = self.getDraftState();
341 340
342 341 if (text === "" && !status) {
343 342 return;
344 343 }
345 344
346 345 // we can pick which commits we want to make the comment by
347 346 // selecting them via click on preview pane, this will alter the hidden inputs
348 347 var cherryPicked = $('#changeset_compare_view_content .compare_select.hl').length > 0;
349 348
350 349 var commitIds = [];
351 350 $('#changeset_compare_view_content .compare_select').each(function(el) {
352 351 var commitId = this.id.replace('row-', '');
353 352 if ($(this).hasClass('hl') || !cherryPicked) {
354 353 $("input[data-commit-id='{0}']".format(commitId)).val(commitId);
355 354 commitIds.push(commitId);
356 355 } else {
357 356 $("input[data-commit-id='{0}']".format(commitId)).val('')
358 357 }
359 358 });
360 359
361 360 self.setActionButtonsDisabled(true);
362 361 self.cm.setOption("readOnly", true);
363 362 var postData = {
364 363 'text': text,
365 364 'changeset_status': status,
366 365 'comment_type': commentType,
367 366 'draft': isDraft,
368 367 'commit_ids': commitIds,
369 368 'csrf_token': CSRF_TOKEN
370 369 };
371 370
372 371 var submitSuccessCallback = function(o) {
373 372 location.reload(true);
374 373 };
375 374 var submitFailCallback = function(){
376 375 self.resetCommentFormState(text)
377 376 };
378 377 self.submitAjaxPOST(
379 378 self.submitUrl, postData, submitSuccessCallback, submitFailCallback);
380 379 });
381 380 % endif
382 381
383 382 </script>
384 383 % else:
385 384 ## form state when not logged in
386 385 <div class="comment-form ac">
387 386
388 387 <div class="comment-area">
389 388 <div class="comment-area-header">
390 389 <ul class="nav-links clearfix">
391 390 <li class="active">
392 391 <a class="disabled" href="#edit-btn" disabled="disabled" onclick="return false">${_('Write')}</a>
393 392 </li>
394 393 <li class="">
395 394 <a class="disabled" href="#preview-btn" disabled="disabled" onclick="return false">${_('Preview')}</a>
396 395 </li>
397 396 </ul>
398 397 </div>
399 398
400 399 <div class="comment-area-write" style="display: block;">
401 400 <div id="edit-container">
402 401 <div style="padding: 20px 0px 0px 0;">
403 402 ${_('You need to be logged in to leave comments.')}
404 403 <a href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">${_('Login now')}</a>
405 404 </div>
406 405 </div>
407 406 <div id="preview-container" class="clearfix" style="display: none;">
408 407 <div id="preview-box" class="preview-box"></div>
409 408 </div>
410 409 </div>
411 410
412 411 <div class="comment-area-footer">
413 412 <div class="toolbar">
414 413 <div class="toolbar-text">
415 414 </div>
416 415 </div>
417 416 </div>
418 417 </div>
419 418
420 419 <div class="comment-footer">
421 420 </div>
422 421
423 422 </div>
424 423 % endif
425 424
426 425 <script type="text/javascript">
427 426 bindToggleButtons();
428 427 </script>
429 428 </div>
430 429 </%def>
431 430
432 431
433 432 <%def name="comment_form(form_type, form_id='', lineno_id='{1}', review_statuses=None, form_extras=None)">
434 433
435 434 ## comment injected based on assumption that user is logged in
436 435 <form ${('id="{}"'.format(form_id) if form_id else '') |n} action="#" method="GET">
437 436
438 437 <div class="comment-area">
439 438 <div class="comment-area-header">
440 439 <div class="pull-left">
441 440 <ul class="nav-links clearfix">
442 441 <li class="active">
443 442 <a href="#edit-btn" tabindex="-1" id="edit-btn_${lineno_id}">${_('Write')}</a>
444 443 </li>
445 444 <li class="">
446 445 <a href="#preview-btn" tabindex="-1" id="preview-btn_${lineno_id}">${_('Preview')}</a>
447 446 </li>
448 447 </ul>
449 448 </div>
450 449 <div class="pull-right">
451 450 <span class="comment-area-text">${_('Mark as')}:</span>
452 451 <select class="comment-type" id="comment_type_${lineno_id}" name="comment_type">
453 452 % for val in c.visual.comment_types:
454 453 <option value="${val}">${val.upper()}</option>
455 454 % endfor
456 455 </select>
457 456 </div>
458 457 </div>
459 458
460 459 <div class="comment-area-write" style="display: block;">
461 460 <div id="edit-container_${lineno_id}" style="margin-top: -1px">
462 461 <textarea id="text_${lineno_id}" name="text" class="comment-block-ta ac-input"></textarea>
463 462 </div>
464 463 <div id="preview-container_${lineno_id}" class="clearfix" style="display: none;">
465 464 <div id="preview-box_${lineno_id}" class="preview-box"></div>
466 465 </div>
467 466 </div>
468 467
469 468 <div class="comment-area-footer comment-attachment-uploader">
470 469 <div class="toolbar">
471 470
472 471 <div class="comment-attachment-text">
473 472 <div class="dropzone-text">
474 473 ${_("Drag'n Drop files here or")} <span class="link pick-attachment">${_('Choose your files')}</span>.<br>
475 474 </div>
476 475 <div class="dropzone-upload" style="display:none">
477 476 <i class="icon-spin animate-spin"></i> ${_('uploading...')}
478 477 </div>
479 478 </div>
480 479
481 480 ## comments dropzone template, empty on purpose
482 481 <div style="display: none" class="comment-attachment-uploader-template">
483 482 <div class="dz-file-preview" style="margin: 0">
484 483 <div class="dz-error-message"></div>
485 484 </div>
486 485 </div>
487 486
488 487 </div>
489 488 </div>
490 489 </div>
491 490
492 491 <div class="comment-footer">
493 492
494 493 ## inject extra inputs into the form
495 494 % if form_extras and isinstance(form_extras, (list, tuple)):
496 495 <div id="comment_form_extras">
497 496 % for form_ex_el in form_extras:
498 497 ${form_ex_el|n}
499 498 % endfor
500 499 </div>
501 500 % endif
502 501
503 502 <div class="action-buttons">
504 503 % if form_type != 'inline':
505 504 <div class="action-buttons-extra"></div>
506 505 % endif
507 506
508 507 <input class="btn btn-success comment-button-input submit-comment-action" id="save_${lineno_id}" name="save" type="submit" value="${_('Add comment')}" data-is-draft=false onclick="$(this).addClass('submitter')">
509 508
510 509 % if form_type == 'inline':
511 510 % if c.rhodecode_edition_id == 'EE':
512 511 ## Disable the button for CE, the "real" validation is in the backend code anyway
513 512 <input class="btn btn-draft comment-button-input submit-draft-action" id="save_draft_${lineno_id}" name="save_draft" type="submit" value="${_('Add draft')}" data-is-draft=true onclick="$(this).addClass('submitter')">
514 513 % else:
515 514 <input class="btn btn-draft comment-button-input submit-draft-action disabled" disabled="disabled" type="submit" value="${_('Add draft')}" onclick="return false;" title="Draft comments only available in EE edition of RhodeCode">
516 515 % endif
517 516 % endif
518 517
519 518 % if review_statuses:
520 519 <div class="comment-status-box">
521 520 <select id="change_status_${lineno_id}" name="changeset_status">
522 521 <option></option> ## Placeholder
523 522 % for status, lbl in review_statuses:
524 523 <option value="${status}" data-status="${status}">${lbl}</option>
525 524 %if is_pull_request and change_status and status in ('approved', 'rejected'):
526 525 <option value="${status}_closed" data-status="${status}">${lbl} & ${_('Closed')}</option>
527 526 %endif
528 527 % endfor
529 528 </select>
530 529 </div>
531 530 % endif
532 531
533 532 ## inline for has a file, and line-number together with cancel hide button.
534 533 % if form_type == 'inline':
535 534 <input type="hidden" name="f_path" value="{0}">
536 535 <input type="hidden" name="line" value="${lineno_id}">
537 536 <span style="opacity: 0.7" class="cursor-pointer cb-comment-cancel" onclick="return Rhodecode.comments.cancelComment(this);">
538 537 ${_('dismiss')}
539 538 </span>
540 539 % endif
541 540 </div>
542 541
543 542 <div class="toolbar-text">
544 543 <% renderer_url = '<a href="%s">%s</a>' % (h.route_url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper()) %>
545 544 <span>${_('{} is supported.').format(renderer_url)|n}
546 545
547 546 <i class="icon-info-circled tooltip-hovercard"
548 547 data-hovercard-alt="ALT"
549 548 data-hovercard-url="javascript:commentHelp('${c.visual.default_renderer.upper()}')"
550 549 data-comment-json-b64='${h.b64(h.str_json({}))}'></i>
551 550 </span>
552 551 </div>
553 552 </div>
554 553
555 554 </form>
556 555
557 556 </%def> No newline at end of file
@@ -1,123 +1,122 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('%s Commits') % c.repo_name} -
6 5 r${c.commit_ranges[0].idx}:${h.short_id(c.commit_ranges[0].raw_id)}
7 6 ...
8 7 r${c.commit_ranges[-1].idx}:${h.short_id(c.commit_ranges[-1].raw_id)}
9 8 ${_ungettext('(%s commit)','(%s commits)', len(c.commit_ranges)) % len(c.commit_ranges)}
10 9 %if c.rhodecode_name:
11 10 &middot; ${h.branding(c.rhodecode_name)}
12 11 %endif
13 12 </%def>
14 13
15 14 <%def name="breadcrumbs_links()"></%def>
16 15
17 16 <%def name="menu_bar_nav()">
18 17 ${self.menu_items(active='repositories')}
19 18 </%def>
20 19
21 20 <%def name="menu_bar_subnav()">
22 21 ${self.repo_menu(active='commits')}
23 22 </%def>
24 23
25 24 <%def name="main()">
26 25
27 26 <div class="box">
28 27 <div class="summary changeset">
29 28 <div class="summary-detail">
30 29 <div class="summary-detail-header">
31 30 <span class="breadcrumbs files_location">
32 31 <h4>
33 32 ${_('Commit Range')}
34 33 </h4>
35 34 </span>
36 35
37 36 <div class="clear-fix"></div>
38 37 </div>
39 38
40 39 <div class="fieldset">
41 40 <div class="left-label-summary">
42 41 <p class="spacing">${_('Range')}:</p>
43 42 <div class="right-label-summary">
44 43 <div class="code-header" >
45 44 <div class="compare_header">
46 45 <code class="fieldset-text-line">
47 46 r${c.commit_ranges[0].idx}:${h.short_id(c.commit_ranges[0].raw_id)}
48 47 ...
49 48 r${c.commit_ranges[-1].idx}:${h.short_id(c.commit_ranges[-1].raw_id)}
50 49 ${_ungettext('(%s commit)','(%s commits)', len(c.commit_ranges)) % len(c.commit_ranges)}
51 50 </code>
52 51 </div>
53 52 </div>
54 53 </div>
55 54 </div>
56 55 </div>
57 56
58 57 <div class="fieldset">
59 58 <div class="left-label-summary">
60 59 <p class="spacing">${_('Diff Option')}:</p>
61 60 <div class="right-label-summary">
62 61 <div class="code-header" >
63 62 <div class="compare_header">
64 63 <a class="btn btn-primary" href="${h.route_path('repo_compare',
65 64 repo_name=c.repo_name,
66 65 source_ref_type='rev',
67 66 source_ref=getattr(c.commit_ranges[0].parents[0] if c.commit_ranges[0].parents else h.EmptyCommit(), 'raw_id'),
68 67 target_ref_type='rev',
69 68 target_ref=c.commit_ranges[-1].raw_id)}"
70 69 >
71 70 ${_('Show combined diff')}
72 71 </a>
73 72 </div>
74 73 </div>
75 74 </div>
76 75 </div>
77 76 </div>
78 77
79 78 <div class="clear-fix"></div>
80 79 </div> <!-- end summary-detail -->
81 80 </div> <!-- end summary -->
82 81
83 82 <div id="changeset_compare_view_content">
84 83 <div class="pull-left">
85 84 <div class="btn-group">
86 85 <a class="${('collapsed' if c.collapse_all_commits else '')}" href="#expand-commits" onclick="toggleCommitExpand(this); return false" data-toggle-commits-cnt=${len(c.commit_ranges)} >
87 86 % if c.collapse_all_commits:
88 87 <i class="icon-plus-squared-alt icon-no-margin"></i>
89 88 ${_ungettext('Expand {} commit', 'Expand {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))}
90 89 % else:
91 90 <i class="icon-minus-squared-alt icon-no-margin"></i>
92 91 ${_ungettext('Collapse {} commit', 'Collapse {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))}
93 92 % endif
94 93 </a>
95 94 </div>
96 95 </div>
97 96 ## Commit range generated below
98 97 <%include file="../compare/compare_commits.mako"/>
99 98 <div class="cs_files">
100 99 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
101 100 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
102 101 <%namespace name="diff_block" file="/changeset/diff_block.mako"/>
103 102
104 103 %for commit in c.commit_ranges:
105 104 ## commit range header for each individual diff
106 105 <h3>
107 106 <a class="tooltip-hovercard revision" data-hovercard-alt="Commit: ${commit.short_id}" data-hovercard-url="${h.route_path('hovercard_repo_commit', repo_name=c.repo_name, commit_id=commit.raw_id)}" href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=commit.raw_id)}">
108 107 ${('r%s:%s' % (commit.idx,h.short_id(commit.raw_id)))}
109 108 </a>
110 109 </h3>
111 110
112 111 ${cbdiffs.render_diffset_menu(c.changes[commit.raw_id])}
113 112 ${cbdiffs.render_diffset(
114 113 diffset=c.changes[commit.raw_id],
115 114 collapse_when_files_over=5,
116 115 commit=commit,
117 116 )}
118 117 %endfor
119 118 </div>
120 119 </div>
121 120 </div>
122 121
123 122 </%def>
@@ -1,353 +1,352 b''
1 ## -*- coding: utf-8 -*-
2 1
3 2 <%inherit file="/base/base.mako"/>
4 3
5 4 <%def name="title()">
6 5 ${_('%s Changelog') % c.repo_name}
7 6 %if c.changelog_for_path:
8 7 /${c.changelog_for_path}
9 8 %endif
10 9 %if c.rhodecode_name:
11 10 &middot; ${h.branding(c.rhodecode_name)}
12 11 %endif
13 12 </%def>
14 13
15 14 <%def name="breadcrumbs_links()">
16 15 %if c.changelog_for_path:
17 16 /${c.changelog_for_path}
18 17 %endif
19 18 </%def>
20 19
21 20 <%def name="menu_bar_nav()">
22 21 ${self.menu_items(active='repositories')}
23 22 </%def>
24 23
25 24 <%def name="menu_bar_subnav()">
26 25 ${self.repo_menu(active='commits')}
27 26 </%def>
28 27
29 28 <%def name="main()">
30 29
31 30 <div class="box">
32 31
33 32 <div class="title">
34 33 <div id="filter_changelog">
35 34 ${h.hidden('branch_filter')}
36 35 %if c.selected_name:
37 36 <div class="btn btn-default" id="clear_filter" >
38 37 ${_('Clear filter')}
39 38 </div>
40 39 %endif
41 40 </div>
42 41 <div class="pull-left obsolete-toggle">
43 42 % if h.is_hg(c.rhodecode_repo):
44 43 % if c.show_hidden:
45 44 <a class="action-link" href="${h.current_route_path(request, evolve=0)}">${_('Hide obsolete/hidden')}</a>
46 45 % else:
47 46 <a class="action-link" href="${h.current_route_path(request, evolve=1)}">${_('Show obsolete/hidden')}</a>
48 47 % endif
49 48 % else:
50 49 <span class="action-link disabled">${_('Show hidden')}</span>
51 50 % endif
52 51 </div>
53 52 <ul class="links">
54 53 <li>
55 54
56 55 %if c.rhodecode_db_repo.fork:
57 56 <span>
58 57 <a id="compare_fork_button"
59 58 title="${h.tooltip(_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name))}"
60 59 class="btn btn-small"
61 60 href="${h.route_path('repo_compare',
62 61 repo_name=c.rhodecode_db_repo.fork.repo_name,
63 62 source_ref_type=c.rhodecode_db_repo.landing_ref_type,
64 63 source_ref=c.rhodecode_db_repo.landing_ref_name,
65 64 target_ref_type='branch' if request.GET.get('branch') else c.rhodecode_db_repo.landing_ref_type,
66 65 target_ref=request.GET.get('branch') or c.rhodecode_db_repo.landing_ref_name,
67 66 _query=dict(merge=1, target_repo=c.repo_name))}"
68 67 >
69 68 ${_('Compare fork with Parent (%s)' % c.rhodecode_db_repo.fork.repo_name)}
70 69 </a>
71 70 </span>
72 71 %endif
73 72
74 73 ## pr open link
75 74 %if h.is_hg(c.rhodecode_repo) or h.is_git(c.rhodecode_repo):
76 75 <span>
77 76 <a id="open_new_pull_request" class="btn btn-small btn-success" href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">
78 77 ${_('Open new pull request')}
79 78 </a>
80 79 </span>
81 80 %endif
82 81
83 82 </li>
84 83 </ul>
85 84 </div>
86 85
87 86 % if c.pagination:
88 87 <script type="text/javascript" src="${h.asset('js/src/plugins/jquery.commits-graph.js')}"></script>
89 88
90 89 <div class="graph-header">
91 90 ${self.breadcrumbs('breadcrumbs_light')}
92 91 </div>
93 92
94 93 <div id="graph">
95 94 <div class="graph-col-wrapper">
96 95 <div id="graph_nodes">
97 96 <div id="graph_canvas"></div>
98 97 </div>
99 98 <div id="graph_content" class="graph_full_width">
100 99
101 100 <div class="table">
102 101 <table id="changesets" class="rctable table-bordered">
103 102 <tr>
104 103 ## checkbox
105 104 <th colspan="4">
106 105 ## clear selection
107 106 <div title="${_('Clear selection')}" class="btn btn-sm" id="rev_range_clear" style="display:none">
108 107 <i class="icon-cancel-circled2"></i>
109 108 </div>
110 109 <div class="btn btn-sm disabled" disabled="disabled" id="rev_range_more" style="display:none;">${_('Select second commit')}</div>
111 110
112 111 <div id="rev_range_action" class="btn-group btn-group-actions" style="display:none;">
113 112 <a href="#" class="btn btn-success btn-sm" id="rev_range_container" style="display:none;"></a>
114 113
115 114 <a class="btn btn-success btn-sm btn-more-option" data-toggle="dropdown" aria-pressed="false" role="button">
116 115 <i class="icon-down"></i>
117 116 </a>
118 117
119 118 <div class="btn-action-switcher-container right-align">
120 119 <ul class="btn-action-switcher" role="menu" style="min-width: 220px; width: max-content">
121 120 <li>
122 121 ## JS fills the URL
123 122 <a id="rev_range_combined_url" class="btn btn-primary btn-sm" href="">
124 123 ${_('Show combined diff')}
125 124 </a>
126 125 </li>
127 126 </ul>
128 127 </div>
129 128 </div>
130 129
131 130 </th>
132 131
133 132 ## commit message expand arrow
134 133 <th></th>
135 134 <th>${_('Commit Message')}</th>
136 135
137 136 <th>${_('Age')}</th>
138 137 <th>${_('Author')}</th>
139 138
140 139 <th>${_('Refs')}</th>
141 140 ## comments
142 141 <th></th>
143 142 </tr>
144 143
145 144 <tbody class="commits-range">
146 145 <%include file='changelog_elements.mako'/>
147 146 </tbody>
148 147 </table>
149 148 </div>
150 149 </div>
151 150 <div class="pagination-wh pagination-left">
152 151 ${c.pagination.render()}
153 152 </div>
154 153 <div id="commit-counter" data-total=${c.total_cs} class="pull-right">
155 154 ${_ungettext('showing %d out of %d commit', 'showing %d out of %d commits', c.showing_commits) % (c.showing_commits, c.total_cs)}
156 155 </div>
157 156 </div>
158 157
159 158 <script type="text/javascript">
160 159 var cache = {};
161 160 $(function(){
162 161
163 162 // Create links to commit ranges when range checkboxes are selected
164 163 var $commitCheckboxes = $('.commit-range');
165 164 // cache elements
166 165 var $commitRangeMore = $('#rev_range_more');
167 166 var $commitRangeContainer = $('#rev_range_container');
168 167 var $commitRangeClear = $('#rev_range_clear');
169 168 var $commitRangeAction = $('#rev_range_action');
170 169 var $commitRangeCombinedUrl = $('#rev_range_combined_url');
171 170 var $compareFork = $('#compare_fork_button');
172 171
173 172 var checkboxRangeSelector = function(e){
174 173 var selectedCheckboxes = [];
175 174 for (pos in $commitCheckboxes){
176 175 if($commitCheckboxes[pos].checked){
177 176 selectedCheckboxes.push($commitCheckboxes[pos]);
178 177 }
179 178 }
180 179 var open_new_pull_request = $('#open_new_pull_request');
181 180
182 181 if (open_new_pull_request) {
183 182 var selected_changes = selectedCheckboxes.length;
184 183 open_new_pull_request.hide();
185 184 if (selected_changes == 1) {
186 185 open_new_pull_request.html(_gettext('Open new pull request for selected commit'));
187 186 } else {
188 187 open_new_pull_request.html(_gettext('Open new pull request'));
189 188 }
190 189 open_new_pull_request.show();
191 190 }
192 191
193 192 if (selectedCheckboxes.length > 0) {
194 193 $compareFork.hide();
195 194 var commitStart = $(selectedCheckboxes[selectedCheckboxes.length-1]).data();
196 195 var revStart = commitStart.commitId;
197 196
198 197 var commitEnd = $(selectedCheckboxes[0]).data();
199 198 var revEnd = commitEnd.commitId;
200 199
201 200 var lbl_start = '{0}'.format(commitStart.commitIdx, commitStart.shortId);
202 201 var lbl_end = '{0}'.format(commitEnd.commitIdx, commitEnd.shortId);
203 202
204 203 var url = pyroutes.url('repo_commit', {'repo_name': '${c.repo_name}', 'commit_id': revStart+'...'+revEnd});
205 204 var urlCombined = pyroutes.url('repo_commit', {'repo_name': '${c.repo_name}', 'commit_id': revStart+'...'+revEnd, 'redirect_combined': '1'});
206 205
207 206 var link = _gettext('Show commit range {0}<i class="icon-angle-right"></i>{1}').format(lbl_start, lbl_end);
208 207
209 208 if (selectedCheckboxes.length > 1) {
210 209 $commitRangeClear.show();
211 210 $commitRangeMore.hide();
212 211
213 212 $commitRangeContainer
214 213 .attr('href',url)
215 214 .html(link)
216 215 .show();
217 216
218 217 $commitRangeCombinedUrl.attr('href', urlCombined);
219 218 $commitRangeAction.show();
220 219
221 220 } else {
222 221 $commitRangeContainer.hide();
223 222 $commitRangeAction.hide();
224 223 $commitRangeClear.show();
225 224 $commitRangeMore.show();
226 225 }
227 226
228 227 // pull-request link
229 228 if (selectedCheckboxes.length == 1){
230 229 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}', 'commit': revEnd});
231 230 open_new_pull_request.attr('href', _url);
232 231 } else {
233 232 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}'});
234 233 open_new_pull_request.attr('href', _url);
235 234 }
236 235
237 236 } else {
238 237 $commitRangeContainer.hide();
239 238 $commitRangeClear.hide();
240 239 $commitRangeMore.hide();
241 240 $commitRangeAction.hide();
242 241
243 242 %if c.branch_name:
244 243 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}', 'branch':'${c.branch_name}'});
245 244 open_new_pull_request.attr('href', _url);
246 245 %else:
247 246 var _url = pyroutes.url('pullrequest_new', {'repo_name': '${c.repo_name}'});
248 247 open_new_pull_request.attr('href', _url);
249 248 %endif
250 249 $compareFork.show();
251 250 }
252 251 };
253 252
254 253 $commitCheckboxes.on('click', checkboxRangeSelector);
255 254
256 255 $commitRangeClear.on('click',function(e) {
257 256 $commitCheckboxes.attr('checked', false);
258 257 checkboxRangeSelector();
259 258 e.preventDefault();
260 259 });
261 260
262 261 // make sure the buttons are consistent when navigate back and forth
263 262 checkboxRangeSelector();
264 263
265 264 var msgs = $('.message');
266 265 // get first element height
267 266 var el = $('#graph_content .container')[0];
268 267 var row_h = el.clientHeight;
269 268 for (var i=0; i < msgs.length; i++) {
270 269 var m = msgs[i];
271 270
272 271 var h = m.clientHeight;
273 272 var pad = $(m).css('padding');
274 273 if (h > row_h) {
275 274 var offset = row_h - (h+12);
276 275 $(m.nextElementSibling).css('display','block');
277 276 $(m.nextElementSibling).css('margin-top',offset+'px');
278 277 }
279 278 }
280 279
281 280 $("#clear_filter").on("click", function() {
282 281 var filter = {'repo_name': '${c.repo_name}'};
283 282 window.location = pyroutes.url('repo_commits', filter);
284 283 });
285 284
286 285 $("#branch_filter").select2({
287 286 'dropdownAutoWidth': true,
288 287 'width': 'resolve',
289 288 'placeholder': "${c.selected_name or _('Branch filter')}",
290 289 containerCssClass: "drop-menu",
291 290 dropdownCssClass: "drop-menu-dropdown",
292 291 query: function(query){
293 292 var key = 'cache';
294 293 var cached = cache[key] ;
295 294 if(cached) {
296 295 var data = {results: []};
297 296 //filter results
298 297 $.each(cached.results, function(){
299 298 var section = this.text;
300 299 var children = [];
301 300 $.each(this.children, function(){
302 301 if(query.term.length == 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
303 302 children.push({'id': this.id, 'text': this.text, 'type': this.type})
304 303 }
305 304 });
306 305 data.results.push({'text': section, 'children': children});
307 306 query.callback({results: data.results});
308 307 });
309 308 }else{
310 309 $.ajax({
311 310 url: pyroutes.url('repo_refs_changelog_data', {'repo_name': '${c.repo_name}'}),
312 311 data: {},
313 312 dataType: 'json',
314 313 type: 'GET',
315 314 success: function(data) {
316 315 cache[key] = data;
317 316 query.callback({results: data.results});
318 317 }
319 318 })
320 319 }
321 320 }
322 321 });
323 322 $('#branch_filter').on('change', function(e){
324 323 var data = $('#branch_filter').select2('data');
325 324 //type: branch_closed
326 325 var selected = data.text;
327 326 var filter = {'repo_name': '${c.repo_name}'};
328 327 if(data.type == 'branch' || data.type == 'branch_closed'){
329 328 filter["branch"] = selected;
330 329 if (data.type == 'branch_closed') {
331 330 filter["evolve"] = '1';
332 331 }
333 332 }
334 333 else if (data.type == 'book'){
335 334 filter["bookmark"] = selected;
336 335 }
337 336 window.location = pyroutes.url('repo_commits', filter);
338 337 });
339 338
340 339 commitsController = new CommitsController();
341 340 % if not c.changelog_for_path:
342 341 commitsController.reloadGraph();
343 342 % endif
344 343
345 344 });
346 345
347 346 </script>
348 347 </div>
349 348 % else:
350 349 ${_('There are no changes yet')}
351 350 % endif
352 351 </div>
353 352 </%def>
@@ -1,308 +1,307 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
4 3
5 4 <%def name="title()">
6 5 %if c.compare_home:
7 6 ${_('%s Compare') % c.repo_name}
8 7 %else:
9 8 ${_('%s Compare') % c.repo_name} - ${'%s@%s' % (c.source_repo.repo_name, c.source_ref)} &gt; ${'%s@%s' % (c.target_repo.repo_name, c.target_ref)}
10 9 %endif
11 10 %if c.rhodecode_name:
12 11 &middot; ${h.branding(c.rhodecode_name)}
13 12 %endif
14 13 </%def>
15 14
16 15 <%def name="breadcrumbs_links()"></%def>
17 16
18 17 <%def name="menu_bar_nav()">
19 18 ${self.menu_items(active='repositories')}
20 19 </%def>
21 20
22 21 <%def name="menu_bar_subnav()">
23 22 ${self.repo_menu(active='compare')}
24 23 </%def>
25 24
26 25 <%def name="main()">
27 26 <script type="text/javascript">
28 27 // set fake commitId on this commit-range page
29 28 templateContext.commit_data.commit_id = "${h.EmptyCommit().raw_id}";
30 29 </script>
31 30
32 31 <div class="box">
33 32 <div class="summary changeset">
34 33 <div class="summary-detail">
35 34 <div class="summary-detail-header">
36 35 <span class="breadcrumbs files_location">
37 36 <h4>
38 37 ${_('Compare Commits')}
39 38 % if c.file_path:
40 39 ${_('for file')} <a href="#${('a_' + h.FID('',c.file_path))}">${c.file_path}</a>
41 40 % endif
42 41
43 42 % if c.commit_ranges:
44 43 <code>
45 44 r${c.commit_ranges[0].idx}:${h.short_id(c.commit_ranges[0].raw_id)}...r${c.commit_ranges[-1].idx}:${h.short_id(c.commit_ranges[-1].raw_id)}
46 45 </code>
47 46 % endif
48 47 </h4>
49 48 </span>
50 49
51 50 <div class="clear-fix"></div>
52 51 </div>
53 52
54 53 <div class="fieldset">
55 54 <div class="left-label-summary">
56 55 <p class="spacing">${_('Target')}:</p>
57 56 <div class="right-label-summary">
58 57 <div class="code-header" >
59 58 <div class="compare_header">
60 59 ## The hidden elements are replaced with a select2 widget
61 60 ${h.hidden('compare_source')}
62 61 </div>
63 62 </div>
64 63 </div>
65 64 </div>
66 65 </div>
67 66
68 67 <div class="fieldset">
69 68 <div class="left-label-summary">
70 69 <p class="spacing">${_('Source')}:</p>
71 70 <div class="right-label-summary">
72 71 <div class="code-header" >
73 72 <div class="compare_header">
74 73 ## The hidden elements are replaced with a select2 widget
75 74 ${h.hidden('compare_target')}
76 75 </div>
77 76 </div>
78 77 </div>
79 78 </div>
80 79 </div>
81 80
82 81 <div class="fieldset">
83 82 <div class="left-label-summary">
84 83 <p class="spacing">${_('Actions')}:</p>
85 84 <div class="right-label-summary">
86 85 <div class="code-header" >
87 86 <div class="compare_header">
88 87 <div class="compare-buttons">
89 88 % if c.compare_home:
90 89 <a id="compare_revs" class="btn btn-primary"> ${_('Compare Commits')}</a>
91 90 %if c.rhodecode_db_repo.fork:
92 91
93 92 <a class="btn btn-default" title="${h.tooltip(_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name))}"
94 93 href="${h.route_path('repo_compare',
95 94 repo_name=c.rhodecode_db_repo.fork.repo_name,
96 95 source_ref_type=c.rhodecode_db_repo.landing_ref_type,
97 96 source_ref=c.rhodecode_db_repo.landing_ref_name,
98 97 target_repo=c.repo_name,target_ref_type='branch' if request.GET.get('branch') else c.rhodecode_db_repo.landing_ref_type,
99 98 target_ref=request.GET.get('branch') or c.rhodecode_db_repo.landing_ref_name,
100 99 _query=dict(merge=1))}"
101 100 >
102 101 ${_('Compare with origin')}
103 102 </a>
104 103
105 104 %endif
106 105
107 106 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Swap')}</a>
108 107 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Comment')}</a>
109 108 <div id="changeset_compare_view_content">
110 109 <div class="help-block">${_('Compare commits, branches, bookmarks or tags.')}</div>
111 110 </div>
112 111
113 112 % elif c.preview_mode:
114 113 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Compare Commits')}</a>
115 114 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Swap')}</a>
116 115 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Comment')}</a>
117 116
118 117 % else:
119 118 <a id="compare_revs" class="btn btn-primary"> ${_('Compare Commits')}</a>
120 119 <a id="btn-swap" class="btn btn-primary" href="${c.swap_url}">${_('Swap')}</a>
121 120
122 121 ## allow comment only if there are commits to comment on
123 122 % if c.diffset and c.diffset.files and c.commit_ranges:
124 123 <a id="compare_changeset_status_toggle" class="btn btn-primary">${_('Comment')}</a>
125 124 % else:
126 125 <a class="btn disabled tooltip" disabled="disabled" title="${_('Action unavailable in current view')}">${_('Comment')}</a>
127 126 % endif
128 127 % endif
129 128 </div>
130 129 </div>
131 130 </div>
132 131 </div>
133 132 </div>
134 133 </div>
135 134
136 135 ## commit status form
137 136 <div class="fieldset" id="compare_changeset_status" style="display: none; margin-bottom: -80px;">
138 137 <div class="left-label-summary">
139 138 <p class="spacing">${_('Commit status')}:</p>
140 139 <div class="right-label-summary">
141 140 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
142 141 ## main comment form and it status
143 142 <%
144 143 def revs(_revs):
145 144 form_inputs = []
146 145 for cs in _revs:
147 146 tmpl = '<input type="hidden" data-commit-id="%(cid)s" name="commit_ids" value="%(cid)s">' % {'cid': cs.raw_id}
148 147 form_inputs.append(tmpl)
149 148 return form_inputs
150 149 %>
151 150 <div>
152 151 ${comment.comments(h.route_path('repo_commit_comment_create', repo_name=c.repo_name, commit_id='0'*16), None, is_compare=True, form_extras=revs(c.commit_ranges))}
153 152 </div>
154 153 </div>
155 154 </div>
156 155 </div>
157 156 <div class="clear-fix"></div>
158 157 </div> <!-- end summary-detail -->
159 158 </div> <!-- end summary -->
160 159
161 160 ## use JS script to load it quickly before potentially large diffs render long time
162 161 ## this prevents from situation when large diffs block rendering of select2 fields
163 162 <script type="text/javascript">
164 163
165 164 var cache = {};
166 165
167 166 var formatSelection = function(repoName){
168 167 return function(data, container, escapeMarkup) {
169 168 var selection = data ? this.text(data) : "";
170 169 return escapeMarkup('{0}@{1}'.format(repoName, selection));
171 170 }
172 171 };
173 172
174 173 var feedCompareData = function(query, cachedValue){
175 174 var data = {results: []};
176 175 //filter results
177 176 $.each(cachedValue.results, function() {
178 177 var section = this.text;
179 178 var children = [];
180 179 $.each(this.children, function() {
181 180 if (query.term.length === 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
182 181 children.push({
183 182 'id': this.id,
184 183 'text': this.text,
185 184 'type': this.type
186 185 })
187 186 }
188 187 });
189 188 data.results.push({
190 189 'text': section,
191 190 'children': children
192 191 })
193 192 });
194 193 //push the typed in changeset
195 194 data.results.push({
196 195 'text': _gettext('specify commit'),
197 196 'children': [{
198 197 'id': query.term,
199 198 'text': query.term,
200 199 'type': 'rev'
201 200 }]
202 201 });
203 202 query.callback(data);
204 203 };
205 204
206 205 var loadCompareData = function(repoName, query, cache){
207 206 $.ajax({
208 207 url: pyroutes.url('repo_refs_data', {'repo_name': repoName}),
209 208 data: {},
210 209 dataType: 'json',
211 210 type: 'GET',
212 211 success: function(data) {
213 212 cache[repoName] = data;
214 213 query.callback({results: data.results});
215 214 }
216 215 })
217 216 };
218 217
219 218 var enable_fields = ${"false" if c.preview_mode else "true"};
220 219 $("#compare_source").select2({
221 220 placeholder: "${'%s@%s' % (c.source_repo.repo_name, c.source_ref)}",
222 221 containerCssClass: "drop-menu",
223 222 dropdownCssClass: "drop-menu-dropdown",
224 223 formatSelection: formatSelection("${c.source_repo.repo_name}"),
225 224 dropdownAutoWidth: true,
226 225 query: function(query) {
227 226 var repoName = '${c.source_repo.repo_name}';
228 227 var cachedValue = cache[repoName];
229 228
230 229 if (cachedValue){
231 230 feedCompareData(query, cachedValue);
232 231 }
233 232 else {
234 233 loadCompareData(repoName, query, cache);
235 234 }
236 235 }
237 236 }).select2("enable", enable_fields);
238 237
239 238 $("#compare_target").select2({
240 239 placeholder: "${'%s@%s' % (c.target_repo.repo_name, c.target_ref)}",
241 240 dropdownAutoWidth: true,
242 241 containerCssClass: "drop-menu",
243 242 dropdownCssClass: "drop-menu-dropdown",
244 243 formatSelection: formatSelection("${c.target_repo.repo_name}"),
245 244 query: function(query) {
246 245 var repoName = '${c.target_repo.repo_name}';
247 246 var cachedValue = cache[repoName];
248 247
249 248 if (cachedValue){
250 249 feedCompareData(query, cachedValue);
251 250 }
252 251 else {
253 252 loadCompareData(repoName, query, cache);
254 253 }
255 254 }
256 255 }).select2("enable", enable_fields);
257 256 var initial_compare_source = {id: "${c.source_ref}", type:"${c.source_ref_type}"};
258 257 var initial_compare_target = {id: "${c.target_ref}", type:"${c.target_ref_type}"};
259 258
260 259 $('#compare_revs').on('click', function(e) {
261 260 var source = $('#compare_source').select2('data') || initial_compare_source;
262 261 var target = $('#compare_target').select2('data') || initial_compare_target;
263 262 if (source && target) {
264 263 var url_data = {
265 264 repo_name: "${c.repo_name}",
266 265 source_ref: source.id,
267 266 source_ref_type: source.type,
268 267 target_ref: target.id,
269 268 target_ref_type: target.type
270 269 };
271 270 window.location = pyroutes.url('repo_compare', url_data);
272 271 }
273 272 });
274 273 $('#compare_changeset_status_toggle').on('click', function(e) {
275 274 $('#compare_changeset_status').toggle();
276 275 });
277 276
278 277 </script>
279 278
280 279 ## table diff data
281 280 <div class="table">
282 281 % if not c.compare_home:
283 282 <div id="changeset_compare_view_content">
284 283 <div class="pull-left">
285 284 <div class="btn-group">
286 285 <a class="${('collapsed' if c.collapse_all_commits else '')}" href="#expand-commits" onclick="toggleCommitExpand(this); return false" data-toggle-commits-cnt=${len(c.commit_ranges)} >
287 286 % if c.collapse_all_commits:
288 287 <i class="icon-plus-squared-alt icon-no-margin"></i>
289 288 ${_ungettext('Expand {} commit', 'Expand {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))}
290 289 % else:
291 290 <i class="icon-minus-squared-alt icon-no-margin"></i>
292 291 ${_ungettext('Collapse {} commit', 'Collapse {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))}
293 292 % endif
294 293 </a>
295 294 </div>
296 295 </div>
297 296 <div style="padding:0 10px 10px 0px" class="pull-left"></div>
298 297 ## commit compare generated below
299 298 <%include file="compare_commits.mako"/>
300 299 ${cbdiffs.render_diffset_menu(c.diffset)}
301 300 ${cbdiffs.render_diffset(c.diffset)}
302 301 </div>
303 302 % endif
304 303
305 304 </div>
306 305 </div>
307 306
308 307 </%def>
@@ -1,645 +1,644 b''
1 ## -*- coding: utf-8 -*-
2 1
3 2 ## helpers
4 3 <%def name="tag_button(text, tag_type=None)">
5 4 <%
6 5 color_scheme = {
7 6 'default': 'border:1px solid #979797;color:#666666;background-color:#f9f9f9',
8 7 'approved': 'border:1px solid #0ac878;color:#0ac878;background-color:#f9f9f9',
9 8 'rejected': 'border:1px solid #e85e4d;color:#e85e4d;background-color:#f9f9f9',
10 9 'under_review': 'border:1px solid #ffc854;color:#ffc854;background-color:#f9f9f9',
11 10 }
12 11
13 12 css_style = ';'.join([
14 13 'display:inline',
15 14 'border-radius:2px',
16 15 'font-size:12px',
17 16 'padding:.2em',
18 17 ])
19 18
20 19 %>
21 20 <pre style="${css_style}; ${color_scheme.get(tag_type, color_scheme['default'])}">${text}</pre>
22 21 </%def>
23 22
24 23 <%def name="status_text(text, tag_type=None)">
25 24 <%
26 25 color_scheme = {
27 26 'default': 'color:#666666',
28 27 'approved': 'color:#0ac878',
29 28 'rejected': 'color:#e85e4d',
30 29 'under_review': 'color:#ffc854',
31 30 }
32 31 %>
33 32 <span style="font-weight:bold;font-size:12px;padding:.2em;${color_scheme.get(tag_type, color_scheme['default'])}">${text}</span>
34 33 </%def>
35 34
36 35 <%def name="gravatar_img(email, size=16)">
37 36 <%
38 37 css_style = ';'.join([
39 38 'padding: 0',
40 39 'margin: -4px 0',
41 40 'border-radius: 50%',
42 41 'box-sizing: content-box',
43 42 'display: inline',
44 43 'line-height: 1em',
45 44 'min-width: 16px',
46 45 'min-height: 16px',
47 46 ])
48 47 %>
49 48
50 49 <img alt="gravatar" style="${css_style}" src="${h.gravatar_url(email, size)}" height="${size}" width="${size}">
51 50 </%def>
52 51
53 52 <%def name="link_css()">\
54 53 <%
55 54 css_style = ';'.join([
56 55 'color:#427cc9',
57 56 'text-decoration:none',
58 57 'cursor:pointer'
59 58 ])
60 59 %>\
61 60 ${css_style}\
62 61 </%def>
63 62
64 63 ## Constants
65 64 <%
66 65 text_regular = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, sans-serif"
67 66 text_monospace = "'Menlo', 'Liberation Mono', 'Consolas', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace"
68 67
69 68 %>
70 69
71 70 <%def name="plaintext_footer()" filter="trim">
72 71 ${_('This is a notification from RhodeCode.')} ${instance_url}
73 72 </%def>
74 73
75 74 <%def name="body_plaintext()" filter="n,trim">
76 75 ## this example is not called itself but overridden in each template
77 76 ## the plaintext_footer should be at the bottom of both html and text emails
78 77 ${self.plaintext_footer()}
79 78 </%def>
80 79
81 80 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
82 81 <html xmlns="http://www.w3.org/1999/xhtml">
83 82 <head>
84 83 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
85 84 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
86 85 <title>${self.subject()}</title>
87 86 <style type="text/css">
88 87 /* Based on The MailChimp Reset INLINE: Yes. */
89 88 #outlook a {
90 89 padding: 0;
91 90 }
92 91
93 92 /* Force Outlook to provide a "view in browser" menu link. */
94 93 body {
95 94 width: 100% !important;
96 95 -webkit-text-size-adjust: 100%;
97 96 -ms-text-size-adjust: 100%;
98 97 margin: 0;
99 98 padding: 0;
100 99 font-family: ${text_regular|n};
101 100 color: #000000;
102 101 }
103 102
104 103 /* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
105 104 .ExternalClass {
106 105 width: 100%;
107 106 }
108 107
109 108 /* Force Hotmail to display emails at full width */
110 109 .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {
111 110 line-height: 100%;
112 111 }
113 112
114 113 /* Forces Hotmail to display normal line spacing. More on that: http://www.emailonacid.com/forum/viewthread/43/ */
115 114 #backgroundTable {
116 115 margin: 0;
117 116 padding: 0;
118 117 line-height: 100% !important;
119 118 }
120 119
121 120 /* End reset */
122 121
123 122 /* defaults for images*/
124 123 img {
125 124 outline: none;
126 125 text-decoration: none;
127 126 -ms-interpolation-mode: bicubic;
128 127 }
129 128
130 129 a img {
131 130 border: none;
132 131 }
133 132
134 133 .image_fix {
135 134 display: block;
136 135 }
137 136
138 137 body {
139 138 line-height: 1.2em;
140 139 }
141 140
142 141 p {
143 142 margin: 0 0 20px;
144 143 }
145 144
146 145 h1, h2, h3, h4, h5, h6 {
147 146 color: #323232 !important;
148 147 }
149 148
150 149 a {
151 150 color: #427cc9;
152 151 text-decoration: none;
153 152 outline: none;
154 153 cursor: pointer;
155 154 }
156 155
157 156 a:focus {
158 157 outline: none;
159 158 }
160 159
161 160 a:hover {
162 161 color: #305b91;
163 162 }
164 163
165 164 h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
166 165 color: #427cc9 !important;
167 166 text-decoration: none !important;
168 167 }
169 168
170 169 h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {
171 170 color: #305b91 !important;
172 171 }
173 172
174 173 h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {
175 174 color: #305b91 !important;
176 175 }
177 176
178 177 table {
179 178 font-size: 13px;
180 179 border-collapse: collapse;
181 180 mso-table-lspace: 0pt;
182 181 mso-table-rspace: 0pt;
183 182 }
184 183
185 184 table tr {
186 185 display: table-row;
187 186 vertical-align: inherit;
188 187 border-color: inherit;
189 188 border-spacing: 0 3px;
190 189 }
191 190
192 191 table td {
193 192 padding: .65em 1em .65em 0;
194 193 border-collapse: collapse;
195 194 vertical-align: top;
196 195 text-align: left;
197 196 }
198 197
199 198 input {
200 199 display: inline;
201 200 border-radius: 2px;
202 201 border: 1px solid #dbd9da;
203 202 padding: .5em;
204 203 }
205 204
206 205 input:focus {
207 206 outline: 1px solid #979797
208 207 }
209 208
210 209 code {
211 210 font-family: ${text_monospace|n};
212 211 white-space: pre-line !important;
213 212 color: #000000;
214 213 }
215 214
216 215 ul.changes-ul {
217 216 list-style: none;
218 217 list-style-type: none;
219 218 padding: 0;
220 219 margin: 10px 0;
221 220 }
222 221 ul.changes-ul li {
223 222 list-style: none;
224 223 list-style-type: none;
225 224 margin: 2px 0;
226 225 }
227 226
228 227 @media only screen and (-webkit-min-device-pixel-ratio: 2) {
229 228 /* Put your iPhone 4g styles in here */
230 229 }
231 230
232 231 /* Android targeting */
233 232 @media only screen and (-webkit-device-pixel-ratio:.75){
234 233 /* Put CSS for low density (ldpi) Android layouts in here */
235 234 }
236 235 @media only screen and (-webkit-device-pixel-ratio:1){
237 236 /* Put CSS for medium density (mdpi) Android layouts in here */
238 237 }
239 238 @media only screen and (-webkit-device-pixel-ratio:1.5){
240 239 /* Put CSS for high density (hdpi) Android layouts in here */
241 240 }
242 241 /* end Android targeting */
243 242
244 243 /** MARKDOWN styling **/
245 244 div.markdown-block {
246 245 clear: both;
247 246 overflow: hidden;
248 247 margin: 0;
249 248 padding: 3px 5px 3px
250 249 }
251 250
252 251 div.markdown-block h1,
253 252 div.markdown-block h2,
254 253 div.markdown-block h3,
255 254 div.markdown-block h4,
256 255 div.markdown-block h5,
257 256 div.markdown-block h6 {
258 257 border-bottom: none !important;
259 258 padding: 0 !important;
260 259 overflow: visible !important
261 260 }
262 261
263 262 div.markdown-block h1,
264 263 div.markdown-block h2 {
265 264 border-bottom: 1px #e6e5e5 solid !important
266 265 }
267 266
268 267 div.markdown-block h1 {
269 268 font-size: 32px;
270 269 margin: 15px 0 15px 0 !important;
271 270 padding-bottom: 5px !important
272 271 }
273 272
274 273 div.markdown-block h2 {
275 274 font-size: 24px !important;
276 275 margin: 34px 0 10px 0 !important;
277 276 padding-top: 15px !important;
278 277 padding-bottom: 8px !important
279 278 }
280 279
281 280 div.markdown-block h3 {
282 281 font-size: 18px !important;
283 282 margin: 30px 0 8px 0 !important;
284 283 padding-bottom: 2px !important
285 284 }
286 285
287 286 div.markdown-block h4 {
288 287 font-size: 13px !important;
289 288 margin: 18px 0 3px 0 !important
290 289 }
291 290
292 291 div.markdown-block h5 {
293 292 font-size: 12px !important;
294 293 margin: 15px 0 3px 0 !important
295 294 }
296 295
297 296 div.markdown-block h6 {
298 297 font-size: 12px;
299 298 color: #777777;
300 299 margin: 15px 0 3px 0 !important
301 300 }
302 301
303 302 div.markdown-block hr {
304 303 border: 0;
305 304 color: #e6e5e5;
306 305 background-color: #e6e5e5;
307 306 height: 3px;
308 307 margin-bottom: 13px
309 308 }
310 309
311 310 div.markdown-block ol,
312 311 div.markdown-block ul,
313 312 div.markdown-block p,
314 313 div.markdown-block blockquote,
315 314 div.markdown-block dl,
316 315 div.markdown-block li,
317 316 div.markdown-block table {
318 317 margin: 3px 0 13px 0 !important;
319 318 color: #424242 !important;
320 319 font-size: 13px !important;
321 320 font-family: ${text_regular|n};
322 321 font-weight: normal !important;
323 322 overflow: visible !important;
324 323 line-height: 140% !important
325 324 }
326 325
327 326 div.markdown-block pre {
328 327 margin: 3px 0 13px 0 !important;
329 328 padding: .5em;
330 329 color: #424242 !important;
331 330 font-size: 13px !important;
332 331 overflow: visible !important;
333 332 line-height: 140% !important;
334 333 background-color: #F5F5F5
335 334 }
336 335
337 336 div.markdown-block img {
338 337 border-style: none;
339 338 background-color: #fff;
340 339 max-width: 100%
341 340 }
342 341
343 342 div.markdown-block strong {
344 343 font-weight: 600;
345 344 margin: 0
346 345 }
347 346
348 347 div.markdown-block ul.checkbox, div.markdown-block ol.checkbox {
349 348 padding-left: 20px !important;
350 349 margin-top: 0 !important;
351 350 margin-bottom: 18px !important
352 351 }
353 352
354 353 div.markdown-block ul, div.markdown-block ol {
355 354 padding-left: 30px !important;
356 355 margin-top: 0 !important;
357 356 margin-bottom: 18px !important
358 357 }
359 358
360 359 div.markdown-block ul.checkbox li, div.markdown-block ol.checkbox li {
361 360 list-style: none !important;
362 361 margin: 0px !important;
363 362 padding: 0 !important
364 363 }
365 364
366 365 div.markdown-block ul li, div.markdown-block ol li {
367 366 list-style: disc !important;
368 367 margin: 0px !important;
369 368 padding: 0 !important
370 369 }
371 370
372 371 div.markdown-block ol li {
373 372 list-style: decimal !important
374 373 }
375 374
376 375 div.markdown-block #message {
377 376 -webkit-border-radius: 2px;
378 377 -moz-border-radius: 2px;
379 378 border-radius: 2px;
380 379 border: 1px solid #dbd9da;
381 380 display: block;
382 381 width: 100%;
383 382 height: 60px;
384 383 margin: 6px 0
385 384 }
386 385
387 386 div.markdown-block button, div.markdown-block #ws {
388 387 font-size: 13px;
389 388 padding: 4px 6px;
390 389 -webkit-border-radius: 2px;
391 390 -moz-border-radius: 2px;
392 391 border-radius: 2px;
393 392 border: 1px solid #dbd9da;
394 393 background-color: #eeeeee
395 394 }
396 395
397 396 div.markdown-block p {
398 397 margin-top: 0;
399 398 margin-bottom: 16px;
400 399 padding: 0;
401 400 line-height: unset;
402 401 }
403 402
404 403 div.markdown-block code,
405 404 div.markdown-block pre,
406 405 div.markdown-block #ws,
407 406 div.markdown-block #message {
408 407 font-family: ${text_monospace|n};
409 408 font-size: 11px;
410 409 -webkit-border-radius: 2px;
411 410 -moz-border-radius: 2px;
412 411 border-radius: 2px;
413 412 background-color: #FFFFFF;
414 413 color: #7E7F7F
415 414 }
416 415
417 416 div.markdown-block code {
418 417 border: 1px solid #7E7F7F;
419 418 margin: 0 2px;
420 419 padding: 0 5px
421 420 }
422 421
423 422 div.markdown-block pre {
424 423 border: 1px solid #7E7F7F;
425 424 overflow: auto;
426 425 padding: .5em;
427 426 background-color: #FFFFFF;
428 427 }
429 428
430 429 div.markdown-block pre > code {
431 430 border: 0;
432 431 margin: 0;
433 432 padding: 0
434 433 }
435 434
436 435 div.rst-block {
437 436 clear: both;
438 437 overflow: hidden;
439 438 margin: 0;
440 439 padding: 3px 5px 3px
441 440 }
442 441
443 442 div.rst-block h2 {
444 443 font-weight: normal
445 444 }
446 445
447 446 div.rst-block h1,
448 447 div.rst-block h2,
449 448 div.rst-block h3,
450 449 div.rst-block h4,
451 450 div.rst-block h5,
452 451 div.rst-block h6 {
453 452 border-bottom: 0 !important;
454 453 margin: 0 !important;
455 454 padding: 0 !important;
456 455 line-height: 1.5em !important
457 456 }
458 457
459 458 div.rst-block h1:first-child {
460 459 padding-top: .25em !important
461 460 }
462 461
463 462 div.rst-block h2, div.rst-block h3 {
464 463 margin: 1em 0 !important
465 464 }
466 465
467 466 div.rst-block h1, div.rst-block h2 {
468 467 border-bottom: 1px #e6e5e5 solid !important
469 468 }
470 469
471 470 div.rst-block h2 {
472 471 margin-top: 1.5em !important;
473 472 padding-top: .5em !important
474 473 }
475 474
476 475 div.rst-block p {
477 476 color: black !important;
478 477 margin: 1em 0 !important;
479 478 line-height: 1.5em !important
480 479 }
481 480
482 481 div.rst-block ul {
483 482 list-style: disc !important;
484 483 margin: 1em 0 1em 2em !important;
485 484 clear: both
486 485 }
487 486
488 487 div.rst-block ol {
489 488 list-style: decimal;
490 489 margin: 1em 0 1em 2em !important
491 490 }
492 491
493 492 div.rst-block pre, div.rst-block code {
494 493 font: 12px "Bitstream Vera Sans Mono", "Courier", monospace
495 494 }
496 495
497 496 div.rst-block code {
498 497 font-size: 12px !important;
499 498 background-color: ghostWhite !important;
500 499 color: #444 !important;
501 500 padding: 0 .2em !important;
502 501 border: 1px solid #7E7F7F !important
503 502 }
504 503
505 504 div.rst-block pre code {
506 505 padding: 0 !important;
507 506 font-size: 12px !important;
508 507 background-color: #eee !important;
509 508 border: none !important
510 509 }
511 510
512 511 div.rst-block pre {
513 512 margin: 1em 0;
514 513 padding: 15px;
515 514 border: 1px solid #7E7F7F;
516 515 -webkit-border-radius: 2px;
517 516 -moz-border-radius: 2px;
518 517 border-radius: 2px;
519 518 overflow: auto;
520 519 font-size: 12px;
521 520 color: #444;
522 521 background-color: #FFFFFF;
523 522 }
524 523
525 524 .clear-both {
526 525 clear:both;
527 526 }
528 527
529 528 /*elasticmatch is custom rhodecode tag*/
530 529 .codehilite .c-ElasticMatch {
531 530 background-color: #faffa6;
532 531 padding: 0.2em;
533 532 }
534 533
535 534 .codehilite .c-ElasticMatch { background-color: #faffa6; padding: 0.2em;}
536 535 .codehilite .hll { background-color: #ffffcc }
537 536 .codehilite .c { color: #408080; font-style: italic } /* Comment */
538 537 .codehilite .err { border: none } /* Error */
539 538 .codehilite .k { color: #008000; font-weight: bold } /* Keyword */
540 539 .codehilite .o { color: #666666 } /* Operator */
541 540 .codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
542 541 .codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */
543 542 .codehilite .cp { color: #BC7A00 } /* Comment.Preproc */
544 543 .codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
545 544 .codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */
546 545 .codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */
547 546 .codehilite .gd { color: #A00000 } /* Generic.Deleted */
548 547 .codehilite .ge { font-style: italic } /* Generic.Emph */
549 548 .codehilite .gr { color: #FF0000 } /* Generic.Error */
550 549 .codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
551 550 .codehilite .gi { color: #00A000 } /* Generic.Inserted */
552 551 .codehilite .go { color: #888888 } /* Generic.Output */
553 552 .codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
554 553 .codehilite .gs { font-weight: bold } /* Generic.Strong */
555 554 .codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
556 555 .codehilite .gt { color: #0044DD } /* Generic.Traceback */
557 556 .codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
558 557 .codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
559 558 .codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
560 559 .codehilite .kp { color: #008000 } /* Keyword.Pseudo */
561 560 .codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
562 561 .codehilite .kt { color: #B00040 } /* Keyword.Type */
563 562 .codehilite .m { color: #666666 } /* Literal.Number */
564 563 .codehilite .s { color: #BA2121 } /* Literal.String */
565 564 .codehilite .na { color: #7D9029 } /* Name.Attribute */
566 565 .codehilite .nb { color: #008000 } /* Name.Builtin */
567 566 .codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */
568 567 .codehilite .no { color: #880000 } /* Name.Constant */
569 568 .codehilite .nd { color: #AA22FF } /* Name.Decorator */
570 569 .codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */
571 570 .codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
572 571 .codehilite .nf { color: #0000FF } /* Name.Function */
573 572 .codehilite .nl { color: #A0A000 } /* Name.Label */
574 573 .codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
575 574 .codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */
576 575 .codehilite .nv { color: #19177C } /* Name.Variable */
577 576 .codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
578 577 .codehilite .w { color: #bbbbbb } /* Text.Whitespace */
579 578 .codehilite .mb { color: #666666 } /* Literal.Number.Bin */
580 579 .codehilite .mf { color: #666666 } /* Literal.Number.Float */
581 580 .codehilite .mh { color: #666666 } /* Literal.Number.Hex */
582 581 .codehilite .mi { color: #666666 } /* Literal.Number.Integer */
583 582 .codehilite .mo { color: #666666 } /* Literal.Number.Oct */
584 583 .codehilite .sa { color: #BA2121 } /* Literal.String.Affix */
585 584 .codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */
586 585 .codehilite .sc { color: #BA2121 } /* Literal.String.Char */
587 586 .codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */
588 587 .codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
589 588 .codehilite .s2 { color: #BA2121 } /* Literal.String.Double */
590 589 .codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
591 590 .codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */
592 591 .codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
593 592 .codehilite .sx { color: #008000 } /* Literal.String.Other */
594 593 .codehilite .sr { color: #BB6688 } /* Literal.String.Regex */
595 594 .codehilite .s1 { color: #BA2121 } /* Literal.String.Single */
596 595 .codehilite .ss { color: #19177C } /* Literal.String.Symbol */
597 596 .codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */
598 597 .codehilite .fm { color: #0000FF } /* Name.Function.Magic */
599 598 .codehilite .vc { color: #19177C } /* Name.Variable.Class */
600 599 .codehilite .vg { color: #19177C } /* Name.Variable.Global */
601 600 .codehilite .vi { color: #19177C } /* Name.Variable.Instance */
602 601 .codehilite .vm { color: #19177C } /* Name.Variable.Magic */
603 602 .codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */
604 603
605 604 </style>
606 605
607 606 </head>
608 607 <body>
609 608
610 609 <div>
611 610 <!-- Wrapper/Container Table: Use a wrapper table to control the width and the background color consistently of your email. Use this approach instead of setting attributes on the body tag. -->
612 611 <table cellpadding="0" cellspacing="0" border="0" id="backgroundTable" align="left" style="margin:1%;width:97%;padding:0;font-family:${text_regular|n};font-weight:100;border:1px solid #dbd9da">
613 612 <tr>
614 613 <td valign="top" style="padding:0;">
615 614 <table cellpadding="0" cellspacing="0" border="0" align="left" width="100%">
616 615 <tr>
617 616 <td style="width:100%;padding:10px 15px;background-color:#202020" valign="top">
618 617 <a style="color:#eeeeee;text-decoration:none;" href="${instance_url}">
619 618 ${_('RhodeCode')}
620 619 % if rhodecode_instance_name:
621 620 - ${rhodecode_instance_name}
622 621 % endif
623 622 </a>
624 623 </td>
625 624 </tr>
626 625 <tr style="background-color: #fff">
627 626 <td style="padding:15px;" valign="top">${self.body()}</td>
628 627 </tr>
629 628 </table>
630 629 </td>
631 630 </tr>
632 631 </table>
633 632 <!-- End of wrapper table -->
634 633 </div>
635 634
636 635 <div style="width:100%; clear: both; height: 1px">&nbsp;</div>
637 636
638 637 <div style="margin-left:1%;font-weight:100;font-size:11px;color:#666666;text-decoration:none;font-family:${text_monospace};">
639 638 ${_('This is a notification from RhodeCode.')}
640 639 <a style="font-weight:100;font-size:11px;color:#666666;text-decoration:none;font-family:${text_monospace};" href="${instance_url}">
641 640 ${instance_url}
642 641 </a>
643 642 </div>
644 643 </body>
645 644 </html>
@@ -1,176 +1,175 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="base" file="base.mako"/>
4 3
5 4 ## EMAIL SUBJECT
6 5 <%def name="subject()" filter="n,trim,whitespace_filter">
7 6 <%
8 7 data = {
9 8 'user': '@'+h.person(user),
10 9 'repo_name': repo_name,
11 10 'status': status_change,
12 11 'comment_file': comment_file,
13 12 'comment_line': comment_line,
14 13 'comment_type': comment_type,
15 14 'comment_id': comment_id,
16 15
17 16 'commit_id': h.show_id(commit),
18 17 'mention_prefix': '[mention] ' if mention else '',
19 18 }
20 19
21 20
22 21 if comment_file:
23 22 subject_template = email_comment_file_subject_template or \
24 23 _('{mention_prefix}{user} left a {comment_type} on file `{comment_file}` in commit `{commit_id}` in the `{repo_name}` repository').format(**data)
25 24 else:
26 25 if status_change:
27 26 subject_template = email_comment_status_change_subject_template or \
28 27 _('{mention_prefix}[status: {status}] {user} left a {comment_type} on commit `{commit_id}` in the `{repo_name}` repository').format(**data)
29 28 else:
30 29 subject_template = email_comment_subject_template or \
31 30 _('{mention_prefix}{user} left a {comment_type} on commit `{commit_id}` in the `{repo_name}` repository').format(**data)
32 31 %>
33 32
34 33
35 34 ${subject_template.format(**data) |n}
36 35 </%def>
37 36
38 37 ## PLAINTEXT VERSION OF BODY
39 38 <%def name="body_plaintext()" filter="n,trim">
40 39 <%
41 40 data = {
42 41 'user': h.person(user),
43 42 'repo_name': repo_name,
44 43 'status': status_change,
45 44 'comment_file': comment_file,
46 45 'comment_line': comment_line,
47 46 'comment_type': comment_type,
48 47 'comment_id': comment_id,
49 48
50 49 'commit_id': h.show_id(commit),
51 50 }
52 51 %>
53 52
54 53 * ${_('Comment link')}: ${commit_comment_url}
55 54
56 55 %if status_change:
57 56 * ${_('Commit status')}: ${_('Status was changed to')}: *${status_change}*
58 57
59 58 %endif
60 59 * ${_('Commit')}: ${h.show_id(commit)}
61 60
62 61 * ${_('Commit message')}: ${commit.message}
63 62
64 63 %if comment_file:
65 64 * ${_('File: {comment_file} on line {comment_line}').format(**data)}
66 65
67 66 %endif
68 67 % if comment_type == 'todo':
69 68 ${('Inline' if comment_file else 'General')} ${_('`TODO` number')} ${comment_id}:
70 69 % else:
71 70 ${('Inline' if comment_file else 'General')} ${_('`Note` number')} ${comment_id}:
72 71 % endif
73 72
74 73 ${comment_body |n, trim}
75 74
76 75 ---
77 76 ${self.plaintext_footer()}
78 77 </%def>
79 78
80 79
81 80 <%
82 81 data = {
83 82 'user': h.person(user),
84 83 'comment_file': comment_file,
85 84 'comment_line': comment_line,
86 85 'comment_type': comment_type,
87 86 'comment_id': comment_id,
88 87 'renderer_type': renderer_type or 'plain',
89 88
90 89 'repo': commit_target_repo_url,
91 90 'repo_name': repo_name,
92 91 'commit_id': h.show_id(commit),
93 92 }
94 93 %>
95 94
96 95 ## header
97 96 <table style="text-align:left;vertical-align:middle;width: 100%">
98 97 <tr>
99 98 <td style="width:100%;border-bottom:1px solid #dbd9da;">
100 99
101 100 <div style="margin: 0; font-weight: bold">
102 101 <div class="clear-both" style="margin-bottom: 4px">
103 102 <span style="color:#7E7F7F">@${h.person(user.username)}</span>
104 103 ${_('left a')}
105 104 <a href="${commit_comment_url}" style="${base.link_css()}">
106 105 % if comment_file:
107 106 ${_('{comment_type} on file `{comment_file}` in commit.').format(**data)}
108 107 % else:
109 108 ${_('{comment_type} on commit.').format(**data) |n}
110 109 % endif
111 110 </a>
112 111 </div>
113 112 <div style="margin-top: 10px"></div>
114 113 ${_('Commit')} <code>${data['commit_id']}</code> ${_('of repository')}: ${data['repo_name']}
115 114 </div>
116 115
117 116 </td>
118 117 </tr>
119 118
120 119 </table>
121 120 <div class="clear-both"></div>
122 121 ## main body
123 122 <table style="text-align:left;vertical-align:middle;width: 100%">
124 123
125 124 ## spacing def
126 125 <tr>
127 126 <td style="width: 130px"></td>
128 127 <td></td>
129 128 </tr>
130 129
131 130 % if status_change:
132 131 <tr>
133 132 <td style="padding-right:20px;">${_('Commit Status')}:</td>
134 133 <td>
135 134 ${_('Status was changed to')}: ${base.status_text(status_change, tag_type=status_change_type)}
136 135 </td>
137 136 </tr>
138 137 % endif
139 138
140 139 <tr>
141 140 <td style="padding-right:20px;">${_('Commit')}:</td>
142 141 <td>
143 142 <a href="${commit_comment_url}" style="${base.link_css()}">${h.show_id(commit)}</a>
144 143 </td>
145 144 </tr>
146 145 <tr>
147 146 <td style="padding-right:20px;">${_('Commit message')}:</td>
148 147 <td style="white-space:pre-wrap">${h.urlify_commit_message(commit.message, repo_name)}</td>
149 148 </tr>
150 149
151 150 % if comment_file:
152 151 <tr>
153 152 <td style="padding-right:20px;">${_('File')}:</td>
154 153 <td><a href="${commit_comment_url}" style="${base.link_css()}">${_('`{comment_file}` on line {comment_line}').format(**data)}</a></td>
155 154 </tr>
156 155 % endif
157 156
158 157 <tr style="border-bottom:1px solid #dbd9da;">
159 158 <td colspan="2" style="padding-right:20px;">
160 159 % if comment_type == 'todo':
161 160 ${('Inline' if comment_file else 'General')} ${_('`TODO` number')} ${comment_id}:
162 161 % else:
163 162 ${('Inline' if comment_file else 'General')} ${_('`Note` number')} ${comment_id}:
164 163 % endif
165 164 </td>
166 165 </tr>
167 166
168 167 <tr>
169 168 <td colspan="2" style="background: #F7F7F7">${h.render(comment_body, renderer=data['renderer_type'], mentions=True)}</td>
170 169 </tr>
171 170
172 171 <tr>
173 172 <td><a href="${commit_comment_reply_url}">${_('Reply')}</a></td>
174 173 <td></td>
175 174 </tr>
176 175 </table>
@@ -1,20 +1,19 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="base" file="base.mako"/>
4 3
5 4 <%def name="subject()" filter="n,trim,whitespace_filter">
6 5 RhodeCode test email: ${h.format_date(date)}
7 6 </%def>
8 7
9 8 ## plain text version of the email. Empty by default
10 9 <%def name="body_plaintext()" filter="n,trim">
11 10 Test Email from RhodeCode version: ${rhodecode_version}
12 11 Email sent by: ${h.person(user)}
13 12
14 13 ---
15 14 ${self.plaintext_footer()}
16 15 </%def>
17 16
18 17 Test Email from RhodeCode version: ${rhodecode_version}
19 18 <br/><br/>
20 19 Email sent by: <strong>${h.person(user)}</strong>
@@ -1,18 +1,17 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="base" file="base.mako"/>
4 3
5 4 <%def name="subject()" filter="n,trim,whitespace_filter">
6 5 ${email_prefix} ${exc_type_name} (${exc_id})
7 6 </%def>
8 7
9 8 ## plain text version of the email. Empty by default
10 9 <%def name="body_plaintext()" filter="n,trim">
11 10 NO PLAINTEXT VERSION
12 11 </%def>
13 12
14 13 <h4>${_('Exception `{}` generated on UTC date: {}').format(exc_traceback.get('exc_type', 'NO_TYPE'), exc_traceback.get('exc_utc_date', 'NO_DATE'))}</h4>
15 14 <p>
16 15 View exception <a href="${exc_url}">${exc_id}</a>
17 16 </p>
18 17 <pre>${exc_traceback.get('exc_message', 'NO_MESSAGE')}</pre>
@@ -1,21 +1,20 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2
4 3 <%def name="subject()" filter="n,trim,whitespace_filter">
5 4 </%def>
6 5
7 6
8 7 ## plain text version of the email. Empty by default
9 8 <%def name="body_plaintext()" filter="n,trim">
10 9 ${body}
11 10
12 11 ---
13 12 ${self.plaintext_footer()}
14 13 </%def>
15 14
16 15 ## BODY GOES BELOW
17 16 <table style="text-align:left;vertical-align:top;">
18 17 <tr>
19 18 <td style="padding-right:20px;padding-top:15px;white-space:pre-wrap">${body}</td>
20 19 </tr>
21 20 </table>
@@ -1,37 +1,36 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="base" file="base.mako"/>
4 3
5 4 <%def name="subject()" filter="n,trim,whitespace_filter">
6 5 RhodeCode Password reset
7 6 </%def>
8 7
9 8 ## plain text version of the email. Empty by default
10 9 <%def name="body_plaintext()" filter="n,trim">
11 10 Hello ${user.username},
12 11
13 12 On ${h.format_date(date)} there was a request to reset your password using the email address `${email}`
14 13
15 14 *If you did not request a password reset, please contact your RhodeCode administrator at: ${first_admin_email}*
16 15
17 16 You can continue, and generate new password by clicking following URL:
18 17 ${password_reset_url}
19 18
20 19 This link will be active for 10 minutes.
21 20
22 21 ---
23 22 ${self.plaintext_footer()}
24 23 </%def>
25 24
26 25 ## BODY GOES BELOW
27 26 <p>
28 27 Hello ${user.username},
29 28 </p><p>
30 29 On ${h.format_date(date)} there was a request to reset your password using the email address `${email}`
31 30 <br/><br/>
32 31 <strong>If you did not request a password reset, please contact your RhodeCode administrator at: ${first_admin_email}.</strong>
33 32 </p><p>
34 33 You can continue, and generate new password by clicking following URL:<br/><br/>
35 34 <a href="${password_reset_url}" style="${base.link_css()}">${password_reset_url}</a>
36 35 <br/><br/>This link will be active for 10 minutes.
37 36 </p>
@@ -1,31 +1,30 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="base" file="base.mako"/>
4 3
5 4 <%def name="subject()" filter="n,trim,whitespace_filter">
6 5 Your new RhodeCode password
7 6 </%def>
8 7
9 8 ## plain text version of the email. Empty by default
10 9 <%def name="body_plaintext()" filter="n,trim">
11 10 Hello ${user.username},
12 11
13 12 Below is your new access password for RhodeCode requested via password reset link.
14 13
15 14 *If you did not request a password reset, please contact your RhodeCode administrator at: ${first_admin_email}.*
16 15
17 16 new password: ${new_password}
18 17
19 18 ---
20 19 ${self.plaintext_footer()}
21 20 </%def>
22 21
23 22 ## BODY GOES BELOW
24 23 <p>
25 24 Hello ${user.username},
26 25 </p><p>
27 26 Below is your new access password for RhodeCode requested via password reset link.
28 27 <br/><br/>
29 28 <strong>If you did not request a password reset, please contact your RhodeCode administrator at: ${first_admin_email}.</strong>
30 29 </p>
31 30 <p>new password: <code>${new_password}</code>
@@ -1,205 +1,204 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="base" file="base.mako"/>
4 3
5 4 ## EMAIL SUBJECT
6 5 <%def name="subject()" filter="n,trim,whitespace_filter">
7 6 <%
8 7 data = {
9 8 'user': '@'+h.person(user),
10 9 'repo_name': repo_name,
11 10 'status': status_change,
12 11 'comment_file': comment_file,
13 12 'comment_line': comment_line,
14 13 'comment_type': comment_type,
15 14 'comment_id': comment_id,
16 15
17 16 'pr_title': pull_request.title_safe,
18 17 'pr_id': pull_request.pull_request_id,
19 18 'mention_prefix': '[mention] ' if mention else '',
20 19 }
21 20
22 21 if comment_file:
23 22 subject_template = email_pr_comment_file_subject_template or \
24 23 _('{mention_prefix}{user} left a {comment_type} on file `{comment_file}` in pull request !{pr_id}: "{pr_title}"').format(**data)
25 24 else:
26 25 if status_change:
27 26 subject_template = email_pr_comment_status_change_subject_template or \
28 27 _('{mention_prefix}[status: {status}] {user} left a {comment_type} on pull request !{pr_id}: "{pr_title}"').format(**data)
29 28 else:
30 29 subject_template = email_pr_comment_subject_template or \
31 30 _('{mention_prefix}{user} left a {comment_type} on pull request !{pr_id}: "{pr_title}"').format(**data)
32 31 %>
33 32
34 33 ${subject_template.format(**data) |n}
35 34 </%def>
36 35
37 36 ## PLAINTEXT VERSION OF BODY
38 37 <%def name="body_plaintext()" filter="n,trim">
39 38 <%
40 39 data = {
41 40 'user': h.person(user),
42 41 'repo_name': repo_name,
43 42 'status': status_change,
44 43 'comment_file': comment_file,
45 44 'comment_line': comment_line,
46 45 'comment_type': comment_type,
47 46 'comment_id': comment_id,
48 47
49 48 'pr_title': pull_request.title_safe,
50 49 'pr_id': pull_request.pull_request_id,
51 50 'source_ref_type': pull_request.source_ref_parts.type,
52 51 'source_ref_name': pull_request.source_ref_parts.name,
53 52 'target_ref_type': pull_request.target_ref_parts.type,
54 53 'target_ref_name': pull_request.target_ref_parts.name,
55 54 'source_repo': pull_request_source_repo.repo_name,
56 55 'target_repo': pull_request_target_repo.repo_name,
57 56 'source_repo_url': pull_request_source_repo_url,
58 57 'target_repo_url': pull_request_target_repo_url,
59 58 }
60 59 %>
61 60
62 61 * ${_('Comment link')}: ${pr_comment_url}
63 62
64 63 * ${_('Pull Request')}: !${pull_request.pull_request_id}
65 64
66 65 * ${h.literal(_('Commit flow: {source_ref_type}:{source_ref_name} of {source_repo_url} into {target_ref_type}:{target_ref_name} of {target_repo_url}').format(**data))}
67 66
68 67 %if status_change and not closing_pr:
69 68 * ${_('{user} submitted pull request !{pr_id} status: *{status}*').format(**data)}
70 69
71 70 %elif status_change and closing_pr:
72 71 * ${_('{user} submitted pull request !{pr_id} status: *{status} and closed*').format(**data)}
73 72
74 73 %endif
75 74 %if comment_file:
76 75 * ${_('File: {comment_file} on line {comment_line}').format(**data)}
77 76
78 77 %endif
79 78 % if comment_type == 'todo':
80 79 ${('Inline' if comment_file else 'General')} ${_('`TODO` number')} ${comment_id}:
81 80 % else:
82 81 ${('Inline' if comment_file else 'General')} ${_('`Note` number')} ${comment_id}:
83 82 % endif
84 83
85 84 ${comment_body |n, trim}
86 85
87 86 ---
88 87 ${self.plaintext_footer()}
89 88 </%def>
90 89
91 90
92 91 <%
93 92 data = {
94 93 'user': h.person(user),
95 94 'comment_file': comment_file,
96 95 'comment_line': comment_line,
97 96 'comment_type': comment_type,
98 97 'comment_id': comment_id,
99 98 'renderer_type': renderer_type or 'plain',
100 99
101 100 'pr_title': pull_request.title_safe,
102 101 'pr_id': pull_request.pull_request_id,
103 102 'status': status_change,
104 103 'source_ref_type': pull_request.source_ref_parts.type,
105 104 'source_ref_name': pull_request.source_ref_parts.name,
106 105 'target_ref_type': pull_request.target_ref_parts.type,
107 106 'target_ref_name': pull_request.target_ref_parts.name,
108 107 'source_repo': pull_request_source_repo.repo_name,
109 108 'target_repo': pull_request_target_repo.repo_name,
110 109 'source_repo_url': h.link_to(pull_request_source_repo.repo_name, pull_request_source_repo_url),
111 110 'target_repo_url': h.link_to(pull_request_target_repo.repo_name, pull_request_target_repo_url),
112 111 }
113 112 %>
114 113
115 114 ## header
116 115 <table style="text-align:left;vertical-align:middle;width: 100%">
117 116 <tr>
118 117 <td style="width:100%;border-bottom:1px solid #dbd9da;">
119 118
120 119 <div style="margin: 0; font-weight: bold">
121 120 <div class="clear-both" style="margin-bottom: 4px">
122 121 <span style="color:#7E7F7F">@${h.person(user.username)}</span>
123 122 ${_('left a')}
124 123 <a href="${pr_comment_url}" style="${base.link_css()}">
125 124 % if comment_file:
126 125 ${_('{comment_type} on file `{comment_file}` in pull request.').format(**data)}
127 126 % else:
128 127 ${_('{comment_type} on pull request.').format(**data) |n}
129 128 % endif
130 129 </a>
131 130 </div>
132 131 <div style="margin-top: 10px"></div>
133 132 ${_('Pull request')} <code>!${data['pr_id']}: ${data['pr_title']}</code>
134 133 </div>
135 134
136 135 </td>
137 136 </tr>
138 137
139 138 </table>
140 139 <div class="clear-both"></div>
141 140 ## main body
142 141 <table style="text-align:left;vertical-align:middle;width: 100%">
143 142
144 143 ## spacing def
145 144 <tr>
146 145 <td style="width: 130px"></td>
147 146 <td></td>
148 147 </tr>
149 148
150 149 % if status_change:
151 150 <tr>
152 151 <td style="padding-right:20px;">${_('Review Status')}:</td>
153 152 <td>
154 153 % if closing_pr:
155 154 ${_('Closed pull request with status')}: ${base.status_text(status_change, tag_type=status_change_type)}
156 155 % else:
157 156 ${_('Submitted review status')}: ${base.status_text(status_change, tag_type=status_change_type)}
158 157 % endif
159 158 </td>
160 159 </tr>
161 160 % endif
162 161 <tr>
163 162 <td style="padding-right:20px;">${_('Pull request')}:</td>
164 163 <td>
165 164 <a href="${pull_request_url}" style="${base.link_css()}">
166 165 !${pull_request.pull_request_id}
167 166 </a>
168 167 </td>
169 168 </tr>
170 169
171 170 <tr>
172 171 <td style="padding-right:20px;line-height:20px;">${_('Commit Flow')}:</td>
173 172 <td style="line-height:20px;">
174 173 <code>${data['source_ref_type']}:${pull_request.source_ref_parts.name}</code> ${_('of')} ${data['source_repo_url']}
175 174 &rarr;
176 175 <code>${data['target_ref_type']}:${pull_request.target_ref_parts.name}</code> ${_('of')} ${data['target_repo_url']}
177 176 </td>
178 177 </tr>
179 178
180 179 % if comment_file:
181 180 <tr>
182 181 <td style="padding-right:20px;">${_('File')}:</td>
183 182 <td><a href="${pr_comment_url}" style="${base.link_css()}">${_('`{comment_file}` on line {comment_line}').format(**data)}</a></td>
184 183 </tr>
185 184 % endif
186 185
187 186 <tr style="border-bottom:1px solid #dbd9da;">
188 187 <td colspan="2" style="padding-right:20px;">
189 188 % if comment_type == 'todo':
190 189 ${('Inline' if comment_file else 'General')} ${_('`TODO` number')} ${comment_id}:
191 190 % else:
192 191 ${('Inline' if comment_file else 'General')} ${_('`Note` number')} ${comment_id}:
193 192 % endif
194 193 </td>
195 194 </tr>
196 195
197 196 <tr>
198 197 <td colspan="2" style="background: #F7F7F7">${h.render(comment_body, renderer=data['renderer_type'], mentions=True)}</td>
199 198 </tr>
200 199
201 200 <tr>
202 201 <td><a href="${pr_comment_reply_url}">${_('Reply')}</a></td>
203 202 <td></td>
204 203 </tr>
205 204 </table>
@@ -1,154 +1,153 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="base" file="base.mako"/>
4 3
5 4 ## EMAIL SUBJECT
6 5 <%def name="subject()" filter="n,trim,whitespace_filter">
7 6 <%
8 7 data = {
9 8 'user': '@'+h.person(user),
10 9 'pr_id': pull_request.pull_request_id,
11 10 'pr_title': pull_request.title_safe,
12 11 }
13 12
14 13 if user_role == 'observer':
15 14 subject_template = email_pr_review_subject_template or _('{user} added you as observer to pull request. !{pr_id}: "{pr_title}"')
16 15 else:
17 16 subject_template = email_pr_review_subject_template or _('{user} requested a pull request review. !{pr_id}: "{pr_title}"')
18 17 %>
19 18
20 19 ${subject_template.format(**data) |n}
21 20 </%def>
22 21
23 22 ## PLAINTEXT VERSION OF BODY
24 23 <%def name="body_plaintext()" filter="n,trim">
25 24 <%
26 25 data = {
27 26 'user': h.person(user),
28 27 'pr_id': pull_request.pull_request_id,
29 28 'pr_title': pull_request.title_safe,
30 29 'source_ref_type': pull_request.source_ref_parts.type,
31 30 'source_ref_name': pull_request.source_ref_parts.name,
32 31 'target_ref_type': pull_request.target_ref_parts.type,
33 32 'target_ref_name': pull_request.target_ref_parts.name,
34 33 'repo_url': pull_request_source_repo_url,
35 34 'source_repo': pull_request_source_repo.repo_name,
36 35 'target_repo': pull_request_target_repo.repo_name,
37 36 'source_repo_url': pull_request_source_repo_url,
38 37 'target_repo_url': pull_request_target_repo_url,
39 38 }
40 39
41 40 %>
42 41
43 42 * ${_('Pull Request link')}: ${pull_request_url}
44 43
45 44 * ${h.literal(_('Commit flow: {source_ref_type}:{source_ref_name} of {source_repo_url} into {target_ref_type}:{target_ref_name} of {target_repo_url}').format(**data))}
46 45
47 46 * ${_('Title')}: ${pull_request.title}
48 47
49 48 * ${_('Description')}:
50 49
51 50 ${pull_request.description | trim}
52 51
53 52
54 53 * ${_ungettext('Commit (%(num)s)', 'Commits (%(num)s)', len(pull_request_commits) ) % {'num': len(pull_request_commits)}}:
55 54
56 55 % for commit_id, message in pull_request_commits:
57 56 - ${h.short_id(commit_id)}
58 57 ${h.chop_at_smart(message.lstrip(), '\n', suffix_if_chopped='...')}
59 58
60 59 % endfor
61 60
62 61 ---
63 62 ${self.plaintext_footer()}
64 63 </%def>
65 64 <%
66 65 data = {
67 66 'user': h.person(user),
68 67 'pr_id': pull_request.pull_request_id,
69 68 'pr_title': pull_request.title_safe,
70 69 'source_ref_type': pull_request.source_ref_parts.type,
71 70 'source_ref_name': pull_request.source_ref_parts.name,
72 71 'target_ref_type': pull_request.target_ref_parts.type,
73 72 'target_ref_name': pull_request.target_ref_parts.name,
74 73 'repo_url': pull_request_source_repo_url,
75 74 'source_repo': pull_request_source_repo.repo_name,
76 75 'target_repo': pull_request_target_repo.repo_name,
77 76 'source_repo_url': h.link_to(pull_request_source_repo.repo_name, pull_request_source_repo_url),
78 77 'target_repo_url': h.link_to(pull_request_target_repo.repo_name, pull_request_target_repo_url),
79 78 }
80 79 %>
81 80 ## header
82 81 <table style="text-align:left;vertical-align:middle;width: 100%">
83 82 <tr>
84 83 <td style="width:100%;border-bottom:1px solid #dbd9da;">
85 84 <div style="margin: 0; font-weight: bold">
86 85 % if user_role == 'observer':
87 86 <div class="clear-both" class="clear-both" style="margin-bottom: 4px">
88 87 <span style="color:#7E7F7F">@${h.person(user.username)}</span>
89 88 ${_('added you as observer to')}
90 89 <a href="${pull_request_url}" style="${base.link_css()}">pull request</a>.
91 90 </div>
92 91 % else:
93 92 <div class="clear-both" class="clear-both" style="margin-bottom: 4px">
94 93 <span style="color:#7E7F7F">@${h.person(user.username)}</span>
95 94 ${_('requested a')}
96 95 <a href="${pull_request_url}" style="${base.link_css()}">pull request</a> review.
97 96 </div>
98 97 % endif
99 98 <div style="margin-top: 10px"></div>
100 99 ${_('Pull request')} <code>!${data['pr_id']}: ${data['pr_title']}</code>
101 100 </div>
102 101 </td>
103 102 </tr>
104 103
105 104 </table>
106 105 <div class="clear-both"></div>
107 106 ## main body
108 107 <table style="text-align:left;vertical-align:middle;width: 100%">
109 108 ## spacing def
110 109 <tr>
111 110 <td style="width: 130px"></td>
112 111 <td></td>
113 112 </tr>
114 113
115 114 <tr>
116 115 <td style="padding-right:20px;">${_('Pull request')}:</td>
117 116 <td>
118 117 <a href="${pull_request_url}" style="${base.link_css()}">
119 118 !${pull_request.pull_request_id}
120 119 </a>
121 120 </td>
122 121 </tr>
123 122
124 123 <tr>
125 124 <td style="padding-right:20px;line-height:20px;">${_('Commit Flow')}:</td>
126 125 <td style="line-height:20px;">
127 126 <code>${data['source_ref_type']}:${pull_request.source_ref_parts.name}</code> ${_('of')} ${data['source_repo_url']}
128 127 &rarr;
129 128 <code>${data['target_ref_type']}:${pull_request.target_ref_parts.name}</code> ${_('of')} ${data['target_repo_url']}
130 129 </td>
131 130 </tr>
132 131
133 132 <tr>
134 133 <td style="padding-right:20px;">${_('Description')}:</td>
135 134 <td style="white-space:pre-wrap"><code>${pull_request.description | trim}</code></td>
136 135 </tr>
137 136 <tr>
138 137 <td style="padding-right:20px;">${_ungettext('Commit (%(num)s)', 'Commits (%(num)s)', len(pull_request_commits)) % {'num': len(pull_request_commits)}}:</td>
139 138 <td></td>
140 139 </tr>
141 140
142 141 <tr>
143 142 <td colspan="2">
144 143 <ol style="margin:0 0 0 1em;padding:0;text-align:left;">
145 144 % for commit_id, message in pull_request_commits:
146 145 <li style="margin:0 0 1em;">
147 146 <pre style="margin:0 0 .5em"><a href="${h.route_path('repo_commit', repo_name=pull_request_source_repo.repo_name, commit_id=commit_id)}" style="${base.link_css()}">${h.short_id(commit_id)}</a></pre>
148 147 ${h.chop_at_smart(message, '\n', suffix_if_chopped='...')}
149 148 </li>
150 149 % endfor
151 150 </ol>
152 151 </td>
153 152 </tr>
154 153 </table>
@@ -1,172 +1,171 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="base" file="base.mako"/>
4 3
5 4 ## EMAIL SUBJECT
6 5 <%def name="subject()" filter="n,trim,whitespace_filter">
7 6 <%
8 7 data = {
9 8 'updating_user': '@'+h.person(updating_user),
10 9 'pr_id': pull_request.pull_request_id,
11 10 'pr_title': pull_request.title_safe,
12 11 }
13 12
14 13 subject_template = email_pr_update_subject_template or _('{updating_user} updated pull request. !{pr_id}: "{pr_title}"')
15 14 %>
16 15
17 16 ${subject_template.format(**data) |n}
18 17 </%def>
19 18
20 19 ## PLAINTEXT VERSION OF BODY
21 20 <%def name="body_plaintext()" filter="n,trim">
22 21 <%
23 22 data = {
24 23 'updating_user': h.person(updating_user),
25 24 'pr_id': pull_request.pull_request_id,
26 25 'pr_title': pull_request.title_safe,
27 26 'source_ref_type': pull_request.source_ref_parts.type,
28 27 'source_ref_name': pull_request.source_ref_parts.name,
29 28 'target_ref_type': pull_request.target_ref_parts.type,
30 29 'target_ref_name': pull_request.target_ref_parts.name,
31 30 'repo_url': pull_request_source_repo_url,
32 31 'source_repo': pull_request_source_repo.repo_name,
33 32 'target_repo': pull_request_target_repo.repo_name,
34 33 'source_repo_url': pull_request_source_repo_url,
35 34 'target_repo_url': pull_request_target_repo_url,
36 35 }
37 36 %>
38 37
39 38 * ${_('Pull Request link')}: ${pull_request_url}
40 39
41 40 * ${h.literal(_('Commit flow: {source_ref_type}:{source_ref_name} of {source_repo_url} into {target_ref_type}:{target_ref_name} of {target_repo_url}').format(**data))}
42 41
43 42 * ${_('Title')}: ${pull_request.title}
44 43
45 44 * ${_('Description')}:
46 45
47 46 ${pull_request.description | trim}
48 47
49 48 * Changed commits:
50 49
51 50 - Added: ${len(added_commits)}
52 51 - Removed: ${len(removed_commits)}
53 52
54 53 * Changed files:
55 54
56 55 %if not changed_files:
57 56 No file changes found
58 57 %else:
59 58 %for file_name in added_files:
60 59 - A `${file_name}`
61 60 %endfor
62 61 %for file_name in modified_files:
63 62 - M `${file_name}`
64 63 %endfor
65 64 %for file_name in removed_files:
66 65 - R `${file_name}`
67 66 %endfor
68 67 %endif
69 68
70 69 ---
71 70 ${self.plaintext_footer()}
72 71 </%def>
73 72 <%
74 73 data = {
75 74 'updating_user': h.person(updating_user),
76 75 'pr_id': pull_request.pull_request_id,
77 76 'pr_title': pull_request.title_safe,
78 77 'source_ref_type': pull_request.source_ref_parts.type,
79 78 'source_ref_name': pull_request.source_ref_parts.name,
80 79 'target_ref_type': pull_request.target_ref_parts.type,
81 80 'target_ref_name': pull_request.target_ref_parts.name,
82 81 'repo_url': pull_request_source_repo_url,
83 82 'source_repo': pull_request_source_repo.repo_name,
84 83 'target_repo': pull_request_target_repo.repo_name,
85 84 'source_repo_url': h.link_to(pull_request_source_repo.repo_name, pull_request_source_repo_url),
86 85 'target_repo_url': h.link_to(pull_request_target_repo.repo_name, pull_request_target_repo_url),
87 86 }
88 87 %>
89 88
90 89 ## header
91 90 <table style="text-align:left;vertical-align:middle;width: 100%">
92 91 <tr>
93 92 <td style="width:100%;border-bottom:1px solid #dbd9da;">
94 93
95 94 <div style="margin: 0; font-weight: bold">
96 95 <div class="clear-both" style="margin-bottom: 4px">
97 96 <span style="color:#7E7F7F">@${h.person(updating_user.username)}</span>
98 97 ${_('updated')}
99 98 <a href="${pull_request_url}" style="${base.link_css()}">
100 99 ${_('pull request.').format(**data) }
101 100 </a>
102 101 </div>
103 102 <div style="margin-top: 10px"></div>
104 103 ${_('Pull request')} <code>!${data['pr_id']}: ${data['pr_title']}</code>
105 104 </div>
106 105
107 106 </td>
108 107 </tr>
109 108
110 109 </table>
111 110 <div class="clear-both"></div>
112 111 ## main body
113 112 <table style="text-align:left;vertical-align:middle;width: 100%">
114 113 ## spacing def
115 114 <tr>
116 115 <td style="width: 130px"></td>
117 116 <td></td>
118 117 </tr>
119 118
120 119 <tr>
121 120 <td style="padding-right:20px;">${_('Pull request')}:</td>
122 121 <td>
123 122 <a href="${pull_request_url}" style="${base.link_css()}">
124 123 !${pull_request.pull_request_id}
125 124 </a>
126 125 </td>
127 126 </tr>
128 127
129 128 <tr>
130 129 <td style="padding-right:20px;line-height:20px;">${_('Commit Flow')}:</td>
131 130 <td style="line-height:20px;">
132 131 <code>${data['source_ref_type']}:${pull_request.source_ref_parts.name}</code> ${_('of')} ${data['source_repo_url']}
133 132 &rarr;
134 133 <code>${data['target_ref_type']}:${pull_request.target_ref_parts.name}</code> ${_('of')} ${data['target_repo_url']}
135 134 </td>
136 135 </tr>
137 136
138 137 <tr>
139 138 <td style="padding-right:20px;">${_('Description')}:</td>
140 139 <td style="white-space:pre-wrap"><code>${pull_request.description | trim}</code></td>
141 140 </tr>
142 141 <tr>
143 142 <td style="padding-right:20px;">${_('Changes')}:</td>
144 143 <td>
145 144 <strong>Changed commits:</strong>
146 145 <ul class="changes-ul">
147 146 <li>- Added: ${len(added_commits)}</li>
148 147 <li>- Removed: ${len(removed_commits)}</li>
149 148 </ul>
150 149
151 150 <strong>Changed files:</strong>
152 151 <ul class="changes-ul">
153 152
154 153 %if not changed_files:
155 154 <li>No file changes found</li>
156 155 %else:
157 156 %for file_name in added_files:
158 157 <li>- A <a href="${pull_request_url + '#a_' + h.FID(ancestor_commit_id, file_name)}">${file_name}</a></li>
159 158 %endfor
160 159 %for file_name in modified_files:
161 160 <li>- M <a href="${pull_request_url + '#a_' + h.FID(ancestor_commit_id, file_name)}">${file_name}</a></li>
162 161 %endfor
163 162 %for file_name in removed_files:
164 163 <li>- R <a href="${pull_request_url + '#a_' + h.FID(ancestor_commit_id, file_name)}">${file_name}</a></li>
165 164 %endfor
166 165 %endif
167 166
168 167 </ul>
169 168 </td>
170 169 </tr>
171 170
172 171 </table>
@@ -1,18 +1,17 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2
4 3 <%def name="subject()" filter="n,trim,whitespace_filter">
5 4 Test "Subject" ${_('hello "world"')|n}
6 5 </%def>
7 6
8 7 ## plain text version of the email. Empty by default
9 8 <%def name="body_plaintext()" filter="n,trim">
10 9 Email Plaintext Body
11 10 </%def>
12 11
13 12 ## BODY GOES BELOW
14 13 <strong>Email Body</strong>
15 14 <br/>
16 15 <br/>
17 16 `h.short_id()`: ${h.short_id('0' * 40)}<br/>
18 17 ${_('Translation String')}<br/>
@@ -1,32 +1,31 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2
4 3 <%def name="subject()" filter="n,trim,whitespace_filter">
5 4 New Version of RhodeCode is available !
6 5 </%def>
7 6
8 7 ## plain text version of the email. Empty by default
9 8 <%def name="body_plaintext()" filter="n,trim">
10 9 A new version of RhodeCode is available!
11 10
12 11 Your version: ${current_ver}
13 12 New version: ${latest_ver}
14 13
15 14 Release notes:
16 15
17 16 https://docs.rhodecode.com/RhodeCode-Enterprise/release-notes/release-notes-${latest_ver}.html
18 17 </%def>
19 18
20 19 ## BODY GOES BELOW
21 20
22 21 <h3>A new version of RhodeCode is available!</h3>
23 22 <br/>
24 23 Your version: ${current_ver}<br/>
25 24 New version: <strong>${latest_ver}</strong><br/>
26 25
27 26 <h4>Release notes</h4>
28 27
29 28 <a href="https://docs.rhodecode.com/RhodeCode-Enterprise/release-notes/release-notes-${latest_ver}.html">
30 29 https://docs.rhodecode.com/RhodeCode-Enterprise/release-notes/release-notes-${latest_ver}.html
31 30 </a>
32 31
@@ -1,60 +1,59 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base.mako"/>
3 2 <%namespace name="base" file="base.mako"/>
4 3
5 4 <%def name="subject()" filter="n,trim,whitespace_filter">
6 5 RhodeCode new user registration: ${user.username}
7 6 </%def>
8 7
9 8 <%def name="body_plaintext()" filter="n,trim">
10 9
11 10 A new user `${user.username}` has registered on ${h.format_date(date)}
12 11
13 12 - Username: ${user.username}
14 13 - Full Name: ${user.first_name} ${user.last_name}
15 14 - Email: ${user.email}
16 15 - Profile link: ${h.route_url('user_profile', username=user.username)}
17 16
18 17 ---
19 18 ${self.plaintext_footer()}
20 19 </%def>
21 20
22 21 ## header
23 22 <table style="text-align:left;vertical-align:middle;width: 100%">
24 23 <tr>
25 24 <td style="width:100%;border-bottom:1px solid #dbd9da;">
26 25 <h4 style="margin: 0">
27 26 <a href="${h.route_url('user_profile', username=user.username)}" style="${base.link_css()}">
28 27 ${_('New user {user} has registered on {date}').format(user=user.username, date=h.format_date(date))}
29 28 </a>
30 29 </h4>
31 30 </td>
32 31 </tr>
33 32 </table>
34 33 <div class="clear-both"></div>
35 34 ## main body
36 35 <table style="text-align:left;vertical-align:middle;width: 100%">
37 36 ## spacing def
38 37 <tr>
39 38 <td style="width: 130px"></td>
40 39 <td></td>
41 40 </tr>
42 41 <tr>
43 42 <td style="padding-right:20px;padding-top:20px;">${_('Username')}:</td>
44 43 <td style="line-height:1;padding-top:20px;">${user.username}</td>
45 44 </tr>
46 45 <tr>
47 46 <td style="padding-right:20px;">${_('Full Name')}:</td>
48 47 <td>${user.first_name} ${user.last_name}</td>
49 48 </tr>
50 49 <tr>
51 50 <td style="padding-right:20px;">${_('Email')}:</td>
52 51 <td>${user.email}</td>
53 52 </tr>
54 53 <tr>
55 54 <td style="padding-right:20px;">${_('Profile')}:</td>
56 55 <td>
57 56 <a href="${h.route_url('user_profile', username=user.username)}">${h.route_url('user_profile', username=user.username)}</a>
58 57 </td>
59 58 </tr>
60 59 </table>
@@ -1,112 +1,111 b''
1 ## -*- coding: utf-8 -*-
2 1 <!DOCTYPE html>
3 2 <html xmlns="http://www.w3.org/1999/xhtml">
4 3 <head>
5 4 <title>Error - ${c.error_message}</title>
6 5 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7 6 <meta name="robots" content="index, nofollow"/>
8 7
9 8 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
10 9 %if c.redirect_time:
11 10 <meta http-equiv="refresh" content="${c.redirect_time}; url=${c.url_redirect}"/>
12 11 %endif
13 12
14 13 <link id="favicon" rel="shortcut icon" type="image/png" href="data:image/png;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALMiIiK1OTk5ADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMEsLCz/SUlJ/xUVFcM3NzcAMzMzADMzMwAzMzMAMzMzADMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAM8eHh7/8/Pz//39/f9BQUH/Dw8P0DY2NgMzMzMAMzMzADMzMwAzMzMAAAAAAAAAAAAAAAAAAAAAAAAAAMcjIyP/8vLy////////////9/f3/0RERf8REhTINzc3ADMzMwAzMzMAMzMzAAAAAAAAAAAAAAAAAAAAAKUWFhb/7Ozs///////o6Of/6Onq///////z+v//NUFh/xgaIao3NjIAMzMzADMzMwAAAAAAAAAAAAAAAGgAAAD/0dHR///////o5+X/7O/2/+v5///j5Oj//+ic/92wMv83MB3/Jys2ajMzMwAzMzMAAAAAAAAAABYAAAD4kZGR///////p6er/7Pf//+jv+//my4D/6q0J9PqkAJz/zAAlXlcoeRshOf8zMzMaMzMzAAAAAAAAAACRMDAw///////09fj/6vj//+Xcwv/vtBns/7UAav+8AAP/vgAAyZUKACotNQAtLzXyMzMzsDMzMwAAAAAKAAAA8aSjov//////6PX//+fOif/2qwCH/7YAAKN7EgBsWSQAU0gqAC4wNAAqLTUANTQyZjMzM/8zMzMOAAAAUBMTEv/x8vb/9f///+nLdfL2ogAz/7kAAG5bIwAFFD81Dhs9ShskOU8qLTZMNTQyKTMzMwAzMzP/MzMzZgAAAIVJSEf//////+nRjeb4pQAV/9sAAKiFFQAADkEAMDE0UzQ0M+IzMzOOMzMzvDMzM2QzMzMAMzMz3zMzM6oAAACeXGV9////7/j/yAAe/70AALiDAAA0NTcALDJAADMzMlEzMzPVMzMzgDMzM30zMzMjMzMzADMzM8MzMzPIAAAAnWBlaf//5V86nGYAACgeAAAAAAAABgcNACsrKQA2NjYKMzMzEDMzMwwzMzMGMzMzDDMzMwAzMzPNMzMzvwAAAG0bFQv/JRgHfQAAAB4AAAAAAAAAAAAAAAADAwMAMjIyADY2NgAzMzMAMzMzADMzMxIzMzOKMzMz/zMzM3EAAAADAAAAjAAAAP8AAAD/AAAA/QAAANAAAACZAgICXzExMV82NjaZMzMz0DMzM/wzMzP/MzMz/zMzM5gzMzMAAAAAAAAAAAAAAAAAAAAAOAAAAIoAAADKAAAA9AICAv8xMTH/NjY29DMzM8ozMzOLMzMzODMzMwAzMzMAMzMzAP5/AAD8PwAA+B8AAPAPAADgBwAA4AcAAMAbAACA+QAAgf0AAIf9AAAPjAAAH5wAAD/8AAC/+QAAgYEAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICtjExMbk2NjYAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAM4BAQH/MDAw/zY2NtEzMzMNMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMAAADsAAAA/wEBAf8XFxf/MDAw/zU1Ne4zMzMmMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAA/QAAAP8AAAD/eXl5/56env8ODg7/Jycn/zY2Nv8zMzM6MzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQQAAAP8AAAD/AAAA/4SEhP///////////6Ghof8QEBD/IiIi/zc3N/8zMzNFMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEAAAD/AAAA/wAAAP+bm5v//////+/v7//u7u7//////7S0tP8VFRX/ICAg/zc3N/8zMzNFMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3AAAA/wAAAP8AAAD/p6en///////u7u7/6urq/+rq6v/t7e3//////729vf8WFhb/ICAg/zc3N/8zMzM6MzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAPgAAAD/AAAA/6ampv//////7e3t/+rq6v/r6+v/6+vr/+rq6v/s7Oz//////729vf8UFBT/IyMj/zY2NvozMzMlMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAADdAAAA/wAAAP+ampr//////+3t7f/q6ur/6+vr/+vr6//r6+v/6+vr/+rq6v/s7Oz//////7Kysf8PDw//KSkp/zU1NeAzMzMIMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsQAAAP8AAAD/f39////////u7u7/6urq/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+rq6f/t7e///////5ynwf8KEy3/MC8t/zQ0M7UzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHUAAAD/AAAA/1paWv//////8vLy/+rq6v/r6+v/6+vr/+vr6//r6+v/6+vr/+vq6f/r7PD/7/f//+v3///o6Oj//+mZ/3FcJv8OGDL/NjUy/zMzM3ozMzMAMzMzADMzMwAzMzMAMzMzAAAAAAAAAAAAAAAAAAAAAAAAAAAuAAAA/wAAAP8sLCz///////v7+//p6en/6+vr/+vr6//r6+v/6+vr/+vq6f/r6+7/7/j//+r2///h2sf/37tY/9+iA//zpgD//74A/2BRJv8eJTn/MzMz/zMzMzIzMzMAMzMzADMzMwAzMzMAAAAAAAAAAAAAAAAAAAAAAAAAAMUAAAD/AAAA/9DQ0P//////6Ojo/+vr6//r6+v/6+vr/+vr6v/r6uv/7vX+/+v4///i2sb/4LZC/+OfAP/sngD/9K0A/fCuALz/zgBgoIMYRRAZPPUzMzP/MzMzyTMzMwAzMzMAMzMzADMzMwAAAAAAAAAAAAAAAAAAAABfAAAA/wAAAP9+fn7//////+np6f/r6+v/6+vr/+vr6//r6uj/7O/z/+36///k5OH/4btP/+WfAP/voQD/9K8AyvCwAGTvrgAQ764AAP/CAABrWSUAFyA6eTMzM/8zMzP/MzMzYzMzMwAzMzMAMzMzAAAAAAAAAAAAAAAAAAAAAN4AAAD/HR0d//r6+v/4+Pj/6urq/+vr6//r6+v/6+rp/+31///o9P//4sqI/+SjAP/unwD/9K8Aou+vACjurgAA8K8AAPayAAD/xAAA6K0FACwuNAArLjUAMzMz2jMzM/8zMzPiMzMzADMzMwAzMzMAAAAAAAAAAAAAAABgAAAA/wAAAP+dnZ3//////+jo6P/r6+v/6+rq/+zr7f/t+f//5ebi/+OzMv/rnQD/8aoAnfKxABT/ugAA/8IAAP/EAAD/wQAA/LYAAP+5AACNbhoAEh48ADU0MwAzMzNaMzMz/zMzM/8zMzNkMzMzADMzMwAAAAAAAAAAAAAAAMgAAAD/IiIi//z8/P/09PT/6+vr/+vq6f/s7fD/6/r//+TYsf/npQP/8aEAwe+tAB34uAAA/8MAAN+iBAC+jg0Apn8TAHJcIgBYSykAPDkwACcrNgAxMjQAMzMzADMzMwAzMzPYMzMz/zMzM8wzMzMAMzMzAAAAAAAAAAAwAAAA/wAAAP+Hh4f//////+np6f/r6un/7O/z/+r4///lzIf/658A+/KoAFburQAA/8EAAP+/AACCZR0AKSw2ABwkOQAWIDsAEBw8ABoiOgAjKDcALzA0ADU0MgAzMzMAMzMzADMzM3AzMzP/MzMz/zMzMzQzMzMAAAAAAAAAAHoAAAD/AAAA/9ra2v//////6+rp/+zv8//q+P//5cdy/+2eAMvyqwAP7KwAAP+/AADqrQMAUEUrAAcWPwAkKTcAMDE0ADIyMwA0MzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzGTMzM/8zMzP/MzMzfzMzMwAAAAAkAAAAvgAAAP8+Pj7//////+3s6//s7fD/6vj//+fIdP/ungCa8a0AAO6uAAD+uAAA6q0DADAxMwAMGT4ANTQzCDQ0M8gzMzOOMzMzKjMzM8QzMzOQMzMz1DMzM0szMzO9MzMzSTMzMwAzMzMAMzMzvDMzM/8zMzPCMzMzJwAAAFMAAADsAAAA/3d3d///////6urq/+r5///nz4v/7p4AffGsAADvrwAA7asAAP/OAACUdRoAABBAADc1MgAzMzMAMzMzyzMzM6QzMzOFMzMzyDMzM0AzMzPXMzMzLzMzM+gzMzMcMzMzADMzMwAzMzOAMzMz/zMzM+8zMzNXAAAAegAAAP8AAAD/mJiY///////r9///6dyz/+6hAHfwqwAA768AAO2sAAD/vgAA8LQDADUzMgAmKjcAMzMzADMzMwAzMzOdMzMz4zMzM+szMzN4MzMzADMzM+UzMzPPMzMz1DMzMwAzMzMAMzMzADMzM1ozMzP/MzMz/zMzM3wAAACUAAAA/wAAAP+traz//////+ns5//uqguL8KcAAO2tAAD5tAAA/9IAAP/UAABoVCkADho8ADc2MgAzMzMAMzMzADMzM8IzMzOoMzMzdjMzM9ozMzMkMzMz5TMzM5QzMzMmMzMzADMzMwAzMzMAMzMzQjMzM/8zMzP/MzMzkwAAAJ4AAAD/AAAA/7S1tv//////7L5RtfCfAAD8uwAA/9MAAPy9AACxfQAASTgLABYhPwA+Pj0ANDQzADIyMgAzMzMGMzMzwzMzM8kzMzPNMzMzRDMzM24zMzPiMzMzADMzMyEzMzNTMzMzFDMzMwAzMzM5MzMz/zMzM/8zMzOaAAAAlAAAAP8AAAD/q7fS///80O//tgAQ/9MAAPSzAACUagAAIBcAAAAAAAAAAAAABwcHACcnJgA9PT0AOjo6ADIyMgEzMzMBMzMzATMzMwEzMzMAMzMzEDMzMwYzMzMAMzMzRjMzM1wzMzMSMzMzADMzM0IzMzP/MzMz/zMzM5MAAAB5AAAA/wAAAP+fp6r///5ZR96WAAB0VQAADgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDwAvLy8ANjY2ADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMBMzMzATMzMwAzMzMAMzMzWzMzM/8zMzP/MzMzegAAAE0AAADmAAAA/1BDKeFvUA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAzMzMANjY2ADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzOrMzMz/zMzM+ozMzNRAAAAEgAAAKkAAAD/AAAA/wAAAPUAAACnAAAAVgAAABEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICADExMQA2NjYAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzDzMzM1UzMzOlMzMz9TMzM/8zMzP/MzMzrjMzMxYAAAAAAAAAMAAAAOoAAAD/AAAA/wAAAP8AAAD/AAAA/QAAAMgAAACQAAAAXgAAADEAAAAKAAAAAAAAAAACAgIAMTExADY2NgAzMzMAMzMzCTMzMzEzMzNdMzMzjzMzM8czMzP8MzMz/zMzM/8zMzP/MzMz/zMzM+wzMzMzMzMzAAAAAAAAAAAAAAAAAAAAAD0AAACaAAAA5wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPYAAADPAAAArAICAoQxMTGDNjY2qzMzM88zMzP1MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz6TMzM5wzMzM/MzMzADMzMwAzMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgAAAHQAAACvAAAA5QAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/zExMf82Njb/MzMz/zMzM/8zMzP/MzMz/zMzM+UzMzOvMzMzdjMzMzQzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIgAAAFEAAAB7AAAAowAAAMYCAgLqMTEx6zY2NsczMzOkMzMzfDMzM1EzMzMjMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzADMzMwAzMzMAMzMzAP/+f////D////gf///wD///4Af//8AD//+AAf//AAD//gAAf/wAAD/8AAA/+AAAH/AAAY/wAA/P4AA/x+AA/+fAA//jwA//88Af//OAP5FxgP+FcYH/jHkB/5T4A/+N+Af///iP///5j///8YP//8HAP/wD8AAAD/8AAP//+B//">
15 14 <script src="${h.asset('js/vendors/webcomponentsjs/custom-elements-es5-adapter.js', ver=c.rhodecode_version_hash)}"></script>
16 15 <script src="${h.asset('js/vendors/webcomponentsjs/webcomponents-bundle.js', ver=c.rhodecode_version_hash)}"></script>
17 16
18 17 <link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/>
19 18 <style>body { background:#eeeeee; }</style>
20 19 <script type="text/javascript">
21 20 // register templateContext to pass template variables to JS
22 21 var templateContext = {timeago: {}};
23 22 </script>
24 23 <%include file="/base/plugins_base.mako"/>
25 24 <script type="text/javascript" src="${h.asset('js/scripts.min.js', ver=c.rhodecode_version_hash)}"></script>
26 25 </head>
27 26 <body>
28 27
29 28 <div class="wrapper error_page">
30 29 <div class="sidebar">
31 30 <a href="${h.route_path('home')}"><img class="error-page-logo" src="${h.asset('images/RhodeCode_Logo_Black.png')}" alt="RhodeCode"/></a>
32 31 </div>
33 32 <div class="main-content">
34 33 <h1>
35 34 <span class="error-branding">
36 35 ${h.branding(c.rhodecode_name)}
37 36 </span><br/>
38 37 ${c.error_message}
39 38 <br/>
40 39 <span class="error_message">${c.error_explanation}</span>
41 40 </h1>
42 41 % if c.messages:
43 42 % for message in c.messages:
44 43 <div class="alert alert-${message.category}">${message}</div>
45 44 % endfor
46 45 % endif
47 46 %if c.redirect_time:
48 47 <p>${_('You will be redirected to %s in %s seconds') % (c.redirect_module,c.redirect_time)}</p>
49 48 %endif
50 49 <div class="inner-column">
51 50 <h4>Possible Causes</h4>
52 51 <ul>
53 52 % if c.causes:
54 53 %for cause in c.causes:
55 54 <li>${cause}</li>
56 55 %endfor
57 56 %else:
58 57 <li>The resource may have been deleted.</li>
59 58 <li>You may not have access to this repository.</li>
60 59 <li>The link may be incorrect.</li>
61 60 %endif
62 61 </ul>
63 62 </div>
64 63 <div class="inner-column">
65 64 <h4>Support</h4>
66 65 <p>For help and support, go to the <a href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support Page')}</a>.
67 66 It may be useful to include your log file; see the log file locations <a href="${h.route_url('enterprise_log_file_locations')}">here</a>.
68 67 </p>
69 68
70 69 </div>
71 70 <div class="inner-column">
72 71 <h4>Documentation</h4>
73 72 <p>For more information, see <a href="${h.route_url('enterprise_docs')}">docs.rhodecode.com</a>.</p>
74 73 </div>
75 74 </div>
76 75
77 76 % if c.show_exception_id:
78 77 <div class="sidebar" style="width: 130px">
79 78
80 79 </div>
81 80 <div class="main-content">
82 81 <p>
83 82 <strong>Exception ID: <code><a href="${c.exception_id_url}">${c.exception_id}</a></code> </strong> <br/>
84 83
85 84 Super-admins can see details of the above error in the exception tracker found under
86 85 <a href="${h.route_url('admin_settings_exception_tracker')}">admin > settings > exception tracker</a>.
87 86
88 87 % if c.exception_debug:
89 88 <pre>
90 89 <strong>DEBUG MODE ON FOR EXCEPTION: ${c.exception_id}</strong>
91 90 <strong>REQUEST_ID: ${getattr(request, 'req_id', None)}</strong>
92 91 ----------------
93 92 debug mode is controlled by
94 93 ${c.exception_config_ini}
95 94 file settings:
96 95
97 96 debug = true
98 97 ----------------
99 98
100 99 % for rec in getattr(request, 'req_id_bucket', []):
101 100 ${rec}
102 101 % endfor
103 102 </pre>
104 103 % endif
105 104 </p>
106 105 </div>
107 106 % endif
108 107 </div>
109 108
110 109 </body>
111 110
112 111 </html>
@@ -1,38 +1,37 b''
1 ## -*- coding: utf-8 -*-
2 1
3 2 ${_('%(user)s committed on %(date)s UTC') % {
4 3 'user': h.person(commit.author),
5 4 'date': h.format_date(commit.date)
6 5 }}
7 6 <br/>
8 7 % if commit.branch:
9 8 branch: ${commit.branch} <br/>
10 9 % endif
11 10
12 11 % for bookmark in getattr(commit, 'bookmarks', []):
13 12 bookmark: ${bookmark} <br/>
14 13 % endfor
15 14
16 15 % for tag in commit.tags:
17 16 tag: ${tag} <br/>
18 17 % endfor
19 18
20 19 % if has_hidden_changes:
21 20 Has hidden changes<br/>
22 21 % endif
23 22
24 23 commit: <a href="${h.route_url('repo_commit', repo_name=c.rhodecode_db_repo.repo_name, commit_id=commit.raw_id)}">${h.show_id(commit)}</a>
25 24 <pre>
26 25 ${h.urlify_commit_message(commit.message)}
27 26
28 27 % for change in parsed_diff:
29 28 % if limited_diff:
30 29 ${_('Commit was too big and was cut off...')}
31 30 % endif
32 31 ${change['operation']} ${change['filename']} ${'(%(added)s lines added, %(removed)s lines removed)' % {'added': change['stats']['added'], 'removed': change['stats']['deleted']}}
33 32 % endfor
34 33
35 34 % if feed_include_diff:
36 35 ${c.path_filter.get_raw_patch(diff_processor)}
37 36 % endif
38 37 </pre>
@@ -1,124 +1,123 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Fork repository %s') % c.repo_name}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='repositories')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.repo_menu(active='options')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21 <div class="box">
23 22 ${h.secure_form(h.route_path('repo_fork_create',repo_name=c.rhodecode_db_repo.repo_name), request=request)}
24 23 <div class="form">
25 24 <!-- fields -->
26 25 <div class="fields">
27 26
28 27 <div class="field">
29 28 <div class="label">
30 29 <label for="repo_name">${_('Fork name')}:</label>
31 30 </div>
32 31 <div class="input">
33 32 ${h.text('repo_name', class_="medium")}
34 33 ${h.hidden('repo_type',c.rhodecode_db_repo.repo_type)}
35 34 ${h.hidden('fork_parent_id',c.rhodecode_db_repo.repo_id)}
36 35 </div>
37 36 </div>
38 37
39 38 <div class="field">
40 39 <div class="label">
41 40 <label for="repo_group">${_('Repository group')}:</label>
42 41 </div>
43 42 <div class="select">
44 43 ${h.select('repo_group','',c.repo_groups,class_="medium")}
45 44 % if c.personal_repo_group:
46 45 <a class="btn" href="#" id="select_my_group" data-personal-group-id="${c.personal_repo_group.group_id}">
47 46 ${_('Select my personal group (%(repo_group_name)s)') % {'repo_group_name': c.personal_repo_group.group_name}}
48 47 </a>
49 48 % endif
50 49 <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
51 50 </div>
52 51 </div>
53 52
54 53 <div class="field">
55 54 <div class="label label-textarea">
56 55 <label for="description">${_('Description')}:</label>
57 56 </div>
58 57 <div class="textarea editor">
59 58 ${h.textarea('description',cols=23,rows=5,class_="medium")}
60 59 <% metatags_url = h.literal('''<a href="#metatagsShow" onclick="$('#meta-tags-desc').toggle();return false">meta-tags</a>''') %>
61 60 <span class="help-block">
62 61 % if c.visual.stylify_metatags:
63 62 ${_('Plain text format with {metatags} support.').format(metatags=metatags_url)|n}
64 63 % else:
65 64 ${_('Plain text format.')}
66 65 % endif
67 66 ${_('Add a README file for longer descriptions')}
68 67 </span>
69 68 <span id="meta-tags-desc" style="display: none">
70 69 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
71 70 ${dt.metatags_help()}
72 71 </span>
73 72 </div>
74 73 </div>
75 74
76 75 <div class="field">
77 76 <div class="label label-checkbox">
78 77 <label for="private">${_('Copy permissions')}:</label>
79 78 </div>
80 79 <div class="checkboxes">
81 80 ${h.checkbox('copy_permissions',value="True", checked="checked")}
82 81 <span class="help-block">${_('Copy permissions from parent repository.')}</span>
83 82 </div>
84 83 </div>
85 84
86 85 <div class="field">
87 86 <div class="label label-checkbox">
88 87 <label for="private">${_('Private')}:</label>
89 88 </div>
90 89 <div class="checkboxes">
91 90 ${h.checkbox('private',value="True")}
92 91 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
93 92 </div>
94 93 </div>
95 94
96 95 <div class="buttons">
97 96 ${h.submit('',_('Fork this Repository'),class_="btn")}
98 97 </div>
99 98 </div>
100 99 </div>
101 100 ${h.end_form()}
102 101 </div>
103 102 <script>
104 103 $(document).ready(function(){
105 104 $("#repo_group").select2({
106 105 'dropdownAutoWidth': true,
107 106 'containerCssClass': "drop-menu",
108 107 'dropdownCssClass': "drop-menu-dropdown",
109 108 'width': "resolve"
110 109 });
111 110 $("#landing_rev").select2({
112 111 'containerCssClass': "drop-menu",
113 112 'dropdownCssClass': "drop-menu-dropdown",
114 113 'minimumResultsForSearch': -1
115 114 });
116 115 $('#repo_name').focus();
117 116
118 117 $('#select_my_group').on('click', function(e){
119 118 e.preventDefault();
120 119 $("#repo_group").val($(this).data('personalGroupId')).trigger("change");
121 120 })
122 121 })
123 122 </script>
124 123 </%def>
@@ -1,104 +1,103 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('%s Forks') % c.repo_name}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs_links()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='repositories')}
15 14 </%def>
16 15
17 16 <%def name="menu_bar_subnav()">
18 17 ${self.repo_menu(active='summary')}
19 18 </%def>
20 19
21 20 <%def name="main()">
22 21 <div class="box">
23 22 <div class="title">
24 23
25 24 <ul class="links">
26 25 <li>
27 26 <a class="btn btn-small btn-success" href="${h.route_path('repo_fork_new',repo_name=c.repo_name)}">
28 27 ${_('Create new fork')}
29 28 </a>
30 29 </li>
31 30 </ul>
32 31 </div>
33 32
34 33 <div id="fork_list_wrap">
35 34 <table id="fork_list_table" class="display"></table>
36 35 </div>
37 36 </div>
38 37
39 38
40 39
41 40 <script type="text/javascript">
42 41
43 42 $(document).ready(function() {
44 43 var $forksListTable = $('#fork_list_table');
45 44
46 45 // fork list
47 46 $forksListTable.DataTable({
48 47 processing: true,
49 48 serverSide: true,
50 49 ajax: {
51 50 "url": "${h.route_path('repo_forks_data', repo_name=c.repo_name)}",
52 51 },
53 52 dom: 'rtp',
54 53 pageLength: ${c.visual.dashboard_items},
55 54 order: [[ 0, "asc" ]],
56 55 columns: [
57 56 { data: {"_": "username",
58 57 "sort": "username"}, title: "${_('Owner')}", className: "td-user" },
59 58 { data: {"_": "fork_name",
60 59 "sort": "fork_name"}, title: "${_('Fork name')}", className: "td-email" },
61 60 { data: {"_": "description",
62 61 "sort": "description"}, title: "${_('Description')}", className: "td-user" },
63 62 { data: {"_": "fork_date",
64 63 "sort": "fork_date"}, title: "${_('Forked')}", className: "td-user" },
65 64 { data: {"_": "last_activity",
66 65 "sort": "last_activity",
67 66 "type": Number}, title: "${_('Last activity')}", className: "td-time" },
68 67 { data: {"_": "action",
69 68 "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false }
70 69 ],
71 70
72 71 language: {
73 72 paginate: DEFAULT_GRID_PAGINATION,
74 73 sProcessing: _gettext('loading...'),
75 74 emptyTable: _gettext("No forks available yet.")
76 75 },
77 76
78 77 "createdRow": function ( row, data, index ) {
79 78 if (!data['active_raw']){
80 79 $(row).addClass('closed')
81 80 }
82 81 }
83 82 });
84 83
85 84 $forksListTable.on('xhr.dt', function(e, settings, json, xhr){
86 85 $forksListTable.css('opacity', 1);
87 86 });
88 87
89 88 $forksListTable.on('preXhr.dt', function(e, settings, data){
90 89 $forksListTable.css('opacity', 0.3);
91 90 });
92 91
93 92 // filter
94 93 $('#q_filter').on('keyup',
95 94 $.debounce(250, function() {
96 95 $forksListTable.DataTable().search(
97 96 $('#q_filter').val()
98 97 ).draw();
99 98 })
100 99 );
101 100
102 101 });
103 102 </script>
104 103 </%def>
@@ -1,15 +1,14 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="index_base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Dashboard')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs()"></%def>
12 11
13 12 <%def name="menu_bar_nav()">
14 13 ${self.menu_items(active='repositories')}
15 14 </%def>
@@ -1,23 +1,22 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="index_base.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('%s Repository group dashboard') % c.repo_group.group_name}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9
11 10 <%def name="breadcrumbs()">
12 11 <span class="groups_breadcrumbs">
13 12 ${h.link_to(_(u'Home'), h.route_path('home'))}
14 13 %if c.repo_group.parent_group:
15 14 &raquo; ${h.link_to(c.repo_group.parent_group.name, h.route_path('repo_group_home', repo_group_name=c.repo_group.parent_group.group_name))}
16 15 %endif
17 16 &raquo; ${c.repo_group.name}
18 17 </span>
19 18 </%def>
20 19
21 20 <%def name="menu_bar_nav()">
22 21 ${self.menu_items(active='repositories')}
23 22 </%def>
@@ -1,52 +1,51 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2 <%def name="title()">
4 3 ${_('Journal')}
5 4 %if c.rhodecode_name:
6 5 &middot; ${h.branding(c.rhodecode_name)}
7 6 %endif
8 7 </%def>
9 8
10 9 <%def name="breadcrumbs_links()">
11 10 ${h.form(None, id_="filter_form", method="get")}
12 11 <input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term}" placeholder="${_('quick filter...')}"/>
13 12 <input type='submit' value="${_('filter')}" class="btn" />
14 13 ${_('Journal')} - ${_ungettext('%s entry', '%s entries', c.journal_pager.item_count) % (c.journal_pager.item_count)}
15 14 ${h.end_form()}
16 15 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p>
17 16 <pre id="search-help" style="display: none">${h.tooltip(h.journal_filter_help(request))}</pre>
18 17 </%def>
19 18
20 19 <%def name="menu_bar_nav()">
21 20 ${self.menu_items(active='journal')}
22 21 </%def>
23 22
24 23 <%def name="head_extra()">
25 24 <link href="${h.route_path('journal_atom', _query=dict(auth_token=c.rhodecode_user.feed_token))}" rel="alternate" title="${_('ATOM journal feed')}" type="application/atom+xml" />
26 25 <link href="${h.route_path('journal_rss', _query=dict(auth_token=c.rhodecode_user.feed_token))}" rel="alternate" title="${_('RSS journal feed')}" type="application/rss+xml" />
27 26 </%def>
28 27
29 28 <%def name="main()">
30 29
31 30 <div class="box">
32 31 <!-- box / title -->
33 32 <div class="title journal">
34 33 ${self.breadcrumbs()}
35 34 <ul class="links icon-only-links block-right">
36 35 <li>
37 36 <span><a id="refresh" href="${h.route_path('journal')}"><i class="icon-refresh"></i></a></span>
38 37 </li>
39 38 <li>
40 39 <span>
41 40 <a href="${h.route_path('journal_atom', _query=dict(auth_token=c.rhodecode_user.feed_token))}" title="RSS Feed" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
42 41 </span>
43 42 </li>
44 43 </ul>
45 44 </div>
46 45 <div id="journal">${c.journal_data|n}</div>
47 46 </div>
48 47
49 48 <script type="text/javascript">
50 49 $('#j_filter').autoGrowInput();
51 50 </script>
52 51 </%def>
@@ -1,47 +1,46 b''
1 ## -*- coding: utf-8 -*-
2 1 <%namespace name="base" file="/base/base.mako"/>
3 2
4 3 %if c.journal_day_aggreagate:
5 4 %for day,items in c.journal_day_aggreagate:
6 5 <div class="journal_day">${day}</div>
7 6 % for user,entries in items:
8 7 <div class="journal_container">
9 8 ${base.gravatar(user.email if user else '', 30)}
10 9 %if user:
11 10 <div class="journal_user user">${h.link_to_user(user.username)}</div>
12 11 %else:
13 12 <div class="journal_user user deleted">${entries[0].username}</div>
14 13 %endif
15 14 <div class="journal_action_container">
16 15 % for entry in entries:
17 16 <div class="journal_icon"> ${h.action_parser(request, entry)[2]()}</div>
18 17 <div class="journal_action">${h.action_parser(request, entry)[0]()}</div>
19 18 <div class="journal_repo">
20 19 <span class="journal_repo_name">
21 20 %if entry.repository is not None:
22 21 ${h.link_to(entry.repository.repo_name,
23 22 h.route_path('repo_summary',repo_name=entry.repository.repo_name))}
24 23 %else:
25 24 ${entry.repository_name}
26 25 %endif
27 26 </span>
28 27 </div>
29 28 <div class="journal_action_params">${h.literal(h.action_parser(request, entry)[1]())}</div>
30 29 <div class="date">
31 30 ${h.age_component(entry.action_date, time_is_local=True)}
32 31 </div>
33 32 %endfor
34 33 </div>
35 34 </div>
36 35 %endfor
37 36 %endfor
38 37
39 38 <div class="pagination-wh pagination-left">
40 39 ${c.journal_pager.render()}
41 40 </div>
42 41
43 42 %else:
44 43 <div>
45 44 ${_('No entries yet')}
46 45 </div>
47 46 %endif
@@ -1,43 +1,42 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2 <%def name="title()">
4 3 ${_('Public Journal')}
5 4 %if c.rhodecode_name:
6 5 &middot; ${h.branding(c.rhodecode_name)}
7 6 %endif
8 7 </%def>
9 8
10 9 <%def name="breadcrumbs()">
11 10 <h1 class="block-left">
12 11 ${_('Public Journal')} - ${_ungettext('%s entry', '%s entries', c.journal_pager.item_count) % (c.journal_pager.item_count)}
13 12 </h1>
14 13 </%def>
15 14
16 15 <%def name="menu_bar_nav()">
17 16 ${self.menu_items(active='journal')}
18 17 </%def>
19 18
20 19 <%def name="head_extra()">
21 20 <link href="${h.route_path('journal_public_atom')}" rel="alternate" title="${_('ATOM public journal feed')}" type="application/atom+xml" />
22 21 <link href="${h.route_path('journal_public_rss')}" rel="alternate" title="${_('RSS public journal feed')}" type="application/rss+xml" />
23 22 </%def>
24 23
25 24 <%def name="main()">
26 25
27 26 <div class="box">
28 27 <!-- box / title -->
29 28 <div class="title journal">
30 29 ${self.breadcrumbs()}
31 30
32 31 <ul class="links icon-only-links block-right">
33 32 <li>
34 33 <span>
35 34 <a href="${h.route_path('journal_public_atom')}"> <i class="icon-rss-sign" ></i></a>
36 35 </span>
37 36 </li>
38 37 </ul>
39 38 </div>
40 39 <div id="journal">${c.journal_data|n}</div>
41 40 </div>
42 41
43 42 </%def>
@@ -1,106 +1,105 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base/root.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Sign In')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9 <style>body{background-color:#eeeeee;}</style>
11 10
12 11 <div class="loginbox">
13 12 <div class="header-account">
14 13 <div id="header-inner" class="title">
15 14 <div id="logo">
16 15 <div class="logo-wrapper">
17 16 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
18 17 </div>
19 18 % if c.rhodecode_name:
20 19 <div class="branding">
21 20 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
22 21 </div>
23 22 % endif
24 23 </div>
25 24 </div>
26 25 </div>
27 26
28 27 <div class="loginwrapper">
29 28 <rhodecode-toast id="notifications"></rhodecode-toast>
30 29
31 30 <div class="auth-image-wrapper">
32 31 <img class="sign-in-image" src="${h.asset('images/sign-in.png')}" alt="RhodeCode"/>
33 32 </div>
34 33
35 34 <div id="login">
36 35 <%block name="above_login_button" />
37 36 <!-- login -->
38 37 <div class="sign-in-title">
39 38 <h1>${_('Sign In using username/password')}</h1>
40 39 </div>
41 40 <div class="inner form">
42 41 ${h.form(request.route_path('login', _query={'came_from': c.came_from}), needs_csrf_token=False)}
43 42
44 43 <label for="username">${_('Username')}:</label>
45 44 ${h.text('username', class_='focus', value=defaults.get('username'))}
46 45 %if 'username' in errors:
47 46 <span class="error-message">${errors.get('username')}</span>
48 47 <br />
49 48 %endif
50 49
51 50 <label for="password">${_('Password')}:
52 51 %if h.HasPermissionAny('hg.password_reset.enabled')():
53 52 <div class="pull-right">${h.link_to(_('Forgot your password?'), h.route_path('reset_password'), class_='pwd_reset', tabindex="-1")}</div>
54 53 %endif
55 54
56 55 </label>
57 56 ${h.password('password', class_='focus')}
58 57 %if 'password' in errors:
59 58 <span class="error-message">${errors.get('password')}</span>
60 59 <br />
61 60 %endif
62 61
63 62 ${h.checkbox('remember', value=True, checked=defaults.get('remember'))}
64 63 <% timeout = request.registry.settings.get('beaker.session.timeout', '0') %>
65 64 % if timeout == '0':
66 65 <% remember_label = _('Remember my indefinitely') %>
67 66 % else:
68 67 <% remember_label = _('Remember me for {}').format(h.age_from_seconds(timeout)) %>
69 68 % endif
70 69 <label class="checkbox" for="remember">${remember_label}</label>
71 70
72 71 <p class="links">
73 72 %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
74 73 ${h.link_to(_("Create a new account."), request.route_path('register'), class_='new_account')}
75 74 %endif
76 75 </p>
77 76
78 77 %if not h.HasPermissionAny('hg.password_reset.enabled')():
79 78 ## password reset hidden or disabled.
80 79 <p class="help-block">
81 80 ${_('Password reset is disabled.')} <br/>
82 81 ${_('Please contact ')}
83 82 % if c.visual.rhodecode_support_url:
84 83 <a href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a>
85 84 ${_('or')}
86 85 % endif
87 86 ${_('an administrator if you need help.')}
88 87 </p>
89 88 %endif
90 89
91 90 ${h.submit('sign_in', _('Sign In'), class_="btn sign-in", title=_('Sign in to {}').format(c.rhodecode_edition))}
92 91
93 92 ${h.end_form()}
94 93 <script type="text/javascript">
95 94 $(document).ready(function(){
96 95 $('#username').focus();
97 96 })
98 97 </script>
99 98
100 99 </div>
101 100 <!-- end login -->
102 101
103 102 <%block name="below_login_button" />
104 103 </div>
105 104 </div>
106 105 </div>
@@ -1,104 +1,103 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base/root.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Reset Password')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9 <style>body{background-color:#eeeeee;}</style>
11 10
12 11 <div class="loginbox">
13 12 <div class="header-account">
14 13 <div id="header-inner" class="title">
15 14 <div id="logo">
16 15 <div class="logo-wrapper">
17 16 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
18 17 </div>
19 18 % if c.rhodecode_name:
20 19 <div class="branding">
21 20 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
22 21 </div>
23 22 % endif
24 23 </div>
25 24 </div>
26 25 </div>
27 26
28 27 <div class="loginwrapper">
29 28 <rhodecode-toast id="notifications"></rhodecode-toast>
30 29
31 30 <div class="auth-image-wrapper">
32 31 <img class="sign-in-image" src="${h.asset('images/sign-in.png')}" alt="RhodeCode"/>
33 32 </div>
34 33
35 34 %if h.HasPermissionAny('hg.password_reset.disabled')():
36 35 <div class="right-column">
37 36 <p>
38 37 ${_('Password reset is disabled. Please contact ')}
39 38 % if c.visual.rhodecode_support_url:
40 39 <a href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a>
41 40 ${_('or')}
42 41 % endif
43 42 ${_('an administrator if you need help.')}
44 43 </p>
45 44 </div>
46 45 %else:
47 46 <div id="register">
48 47 <!-- login -->
49 48 <div class="sign-in-title">
50 49 <h1>${_('Reset your Password')}</h1>
51 50 <h4>${h.link_to(_("Go to the login page to sign in."), request.route_path('login'))}</h4>
52 51 </div>
53 52 <div class="inner form">
54 53 ${h.form(request.route_path('reset_password'), needs_csrf_token=False)}
55 54 <label for="email">${_('Email Address')}:</label>
56 55 ${h.text('email', defaults.get('email'))}
57 56 %if 'email' in errors:
58 57 <span class="error-message">${errors.get('email')}</span>
59 58 <br />
60 59 %endif
61 60 <p class="help-block">${_('Password reset link will be sent to matching email address')}</p>
62 61
63 62 %if captcha_active:
64 63 <div class="login-captcha">
65 64 <label for="email">${_('Captcha')}:</label>
66 65 ${h.hidden('recaptcha_field')}
67 66 <div id="recaptcha"></div>
68 67
69 68 %if 'recaptcha_field' in errors:
70 69 <span class="error-message">${errors.get('recaptcha_field')}</span>
71 70 <br />
72 71 %endif
73 72 </div>
74 73 %endif
75 74
76 75 ${h.submit('send', _('Send password reset email'), class_="btn sign-in")}
77 76 <p class="help-block pull-right">
78 77 RhodeCode ${c.rhodecode_edition}
79 78 </p>
80 79
81 80 ${h.end_form()}
82 81 </div>
83 82 </div>
84 83 %endif
85 84 </div>
86 85 </div>
87 86
88 87 <script type="text/javascript">
89 88 $(document).ready(function(){
90 89 $('#email').focus();
91 90 });
92 91 </script>
93 92
94 93 % if captcha_active:
95 94 <script type="text/javascript">
96 95 var onloadCallback = function() {
97 96 grecaptcha.render('recaptcha', {
98 97 'sitekey' : "${captcha_public_key}"
99 98 });
100 99 };
101 100 </script>
102 101 <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
103 102 % endif
104 103
@@ -1,150 +1,149 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="base/root.mako"/>
3 2
4 3 <%def name="title()">
5 4 ${_('Create an Account')}
6 5 %if c.rhodecode_name:
7 6 &middot; ${h.branding(c.rhodecode_name)}
8 7 %endif
9 8 </%def>
10 9 <style>body{background-color:#eeeeee;}</style>
11 10
12 11 <div class="loginbox">
13 12 <div class="header-account">
14 13 <div id="header-inner" class="title">
15 14 <div id="logo">
16 15 <div class="logo-wrapper">
17 16 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
18 17 </div>
19 18 % if c.rhodecode_name:
20 19 <div class="branding">
21 20 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
22 21 </div>
23 22 % endif
24 23 </div>
25 24 </div>
26 25 </div>
27 26
28 27 <div class="loginwrapper">
29 28 <rhodecode-toast id="notifications"></rhodecode-toast>
30 29
31 30 <div class="auth-image-wrapper">
32 31 <img class="sign-in-image" src="${h.asset('images/sign-in.png')}" alt="RhodeCode"/>
33 32 </div>
34 33
35 34 <div id="register">
36 35 <%block name="above_register_button" />
37 36 <!-- login -->
38 37 <div class="sign-in-title">
39 38 % if external_auth_provider:
40 39 <h1>${_('Create an account linked with {}').format(external_auth_provider)}</h1>
41 40 % else:
42 41 <h1>${_('Create an account')}</h1>
43 42 % endif
44 43
45 44 <h4>${h.link_to(_("Go to the login page to sign in with an existing account."), request.route_path('login'))}</h4>
46 45 </div>
47 46 <div class="inner form">
48 47 ${h.form(request.route_path('register'), needs_csrf_token=False)}
49 48
50 49 <label for="username">${_('Username')}:</label>
51 50 ${h.text('username', defaults.get('username'))}
52 51 %if 'username' in errors:
53 52 <span class="error-message">${errors.get('username')}</span>
54 53 <br />
55 54 %endif
56 55
57 56 % if external_auth_provider:
58 57 ## store internal marker about external identity
59 58 ${h.hidden('external_identity', external_auth_provider)}
60 59 ## hide password prompts for social auth
61 60 <div style="display: none">
62 61 % endif
63 62
64 63 <label for="password">${_('Password')}:</label>
65 64 ${h.password('password', defaults.get('password'))}
66 65 %if 'password' in errors:
67 66 <span class="error-message">${errors.get('password')}</span>
68 67 <br />
69 68 %endif
70 69
71 70 <label for="password_confirmation">${_('Re-enter password')}:</label>
72 71 ${h.password('password_confirmation', defaults.get('password_confirmation'))}
73 72 %if 'password_confirmation' in errors:
74 73 <span class="error-message">${errors.get('password_confirmation')}</span>
75 74 <br />
76 75 %endif
77 76
78 77 % if external_auth_provider:
79 78 ## hide password prompts for social auth
80 79 </div>
81 80 % endif
82 81
83 82 <label for="firstname">${_('First Name')}:</label>
84 83 ${h.text('firstname', defaults.get('firstname'))}
85 84 %if 'firstname' in errors:
86 85 <span class="error-message">${errors.get('firstname')}</span>
87 86 <br />
88 87 %endif
89 88
90 89 <label for="lastname">${_('Last Name')}:</label>
91 90 ${h.text('lastname', defaults.get('lastname'))}
92 91 %if 'lastname' in errors:
93 92 <span class="error-message">${errors.get('lastname')}</span>
94 93 <br />
95 94 %endif
96 95
97 96 <label for="email">${_('Email')}:</label>
98 97 ${h.text('email', defaults.get('email'))}
99 98 %if 'email' in errors:
100 99 <span class="error-message">${errors.get('email')}</span>
101 100 <br />
102 101 %endif
103 102
104 103 %if captcha_active:
105 104 <div>
106 105 <label for="recaptcha">${_('Captcha')}:</label>
107 106 ${h.hidden('recaptcha_field')}
108 107 <div id="recaptcha"></div>
109 108 %if 'recaptcha_field' in errors:
110 109 <span class="error-message">${errors.get('recaptcha_field')}</span>
111 110 <br />
112 111 %endif
113 112 </div>
114 113 %endif
115 114
116 115 %if not auto_active:
117 116 <p class="activation_msg">
118 117 ${_('Account activation requires admin approval.')}
119 118 </p>
120 119 %endif
121 120 <p class="register_message">
122 121 ${register_message|n}
123 122 </p>
124 123
125 124 ${h.submit('sign_up',_('Create Account'), class_="btn sign-in", title=_('Create Account in {}').format(c.rhodecode_edition))}
126 125 ${h.end_form()}
127 126 </div>
128 127 <%block name="below_register_button" />
129 128 </div>
130 129 </div>
131 130 </div>
132 131
133 132
134 133 <script type="text/javascript">
135 134 $(document).ready(function(){
136 135 $('#username').focus();
137 136 });
138 137 </script>
139 138
140 139 % if captcha_active:
141 140 <script type="text/javascript">
142 141 var onloadCallback = function() {
143 142 grecaptcha.render('recaptcha', {
144 143 'sitekey' : "${captcha_public_key}"
145 144 });
146 145 };
147 146 </script>
148 147 <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
149 148 % endif
150 149
@@ -1,4 +1,3 b''
1 ## -*- coding: utf-8 -*-
2 1 Auto status change to |new_status|
3 2
4 3 .. |new_status| replace:: *"${new_status_label}"* No newline at end of file
@@ -1,27 +1,26 b''
1 ## -*- coding: utf-8 -*-
2 1 Pull request updated. Auto status change to |under_review|
3 2
4 3 .. role:: added
5 4 .. role:: removed
6 5 .. parsed-literal::
7 6
8 7 Changed commits:
9 8 * :added:`${len(added_commits)} added`
10 9 * :removed:`${len(removed_commits)} removed`
11 10
12 11 %if not changed_files:
13 12 No file changes found
14 13 %else:
15 14 Changed files:
16 15 %for file_name in added_files:
17 16 * `A ${file_name} <#${'a_' + h.FID(ancestor_commit_id, file_name)}>`_
18 17 %endfor
19 18 %for file_name in modified_files:
20 19 * `M ${file_name} <#${'a_' + h.FID(ancestor_commit_id, file_name)}>`_
21 20 %endfor
22 21 %for file_name in removed_files:
23 22 * `R ${file_name}`
24 23 %endfor
25 24 %endif
26 25
27 26 .. |under_review| replace:: *"${under_review_label}"* No newline at end of file
@@ -1,241 +1,240 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2
4 3 <%def name="title()">
5 4 %if c.repo_name:
6 5 ${_('Search inside repository {repo_name}').format(repo_name=c.repo_name)}
7 6 %elif c.repo_group_name:
8 7 ${_('Search inside repository group {repo_group_name}').format(repo_group_name=c.repo_group_name)}
9 8 %else:
10 9 ${_('Search inside all accessible repositories')}
11 10 %endif
12 11 %if c.rhodecode_name:
13 12 &middot; ${h.branding(c.rhodecode_name)}
14 13 %endif
15 14 </%def>
16 15
17 16 <%def name="breadcrumbs_links()">
18 17 %if c.repo_name:
19 18 ${_('Search inside repository {repo_name}').format(repo_name=c.repo_name)}
20 19 %elif c.repo_group_name:
21 20 ${_('Search inside repository group {repo_group_name}').format(repo_group_name=c.repo_group_name)}
22 21 %else:
23 22 ${_('Search inside all accessible repositories')}
24 23 %endif
25 24
26 25 </%def>
27 26
28 27 <%def name="menu_bar_nav()">
29 28 %if c.repo_name:
30 29 ${self.menu_items(active='search')}
31 30 %elif c.repo_group_name:
32 31 ${self.menu_items(active='search')}
33 32 %else:
34 33 ${self.menu_items(active='search')}
35 34 %endif
36 35 </%def>
37 36
38 37 <%def name="menu_bar_subnav()">
39 38 %if c.repo_name:
40 39 <% active_entry = {'content':'files', 'path':'files', 'commit':'commits'}.get(c.search_type, 'summary')%>
41 40 ${self.repo_menu(active=active_entry)}
42 41 %elif c.repo_group_name:
43 42 ${self.repo_group_menu(active='home')}
44 43 %endif
45 44 </%def>
46 45
47 46 <%def name="repo_icon(db_repo)">
48 47 %if h.is_hg(db_repo):
49 48 <i class="icon-hg"></i>
50 49 %endif
51 50 %if h.is_git(db_repo):
52 51 <i class="icon-git"></i>
53 52 %endif
54 53 %if h.is_svn(db_repo):
55 54 <i class="icon-svn"></i>
56 55 %endif
57 56 </%def>
58 57
59 58 <%def name="repo_group_icon()">
60 59 <i class="icon-repo-group"></i>
61 60 </%def>
62 61
63 62
64 63 <%def name="field_sort(field_name)">
65 64
66 65 <%
67 66 if c.sort.startswith('asc:'):
68 67 return h.current_route_path(request, sort='desc:{}'.format(field_name))
69 68 elif c.sort.startswith('desc:'):
70 69 return h.current_route_path(request, sort='asc:{}'.format(field_name))
71 70
72 71 return h.current_route_path(request, sort='asc:{}'.format(field_name))
73 72 %>
74 73 </%def>
75 74
76 75
77 76 <%def name="main()">
78 77 <div class="box">
79 78 %if c.repo_name:
80 79 <!-- box / title -->
81 80 ${h.form(h.route_path('search_repo',repo_name=c.repo_name),method='get')}
82 81 %elif c.repo_group_name:
83 82 <!-- box / title -->
84 83 ${h.form(h.route_path('search_repo_group',repo_group_name=c.repo_group_name),method='get')}
85 84 %else:
86 85 <!-- box / title -->
87 86 <div class="title">
88 87 ${self.breadcrumbs()}
89 88 <ul class="links">&nbsp;</ul>
90 89 </div>
91 90 <!-- end box / title -->
92 91 ${h.form(h.route_path('search'), method='get')}
93 92 %endif
94 93 <div class="form search-form">
95 94 <div class="fields">
96 95
97 96 ${h.text('q', c.cur_query, placeholder="Enter query...")}
98 97
99 98 ${h.select('type',c.search_type,[('content',_('Files')), ('path',_('File path')),('commit',_('Commits'))],id='id_search_type')}
100 99 ${h.hidden('max_lines', '10')}
101 100
102 101 <input type="submit" value="${_('Search')}" class="btn"/>
103 102 <br/>
104 103
105 104 <div class="search-tags">
106 105 <span class="tag tag8">
107 106 %if c.repo_name:
108 107 <a href="${h.route_path('search', _query={'q': c.cur_query, 'type': request.GET.get('type', 'content')})}">${_('Global Search')}</a>
109 108 %elif c.repo_group_name:
110 109 <a href="${h.route_path('search', _query={'q': c.cur_query, 'type': request.GET.get('type', 'content')})}">${_('Global Search')}</a>
111 110 % else:
112 111 ${_('Global Search')}
113 112 %endif
114 113 </span>
115 114
116 115 %if c.repo_name:
117 116 »
118 117 <span class="tag tag8">
119 118 ${repo_icon(c.rhodecode_db_repo)}
120 119 ${c.repo_name}
121 120 </span>
122 121
123 122 %elif c.repo_group_name:
124 123 »
125 124 <span class="tag tag8">
126 125 ${repo_group_icon()}
127 126 ${c.repo_group_name}
128 127 </span>
129 128 %endif
130 129
131 130 % if c.sort_tag:
132 131 <span class="tag tag8">
133 132 % if c.sort_tag_dir == 'asc':
134 133 <i class="icon-angle-down"></i>
135 134 % elif c.sort_tag_dir == 'desc':
136 135 <i class="icon-angle-up"></i>
137 136 % endif
138 137 ${_('sort')}:${c.sort_tag}
139 138 </span>
140 139 % endif
141 140
142 141 % for search_tag in c.search_tags:
143 142 <br/><span class="tag disabled" style="margin-top: 3px">${search_tag}</span>
144 143 % endfor
145 144
146 145 </div>
147 146
148 147 <div class="search-feedback-items">
149 148 % for error in c.errors:
150 149 <span class="error-message">
151 150 % for k,v in error.asdict().items():
152 151 ${k} - ${v}
153 152 % endfor
154 153 </span>
155 154 % endfor
156 155 <div class="field">
157 156 <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Query Language examples')}</p>
158 157 <pre id="search-help" style="display: none">\
159 158
160 159 % if c.searcher.name == 'whoosh':
161 160 Example filter terms for `Whoosh` search:
162 161 query lang: <a href="${c.searcher.query_lang_doc}">Whoosh Query Language</a>
163 162 Whoosh has limited query capabilities. For advanced search use ElasticSearch 6 from RhodeCode EE edition.
164 163
165 164 Generate wildcards using '*' character:
166 165 "repo_name:vcs*" - search everything starting with 'vcs'
167 166 "repo_name:*vcs*" - search for repository containing 'vcs'
168 167
169 168 Optional AND / OR operators in queries
170 169 "repo_name:vcs OR repo_name:test"
171 170 "owner:test AND repo_name:test*" AND extension:py
172 171
173 172 Move advanced search is available via ElasticSearch6 backend in EE edition.
174 173 % elif c.searcher.name == 'elasticsearch' and c.searcher.es_version == '2':
175 174 Example filter terms for `ElasticSearch-${c.searcher.es_version}`search:
176 175 ElasticSearch-2 has limited query capabilities. For advanced search use ElasticSearch 6 from RhodeCode EE edition.
177 176
178 177 search type: content (File Content)
179 178 indexed fields: content
180 179
181 180 # search for `fix` string in all files
182 181 fix
183 182
184 183 search type: commit (Commit message)
185 184 indexed fields: message
186 185
187 186 search type: path (File name)
188 187 indexed fields: path
189 188
190 189 % else:
191 190 Example filter terms for `ElasticSearch-${c.searcher.es_version}`search:
192 191 query lang: <a href="${c.searcher.query_lang_doc}">ES 6 Query Language</a>
193 192 The reserved characters needed espace by `\`: + - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
194 193 % for handler in c.searcher.get_handlers().values():
195 194
196 195 search type: ${handler.search_type_label}
197 196 *indexed fields*: ${', '.join( [('\n ' if x[0]%4==0 else '')+x[1] for x in enumerate(handler.es_6_field_names)])}
198 197 % for entry in handler.es_6_example_queries:
199 198 ${entry.rstrip()}
200 199 % endfor
201 200 % endfor
202 201
203 202 % endif
204 203 </pre>
205 204 </div>
206 205
207 206 <div class="field">${c.runtime}</div>
208 207 </div>
209 208 </div>
210 209 </div>
211 210
212 211 ${h.end_form()}
213 212 <div class="search">
214 213 % if c.search_type == 'content':
215 214 <%include file='search_content.mako'/>
216 215 % elif c.search_type == 'path':
217 216 <%include file='search_path.mako'/>
218 217 % elif c.search_type == 'commit':
219 218 <%include file='search_commit.mako'/>
220 219 % elif c.search_type == 'repository':
221 220 <%include file='search_repository.mako'/>
222 221 % endif
223 222 </div>
224 223 </div>
225 224 <script>
226 225 $(document).ready(function(){
227 226 $("#id_search_type").select2({
228 227 'containerCssClass': "drop-menu",
229 228 'dropdownCssClass': "drop-menu-dropdown",
230 229 'dropdownAutoWidth': true,
231 230 'minimumResultsForSearch': -1
232 231 });
233 232
234 233 $('#q').autoGrowInput({maxWidth: 920});
235 234
236 235 setTimeout(function() {
237 236 $('#q').keyup()
238 237 }, 1);
239 238 })
240 239 </script>
241 240 </%def>
@@ -1,169 +1,168 b''
1 ## -*- coding: utf-8 -*-
2 1 <%namespace name="base" file="/base/base.mako"/>
3 2 %if c.repo_commits:
4 3 <table class="rctable table-bordered">
5 4 <tr>
6 5
7 6 <th class="status"></th>
8 7 <th></th>
9 8 <th>${_('Commit message')}</th>
10 9 <th>${_('Age')}</th>
11 10 <th>${_('Author')}</th>
12 11 <th colspan="2">${_('Refs')}</th>
13 12 </tr>
14 13
15 14 ## to speed up lookups cache some functions before the loop
16 15 <%
17 16 active_patterns = h.get_active_pattern_entries(c.repo_name)
18 17 urlify_commit_message = h.partial(h.urlify_commit_message, active_pattern_entries=active_patterns)
19 18 %>
20 19 %for cnt,cs in enumerate(c.repo_commits):
21 20 <tr class="parity${cnt%2}">
22 21
23 22 <td class="td-status">
24 23 %if c.statuses.get(cs.raw_id):
25 24 <div class="changeset-status-ico shortlog">
26 25 %if c.statuses.get(cs.raw_id)[2]:
27 26 <a class="tooltip" title="${_('Commit status: %s\nClick to open associated pull request #%s') % (c.statuses.get(cs.raw_id)[0], c.statuses.get(cs.raw_id)[2])}" href="${h.route_path('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}">
28 27 <i class="icon-circle review-status-${c.statuses.get(cs.raw_id)[0]}"></i>
29 28 </a>
30 29 %else:
31 30 <a class="tooltip" title="${_('Commit status: {}').format(h.commit_status_lbl(c.statuses.get(cs.raw_id)[0]))}" href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=cs.raw_id,_anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
32 31 <i class="icon-circle review-status-${c.statuses.get(cs.raw_id)[0]}"></i>
33 32 </a>
34 33 %endif
35 34 </div>
36 35 %else:
37 36 <i class="icon-circle review-status-not_reviewed" title="${_('Commit status: Not Reviewed')}"></i>
38 37 %endif
39 38 </td>
40 39 <td class="td-hash">
41 40 <code>
42 41 <a href="${h.route_path('repo_commit', repo_name=c.repo_name, commit_id=cs.raw_id)}">${h.show_id(cs)}</a>
43 42 <i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${cs.raw_id}" title="${_('Copy the full commit id')}"></i>
44 43 </code>
45 44 </td>
46 45
47 46 <td class="td-description mid">
48 47 <div class="log-container truncate-wrap">
49 48 <div class="message truncate" id="c-${cs.raw_id}">${urlify_commit_message(cs.message, c.repo_name)}</div>
50 49 </div>
51 50 </td>
52 51
53 52 <td class="td-time">
54 53 ${h.age_component(cs.date)}
55 54 </td>
56 55 <td class="td-user author">
57 56 ${base.gravatar_with_user(cs.author, tooltip=True)}
58 57 </td>
59 58
60 59 <td class="td-tags">
61 60 <div class="autoexpand">
62 61 %if h.is_hg(c.rhodecode_repo):
63 62 %for book in cs.bookmarks:
64 63 <span class="booktag tag" title="${h.tooltip(_('Bookmark %s') % book)}">
65 64 <a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=cs.raw_id, _query=dict(at=book))}"><i class="icon-bookmark"></i>${h.shorter(book)}</a>
66 65 </span>
67 66 %endfor
68 67 %endif
69 68 ## tags
70 69 %for tag in cs.tags:
71 70 <span class="tagtag tag" title="${h.tooltip(_('Tag %s') % tag)}">
72 71 <a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=cs.raw_id, _query=dict(at=tag))}"><i class="icon-tag"></i>${h.shorter(tag)}</a>
73 72 </span>
74 73 %endfor
75 74
76 75 ## branch
77 76 %if cs.branch:
78 77 <span class="branchtag tag" title="${h.tooltip(_('Branch %s') % cs.branch)}">
79 78 <a href="${h.route_path('repo_commits',repo_name=c.repo_name,_query=dict(branch=cs.branch))}"><i class="icon-code-fork"></i>${h.shorter(cs.branch)}</a>
80 79 </span>
81 80 %endif
82 81 </div>
83 82 </td>
84 83 <td class="td-comments">
85 84 <% cs_comments = c.comments.get(cs.raw_id,[]) %>
86 85 % if cs_comments:
87 86 <a title="${_('Commit has comments')}" href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=cs.raw_id,_anchor='comment-%s' % cs_comments[0].comment_id)}">
88 87 <i class="icon-comment"></i> ${len(cs_comments)}
89 88 </a>
90 89 % else:
91 90 <i class="icon-comment"></i> ${len(cs_comments)}
92 91 % endif
93 92 </td>
94 93 </tr>
95 94 %endfor
96 95
97 96 </table>
98 97
99 98 <script type="text/javascript">
100 99 $(document).pjax('#shortlog_data .pager_link','#shortlog_data', {timeout: 5000, scrollTo: false, push: false});
101 100 $(document).on('pjax:success', function(){ timeagoActivate(); tooltipActivate();});
102 101 $(document).on('pjax:timeout', function(event) {
103 102 // Prevent default timeout redirection behavior
104 103 event.preventDefault()
105 104 })
106 105
107 106 </script>
108 107
109 108 <div class="pagination-wh pagination-left">
110 109 ${c.repo_commits.render()}
111 110 </div>
112 111 %else:
113 112
114 113
115 114 <div class="quick_start">
116 115 <div class="fieldset">
117 116 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
118 117 <p><b>${_('Add or upload files directly via RhodeCode:')}</b></p>
119 118 <div class="pull-left">
120 119 <a href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=0, f_path='')}" class="btn btn-default">${_('Add New File')}</a>
121 120 </div>
122 121 <div class="pull-left">
123 122 <a href="${h.route_path('repo_files_upload_file',repo_name=c.repo_name,commit_id=0, f_path='')}" class="btn btn-default">${_('Upload New File')}</a>
124 123 </div>
125 124 %endif
126 125 </div>
127 126
128 127
129 128 <div class="fieldset">
130 129 <p><b>${_('Push new repo:')}</b></p>
131 130 <pre>
132 131 %if h.is_git(c.rhodecode_repo):
133 132 git clone ${c.clone_repo_url}
134 133 git add README # add first file
135 134 git commit -m "Initial commit" # commit with message
136 135 git remote add origin ${c.clone_repo_url}
137 136 git push -u origin master # push changes back to default master branch
138 137 %elif h.is_hg(c.rhodecode_repo):
139 138 hg clone ${c.clone_repo_url}
140 139 hg add README # add first file
141 140 hg commit -m "Initial commit" # commit with message
142 141 hg push ${c.clone_repo_url}
143 142 %elif h.is_svn(c.rhodecode_repo):
144 143 svn co ${c.clone_repo_url}
145 144 svn add README # add first file
146 145 svn commit -m "Initial commit"
147 146 svn commit # send changes back to the server
148 147 %endif
149 148 </pre>
150 149 </div>
151 150
152 151 <div class="fieldset">
153 152 <p><b>${_('Existing repository?')}</b></p>
154 153 <pre>
155 154 %if h.is_git(c.rhodecode_repo):
156 155 git remote add origin ${c.clone_repo_url}
157 156 git push -u origin master
158 157 %elif h.is_hg(c.rhodecode_repo):
159 158 hg push ${c.clone_repo_url}
160 159 %elif h.is_svn(c.rhodecode_repo):
161 160 svn co ${c.clone_repo_url}
162 161 %endif
163 162 </pre>
164 163
165 164 </div>
166 165
167 166
168 167 </div>
169 168 %endif
@@ -1,118 +1,117 b''
1 ## -*- coding: utf-8 -*-
2 1 <%inherit file="/base/base.mako"/>
3 2 <%namespace name="components" file="/summary/components.mako"/>
4 3
5 4 <%def name="title()">
6 5 ${_('{} Tags').format(c.repo_name)}
7 6 %if c.rhodecode_name:
8 7 &middot; ${h.branding(c.rhodecode_name)}
9 8 %endif
10 9 </%def>
11 10
12 11 <%def name="breadcrumbs_links()"></%def>
13 12
14 13 <%def name="menu_bar_nav()">
15 14 ${self.menu_items(active='repositories')}
16 15 </%def>
17 16
18 17 <%def name="menu_bar_subnav()">
19 18 ${self.repo_menu(active='summary')}
20 19 </%def>
21 20
22 21 <%def name="main()">
23 22 <div id="repo-summary" class="summary">
24 23 ${components.summary_detail(breadcrumbs_links=self.breadcrumbs_links(), show_downloads=False, simplified=True)}
25 24 </div>
26 25
27 26 <div class="box">
28 27 <div class="title">
29 28
30 29 %if c.has_references:
31 30 <ul class="links">
32 31 <li>
33 32 <input type="submit" id="compare_action" class="btn" disabled="disabled" value="${_('Compare Selected Tags')}">
34 33 </li>
35 34 </ul>
36 35 %endif
37 36 %if c.has_references:
38 37 <div class="grid-quick-filter">
39 38 <ul class="grid-filter-box">
40 39 <li class="grid-filter-box-icon">
41 40 <i class="icon-search"></i>
42 41 </li>
43 42 <li class="grid-filter-box-input">
44 43 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
45 44 </li>
46 45 </ul>
47 46 </div>
48 47 <div id="obj_count">0</div>
49 48 %endif
50 49 </div>
51 50 <table id="obj_list_table" class="rctable table-bordered"></table>
52 51 </div>
53 52
54 53
55 54 <script type="text/javascript">
56 55 $(document).ready(function() {
57 56
58 57 var get_datatable_count = function(){
59 58 var api = $('#obj_list_table').dataTable().api();
60 59 var total = api.page.info().recordsDisplay
61 60 var _text = _ngettext('{0} tag', '{0} tags', total).format(total);
62 61
63 62 $('#obj_count').text(_text);
64 63 };
65 64
66 65 // object list
67 66 $('#obj_list_table').DataTable({
68 67 data: ${c.data|n},
69 68 dom: 'rtp',
70 69 pageLength: ${c.visual.dashboard_items},
71 70 order: [[ 0, "asc" ]],
72 71 columns: [
73 72 { data: {"_": "name",
74 73 "sort": "name_raw"}, title: "${_('Name')}", className: "td-tags" },
75 74 { data: {"_": "date",
76 75 "sort": "date_raw"}, title: "${_('Date')}", className: "td-time" },
77 76 { data: {"_": "author",
78 77 "sort": "author"}, title: "${_('Author')}", className: "td-user" },
79 78 { data: {"_": "commit",
80 79 "sort": "commit_raw",
81 80 "type": Number}, title: "${_('Commit')}", className: "td-hash" },
82 81 { data: {"_": "compare",
83 82 "sort": "compare"}, title: "${_('Compare')}", className: "td-compare" }
84 83 ],
85 84 language: {
86 85 paginate: DEFAULT_GRID_PAGINATION,
87 86 emptyTable: _gettext("No tags available yet.")
88 87 },
89 88 "initComplete": function(settings, json) {
90 89 get_datatable_count();
91 90 timeagoActivate();
92 91 tooltipActivate();
93 92 compare_radio_buttons("${c.repo_name}", 'tag');
94 93 }
95 94 });
96 95
97 96 // update when things change
98 97 $('#obj_list_table').on('draw.dt', function() {
99 98 get_datatable_count();
100 99 timeagoActivate();
101 100 tooltipActivate();
102 101 });
103 102
104 103 // filter, filter both grids
105 104 $('#q_filter').on('keyup', function() {
106 105 var obj_api = $('#obj_list_table').dataTable().api();
107 106 obj_api
108 107 .columns(0)
109 108 .search(this.value)
110 109 .draw();
111 110 });
112 111
113 112 // refilter table if page load via back button
114 113 $("#q_filter").trigger('keyup');
115 114 });
116 115
117 116 </script>
118 117 </%def>
General Comments 0
You need to be logged in to leave comments. Login now