##// END OF EJS Templates
ui: added action link that repliaces current mix of actions in options and action buttons...
marcink -
r3907:c5a907e3 default
parent child Browse files
Show More
@@ -1,141 +1,141 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2019 RhodeCode GmbH
3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import pytest
22 import pytest
23
23
24 import rhodecode
24 import rhodecode
25 from rhodecode.model.db import Repository
25 from rhodecode.model.db import Repository
26 from rhodecode.model.meta import Session
26 from rhodecode.model.meta import Session
27 from rhodecode.model.repo import RepoModel
27 from rhodecode.model.repo import RepoModel
28 from rhodecode.model.repo_group import RepoGroupModel
28 from rhodecode.model.repo_group import RepoGroupModel
29 from rhodecode.model.settings import SettingsModel
29 from rhodecode.model.settings import SettingsModel
30 from rhodecode.tests import TestController
30 from rhodecode.tests import TestController
31 from rhodecode.tests.fixture import Fixture
31 from rhodecode.tests.fixture import Fixture
32 from rhodecode.lib import helpers as h
32 from rhodecode.lib import helpers as h
33
33
34 fixture = Fixture()
34 fixture = Fixture()
35
35
36
36
37 def route_path(name, **kwargs):
37 def route_path(name, **kwargs):
38 return {
38 return {
39 'home': '/',
39 'home': '/',
40 'repo_group_home': '/{repo_group_name}'
40 'repo_group_home': '/{repo_group_name}'
41 }[name].format(**kwargs)
41 }[name].format(**kwargs)
42
42
43
43
44 class TestHomeController(TestController):
44 class TestHomeController(TestController):
45
45
46 def test_index(self):
46 def test_index(self):
47 self.log_user()
47 self.log_user()
48 response = self.app.get(route_path('home'))
48 response = self.app.get(route_path('home'))
49 # if global permission is set
49 # if global permission is set
50 response.mustcontain('Add Repository')
50 response.mustcontain('New Repository')
51
51
52 # search for objects inside the JavaScript JSON
52 # search for objects inside the JavaScript JSON
53 for repo in Repository.getAll():
53 for repo in Repository.getAll():
54 response.mustcontain('"name_raw": "%s"' % repo.repo_name)
54 response.mustcontain('"name_raw": "%s"' % repo.repo_name)
55
55
56 def test_index_contains_statics_with_ver(self):
56 def test_index_contains_statics_with_ver(self):
57 from rhodecode.lib.base import calculate_version_hash
57 from rhodecode.lib.base import calculate_version_hash
58
58
59 self.log_user()
59 self.log_user()
60 response = self.app.get(route_path('home'))
60 response = self.app.get(route_path('home'))
61
61
62 rhodecode_version_hash = calculate_version_hash(
62 rhodecode_version_hash = calculate_version_hash(
63 {'beaker.session.secret': 'test-rc-uytcxaz'})
63 {'beaker.session.secret': 'test-rc-uytcxaz'})
64 response.mustcontain('style.css?ver={0}'.format(rhodecode_version_hash))
64 response.mustcontain('style.css?ver={0}'.format(rhodecode_version_hash))
65 response.mustcontain('scripts.js?ver={0}'.format(rhodecode_version_hash))
65 response.mustcontain('scripts.js?ver={0}'.format(rhodecode_version_hash))
66
66
67 def test_index_contains_backend_specific_details(self, backend):
67 def test_index_contains_backend_specific_details(self, backend):
68 self.log_user()
68 self.log_user()
69 response = self.app.get(route_path('home'))
69 response = self.app.get(route_path('home'))
70 tip = backend.repo.get_commit().raw_id
70 tip = backend.repo.get_commit().raw_id
71
71
72 # html in javascript variable:
72 # html in javascript variable:
73 response.mustcontain(r'<i class=\"icon-%s\"' % (backend.alias, ))
73 response.mustcontain(r'<i class=\"icon-%s\"' % (backend.alias, ))
74 response.mustcontain(r'href=\"/%s\"' % (backend.repo_name, ))
74 response.mustcontain(r'href=\"/%s\"' % (backend.repo_name, ))
75
75
76 response.mustcontain("""/%s/changeset/%s""" % (backend.repo_name, tip))
76 response.mustcontain("""/%s/changeset/%s""" % (backend.repo_name, tip))
77 response.mustcontain("""Added a symlink""")
77 response.mustcontain("""Added a symlink""")
78
78
79 def test_index_with_anonymous_access_disabled(self):
79 def test_index_with_anonymous_access_disabled(self):
80 with fixture.anon_access(False):
80 with fixture.anon_access(False):
81 response = self.app.get(route_path('home'), status=302)
81 response = self.app.get(route_path('home'), status=302)
82 assert 'login' in response.location
82 assert 'login' in response.location
83
83
84 def test_index_page_on_groups(self, autologin_user, repo_group):
84 def test_index_page_on_groups(self, autologin_user, repo_group):
85 response = self.app.get(route_path('repo_group_home', repo_group_name='gr1'))
85 response = self.app.get(route_path('repo_group_home', repo_group_name='gr1'))
86 response.mustcontain("gr1/repo_in_group")
86 response.mustcontain("gr1/repo_in_group")
87
87
88 def test_index_page_on_group_with_trailing_slash(
88 def test_index_page_on_group_with_trailing_slash(
89 self, autologin_user, repo_group):
89 self, autologin_user, repo_group):
90 response = self.app.get(route_path('repo_group_home', repo_group_name='gr1') + '/')
90 response = self.app.get(route_path('repo_group_home', repo_group_name='gr1') + '/')
91 response.mustcontain("gr1/repo_in_group")
91 response.mustcontain("gr1/repo_in_group")
92
92
93 @pytest.fixture(scope='class')
93 @pytest.fixture(scope='class')
94 def repo_group(self, request):
94 def repo_group(self, request):
95 gr = fixture.create_repo_group('gr1')
95 gr = fixture.create_repo_group('gr1')
96 fixture.create_repo(name='gr1/repo_in_group', repo_group=gr)
96 fixture.create_repo(name='gr1/repo_in_group', repo_group=gr)
97
97
98 @request.addfinalizer
98 @request.addfinalizer
99 def cleanup():
99 def cleanup():
100 RepoModel().delete('gr1/repo_in_group')
100 RepoModel().delete('gr1/repo_in_group')
101 RepoGroupModel().delete(repo_group='gr1', force_delete=True)
101 RepoGroupModel().delete(repo_group='gr1', force_delete=True)
102 Session().commit()
102 Session().commit()
103
103
104 def test_index_with_name_with_tags(self, user_util, autologin_user):
104 def test_index_with_name_with_tags(self, user_util, autologin_user):
105 user = user_util.create_user()
105 user = user_util.create_user()
106 username = user.username
106 username = user.username
107 user.name = '<img src="/image1" onload="alert(\'Hello, World!\');">'
107 user.name = '<img src="/image1" onload="alert(\'Hello, World!\');">'
108 user.lastname = '#"><img src=x onerror=prompt(document.cookie);>'
108 user.lastname = '#"><img src=x onerror=prompt(document.cookie);>'
109
109
110 Session().add(user)
110 Session().add(user)
111 Session().commit()
111 Session().commit()
112 user_util.create_repo(owner=username)
112 user_util.create_repo(owner=username)
113
113
114 response = self.app.get(route_path('home'))
114 response = self.app.get(route_path('home'))
115 response.mustcontain(h.html_escape(user.first_name))
115 response.mustcontain(h.html_escape(user.first_name))
116 response.mustcontain(h.html_escape(user.last_name))
116 response.mustcontain(h.html_escape(user.last_name))
117
117
118 @pytest.mark.parametrize("name, state", [
118 @pytest.mark.parametrize("name, state", [
119 ('Disabled', False),
119 ('Disabled', False),
120 ('Enabled', True),
120 ('Enabled', True),
121 ])
121 ])
122 def test_index_show_version(self, autologin_user, name, state):
122 def test_index_show_version(self, autologin_user, name, state):
123 version_string = 'RhodeCode Enterprise %s' % rhodecode.__version__
123 version_string = 'RhodeCode Enterprise %s' % rhodecode.__version__
124
124
125 sett = SettingsModel().create_or_update_setting(
125 sett = SettingsModel().create_or_update_setting(
126 'show_version', state, 'bool')
126 'show_version', state, 'bool')
127 Session().add(sett)
127 Session().add(sett)
128 Session().commit()
128 Session().commit()
129 SettingsModel().invalidate_settings_cache()
129 SettingsModel().invalidate_settings_cache()
130
130
131 response = self.app.get(route_path('home'))
131 response = self.app.get(route_path('home'))
132 if state is True:
132 if state is True:
133 response.mustcontain(version_string)
133 response.mustcontain(version_string)
134 if state is False:
134 if state is False:
135 response.mustcontain(no=[version_string])
135 response.mustcontain(no=[version_string])
136
136
137 def test_logout_form_contains_csrf(self, autologin_user, csrf_token):
137 def test_logout_form_contains_csrf(self, autologin_user, csrf_token):
138 response = self.app.get(route_path('home'))
138 response = self.app.get(route_path('home'))
139 assert_response = response.assert_response()
139 assert_response = response.assert_response()
140 element = assert_response.get_element('.logout #csrf_token')
140 element = assert_response.get_element('.logout #csrf_token')
141 assert element.value == csrf_token
141 assert element.value == csrf_token
@@ -1,755 +1,806 b''
1 // navigation.less
1 // navigation.less
2 // For use in RhodeCode applications;
2 // For use in RhodeCode applications;
3 // see style guide documentation for guidelines.
3 // see style guide documentation for guidelines.
4
4
5 // TOP MAIN DARK NAVIGATION
5 // TOP MAIN DARK NAVIGATION
6
6
7 .header .main_nav.horizontal-list {
7 .header .main_nav.horizontal-list {
8 float: right;
8 float: right;
9 color: @grey4;
9 color: @grey4;
10 > li {
10 > li {
11 a {
11 a {
12 color: @grey4;
12 color: @grey4;
13 }
13 }
14 }
14 }
15 }
15 }
16
16
17 // HEADER NAVIGATION
17 // HEADER NAVIGATION
18
18
19 .horizontal-list {
19 .horizontal-list {
20 display: block;
20 display: block;
21 margin: 0;
21 margin: 0;
22 padding: 0;
22 padding: 0;
23 -webkit-padding-start: 0;
23 -webkit-padding-start: 0;
24 text-align: left;
24 text-align: left;
25 font-size: @navigation-fontsize;
25 font-size: @navigation-fontsize;
26 color: @grey6;
26 color: @grey6;
27 z-index:10;
27 z-index:10;
28
28
29 li {
29 li {
30 line-height: 1em;
30 line-height: 1em;
31 list-style-type: none;
31 list-style-type: none;
32 margin: 0 20px 0 0;
32 margin: 0 20px 0 0;
33
33
34 a {
34 a {
35 padding: 0 .5em;
35 padding: 0 .5em;
36
36
37 &.menu_link_notifications {
37 &.menu_link_notifications {
38 .pill(7px,@rcblue);
38 .pill(7px,@rcblue);
39 display: inline;
39 display: inline;
40 margin: 0 7px 0 .7em;
40 margin: 0 7px 0 .7em;
41 font-size: @basefontsize;
41 font-size: @basefontsize;
42 color: white;
42 color: white;
43
43
44 &.empty {
44 &.empty {
45 background-color: @grey4;
45 background-color: @grey4;
46 }
46 }
47
47
48 &:hover {
48 &:hover {
49 background-color: @rcdarkblue;
49 background-color: @rcdarkblue;
50 }
50 }
51 }
51 }
52 }
52 }
53 .pill_container {
53 .pill_container {
54 margin: 1.25em 0px 0px 0px;
54 margin: 1.25em 0px 0px 0px;
55 float: right;
55 float: right;
56 }
56 }
57
57
58 &#quick_login_li {
58 &#quick_login_li {
59 &:hover {
59 &:hover {
60 color: @grey5;
60 color: @grey5;
61 }
61 }
62
62
63 a.menu_link_notifications {
63 a.menu_link_notifications {
64 color: white;
64 color: white;
65 }
65 }
66
66
67 .user {
67 .user {
68 padding-bottom: 10px;
68 padding-bottom: 10px;
69 }
69 }
70 }
70 }
71
71
72 &:before { content: none; }
72 &:before { content: none; }
73
73
74 &:last-child {
74 &:last-child {
75 .menulabel {
75 .menulabel {
76 padding-right: 0;
76 padding-right: 0;
77 border-right: none;
77 border-right: none;
78
78
79 .show_more {
79 .show_more {
80 padding-right: 0;
80 padding-right: 0;
81 }
81 }
82 }
82 }
83
83
84 &> a {
84 &> a {
85 border-bottom: none;
85 border-bottom: none;
86 }
86 }
87 }
87 }
88
88
89 &.open {
89 &.open {
90
90
91 a {
91 a {
92 color: white;
92 color: white;
93 }
93 }
94 }
94 }
95
95
96 &:focus {
96 &:focus {
97 outline: none;
97 outline: none;
98 }
98 }
99
99
100 ul li {
100 ul li {
101 display: block;
101 display: block;
102
102
103 &:last-child> a {
103 &:last-child> a {
104 border-bottom: none;
104 border-bottom: none;
105 }
105 }
106
106
107 ul li:last-child a {
107 ul li:last-child a {
108 /* we don't expect more then 3 levels of submenu and the third
108 /* we don't expect more then 3 levels of submenu and the third
109 level can have different html structure */
109 level can have different html structure */
110 border-bottom: none;
110 border-bottom: none;
111 }
111 }
112 }
112 }
113 }
113 }
114
114
115 > li {
115 > li {
116 float: left;
116 float: left;
117 display: block;
117 display: block;
118 padding: 0;
118 padding: 0;
119
119
120 > a,
120 > a,
121 &.has_select2 a {
121 &.has_select2 a {
122 display: block;
122 display: block;
123 padding: 10px 0;
123 padding: 10px 0;
124 }
124 }
125
125
126 .menulabel {
126 .menulabel {
127 line-height: 1em;
127 line-height: 1em;
128 // for this specifically we do not use a variable
128 // for this specifically we do not use a variable
129 }
129 }
130
130
131 .pr_notifications {
131 .pr_notifications {
132 padding-left: .5em;
132 padding-left: .5em;
133 }
133 }
134
134
135 .pr_notifications + .menulabel {
135 .pr_notifications + .menulabel {
136 display:inline;
136 display:inline;
137 padding-left: 0;
137 padding-left: 0;
138 }
138 }
139
139
140 &:hover,
140 &:hover,
141 &.open,
141 &.open,
142 &.active {
142 &.active {
143 a {
143 a {
144 color: @rcblue;
144 color: @rcblue;
145 }
145 }
146 }
146 }
147 }
147 }
148
148
149 pre {
149 pre {
150 margin: 0;
150 margin: 0;
151 padding: 0;
151 padding: 0;
152 }
152 }
153
153
154 .select2-container,
154 .select2-container,
155 .menulink.childs {
155 .menulink.childs {
156 position: relative;
156 position: relative;
157 }
157 }
158
158
159 .menulink {
159 .menulink {
160 &.disabled {
160 &.disabled {
161 color: @grey3;
161 color: @grey3;
162 cursor: default;
162 cursor: default;
163 opacity: 0.5;
163 opacity: 0.5;
164 }
164 }
165 }
165 }
166
166
167 #quick_login {
167 #quick_login {
168
168
169 li a {
169 li a {
170 padding: .5em 0;
170 padding: .5em 0;
171 border-bottom: none;
171 border-bottom: none;
172 color: @grey2;
172 color: @grey2;
173
173
174 &:hover { color: @grey1; }
174 &:hover { color: @grey1; }
175 }
175 }
176 }
176 }
177
177
178 #quick_login_link {
178 #quick_login_link {
179 display: inline-block;
179 display: inline-block;
180
180
181 .gravatar {
181 .gravatar {
182 border: 1px solid @grey5;
182 border: 1px solid @grey5;
183 }
183 }
184
184
185 .gravatar-login {
185 .gravatar-login {
186 height: 20px;
186 height: 20px;
187 width: 20px;
187 width: 20px;
188 margin: -8px 0;
188 margin: -8px 0;
189 padding: 0;
189 padding: 0;
190 }
190 }
191
191
192 &:hover .user {
192 &:hover .user {
193 color: @grey6;
193 color: @grey6;
194 }
194 }
195 }
195 }
196 }
196 }
197 .header .horizontal-list {
197 .header .horizontal-list {
198
198
199 li {
199 li {
200
200
201 &#quick_login_li {
201 &#quick_login_li {
202 padding-left: .5em;
202 padding-left: .5em;
203 margin-right: 0px;
203
204
204 &:hover #quick_login_link {
205 &:hover #quick_login_link {
205 color: inherit;
206 color: inherit;
206 }
207 }
207
208
208 .menu_link_user {
209 .menu_link_user {
209 padding: 0 2px;
210 padding: 0 2px;
210 }
211 }
211 }
212 }
212 list-style-type: none;
213 list-style-type: none;
213 }
214 }
214
215
215 > li {
216 > li {
216
217
217 a {
218 a {
218 padding: 18px 0 12px 0;
219 padding: 18px 0 12px 0;
219 color: @nav-grey;
220 color: @nav-grey;
220
221
221 &.menu_link_notifications {
222 &.menu_link_notifications {
222 padding: 1px 8px;
223 padding: 1px 8px;
223 }
224 }
224 }
225 }
225
226
226 &:hover,
227 &:hover,
227 &.open,
228 &.open,
228 &.active {
229 &.active {
229 .pill_container a {
230 .pill_container a {
230 // don't select text for the pill container, it has it' own
231 // don't select text for the pill container, it has it' own
231 // hover behaviour
232 // hover behaviour
232 color: @nav-grey;
233 color: @nav-grey;
233 }
234 }
234 }
235 }
235
236
236 &:hover,
237 &:hover,
237 &.open,
238 &.open,
238 &.active {
239 &.active {
239 a {
240 a {
240 color: @grey6;
241 color: @grey6;
241 }
242 }
242 }
243 }
243
244
244 .select2-dropdown-open a {
245 .select2-dropdown-open a {
245 color: @grey6;
246 color: @grey6;
246 }
247 }
247
248
248 .repo-switcher {
249 .repo-switcher {
249 padding-left: 0;
250 padding-left: 0;
250
251
251 .menulabel {
252 .menulabel {
252 padding-left: 0;
253 padding-left: 0;
253 }
254 }
254 }
255 }
255 }
256 }
256
257
257 li ul li {
258 li ul li {
258 background-color:@grey2;
259 background-color:@grey2;
259
260
260 a {
261 a {
261 padding: .5em 0;
262 padding: .5em 0;
262 border-bottom: @border-thickness solid @border-default-color;
263 border-bottom: @border-thickness solid @border-default-color;
263 color: @grey6;
264 color: @grey6;
264 }
265 }
265
266
266 &:last-child a, &.last a{
267 &:last-child a, &.last a{
267 border-bottom: none;
268 border-bottom: none;
268 }
269 }
269
270
270 &:hover {
271 &:hover {
271 background-color: @grey3;
272 background-color: @grey3;
272 }
273 }
273 }
274 }
274
275
275 .submenu {
276 .submenu {
276 margin-top: 5px;
277 margin-top: 5px;
277 }
278 }
278 }
279 }
279
280
280 // SUBMENUS
281 // SUBMENUS
281 .navigation .submenu {
282 .navigation .submenu {
282 display: none;
283 display: none;
283 }
284 }
284
285
285 .navigation li.open {
286 .navigation li.open {
286 .submenu {
287 .submenu {
287 display: block;
288 display: block;
288 }
289 }
289 }
290 }
290
291
291 .navigation li:last-child .submenu {
292 .navigation li:last-child .submenu {
292 right: auto;
293 right: auto;
293 left: 0;
294 left: 0;
294 border: 1px solid @grey5;
295 border: 1px solid @grey5;
295 background: @white;
296 background: @white;
296 box-shadow: @dropdown-shadow;
297 box-shadow: @dropdown-shadow;
297 }
298 }
298
299
299 .submenu {
300 .submenu {
300 position: absolute;
301 position: absolute;
301 top: 100%;
302 top: 100%;
302 left: 0;
303 left: 0;
303 min-width: 180px;
304 min-width: 180px;
304 margin: 2px 0 0;
305 margin: 2px 0 0;
305 padding: 0;
306 padding: 0;
306 text-align: left;
307 text-align: left;
307 font-family: @text-light;
308 font-family: @text-light;
308 border-radius: @border-radius;
309 border-radius: @border-radius;
309 z-index: 20;
310 z-index: 20;
310
311
311 li {
312 li {
312 display: block;
313 display: block;
313 margin: 0;
314 margin: 0;
314 padding: 0 .5em;
315 padding: 0 .5em;
315 line-height: 1em;
316 line-height: 1em;
316 color: @grey3;
317 color: @grey3;
317 background-color: @white;
318 background-color: @white;
318 list-style-type: none;
319 list-style-type: none;
319
320
320 a {
321 a {
321 display: block;
322 display: block;
322 width: 100%;
323 width: 100%;
323 padding: .5em 0;
324 padding: .5em 0;
324 border-right: none;
325 border-right: none;
325 border-bottom: @border-thickness solid white;
326 border-bottom: @border-thickness solid white;
326 color: @grey3;
327 color: @grey3;
327 }
328 }
328
329
329 ul {
330 ul {
330 display: none;
331 display: none;
331 position: absolute;
332 position: absolute;
332 top: 0;
333 top: 0;
333 right: 100%;
334 right: 100%;
334 padding: 0;
335 padding: 0;
335 z-index: 30;
336 z-index: 30;
336 }
337 }
337 &:hover {
338 &:hover {
338 background-color: @grey7;
339 background-color: @grey7;
339 -webkit-transition: background .3s;
340 -webkit-transition: background .3s;
340 -moz-transition: background .3s;
341 -moz-transition: background .3s;
341 -o-transition: background .3s;
342 -o-transition: background .3s;
342 transition: background .3s;
343 transition: background .3s;
343
344
344 ul {
345 ul {
345 display: block;
346 display: block;
346 }
347 }
347 }
348 }
348 }
349 }
349
350
350 }
351 }
351
352
352
353
353
354
354
355
355 // repo dropdown
356 // repo dropdown
356 .quick_repo_menu {
357 .quick_repo_menu {
357 width: 15px;
358 width: 15px;
358 text-align: center;
359 text-align: center;
359 position: relative;
360 position: relative;
360 cursor: pointer;
361 cursor: pointer;
361
362
362 div {
363 div {
363 overflow: visible !important;
364 overflow: visible !important;
364 }
365 }
365
366
366 &.sorting {
367 &.sorting {
367 cursor: auto;
368 cursor: auto;
368 }
369 }
369
370
370 &:hover {
371 &:hover {
371 .menu_items_container {
372 .menu_items_container {
372 position: absolute;
373 position: absolute;
373 display: block;
374 display: block;
374 }
375 }
375 .menu_items {
376 .menu_items {
376 display: block;
377 display: block;
377 }
378 }
378 }
379 }
379
380
380 i {
381 i {
381 margin: 0;
382 margin: 0;
382 color: @grey4;
383 color: @grey4;
383 }
384 }
384
385
385 .menu_items_container {
386 .menu_items_container {
386 position: absolute;
387 position: absolute;
387 top: 0;
388 top: 0;
388 left: 100%;
389 left: 100%;
389 margin: 0;
390 margin: 0;
390 padding: 0;
391 padding: 0;
391 list-style: none;
392 list-style: none;
392 background-color: @grey6;
393 background-color: @grey6;
393 z-index: 999;
394 z-index: 999;
394 text-align: left;
395 text-align: left;
395
396
396 a {
397 a {
397 color: @grey2;
398 color: @grey2;
398 }
399 }
399
400
400 ul.menu_items {
401 ul.menu_items {
401 margin: 0;
402 margin: 0;
402 padding: 0;
403 padding: 0;
403 }
404 }
404
405
405 li {
406 li {
406 margin: 0;
407 margin: 0;
407 padding: 0;
408 padding: 0;
408 line-height: 1em;
409 line-height: 1em;
409 list-style-type: none;
410 list-style-type: none;
410
411
411 a {
412 a {
412 display: block;
413 display: block;
413 height: 16px;
414 height: 16px;
414 padding: 8px; //must add up to td height (28px)
415 padding: 8px; //must add up to td height (28px)
415 width: 120px; // set width
416 width: 120px; // set width
416
417
417 &:hover {
418 &:hover {
418 background-color: @grey5;
419 background-color: @grey5;
419 -webkit-transition: background .3s;
420 -webkit-transition: background .3s;
420 -moz-transition: background .3s;
421 -moz-transition: background .3s;
421 -o-transition: background .3s;
422 -o-transition: background .3s;
422 transition: background .3s;
423 transition: background .3s;
423 }
424 }
424 }
425 }
425 }
426 }
426 }
427 }
427 }
428 }
428
429
430
431 // new objects main action
432 .action-menu {
433 left: auto;
434 right: 0;
435 padding: 12px;
436 z-index: 999;
437 overflow: hidden;
438 background-color: #fff;
439 border: 1px solid @grey5;
440 color: @grey2;
441 box-shadow: @dropdown-shadow;
442
443 .submenu-title {
444 font-weight: bold;
445 }
446
447 .submenu-title:not(:first-of-type) {
448 padding-top: 10px;
449 }
450
451 &.submenu {
452 min-width: 200px;
453
454 ol {
455 padding:0;
456 }
457
458 li {
459 display: block;
460 margin: 0;
461 padding: .2em .5em;
462 line-height: 1em;
463
464 background-color: #fff;
465 list-style-type: none;
466
467 a {
468 padding: 4px;
469 color: @grey4 !important;
470 border-bottom: none;
471 }
472 }
473 li:not(.submenu-title) a:hover{
474 color: @grey2 !important;
475 }
476 }
477 }
478
479
429 // Header Repository Switcher
480 // Header Repository Switcher
430 // Select2 Dropdown
481 // Select2 Dropdown
431 #select2-drop.select2-drop.repo-switcher-dropdown {
482 #select2-drop.select2-drop.repo-switcher-dropdown {
432 width: auto !important;
483 width: auto !important;
433 margin-top: 5px;
484 margin-top: 5px;
434 padding: 1em 0;
485 padding: 1em 0;
435 text-align: left;
486 text-align: left;
436 .border-radius-bottom(@border-radius);
487 .border-radius-bottom(@border-radius);
437 border-color: transparent;
488 border-color: transparent;
438 color: @grey6;
489 color: @grey6;
439 background-color: @grey2;
490 background-color: @grey2;
440
491
441 input {
492 input {
442 min-width: 90%;
493 min-width: 90%;
443 }
494 }
444
495
445 ul.select2-result-sub {
496 ul.select2-result-sub {
446
497
447 li {
498 li {
448 line-height: 1em;
499 line-height: 1em;
449
500
450 &:hover,
501 &:hover,
451 &.select2-highlighted {
502 &.select2-highlighted {
452 background-color: @grey3;
503 background-color: @grey3;
453 }
504 }
454 }
505 }
455
506
456 &:before { content: none; }
507 &:before { content: none; }
457 }
508 }
458
509
459 ul.select2-results {
510 ul.select2-results {
460 min-width: 200px;
511 min-width: 200px;
461 margin: 0;
512 margin: 0;
462 padding: 0;
513 padding: 0;
463 list-style-type: none;
514 list-style-type: none;
464 overflow-x: visible;
515 overflow-x: visible;
465 overflow-y: scroll;
516 overflow-y: scroll;
466
517
467 li {
518 li {
468 padding: 0 8px;
519 padding: 0 8px;
469 line-height: 1em;
520 line-height: 1em;
470 color: @grey6;
521 color: @grey6;
471
522
472 &>.select2-result-label {
523 &>.select2-result-label {
473 padding: 8px 0;
524 padding: 8px 0;
474 border-bottom: @border-thickness solid @grey3;
525 border-bottom: @border-thickness solid @grey3;
475 white-space: nowrap;
526 white-space: nowrap;
476 color: @grey5;
527 color: @grey5;
477 cursor: pointer;
528 cursor: pointer;
478 }
529 }
479
530
480 &.select2-result-with-children {
531 &.select2-result-with-children {
481 margin: 0;
532 margin: 0;
482 padding: 0;
533 padding: 0;
483 }
534 }
484
535
485 &.select2-result-unselectable > .select2-result-label {
536 &.select2-result-unselectable > .select2-result-label {
486 margin: 0 8px;
537 margin: 0 8px;
487 }
538 }
488
539
489 }
540 }
490 }
541 }
491
542
492 ul.select2-result-sub {
543 ul.select2-result-sub {
493 margin: 0;
544 margin: 0;
494 padding: 0;
545 padding: 0;
495
546
496 li {
547 li {
497 display: block;
548 display: block;
498 margin: 0;
549 margin: 0;
499 border-right: none;
550 border-right: none;
500 line-height: 1em;
551 line-height: 1em;
501 font-family: @text-light;
552 font-family: @text-light;
502 color: @grey2;
553 color: @grey2;
503 list-style-type: none;
554 list-style-type: none;
504
555
505 &:hover {
556 &:hover {
506 background-color: @grey3;
557 background-color: @grey3;
507 }
558 }
508 }
559 }
509 }
560 }
510 }
561 }
511
562
512
563
513 #context-bar {
564 #context-bar {
514 display: block;
565 display: block;
515 margin: 0 auto 20px 0;
566 margin: 0 auto 20px 0;
516 padding: 0 @header-padding;
567 padding: 0 @header-padding;
517 background-color: @grey7;
568 background-color: @grey7;
518 border-bottom: 1px solid @grey5;
569 border-bottom: 1px solid @grey5;
519
570
520 .clear {
571 .clear {
521 clear: both;
572 clear: both;
522 }
573 }
523 }
574 }
524
575
525 ul#context-pages {
576 ul#context-pages {
526 li {
577 li {
527 list-style-type: none;
578 list-style-type: none;
528
579
529 a {
580 a {
530 color: @grey2;
581 color: @grey2;
531
582
532 &:hover {
583 &:hover {
533 color: @grey1;
584 color: @grey1;
534 }
585 }
535 }
586 }
536
587
537 &.active {
588 &.active {
538 // special case, non-variable color
589 // special case, non-variable color
539 border-bottom: 2px solid @rcblue;
590 border-bottom: 2px solid @rcblue;
540
591
541 a {
592 a {
542 color: @rcblue;
593 color: @rcblue;
543 }
594 }
544 }
595 }
545 }
596 }
546 }
597 }
547
598
548 // PAGINATION
599 // PAGINATION
549
600
550 .pagination {
601 .pagination {
551 border: @border-thickness solid @grey5;
602 border: @border-thickness solid @grey5;
552 color: @grey2;
603 color: @grey2;
553 box-shadow: @button-shadow;
604 box-shadow: @button-shadow;
554
605
555 .current {
606 .current {
556 color: @grey4;
607 color: @grey4;
557 }
608 }
558 }
609 }
559
610
560 .dataTables_processing {
611 .dataTables_processing {
561 text-align: center;
612 text-align: center;
562 font-size: 1.1em;
613 font-size: 1.1em;
563 position: relative;
614 position: relative;
564 top: 95px;
615 top: 95px;
565 }
616 }
566
617
567 .dataTables_paginate, .pagination-wh {
618 .dataTables_paginate, .pagination-wh {
568 text-align: left;
619 text-align: left;
569 display: inline-block;
620 display: inline-block;
570 border-left: 1px solid @grey5;
621 border-left: 1px solid @grey5;
571 float: none;
622 float: none;
572 overflow: hidden;
623 overflow: hidden;
573 box-shadow: @button-shadow;
624 box-shadow: @button-shadow;
574
625
575 .paginate_button, .pager_curpage,
626 .paginate_button, .pager_curpage,
576 .pager_link, .pg-previous, .pg-next, .pager_dotdot {
627 .pager_link, .pg-previous, .pg-next, .pager_dotdot {
577 display: inline-block;
628 display: inline-block;
578 padding: @menupadding/4 @menupadding;
629 padding: @menupadding/4 @menupadding;
579 border: 1px solid @grey5;
630 border: 1px solid @grey5;
580 border-left: 0;
631 border-left: 0;
581 color: @grey2;
632 color: @grey2;
582 cursor: pointer;
633 cursor: pointer;
583 float: left;
634 float: left;
584
635
585 &:hover {
636 &:hover {
586 color: @rcdarkblue;
637 color: @rcdarkblue;
587 }
638 }
588 }
639 }
589
640
590 .paginate_button.disabled,
641 .paginate_button.disabled,
591 .disabled {
642 .disabled {
592 color: @grey3;
643 color: @grey3;
593 cursor: default;
644 cursor: default;
594 opacity: 0.5;
645 opacity: 0.5;
595 }
646 }
596
647
597 .paginate_button.current, .pager_curpage {
648 .paginate_button.current, .pager_curpage {
598 background: @rcblue;
649 background: @rcblue;
599 border-color: @rcblue;
650 border-color: @rcblue;
600 color: @white;
651 color: @white;
601 }
652 }
602
653
603 .ellipsis {
654 .ellipsis {
604 display: inline-block;
655 display: inline-block;
605 text-align: left;
656 text-align: left;
606 padding: @menupadding/4 @menupadding;
657 padding: @menupadding/4 @menupadding;
607 border: 1px solid @grey5;
658 border: 1px solid @grey5;
608 border-left: 0;
659 border-left: 0;
609 float: left;
660 float: left;
610 }
661 }
611 }
662 }
612
663
613 // SIDEBAR
664 // SIDEBAR
614
665
615 .sidebar {
666 .sidebar {
616 .block-left;
667 .block-left;
617 clear: left;
668 clear: left;
618 max-width: @sidebar-width;
669 max-width: @sidebar-width;
619 margin-right: @sidebarpadding;
670 margin-right: @sidebarpadding;
620 padding-right: @sidebarpadding;
671 padding-right: @sidebarpadding;
621 font-family: @text-regular;
672 font-family: @text-regular;
622 color: @grey1;
673 color: @grey1;
623
674
624 .nav-pills {
675 .nav-pills {
625 margin: 0;
676 margin: 0;
626 }
677 }
627
678
628 .nav {
679 .nav {
629 list-style: none;
680 list-style: none;
630 padding: 0;
681 padding: 0;
631
682
632 li {
683 li {
633 padding-bottom: @menupadding;
684 padding-bottom: @menupadding;
634 line-height: 1em;
685 line-height: 1em;
635 color: @grey4;
686 color: @grey4;
636 list-style-type: none;
687 list-style-type: none;
637
688
638 &.active a {
689 &.active a {
639 color: @grey2;
690 color: @grey2;
640 }
691 }
641
692
642 a {
693 a {
643 color: @grey4;
694 color: @grey4;
644 }
695 }
645 }
696 }
646
697
647 }
698 }
648 }
699 }
649
700
650 .main_filter_help_box {
701 .main_filter_help_box {
651 padding: 7px 7px;
702 padding: 7px 7px;
652 display: inline-block;
703 display: inline-block;
653 vertical-align: top;
704 vertical-align: top;
654 background: inherit;
705 background: inherit;
655 position: absolute;
706 position: absolute;
656 right: 0;
707 right: 0;
657 top: 9px;
708 top: 9px;
658 }
709 }
659
710
660 .main_filter_input_box {
711 .main_filter_input_box {
661 display: inline-block;
712 display: inline-block;
662
713
663 .searchItems {
714 .searchItems {
664 display:flex;
715 display:flex;
665 background: @black;
716 background: @black;
666 padding: 0px;
717 padding: 0px;
667 border-radius: 3px;
718 border-radius: 3px;
668 border: 1px solid @black;
719 border: 1px solid @black;
669
720
670 a {
721 a {
671 border: none !important;
722 border: none !important;
672 }
723 }
673 }
724 }
674
725
675 .searchTag {
726 .searchTag {
676 line-height: 28px;
727 line-height: 28px;
677 padding: 0 5px;
728 padding: 0 5px;
678
729
679 .tag {
730 .tag {
680 color: @grey5;
731 color: @grey5;
681 border-color: @grey2;
732 border-color: @grey2;
682 background: @grey1;
733 background: @grey1;
683 }
734 }
684 }
735 }
685
736
686 .searchTagFilter {
737 .searchTagFilter {
687 background-color: @black !important;
738 background-color: @black !important;
688 margin-right: 0;
739 margin-right: 0;
689 }
740 }
690
741
691 .searchTagHelp {
742 .searchTagHelp {
692 background-color: @grey1 !important;
743 background-color: @grey1 !important;
693 margin: 0;
744 margin: 0;
694 }
745 }
695 .searchTagHelp:hover {
746 .searchTagHelp:hover {
696 background-color: @grey1 !important;
747 background-color: @grey1 !important;
697 }
748 }
698 .searchTagInput {
749 .searchTagInput {
699 background-color: @grey1 !important;
750 background-color: @grey1 !important;
700 margin-right: 0;
751 margin-right: 0;
701 }
752 }
702 }
753 }
703
754
704 .main_filter_box {
755 .main_filter_box {
705 margin: 9px 0 0 0;
756 margin: 9px 0 0 0;
706 }
757 }
707
758
708 #main_filter_help {
759 #main_filter_help {
709 background: @grey1;
760 background: @grey1;
710 border: 1px solid black;
761 border: 1px solid black;
711 position: absolute;
762 position: absolute;
712 white-space: pre;
763 white-space: pre;
713 z-index: 9999;
764 z-index: 9999;
714 color: @nav-grey;
765 color: @nav-grey;
715 padding: 0 10px;
766 padding: 0 10px;
716 }
767 }
717
768
718 input {
769 input {
719
770
720 &.main_filter_input {
771 &.main_filter_input {
721 padding: 5px 10px;
772 padding: 5px 10px;
722 min-width: 340px;
773 min-width: 340px;
723 color: @grey7;
774 color: @grey7;
724 background: @black;
775 background: @black;
725 min-height: 18px;
776 min-height: 18px;
726 border: 0;
777 border: 0;
727
778
728 &:active {
779 &:active {
729 color: @grey2 !important;
780 color: @grey2 !important;
730 background: white !important;
781 background: white !important;
731 }
782 }
732 &:focus {
783 &:focus {
733 color: @grey2 !important;
784 color: @grey2 !important;
734 background: white !important;
785 background: white !important;
735 }
786 }
736 }
787 }
737 }
788 }
738
789
739
790
740
791
741 .main_filter_input::placeholder {
792 .main_filter_input::placeholder {
742 color: @nav-grey;
793 color: @nav-grey;
743 opacity: 1;
794 opacity: 1;
744 }
795 }
745
796
746 .notice-box {
797 .notice-box {
747 display:block !important;
798 display:block !important;
748 padding: 9px 0 !important;
799 padding: 9px 0 !important;
749 }
800 }
750
801
751 .menulabel-notice {
802 .menulabel-notice {
752 border: 1px solid @color5;
803 border: 1px solid @color5;
753 padding:7px 10px;
804 padding:7px 10px;
754 color: @color5;
805 color: @color5;
755 }
806 }
@@ -1,145 +1,137 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.mako"/>
2 <%inherit file="/base/base.mako"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 %if c.show_private:
5 %if c.show_private:
6 ${_('Private Gists for user {}').format(c.rhodecode_user.username)}
6 ${_('Private Gists for user {}').format(c.rhodecode_user.username)}
7 %elif c.show_public:
7 %elif c.show_public:
8 ${_('Public Gists for user {}').format(c.rhodecode_user.username)}
8 ${_('Public Gists for user {}').format(c.rhodecode_user.username)}
9 %else:
9 %else:
10 ${_('Public Gists')}
10 ${_('Public Gists')}
11 %endif
11 %endif
12 %if c.rhodecode_name:
12 %if c.rhodecode_name:
13 &middot; ${h.branding(c.rhodecode_name)}
13 &middot; ${h.branding(c.rhodecode_name)}
14 %endif
14 %endif
15 </%def>
15 </%def>
16
16
17 <%def name="breadcrumbs_links()"></%def>
17 <%def name="breadcrumbs_links()"></%def>
18
18
19 <%def name="menu_bar_nav()">
19 <%def name="menu_bar_nav()">
20 ${self.menu_items(active='gists')}
20 ${self.menu_items(active='gists')}
21 </%def>
21 </%def>
22
22
23 <%def name="main()">
23 <%def name="main()">
24
24
25 <div class="box">
25 <div class="box">
26 <div class="title">
26 <div class="title">
27
27
28 <ul class="button-links">
28 <ul class="button-links">
29 % if c.is_super_admin:
29 % if c.is_super_admin:
30 <li class="btn ${('active' if c.active=='all' else '')}"><a href="${h.route_path('gists_show', _query={'all': 1})}">${_('All gists')}</a></li>
30 <li class="btn ${('active' if c.active=='all' else '')}"><a href="${h.route_path('gists_show', _query={'all': 1})}">${_('All gists')}</a></li>
31 %endif
31 %endif
32 <li class="btn ${('active' if c.active=='public' else '')}"><a href="${h.route_path('gists_show')}">${_('All public')}</a></li>
32 <li class="btn ${('active' if c.active=='public' else '')}"><a href="${h.route_path('gists_show')}">${_('All public')}</a></li>
33 %if c.rhodecode_user.username != h.DEFAULT_USER:
33 %if c.rhodecode_user.username != h.DEFAULT_USER:
34 <li class="btn ${('active' if c.active=='my_all' else '')}"><a href="${h.route_path('gists_show', _query={'public':1, 'private': 1})}">${_('My gists')}</a></li>
34 <li class="btn ${('active' if c.active=='my_all' else '')}"><a href="${h.route_path('gists_show', _query={'public':1, 'private': 1})}">${_('My gists')}</a></li>
35 <li class="btn ${('active' if c.active=='my_private' else '')}"><a href="${h.route_path('gists_show', _query={'private': 1})}">${_('My private')}</a></li>
35 <li class="btn ${('active' if c.active=='my_private' else '')}"><a href="${h.route_path('gists_show', _query={'private': 1})}">${_('My private')}</a></li>
36 <li class="btn ${('active' if c.active=='my_public' else '')}"><a href="${h.route_path('gists_show', _query={'public': 1})}">${_('My public')}</a></li>
36 <li class="btn ${('active' if c.active=='my_public' else '')}"><a href="${h.route_path('gists_show', _query={'public': 1})}">${_('My public')}</a></li>
37 %endif
37 %endif
38 </ul>
38 </ul>
39
39
40 % if c.rhodecode_user.username != h.DEFAULT_USER:
41 <div class="pull-right">
42 <a class="btn btn-primary" href="${h.route_path('gists_new')}" >
43 ${_(u'Create New Gist')}
44 </a>
45 </div>
46 % endif
47
48 <div class="grid-quick-filter">
40 <div class="grid-quick-filter">
49 <ul class="grid-filter-box">
41 <ul class="grid-filter-box">
50 <li class="grid-filter-box-icon">
42 <li class="grid-filter-box-icon">
51 <i class="icon-search"></i>
43 <i class="icon-search"></i>
52 </li>
44 </li>
53 <li class="grid-filter-box-input">
45 <li class="grid-filter-box-input">
54 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
46 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
55 </li>
47 </li>
56 </ul>
48 </ul>
57 </div>
49 </div>
58
50
59 </div>
51 </div>
60
52
61 <div class="main-content-full-width">
53 <div class="main-content-full-width">
62 <div id="repos_list_wrap">
54 <div id="repos_list_wrap">
63 <table id="gist_list_table" class="display"></table>
55 <table id="gist_list_table" class="display"></table>
64 </div>
56 </div>
65 </div>
57 </div>
66
58
67 </div>
59 </div>
68
60
69 <script type="text/javascript">
61 <script type="text/javascript">
70 $(document).ready(function() {
62 $(document).ready(function() {
71
63
72 var get_datatable_count = function(){
64 var get_datatable_count = function(){
73 var api = $('#gist_list_table').dataTable().api();
65 var api = $('#gist_list_table').dataTable().api();
74 $('#gists_count').text(api.page.info().recordsDisplay);
66 $('#gists_count').text(api.page.info().recordsDisplay);
75 };
67 };
76
68
77
69
78 // custom filter that filters by access_id, description or author
70 // custom filter that filters by access_id, description or author
79 $.fn.dataTable.ext.search.push(
71 $.fn.dataTable.ext.search.push(
80 function( settings, data, dataIndex ) {
72 function( settings, data, dataIndex ) {
81 var query = $('#q_filter').val();
73 var query = $('#q_filter').val();
82 var author = data[0].strip();
74 var author = data[0].strip();
83 var access_id = data[2].strip();
75 var access_id = data[2].strip();
84 var description = data[3].strip();
76 var description = data[3].strip();
85
77
86 var query_str = (access_id + " " + author + " " + description).toLowerCase();
78 var query_str = (access_id + " " + author + " " + description).toLowerCase();
87
79
88 if(query_str.indexOf(query.toLowerCase()) !== -1){
80 if(query_str.indexOf(query.toLowerCase()) !== -1){
89 return true;
81 return true;
90 }
82 }
91 return false;
83 return false;
92 }
84 }
93 );
85 );
94
86
95 // gists list
87 // gists list
96 $('#gist_list_table').DataTable({
88 $('#gist_list_table').DataTable({
97 data: ${c.data|n},
89 data: ${c.data|n},
98 dom: 'rtp',
90 dom: 'rtp',
99 pageLength: ${c.visual.dashboard_items},
91 pageLength: ${c.visual.dashboard_items},
100 order: [[ 4, "desc" ]],
92 order: [[ 4, "desc" ]],
101 columns: [
93 columns: [
102 { data: {"_": "author",
94 { data: {"_": "author",
103 "sort": "author_raw"}, title: "${_("Author")}", width: "250px", className: "td-user" },
95 "sort": "author_raw"}, title: "${_("Author")}", width: "250px", className: "td-user" },
104 { data: {"_": "type",
96 { data: {"_": "type",
105 "sort": "type"}, title: "${_("Type")}", width: "70px", className: "td-tags" },
97 "sort": "type"}, title: "${_("Type")}", width: "70px", className: "td-tags" },
106 { data: {"_": "access_id",
98 { data: {"_": "access_id",
107 "sort": "access_id"}, title: "${_("Name")}", width:"150px", className: "td-componentname" },
99 "sort": "access_id"}, title: "${_("Name")}", width:"150px", className: "td-componentname" },
108 { data: {"_": "description",
100 { data: {"_": "description",
109 "sort": "description"}, title: "${_("Description")}", width: "250px", className: "td-description" },
101 "sort": "description"}, title: "${_("Description")}", width: "250px", className: "td-description" },
110 { data: {"_": "created_on",
102 { data: {"_": "created_on",
111 "sort": "created_on_raw"}, title: "${_("Created on")}", className: "td-time" },
103 "sort": "created_on_raw"}, title: "${_("Created on")}", className: "td-time" },
112 { data: {"_": "expires",
104 { data: {"_": "expires",
113 "sort": "expires"}, title: "${_("Expires")}", className: "td-exp" }
105 "sort": "expires"}, title: "${_("Expires")}", className: "td-exp" }
114 ],
106 ],
115 language: {
107 language: {
116 paginate: DEFAULT_GRID_PAGINATION,
108 paginate: DEFAULT_GRID_PAGINATION,
117 emptyTable: _gettext("No gists available yet.")
109 emptyTable: _gettext("No gists available yet.")
118 },
110 },
119 "initComplete": function( settings, json ) {
111 "initComplete": function( settings, json ) {
120 timeagoActivate();
112 timeagoActivate();
121 get_datatable_count();
113 get_datatable_count();
122 }
114 }
123 });
115 });
124
116
125 // update the counter when things change
117 // update the counter when things change
126 $('#gist_list_table').on('draw.dt', function() {
118 $('#gist_list_table').on('draw.dt', function() {
127 timeagoActivate();
119 timeagoActivate();
128 get_datatable_count();
120 get_datatable_count();
129 });
121 });
130
122
131 // filter, filter both grids
123 // filter, filter both grids
132 $('#q_filter').on( 'keyup', function () {
124 $('#q_filter').on( 'keyup', function () {
133 var repo_api = $('#gist_list_table').dataTable().api();
125 var repo_api = $('#gist_list_table').dataTable().api();
134 repo_api
126 repo_api
135 .draw();
127 .draw();
136 });
128 });
137
129
138 // refilter table if page load via back button
130 // refilter table if page load via back button
139 $("#q_filter").trigger('keyup');
131 $("#q_filter").trigger('keyup');
140
132
141 });
133 });
142
134
143 </script>
135 </script>
144 </%def>
136 </%def>
145
137
@@ -1,118 +1,111 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.mako"/>
2 <%inherit file="/base/base.mako"/>
3
3
4 <%def name="robots()">
4 <%def name="robots()">
5 %if c.gist.gist_type != 'public':
5 %if c.gist.gist_type != 'public':
6 <meta name="robots" content="noindex, nofollow">
6 <meta name="robots" content="noindex, nofollow">
7 %else:
7 %else:
8 ${parent.robots()}
8 ${parent.robots()}
9 %endif
9 %endif
10 </%def>
10 </%def>
11
11
12 <%def name="title()">
12 <%def name="title()">
13 ${_('Gist')} &middot; ${c.gist.gist_access_id}
13 ${_('Gist')} &middot; ${c.gist.gist_access_id}
14 %if c.rhodecode_name:
14 %if c.rhodecode_name:
15 &middot; ${h.branding(c.rhodecode_name)}
15 &middot; ${h.branding(c.rhodecode_name)}
16 %endif
16 %endif
17 </%def>
17 </%def>
18
18
19 <%def name="breadcrumbs_links()">
19 <%def name="breadcrumbs_links()">
20 ${_('Gist')} &middot; ${c.gist.gist_access_id}
20 ${_('Gist')} &middot; ${c.gist.gist_access_id}
21 </%def>
21 </%def>
22
22
23 <%def name="menu_bar_nav()">
23 <%def name="menu_bar_nav()">
24 ${self.menu_items(active='gists')}
24 ${self.menu_items(active='gists')}
25 </%def>
25 </%def>
26
26
27 <%def name="main()">
27 <%def name="main()">
28 <div class="box">
28 <div class="box">
29 <!-- box / title -->
29 <!-- box / title -->
30 <div class="title">
30 <div class="title">
31 ${self.breadcrumbs()}
31 ${self.breadcrumbs()}
32 %if c.rhodecode_user.username != h.DEFAULT_USER:
33 <ul class="links">
34 <li>
35 <a href="${h.route_path('gists_new')}" class="btn btn-primary">${_(u'Create New Gist')}</a>
36 </li>
37 </ul>
38 %endif
39 </div>
32 </div>
40
33
41 <div class="table">
34 <div class="table">
42 <div id="files_data">
35 <div id="files_data">
43 <div id="codeblock" class="codeblock">
36 <div id="codeblock" class="codeblock">
44 <div class="code-header">
37 <div class="code-header">
45 <div class="gist_url">
38 <div class="gist_url">
46 <code>
39 <code>
47 ${c.gist.gist_url()} <span class="icon-clipboard clipboard-action" data-clipboard-text="${c.gist.gist_url()}" title="${_('Copy the url')}"></span>
40 ${c.gist.gist_url()} <span class="icon-clipboard clipboard-action" data-clipboard-text="${c.gist.gist_url()}" title="${_('Copy the url')}"></span>
48 </code>
41 </code>
49 </div>
42 </div>
50 <div class="stats">
43 <div class="stats">
51 %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id:
44 %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id:
52 <div class="remove_gist">
45 <div class="remove_gist">
53 ${h.secure_form(h.route_path('gist_delete', gist_id=c.gist.gist_access_id), request=request)}
46 ${h.secure_form(h.route_path('gist_delete', gist_id=c.gist.gist_access_id), request=request)}
54 ${h.submit('remove_gist', _('Delete'),class_="btn btn-mini btn-danger",onclick="return confirm('"+_('Confirm to delete this Gist')+"');")}
47 ${h.submit('remove_gist', _('Delete'),class_="btn btn-mini btn-danger",onclick="return confirm('"+_('Confirm to delete this Gist')+"');")}
55 ${h.end_form()}
48 ${h.end_form()}
56 </div>
49 </div>
57 %endif
50 %endif
58 <div class="buttons">
51 <div class="buttons">
59 ## only owner should see that
52 ## only owner should see that
60 <a href="#copySource" onclick="return false;" class="btn btn-mini icon-clipboard clipboard-action" data-clipboard-text="${c.files[0].content}">${_('Copy content')}</a>
53 <a href="#copySource" onclick="return false;" class="btn btn-mini icon-clipboard clipboard-action" data-clipboard-text="${c.files[0].content}">${_('Copy content')}</a>
61
54
62 %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id:
55 %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id:
63 ${h.link_to(_('Edit'), h.route_path('gist_edit', gist_id=c.gist.gist_access_id), class_="btn btn-mini")}
56 ${h.link_to(_('Edit'), h.route_path('gist_edit', gist_id=c.gist.gist_access_id), class_="btn btn-mini")}
64 %endif
57 %endif
65 ${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")}
58 ${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")}
66 </div>
59 </div>
67 <div class="left" >
60 <div class="left" >
68 %if c.gist.gist_type != 'public':
61 %if c.gist.gist_type != 'public':
69 <span class="tag tag-ok disabled">${_('Private Gist')}</span>
62 <span class="tag tag-ok disabled">${_('Private Gist')}</span>
70 %endif
63 %endif
71 <span> ${c.gist.gist_description}</span>
64 <span> ${c.gist.gist_description}</span>
72 <span>${_('Expires')}:
65 <span>${_('Expires')}:
73 %if c.gist.gist_expires == -1:
66 %if c.gist.gist_expires == -1:
74 ${_('never')}
67 ${_('never')}
75 %else:
68 %else:
76 ${h.age_component(h.time_to_utcdatetime(c.gist.gist_expires))}
69 ${h.age_component(h.time_to_utcdatetime(c.gist.gist_expires))}
77 %endif
70 %endif
78 </span>
71 </span>
79
72
80 </div>
73 </div>
81 </div>
74 </div>
82
75
83 <div class="author">
76 <div class="author">
84 <div title="${h.tooltip(c.file_last_commit.author)}">
77 <div title="${h.tooltip(c.file_last_commit.author)}">
85 ${self.gravatar_with_user(c.file_last_commit.author, 16)} - ${_('created')} ${h.age_component(c.file_last_commit.date)}
78 ${self.gravatar_with_user(c.file_last_commit.author, 16)} - ${_('created')} ${h.age_component(c.file_last_commit.date)}
86 </div>
79 </div>
87
80
88 </div>
81 </div>
89 <div class="commit">${h.urlify_commit_message(c.file_last_commit.message, None)}</div>
82 <div class="commit">${h.urlify_commit_message(c.file_last_commit.message, None)}</div>
90 </div>
83 </div>
91
84
92 ## iterate over the files
85 ## iterate over the files
93 % for file in c.files:
86 % for file in c.files:
94 <% renderer = c.render and h.renderer_from_filename(file.path, exclude=['.txt', '.TXT'])%>
87 <% renderer = c.render and h.renderer_from_filename(file.path, exclude=['.txt', '.TXT'])%>
95 <!--
88 <!--
96 <div id="${h.FID('G', file.path)}" class="stats" >
89 <div id="${h.FID('G', file.path)}" class="stats" >
97 <a href="${c.gist.gist_url()}">ΒΆ</a>
90 <a href="${c.gist.gist_url()}">ΒΆ</a>
98 <b >${file.path}</b>
91 <b >${file.path}</b>
99 <div>
92 <div>
100 ${h.link_to(_('Show as raw'), h.route_path('gist_show_formatted_path', gist_id=c.gist.gist_access_id, revision=file.commit.raw_id, format='raw', f_path=file.path), class_="btn btn-mini")}
93 ${h.link_to(_('Show as raw'), h.route_path('gist_show_formatted_path', gist_id=c.gist.gist_access_id, revision=file.commit.raw_id, format='raw', f_path=file.path), class_="btn btn-mini")}
101 </div>
94 </div>
102 </div>
95 </div>
103 -->
96 -->
104 <div class="code-body textarea text-area editor">
97 <div class="code-body textarea text-area editor">
105 %if renderer:
98 %if renderer:
106 ${h.render(file.content, renderer=renderer)}
99 ${h.render(file.content, renderer=renderer)}
107 %else:
100 %else:
108 ${h.pygmentize(file,linenos=True,anchorlinenos=True,lineanchors='L',cssclass="code-highlight")}
101 ${h.pygmentize(file,linenos=True,anchorlinenos=True,lineanchors='L',cssclass="code-highlight")}
109 %endif
102 %endif
110 </div>
103 </div>
111 %endfor
104 %endfor
112 </div>
105 </div>
113 </div>
106 </div>
114 </div>
107 </div>
115
108
116
109
117 </div>
110 </div>
118 </%def>
111 </%def>
@@ -1,974 +1,1056 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="root.mako"/>
2 <%inherit file="root.mako"/>
3
3
4 <%include file="/ejs_templates/templates.html"/>
4 <%include file="/ejs_templates/templates.html"/>
5
5
6 <div class="outerwrapper">
6 <div class="outerwrapper">
7 <!-- HEADER -->
7 <!-- HEADER -->
8 <div class="header">
8 <div class="header">
9 <div id="header-inner" class="wrapper">
9 <div id="header-inner" class="wrapper">
10 <div id="logo">
10 <div id="logo">
11 <div class="logo-wrapper">
11 <div class="logo-wrapper">
12 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
12 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
13 </div>
13 </div>
14 % if c.rhodecode_name:
14 % if c.rhodecode_name:
15 <div class="branding">
15 <div class="branding">
16 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
16 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
17 </div>
17 </div>
18 % endif
18 % endif
19 </div>
19 </div>
20 <!-- MENU BAR NAV -->
20 <!-- MENU BAR NAV -->
21 ${self.menu_bar_nav()}
21 ${self.menu_bar_nav()}
22 <!-- END MENU BAR NAV -->
22 <!-- END MENU BAR NAV -->
23 </div>
23 </div>
24 </div>
24 </div>
25 ${self.menu_bar_subnav()}
25 ${self.menu_bar_subnav()}
26 <!-- END HEADER -->
26 <!-- END HEADER -->
27
27
28 <!-- CONTENT -->
28 <!-- CONTENT -->
29 <div id="content" class="wrapper">
29 <div id="content" class="wrapper">
30
30
31 <rhodecode-toast id="notifications"></rhodecode-toast>
31 <rhodecode-toast id="notifications"></rhodecode-toast>
32
32
33 <div class="main">
33 <div class="main">
34 ${next.main()}
34 ${next.main()}
35 </div>
35 </div>
36 </div>
36 </div>
37 <!-- END CONTENT -->
37 <!-- END CONTENT -->
38
38
39 </div>
39 </div>
40 <!-- FOOTER -->
40 <!-- FOOTER -->
41 <div id="footer">
41 <div id="footer">
42 <div id="footer-inner" class="title wrapper">
42 <div id="footer-inner" class="title wrapper">
43 <div>
43 <div>
44 <p class="footer-link-right">
44 <p class="footer-link-right">
45 % if c.visual.show_version:
45 % if c.visual.show_version:
46 RhodeCode Enterprise ${c.rhodecode_version} ${c.rhodecode_edition}
46 RhodeCode Enterprise ${c.rhodecode_version} ${c.rhodecode_edition}
47 % endif
47 % endif
48 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
48 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
49 % if c.visual.rhodecode_support_url:
49 % if c.visual.rhodecode_support_url:
50 <a href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a>
50 <a href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a>
51 % endif
51 % endif
52 </p>
52 </p>
53 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
53 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
54 <p class="server-instance" style="display:${sid}">
54 <p class="server-instance" style="display:${sid}">
55 ## display hidden instance ID if specially defined
55 ## display hidden instance ID if specially defined
56 % if c.rhodecode_instanceid:
56 % if c.rhodecode_instanceid:
57 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
57 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
58 % endif
58 % endif
59 </p>
59 </p>
60 </div>
60 </div>
61 </div>
61 </div>
62 </div>
62 </div>
63
63
64 <!-- END FOOTER -->
64 <!-- END FOOTER -->
65
65
66 ### MAKO DEFS ###
66 ### MAKO DEFS ###
67
67
68 <%def name="menu_bar_subnav()">
68 <%def name="menu_bar_subnav()">
69 </%def>
69 </%def>
70
70
71 <%def name="breadcrumbs(class_='breadcrumbs')">
71 <%def name="breadcrumbs(class_='breadcrumbs')">
72 <div class="${class_}">
72 <div class="${class_}">
73 ${self.breadcrumbs_links()}
73 ${self.breadcrumbs_links()}
74 </div>
74 </div>
75 </%def>
75 </%def>
76
76
77 <%def name="admin_menu(active=None)">
77 <%def name="admin_menu(active=None)">
78 <%
78 <%
79 def is_active(selected):
79 def is_active(selected):
80 if selected == active:
80 if selected == active:
81 return "active"
81 return "active"
82 %>
82 %>
83
83
84 <div id="context-bar">
84 <div id="context-bar">
85 <div class="wrapper">
85 <div class="wrapper">
86 <div class="title">
86 <div class="title">
87 <div class="title-content">
87 <div class="title-content">
88 <div class="title-main">
88 <div class="title-main">
89 % if c.is_super_admin:
89 % if c.is_super_admin:
90 ${_('Super Admin Panel')}
90 ${_('Super Admin Panel')}
91 % else:
91 % else:
92 ${_('Delegated Admin Panel')}
92 ${_('Delegated Admin Panel')}
93 % endif
93 % endif
94 </div>
94 </div>
95 </div>
95 </div>
96 </div>
96 </div>
97
97
98 <ul id="context-pages" class="navigation horizontal-list">
98 <ul id="context-pages" class="navigation horizontal-list">
99
99
100 ## super admin case
100 ## super admin case
101 % if c.is_super_admin:
101 % if c.is_super_admin:
102 <li class="${is_active('audit_logs')}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
102 <li class="${is_active('audit_logs')}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
103 <li class="${is_active('repositories')}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
103 <li class="${is_active('repositories')}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
104 <li class="${is_active('repository_groups')}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
104 <li class="${is_active('repository_groups')}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
105 <li class="${is_active('users')}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
105 <li class="${is_active('users')}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
106 <li class="${is_active('user_groups')}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
106 <li class="${is_active('user_groups')}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
107 <li class="${is_active('permissions')}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
107 <li class="${is_active('permissions')}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
108 <li class="${is_active('authentication')}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
108 <li class="${is_active('authentication')}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
109 <li class="${is_active('integrations')}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
109 <li class="${is_active('integrations')}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
110 <li class="${is_active('defaults')}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
110 <li class="${is_active('defaults')}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
111 <li class="${is_active('settings')}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
111 <li class="${is_active('settings')}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
112
112
113 ## delegated admin
113 ## delegated admin
114 % elif c.is_delegated_admin:
114 % elif c.is_delegated_admin:
115 <%
115 <%
116 repositories=c.auth_user.repositories_admin or c.can_create_repo
116 repositories=c.auth_user.repositories_admin or c.can_create_repo
117 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
117 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
118 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
118 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
119 %>
119 %>
120
120
121 %if repositories:
121 %if repositories:
122 <li class="${is_active('repositories')} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
122 <li class="${is_active('repositories')} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
123 %endif
123 %endif
124 %if repository_groups:
124 %if repository_groups:
125 <li class="${is_active('repository_groups')} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
125 <li class="${is_active('repository_groups')} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
126 %endif
126 %endif
127 %if user_groups:
127 %if user_groups:
128 <li class="${is_active('user_groups')} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
128 <li class="${is_active('user_groups')} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
129 %endif
129 %endif
130 % endif
130 % endif
131 </ul>
131 </ul>
132
132
133 </div>
133 </div>
134 <div class="clear"></div>
134 <div class="clear"></div>
135 </div>
135 </div>
136 </%def>
136 </%def>
137
137
138 <%def name="dt_info_panel(elements)">
138 <%def name="dt_info_panel(elements)">
139 <dl class="dl-horizontal">
139 <dl class="dl-horizontal">
140 %for dt, dd, title, show_items in elements:
140 %for dt, dd, title, show_items in elements:
141 <dt>${dt}:</dt>
141 <dt>${dt}:</dt>
142 <dd title="${h.tooltip(title)}">
142 <dd title="${h.tooltip(title)}">
143 %if callable(dd):
143 %if callable(dd):
144 ## allow lazy evaluation of elements
144 ## allow lazy evaluation of elements
145 ${dd()}
145 ${dd()}
146 %else:
146 %else:
147 ${dd}
147 ${dd}
148 %endif
148 %endif
149 %if show_items:
149 %if show_items:
150 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
150 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
151 %endif
151 %endif
152 </dd>
152 </dd>
153
153
154 %if show_items:
154 %if show_items:
155 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
155 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
156 %for item in show_items:
156 %for item in show_items:
157 <dt></dt>
157 <dt></dt>
158 <dd>${item}</dd>
158 <dd>${item}</dd>
159 %endfor
159 %endfor
160 </div>
160 </div>
161 %endif
161 %endif
162
162
163 %endfor
163 %endfor
164 </dl>
164 </dl>
165 </%def>
165 </%def>
166
166
167 <%def name="gravatar(email, size=16)">
167 <%def name="gravatar(email, size=16)">
168 <%
168 <%
169 if (size > 16):
169 if (size > 16):
170 gravatar_class = 'gravatar gravatar-large'
170 gravatar_class = 'gravatar gravatar-large'
171 else:
171 else:
172 gravatar_class = 'gravatar'
172 gravatar_class = 'gravatar'
173 %>
173 %>
174 <%doc>
174 <%doc>
175 TODO: johbo: For now we serve double size images to make it smooth
175 TODO: johbo: For now we serve double size images to make it smooth
176 for retina. This is how it worked until now. Should be replaced
176 for retina. This is how it worked until now. Should be replaced
177 with a better solution at some point.
177 with a better solution at some point.
178 </%doc>
178 </%doc>
179 <img class="${gravatar_class}" src="${h.gravatar_url(email, size * 2)}" height="${size}" width="${size}">
179 <img class="${gravatar_class}" src="${h.gravatar_url(email, size * 2)}" height="${size}" width="${size}">
180 </%def>
180 </%def>
181
181
182
182
183 <%def name="gravatar_with_user(contact, size=16, show_disabled=False)">
183 <%def name="gravatar_with_user(contact, size=16, show_disabled=False)">
184 <% email = h.email_or_none(contact) %>
184 <% email = h.email_or_none(contact) %>
185 <div class="rc-user tooltip" title="${h.tooltip(h.author_string(email))}">
185 <div class="rc-user tooltip" title="${h.tooltip(h.author_string(email))}">
186 ${self.gravatar(email, size)}
186 ${self.gravatar(email, size)}
187 <span class="${'user user-disabled' if show_disabled else 'user'}"> ${h.link_to_user(contact)}</span>
187 <span class="${'user user-disabled' if show_disabled else 'user'}"> ${h.link_to_user(contact)}</span>
188 </div>
188 </div>
189 </%def>
189 </%def>
190
190
191
191
192 <%def name="repo_page_title(repo_instance)">
192 <%def name="repo_page_title(repo_instance)">
193 <div class="title-content repo-title">
193 <div class="title-content repo-title">
194
194
195 <div class="title-main">
195 <div class="title-main">
196 ## SVN/HG/GIT icons
196 ## SVN/HG/GIT icons
197 %if h.is_hg(repo_instance):
197 %if h.is_hg(repo_instance):
198 <i class="icon-hg"></i>
198 <i class="icon-hg"></i>
199 %endif
199 %endif
200 %if h.is_git(repo_instance):
200 %if h.is_git(repo_instance):
201 <i class="icon-git"></i>
201 <i class="icon-git"></i>
202 %endif
202 %endif
203 %if h.is_svn(repo_instance):
203 %if h.is_svn(repo_instance):
204 <i class="icon-svn"></i>
204 <i class="icon-svn"></i>
205 %endif
205 %endif
206
206
207 ## public/private
207 ## public/private
208 %if repo_instance.private:
208 %if repo_instance.private:
209 <i class="icon-repo-private"></i>
209 <i class="icon-repo-private"></i>
210 %else:
210 %else:
211 <i class="icon-repo-public"></i>
211 <i class="icon-repo-public"></i>
212 %endif
212 %endif
213
213
214 ## repo name with group name
214 ## repo name with group name
215 ${h.breadcrumb_repo_link(repo_instance)}
215 ${h.breadcrumb_repo_link(repo_instance)}
216
216
217 ## Context Actions
217 ## Context Actions
218 <div class="pull-right">
218 <div class="pull-right">
219 %if c.rhodecode_user.username != h.DEFAULT_USER:
219 %if c.rhodecode_user.username != h.DEFAULT_USER:
220 <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>
220 <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>
221
221
222 <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 '')}">
222 <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 '')}">
223 % if c.repository_is_user_following:
223 % if c.repository_is_user_following:
224 <i class="icon-eye-off"></i>${_('Unwatch')}
224 <i class="icon-eye-off"></i>${_('Unwatch')}
225 % else:
225 % else:
226 <i class="icon-eye"></i>${_('Watch')}
226 <i class="icon-eye"></i>${_('Watch')}
227 % endif
227 % endif
228
228
229 </a>
229 </a>
230 %else:
230 %else:
231 <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>
231 <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>
232 %endif
232 %endif
233 </div>
233 </div>
234
234
235 </div>
235 </div>
236
236
237 ## FORKED
237 ## FORKED
238 %if repo_instance.fork:
238 %if repo_instance.fork:
239 <p class="discreet">
239 <p class="discreet">
240 <i class="icon-code-fork"></i> ${_('Fork of')}
240 <i class="icon-code-fork"></i> ${_('Fork of')}
241 ${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))}
241 ${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))}
242 </p>
242 </p>
243 %endif
243 %endif
244
244
245 ## IMPORTED FROM REMOTE
245 ## IMPORTED FROM REMOTE
246 %if repo_instance.clone_uri:
246 %if repo_instance.clone_uri:
247 <p class="discreet">
247 <p class="discreet">
248 <i class="icon-code-fork"></i> ${_('Clone from')}
248 <i class="icon-code-fork"></i> ${_('Clone from')}
249 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
249 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
250 </p>
250 </p>
251 %endif
251 %endif
252
252
253 ## LOCKING STATUS
253 ## LOCKING STATUS
254 %if repo_instance.locked[0]:
254 %if repo_instance.locked[0]:
255 <p class="locking_locked discreet">
255 <p class="locking_locked discreet">
256 <i class="icon-repo-lock"></i>
256 <i class="icon-repo-lock"></i>
257 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
257 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
258 </p>
258 </p>
259 %elif repo_instance.enable_locking:
259 %elif repo_instance.enable_locking:
260 <p class="locking_unlocked discreet">
260 <p class="locking_unlocked discreet">
261 <i class="icon-repo-unlock"></i>
261 <i class="icon-repo-unlock"></i>
262 ${_('Repository not locked. Pull repository to lock it.')}
262 ${_('Repository not locked. Pull repository to lock it.')}
263 </p>
263 </p>
264 %endif
264 %endif
265
265
266 </div>
266 </div>
267 </%def>
267 </%def>
268
268
269 <%def name="repo_menu(active=None)">
269 <%def name="repo_menu(active=None)">
270 <%
270 <%
271 def is_active(selected):
271 def is_active(selected):
272 if selected == active:
272 if selected == active:
273 return "active"
273 return "active"
274 ## determine if we have "any" option available
275 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
276 has_actions = can_lock
277
274 %>
278 %>
275 % if c.rhodecode_db_repo.archived:
279 % if c.rhodecode_db_repo.archived:
276 <div class="alert alert-warning text-center">
280 <div class="alert alert-warning text-center">
277 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
281 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
278 </div>
282 </div>
279 % endif
283 % endif
280
284
281 <!--- REPO CONTEXT BAR -->
285 <!--- REPO CONTEXT BAR -->
282 <div id="context-bar">
286 <div id="context-bar">
283 <div class="wrapper">
287 <div class="wrapper">
284
288
285 <div class="title">
289 <div class="title">
286 ${self.repo_page_title(c.rhodecode_db_repo)}
290 ${self.repo_page_title(c.rhodecode_db_repo)}
287 </div>
291 </div>
288
292
289 <ul id="context-pages" class="navigation horizontal-list">
293 <ul id="context-pages" class="navigation horizontal-list">
290 <li class="${is_active('summary')}"><a class="menulink" href="${h.route_path('repo_summary', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
294 <li class="${is_active('summary')}"><a class="menulink" href="${h.route_path('repo_summary', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
291 <li class="${is_active('commits')}"><a class="menulink" href="${h.route_path('repo_commits', repo_name=c.repo_name)}"><div class="menulabel">${_('Commits')}</div></a></li>
295 <li class="${is_active('commits')}"><a class="menulink" href="${h.route_path('repo_commits', repo_name=c.repo_name)}"><div class="menulabel">${_('Commits')}</div></a></li>
292 <li class="${is_active('files')}"><a class="menulink" href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.rhodecode_db_repo.landing_rev[1], f_path='')}"><div class="menulabel">${_('Files')}</div></a></li>
296 <li class="${is_active('files')}"><a class="menulink" href="${h.route_path('repo_files', repo_name=c.repo_name, commit_id=c.rhodecode_db_repo.landing_rev[1], f_path='')}"><div class="menulabel">${_('Files')}</div></a></li>
293 <li class="${is_active('compare')}"><a class="menulink" href="${h.route_path('repo_compare_select',repo_name=c.repo_name)}"><div class="menulabel">${_('Compare')}</div></a></li>
297 <li class="${is_active('compare')}"><a class="menulink" href="${h.route_path('repo_compare_select',repo_name=c.repo_name)}"><div class="menulabel">${_('Compare')}</div></a></li>
294
298
295 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
299 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
296 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
300 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
297 <li class="${is_active('showpullrequest')}">
301 <li class="${is_active('showpullrequest')}">
298 <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)}">
302 <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)}">
299 <div class="menulabel">
303 <div class="menulabel">
300 %if c.repository_pull_requests == 1:
304 %if c.repository_pull_requests == 1:
301 ${_('Pull Request')} ${c.repository_pull_requests}
305 ${_('Pull Request')} ${c.repository_pull_requests}
302 %else:
306 %else:
303 ${_('Pull Requests')} ${c.repository_pull_requests}
307 ${_('Pull Requests')} ${c.repository_pull_requests}
304 %endif
308 %endif
305 </div>
309 </div>
306 </a>
310 </a>
307 </li>
311 </li>
308 %endif
312 %endif
309
313
310 <li class="${is_active('artifacts')}"><a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}"><div class="menulabel">${_('Artifacts')}</div></a></li>
314 <li class="${is_active('artifacts')}"><a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}"><div class="menulabel">${_('Artifacts')}</div></a></li>
311
315
312 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
316 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
313 <li class="${is_active('settings')}"><a class="menulink" href="${h.route_path('edit_repo',repo_name=c.repo_name)}"><div class="menulabel">${_('Repository Settings')}</div></a></li>
317 <li class="${is_active('settings')}"><a class="menulink" href="${h.route_path('edit_repo',repo_name=c.repo_name)}"><div class="menulabel">${_('Repository Settings')}</div></a></li>
314 %endif
318 %endif
315
319
316 ## determine if we have "any" option available
317 <%
318 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
319 has_actions = (c.rhodecode_user.username != h.DEFAULT_USER and c.rhodecode_db_repo.repo_type in ['git','hg'] ) or can_lock
320 %>
321 <li class="${is_active('options')}">
320 <li class="${is_active('options')}">
322 % if has_actions:
321 % if has_actions:
323 <a class="menulink dropdown">
322 <a class="menulink dropdown">
324 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
323 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
325 </a>
324 </a>
326 <ul class="submenu">
325 <ul class="submenu">
327 <li><a href="${h.route_path('repo_fork_new',repo_name=c.repo_name)}">${_('Fork this repository')}</a></li>
328 <li><a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a></li>
329 %if can_lock:
326 %if can_lock:
330 %if c.rhodecode_db_repo.locked[0]:
327 %if c.rhodecode_db_repo.locked[0]:
331 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock Repository')}</a></li>
328 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock Repository')}</a></li>
332 %else:
329 %else:
333 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock Repository')}</a></li>
330 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock Repository')}</a></li>
334 %endif
331 %endif
335 %endif
332 %endif
336 </ul>
333 </ul>
337 % else:
334 % else:
338 <a class="menulink disabled">
335 <a class="menulink disabled">
339 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
336 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
340 </a>
337 </a>
341 % endif
338 % endif
342 </li>
339 </li>
343
340
344 </ul>
341 </ul>
345 </div>
342 </div>
346 <div class="clear"></div>
343 <div class="clear"></div>
347 </div>
344 </div>
348
345
349 <!--- REPO END CONTEXT BAR -->
346 <!--- REPO END CONTEXT BAR -->
350
347
351 </%def>
348 </%def>
352
349
353 <%def name="repo_group_page_title(repo_group_instance)">
350 <%def name="repo_group_page_title(repo_group_instance)">
354 <div class="title-content">
351 <div class="title-content">
355 <div class="title-main">
352 <div class="title-main">
356 ## Repository Group icon
353 ## Repository Group icon
357 <i class="icon-repo-group"></i>
354 <i class="icon-repo-group"></i>
358
355
359 ## repo name with group name
356 ## repo name with group name
360 ${h.breadcrumb_repo_group_link(repo_group_instance)}
357 ${h.breadcrumb_repo_group_link(repo_group_instance)}
361 </div>
358 </div>
362
359
363 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
360 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
364 <div class="repo-group-desc discreet">
361 <div class="repo-group-desc discreet">
365 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
362 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
366 </div>
363 </div>
367
364
368 </div>
365 </div>
369 </%def>
366 </%def>
370
367
368
371 <%def name="repo_group_menu(active=None)">
369 <%def name="repo_group_menu(active=None)">
372 <%
370 <%
373 def is_active(selected):
371 def is_active(selected):
374 if selected == active:
372 if selected == active:
375 return "active"
373 return "active"
376
374
377 gr_name = c.repo_group.group_name if c.repo_group else None
375 gr_name = c.repo_group.group_name if c.repo_group else None
378 # create repositories with write permission on group is set to true
376 # create repositories with write permission on group is set to true
379 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
380 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
377 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
381 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
382
378
383 %>
379 %>
384
380
381
385 <!--- REPO GROUP CONTEXT BAR -->
382 <!--- REPO GROUP CONTEXT BAR -->
386 <div id="context-bar">
383 <div id="context-bar">
387 <div class="wrapper">
384 <div class="wrapper">
388 <div class="title">
385 <div class="title">
389 ${self.repo_group_page_title(c.repo_group)}
386 ${self.repo_group_page_title(c.repo_group)}
390 </div>
387 </div>
391
388
392 <ul id="context-pages" class="navigation horizontal-list">
389 <ul id="context-pages" class="navigation horizontal-list">
393 <li class="${is_active('home')}"><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></li>
390 <li class="${is_active('home')}">
391 <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>
392 </li>
394 % if c.is_super_admin or group_admin:
393 % if c.is_super_admin or group_admin:
395 <li class="${is_active('settings')}"><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></li>
394 <li class="${is_active('settings')}">
395 <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>
396 </li>
396 % endif
397 % endif
397 ## determine if we have "any" option available
398
398 <%
399 can_create_repos = c.is_super_admin or group_admin or (group_write and create_on_write)
400 can_create_repo_groups = c.is_super_admin or group_admin
401 has_actions = can_create_repos or can_create_repo_groups
402 %>
403 <li class="${is_active('options')}">
404 % if has_actions:
405 <a class="menulink dropdown">
406 <div class="menulabel">${_('Options')} <div class="show_more"></div></div>
407 </a>
408 <ul class="submenu">
409 %if can_create_repos:
410 <li><a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('Add Repository')}</a></li>
411 %endif
412 %if can_create_repo_groups:
413 <li><a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'Add Repository Group')}</a></li>
414 %endif
415 </ul>
416 % else:
417 <a class="menulink disabled">
418 <div class="menulabel">${_('Options')} <div class="show_more"></div></div>
419 </a>
420 % endif
421 </li>
422 </ul>
399 </ul>
423 </div>
400 </div>
424 <div class="clear"></div>
401 <div class="clear"></div>
425 </div>
402 </div>
426
403
427 <!--- REPO GROUP CONTEXT BAR -->
404 <!--- REPO GROUP CONTEXT BAR -->
428
405
429 </%def>
406 </%def>
430
407
431
408
432 <%def name="usermenu(active=False)">
409 <%def name="usermenu(active=False)">
410 <%
411 not_anonymous = c.rhodecode_user.username != h.DEFAULT_USER
412
413 gr_name = c.repo_group.group_name if (hasattr(c, 'repo_group') and c.repo_group) else None
414 # create repositories with write permission on group is set to true
415
416 can_fork = c.is_super_admin or h.HasPermissionAny('hg.fork.repository')()
417 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
418 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
419 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
420
421 can_create_repos = c.is_super_admin or c.can_create_repo
422 can_create_repo_groups = c.is_super_admin or c.can_create_repo_group
423
424 can_create_repos_in_group = c.is_super_admin or group_admin or (group_write and create_on_write)
425 can_create_repo_groups_in_group = c.is_super_admin or group_admin
426 %>
427
428 % if not_anonymous:
429 <%
430 default_target_group = dict()
431 if c.rhodecode_user.personal_repo_group:
432 default_target_group = dict(parent_group=c.rhodecode_user.personal_repo_group.group_id)
433 %>
434
435 ## create action
436 <li>
437 <a href="#create-actions" onclick="return false;" class="menulink childs">
438 <i class="icon-plus-circled"></i>
439 </a>
440
441 <div class="action-menu submenu">
442
443 <ol>
444 ## scope of within a repository
445 % if hasattr(c, 'rhodecode_db_repo') and c.rhodecode_db_repo:
446 <li class="submenu-title">${_('This Repository')}</li>
447 <li>
448 <a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a>
449 </li>
450 % if can_fork:
451 <li>
452 <a href="${h.route_path('repo_fork_new',repo_name=c.repo_name,_query=default_target_group)}">${_('Fork this repository')}</a>
453 </li>
454 % endif
455 % endif
456
457 ## scope of within repository groups
458 % if hasattr(c, 'repo_group') and c.repo_group and (can_create_repos_in_group or can_create_repo_groups_in_group):
459 <li class="submenu-title">${_('This Repository Group')}</li>
460
461 % if can_create_repos_in_group:
462 <li>
463 <a href="${h.route_path('repo_new',_query=default_target_group)}">${_('New Repository')}</a>
464 </li>
465 % endif
466
467 % if can_create_repo_groups_in_group:
468 <li>
469 <a href="${h.route_path('repo_group_new',_query=default_target_group)}">${_(u'New Repository Group')}</a>
470 </li>
471 % endif
472 % endif
473
474 ## personal group
475 % if c.rhodecode_user.personal_repo_group:
476 <li class="submenu-title">Personal Group</li>
477
478 <li>
479 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}" >${_('New Repository')} </a>
480 </li>
481
482 <li>
483 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}">${_('New Repository Group')} </a>
484 </li>
485 % endif
486
487 ## Global actions
488 <li class="submenu-title">RhodeCode</li>
489 % if can_create_repos:
490 <li>
491 <a href="${h.route_path('repo_new')}" >${_('New Repository')}</a>
492 </li>
493 % endif
494
495 % if can_create_repo_groups:
496 <li>
497 <a href="${h.route_path('repo_group_new')}" >${_(u'New Repository Group')}</a>
498 </li>
499 % endif
500
501 <li>
502 <a href="${h.route_path('gists_new')}">${_(u'New Gist')}</a>
503 </li>
504
505 </ol>
506
507 </div>
508 </li>
509
510 ## notifications
511 <li>
512 <a class="${('empty' if c.unread_notifications == 0 else '')}" href="${h.route_path('notifications_show_all')}">
513 ${c.unread_notifications}
514 </a>
515 </li>
516 % endif
517
433 ## USER MENU
518 ## USER MENU
434 <li id="quick_login_li" class="${'active' if active else ''}">
519 <li id="quick_login_li" class="${'active' if active else ''}">
435 % if c.rhodecode_user.username == h.DEFAULT_USER:
520 % if c.rhodecode_user.username == h.DEFAULT_USER:
436 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
521 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
437 ${gravatar(c.rhodecode_user.email, 20)}
522 ${gravatar(c.rhodecode_user.email, 20)}
438 <span class="user">
523 <span class="user">
439 <span>${_('Sign in')}</span>
524 <span>${_('Sign in')}</span>
440 </span>
525 </span>
441 </a>
526 </a>
442 % else:
527 % else:
443 ## logged in user
528 ## logged in user
444 <a id="quick_login_link" class="menulink childs">
529 <a id="quick_login_link" class="menulink childs">
445 ${gravatar(c.rhodecode_user.email, 20)}
530 ${gravatar(c.rhodecode_user.email, 20)}
446 <span class="user">
531 <span class="user">
447 <span class="menu_link_user">${c.rhodecode_user.username}</span>
532 <span class="menu_link_user">${c.rhodecode_user.username}</span>
448 <div class="show_more"></div>
533 <div class="show_more"></div>
449 </span>
534 </span>
450 </a>
535 </a>
451 ## subnav with menu for logged in user
536 ## subnav with menu for logged in user
452 <div class="user-menu submenu">
537 <div class="user-menu submenu">
453 <div id="quick_login">
538 <div id="quick_login">
454 %if c.rhodecode_user.username != h.DEFAULT_USER:
539 %if c.rhodecode_user.username != h.DEFAULT_USER:
455 <div class="">
540 <div class="">
456 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
541 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
457 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
542 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
458 <div class="email">${c.rhodecode_user.email}</div>
543 <div class="email">${c.rhodecode_user.email}</div>
459 </div>
544 </div>
460 <div class="">
545 <div class="">
461 <ol class="links">
546 <ol class="links">
462 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
547 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
463 % if c.rhodecode_user.personal_repo_group:
548 % if c.rhodecode_user.personal_repo_group:
464 <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>
549 <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>
465 % endif
550 % endif
466 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
551 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
467 ## bookmark-items
552 ## bookmark-items
468 <li class="bookmark-items">
553 <li class="bookmark-items">
469 ${_('Bookmarks')}
554 ${_('Bookmarks')}
470 <div class="pull-right">
555 <div class="pull-right">
471 <a href="${h.route_path('my_account_bookmarks')}">${_('Manage')}</a>
556 <a href="${h.route_path('my_account_bookmarks')}">${_('Manage')}</a>
472 </div>
557 </div>
473 </li>
558 </li>
474 % if not c.bookmark_items:
559 % if not c.bookmark_items:
475 <li>
560 <li>
476 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
561 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
477 </li>
562 </li>
478 % endif
563 % endif
479 % for item in c.bookmark_items:
564 % for item in c.bookmark_items:
480 <li>
565 <li>
481 % if item.repository:
566 % if item.repository:
482 <div>
567 <div>
483 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
568 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
484 <code>${item.position}</code>
569 <code>${item.position}</code>
485 % if item.repository.repo_type == 'hg':
570 % if item.repository.repo_type == 'hg':
486 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
571 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
487 % elif item.repository.repo_type == 'git':
572 % elif item.repository.repo_type == 'git':
488 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
573 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
489 % elif item.repository.repo_type == 'svn':
574 % elif item.repository.repo_type == 'svn':
490 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
575 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
491 % endif
576 % endif
492 ${(item.title or h.shorter(item.repository.repo_name, 30))}
577 ${(item.title or h.shorter(item.repository.repo_name, 30))}
493 </a>
578 </a>
494 </div>
579 </div>
495 % elif item.repository_group:
580 % elif item.repository_group:
496 <div>
581 <div>
497 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
582 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
498 <code>${item.position}</code>
583 <code>${item.position}</code>
499 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
584 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
500 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
585 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
501 </a>
586 </a>
502 </div>
587 </div>
503 % else:
588 % else:
504 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
589 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
505 <code>${item.position}</code>
590 <code>${item.position}</code>
506 ${item.title}
591 ${item.title}
507 </a>
592 </a>
508 % endif
593 % endif
509 </li>
594 </li>
510 % endfor
595 % endfor
511
596
512 <li class="logout">
597 <li class="logout">
513 ${h.secure_form(h.route_path('logout'), request=request)}
598 ${h.secure_form(h.route_path('logout'), request=request)}
514 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
599 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
515 ${h.end_form()}
600 ${h.end_form()}
516 </li>
601 </li>
517 </ol>
602 </ol>
518 </div>
603 </div>
519 %endif
604 %endif
520 </div>
605 </div>
521 </div>
606 </div>
522 ## unread counter
607
523 <div class="pill_container">
524 <a class="menu_link_notifications ${'empty' if c.unread_notifications == 0 else ''}" href="${h.route_path('notifications_show_all')}">${c.unread_notifications}</a>
525 </div>
526 % endif
608 % endif
527 </li>
609 </li>
528 </%def>
610 </%def>
529
611
530 <%def name="menu_items(active=None)">
612 <%def name="menu_items(active=None)">
531 <%
613 <%
532 def is_active(selected):
614 def is_active(selected):
533 if selected == active:
615 if selected == active:
534 return "active"
616 return "active"
535 return ""
617 return ""
536 %>
618 %>
537
619
538 <ul id="quick" class="main_nav navigation horizontal-list">
620 <ul id="quick" class="main_nav navigation horizontal-list">
539 ## notice box for important system messages
621 ## notice box for important system messages
540 <li style="display: none">
622 <li style="display: none">
541 <a class="notice-box" href="#openNotice" onclick="return false">
623 <a class="notice-box" href="#openNotice" onclick="return false">
542 <div class="menulabel-notice" >
624 <div class="menulabel-notice" >
543 0
625 0
544 </div>
626 </div>
545 </a>
627 </a>
546 </li>
628 </li>
547
629
548 ## Main filter
630 ## Main filter
549 <li>
631 <li>
550 <div class="menulabel main_filter_box">
632 <div class="menulabel main_filter_box">
551 <div class="main_filter_input_box">
633 <div class="main_filter_input_box">
552 <ul class="searchItems">
634 <ul class="searchItems">
553
635
554 % if c.template_context['search_context']['repo_id']:
636 % if c.template_context['search_context']['repo_id']:
555 <li class="searchTag searchTagFilter searchTagHidable" >
637 <li class="searchTag searchTagFilter searchTagHidable" >
556 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
638 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
557 <span class="tag">
639 <span class="tag">
558 This repo
640 This repo
559 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
641 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
560 </span>
642 </span>
561 ##</a>
643 ##</a>
562 </li>
644 </li>
563 % elif c.template_context['search_context']['repo_group_id']:
645 % elif c.template_context['search_context']['repo_group_id']:
564 <li class="searchTag searchTagFilter searchTagHidable">
646 <li class="searchTag searchTagFilter searchTagHidable">
565 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
647 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
566 <span class="tag">
648 <span class="tag">
567 This group
649 This group
568 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
650 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
569 </span>
651 </span>
570 ##</a>
652 ##</a>
571 </li>
653 </li>
572 % endif
654 % endif
573
655
574 <li class="searchTagInput">
656 <li class="searchTagInput">
575 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
657 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
576 </li>
658 </li>
577 <li class="searchTag searchTagHelp">
659 <li class="searchTag searchTagHelp">
578 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
660 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
579 </li>
661 </li>
580 </ul>
662 </ul>
581 </div>
663 </div>
582 </div>
664 </div>
583
665
584 <div id="main_filter_help" style="display: none">
666 <div id="main_filter_help" style="display: none">
585 - Use '/' key to quickly access this field.
667 - Use '/' key to quickly access this field.
586
668
587 - Enter a name of repository, or repository group for quick search.
669 - Enter a name of repository, or repository group for quick search.
588
670
589 - Prefix query to allow special search:
671 - Prefix query to allow special search:
590
672
591 user:admin, to search for usernames, always global
673 user:admin, to search for usernames, always global
592
674
593 user_group:devops, to search for user groups, always global
675 user_group:devops, to search for user groups, always global
594
676
595 commit:efced4, to search for commits, scoped to repositories or groups
677 commit:efced4, to search for commits, scoped to repositories or groups
596
678
597 file:models.py, to search for file paths, scoped to repositories or groups
679 file:models.py, to search for file paths, scoped to repositories or groups
598
680
599 % if c.template_context['search_context']['repo_id']:
681 % if c.template_context['search_context']['repo_id']:
600 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>
682 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>
601 % elif c.template_context['search_context']['repo_group_id']:
683 % elif c.template_context['search_context']['repo_group_id']:
602 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>
684 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>
603 % else:
685 % else:
604 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
686 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
605 % endif
687 % endif
606 </div>
688 </div>
607 </li>
689 </li>
608
690
609 ## ROOT MENU
691 ## ROOT MENU
610 <li class="${is_active('home')}">
692 <li class="${is_active('home')}">
611 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
693 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
612 <div class="menulabel">${_('Home')}</div>
694 <div class="menulabel">${_('Home')}</div>
613 </a>
695 </a>
614 </li>
696 </li>
615
697
616 %if c.rhodecode_user.username != h.DEFAULT_USER:
698 %if c.rhodecode_user.username != h.DEFAULT_USER:
617 <li class="${is_active('journal')}">
699 <li class="${is_active('journal')}">
618 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
700 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
619 <div class="menulabel">${_('Journal')}</div>
701 <div class="menulabel">${_('Journal')}</div>
620 </a>
702 </a>
621 </li>
703 </li>
622 %else:
704 %else:
623 <li class="${is_active('journal')}">
705 <li class="${is_active('journal')}">
624 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
706 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
625 <div class="menulabel">${_('Public journal')}</div>
707 <div class="menulabel">${_('Public journal')}</div>
626 </a>
708 </a>
627 </li>
709 </li>
628 %endif
710 %endif
629
711
630 <li class="${is_active('gists')}">
712 <li class="${is_active('gists')}">
631 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
713 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
632 <div class="menulabel">${_('Gists')}</div>
714 <div class="menulabel">${_('Gists')}</div>
633 </a>
715 </a>
634 </li>
716 </li>
635
717
636 % if c.is_super_admin or c.is_delegated_admin:
718 % if c.is_super_admin or c.is_delegated_admin:
637 <li class="${is_active('admin')}">
719 <li class="${is_active('admin')}">
638 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
720 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
639 <div class="menulabel">${_('Admin')} </div>
721 <div class="menulabel">${_('Admin')} </div>
640 </a>
722 </a>
641 </li>
723 </li>
642 % endif
724 % endif
643
725
644 ## render extra user menu
726 ## render extra user menu
645 ${usermenu(active=(active=='my_account'))}
727 ${usermenu(active=(active=='my_account'))}
646
728
647 % if c.debug_style:
729 % if c.debug_style:
648 <li>
730 <li>
649 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
731 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
650 <div class="menulabel">${_('[Style]')}</div>
732 <div class="menulabel">${_('[Style]')}</div>
651 </a>
733 </a>
652 </li>
734 </li>
653 % endif
735 % endif
654 </ul>
736 </ul>
655
737
656 <script type="text/javascript">
738 <script type="text/javascript">
657 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
739 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
658
740
659 var formatRepoResult = function(result, container, query, escapeMarkup) {
741 var formatRepoResult = function(result, container, query, escapeMarkup) {
660 return function(data, escapeMarkup) {
742 return function(data, escapeMarkup) {
661 if (!data.repo_id){
743 if (!data.repo_id){
662 return data.text; // optgroup text Repositories
744 return data.text; // optgroup text Repositories
663 }
745 }
664
746
665 var tmpl = '';
747 var tmpl = '';
666 var repoType = data['repo_type'];
748 var repoType = data['repo_type'];
667 var repoName = data['text'];
749 var repoName = data['text'];
668
750
669 if(data && data.type == 'repo'){
751 if(data && data.type == 'repo'){
670 if(repoType === 'hg'){
752 if(repoType === 'hg'){
671 tmpl += '<i class="icon-hg"></i> ';
753 tmpl += '<i class="icon-hg"></i> ';
672 }
754 }
673 else if(repoType === 'git'){
755 else if(repoType === 'git'){
674 tmpl += '<i class="icon-git"></i> ';
756 tmpl += '<i class="icon-git"></i> ';
675 }
757 }
676 else if(repoType === 'svn'){
758 else if(repoType === 'svn'){
677 tmpl += '<i class="icon-svn"></i> ';
759 tmpl += '<i class="icon-svn"></i> ';
678 }
760 }
679 if(data['private']){
761 if(data['private']){
680 tmpl += '<i class="icon-lock" ></i> ';
762 tmpl += '<i class="icon-lock" ></i> ';
681 }
763 }
682 else if(visualShowPublicIcon){
764 else if(visualShowPublicIcon){
683 tmpl += '<i class="icon-unlock-alt"></i> ';
765 tmpl += '<i class="icon-unlock-alt"></i> ';
684 }
766 }
685 }
767 }
686 tmpl += escapeMarkup(repoName);
768 tmpl += escapeMarkup(repoName);
687 return tmpl;
769 return tmpl;
688
770
689 }(result, escapeMarkup);
771 }(result, escapeMarkup);
690 };
772 };
691
773
692 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
774 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
693 return function(data, escapeMarkup) {
775 return function(data, escapeMarkup) {
694 if (!data.repo_group_id){
776 if (!data.repo_group_id){
695 return data.text; // optgroup text Repositories
777 return data.text; // optgroup text Repositories
696 }
778 }
697
779
698 var tmpl = '';
780 var tmpl = '';
699 var repoGroupName = data['text'];
781 var repoGroupName = data['text'];
700
782
701 if(data){
783 if(data){
702
784
703 tmpl += '<i class="icon-repo-group"></i> ';
785 tmpl += '<i class="icon-repo-group"></i> ';
704
786
705 }
787 }
706 tmpl += escapeMarkup(repoGroupName);
788 tmpl += escapeMarkup(repoGroupName);
707 return tmpl;
789 return tmpl;
708
790
709 }(result, escapeMarkup);
791 }(result, escapeMarkup);
710 };
792 };
711
793
712 var escapeRegExChars = function (value) {
794 var escapeRegExChars = function (value) {
713 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
795 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
714 };
796 };
715
797
716 var getRepoIcon = function(repo_type) {
798 var getRepoIcon = function(repo_type) {
717 if (repo_type === 'hg') {
799 if (repo_type === 'hg') {
718 return '<i class="icon-hg"></i> ';
800 return '<i class="icon-hg"></i> ';
719 }
801 }
720 else if (repo_type === 'git') {
802 else if (repo_type === 'git') {
721 return '<i class="icon-git"></i> ';
803 return '<i class="icon-git"></i> ';
722 }
804 }
723 else if (repo_type === 'svn') {
805 else if (repo_type === 'svn') {
724 return '<i class="icon-svn"></i> ';
806 return '<i class="icon-svn"></i> ';
725 }
807 }
726 return ''
808 return ''
727 };
809 };
728
810
729 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
811 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
730
812
731 if (value.split(':').length === 2) {
813 if (value.split(':').length === 2) {
732 value = value.split(':')[1]
814 value = value.split(':')[1]
733 }
815 }
734
816
735 var searchType = data['type'];
817 var searchType = data['type'];
736 var searchSubType = data['subtype'];
818 var searchSubType = data['subtype'];
737 var valueDisplay = data['value_display'];
819 var valueDisplay = data['value_display'];
738
820
739 var pattern = '(' + escapeRegExChars(value) + ')';
821 var pattern = '(' + escapeRegExChars(value) + ')';
740
822
741 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
823 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
742
824
743 // highlight match
825 // highlight match
744 if (searchType != 'text') {
826 if (searchType != 'text') {
745 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
827 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
746 }
828 }
747
829
748 var icon = '';
830 var icon = '';
749
831
750 if (searchType === 'hint') {
832 if (searchType === 'hint') {
751 icon += '<i class="icon-repo-group"></i> ';
833 icon += '<i class="icon-repo-group"></i> ';
752 }
834 }
753 // full text search/hints
835 // full text search/hints
754 else if (searchType === 'search') {
836 else if (searchType === 'search') {
755 icon += '<i class="icon-more"></i> ';
837 icon += '<i class="icon-more"></i> ';
756 if (searchSubType !== undefined && searchSubType == 'repo') {
838 if (searchSubType !== undefined && searchSubType == 'repo') {
757 valueDisplay += '<div class="pull-right tag">repository</div>';
839 valueDisplay += '<div class="pull-right tag">repository</div>';
758 }
840 }
759 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
841 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
760 valueDisplay += '<div class="pull-right tag">repo group</div>';
842 valueDisplay += '<div class="pull-right tag">repo group</div>';
761 }
843 }
762 }
844 }
763 // repository
845 // repository
764 else if (searchType === 'repo') {
846 else if (searchType === 'repo') {
765
847
766 var repoIcon = getRepoIcon(data['repo_type']);
848 var repoIcon = getRepoIcon(data['repo_type']);
767 icon += repoIcon;
849 icon += repoIcon;
768
850
769 if (data['private']) {
851 if (data['private']) {
770 icon += '<i class="icon-lock" ></i> ';
852 icon += '<i class="icon-lock" ></i> ';
771 }
853 }
772 else if (visualShowPublicIcon) {
854 else if (visualShowPublicIcon) {
773 icon += '<i class="icon-unlock-alt"></i> ';
855 icon += '<i class="icon-unlock-alt"></i> ';
774 }
856 }
775 }
857 }
776 // repository groups
858 // repository groups
777 else if (searchType === 'repo_group') {
859 else if (searchType === 'repo_group') {
778 icon += '<i class="icon-repo-group"></i> ';
860 icon += '<i class="icon-repo-group"></i> ';
779 }
861 }
780 // user group
862 // user group
781 else if (searchType === 'user_group') {
863 else if (searchType === 'user_group') {
782 icon += '<i class="icon-group"></i> ';
864 icon += '<i class="icon-group"></i> ';
783 }
865 }
784 // user
866 // user
785 else if (searchType === 'user') {
867 else if (searchType === 'user') {
786 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
868 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
787 }
869 }
788 // commit
870 // commit
789 else if (searchType === 'commit') {
871 else if (searchType === 'commit') {
790 var repo_data = data['repo_data'];
872 var repo_data = data['repo_data'];
791 var repoIcon = getRepoIcon(repo_data['repository_type']);
873 var repoIcon = getRepoIcon(repo_data['repository_type']);
792 if (repoIcon) {
874 if (repoIcon) {
793 icon += repoIcon;
875 icon += repoIcon;
794 } else {
876 } else {
795 icon += '<i class="icon-tag"></i>';
877 icon += '<i class="icon-tag"></i>';
796 }
878 }
797 }
879 }
798 // file
880 // file
799 else if (searchType === 'file') {
881 else if (searchType === 'file') {
800 var repo_data = data['repo_data'];
882 var repo_data = data['repo_data'];
801 var repoIcon = getRepoIcon(repo_data['repository_type']);
883 var repoIcon = getRepoIcon(repo_data['repository_type']);
802 if (repoIcon) {
884 if (repoIcon) {
803 icon += repoIcon;
885 icon += repoIcon;
804 } else {
886 } else {
805 icon += '<i class="icon-tag"></i>';
887 icon += '<i class="icon-tag"></i>';
806 }
888 }
807 }
889 }
808 // generic text
890 // generic text
809 else if (searchType === 'text') {
891 else if (searchType === 'text') {
810 icon = '';
892 icon = '';
811 }
893 }
812
894
813 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
895 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
814 return tmpl.format(icon, valueDisplay);
896 return tmpl.format(icon, valueDisplay);
815 };
897 };
816
898
817 var handleSelect = function(element, suggestion) {
899 var handleSelect = function(element, suggestion) {
818 if (suggestion.type === "hint") {
900 if (suggestion.type === "hint") {
819 // we skip action
901 // we skip action
820 $('#main_filter').focus();
902 $('#main_filter').focus();
821 }
903 }
822 else if (suggestion.type === "text") {
904 else if (suggestion.type === "text") {
823 // we skip action
905 // we skip action
824 $('#main_filter').focus();
906 $('#main_filter').focus();
825
907
826 } else {
908 } else {
827 window.location = suggestion['url'];
909 window.location = suggestion['url'];
828 }
910 }
829 };
911 };
830
912
831 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
913 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
832 if (queryLowerCase.split(':').length === 2) {
914 if (queryLowerCase.split(':').length === 2) {
833 queryLowerCase = queryLowerCase.split(':')[1]
915 queryLowerCase = queryLowerCase.split(':')[1]
834 }
916 }
835 if (suggestion.type === "text") {
917 if (suggestion.type === "text") {
836 // special case we don't want to "skip" display for
918 // special case we don't want to "skip" display for
837 return true
919 return true
838 }
920 }
839 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
921 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
840 };
922 };
841
923
842 var cleanContext = {
924 var cleanContext = {
843 repo_view_type: null,
925 repo_view_type: null,
844
926
845 repo_id: null,
927 repo_id: null,
846 repo_name: "",
928 repo_name: "",
847
929
848 repo_group_id: null,
930 repo_group_id: null,
849 repo_group_name: null
931 repo_group_name: null
850 };
932 };
851 var removeGoToFilter = function () {
933 var removeGoToFilter = function () {
852 $('.searchTagHidable').hide();
934 $('.searchTagHidable').hide();
853 $('#main_filter').autocomplete(
935 $('#main_filter').autocomplete(
854 'setOptions', {params:{search_context: cleanContext}});
936 'setOptions', {params:{search_context: cleanContext}});
855 };
937 };
856
938
857 $('#main_filter').autocomplete({
939 $('#main_filter').autocomplete({
858 serviceUrl: pyroutes.url('goto_switcher_data'),
940 serviceUrl: pyroutes.url('goto_switcher_data'),
859 params: {
941 params: {
860 "search_context": templateContext.search_context
942 "search_context": templateContext.search_context
861 },
943 },
862 minChars:2,
944 minChars:2,
863 maxHeight:400,
945 maxHeight:400,
864 deferRequestBy: 300, //miliseconds
946 deferRequestBy: 300, //miliseconds
865 tabDisabled: true,
947 tabDisabled: true,
866 autoSelectFirst: false,
948 autoSelectFirst: false,
867 containerClass: 'autocomplete-qfilter-suggestions',
949 containerClass: 'autocomplete-qfilter-suggestions',
868 formatResult: autocompleteMainFilterFormatResult,
950 formatResult: autocompleteMainFilterFormatResult,
869 lookupFilter: autocompleteMainFilterResult,
951 lookupFilter: autocompleteMainFilterResult,
870 onSelect: function (element, suggestion) {
952 onSelect: function (element, suggestion) {
871 handleSelect(element, suggestion);
953 handleSelect(element, suggestion);
872 return false;
954 return false;
873 },
955 },
874 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
956 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
875 if (jqXHR !== 'abort') {
957 if (jqXHR !== 'abort') {
876 alert("Error during search.\nError code: {0}".format(textStatus));
958 alert("Error during search.\nError code: {0}".format(textStatus));
877 window.location = '';
959 window.location = '';
878 }
960 }
879 }
961 }
880 });
962 });
881
963
882 showMainFilterBox = function () {
964 showMainFilterBox = function () {
883 $('#main_filter_help').toggle();
965 $('#main_filter_help').toggle();
884 };
966 };
885
967
886 $('#main_filter').on('keydown.autocomplete', function (e) {
968 $('#main_filter').on('keydown.autocomplete', function (e) {
887
969
888 var BACKSPACE = 8;
970 var BACKSPACE = 8;
889 var el = $(e.currentTarget);
971 var el = $(e.currentTarget);
890 if(e.which === BACKSPACE){
972 if(e.which === BACKSPACE){
891 var inputVal = el.val();
973 var inputVal = el.val();
892 if (inputVal === ""){
974 if (inputVal === ""){
893 removeGoToFilter()
975 removeGoToFilter()
894 }
976 }
895 }
977 }
896 });
978 });
897
979
898 </script>
980 </script>
899 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
981 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
900 </%def>
982 </%def>
901
983
902 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
984 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
903 <div class="modal-dialog">
985 <div class="modal-dialog">
904 <div class="modal-content">
986 <div class="modal-content">
905 <div class="modal-header">
987 <div class="modal-header">
906 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
988 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
907 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
989 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
908 </div>
990 </div>
909 <div class="modal-body">
991 <div class="modal-body">
910 <div class="block-left">
992 <div class="block-left">
911 <table class="keyboard-mappings">
993 <table class="keyboard-mappings">
912 <tbody>
994 <tbody>
913 <tr>
995 <tr>
914 <th></th>
996 <th></th>
915 <th>${_('Site-wide shortcuts')}</th>
997 <th>${_('Site-wide shortcuts')}</th>
916 </tr>
998 </tr>
917 <%
999 <%
918 elems = [
1000 elems = [
919 ('/', 'Use quick search box'),
1001 ('/', 'Use quick search box'),
920 ('g h', 'Goto home page'),
1002 ('g h', 'Goto home page'),
921 ('g g', 'Goto my private gists page'),
1003 ('g g', 'Goto my private gists page'),
922 ('g G', 'Goto my public gists page'),
1004 ('g G', 'Goto my public gists page'),
923 ('g 0-9', 'Goto bookmarked items from 0-9'),
1005 ('g 0-9', 'Goto bookmarked items from 0-9'),
924 ('n r', 'New repository page'),
1006 ('n r', 'New repository page'),
925 ('n g', 'New gist page'),
1007 ('n g', 'New gist page'),
926 ]
1008 ]
927 %>
1009 %>
928 %for key, desc in elems:
1010 %for key, desc in elems:
929 <tr>
1011 <tr>
930 <td class="keys">
1012 <td class="keys">
931 <span class="key tag">${key}</span>
1013 <span class="key tag">${key}</span>
932 </td>
1014 </td>
933 <td>${desc}</td>
1015 <td>${desc}</td>
934 </tr>
1016 </tr>
935 %endfor
1017 %endfor
936 </tbody>
1018 </tbody>
937 </table>
1019 </table>
938 </div>
1020 </div>
939 <div class="block-left">
1021 <div class="block-left">
940 <table class="keyboard-mappings">
1022 <table class="keyboard-mappings">
941 <tbody>
1023 <tbody>
942 <tr>
1024 <tr>
943 <th></th>
1025 <th></th>
944 <th>${_('Repositories')}</th>
1026 <th>${_('Repositories')}</th>
945 </tr>
1027 </tr>
946 <%
1028 <%
947 elems = [
1029 elems = [
948 ('g s', 'Goto summary page'),
1030 ('g s', 'Goto summary page'),
949 ('g c', 'Goto changelog page'),
1031 ('g c', 'Goto changelog page'),
950 ('g f', 'Goto files page'),
1032 ('g f', 'Goto files page'),
951 ('g F', 'Goto files page with file search activated'),
1033 ('g F', 'Goto files page with file search activated'),
952 ('g p', 'Goto pull requests page'),
1034 ('g p', 'Goto pull requests page'),
953 ('g o', 'Goto repository settings'),
1035 ('g o', 'Goto repository settings'),
954 ('g O', 'Goto repository permissions settings'),
1036 ('g O', 'Goto repository permissions settings'),
955 ]
1037 ]
956 %>
1038 %>
957 %for key, desc in elems:
1039 %for key, desc in elems:
958 <tr>
1040 <tr>
959 <td class="keys">
1041 <td class="keys">
960 <span class="key tag">${key}</span>
1042 <span class="key tag">${key}</span>
961 </td>
1043 </td>
962 <td>${desc}</td>
1044 <td>${desc}</td>
963 </tr>
1045 </tr>
964 %endfor
1046 %endfor
965 </tbody>
1047 </tbody>
966 </table>
1048 </table>
967 </div>
1049 </div>
968 </div>
1050 </div>
969 <div class="modal-footer">
1051 <div class="modal-footer">
970 </div>
1052 </div>
971 </div><!-- /.modal-content -->
1053 </div><!-- /.modal-content -->
972 </div><!-- /.modal-dialog -->
1054 </div><!-- /.modal-dialog -->
973 </div><!-- /.modal -->
1055 </div><!-- /.modal -->
974
1056
@@ -1,132 +1,119 b''
1 <%inherit file="/base/base.mako"/>
1 <%inherit file="/base/base.mako"/>
2
2
3
3
4 <%def name="menu_bar_subnav()">
4 <%def name="menu_bar_subnav()">
5 % if c.repo_group:
5 % if c.repo_group:
6 ${self.repo_group_menu(active='home')}
6 ${self.repo_group_menu(active='home')}
7 % endif
7 % endif
8 </%def>
8 </%def>
9
9
10
10
11 <%def name="main()">
11 <%def name="main()">
12 <div class="box">
12 <div class="box">
13 <!-- box / title -->
13 <!-- box / title -->
14 <div class="title">
14 <div class="title">
15 %if c.rhodecode_user.username != h.DEFAULT_USER:
16 <div class="block-right">
17 %if not c.repo_group:
18 ## no repository group context here
19 %if c.is_super_admin or c.can_create_repo:
20 <a href="${h.route_path('repo_new')}" class="btn btn-small btn-success btn-primary">${_('Add Repository')}</a>
21 %endif
22
15
23 %if c.is_super_admin or c.can_create_repo_group:
24 <a href="${h.route_path('repo_group_new')}" class="btn btn-small btn-default">${_(u'Add Repository Group')}</a>
25 %endif
26 %endif
27 </div>
28 %endif
29 </div>
16 </div>
30 <!-- end box / title -->
17 <!-- end box / title -->
31 <div class="table">
18 <div class="table">
32 <div id="groups_list_wrap">
19 <div id="groups_list_wrap">
33 <table id="group_list_table" class="display" style="width: 100%"></table>
20 <table id="group_list_table" class="display" style="width: 100%"></table>
34 </div>
21 </div>
35 </div>
22 </div>
36
23
37 <div class="table">
24 <div class="table">
38 <div id="repos_list_wrap">
25 <div id="repos_list_wrap">
39 <table id="repo_list_table" class="display" style="width: 100%"></table>
26 <table id="repo_list_table" class="display" style="width: 100%"></table>
40 </div>
27 </div>
41 </div>
28 </div>
42
29
43 ## no repository groups and repos present, show something to the users
30 ## no repository groups and repos present, show something to the users
44 % if c.repo_groups_data == '[]' and c.repos_data == '[]':
31 % if c.repo_groups_data == '[]' and c.repos_data == '[]':
45 <div class="table">
32 <div class="table">
46 <h2 class="no-object-border">
33 <h2 class="no-object-border">
47 ${_('No repositories or repositories groups exists here.')}
34 ${_('No repositories or repositories groups exists here.')}
48 </h2>
35 </h2>
49 </div>
36 </div>
50 % endif
37 % endif
51
38
52 </div>
39 </div>
53 <script>
40 <script>
54 $(document).ready(function() {
41 $(document).ready(function() {
55
42
56 // repo group list
43 // repo group list
57 % if c.repo_groups_data != '[]':
44 % if c.repo_groups_data != '[]':
58 $('#group_list_table').DataTable({
45 $('#group_list_table').DataTable({
59 data: ${c.repo_groups_data|n},
46 data: ${c.repo_groups_data|n},
60 dom: 'rtp',
47 dom: 'rtp',
61 pageLength: ${c.visual.dashboard_items},
48 pageLength: ${c.visual.dashboard_items},
62 order: [[ 0, "asc" ]],
49 order: [[ 0, "asc" ]],
63 columns: [
50 columns: [
64 { data: {"_": "name",
51 { data: {"_": "name",
65 "sort": "name_raw"}, title: "${_('Name')}", className: "truncate-wrap td-grid-name" },
52 "sort": "name_raw"}, title: "${_('Name')}", className: "truncate-wrap td-grid-name" },
66 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
53 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
67 { data: {"_": "desc",
54 { data: {"_": "desc",
68 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
55 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
69 { data: {"_": "last_change",
56 { data: {"_": "last_change",
70 "sort": "last_change_raw",
57 "sort": "last_change_raw",
71 "type": Number}, title: "${_('Last Change')}", className: "td-time" },
58 "type": Number}, title: "${_('Last Change')}", className: "td-time" },
72 { data: {"_": "last_changeset",
59 { data: {"_": "last_changeset",
73 "sort": "last_changeset_raw",
60 "sort": "last_changeset_raw",
74 "type": Number}, title: "", className: "td-hash" },
61 "type": Number}, title: "", className: "td-hash" },
75 { data: {"_": "owner",
62 { data: {"_": "owner",
76 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" }
63 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" }
77 ],
64 ],
78 language: {
65 language: {
79 paginate: DEFAULT_GRID_PAGINATION,
66 paginate: DEFAULT_GRID_PAGINATION,
80 emptyTable: _gettext("No repository groups available yet.")
67 emptyTable: _gettext("No repository groups available yet.")
81 },
68 },
82 "drawCallback": function( settings, json ) {
69 "drawCallback": function( settings, json ) {
83 timeagoActivate();
70 timeagoActivate();
84 quick_repo_menu();
71 quick_repo_menu();
85 // hide pagination for single page
72 // hide pagination for single page
86 if (settings._iDisplayLength > settings.fnRecordsDisplay()) {
73 if (settings._iDisplayLength > settings.fnRecordsDisplay()) {
87 $(settings.nTableWrapper).find('.dataTables_paginate').hide();
74 $(settings.nTableWrapper).find('.dataTables_paginate').hide();
88 }
75 }
89 }
76 }
90 });
77 });
91 % endif
78 % endif
92
79
93 // repo list
80 // repo list
94 % if c.repos_data != '[]':
81 % if c.repos_data != '[]':
95 $('#repo_list_table').DataTable({
82 $('#repo_list_table').DataTable({
96 data: ${c.repos_data|n},
83 data: ${c.repos_data|n},
97 dom: 'rtp',
84 dom: 'rtp',
98 order: [[ 0, "asc" ]],
85 order: [[ 0, "asc" ]],
99 pageLength: ${c.visual.dashboard_items},
86 pageLength: ${c.visual.dashboard_items},
100 columns: [
87 columns: [
101 { data: {"_": "name",
88 { data: {"_": "name",
102 "sort": "name_raw"}, title: "${_('Name')}", className: "truncate-wrap td-grid-name" },
89 "sort": "name_raw"}, title: "${_('Name')}", className: "truncate-wrap td-grid-name" },
103 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
90 { data: 'menu', "bSortable": false, className: "quick_repo_menu" },
104 { data: {"_": "desc",
91 { data: {"_": "desc",
105 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
92 "sort": "desc"}, title: "${_('Description')}", className: "td-description" },
106 { data: {"_": "last_change",
93 { data: {"_": "last_change",
107 "sort": "last_change_raw",
94 "sort": "last_change_raw",
108 "type": Number}, title: "${_('Last Change')}", className: "td-time" },
95 "type": Number}, title: "${_('Last Change')}", className: "td-time" },
109 { data: {"_": "last_changeset",
96 { data: {"_": "last_changeset",
110 "sort": "last_changeset_raw",
97 "sort": "last_changeset_raw",
111 "type": Number}, title: "${_('Commit')}", className: "td-hash" },
98 "type": Number}, title: "${_('Commit')}", className: "td-hash" },
112 { data: {"_": "owner",
99 { data: {"_": "owner",
113 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" }
100 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" }
114 ],
101 ],
115 language: {
102 language: {
116 paginate: DEFAULT_GRID_PAGINATION,
103 paginate: DEFAULT_GRID_PAGINATION,
117 emptyTable: _gettext("No repositories available yet.")
104 emptyTable: _gettext("No repositories available yet.")
118 },
105 },
119 "drawCallback": function( settings, json ) {
106 "drawCallback": function( settings, json ) {
120 timeagoActivate();
107 timeagoActivate();
121 quick_repo_menu();
108 quick_repo_menu();
122 // hide pagination for single page
109 // hide pagination for single page
123 if (settings._iDisplayLength > settings.fnRecordsDisplay()) {
110 if (settings._iDisplayLength > settings.fnRecordsDisplay()) {
124 $(settings.nTableWrapper).find('.dataTables_paginate').hide();
111 $(settings.nTableWrapper).find('.dataTables_paginate').hide();
125 }
112 }
126 }
113 }
127 });
114 });
128 % endif
115 % endif
129
116
130 });
117 });
131 </script>
118 </script>
132 </%def>
119 </%def>
General Comments 0
You need to be logged in to leave comments. Login now