##// END OF EJS Templates
pyramid: stop relying on global mako url() function....
marcink -
r1910:45702bf2 default
parent child Browse files
Show More
@@ -1,331 +1,330 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 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 import io
20 import io
21 import re
21 import re
22 import datetime
22 import datetime
23 import logging
23 import logging
24 import pylons
24 import pylons
25 import Queue
25 import Queue
26 import subprocess32
26 import subprocess32
27 import os
27 import os
28
28
29 from pyramid.i18n import get_localizer
29 from pyramid.i18n import get_localizer
30 from pyramid.threadlocal import get_current_request
30 from pyramid.threadlocal import get_current_request
31 from pyramid.interfaces import IRoutesMapper
31 from pyramid.interfaces import IRoutesMapper
32 from pyramid.settings import asbool
32 from pyramid.settings import asbool
33 from pyramid.path import AssetResolver
33 from pyramid.path import AssetResolver
34 from threading import Thread
34 from threading import Thread
35
35
36 from rhodecode.translation import _ as tsf
36 from rhodecode.translation import _ as tsf
37 from rhodecode.config.jsroutes import generate_jsroutes_content
37 from rhodecode.config.jsroutes import generate_jsroutes_content
38
38
39 import rhodecode
39 import rhodecode
40
40
41 from pylons.i18n.translation import _get_translator
41 from pylons.i18n.translation import _get_translator
42 from pylons.util import ContextObj
42 from pylons.util import ContextObj
43 from routes.util import URLGenerator
43 from routes.util import URLGenerator
44
44
45 from rhodecode.lib.base import attach_context_attributes, get_auth_user
45 from rhodecode.lib.base import attach_context_attributes, get_auth_user
46
46
47 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
48
48
49
49
50 def add_renderer_globals(event):
50 def add_renderer_globals(event):
51 from rhodecode.lib import helpers
51 from rhodecode.lib import helpers
52
52
53 # NOTE(marcink):
53 # NOTE(marcink):
54 # Put pylons stuff into the context. This will be removed as soon as
54 # Put pylons stuff into the context. This will be removed as soon as
55 # migration to pyramid is finished.
55 # migration to pyramid is finished.
56 event['c'] = pylons.tmpl_context
56 event['c'] = pylons.tmpl_context
57 event['url'] = pylons.url
58
57
59 # TODO: When executed in pyramid view context the request is not available
58 # TODO: When executed in pyramid view context the request is not available
60 # in the event. Find a better solution to get the request.
59 # in the event. Find a better solution to get the request.
61 request = event['request'] or get_current_request()
60 request = event['request'] or get_current_request()
62
61
63 # Add Pyramid translation as '_' to context
62 # Add Pyramid translation as '_' to context
64 event['_'] = request.translate
63 event['_'] = request.translate
65 event['_ungettext'] = request.plularize
64 event['_ungettext'] = request.plularize
66 event['h'] = helpers
65 event['h'] = helpers
67
66
68
67
69 def add_localizer(event):
68 def add_localizer(event):
70 request = event.request
69 request = event.request
71 localizer = get_localizer(request)
70 localizer = get_localizer(request)
72
71
73 def auto_translate(*args, **kwargs):
72 def auto_translate(*args, **kwargs):
74 return localizer.translate(tsf(*args, **kwargs))
73 return localizer.translate(tsf(*args, **kwargs))
75
74
76 request.localizer = localizer
75 request.localizer = localizer
77 request.translate = auto_translate
76 request.translate = auto_translate
78 request.plularize = localizer.pluralize
77 request.plularize = localizer.pluralize
79
78
80
79
81 def set_user_lang(event):
80 def set_user_lang(event):
82 request = event.request
81 request = event.request
83 cur_user = getattr(request, 'user', None)
82 cur_user = getattr(request, 'user', None)
84
83
85 if cur_user:
84 if cur_user:
86 user_lang = cur_user.get_instance().user_data.get('language')
85 user_lang = cur_user.get_instance().user_data.get('language')
87 if user_lang:
86 if user_lang:
88 log.debug('lang: setting current user:%s language to: %s', cur_user, user_lang)
87 log.debug('lang: setting current user:%s language to: %s', cur_user, user_lang)
89 event.request._LOCALE_ = user_lang
88 event.request._LOCALE_ = user_lang
90
89
91
90
92 def add_request_user_context(event):
91 def add_request_user_context(event):
93 """
92 """
94 Adds auth user into request context
93 Adds auth user into request context
95 """
94 """
96 request = event.request
95 request = event.request
97
96
98 if hasattr(request, 'vcs_call'):
97 if hasattr(request, 'vcs_call'):
99 # skip vcs calls
98 # skip vcs calls
100 return
99 return
101
100
102 if hasattr(request, 'rpc_method'):
101 if hasattr(request, 'rpc_method'):
103 # skip api calls
102 # skip api calls
104 return
103 return
105
104
106 auth_user = get_auth_user(request)
105 auth_user = get_auth_user(request)
107 request.user = auth_user
106 request.user = auth_user
108 request.environ['rc_auth_user'] = auth_user
107 request.environ['rc_auth_user'] = auth_user
109
108
110
109
111 def add_pylons_context(event):
110 def add_pylons_context(event):
112 request = event.request
111 request = event.request
113
112
114 config = rhodecode.CONFIG
113 config = rhodecode.CONFIG
115 environ = request.environ
114 environ = request.environ
116 session = request.session
115 session = request.session
117
116
118 if hasattr(request, 'vcs_call'):
117 if hasattr(request, 'vcs_call'):
119 # skip vcs calls
118 # skip vcs calls
120 return
119 return
121
120
122 # Setup pylons globals.
121 # Setup pylons globals.
123 pylons.config._push_object(config)
122 pylons.config._push_object(config)
124 pylons.request._push_object(request)
123 pylons.request._push_object(request)
125 pylons.session._push_object(session)
124 pylons.session._push_object(session)
126 pylons.translator._push_object(_get_translator(config.get('lang')))
125 pylons.translator._push_object(_get_translator(config.get('lang')))
127
126
128 pylons.url._push_object(URLGenerator(config['routes.map'], environ))
127 pylons.url._push_object(URLGenerator(config['routes.map'], environ))
129 session_key = (
128 session_key = (
130 config['pylons.environ_config'].get('session', 'beaker.session'))
129 config['pylons.environ_config'].get('session', 'beaker.session'))
131 environ[session_key] = session
130 environ[session_key] = session
132
131
133 if hasattr(request, 'rpc_method'):
132 if hasattr(request, 'rpc_method'):
134 # skip api calls
133 # skip api calls
135 return
134 return
136
135
137 # Setup the pylons context object ('c')
136 # Setup the pylons context object ('c')
138 context = ContextObj()
137 context = ContextObj()
139 context.rhodecode_user = request.user
138 context.rhodecode_user = request.user
140 attach_context_attributes(context, request, request.user.user_id)
139 attach_context_attributes(context, request, request.user.user_id)
141 pylons.tmpl_context._push_object(context)
140 pylons.tmpl_context._push_object(context)
142
141
143
142
144 def scan_repositories_if_enabled(event):
143 def scan_repositories_if_enabled(event):
145 """
144 """
146 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
145 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
147 does a repository scan if enabled in the settings.
146 does a repository scan if enabled in the settings.
148 """
147 """
149 settings = event.app.registry.settings
148 settings = event.app.registry.settings
150 vcs_server_enabled = settings['vcs.server.enable']
149 vcs_server_enabled = settings['vcs.server.enable']
151 import_on_startup = settings['startup.import_repos']
150 import_on_startup = settings['startup.import_repos']
152 if vcs_server_enabled and import_on_startup:
151 if vcs_server_enabled and import_on_startup:
153 from rhodecode.model.scm import ScmModel
152 from rhodecode.model.scm import ScmModel
154 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_base_path
153 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_base_path
155 repositories = ScmModel().repo_scan(get_rhodecode_base_path())
154 repositories = ScmModel().repo_scan(get_rhodecode_base_path())
156 repo2db_mapper(repositories, remove_obsolete=False)
155 repo2db_mapper(repositories, remove_obsolete=False)
157
156
158
157
159 def write_metadata_if_needed(event):
158 def write_metadata_if_needed(event):
160 """
159 """
161 Writes upgrade metadata
160 Writes upgrade metadata
162 """
161 """
163 import rhodecode
162 import rhodecode
164 from rhodecode.lib import system_info
163 from rhodecode.lib import system_info
165 from rhodecode.lib import ext_json
164 from rhodecode.lib import ext_json
166
165
167 def write():
166 def write():
168 fname = '.rcmetadata.json'
167 fname = '.rcmetadata.json'
169 ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__'))
168 ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__'))
170 metadata_destination = os.path.join(ini_loc, fname)
169 metadata_destination = os.path.join(ini_loc, fname)
171
170
172 configuration = system_info.SysInfo(
171 configuration = system_info.SysInfo(
173 system_info.rhodecode_config)()['value']
172 system_info.rhodecode_config)()['value']
174 license_token = configuration['config']['license_token']
173 license_token = configuration['config']['license_token']
175 dbinfo = system_info.SysInfo(system_info.database_info)()['value']
174 dbinfo = system_info.SysInfo(system_info.database_info)()['value']
176 del dbinfo['url']
175 del dbinfo['url']
177 metadata = dict(
176 metadata = dict(
178 desc='upgrade metadata info',
177 desc='upgrade metadata info',
179 license_token=license_token,
178 license_token=license_token,
180 created_on=datetime.datetime.utcnow().isoformat(),
179 created_on=datetime.datetime.utcnow().isoformat(),
181 usage=system_info.SysInfo(system_info.usage_info)()['value'],
180 usage=system_info.SysInfo(system_info.usage_info)()['value'],
182 platform=system_info.SysInfo(system_info.platform_type)()['value'],
181 platform=system_info.SysInfo(system_info.platform_type)()['value'],
183 database=dbinfo,
182 database=dbinfo,
184 cpu=system_info.SysInfo(system_info.cpu)()['value'],
183 cpu=system_info.SysInfo(system_info.cpu)()['value'],
185 memory=system_info.SysInfo(system_info.memory)()['value'],
184 memory=system_info.SysInfo(system_info.memory)()['value'],
186 )
185 )
187
186
188 with open(metadata_destination, 'wb') as f:
187 with open(metadata_destination, 'wb') as f:
189 f.write(ext_json.json.dumps(metadata))
188 f.write(ext_json.json.dumps(metadata))
190
189
191 settings = event.app.registry.settings
190 settings = event.app.registry.settings
192 if settings.get('metadata.skip'):
191 if settings.get('metadata.skip'):
193 return
192 return
194
193
195 try:
194 try:
196 write()
195 write()
197 except Exception:
196 except Exception:
198 pass
197 pass
199
198
200
199
201 def write_js_routes_if_enabled(event):
200 def write_js_routes_if_enabled(event):
202 registry = event.app.registry
201 registry = event.app.registry
203
202
204 mapper = registry.queryUtility(IRoutesMapper)
203 mapper = registry.queryUtility(IRoutesMapper)
205 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
204 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
206
205
207 def _extract_route_information(route):
206 def _extract_route_information(route):
208 """
207 """
209 Convert a route into tuple(name, path, args), eg:
208 Convert a route into tuple(name, path, args), eg:
210 ('show_user', '/profile/%(username)s', ['username'])
209 ('show_user', '/profile/%(username)s', ['username'])
211 """
210 """
212
211
213 routepath = route.pattern
212 routepath = route.pattern
214 pattern = route.pattern
213 pattern = route.pattern
215
214
216 def replace(matchobj):
215 def replace(matchobj):
217 if matchobj.group(1):
216 if matchobj.group(1):
218 return "%%(%s)s" % matchobj.group(1).split(':')[0]
217 return "%%(%s)s" % matchobj.group(1).split(':')[0]
219 else:
218 else:
220 return "%%(%s)s" % matchobj.group(2)
219 return "%%(%s)s" % matchobj.group(2)
221
220
222 routepath = _argument_prog.sub(replace, routepath)
221 routepath = _argument_prog.sub(replace, routepath)
223
222
224 if not routepath.startswith('/'):
223 if not routepath.startswith('/'):
225 routepath = '/'+routepath
224 routepath = '/'+routepath
226
225
227 return (
226 return (
228 route.name,
227 route.name,
229 routepath,
228 routepath,
230 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
229 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
231 for arg in _argument_prog.findall(pattern)]
230 for arg in _argument_prog.findall(pattern)]
232 )
231 )
233
232
234 def get_routes():
233 def get_routes():
235 # pylons routes
234 # pylons routes
236 for route in rhodecode.CONFIG['routes.map'].jsroutes():
235 for route in rhodecode.CONFIG['routes.map'].jsroutes():
237 yield route
236 yield route
238
237
239 # pyramid routes
238 # pyramid routes
240 for route in mapper.get_routes():
239 for route in mapper.get_routes():
241 if not route.name.startswith('__'):
240 if not route.name.startswith('__'):
242 yield _extract_route_information(route)
241 yield _extract_route_information(route)
243
242
244 if asbool(registry.settings.get('generate_js_files', 'false')):
243 if asbool(registry.settings.get('generate_js_files', 'false')):
245 static_path = AssetResolver().resolve('rhodecode:public').abspath()
244 static_path = AssetResolver().resolve('rhodecode:public').abspath()
246 jsroutes = get_routes()
245 jsroutes = get_routes()
247 jsroutes_file_content = generate_jsroutes_content(jsroutes)
246 jsroutes_file_content = generate_jsroutes_content(jsroutes)
248 jsroutes_file_path = os.path.join(
247 jsroutes_file_path = os.path.join(
249 static_path, 'js', 'rhodecode', 'routes.js')
248 static_path, 'js', 'rhodecode', 'routes.js')
250
249
251 with io.open(jsroutes_file_path, 'w', encoding='utf-8') as f:
250 with io.open(jsroutes_file_path, 'w', encoding='utf-8') as f:
252 f.write(jsroutes_file_content)
251 f.write(jsroutes_file_content)
253
252
254
253
255 class Subscriber(object):
254 class Subscriber(object):
256 """
255 """
257 Base class for subscribers to the pyramid event system.
256 Base class for subscribers to the pyramid event system.
258 """
257 """
259 def __call__(self, event):
258 def __call__(self, event):
260 self.run(event)
259 self.run(event)
261
260
262 def run(self, event):
261 def run(self, event):
263 raise NotImplementedError('Subclass has to implement this.')
262 raise NotImplementedError('Subclass has to implement this.')
264
263
265
264
266 class AsyncSubscriber(Subscriber):
265 class AsyncSubscriber(Subscriber):
267 """
266 """
268 Subscriber that handles the execution of events in a separate task to not
267 Subscriber that handles the execution of events in a separate task to not
269 block the execution of the code which triggers the event. It puts the
268 block the execution of the code which triggers the event. It puts the
270 received events into a queue from which the worker process takes them in
269 received events into a queue from which the worker process takes them in
271 order.
270 order.
272 """
271 """
273 def __init__(self):
272 def __init__(self):
274 self._stop = False
273 self._stop = False
275 self._eventq = Queue.Queue()
274 self._eventq = Queue.Queue()
276 self._worker = self.create_worker()
275 self._worker = self.create_worker()
277 self._worker.start()
276 self._worker.start()
278
277
279 def __call__(self, event):
278 def __call__(self, event):
280 self._eventq.put(event)
279 self._eventq.put(event)
281
280
282 def create_worker(self):
281 def create_worker(self):
283 worker = Thread(target=self.do_work)
282 worker = Thread(target=self.do_work)
284 worker.daemon = True
283 worker.daemon = True
285 return worker
284 return worker
286
285
287 def stop_worker(self):
286 def stop_worker(self):
288 self._stop = False
287 self._stop = False
289 self._eventq.put(None)
288 self._eventq.put(None)
290 self._worker.join()
289 self._worker.join()
291
290
292 def do_work(self):
291 def do_work(self):
293 while not self._stop:
292 while not self._stop:
294 event = self._eventq.get()
293 event = self._eventq.get()
295 if event is not None:
294 if event is not None:
296 self.run(event)
295 self.run(event)
297
296
298
297
299 class AsyncSubprocessSubscriber(AsyncSubscriber):
298 class AsyncSubprocessSubscriber(AsyncSubscriber):
300 """
299 """
301 Subscriber that uses the subprocess32 module to execute a command if an
300 Subscriber that uses the subprocess32 module to execute a command if an
302 event is received. Events are handled asynchronously.
301 event is received. Events are handled asynchronously.
303 """
302 """
304
303
305 def __init__(self, cmd, timeout=None):
304 def __init__(self, cmd, timeout=None):
306 super(AsyncSubprocessSubscriber, self).__init__()
305 super(AsyncSubprocessSubscriber, self).__init__()
307 self._cmd = cmd
306 self._cmd = cmd
308 self._timeout = timeout
307 self._timeout = timeout
309
308
310 def run(self, event):
309 def run(self, event):
311 cmd = self._cmd
310 cmd = self._cmd
312 timeout = self._timeout
311 timeout = self._timeout
313 log.debug('Executing command %s.', cmd)
312 log.debug('Executing command %s.', cmd)
314
313
315 try:
314 try:
316 output = subprocess32.check_output(
315 output = subprocess32.check_output(
317 cmd, timeout=timeout, stderr=subprocess32.STDOUT)
316 cmd, timeout=timeout, stderr=subprocess32.STDOUT)
318 log.debug('Command finished %s', cmd)
317 log.debug('Command finished %s', cmd)
319 if output:
318 if output:
320 log.debug('Command output: %s', output)
319 log.debug('Command output: %s', output)
321 except subprocess32.TimeoutExpired as e:
320 except subprocess32.TimeoutExpired as e:
322 log.exception('Timeout while executing command.')
321 log.exception('Timeout while executing command.')
323 if e.output:
322 if e.output:
324 log.error('Command output: %s', e.output)
323 log.error('Command output: %s', e.output)
325 except subprocess32.CalledProcessError as e:
324 except subprocess32.CalledProcessError as e:
326 log.exception('Error while executing command.')
325 log.exception('Error while executing command.')
327 if e.output:
326 if e.output:
328 log.error('Command output: %s', e.output)
327 log.error('Command output: %s', e.output)
329 except:
328 except:
330 log.exception(
329 log.exception(
331 'Exception while executing command %s.', cmd)
330 'Exception while executing command %s.', cmd)
@@ -1,81 +1,81 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Default Settings For New Repositories')}</h3>
3 <h3 class="panel-title">${_('Default Settings For New Repositories')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6 ${h.secure_form(url('admin_defaults_repositories'), method='post')}
6 ${h.secure_form(h.url('admin_defaults_repositories'), method='post')}
7 <div class="form">
7 <div class="form">
8 <!-- fields -->
8 <!-- fields -->
9
9
10 <div class="fields">
10 <div class="fields">
11
11
12 <div class="field">
12 <div class="field">
13 <div class="label">
13 <div class="label">
14 <label for="default_repo_type">${_('Type')}:</label>
14 <label for="default_repo_type">${_('Type')}:</label>
15 </div>
15 </div>
16 <div class="select">
16 <div class="select">
17 ${h.select('default_repo_type','hg',c.backends,class_="medium")}
17 ${h.select('default_repo_type','hg',c.backends,class_="medium")}
18 </div>
18 </div>
19 </div>
19 </div>
20
20
21 <div class="field">
21 <div class="field">
22 <div class="label label-checkbox">
22 <div class="label label-checkbox">
23 <label for="default_repo_private">${_('Private Repository')}:</label>
23 <label for="default_repo_private">${_('Private Repository')}:</label>
24 </div>
24 </div>
25 <div class="checkboxes">
25 <div class="checkboxes">
26 ${h.checkbox('default_repo_private',value="True")}
26 ${h.checkbox('default_repo_private',value="True")}
27 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
27 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
28 </div>
28 </div>
29 </div>
29 </div>
30
30
31
31
32 <div class="field">
32 <div class="field">
33 <div class="label label-checkbox">
33 <div class="label label-checkbox">
34 <label for="default_repo_enable_statistics">${_('Enable Statistics')}:</label>
34 <label for="default_repo_enable_statistics">${_('Enable Statistics')}:</label>
35 </div>
35 </div>
36 <div class="checkboxes">
36 <div class="checkboxes">
37 ${h.checkbox('default_repo_enable_statistics',value="True")}
37 ${h.checkbox('default_repo_enable_statistics',value="True")}
38 <span class="help-block">${_('Enable a statistics window on the repository summary page.')}</span>
38 <span class="help-block">${_('Enable a statistics window on the repository summary page.')}</span>
39 </div>
39 </div>
40 </div>
40 </div>
41
41
42 <div class="field">
42 <div class="field">
43 <div class="label label-checkbox">
43 <div class="label label-checkbox">
44 <label for="default_repo_enable_downloads">${_('Enable Downloads')}:</label>
44 <label for="default_repo_enable_downloads">${_('Enable Downloads')}:</label>
45 </div>
45 </div>
46 <div class="checkboxes">
46 <div class="checkboxes">
47 ${h.checkbox('default_repo_enable_downloads',value="True")}
47 ${h.checkbox('default_repo_enable_downloads',value="True")}
48 <span class="help-block">${_('Enable the download option on the repository summary page.')}</span>
48 <span class="help-block">${_('Enable the download option on the repository summary page.')}</span>
49 </div>
49 </div>
50 </div>
50 </div>
51
51
52 <div class="field">
52 <div class="field">
53 <div class="label label-checkbox">
53 <div class="label label-checkbox">
54 <label for="default_repo_enable_locking">${_('Enable Locking')}:</label>
54 <label for="default_repo_enable_locking">${_('Enable Locking')}:</label>
55 </div>
55 </div>
56 <div class="checkboxes">
56 <div class="checkboxes">
57 ${h.checkbox('default_repo_enable_locking',value="True")}
57 ${h.checkbox('default_repo_enable_locking',value="True")}
58 <span class="help-block">${_('Enable automatic repository locking. Pulling from a repository will lock it, and it is unlocked by pushing back by the same user.')}</span>
58 <span class="help-block">${_('Enable automatic repository locking. Pulling from a repository will lock it, and it is unlocked by pushing back by the same user.')}</span>
59 </div>
59 </div>
60 </div>
60 </div>
61
61
62 <div class="buttons">
62 <div class="buttons">
63 ${h.submit('save',_('Save'),class_="btn")}
63 ${h.submit('save',_('Save'),class_="btn")}
64 </div>
64 </div>
65 </div>
65 </div>
66 </div>
66 </div>
67 ${h.end_form()}
67 ${h.end_form()}
68 </div>
68 </div>
69
69
70 </div>
70 </div>
71
71
72 <script>
72 <script>
73 $(document).ready(function(){
73 $(document).ready(function(){
74 $("#default_repo_type").select2({
74 $("#default_repo_type").select2({
75 containerCssClass: 'drop-menu',
75 containerCssClass: 'drop-menu',
76 dropdownCssClass: 'drop-menu-dropdown',
76 dropdownCssClass: 'drop-menu-dropdown',
77 dropdownAutoWidth: true,
77 dropdownAutoWidth: true,
78 minimumResultsForSearch: -1
78 minimumResultsForSearch: -1
79 });
79 });
80 })
80 })
81 </script>
81 </script>
@@ -1,78 +1,78 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 ${_('My Notifications')} ${c.rhodecode_user.username}
5 ${_('My Notifications')} ${c.rhodecode_user.username}
6 %if c.rhodecode_name:
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()">
12 ${_('My Notifications')}
12 ${_('My Notifications')}
13 </%def>
13 </%def>
14
14
15 <%def name="menu_bar_nav()">
15 <%def name="menu_bar_nav()">
16 ${self.menu_items(active='admin')}
16 ${self.menu_items(active='admin')}
17 </%def>
17 </%def>
18
18
19 <%def name="main()">
19 <%def name="main()">
20 <div class="box">
20 <div class="box">
21 <!-- box / title -->
21 <!-- box / title -->
22 <div class="title">
22 <div class="title">
23 ${self.breadcrumbs()}
23 ${self.breadcrumbs()}
24 ##<ul class="links">
24 ##<ul class="links">
25 ## <li>
25 ## <li>
26 ## <span ><a href="#">${_('Compose message')}</a></span>
26 ## <span ><a href="#">${_('Compose message')}</a></span>
27 ## </li>
27 ## </li>
28 ##</ul>
28 ##</ul>
29
29
30 <div class="notifications_buttons">
30 <div class="notifications_buttons">
31 <span id='all' class="action-link first ${'active' if c.current_filter=='all' else ''}"><a href="${h.url.current()}">${_('All')}</a></span>
31 <span id='all' class="action-link first ${'active' if c.current_filter=='all' else ''}"><a href="${h.url.current()}">${_('All')}</a></span>
32 <span id='comment' class="action-link ${'active' if c.current_filter=='comment' else ''}"><a href="${h.url.current(type=c.comment_type)}">${_('Comments')}</a></span>
32 <span id='comment' class="action-link ${'active' if c.current_filter=='comment' else ''}"><a href="${h.url.current(type=c.comment_type)}">${_('Comments')}</a></span>
33 <span id='pull_request' class="action-link last ${'active' if c.current_filter=='pull_request' else ''}"><a href="${h.url.current(type=c.pull_request_type)}">${_('Pull Requests')}</a></span>
33 <span id='pull_request' class="action-link last ${'active' if c.current_filter=='pull_request' else ''}"><a href="${h.url.current(type=c.pull_request_type)}">${_('Pull Requests')}</a></span>
34
34
35 %if c.notifications:
35 %if c.notifications:
36
36
37 <span id='mark_all_read' class="btn btn-default">${_('Mark all as read')}</span>
37 <span id='mark_all_read' class="btn btn-default">${_('Mark all as read')}</span>
38
38
39 %endif
39 %endif
40 </div>
40 </div>
41 </div>
41 </div>
42 <div id='notification_data' class='main-content-full'>
42 <div id='notification_data' class='main-content-full'>
43 <%include file='notifications_data.mako'/>
43 <%include file='notifications_data.mako'/>
44 </div>
44 </div>
45 </div>
45 </div>
46 <script type="text/javascript">
46 <script type="text/javascript">
47 var url_action = "${url('notification', notification_id='__NOTIFICATION_ID__')}";
47 var url_action = "${h.url('notification', notification_id='__NOTIFICATION_ID__')}";
48 var run = function(){
48 var run = function(){
49 $('#notification_data').on('click','.delete-notification',function(e){
49 $('#notification_data').on('click','.delete-notification',function(e){
50 var notification_id = e.currentTarget.id;
50 var notification_id = e.currentTarget.id;
51 deleteNotification(url_action,notification_id)
51 deleteNotification(url_action,notification_id)
52 });
52 });
53 $('#notification_data').on('click','.read-notification',function(e){
53 $('#notification_data').on('click','.read-notification',function(e){
54 var notification_id = e.currentTarget.id;
54 var notification_id = e.currentTarget.id;
55 readNotification(url_action,notification_id)
55 readNotification(url_action,notification_id)
56 })
56 })
57 };
57 };
58 run();
58 run();
59 $('#mark_all_read').on('click',function(e){
59 $('#mark_all_read').on('click',function(e){
60 //set notifications as read
60 //set notifications as read
61 var url = "${h.url('notifications_mark_all_read', **request.GET.mixed())}";
61 var url = "${h.url('notifications_mark_all_read', **request.GET.mixed())}";
62 $.post(url, {'csrf_token': CSRF_TOKEN}).
62 $.post(url, {'csrf_token': CSRF_TOKEN}).
63 done(function(data){
63 done(function(data){
64 // hide notifications counter
64 // hide notifications counter
65 $('#quick_login_link > .menu_link_notifications').hide();
65 $('#quick_login_link > .menu_link_notifications').hide();
66 $('#notification_data').html(data);
66 $('#notification_data').html(data);
67 })
67 })
68 .fail(function(data, textStatus, errorThrown){
68 .fail(function(data, textStatus, errorThrown){
69 alert("Error while saving notifications.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
69 alert("Error while saving notifications.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
70 });
70 });
71 });
71 });
72
72
73 var current_filter = $("${c.current_filter}");
73 var current_filter = $("${c.current_filter}");
74 if (current_filter.length){
74 if (current_filter.length){
75 current_filter.addClass('active');
75 current_filter.addClass('active');
76 }
76 }
77 </script>
77 </script>
78 </%def>
78 </%def>
@@ -1,40 +1,40 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2 %if c.notifications:
2 %if c.notifications:
3 <%
3 <%
4 unread = lambda n:{False:'unread'}.get(n)
4 unread = lambda n:{False:'unread'}.get(n)
5 %>
5 %>
6
6
7
7
8 <div class="notification-list notification-table">
8 <div class="notification-list notification-table">
9 %for notification in c.notifications:
9 %for notification in c.notifications:
10 <div id="notification_${notification.notification.notification_id}" class="container ${unread(notification.read)}">
10 <div id="notification_${notification.notification.notification_id}" class="container ${unread(notification.read)}">
11 <div class="notification-header">
11 <div class="notification-header">
12 <div class="desc ${unread(notification.read)}">
12 <div class="desc ${unread(notification.read)}">
13 <a href="${url('notification', notification_id=notification.notification.notification_id)}">
13 <a href="${h.url('notification', notification_id=notification.notification.notification_id)}">
14 ${base.gravatar(notification.notification.created_by_user.email, 16)}
14 ${base.gravatar(notification.notification.created_by_user.email, 16)}
15 ${notification.notification.description}
15 ${notification.notification.description}
16 </a>
16 </a>
17 </div>
17 </div>
18 <div class="delete-notifications">
18 <div class="delete-notifications">
19 <span id="${notification.notification.notification_id}" class="delete-notification"><i class="icon-delete" ></i></span>
19 <span id="${notification.notification.notification_id}" class="delete-notification"><i class="icon-delete" ></i></span>
20 </div>
20 </div>
21 <div class="read-notifications">
21 <div class="read-notifications">
22 %if not notification.read:
22 %if not notification.read:
23 <span id="${notification.notification.notification_id}" class="read-notification"><i class="icon-ok" ></i></span>
23 <span id="${notification.notification.notification_id}" class="read-notification"><i class="icon-ok" ></i></span>
24 %endif
24 %endif
25 </div>
25 </div>
26 </div>
26 </div>
27 <div class="notification-subject"></div>
27 <div class="notification-subject"></div>
28 </div>
28 </div>
29 %endfor
29 %endfor
30 </div>
30 </div>
31
31
32 <div class="notification-paginator">
32 <div class="notification-paginator">
33 <div class="pagination-wh pagination-left">
33 <div class="pagination-wh pagination-left">
34 ${c.notifications.pager('$link_previous ~2~ $link_next')}
34 ${c.notifications.pager('$link_previous ~2~ $link_next')}
35 </div>
35 </div>
36 </div>
36 </div>
37
37
38 %else:
38 %else:
39 <div class="table">${_('No notifications here yet')}</div>
39 <div class="table">${_('No notifications here yet')}</div>
40 %endif
40 %endif
@@ -1,57 +1,57 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 ${_('Show notification')} ${c.rhodecode_user.username}
5 ${_('Show notification')} ${c.rhodecode_user.username}
6 %if c.rhodecode_name:
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()">
12 ${h.link_to(_('Notifications'), h.url('notifications'))}
12 ${h.link_to(_('Notifications'), h.url('notifications'))}
13 &raquo;
13 &raquo;
14 ${_('Show notification')}
14 ${_('Show notification')}
15 </%def>
15 </%def>
16
16
17 <%def name="menu_bar_nav()">
17 <%def name="menu_bar_nav()">
18 ${self.menu_items(active='admin')}
18 ${self.menu_items(active='admin')}
19 </%def>
19 </%def>
20
20
21 <%def name="main()">
21 <%def name="main()">
22 <div class="box">
22 <div class="box">
23 <!-- box / title -->
23 <!-- box / title -->
24 <div class="title">
24 <div class="title">
25 ${self.breadcrumbs()}
25 ${self.breadcrumbs()}
26 </div>
26 </div>
27 <div class="table">
27 <div class="table">
28 <div id="notification_${c.notification.notification_id}" class="main-content-full">
28 <div id="notification_${c.notification.notification_id}" class="main-content-full">
29 <div class="notification-header">
29 <div class="notification-header">
30 ${self.gravatar(c.notification.created_by_user.email, 30)}
30 ${self.gravatar(c.notification.created_by_user.email, 30)}
31 <div class="desc">
31 <div class="desc">
32 ${c.notification.description}
32 ${c.notification.description}
33 </div>
33 </div>
34 <div class="delete-notifications">
34 <div class="delete-notifications">
35 <span id="${c.notification.notification_id}" class="delete-notification action"><i class="icon-delete" ></i></span>
35 <span id="${c.notification.notification_id}" class="delete-notification action"><i class="icon-delete" ></i></span>
36 </div>
36 </div>
37 </div>
37 </div>
38 <div class="notification-body">
38 <div class="notification-body">
39 <div class="notification-subject">
39 <div class="notification-subject">
40 <h3>${_('Subject')}: ${c.notification.subject}</h3>
40 <h3>${_('Subject')}: ${c.notification.subject}</h3>
41 </div>
41 </div>
42 %if c.notification.body:
42 %if c.notification.body:
43 ${h.render(c.notification.body, renderer=c.visual.default_renderer, mentions=True)}
43 ${h.render(c.notification.body, renderer=c.visual.default_renderer, mentions=True)}
44 %endif
44 %endif
45 </div>
45 </div>
46 </div>
46 </div>
47 </div>
47 </div>
48 </div>
48 </div>
49 <script type="text/javascript">
49 <script type="text/javascript">
50 var url = "${url('notification', notification_id='__NOTIFICATION_ID__')}";
50 var url = "${h.url('notification', notification_id='__NOTIFICATION_ID__')}";
51 var main = "${url('notifications')}";
51 var main = "${h.url('notifications')}";
52 $('.delete-notification').on('click',function(e){
52 $('.delete-notification').on('click',function(e){
53 var notification_id = e.currentTarget.id;
53 var notification_id = e.currentTarget.id;
54 deleteNotification(url,notification_id,[function(){window.location=main}])
54 deleteNotification(url,notification_id,[function(){window.location=main}])
55 })
55 })
56 </script>
56 </script>
57 </%def>
57 </%def>
@@ -1,81 +1,81 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('System Wide Application Permissions')}</h3>
3 <h3 class="panel-title">${_('System Wide Application Permissions')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6 ${h.secure_form(url('admin_permissions_application'), method='post')}
6 ${h.secure_form(h.url('admin_permissions_application'), method='post')}
7 <div class="form">
7 <div class="form">
8 <!-- fields -->
8 <!-- fields -->
9 <div class="fields">
9 <div class="fields">
10 <div class="field">
10 <div class="field">
11 <div class="label label-checkbox">
11 <div class="label label-checkbox">
12 <label for="anonymous">${_('Anonymous Access')}:</label>
12 <label for="anonymous">${_('Anonymous Access')}:</label>
13 </div>
13 </div>
14 <div class="checkboxes">
14 <div class="checkboxes">
15 <div class="checkbox">
15 <div class="checkbox">
16 ${h.checkbox('anonymous',True)} Allow Anonymous Access
16 ${h.checkbox('anonymous',True)} Allow Anonymous Access
17 </div>
17 </div>
18 <span class="help-block">${h.literal(_('Allow access to RhodeCode Enterprise without requiring users to login. Anonymous users get the %s permission settings.' % (h.link_to('"default user"',h.url('admin_permissions_object')))))}</span>
18 <span class="help-block">${h.literal(_('Allow access to RhodeCode Enterprise without requiring users to login. Anonymous users get the %s permission settings.' % (h.link_to('"default user"',h.url('admin_permissions_object')))))}</span>
19 </div>
19 </div>
20 </div>
20 </div>
21
21
22 <div class="field">
22 <div class="field">
23 <div class="label label-select">
23 <div class="label label-select">
24 <label for="default_register">${_('Registration')}:</label>
24 <label for="default_register">${_('Registration')}:</label>
25 </div>
25 </div>
26 <div class="select">
26 <div class="select">
27 ${h.select('default_register','',c.register_choices)}
27 ${h.select('default_register','',c.register_choices)}
28 </div>
28 </div>
29 </div>
29 </div>
30
30
31 <div class="field">
31 <div class="field">
32 <div class="label label-select">
32 <div class="label label-select">
33 <label for="default_password_reset">${_('Password Reset')}:</label>
33 <label for="default_password_reset">${_('Password Reset')}:</label>
34 </div>
34 </div>
35 <div class="select">
35 <div class="select">
36 ${h.select('default_password_reset','',c.password_reset_choices)}
36 ${h.select('default_password_reset','',c.password_reset_choices)}
37 </div>
37 </div>
38 </div>
38 </div>
39
39
40 <div class="field">
40 <div class="field">
41 <div class="label label-textarea">
41 <div class="label label-textarea">
42 <label for="default_register_message">${_('Registration Page Message')}:</label>
42 <label for="default_register_message">${_('Registration Page Message')}:</label>
43 </div>
43 </div>
44 <div class="textarea text-area editor" >
44 <div class="textarea text-area editor" >
45 ${h.textarea('default_register_message', class_="medium", )}
45 ${h.textarea('default_register_message', class_="medium", )}
46 <span class="help-block">${_('Custom message to be displayed on the registration page. HTML syntax is supported.')}</span>
46 <span class="help-block">${_('Custom message to be displayed on the registration page. HTML syntax is supported.')}</span>
47 </div>
47 </div>
48 </div>
48 </div>
49
49
50 <div class="field">
50 <div class="field">
51 <div class="label">
51 <div class="label">
52 <label for="default_extern_activate">${_('External Authentication Account Activation')}:</label>
52 <label for="default_extern_activate">${_('External Authentication Account Activation')}:</label>
53 </div>
53 </div>
54 <div class="select">
54 <div class="select">
55 ${h.select('default_extern_activate','',c.extern_activate_choices)}
55 ${h.select('default_extern_activate','',c.extern_activate_choices)}
56 </div>
56 </div>
57 </div>
57 </div>
58 <div class="buttons">
58 <div class="buttons">
59 ${h.submit('save',_('Save'),class_="btn")}
59 ${h.submit('save',_('Save'),class_="btn")}
60 ${h.reset('reset',_('Reset'),class_="btn")}
60 ${h.reset('reset',_('Reset'),class_="btn")}
61 </div>
61 </div>
62 </div>
62 </div>
63 </div>
63 </div>
64 ${h.end_form()}
64 ${h.end_form()}
65 </div>
65 </div>
66 </div>
66 </div>
67
67
68 <script>
68 <script>
69 $(document).ready(function(){
69 $(document).ready(function(){
70 var select2Options = {
70 var select2Options = {
71 containerCssClass: 'drop-menu',
71 containerCssClass: 'drop-menu',
72 dropdownCssClass: 'drop-menu-dropdown',
72 dropdownCssClass: 'drop-menu-dropdown',
73 dropdownAutoWidth: true,
73 dropdownAutoWidth: true,
74 minimumResultsForSearch: -1
74 minimumResultsForSearch: -1
75 };
75 };
76
76
77 $("#default_register").select2(select2Options);
77 $("#default_register").select2(select2Options);
78 $("#default_password_reset").select2(select2Options);
78 $("#default_password_reset").select2(select2Options);
79 $("#default_extern_activate").select2(select2Options);
79 $("#default_extern_activate").select2(select2Options);
80 });
80 });
81 </script>
81 </script>
@@ -1,10 +1,10 b''
1
1
2 ${h.secure_form(url('admin_permissions_global'), method='post')}
2 ${h.secure_form(h.url('admin_permissions_global'), method='post')}
3 <div class="form permissions-global">
3 <div class="form permissions-global">
4 <!-- fields -->
4 <!-- fields -->
5 <div class="fields">
5 <div class="fields">
6 <%namespace name="dpb" file="/base/default_perms_box.mako"/>
6 <%namespace name="dpb" file="/base/default_perms_box.mako"/>
7 ${dpb.default_perms_radios(global_permissions_template = True)}
7 ${dpb.default_perms_radios(global_permissions_template = True)}
8 </div>
8 </div>
9 </div>
9 </div>
10 ${h.end_form()}
10 ${h.end_form()}
@@ -1,77 +1,77 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Default Permissions for Repositories, User Groups and Repository Groups.')}</h3>
3 <h3 class="panel-title">${_('Default Permissions for Repositories, User Groups and Repository Groups.')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6 <p>${_('Default system permissions. Each permissions management entity will be created with the following default settings. Check the overwrite checkbox to force any permission changes on already existing settings.')}
6 <p>${_('Default system permissions. Each permissions management entity will be created with the following default settings. Check the overwrite checkbox to force any permission changes on already existing settings.')}
7 </p>
7 </p>
8 ${h.secure_form(url('admin_permissions_object'), method='post')}
8 ${h.secure_form(h.url('admin_permissions_object'), method='post')}
9 <div class="form">
9 <div class="form">
10 <div class="fields">
10 <div class="fields">
11 <div class="field">
11 <div class="field">
12 <div class="label">
12 <div class="label">
13 <label for="default_repo_perm">${_('Repository')}:</label>
13 <label for="default_repo_perm">${_('Repository')}:</label>
14 </div>
14 </div>
15 <div class="select">
15 <div class="select">
16 ${h.select('default_repo_perm','',c.repo_perms_choices)}
16 ${h.select('default_repo_perm','',c.repo_perms_choices)}
17
17
18 ${h.checkbox('overwrite_default_repo','true')}
18 ${h.checkbox('overwrite_default_repo','true')}
19 <label for="overwrite_default_repo">
19 <label for="overwrite_default_repo">
20 <span class="tooltip" title="${h.tooltip(_('All default permissions on each repository will be reset to chosen permission, note that all custom default permission on repositories will be lost'))}">
20 <span class="tooltip" title="${h.tooltip(_('All default permissions on each repository will be reset to chosen permission, note that all custom default permission on repositories will be lost'))}">
21 ${_('Overwrite Existing Settings')}
21 ${_('Overwrite Existing Settings')}
22 </span>
22 </span>
23 </label>
23 </label>
24 </div>
24 </div>
25 </div>
25 </div>
26 <div class="field">
26 <div class="field">
27 <div class="label">
27 <div class="label">
28 <label for="default_group_perm">${_('Repository Groups')}:</label>
28 <label for="default_group_perm">${_('Repository Groups')}:</label>
29 </div>
29 </div>
30 <div class="select">
30 <div class="select">
31 ${h.select('default_group_perm','',c.group_perms_choices)}
31 ${h.select('default_group_perm','',c.group_perms_choices)}
32 ${h.checkbox('overwrite_default_group','true')}
32 ${h.checkbox('overwrite_default_group','true')}
33 <label for="overwrite_default_group">
33 <label for="overwrite_default_group">
34 <span class="tooltip" title="${h.tooltip(_('All default permissions on each repository group will be reset to chosen permission, note that all custom default permission on repository groups will be lost'))}">
34 <span class="tooltip" title="${h.tooltip(_('All default permissions on each repository group will be reset to chosen permission, note that all custom default permission on repository groups will be lost'))}">
35 ${_('Overwrite Existing Settings')}
35 ${_('Overwrite Existing Settings')}
36 </span>
36 </span>
37 </label>
37 </label>
38 </div>
38 </div>
39 </div>
39 </div>
40 <div class="field">
40 <div class="field">
41 <div class="label">
41 <div class="label">
42 <label for="default_group_perm">${_('User Groups')}:</label>
42 <label for="default_group_perm">${_('User Groups')}:</label>
43 </div>
43 </div>
44 <div class="select">
44 <div class="select">
45 ${h.select('default_user_group_perm','',c.user_group_perms_choices)}
45 ${h.select('default_user_group_perm','',c.user_group_perms_choices)}
46 ${h.checkbox('overwrite_default_user_group','true')}
46 ${h.checkbox('overwrite_default_user_group','true')}
47 <label for="overwrite_default_user_group">
47 <label for="overwrite_default_user_group">
48 <span class="tooltip" title="${h.tooltip(_('All default permissions on each user group will be reset to chosen permission, note that all custom default permission on repository groups will be lost'))}">
48 <span class="tooltip" title="${h.tooltip(_('All default permissions on each user group will be reset to chosen permission, note that all custom default permission on repository groups will be lost'))}">
49 ${_('Overwrite Existing Settings')}
49 ${_('Overwrite Existing Settings')}
50 </span>
50 </span>
51 </label>
51 </label>
52 </div>
52 </div>
53 </div>
53 </div>
54
54
55 <div class="buttons">
55 <div class="buttons">
56 ${h.submit('save',_('Save'),class_="btn")}
56 ${h.submit('save',_('Save'),class_="btn")}
57 ${h.reset('reset',_('Reset'),class_="btn")}
57 ${h.reset('reset',_('Reset'),class_="btn")}
58 </div>
58 </div>
59 </div>
59 </div>
60 </div>
60 </div>
61 ${h.end_form()}
61 ${h.end_form()}
62 </div>
62 </div>
63 </div>
63 </div>
64
64
65 <script>
65 <script>
66 $(document).ready(function(){
66 $(document).ready(function(){
67 var select2Options = {
67 var select2Options = {
68 containerCssClass: 'drop-menu',
68 containerCssClass: 'drop-menu',
69 dropdownCssClass: 'drop-menu-dropdown',
69 dropdownCssClass: 'drop-menu-dropdown',
70 dropdownAutoWidth: true,
70 dropdownAutoWidth: true,
71 minimumResultsForSearch: -1
71 minimumResultsForSearch: -1
72 };
72 };
73 $("#default_repo_perm").select2(select2Options);
73 $("#default_repo_perm").select2(select2Options);
74 $("#default_group_perm").select2(select2Options);
74 $("#default_group_perm").select2(select2Options);
75 $("#default_user_group_perm").select2(select2Options);
75 $("#default_user_group_perm").select2(select2Options);
76 });
76 });
77 </script>
77 </script>
@@ -1,100 +1,100 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 ${_('Add repository group')}
5 ${_('Add repository group')}
6 %if c.rhodecode_name:
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()">
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 &raquo;
13 &raquo;
14 ${h.link_to(_('Repository groups'),h.url('repo_groups'))}
14 ${h.link_to(_('Repository groups'),h.url('repo_groups'))}
15 &raquo;
15 &raquo;
16 ${_('Add Repository Group')}
16 ${_('Add Repository Group')}
17 </%def>
17 </%def>
18
18
19 <%def name="menu_bar_nav()">
19 <%def name="menu_bar_nav()">
20 ${self.menu_items(active='admin')}
20 ${self.menu_items(active='admin')}
21 </%def>
21 </%def>
22
22
23 <%def name="main()">
23 <%def name="main()">
24 <div class="box">
24 <div class="box">
25 <!-- box / title -->
25 <!-- box / title -->
26 <div class="title">
26 <div class="title">
27 ${self.breadcrumbs()}
27 ${self.breadcrumbs()}
28 </div>
28 </div>
29 <!-- end box / title -->
29 <!-- end box / title -->
30 ${h.secure_form(url('repo_groups'), method='post')}
30 ${h.secure_form(h.url('repo_groups'), method='post')}
31 <div class="form">
31 <div class="form">
32 <!-- fields -->
32 <!-- fields -->
33 <div class="fields">
33 <div class="fields">
34 <div class="field">
34 <div class="field">
35 <div class="label">
35 <div class="label">
36 <label for="group_name">${_('Group Name')}:</label>
36 <label for="group_name">${_('Group Name')}:</label>
37 </div>
37 </div>
38 <div class="input">
38 <div class="input">
39 ${h.text('group_name', class_="medium")}
39 ${h.text('group_name', class_="medium")}
40 </div>
40 </div>
41 </div>
41 </div>
42
42
43 <div class="field">
43 <div class="field">
44 <div class="label">
44 <div class="label">
45 <label for="group_description">${_('Description')}:</label>
45 <label for="group_description">${_('Description')}:</label>
46 </div>
46 </div>
47 <div class="textarea editor">
47 <div class="textarea editor">
48 ${h.textarea('group_description',cols=23,rows=5,class_="medium")}
48 ${h.textarea('group_description',cols=23,rows=5,class_="medium")}
49 </div>
49 </div>
50 </div>
50 </div>
51
51
52 <div class="field">
52 <div class="field">
53 <div class="label">
53 <div class="label">
54 <label for="group_parent_id">${_('Group Parent')}:</label>
54 <label for="group_parent_id">${_('Group Parent')}:</label>
55 </div>
55 </div>
56 <div class="select">
56 <div class="select">
57 ${h.select('group_parent_id',request.GET.get('parent_group'),c.repo_groups,class_="medium")}
57 ${h.select('group_parent_id',request.GET.get('parent_group'),c.repo_groups,class_="medium")}
58 </div>
58 </div>
59 </div>
59 </div>
60
60
61 <div id="copy_perms" class="field">
61 <div id="copy_perms" class="field">
62 <div class="label label-checkbox">
62 <div class="label label-checkbox">
63 <label for="group_copy_permissions">${_('Copy Parent Group Permissions')}:</label>
63 <label for="group_copy_permissions">${_('Copy Parent Group Permissions')}:</label>
64 </div>
64 </div>
65 <div class="checkboxes">
65 <div class="checkboxes">
66 ${h.checkbox('group_copy_permissions', value="True", checked="checked")}
66 ${h.checkbox('group_copy_permissions', value="True", checked="checked")}
67 <span class="help-block">${_('Copy permission settings from parent repository group.')}</span>
67 <span class="help-block">${_('Copy permission settings from parent repository group.')}</span>
68 </div>
68 </div>
69 </div>
69 </div>
70
70
71 <div class="buttons">
71 <div class="buttons">
72 ${h.submit('save',_('Save'),class_="btn")}
72 ${h.submit('save',_('Save'),class_="btn")}
73 </div>
73 </div>
74 </div>
74 </div>
75 </div>
75 </div>
76 ${h.end_form()}
76 ${h.end_form()}
77 </div>
77 </div>
78 <script>
78 <script>
79 $(document).ready(function(){
79 $(document).ready(function(){
80 var setCopyPermsOption = function(group_val){
80 var setCopyPermsOption = function(group_val){
81 if(group_val != "-1"){
81 if(group_val != "-1"){
82 $('#copy_perms').show()
82 $('#copy_perms').show()
83 }
83 }
84 else{
84 else{
85 $('#copy_perms').hide();
85 $('#copy_perms').hide();
86 }
86 }
87 }
87 }
88 $("#group_parent_id").select2({
88 $("#group_parent_id").select2({
89 'containerCssClass': "drop-menu",
89 'containerCssClass': "drop-menu",
90 'dropdownCssClass': "drop-menu-dropdown",
90 'dropdownCssClass': "drop-menu-dropdown",
91 'dropdownAutoWidth': true
91 'dropdownAutoWidth': true
92 });
92 });
93 setCopyPermsOption($('#group_parent_id').val())
93 setCopyPermsOption($('#group_parent_id').val())
94 $("#group_parent_id").on("change", function(e) {
94 $("#group_parent_id").on("change", function(e) {
95 setCopyPermsOption(e.val)
95 setCopyPermsOption(e.val)
96 })
96 })
97 $('#group_name').focus();
97 $('#group_name').focus();
98 })
98 })
99 </script>
99 </script>
100 </%def>
100 </%def>
@@ -1,148 +1,148 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('Repository Group Permissions')}</h3>
5 <h3 class="panel-title">${_('Repository Group Permissions')}</h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 ${h.secure_form(url('edit_repo_group_perms', group_name=c.repo_group.group_name),method='put')}
8 ${h.secure_form(h.url('edit_repo_group_perms', group_name=c.repo_group.group_name),method='put')}
9 <table id="permissions_manage" class="rctable permissions">
9 <table id="permissions_manage" class="rctable permissions">
10 <tr>
10 <tr>
11 <th class="td-radio">${_('None')}</th>
11 <th class="td-radio">${_('None')}</th>
12 <th class="td-radio">${_('Read')}</th>
12 <th class="td-radio">${_('Read')}</th>
13 <th class="td-radio">${_('Write')}</th>
13 <th class="td-radio">${_('Write')}</th>
14 <th class="td-radio">${_('Admin')}</th>
14 <th class="td-radio">${_('Admin')}</th>
15 <th class="td-user">${_('User/User Group')}</th>
15 <th class="td-user">${_('User/User Group')}</th>
16 <th></th>
16 <th></th>
17 </tr>
17 </tr>
18 ## USERS
18 ## USERS
19 %for _user in c.repo_group.permissions():
19 %for _user in c.repo_group.permissions():
20 %if getattr(_user, 'admin_row', None) or getattr(_user, 'owner_row', None):
20 %if getattr(_user, 'admin_row', None) or getattr(_user, 'owner_row', None):
21 <tr class="perm_admin_row">
21 <tr class="perm_admin_row">
22 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.none', disabled="disabled")}</td>
22 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.none', disabled="disabled")}</td>
23 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.read', disabled="disabled")}</td>
23 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.read', disabled="disabled")}</td>
24 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.write', disabled="disabled")}</td>
24 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.write', disabled="disabled")}</td>
25 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.admin', 'repository.admin', disabled="disabled")}</td>
25 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.admin', 'repository.admin', disabled="disabled")}</td>
26 <td class="td-user">
26 <td class="td-user">
27 ${base.gravatar(_user.email, 16)}
27 ${base.gravatar(_user.email, 16)}
28 <span class="user">
28 <span class="user">
29 ${h.link_to_user(_user.username)}
29 ${h.link_to_user(_user.username)}
30 %if getattr(_user, 'admin_row', None):
30 %if getattr(_user, 'admin_row', None):
31 (${_('super admin')})
31 (${_('super admin')})
32 %endif
32 %endif
33 %if getattr(_user, 'owner_row', None):
33 %if getattr(_user, 'owner_row', None):
34 (${_('owner')})
34 (${_('owner')})
35 %endif
35 %endif
36 </span>
36 </span>
37 </td>
37 </td>
38 <td></td>
38 <td></td>
39 </tr>
39 </tr>
40 %else:
40 %else:
41 ##forbid revoking permission from yourself, except if you're an super admin
41 ##forbid revoking permission from yourself, except if you're an super admin
42 <tr>
42 <tr>
43 %if c.rhodecode_user.user_id != _user.user_id or c.rhodecode_user.is_admin:
43 %if c.rhodecode_user.user_id != _user.user_id or c.rhodecode_user.is_admin:
44 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.none')}</td>
44 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.none')}</td>
45 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.read')}</td>
45 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.read')}</td>
46 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.write')}</td>
46 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.write')}</td>
47 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.admin')}</td>
47 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.admin')}</td>
48 <td class="td-user">
48 <td class="td-user">
49 ${base.gravatar(_user.email, 16)}
49 ${base.gravatar(_user.email, 16)}
50 <span class="user">
50 <span class="user">
51 % if _user.username == h.DEFAULT_USER:
51 % if _user.username == h.DEFAULT_USER:
52 ${h.DEFAULT_USER} <span class="user-perm-help-text"> - ${_('permission for all other users')}</span>
52 ${h.DEFAULT_USER} <span class="user-perm-help-text"> - ${_('permission for all other users')}</span>
53 % else:
53 % else:
54 ${h.link_to_user(_user.username)}
54 ${h.link_to_user(_user.username)}
55 % endif
55 % endif
56 </span>
56 </span>
57 </td>
57 </td>
58 <td class="td-action">
58 <td class="td-action">
59 %if _user.username != h.DEFAULT_USER:
59 %if _user.username != h.DEFAULT_USER:
60 <span class="btn btn-link btn-danger revoke_perm"
60 <span class="btn btn-link btn-danger revoke_perm"
61 member="${_user.user_id}" member_type="user">
61 member="${_user.user_id}" member_type="user">
62 <i class="icon-remove"></i> ${_('Revoke')}
62 <i class="icon-remove"></i> ${_('Revoke')}
63 </span>
63 </span>
64 %endif
64 %endif
65 </td>
65 </td>
66 %else:
66 %else:
67 ## special case for current user permissions, we make sure he cannot take his own permissions
67 ## special case for current user permissions, we make sure he cannot take his own permissions
68 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.none', disabled="disabled")}</td>
68 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.none', disabled="disabled")}</td>
69 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.read', disabled="disabled")}</td>
69 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.read', disabled="disabled")}</td>
70 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.write', disabled="disabled")}</td>
70 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.write', disabled="disabled")}</td>
71 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.admin', disabled="disabled")}</td>
71 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'group.admin', disabled="disabled")}</td>
72 <td class="td-user">
72 <td class="td-user">
73 ${base.gravatar(_user.email, 16)}
73 ${base.gravatar(_user.email, 16)}
74 <span class="user">
74 <span class="user">
75 % if _user.username == h.DEFAULT_USER:
75 % if _user.username == h.DEFAULT_USER:
76 ${h.DEFAULT_USER} <span class="user-perm-help-text"> - ${_('permission for all other users')}</span>
76 ${h.DEFAULT_USER} <span class="user-perm-help-text"> - ${_('permission for all other users')}</span>
77 % else:
77 % else:
78 ${h.link_to_user(_user.username)}
78 ${h.link_to_user(_user.username)}
79 % endif
79 % endif
80 <span class="user-perm-help-text">(${_('delegated admin')})</span>
80 <span class="user-perm-help-text">(${_('delegated admin')})</span>
81 </span>
81 </span>
82 </td>
82 </td>
83 <td></td>
83 <td></td>
84 %endif
84 %endif
85 </tr>
85 </tr>
86 %endif
86 %endif
87 %endfor
87 %endfor
88
88
89 ## USER GROUPS
89 ## USER GROUPS
90 %for _user_group in c.repo_group.permission_user_groups():
90 %for _user_group in c.repo_group.permission_user_groups():
91 <tr id="id${id(_user_group.users_group_name)}">
91 <tr id="id${id(_user_group.users_group_name)}">
92 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.none')}</td>
92 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.none')}</td>
93 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.read')}</td>
93 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.read')}</td>
94 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.write')}</td>
94 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.write')}</td>
95 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.admin')}</td>
95 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.admin')}</td>
96 <td class="td-componentname">
96 <td class="td-componentname">
97 <i class="icon-group" ></i>
97 <i class="icon-group" ></i>
98 %if h.HasPermissionAny('hg.admin')():
98 %if h.HasPermissionAny('hg.admin')():
99 <a href="${h.url('edit_users_group',user_group_id=_user_group.users_group_id)}">
99 <a href="${h.url('edit_users_group',user_group_id=_user_group.users_group_id)}">
100 ${_user_group.users_group_name}
100 ${_user_group.users_group_name}
101 </a>
101 </a>
102 %else:
102 %else:
103 ${_user_group.users_group_name}
103 ${_user_group.users_group_name}
104 %endif
104 %endif
105 </td>
105 </td>
106 <td class="td-action">
106 <td class="td-action">
107 <span class="btn btn-link btn-danger revoke_perm"
107 <span class="btn btn-link btn-danger revoke_perm"
108 member="${_user_group.users_group_id}" member_type="user_group">
108 member="${_user_group.users_group_id}" member_type="user_group">
109 <i class="icon-remove"></i> ${_('Revoke')}
109 <i class="icon-remove"></i> ${_('Revoke')}
110 </span>
110 </span>
111 </td>
111 </td>
112 </tr>
112 </tr>
113 %endfor
113 %endfor
114
114
115 <tr class="new_members" id="add_perm_input"></tr>
115 <tr class="new_members" id="add_perm_input"></tr>
116 </table>
116 </table>
117 <div id="add_perm" class="link">
117 <div id="add_perm" class="link">
118 ${_('Add new')}
118 ${_('Add new')}
119 </div>
119 </div>
120 <div class="fields">
120 <div class="fields">
121 <div class="field">
121 <div class="field">
122 <div class="label label-radio">
122 <div class="label label-radio">
123 ${_('Apply to children')}:
123 ${_('Apply to children')}:
124 </div>
124 </div>
125 <div class="radios">
125 <div class="radios">
126 ${h.radio('recursive', 'none', label=_('None'), checked="checked")}
126 ${h.radio('recursive', 'none', label=_('None'), checked="checked")}
127 ${h.radio('recursive', 'groups', label=_('Repository Groups'))}
127 ${h.radio('recursive', 'groups', label=_('Repository Groups'))}
128 ${h.radio('recursive', 'repos', label=_('Repositories'))}
128 ${h.radio('recursive', 'repos', label=_('Repositories'))}
129 ${h.radio('recursive', 'all', label=_('Both'))}
129 ${h.radio('recursive', 'all', label=_('Both'))}
130 <span class="help-block">${_('Set or revoke permissions to selected types of children of this group, including non-private repositories and other groups if chosen.')}</span>
130 <span class="help-block">${_('Set or revoke permissions to selected types of children of this group, including non-private repositories and other groups if chosen.')}</span>
131 </div>
131 </div>
132 </div>
132 </div>
133 </div>
133 </div>
134 <div class="buttons">
134 <div class="buttons">
135 ${h.submit('save',_('Save'),class_="btn btn-primary")}
135 ${h.submit('save',_('Save'),class_="btn btn-primary")}
136 ${h.reset('reset',_('Reset'),class_="btn btn-danger")}
136 ${h.reset('reset',_('Reset'),class_="btn btn-danger")}
137 </div>
137 </div>
138 ${h.end_form()}
138 ${h.end_form()}
139 </div>
139 </div>
140 </div>
140 </div>
141 <script type="text/javascript">
141 <script type="text/javascript">
142 $('#add_perm').on('click', function(e){
142 $('#add_perm').on('click', function(e){
143 addNewPermInput($(this), 'group');
143 addNewPermInput($(this), 'group');
144 });
144 });
145 $('.revoke_perm').on('click', function(e){
145 $('.revoke_perm').on('click', function(e){
146 markRevokePermInput($(this), 'group');
146 markRevokePermInput($(this), 'group');
147 })
147 })
148 </script>
148 </script>
@@ -1,84 +1,84 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%namespace name="base" file="/base/base.mako"/>
2 <%namespace name="base" file="/base/base.mako"/>
3
3
4 <div class="panel panel-default">
4 <div class="panel panel-default">
5 <div class="panel-heading">
5 <div class="panel-heading">
6 <h3 class="panel-title">${_('Settings for Repository Group: %s') % c.repo_group.name}</h3>
6 <h3 class="panel-title">${_('Settings for Repository Group: %s') % c.repo_group.name}</h3>
7 </div>
7 </div>
8 <div class="panel-body">
8 <div class="panel-body">
9 ${h.secure_form(url('update_repo_group',group_name=c.repo_group.group_name),method='put')}
9 ${h.secure_form(h.url('update_repo_group',group_name=c.repo_group.group_name),method='put')}
10 <div class="form">
10 <div class="form">
11 <!-- fields -->
11 <!-- fields -->
12 <div class="fields">
12 <div class="fields">
13 <div class="field">
13 <div class="field">
14 <div class="label">
14 <div class="label">
15 <label for="group_name">${_('Group Name')}:</label>
15 <label for="group_name">${_('Group Name')}:</label>
16 </div>
16 </div>
17 <div class="input">
17 <div class="input">
18 ${h.text('group_name',class_='medium')}
18 ${h.text('group_name',class_='medium')}
19 </div>
19 </div>
20 </div>
20 </div>
21
21
22 <div class="field badged-field">
22 <div class="field badged-field">
23 <div class="label">
23 <div class="label">
24 <label for="user">${_('Owner')}:</label>
24 <label for="user">${_('Owner')}:</label>
25 </div>
25 </div>
26 <div class="input">
26 <div class="input">
27 <div class="badge-input-container">
27 <div class="badge-input-container">
28 <div class="user-badge">
28 <div class="user-badge">
29 ${base.gravatar_with_user(c.repo_group.user.email, show_disabled=not c.repo_group.user.active)}
29 ${base.gravatar_with_user(c.repo_group.user.email, show_disabled=not c.repo_group.user.active)}
30 </div>
30 </div>
31 <div class="badge-input-wrap">
31 <div class="badge-input-wrap">
32 ${h.text('user', class_="medium", autocomplete="off")}
32 ${h.text('user', class_="medium", autocomplete="off")}
33 </div>
33 </div>
34 </div>
34 </div>
35 <form:error name="user"/>
35 <form:error name="user"/>
36 <p class="help-block">${_('Change owner of this repository group.')}</p>
36 <p class="help-block">${_('Change owner of this repository group.')}</p>
37 </div>
37 </div>
38 </div>
38 </div>
39
39
40 <div class="field">
40 <div class="field">
41 <div class="label label-textarea">
41 <div class="label label-textarea">
42 <label for="group_description">${_('Description')}:</label>
42 <label for="group_description">${_('Description')}:</label>
43 </div>
43 </div>
44 <div class="textarea text-area editor">
44 <div class="textarea text-area editor">
45 ${h.textarea('group_description',cols=23,rows=5,class_="medium")}
45 ${h.textarea('group_description',cols=23,rows=5,class_="medium")}
46 </div>
46 </div>
47 </div>
47 </div>
48
48
49 <div class="field">
49 <div class="field">
50 <div class="label">
50 <div class="label">
51 <label for="group_parent_id">${_('Group parent')}:</label>
51 <label for="group_parent_id">${_('Group parent')}:</label>
52 </div>
52 </div>
53 <div class="select">
53 <div class="select">
54 ${h.select('group_parent_id','',c.repo_groups,class_="medium")}
54 ${h.select('group_parent_id','',c.repo_groups,class_="medium")}
55 </div>
55 </div>
56 </div>
56 </div>
57 <div class="field">
57 <div class="field">
58 <div class="label label-checkbox">
58 <div class="label label-checkbox">
59 <label for="enable_locking">${_('Enable Repository Locking')}:</label>
59 <label for="enable_locking">${_('Enable Repository Locking')}:</label>
60 </div>
60 </div>
61 <div class="checkboxes">
61 <div class="checkboxes">
62 ${h.checkbox('enable_locking',value="True")}
62 ${h.checkbox('enable_locking',value="True")}
63 <span class="help-block">${_('Repository locking will be enabled on all subgroups and repositories inside this repository group. Pulling from a repository locks it, and it is unlocked by pushing back by the same user.')}</span>
63 <span class="help-block">${_('Repository locking will be enabled on all subgroups and repositories inside this repository group. Pulling from a repository locks it, and it is unlocked by pushing back by the same user.')}</span>
64 </div>
64 </div>
65 </div>
65 </div>
66 <div class="buttons">
66 <div class="buttons">
67 ${h.submit('save',_('Save'),class_="btn")}
67 ${h.submit('save',_('Save'),class_="btn")}
68 ${h.reset('reset',_('Reset'),class_="btn")}
68 ${h.reset('reset',_('Reset'),class_="btn")}
69 </div>
69 </div>
70 </div>
70 </div>
71 </div>
71 </div>
72 ${h.end_form()}
72 ${h.end_form()}
73 </div>
73 </div>
74 </div>
74 </div>
75 <script>
75 <script>
76 $(document).ready(function(){
76 $(document).ready(function(){
77 $("#group_parent_id").select2({
77 $("#group_parent_id").select2({
78 'containerCssClass': "drop-menu",
78 'containerCssClass': "drop-menu",
79 'dropdownCssClass': "drop-menu-dropdown",
79 'dropdownCssClass': "drop-menu-dropdown",
80 'dropdownAutoWidth': true
80 'dropdownAutoWidth': true
81 });
81 });
82 UsersAutoComplete('user', '${c.rhodecode_user.user_id}');
82 UsersAutoComplete('user', '${c.rhodecode_user.user_id}');
83 })
83 })
84 </script>
84 </script>
@@ -1,159 +1,159 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 ${h.secure_form(url('repos'))}
3 ${h.secure_form(h.url('repos'))}
4 <div class="form">
4 <div class="form">
5 <!-- fields -->
5 <!-- fields -->
6 <div class="fields">
6 <div class="fields">
7 <div class="field">
7 <div class="field">
8 <div class="label">
8 <div class="label">
9 <label for="repo_name">${_('Name')}:</label>
9 <label for="repo_name">${_('Name')}:</label>
10 </div>
10 </div>
11 <div class="input">
11 <div class="input">
12 ${h.text('repo_name', class_="medium")}
12 ${h.text('repo_name', class_="medium")}
13 <div class="info-block">
13 <div class="info-block">
14 <a id="remote_clone_toggle" href="#"><i class="icon-download-alt"></i> ${_('Import Existing Repository ?')}</a>
14 <a id="remote_clone_toggle" href="#"><i class="icon-download-alt"></i> ${_('Import Existing Repository ?')}</a>
15 </div>
15 </div>
16 %if not c.rhodecode_user.is_admin:
16 %if not c.rhodecode_user.is_admin:
17 ${h.hidden('user_created',True)}
17 ${h.hidden('user_created',True)}
18 %endif
18 %endif
19 </div>
19 </div>
20 </div>
20 </div>
21 <div id="remote_clone" class="field" style="display: none;">
21 <div id="remote_clone" class="field" style="display: none;">
22 <div class="label">
22 <div class="label">
23 <label for="clone_uri">${_('Clone from')}:</label>
23 <label for="clone_uri">${_('Clone from')}:</label>
24 </div>
24 </div>
25 <div class="input">
25 <div class="input">
26 ${h.text('clone_uri', class_="medium")}
26 ${h.text('clone_uri', class_="medium")}
27 <span class="help-block">
27 <span class="help-block">
28 <pre>
28 <pre>
29 - The repository must be accessible over http:// or https://
29 - The repository must be accessible over http:// or https://
30 - For Git projects it's recommended appending .git to the end of clone url.
30 - For Git projects it's recommended appending .git to the end of clone url.
31 - Make sure to select proper repository type from the below selector before importing it.
31 - Make sure to select proper repository type from the below selector before importing it.
32 - If your HTTP[S] repository is not publicly accessible,
32 - If your HTTP[S] repository is not publicly accessible,
33 add authentication information to the URL: https://username:password@server.company.com/repo-name.
33 add authentication information to the URL: https://username:password@server.company.com/repo-name.
34 - The Git LFS/Mercurial Largefiles objects will not be imported.
34 - The Git LFS/Mercurial Largefiles objects will not be imported.
35 - For very large repositories, it's recommended to manually copy them into the
35 - For very large repositories, it's recommended to manually copy them into the
36 RhodeCode <a href="${h.url('admin_settings_vcs', anchor='vcs-storage-options')}">storage location</a> and run <a href="${h.url('admin_settings_mapping')}">Remap and Rescan</a>.
36 RhodeCode <a href="${h.url('admin_settings_vcs', anchor='vcs-storage-options')}">storage location</a> and run <a href="${h.url('admin_settings_mapping')}">Remap and Rescan</a>.
37 </pre>
37 </pre>
38 </span>
38 </span>
39 </div>
39 </div>
40 </div>
40 </div>
41 <div class="field">
41 <div class="field">
42 <div class="label">
42 <div class="label">
43 <label for="repo_description">${_('Description')}:</label>
43 <label for="repo_description">${_('Description')}:</label>
44 </div>
44 </div>
45 <div class="textarea editor">
45 <div class="textarea editor">
46 ${h.textarea('repo_description')}
46 ${h.textarea('repo_description')}
47 <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
47 <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
48 </div>
48 </div>
49 </div>
49 </div>
50 <div class="field">
50 <div class="field">
51 <div class="label">
51 <div class="label">
52 <label for="repo_group">${_('Repository Group')}:</label>
52 <label for="repo_group">${_('Repository Group')}:</label>
53 </div>
53 </div>
54 <div class="select">
54 <div class="select">
55 ${h.select('repo_group',request.GET.get('parent_group'),c.repo_groups,class_="medium")}
55 ${h.select('repo_group',request.GET.get('parent_group'),c.repo_groups,class_="medium")}
56 % if c.personal_repo_group:
56 % if c.personal_repo_group:
57 <a class="btn" href="#" id="select_my_group" data-personal-group-id="${c.personal_repo_group.group_id}">
57 <a class="btn" href="#" id="select_my_group" data-personal-group-id="${c.personal_repo_group.group_id}">
58 ${_('Select my personal group (%(repo_group_name)s)') % {'repo_group_name': c.personal_repo_group.group_name}}
58 ${_('Select my personal group (%(repo_group_name)s)') % {'repo_group_name': c.personal_repo_group.group_name}}
59 </a>
59 </a>
60 % endif
60 % endif
61 <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
61 <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
62 </div>
62 </div>
63 </div>
63 </div>
64 <div id="copy_perms" class="field">
64 <div id="copy_perms" class="field">
65 <div class="label label-checkbox">
65 <div class="label label-checkbox">
66 <label for="repo_copy_permissions">${_('Copy Parent Group Permissions')}:</label>
66 <label for="repo_copy_permissions">${_('Copy Parent Group Permissions')}:</label>
67 </div>
67 </div>
68 <div class="checkboxes">
68 <div class="checkboxes">
69 ${h.checkbox('repo_copy_permissions', value="True", checked="checked")}
69 ${h.checkbox('repo_copy_permissions', value="True", checked="checked")}
70 <span class="help-block">${_('Copy permission set from the parent repository group.')}</span>
70 <span class="help-block">${_('Copy permission set from the parent repository group.')}</span>
71 </div>
71 </div>
72 </div>
72 </div>
73 <div class="field">
73 <div class="field">
74 <div class="label">
74 <div class="label">
75 <label for="repo_type">${_('Type')}:</label>
75 <label for="repo_type">${_('Type')}:</label>
76 </div>
76 </div>
77 <div class="select">
77 <div class="select">
78 ${h.select('repo_type','hg',c.backends)}
78 ${h.select('repo_type','hg',c.backends)}
79 <span class="help-block">${_('Set the type of repository to create.')}</span>
79 <span class="help-block">${_('Set the type of repository to create.')}</span>
80 </div>
80 </div>
81 </div>
81 </div>
82 <div class="field">
82 <div class="field">
83 <div class="label">
83 <div class="label">
84 <label for="repo_landing_rev">${_('Landing commit')}:</label>
84 <label for="repo_landing_rev">${_('Landing commit')}:</label>
85 </div>
85 </div>
86 <div class="select">
86 <div class="select">
87 ${h.select('repo_landing_rev','',c.landing_revs,class_="medium")}
87 ${h.select('repo_landing_rev','',c.landing_revs,class_="medium")}
88 <span class="help-block">${_('The default commit for file pages, downloads, full text search index, and README generation.')}</span>
88 <span class="help-block">${_('The default commit for file pages, downloads, full text search index, and README generation.')}</span>
89 </div>
89 </div>
90 </div>
90 </div>
91 <div class="field">
91 <div class="field">
92 <div class="label label-checkbox">
92 <div class="label label-checkbox">
93 <label for="repo_private">${_('Private Repository')}:</label>
93 <label for="repo_private">${_('Private Repository')}:</label>
94 </div>
94 </div>
95 <div class="checkboxes">
95 <div class="checkboxes">
96 ${h.checkbox('repo_private',value="True")}
96 ${h.checkbox('repo_private',value="True")}
97 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
97 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
98 </div>
98 </div>
99 </div>
99 </div>
100 <div class="buttons">
100 <div class="buttons">
101 ${h.submit('save',_('Save'),class_="btn")}
101 ${h.submit('save',_('Save'),class_="btn")}
102 </div>
102 </div>
103 </div>
103 </div>
104 </div>
104 </div>
105 <script>
105 <script>
106 $(document).ready(function(){
106 $(document).ready(function(){
107 var setCopyPermsOption = function(group_val){
107 var setCopyPermsOption = function(group_val){
108 if(group_val != "-1"){
108 if(group_val != "-1"){
109 $('#copy_perms').show()
109 $('#copy_perms').show()
110 }
110 }
111 else{
111 else{
112 $('#copy_perms').hide();
112 $('#copy_perms').hide();
113 }
113 }
114 };
114 };
115
115
116 $('#remote_clone_toggle').on('click', function(e){
116 $('#remote_clone_toggle').on('click', function(e){
117 $('#remote_clone').show();
117 $('#remote_clone').show();
118 e.preventDefault();
118 e.preventDefault();
119 });
119 });
120
120
121 if($('#remote_clone input').hasClass('error')){
121 if($('#remote_clone input').hasClass('error')){
122 $('#remote_clone').show();
122 $('#remote_clone').show();
123 }
123 }
124 if($('#remote_clone input').val()){
124 if($('#remote_clone input').val()){
125 $('#remote_clone').show();
125 $('#remote_clone').show();
126 }
126 }
127
127
128 $("#repo_group").select2({
128 $("#repo_group").select2({
129 'containerCssClass': "drop-menu",
129 'containerCssClass': "drop-menu",
130 'dropdownCssClass': "drop-menu-dropdown",
130 'dropdownCssClass': "drop-menu-dropdown",
131 'dropdownAutoWidth': true,
131 'dropdownAutoWidth': true,
132 'width': "resolve"
132 'width': "resolve"
133 });
133 });
134
134
135 setCopyPermsOption($('#repo_group').val());
135 setCopyPermsOption($('#repo_group').val());
136 $("#repo_group").on("change", function(e) {
136 $("#repo_group").on("change", function(e) {
137 setCopyPermsOption(e.val)
137 setCopyPermsOption(e.val)
138 });
138 });
139
139
140 $("#repo_type").select2({
140 $("#repo_type").select2({
141 'containerCssClass': "drop-menu",
141 'containerCssClass': "drop-menu",
142 'dropdownCssClass': "drop-menu-dropdown",
142 'dropdownCssClass': "drop-menu-dropdown",
143 'minimumResultsForSearch': -1,
143 'minimumResultsForSearch': -1,
144 });
144 });
145 $("#repo_landing_rev").select2({
145 $("#repo_landing_rev").select2({
146 'containerCssClass': "drop-menu",
146 'containerCssClass': "drop-menu",
147 'dropdownCssClass': "drop-menu-dropdown",
147 'dropdownCssClass': "drop-menu-dropdown",
148 'minimumResultsForSearch': -1,
148 'minimumResultsForSearch': -1,
149 });
149 });
150 $('#repo_name').focus();
150 $('#repo_name').focus();
151
151
152 $('#select_my_group').on('click', function(e){
152 $('#select_my_group').on('click', function(e){
153 e.preventDefault();
153 e.preventDefault();
154 $("#repo_group").val($(this).data('personalGroupId')).trigger("change");
154 $("#repo_group").val($(this).data('personalGroupId')).trigger("change");
155 })
155 })
156
156
157 })
157 })
158 </script>
158 </script>
159 ${h.end_form()}
159 ${h.end_form()}
@@ -1,79 +1,79 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Custom extra fields for this repository')}</h3>
3 <h3 class="panel-title">${_('Custom extra fields for this repository')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6 %if c.visual.repository_fields:
6 %if c.visual.repository_fields:
7 %if c.repo_fields:
7 %if c.repo_fields:
8 <div class="emails_wrap">
8 <div class="emails_wrap">
9 <table class="rctable edit_fields">
9 <table class="rctable edit_fields">
10 <th>${_('Label')}</th>
10 <th>${_('Label')}</th>
11 <th>${_('Key')}</th>
11 <th>${_('Key')}</th>
12 <th>${_('Type')}</th>
12 <th>${_('Type')}</th>
13 <th>${_('Action')}</th>
13 <th>${_('Action')}</th>
14
14
15 %for field in c.repo_fields:
15 %for field in c.repo_fields:
16 <tr>
16 <tr>
17 <td class="td-tags">${field.field_label}</td>
17 <td class="td-tags">${field.field_label}</td>
18 <td class="td-hash">${field.field_key}</td>
18 <td class="td-hash">${field.field_key}</td>
19 <td class="td-type">${field.field_type}</td>
19 <td class="td-type">${field.field_type}</td>
20 <td class="td-action">
20 <td class="td-action">
21 ${h.secure_form(url('delete_repo_fields', repo_name=c.repo_info.repo_name, field_id=field.repo_field_id),method='delete')}
21 ${h.secure_form(h.url('delete_repo_fields', repo_name=c.repo_info.repo_name, field_id=field.repo_field_id),method='delete')}
22 ${h.hidden('del_repo_field',field.repo_field_id)}
22 ${h.hidden('del_repo_field',field.repo_field_id)}
23 <button class="btn btn-link btn-danger" type="submit"
23 <button class="btn btn-link btn-danger" type="submit"
24 onclick="return confirm('${_('Confirm to delete this field: %s') % field.field_key}');">
24 onclick="return confirm('${_('Confirm to delete this field: %s') % field.field_key}');">
25 ${_('Delete')}
25 ${_('Delete')}
26 </button>
26 </button>
27 ${h.end_form()}
27 ${h.end_form()}
28 </td>
28 </td>
29 </tr>
29 </tr>
30 %endfor
30 %endfor
31 </table>
31 </table>
32 </div>
32 </div>
33 %endif
33 %endif
34 ${h.secure_form(url('create_repo_fields', repo_name=c.repo_name),method='put')}
34 ${h.secure_form(h.url('create_repo_fields', repo_name=c.repo_name),method='put')}
35 <div class="form">
35 <div class="form">
36 <!-- fields -->
36 <!-- fields -->
37 <div class="fields">
37 <div class="fields">
38 <div class="field">
38 <div class="field">
39 <div class="label">
39 <div class="label">
40 <label for="new_field_key">${_('New Field Key')}:</label>
40 <label for="new_field_key">${_('New Field Key')}:</label>
41 </div>
41 </div>
42 <div class="input">
42 <div class="input">
43 ${h.text('new_field_key', class_='medium')}
43 ${h.text('new_field_key', class_='medium')}
44 </div>
44 </div>
45 </div>
45 </div>
46 <div class="field">
46 <div class="field">
47 <div class="label">
47 <div class="label">
48 <label for="new_field_label">${_('New Field Label')}:</label>
48 <label for="new_field_label">${_('New Field Label')}:</label>
49 </div>
49 </div>
50 <div class="input">
50 <div class="input">
51 ${h.text('new_field_label', class_='medium', placeholder=_('Enter short label'))}
51 ${h.text('new_field_label', class_='medium', placeholder=_('Enter short label'))}
52 </div>
52 </div>
53 </div>
53 </div>
54
54
55 <div class="field">
55 <div class="field">
56 <div class="label">
56 <div class="label">
57 <label for="new_field_desc">${_('New Field Description')}:</label>
57 <label for="new_field_desc">${_('New Field Description')}:</label>
58 </div>
58 </div>
59 <div class="input">
59 <div class="input">
60 ${h.text('new_field_desc', class_='medium', placeholder=_('Enter a full description for the field'))}
60 ${h.text('new_field_desc', class_='medium', placeholder=_('Enter a full description for the field'))}
61 </div>
61 </div>
62 </div>
62 </div>
63
63
64 <div class="buttons">
64 <div class="buttons">
65 ${h.submit('save',_('Add'),class_="btn")}
65 ${h.submit('save',_('Add'),class_="btn")}
66 ${h.reset('reset',_('Reset'),class_="btn")}
66 ${h.reset('reset',_('Reset'),class_="btn")}
67 </div>
67 </div>
68 </div>
68 </div>
69 </div>
69 </div>
70 ${h.end_form()}
70 ${h.end_form()}
71 %else:
71 %else:
72 <h2>
72 <h2>
73 ${_('Extra fields are disabled. You can enable them from the Admin/Settings/Visual page.')}
73 ${_('Extra fields are disabled. You can enable them from the Admin/Settings/Visual page.')}
74 </h2>
74 </h2>
75 %endif
75 %endif
76 </div>
76 </div>
77 </div>
77 </div>
78
78
79
79
@@ -1,109 +1,109 b''
1 <%namespace name="its" file="/base/issue_tracker_settings.mako"/>
1 <%namespace name="its" file="/base/issue_tracker_settings.mako"/>
2
2
3 <div id="repo_issue_tracker" class="${'inherited' if c.settings_model.inherit_global_settings else ''}">
3 <div id="repo_issue_tracker" class="${'inherited' if c.settings_model.inherit_global_settings else ''}">
4 ${h.secure_form(url('repo_issuetracker_save', repo_name=c.repo_name), method='post', id="inherit-form")}
4 ${h.secure_form(h.url('repo_issuetracker_save', repo_name=c.repo_name), method='post', id="inherit-form")}
5 <div class="panel panel-default panel-body">
5 <div class="panel panel-default panel-body">
6 <div class="fields">
6 <div class="fields">
7 <div class="field">
7 <div class="field">
8 <div class="label label-checkbox">
8 <div class="label label-checkbox">
9 <label for="inherit_default_permissions">${_('Inherit from global settings')}:</label>
9 <label for="inherit_default_permissions">${_('Inherit from global settings')}:</label>
10 </div>
10 </div>
11 <div class="checkboxes">
11 <div class="checkboxes">
12 ${h.checkbox('inherit_global_issuetracker', value='inherited', checked=c.settings_model.inherit_global_settings)}
12 ${h.checkbox('inherit_global_issuetracker', value='inherited', checked=c.settings_model.inherit_global_settings)}
13 <span class="help-block">
13 <span class="help-block">
14 ${h.literal(_('Select to inherit global patterns for issue tracker.'))}
14 ${h.literal(_('Select to inherit global patterns for issue tracker.'))}
15 </span>
15 </span>
16 </div>
16 </div>
17 </div>
17 </div>
18 </div>
18 </div>
19 </div>
19 </div>
20
20
21 <div id="inherit_overlay">
21 <div id="inherit_overlay">
22 <div class="panel panel-default">
22 <div class="panel panel-default">
23 <div class="panel-heading">
23 <div class="panel-heading">
24 <h3 class="panel-title">${_('Inherited Issue Tracker Patterns')}</h3>
24 <h3 class="panel-title">${_('Inherited Issue Tracker Patterns')}</h3>
25 </div>
25 </div>
26 <div class="panel-body">
26 <div class="panel-body">
27 <table class="rctable issuetracker readonly">
27 <table class="rctable issuetracker readonly">
28 <tr>
28 <tr>
29 <th>${_('Description')}</th>
29 <th>${_('Description')}</th>
30 <th>${_('Pattern')}</th>
30 <th>${_('Pattern')}</th>
31 <th>${_('Url')}</th>
31 <th>${_('Url')}</th>
32 <th>${_('Prefix')}</th>
32 <th>${_('Prefix')}</th>
33 <th ></th>
33 <th ></th>
34 </tr>
34 </tr>
35 %for uid, entry in c.global_patterns.items():
35 %for uid, entry in c.global_patterns.items():
36 <tr id="${uid}">
36 <tr id="${uid}">
37 <td class="td-description issuetracker_desc">
37 <td class="td-description issuetracker_desc">
38 <span class="entry">
38 <span class="entry">
39 ${entry.desc}
39 ${entry.desc}
40 </span>
40 </span>
41 </td>
41 </td>
42 <td class="td-regex issuetracker_pat">
42 <td class="td-regex issuetracker_pat">
43 <span class="entry">
43 <span class="entry">
44 ${entry.pat}
44 ${entry.pat}
45 </span>
45 </span>
46 </td>
46 </td>
47 <td class="td-url issuetracker_url">
47 <td class="td-url issuetracker_url">
48 <span class="entry">
48 <span class="entry">
49 ${entry.url}
49 ${entry.url}
50 </span>
50 </span>
51 </td>
51 </td>
52 <td class="td-prefix issuetracker_pref">
52 <td class="td-prefix issuetracker_pref">
53 <span class="entry">
53 <span class="entry">
54 ${entry.pref}
54 ${entry.pref}
55 </span>
55 </span>
56 </td>
56 </td>
57 <td class="td-action">
57 <td class="td-action">
58 </td>
58 </td>
59 </tr>
59 </tr>
60 %endfor
60 %endfor
61
61
62 </table>
62 </table>
63 </div>
63 </div>
64 </div>
64 </div>
65 </div>
65 </div>
66
66
67 <div id="custom_overlay">
67 <div id="custom_overlay">
68 <div class="panel panel-default">
68 <div class="panel panel-default">
69 <div class="panel-heading">
69 <div class="panel-heading">
70 <h3 class="panel-title">${_('Issue Tracker / Wiki Patterns')}</h3>
70 <h3 class="panel-title">${_('Issue Tracker / Wiki Patterns')}</h3>
71 </div>
71 </div>
72 <div class="panel-body">
72 <div class="panel-body">
73 ${its.issue_tracker_settings_table(
73 ${its.issue_tracker_settings_table(
74 patterns=c.repo_patterns.items(),
74 patterns=c.repo_patterns.items(),
75 form_url=url('repo_settings_issuetracker', repo_name=c.repo_info.repo_name),
75 form_url=h.url('repo_settings_issuetracker', repo_name=c.repo_info.repo_name),
76 delete_url=url('repo_issuetracker_delete', repo_name=c.repo_info.repo_name)
76 delete_url=h.url('repo_issuetracker_delete', repo_name=c.repo_info.repo_name)
77 )}
77 )}
78 <div class="buttons">
78 <div class="buttons">
79 <button type="submit" class="btn btn-primary save-inheritance" id="save">${_('Save')}</button>
79 <button type="submit" class="btn btn-primary save-inheritance" id="save">${_('Save')}</button>
80 <button type="reset" class="btn reset-inheritance">${_('Reset')}</button>
80 <button type="reset" class="btn reset-inheritance">${_('Reset')}</button>
81 </div>
81 </div>
82 </div>
82 </div>
83 </div>
83 </div>
84 </div>
84 </div>
85
85
86
86
87 ${h.end_form()}
87 ${h.end_form()}
88
88
89 <div class="panel panel-default">
89 <div class="panel panel-default">
90 <div class="panel-heading">
90 <div class="panel-heading">
91 <h3 class="panel-title">${_('Test Patterns')}</h3>
91 <h3 class="panel-title">${_('Test Patterns')}</h3>
92 </div>
92 </div>
93 <div class="panel-body">
93 <div class="panel-body">
94 ${its.issue_tracker_new_row()}
94 ${its.issue_tracker_new_row()}
95 ${its.issue_tracker_settings_test(test_url=url('repo_issuetracker_test', repo_name=c.repo_info.repo_name))}
95 ${its.issue_tracker_settings_test(test_url=h.url('repo_issuetracker_test', repo_name=c.repo_info.repo_name))}
96 </div>
96 </div>
97 </div>
97 </div>
98
98
99 </div>
99 </div>
100
100
101 <script>
101 <script>
102 $('#inherit_global_issuetracker').on('change', function(e){
102 $('#inherit_global_issuetracker').on('change', function(e){
103 $('#repo_issue_tracker').toggleClass('inherited',this.checked);
103 $('#repo_issue_tracker').toggleClass('inherited',this.checked);
104 });
104 });
105
105
106 $('.reset-inheritance').on('click', function(e){
106 $('.reset-inheritance').on('click', function(e){
107 $('#inherit_global_issuetracker').prop('checked', false).change();
107 $('#inherit_global_issuetracker').prop('checked', false).change();
108 });
108 });
109 </script>
109 </script>
@@ -1,40 +1,40 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Remote url')}</h3>
3 <h3 class="panel-title">${_('Remote url')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6
6
7 <h4>${_('Manually pull changes from external repository.')}</h4>
7 <h4>${_('Manually pull changes from external repository.')}</h4>
8
8
9 %if c.repo_info.clone_uri:
9 %if c.repo_info.clone_uri:
10
10
11 ${_('Remote mirror url')}:
11 ${_('Remote mirror url')}:
12 <a href="${c.repo_info.clone_uri}">${c.repo_info.clone_uri_hidden}</a>
12 <a href="${c.repo_info.clone_uri}">${c.repo_info.clone_uri_hidden}</a>
13
13
14 <p>
14 <p>
15 ${_('Pull can be automated by such api call. Can be called periodically in crontab etc.')}
15 ${_('Pull can be automated by such api call. Can be called periodically in crontab etc.')}
16 <br/>
16 <br/>
17 <code>
17 <code>
18 ${h.api_call_example(method='pull', args={"repoid": c.repo_info.repo_name})}
18 ${h.api_call_example(method='pull', args={"repoid": c.repo_info.repo_name})}
19 </code>
19 </code>
20 </p>
20 </p>
21
21
22 ${h.secure_form(url('edit_repo_remote', repo_name=c.repo_name), method='put')}
22 ${h.secure_form(h.url('edit_repo_remote', repo_name=c.repo_name), method='put')}
23 <div class="form">
23 <div class="form">
24 <div class="fields">
24 <div class="fields">
25 ${h.submit('remote_pull_%s' % c.repo_info.repo_name,_('Pull changes from remote location'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to pull changes from remote side')+"');")}
25 ${h.submit('remote_pull_%s' % c.repo_info.repo_name,_('Pull changes from remote location'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to pull changes from remote side')+"');")}
26 </div>
26 </div>
27 </div>
27 </div>
28 ${h.end_form()}
28 ${h.end_form()}
29 %else:
29 %else:
30
30
31 ${_('This repository does not have any remote mirror url set.')}
31 ${_('This repository does not have any remote mirror url set.')}
32 <a href="${h.route_path('edit_repo', repo_name=c.repo_info.repo_name)}">${_('Set remote url.')}</a>
32 <a href="${h.route_path('edit_repo', repo_name=c.repo_info.repo_name)}">${_('Set remote url.')}</a>
33 <br/>
33 <br/>
34 <br/>
34 <br/>
35 <button class="btn disabled" type="submit" disabled="disabled">
35 <button class="btn disabled" type="submit" disabled="disabled">
36 ${_('Pull changes from remote location')}
36 ${_('Pull changes from remote location')}
37 </button>
37 </button>
38 %endif
38 %endif
39 </div>
39 </div>
40 </div>
40 </div>
@@ -1,22 +1,22 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Repository statistics')}</h3>
3 <h3 class="panel-title">${_('Repository statistics')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6 ${h.secure_form(url('edit_repo_statistics', repo_name=c.repo_info.repo_name), method='put')}
6 ${h.secure_form(h.url('edit_repo_statistics', repo_name=c.repo_info.repo_name), method='put')}
7 <div class="form">
7 <div class="form">
8 <div class="fields">
8 <div class="fields">
9 <div class="field" >
9 <div class="field" >
10 <dl class="dl-horizontal settings">
10 <dl class="dl-horizontal settings">
11 <dt>${_('Processed commits')}:</dt><dd>${c.stats_revision}/${c.repo_last_rev}</dd>
11 <dt>${_('Processed commits')}:</dt><dd>${c.stats_revision}/${c.repo_last_rev}</dd>
12 <dt>${_('Processed progress')}:</dt><dd>${c.stats_percentage}%</dd>
12 <dt>${_('Processed progress')}:</dt><dd>${c.stats_percentage}%</dd>
13 </dl>
13 </dl>
14 </div>
14 </div>
15 ${h.submit('reset_stats_%s' % c.repo_info.repo_name,_('Reset statistics'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to remove current statistics')+"');")}
15 ${h.submit('reset_stats_%s' % c.repo_info.repo_name,_('Reset statistics'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to remove current statistics')+"');")}
16 </div>
16 </div>
17 </div>
17 </div>
18 ${h.end_form()}
18 ${h.end_form()}
19 </div>
19 </div>
20 </div>
20 </div>
21
21
22
22
@@ -1,74 +1,74 b''
1 <%namespace name="vcss" file="/base/vcs_settings.mako"/>
1 <%namespace name="vcss" file="/base/vcs_settings.mako"/>
2
2
3 <div id="repo_vcs_settings" class="${'inherited' if c.inherit_global_settings else ''}">
3 <div id="repo_vcs_settings" class="${'inherited' if c.inherit_global_settings else ''}">
4 ${h.secure_form(url('repo_vcs_settings', repo_name=c.repo_info.repo_name), method='post')}
4 ${h.secure_form(h.url('repo_vcs_settings', repo_name=c.repo_info.repo_name), method='post')}
5 <div class="form panel panel-default">
5 <div class="form panel panel-default">
6 <div class="fields panel-body">
6 <div class="fields panel-body">
7 <div class="field">
7 <div class="field">
8 <div class="label label-checkbox">
8 <div class="label label-checkbox">
9 <label for="inherit_global_settings">${_('Inherit from global settings')}:</label>
9 <label for="inherit_global_settings">${_('Inherit from global settings')}:</label>
10 </div>
10 </div>
11 <div class="checkboxes">
11 <div class="checkboxes">
12 ${h.checkbox('inherit_global_settings',value=True)}
12 ${h.checkbox('inherit_global_settings',value=True)}
13 <span class="help-block">${h.literal(_('Select to inherit global vcs settings.'))}</span>
13 <span class="help-block">${h.literal(_('Select to inherit global vcs settings.'))}</span>
14 </div>
14 </div>
15 </div>
15 </div>
16 </div>
16 </div>
17 </div>
17 </div>
18
18
19 <div id="inherit_overlay_vcs_default">
19 <div id="inherit_overlay_vcs_default">
20 <div>
20 <div>
21 ${vcss.vcs_settings_fields(
21 ${vcss.vcs_settings_fields(
22 suffix='_inherited',
22 suffix='_inherited',
23 svn_tag_patterns=c.global_svn_tag_patterns,
23 svn_tag_patterns=c.global_svn_tag_patterns,
24 svn_branch_patterns=c.global_svn_branch_patterns,
24 svn_branch_patterns=c.global_svn_branch_patterns,
25 repo_type=c.repo_info.repo_type,
25 repo_type=c.repo_info.repo_type,
26 disabled='disabled'
26 disabled='disabled'
27 )}
27 )}
28 </div>
28 </div>
29 </div>
29 </div>
30
30
31 <div id="inherit_overlay_vcs_custom">
31 <div id="inherit_overlay_vcs_custom">
32 <div>
32 <div>
33 ${vcss.vcs_settings_fields(
33 ${vcss.vcs_settings_fields(
34 suffix='',
34 suffix='',
35 svn_tag_patterns=c.svn_tag_patterns,
35 svn_tag_patterns=c.svn_tag_patterns,
36 svn_branch_patterns=c.svn_branch_patterns,
36 svn_branch_patterns=c.svn_branch_patterns,
37 repo_type=c.repo_info.repo_type
37 repo_type=c.repo_info.repo_type
38 )}
38 )}
39 </div>
39 </div>
40 </div>
40 </div>
41
41
42 <div class="buttons">
42 <div class="buttons">
43 ${h.submit('save',_('Save settings'),class_="btn")}
43 ${h.submit('save',_('Save settings'),class_="btn")}
44 ${h.reset('reset',_('Reset'),class_="btn")}
44 ${h.reset('reset',_('Reset'),class_="btn")}
45 </div>
45 </div>
46
46
47 ${h.end_form()}
47 ${h.end_form()}
48 </div>
48 </div>
49
49
50 <script type="text/javascript">
50 <script type="text/javascript">
51
51
52 function ajaxDeletePattern(pattern_id, field_id) {
52 function ajaxDeletePattern(pattern_id, field_id) {
53 var sUrl = "${h.url('repo_vcs_settings', repo_name=c.repo_info.repo_name)}";
53 var sUrl = "${h.url('repo_vcs_settings', repo_name=c.repo_info.repo_name)}";
54 var callback = function (o) {
54 var callback = function (o) {
55 var elem = $("#"+field_id);
55 var elem = $("#"+field_id);
56 elem.remove();
56 elem.remove();
57 };
57 };
58 var postData = {
58 var postData = {
59 '_method': 'delete',
59 '_method': 'delete',
60 'delete_svn_pattern': pattern_id,
60 'delete_svn_pattern': pattern_id,
61 'csrf_token': CSRF_TOKEN
61 'csrf_token': CSRF_TOKEN
62 };
62 };
63 var request = $.post(sUrl, postData)
63 var request = $.post(sUrl, postData)
64 .done(callback)
64 .done(callback)
65 .fail(function (data, textStatus, errorThrown) {
65 .fail(function (data, textStatus, errorThrown) {
66 alert("Error while deleting hooks.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
66 alert("Error while deleting hooks.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
67 });
67 });
68 }
68 }
69
69
70 $('#inherit_global_settings').on('change', function(e){
70 $('#inherit_global_settings').on('change', function(e){
71 $('#repo_vcs_settings').toggleClass('inherited', this.checked);
71 $('#repo_vcs_settings').toggleClass('inherited', this.checked);
72 });
72 });
73
73
74 </script>
74 </script>
@@ -1,56 +1,56 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Email Configuration')}</h3>
3 <h3 class="panel-title">${_('Email Configuration')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6 <%
6 <%
7 elems = [
7 elems = [
8 (_('Email prefix'), c.rhodecode_ini.get('email_prefix'), ''),
8 (_('Email prefix'), c.rhodecode_ini.get('email_prefix'), ''),
9 (_('RhodeCode email from'), c.rhodecode_ini.get('app_email_from'), ''),
9 (_('RhodeCode email from'), c.rhodecode_ini.get('app_email_from'), ''),
10 (_('Error email from'), c.rhodecode_ini.get('error_email_from'), ''),
10 (_('Error email from'), c.rhodecode_ini.get('error_email_from'), ''),
11 (_('Error email recipients'), c.rhodecode_ini.get('email_to'), ''),
11 (_('Error email recipients'), c.rhodecode_ini.get('email_to'), ''),
12
12
13 (_('SMTP server'), c.rhodecode_ini.get('smtp_server'), ''),
13 (_('SMTP server'), c.rhodecode_ini.get('smtp_server'), ''),
14 (_('SMTP username'), c.rhodecode_ini.get('smtp_username'), ''),
14 (_('SMTP username'), c.rhodecode_ini.get('smtp_username'), ''),
15 (_('SMTP password'), '%s chars' % len(c.rhodecode_ini.get('smtp_password', '')), ''),
15 (_('SMTP password'), '%s chars' % len(c.rhodecode_ini.get('smtp_password', '')), ''),
16 (_('SMTP port'), c.rhodecode_ini.get('smtp_port'), ''),
16 (_('SMTP port'), c.rhodecode_ini.get('smtp_port'), ''),
17
17
18 (_('SMTP use TLS'), c.rhodecode_ini.get('smtp_use_tls'), ''),
18 (_('SMTP use TLS'), c.rhodecode_ini.get('smtp_use_tls'), ''),
19 (_('SMTP use SSL'), c.rhodecode_ini.get('smtp_use_ssl'), ''),
19 (_('SMTP use SSL'), c.rhodecode_ini.get('smtp_use_ssl'), ''),
20 (_('SMTP auth'), c.rhodecode_ini.get('smtp_auth'), ''),
20 (_('SMTP auth'), c.rhodecode_ini.get('smtp_auth'), ''),
21 ]
21 ]
22 %>
22 %>
23 <dl class="dl-horizontal settings">
23 <dl class="dl-horizontal settings">
24 %for dt, dd, tt in elems:
24 %for dt, dd, tt in elems:
25 <dt >${dt}:</dt>
25 <dt >${dt}:</dt>
26 <dd title="${h.tooltip(tt)}">${dd}</dd>
26 <dd title="${h.tooltip(tt)}">${dd}</dd>
27 %endfor
27 %endfor
28 </dl>
28 </dl>
29 </div>
29 </div>
30 </div>
30 </div>
31
31
32 <div class="panel panel-default">
32 <div class="panel panel-default">
33 <div class="panel-heading">
33 <div class="panel-heading">
34 <h3 class="panel-title">${_('Test Email')}</h3>
34 <h3 class="panel-title">${_('Test Email')}</h3>
35 </div>
35 </div>
36 <div class="panel-body">
36 <div class="panel-body">
37 ${h.secure_form(url('admin_settings_email'), method='post')}
37 ${h.secure_form(h.url('admin_settings_email'), method='post')}
38
38
39 <div class="field input">
39 <div class="field input">
40 ${h.text('test_email', size=60, placeholder=_('enter valid email'))}
40 ${h.text('test_email', size=60, placeholder=_('enter valid email'))}
41 </div>
41 </div>
42 <div class="field">
42 <div class="field">
43 <span class="help-block">
43 <span class="help-block">
44 ${_('Send an auto-generated email from this server to above email...')}
44 ${_('Send an auto-generated email from this server to above email...')}
45 </span>
45 </span>
46 </div>
46 </div>
47 <div class="buttons">
47 <div class="buttons">
48 ${h.submit('send',_('Send'),class_="btn")}
48 ${h.submit('send',_('Send'),class_="btn")}
49 </div>
49 </div>
50 ${h.end_form()}
50 ${h.end_form()}
51 </div>
51 </div>
52 </div>
52 </div>
53
53
54
54
55
55
56
56
@@ -1,295 +1,295 b''
1 ${h.secure_form(url('admin_settings_global'), method='post')}
1 ${h.secure_form(h.url('admin_settings_global'), method='post')}
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading" id="branding-options">
4 <div class="panel-heading" id="branding-options">
5 <h3 class="panel-title">${_('Branding')} <a class="permalink" href="#branding-options"> ¶</a></h3>
5 <h3 class="panel-title">${_('Branding')} <a class="permalink" href="#branding-options"> ¶</a></h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 <div class="label">
8 <div class="label">
9 <label for="rhodecode_title">${_('Title')}</label>
9 <label for="rhodecode_title">${_('Title')}</label>
10 </div>
10 </div>
11 <div class="field input">
11 <div class="field input">
12 ${h.text('rhodecode_title',size=60)}
12 ${h.text('rhodecode_title',size=60)}
13 </div>
13 </div>
14 <div class="field">
14 <div class="field">
15 <span class="help-block">
15 <span class="help-block">
16 ${_('Set a custom title for your RhodeCode instance (limited to 40 characters).')}
16 ${_('Set a custom title for your RhodeCode instance (limited to 40 characters).')}
17 </span>
17 </span>
18 </div>
18 </div>
19 <div class="label">
19 <div class="label">
20 <label for="rhodecode_realm">${_('HTTP[S] authentication realm')}</label>
20 <label for="rhodecode_realm">${_('HTTP[S] authentication realm')}</label>
21 </div>
21 </div>
22 <div class="field input">
22 <div class="field input">
23 ${h.text('rhodecode_realm',size=60)}
23 ${h.text('rhodecode_realm',size=60)}
24 </div>
24 </div>
25 <div class="field">
25 <div class="field">
26 <span class="help-block">
26 <span class="help-block">
27 ${_('Set a custom text that is shown as authentication message to clients trying to connect.')}
27 ${_('Set a custom text that is shown as authentication message to clients trying to connect.')}
28 </span>
28 </span>
29 </div>
29 </div>
30 </div>
30 </div>
31 </div>
31 </div>
32
32
33
33
34 <div class="panel panel-default">
34 <div class="panel panel-default">
35 <div class="panel-heading" id="personal-group-options">
35 <div class="panel-heading" id="personal-group-options">
36 <h3 class="panel-title">${_('Personal Repository Group')} <a class="permalink" href="#personal-group-options"> ¶</a></h3>
36 <h3 class="panel-title">${_('Personal Repository Group')} <a class="permalink" href="#personal-group-options"> ¶</a></h3>
37 </div>
37 </div>
38 <div class="panel-body">
38 <div class="panel-body">
39 <div class="checkbox">
39 <div class="checkbox">
40 ${h.checkbox('rhodecode_create_personal_repo_group','True')}
40 ${h.checkbox('rhodecode_create_personal_repo_group','True')}
41 <label for="rhodecode_create_personal_repo_group">${_('Create Personal Repository Group')}</label>
41 <label for="rhodecode_create_personal_repo_group">${_('Create Personal Repository Group')}</label>
42 </div>
42 </div>
43 <span class="help-block">
43 <span class="help-block">
44 ${_('Always create Personal Repository Groups for new users.')} <br/>
44 ${_('Always create Personal Repository Groups for new users.')} <br/>
45 ${_('When creating new users from add user form or API you can still turn this off via a checkbox or flag')}
45 ${_('When creating new users from add user form or API you can still turn this off via a checkbox or flag')}
46 </span>
46 </span>
47
47
48 <div class="label">
48 <div class="label">
49 <label for="rhodecode_personal_repo_group_pattern">${_('Personal Repo Group Pattern')}</label>
49 <label for="rhodecode_personal_repo_group_pattern">${_('Personal Repo Group Pattern')}</label>
50 </div>
50 </div>
51 <div class="field input">
51 <div class="field input">
52 ${h.text('rhodecode_personal_repo_group_pattern',size=60, placeholder=c.personal_repo_group_default_pattern)}
52 ${h.text('rhodecode_personal_repo_group_pattern',size=60, placeholder=c.personal_repo_group_default_pattern)}
53 </div>
53 </div>
54 <span class="help-block">
54 <span class="help-block">
55 ${_('Pattern used to create Personal Repository Groups. Prefix can be other existing repository group path[s], eg. /u/${username}')} <br/>
55 ${_('Pattern used to create Personal Repository Groups. Prefix can be other existing repository group path[s], eg. /u/${username}')} <br/>
56 ${_('Available variables are currently ${username} and ${user_id}')}
56 ${_('Available variables are currently ${username} and ${user_id}')}
57 </span>
57 </span>
58 </div>
58 </div>
59 </div>
59 </div>
60
60
61
61
62 <div class="panel panel-default">
62 <div class="panel panel-default">
63 <div class="panel-heading" id="captcha-options">
63 <div class="panel-heading" id="captcha-options">
64 <h3 class="panel-title">${_('Registration Captcha')} <a class="permalink" href="#captcha-options"> ¶</a></h3>
64 <h3 class="panel-title">${_('Registration Captcha')} <a class="permalink" href="#captcha-options"> ¶</a></h3>
65 </div>
65 </div>
66 <div class="panel-body">
66 <div class="panel-body">
67 <div class="label">
67 <div class="label">
68 <label for="rhodecode_captcha_public_key">${_('Google ReCaptcha public key')}</label>
68 <label for="rhodecode_captcha_public_key">${_('Google ReCaptcha public key')}</label>
69 </div>
69 </div>
70 <div class="field input">
70 <div class="field input">
71 ${h.text('rhodecode_captcha_public_key',size=60)}
71 ${h.text('rhodecode_captcha_public_key',size=60)}
72 </div>
72 </div>
73 <div class="field">
73 <div class="field">
74 <span class="help-block">
74 <span class="help-block">
75 ${_('Public key for reCaptcha system.')}
75 ${_('Public key for reCaptcha system.')}
76 </span>
76 </span>
77 </div>
77 </div>
78
78
79 <div class="label">
79 <div class="label">
80 <label for="rhodecode_captcha_private_key">${_('Google ReCaptcha private key')}</label>
80 <label for="rhodecode_captcha_private_key">${_('Google ReCaptcha private key')}</label>
81 </div>
81 </div>
82 <div class="field input">
82 <div class="field input">
83 ${h.text('rhodecode_captcha_private_key',size=60)}
83 ${h.text('rhodecode_captcha_private_key',size=60)}
84 </div>
84 </div>
85 <div class="field">
85 <div class="field">
86 <span class="help-block">
86 <span class="help-block">
87 ${_('Private key for reCaptcha system. Setting this value will enable captcha on registration')}
87 ${_('Private key for reCaptcha system. Setting this value will enable captcha on registration')}
88 </span>
88 </span>
89 </div>
89 </div>
90 </div>
90 </div>
91 </div>
91 </div>
92
92
93 <div class="panel panel-default">
93 <div class="panel panel-default">
94 <div class="panel-heading" id="header-code-options">
94 <div class="panel-heading" id="header-code-options">
95 <h3 class="panel-title">${_('Custom Header Code')} <a class="permalink" href="#header-code-options"> ¶</a></h3>
95 <h3 class="panel-title">${_('Custom Header Code')} <a class="permalink" href="#header-code-options"> ¶</a></h3>
96 </div>
96 </div>
97 <div class="panel-body">
97 <div class="panel-body">
98 <div class="select">
98 <div class="select">
99 <select id="pre_template" >
99 <select id="pre_template" >
100 <option value="#">${_('Templates...')}</option>
100 <option value="#">${_('Templates...')}</option>
101 <option value="ga">Google Analytics</option>
101 <option value="ga">Google Analytics</option>
102 <option value="clicky">Clicky</option>
102 <option value="clicky">Clicky</option>
103 <option value="server_announce">${_('Server Announcement')}</option>
103 <option value="server_announce">${_('Server Announcement')}</option>
104 <option value="flash_filtering">${_('Flash message filtering')}</option>
104 <option value="flash_filtering">${_('Flash message filtering')}</option>
105 </select>
105 </select>
106 </div>
106 </div>
107 <div style="padding: 10px 0px"></div>
107 <div style="padding: 10px 0px"></div>
108 <div class="textarea text-area">
108 <div class="textarea text-area">
109 ${h.textarea('rhodecode_pre_code',cols=23,rows=5,class_="medium")}
109 ${h.textarea('rhodecode_pre_code',cols=23,rows=5,class_="medium")}
110 <span class="help-block">${_('Custom js/css code added at the end of the <header/> tag.')}
110 <span class="help-block">${_('Custom js/css code added at the end of the <header/> tag.')}
111 ${_('Use <script/> or <css/> tags to define custom styling or scripting')}</span>
111 ${_('Use <script/> or <css/> tags to define custom styling or scripting')}</span>
112 </div>
112 </div>
113 </div>
113 </div>
114 </div>
114 </div>
115
115
116 <div class="panel panel-default">
116 <div class="panel panel-default">
117 <div class="panel-heading" id="footer-code-options">
117 <div class="panel-heading" id="footer-code-options">
118 <h3 class="panel-title">${_('Custom Footer Code')} <a class="permalink" href="#footer-code-options"> ¶</a></h3>
118 <h3 class="panel-title">${_('Custom Footer Code')} <a class="permalink" href="#footer-code-options"> ¶</a></h3>
119 </div>
119 </div>
120 <div class="panel-body">
120 <div class="panel-body">
121 <div class="select">
121 <div class="select">
122 <select id="post_template" >
122 <select id="post_template" >
123 <option value="#">${_('Templates...')}</option>
123 <option value="#">${_('Templates...')}</option>
124 <option value="ga">Google Analytics</option>
124 <option value="ga">Google Analytics</option>
125 <option value="clicky">Clicky</option>
125 <option value="clicky">Clicky</option>
126 <option value="server_announce">${_('Server Announcement')}</option>
126 <option value="server_announce">${_('Server Announcement')}</option>
127 </select>
127 </select>
128 </div>
128 </div>
129 <div style="padding: 10px 0px"></div>
129 <div style="padding: 10px 0px"></div>
130 <div class="textarea text-area">
130 <div class="textarea text-area">
131 ${h.textarea('rhodecode_post_code',cols=23,rows=5, class_="medium")}
131 ${h.textarea('rhodecode_post_code',cols=23,rows=5, class_="medium")}
132 <span class="help-block">${_('Custom js/css code added at the end of the <body> tag.')}
132 <span class="help-block">${_('Custom js/css code added at the end of the <body> tag.')}
133 ${_('Use <script> or <css> tags to define custom styling or scripting')}</span>
133 ${_('Use <script> or <css> tags to define custom styling or scripting')}</span>
134 </div>
134 </div>
135 </div>
135 </div>
136 </div>
136 </div>
137
137
138 <div class="buttons">
138 <div class="buttons">
139 ${h.submit('save',_('Save settings'),class_="btn")}
139 ${h.submit('save',_('Save settings'),class_="btn")}
140 ${h.reset('reset',_('Reset'),class_="btn")}
140 ${h.reset('reset',_('Reset'),class_="btn")}
141 </div>
141 </div>
142 ${h.end_form()}
142 ${h.end_form()}
143
143
144
144
145
145
146 ## TEMPLATES ##
146 ## TEMPLATES ##
147 ###############
147 ###############
148
148
149 <script id="ga_tmpl" type="text/x-template">
149 <script id="ga_tmpl" type="text/x-template">
150 <%text filter="h">
150 <%text filter="h">
151 <script>
151 <script>
152 // Google Analytics
152 // Google Analytics
153 // Put your Google Analytics code instead of _GACODE_
153 // Put your Google Analytics code instead of _GACODE_
154 var _gaq_code = '_GACODE_';
154 var _gaq_code = '_GACODE_';
155 var _gaq = _gaq || [];
155 var _gaq = _gaq || [];
156 _gaq.push(['_setAccount', _gaq_code]);
156 _gaq.push(['_setAccount', _gaq_code]);
157 _gaq.push(['_trackPageview']);
157 _gaq.push(['_trackPageview']);
158
158
159 (function() {
159 (function() {
160 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
160 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
161 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
161 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
162 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
162 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
163 })();
163 })();
164
164
165 rhodecode_statechange_callback = function(url, data){
165 rhodecode_statechange_callback = function(url, data){
166 // ANALYTICS callback on html5 history state changed
166 // ANALYTICS callback on html5 history state changed
167 // triggered by file browser, url is the new url,
167 // triggered by file browser, url is the new url,
168 // data is extra info passed from the State object
168 // data is extra info passed from the State object
169 if (typeof window._gaq !== 'undefined') {
169 if (typeof window._gaq !== 'undefined') {
170 _gaq.push(['_trackPageview', url]);
170 _gaq.push(['_trackPageview', url]);
171 }
171 }
172 };
172 };
173 </script>
173 </script>
174 </%text>
174 </%text>
175 </script>
175 </script>
176
176
177
177
178
178
179 <script id="clicky_tmpl" type="text/x-template">
179 <script id="clicky_tmpl" type="text/x-template">
180 <%text filter="h">
180 <%text filter="h">
181 <script src="//static.getclicky.com/js" type="text/javascript"></script>
181 <script src="//static.getclicky.com/js" type="text/javascript"></script>
182 <script type="text/javascript">
182 <script type="text/javascript">
183 // Clicky Analytics - should be used in the footer code section.
183 // Clicky Analytics - should be used in the footer code section.
184 // Put your Clicky code instead of _CLICKYCODE_ here,
184 // Put your Clicky code instead of _CLICKYCODE_ here,
185 // and below in the <img> tag.
185 // and below in the <img> tag.
186 var _cl_code = _CLICKYCODE_;
186 var _cl_code = _CLICKYCODE_;
187 try{clicky.init(_cl_code);}catch(e){}
187 try{clicky.init(_cl_code);}catch(e){}
188
188
189 rhodecode_statechange_callback = function(url, data){
189 rhodecode_statechange_callback = function(url, data){
190 // ANALYTICS callback on html5 history state changed
190 // ANALYTICS callback on html5 history state changed
191 // triggered by file browser, url is the new url,
191 // triggered by file browser, url is the new url,
192 // data is extra info passed from the State object
192 // data is extra info passed from the State object
193 if (typeof window.clicky !== 'undefined') {
193 if (typeof window.clicky !== 'undefined') {
194 clicky.log(url);
194 clicky.log(url);
195 }
195 }
196 }
196 }
197 </script>
197 </script>
198 <noscript>
198 <noscript>
199 // Put your clicky code in the src file.
199 // Put your clicky code in the src file.
200 <p><img alt="Clicky" width="1" height="1"
200 <p><img alt="Clicky" width="1" height="1"
201 src="//in.getclicky.com/_CLICKYCODE_ns.gif" /></p>
201 src="//in.getclicky.com/_CLICKYCODE_ns.gif" /></p>
202 </noscript>
202 </noscript>
203 </%text>
203 </%text>
204 </script>
204 </script>
205
205
206
206
207
207
208 <script id="server_announce_tmpl" type='text/x-template'>
208 <script id="server_announce_tmpl" type='text/x-template'>
209 <%text filter="h">
209 <%text filter="h">
210 <script>
210 <script>
211 // Server announcement displayed on the top of the page.
211 // Server announcement displayed on the top of the page.
212 // This can be used to send a global maintenance messages or other
212 // This can be used to send a global maintenance messages or other
213 // important messages to all users of the RhodeCode Enterprise system.
213 // important messages to all users of the RhodeCode Enterprise system.
214
214
215 $(document).ready(function(e){
215 $(document).ready(function(e){
216
216
217 // EDIT - put your message below
217 // EDIT - put your message below
218 var message = "TYPE YOUR MESSAGE HERE";
218 var message = "TYPE YOUR MESSAGE HERE";
219
219
220 // EDIT - choose "info"/"warning"/"error"/"success"/"neutral" as appropriate
220 // EDIT - choose "info"/"warning"/"error"/"success"/"neutral" as appropriate
221 var alert_level = "info";
221 var alert_level = "info";
222
222
223 $("#body").prepend(
223 $("#body").prepend(
224 ("<div id='server-announcement' class='"+alert_level+"'>_MSG_"+"</div>").replace("_MSG_", message)
224 ("<div id='server-announcement' class='"+alert_level+"'>_MSG_"+"</div>").replace("_MSG_", message)
225 )
225 )
226 })
226 })
227 </script>
227 </script>
228 </%text>
228 </%text>
229 </script>
229 </script>
230
230
231 <script id="flash_filtering_tmpl" type='text/x-template'>
231 <script id="flash_filtering_tmpl" type='text/x-template'>
232 <%text filter="h">
232 <%text filter="h">
233 <script>
233 <script>
234 // This filters out some flash messages before they are presented to user
234 // This filters out some flash messages before they are presented to user
235 // based on their contents. Could be used to filter out warnings/errors
235 // based on their contents. Could be used to filter out warnings/errors
236 // of license messages
236 // of license messages
237
237
238 var filteredMessages = [];
238 var filteredMessages = [];
239 for(var i =0; i< alertMessagePayloads.length; i++){
239 for(var i =0; i< alertMessagePayloads.length; i++){
240 if (typeof alertMessagePayloads[i].message.subdata.subtype !== 'undefined' &&
240 if (typeof alertMessagePayloads[i].message.subdata.subtype !== 'undefined' &&
241 alertMessagePayloads[i].message.subdata.subtype.indexOf('rc_license') !== -1){
241 alertMessagePayloads[i].message.subdata.subtype.indexOf('rc_license') !== -1){
242 continue
242 continue
243 }
243 }
244 filteredMessages.push(alertMessagePayloads[i]);
244 filteredMessages.push(alertMessagePayloads[i]);
245 }
245 }
246 alertMessagePayloads = filteredMessages;
246 alertMessagePayloads = filteredMessages;
247 </script>
247 </script>
248 </%text>
248 </%text>
249 </script>
249 </script>
250
250
251 <script>
251 <script>
252 var pre_cm = initCodeMirror('rhodecode_pre_code', '', false);
252 var pre_cm = initCodeMirror('rhodecode_pre_code', '', false);
253 var pre_old = pre_cm.getValue();
253 var pre_old = pre_cm.getValue();
254
254
255 var post_cm = initCodeMirror('rhodecode_post_code', '', false);
255 var post_cm = initCodeMirror('rhodecode_post_code', '', false);
256 var post_old = post_cm.getValue();
256 var post_old = post_cm.getValue();
257
257
258 var get_data = function(type, old){
258 var get_data = function(type, old){
259 var get_tmpl = function(tmpl_name){
259 var get_tmpl = function(tmpl_name){
260 // unescape some stuff
260 // unescape some stuff
261 return htmlEnDeCode.htmlDecode($('#'+tmpl_name+'_tmpl').html());
261 return htmlEnDeCode.htmlDecode($('#'+tmpl_name+'_tmpl').html());
262 };
262 };
263 return {
263 return {
264 '#': old,
264 '#': old,
265 'ga': get_tmpl('ga'),
265 'ga': get_tmpl('ga'),
266 'clicky': get_tmpl('clicky'),
266 'clicky': get_tmpl('clicky'),
267 'server_announce': get_tmpl('server_announce'),
267 'server_announce': get_tmpl('server_announce'),
268 'flash_filtering': get_tmpl('flash_filtering')
268 'flash_filtering': get_tmpl('flash_filtering')
269 }[type]
269 }[type]
270 };
270 };
271
271
272 $('#pre_template').select2({
272 $('#pre_template').select2({
273 containerCssClass: 'drop-menu',
273 containerCssClass: 'drop-menu',
274 dropdownCssClass: 'drop-menu-dropdown',
274 dropdownCssClass: 'drop-menu-dropdown',
275 dropdownAutoWidth: true,
275 dropdownAutoWidth: true,
276 minimumResultsForSearch: -1
276 minimumResultsForSearch: -1
277 });
277 });
278
278
279 $('#post_template').select2({
279 $('#post_template').select2({
280 containerCssClass: 'drop-menu',
280 containerCssClass: 'drop-menu',
281 dropdownCssClass: 'drop-menu-dropdown',
281 dropdownCssClass: 'drop-menu-dropdown',
282 dropdownAutoWidth: true,
282 dropdownAutoWidth: true,
283 minimumResultsForSearch: -1
283 minimumResultsForSearch: -1
284 });
284 });
285
285
286 $('#post_template').on('change', function(e){
286 $('#post_template').on('change', function(e){
287 var sel = this.value;
287 var sel = this.value;
288 post_cm.setValue(get_data(sel, post_old))
288 post_cm.setValue(get_data(sel, post_old))
289 });
289 });
290
290
291 $('#pre_template').on('change', function(e){
291 $('#pre_template').on('change', function(e){
292 var sel = this.value;
292 var sel = this.value;
293 pre_cm.setValue(get_data(sel, pre_old))
293 pre_cm.setValue(get_data(sel, pre_old))
294 })
294 })
295 </script>
295 </script>
@@ -1,93 +1,93 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Built in Mercurial hooks - read only')}</h3>
3 <h3 class="panel-title">${_('Built in Mercurial hooks - read only')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6 <div class="form">
6 <div class="form">
7 <div class="fields">
7 <div class="fields">
8 % for hook in c.hooks:
8 % for hook in c.hooks:
9 <div class="field">
9 <div class="field">
10 <div class="label label">
10 <div class="label label">
11 <label for="${hook.ui_key}">${hook.ui_key}</label>
11 <label for="${hook.ui_key}">${hook.ui_key}</label>
12 </div>
12 </div>
13 <div class="input" >
13 <div class="input" >
14 ${h.text(hook.ui_key,hook.ui_value,size=59,readonly="readonly")}
14 ${h.text(hook.ui_key,hook.ui_value,size=59,readonly="readonly")}
15 </div>
15 </div>
16 </div>
16 </div>
17 % endfor
17 % endfor
18 </div>
18 </div>
19 <span class="help-block">${_('Hooks can be used to trigger actions on certain events such as push / pull. They can trigger Python functions or external applications.')}</span>
19 <span class="help-block">${_('Hooks can be used to trigger actions on certain events such as push / pull. They can trigger Python functions or external applications.')}</span>
20 </div>
20 </div>
21 </div>
21 </div>
22 </div>
22 </div>
23
23
24
24
25 <div class="panel panel-default">
25 <div class="panel panel-default">
26 <div class="panel-heading">
26 <div class="panel-heading">
27 <h3 class="panel-title">${_('Custom hooks')}</h3>
27 <h3 class="panel-title">${_('Custom hooks')}</h3>
28 </div>
28 </div>
29 <div class="panel-body">
29 <div class="panel-body">
30 % if c.visual.allow_custom_hooks_settings:
30 % if c.visual.allow_custom_hooks_settings:
31 ${h.secure_form(url('admin_settings_hooks'), method='post')}
31 ${h.secure_form(h.url('admin_settings_hooks'), method='post')}
32 <div class="form">
32 <div class="form">
33 <div class="fields">
33 <div class="fields">
34
34
35 % for hook in c.custom_hooks:
35 % for hook in c.custom_hooks:
36 <div class="field" id="${'id%s' % hook.ui_id }">
36 <div class="field" id="${'id%s' % hook.ui_id }">
37 <div class="label label">
37 <div class="label label">
38 <label for="${hook.ui_key}">${hook.ui_key}</label>
38 <label for="${hook.ui_key}">${hook.ui_key}</label>
39 </div>
39 </div>
40 <div class="input" >
40 <div class="input" >
41 ${h.hidden('hook_ui_key',hook.ui_key)}
41 ${h.hidden('hook_ui_key',hook.ui_key)}
42 ${h.hidden('hook_ui_value',hook.ui_value)}
42 ${h.hidden('hook_ui_value',hook.ui_value)}
43 ${h.text('hook_ui_value_new',hook.ui_value,size=59)}
43 ${h.text('hook_ui_value_new',hook.ui_value,size=59)}
44 <span class="btn btn-danger"
44 <span class="btn btn-danger"
45 onclick="ajaxActionHook(${hook.ui_id},'${'id%s' % hook.ui_id }')">
45 onclick="ajaxActionHook(${hook.ui_id},'${'id%s' % hook.ui_id }')">
46 ${_('Delete')}
46 ${_('Delete')}
47 </span>
47 </span>
48 </div>
48 </div>
49 </div>
49 </div>
50 % endfor
50 % endfor
51
51
52 <div class="field customhooks">
52 <div class="field customhooks">
53 <div class="label">
53 <div class="label">
54 <div class="input-wrapper">
54 <div class="input-wrapper">
55 ${h.text('new_hook_ui_key',size=30)}
55 ${h.text('new_hook_ui_key',size=30)}
56 </div>
56 </div>
57 </div>
57 </div>
58 <div class="input">
58 <div class="input">
59 ${h.text('new_hook_ui_value',size=59)}
59 ${h.text('new_hook_ui_value',size=59)}
60 </div>
60 </div>
61 </div>
61 </div>
62 <div class="buttons">
62 <div class="buttons">
63 ${h.submit('save',_('Save'),class_="btn")}
63 ${h.submit('save',_('Save'),class_="btn")}
64 </div>
64 </div>
65 </div>
65 </div>
66 </div>
66 </div>
67 ${h.end_form()}
67 ${h.end_form()}
68 %else:
68 %else:
69 DISABLED
69 DISABLED
70 % endif
70 % endif
71 </div>
71 </div>
72 </div>
72 </div>
73
73
74
74
75 <script type="text/javascript">
75 <script type="text/javascript">
76 function ajaxActionHook(hook_id,field_id) {
76 function ajaxActionHook(hook_id,field_id) {
77 var sUrl = "${h.url('admin_settings_hooks')}";
77 var sUrl = "${h.url('admin_settings_hooks')}";
78 var callback = function (o) {
78 var callback = function (o) {
79 var elem = $("#"+field_id);
79 var elem = $("#"+field_id);
80 elem.remove();
80 elem.remove();
81 };
81 };
82 var postData = {
82 var postData = {
83 '_method': 'delete',
83 '_method': 'delete',
84 'hook_id': hook_id,
84 'hook_id': hook_id,
85 'csrf_token': CSRF_TOKEN
85 'csrf_token': CSRF_TOKEN
86 };
86 };
87 var request = $.post(sUrl, postData)
87 var request = $.post(sUrl, postData)
88 .done(callback)
88 .done(callback)
89 .fail(function (data, textStatus, errorThrown) {
89 .fail(function (data, textStatus, errorThrown) {
90 alert("Error while deleting hooks.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
90 alert("Error while deleting hooks.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
91 });
91 });
92 };
92 };
93 </script>
93 </script>
@@ -1,34 +1,34 b''
1 <%namespace name="its" file="/base/issue_tracker_settings.mako"/>
1 <%namespace name="its" file="/base/issue_tracker_settings.mako"/>
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('Issue Tracker / Wiki Patterns')}</h3>
5 <h3 class="panel-title">${_('Issue Tracker / Wiki Patterns')}</h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 ${h.secure_form(url('admin_settings_issuetracker_save'), method='post')}
8 ${h.secure_form(h.url('admin_settings_issuetracker_save'), method='post')}
9 ${its.issue_tracker_settings_table(
9 ${its.issue_tracker_settings_table(
10 patterns=c.issuetracker_entries.items(),
10 patterns=c.issuetracker_entries.items(),
11 form_url=url('admin_settings_issuetracker'),
11 form_url=h.url('admin_settings_issuetracker'),
12 delete_url=url('admin_issuetracker_delete')
12 delete_url=h.url('admin_issuetracker_delete')
13 )}
13 )}
14 <div class="buttons">
14 <div class="buttons">
15 <button type="submit" class="btn btn-primary" id="save">${_('Save')}</button>
15 <button type="submit" class="btn btn-primary" id="save">${_('Save')}</button>
16 <button type="reset" class="btn">${_('Reset')}</button>
16 <button type="reset" class="btn">${_('Reset')}</button>
17 </div>
17 </div>
18 ${h.end_form()}
18 ${h.end_form()}
19 </div>
19 </div>
20 </div>
20 </div>
21
21
22 <div class="panel panel-default">
22 <div class="panel panel-default">
23 <div class="panel-heading">
23 <div class="panel-heading">
24 <h3 class="panel-title">${_('Test Patterns')}</h3>
24 <h3 class="panel-title">${_('Test Patterns')}</h3>
25 </div>
25 </div>
26 <div class="panel-body">
26 <div class="panel-body">
27 ${its.issue_tracker_new_row()}
27 ${its.issue_tracker_new_row()}
28 ${its.issue_tracker_settings_test(test_url=url('admin_issuetracker_test'))}
28 ${its.issue_tracker_settings_test(test_url=h.url('admin_issuetracker_test'))}
29 </div>
29 </div>
30 </div>
30 </div>
31
31
32
32
33
33
34
34
@@ -1,58 +1,58 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Labs Settings')}</h3>
3 <h3 class="panel-title">${_('Labs Settings')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6 ${h.secure_form(url('admin_settings_labs'), method='post')}
6 ${h.secure_form(h.url('admin_settings_labs'), method='post')}
7 <div class="form">
7 <div class="form">
8 <div class="fields">
8 <div class="fields">
9 % if not c.lab_settings:
9 % if not c.lab_settings:
10 ${_('There are no Labs settings currently')}
10 ${_('There are no Labs settings currently')}
11 % else:
11 % else:
12 % for lab_setting in c.lab_settings:
12 % for lab_setting in c.lab_settings:
13 <div class="field">
13 <div class="field">
14 <div class="label">
14 <div class="label">
15 <label>${lab_setting.group}:</label>
15 <label>${lab_setting.group}:</label>
16 </div>
16 </div>
17 % if lab_setting.type == 'bool':
17 % if lab_setting.type == 'bool':
18 <div class="checkboxes">
18 <div class="checkboxes">
19 <div class="checkbox">
19 <div class="checkbox">
20 ${h.checkbox(lab_setting.key, 'True')}
20 ${h.checkbox(lab_setting.key, 'True')}
21 % if lab_setting.label:
21 % if lab_setting.label:
22 <label for="${lab_setting.key}">${lab_setting.label}</label>
22 <label for="${lab_setting.key}">${lab_setting.label}</label>
23 % endif
23 % endif
24 </div>
24 </div>
25 % if lab_setting.help:
25 % if lab_setting.help:
26 <p class="help-block">${lab_setting.help}</p>
26 <p class="help-block">${lab_setting.help}</p>
27 % endif
27 % endif
28 </div>
28 </div>
29 % else:
29 % else:
30 <div class="input">
30 <div class="input">
31 ${h.text(lab_setting.key, size=60)}
31 ${h.text(lab_setting.key, size=60)}
32
32
33 ## TODO: johbo: This style does not yet exist for our forms,
33 ## TODO: johbo: This style does not yet exist for our forms,
34 ## the lab settings seem not to adhere to the structure which
34 ## the lab settings seem not to adhere to the structure which
35 ## we use in other places.
35 ## we use in other places.
36 % if lab_setting.label:
36 % if lab_setting.label:
37 <label for="${lab_setting.key}">${lab_setting.label}</label>
37 <label for="${lab_setting.key}">${lab_setting.label}</label>
38 % endif
38 % endif
39
39
40 % if lab_setting.help:
40 % if lab_setting.help:
41 <p class="help-block">${lab_setting.help}</p>
41 <p class="help-block">${lab_setting.help}</p>
42 % endif
42 % endif
43 </div>
43 </div>
44 % endif
44 % endif
45 </div>
45 </div>
46 % endfor
46 % endfor
47 <div class="buttons">
47 <div class="buttons">
48 ${h.submit('save', _('Save settings'), class_='btn')}
48 ${h.submit('save', _('Save settings'), class_='btn')}
49 ${h.reset('reset', _('Reset'), class_='btn')}
49 ${h.reset('reset', _('Reset'), class_='btn')}
50 </div>
50 </div>
51 % endif
51 % endif
52 </div>
52 </div>
53 </div>
53 </div>
54 ${h.end_form()}
54 ${h.end_form()}
55 </div>
55 </div>
56 </div>
56 </div>
57
57
58
58
@@ -1,28 +1,28 b''
1 ${h.secure_form(url('admin_settings_mapping'), method='post')}
1 ${h.secure_form(h.url('admin_settings_mapping'), method='post')}
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('Import New Groups or Repositories')}</h3>
5 <h3 class="panel-title">${_('Import New Groups or Repositories')}</h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 <div class="checkbox">
8 <div class="checkbox">
9 ${h.checkbox('destroy',True)}
9 ${h.checkbox('destroy',True)}
10 <label for="destroy">${_('Destroy old data')}</label>
10 <label for="destroy">${_('Destroy old data')}</label>
11 </div>
11 </div>
12 <span class="help-block">${_('In case a repository or a group was deleted from the filesystem and it still exists in the database, check this option to remove obsolete data from the database.')}</span>
12 <span class="help-block">${_('In case a repository or a group was deleted from the filesystem and it still exists in the database, check this option to remove obsolete data from the database.')}</span>
13
13
14 <div class="checkbox">
14 <div class="checkbox">
15 ${h.checkbox('invalidate',True)}
15 ${h.checkbox('invalidate',True)}
16 <label for="invalidate"> ${_('Invalidate cache for all repositories')}</label>
16 <label for="invalidate"> ${_('Invalidate cache for all repositories')}</label>
17 </div>
17 </div>
18 <span class="help-block">${_('Each cache data for repositories will be cleaned with this option selected. Use this to reload data and clear cache keys.')}</span>
18 <span class="help-block">${_('Each cache data for repositories will be cleaned with this option selected. Use this to reload data and clear cache keys.')}</span>
19
19
20 <div class="buttons">
20 <div class="buttons">
21 ${h.submit('rescan',_('Rescan Filesystem'),class_="btn")}
21 ${h.submit('rescan',_('Rescan Filesystem'),class_="btn")}
22 </div>
22 </div>
23
23
24 </div>
24 </div>
25 </div>
25 </div>
26
26
27
27
28 ${h.end_form()}
28 ${h.end_form()}
@@ -1,66 +1,66 b''
1 <%namespace name="vcss" file="/base/vcs_settings.mako"/>
1 <%namespace name="vcss" file="/base/vcs_settings.mako"/>
2
2
3 ${h.secure_form(url('admin_settings_vcs'), method='post')}
3 ${h.secure_form(h.url('admin_settings_vcs'), method='post')}
4 <div>
4 <div>
5 ${vcss.vcs_settings_fields(
5 ${vcss.vcs_settings_fields(
6 suffix='',
6 suffix='',
7 svn_tag_patterns=c.svn_tag_patterns,
7 svn_tag_patterns=c.svn_tag_patterns,
8 svn_branch_patterns=c.svn_branch_patterns,
8 svn_branch_patterns=c.svn_branch_patterns,
9 display_globals=True,
9 display_globals=True,
10 allow_repo_location_change=c.visual.allow_repo_location_change
10 allow_repo_location_change=c.visual.allow_repo_location_change
11 )}
11 )}
12 <div class="buttons">
12 <div class="buttons">
13 ${h.submit('save',_('Save settings'),class_="btn")}
13 ${h.submit('save',_('Save settings'),class_="btn")}
14 ${h.reset('reset',_('Reset'),class_="btn")}
14 ${h.reset('reset',_('Reset'),class_="btn")}
15 </div>
15 </div>
16 </div>
16 </div>
17 ${h.end_form()}
17 ${h.end_form()}
18
18
19 <script type="text/javascript">
19 <script type="text/javascript">
20
20
21 function ajaxDeletePattern(pattern_id, field_id) {
21 function ajaxDeletePattern(pattern_id, field_id) {
22 var sUrl = "${h.url('admin_settings_vcs')}";
22 var sUrl = "${h.url('admin_settings_vcs')}";
23 var callback = function (o) {
23 var callback = function (o) {
24 var elem = $("#"+field_id);
24 var elem = $("#"+field_id);
25 elem.remove();
25 elem.remove();
26 };
26 };
27 var postData = {
27 var postData = {
28 '_method': 'delete',
28 '_method': 'delete',
29 'delete_svn_pattern': pattern_id,
29 'delete_svn_pattern': pattern_id,
30 'csrf_token': CSRF_TOKEN
30 'csrf_token': CSRF_TOKEN
31 };
31 };
32 var request = $.post(sUrl, postData)
32 var request = $.post(sUrl, postData)
33 .done(callback)
33 .done(callback)
34 .fail(function (data, textStatus, errorThrown) {
34 .fail(function (data, textStatus, errorThrown) {
35 alert("Error while deleting hooks.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
35 alert("Error while deleting hooks.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(this)[0].url));
36 });
36 });
37 };
37 };
38
38
39 $(document).ready(function() {
39 $(document).ready(function() {
40
40
41 var unlockpath = function() {
41 var unlockpath = function() {
42 $('#path_unlock_icon').removeClass('icon-lock').addClass('icon-unlock');
42 $('#path_unlock_icon').removeClass('icon-lock').addClass('icon-unlock');
43 $('#paths_root_path').removeAttr('readonly').removeClass('disabled');
43 $('#paths_root_path').removeAttr('readonly').removeClass('disabled');
44 };
44 };
45
45
46 $('#path_unlock').on('click', function(e) {
46 $('#path_unlock').on('click', function(e) {
47 unlockpath();
47 unlockpath();
48 });
48 });
49
49
50 if ($('.locked_input').children().hasClass('error-message')) {
50 if ($('.locked_input').children().hasClass('error-message')) {
51 unlockpath();
51 unlockpath();
52 }
52 }
53
53
54 /* On click handler for the `Generate Apache Config` button. It sends a
54 /* On click handler for the `Generate Apache Config` button. It sends a
55 POST request to trigger the (re)generation of the mod_dav_svn config. */
55 POST request to trigger the (re)generation of the mod_dav_svn config. */
56 $('#vcs_svn_generate_cfg').on('click', function(event) {
56 $('#vcs_svn_generate_cfg').on('click', function(event) {
57 event.preventDefault();
57 event.preventDefault();
58 var url = "${h.route_path('admin_settings_vcs_svn_generate_cfg')}";
58 var url = "${h.route_path('admin_settings_vcs_svn_generate_cfg')}";
59 var jqxhr = $.post(url, {'csrf_token': CSRF_TOKEN});
59 var jqxhr = $.post(url, {'csrf_token': CSRF_TOKEN});
60 jqxhr.done(function(data) {
60 jqxhr.done(function(data) {
61 $.Topic('/notifications').publish(data);
61 $.Topic('/notifications').publish(data);
62 });
62 });
63 });
63 });
64
64
65 });
65 });
66 </script>
66 </script>
@@ -1,237 +1,237 b''
1 ${h.secure_form(url('admin_settings_visual'), method='post')}
1 ${h.secure_form(h.url('admin_settings_visual'), method='post')}
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading" id="general">
4 <div class="panel-heading" id="general">
5 <h3 class="panel-title">${_('General')}</h3>
5 <h3 class="panel-title">${_('General')}</h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 <div class="checkbox">
8 <div class="checkbox">
9 ${h.checkbox('rhodecode_repository_fields','True')}
9 ${h.checkbox('rhodecode_repository_fields','True')}
10 <label for="rhodecode_repository_fields">${_('Use repository extra fields')}</label>
10 <label for="rhodecode_repository_fields">${_('Use repository extra fields')}</label>
11 </div>
11 </div>
12 <span class="help-block">${_('Allows storing additional customized fields per repository.')}</span>
12 <span class="help-block">${_('Allows storing additional customized fields per repository.')}</span>
13
13
14 <div></div>
14 <div></div>
15 <div class="checkbox">
15 <div class="checkbox">
16 ${h.checkbox('rhodecode_show_version','True')}
16 ${h.checkbox('rhodecode_show_version','True')}
17 <label for="rhodecode_show_version">${_('Show RhodeCode version')}</label>
17 <label for="rhodecode_show_version">${_('Show RhodeCode version')}</label>
18 </div>
18 </div>
19 <span class="help-block">${_('Shows or hides a version number of RhodeCode displayed in the footer.')}</span>
19 <span class="help-block">${_('Shows or hides a version number of RhodeCode displayed in the footer.')}</span>
20 </div>
20 </div>
21 </div>
21 </div>
22
22
23
23
24 <div class="panel panel-default">
24 <div class="panel panel-default">
25 <div class="panel-heading" id="gravatars">
25 <div class="panel-heading" id="gravatars">
26 <h3 class="panel-title">${_('Gravatars')}</h3>
26 <h3 class="panel-title">${_('Gravatars')}</h3>
27 </div>
27 </div>
28 <div class="panel-body">
28 <div class="panel-body">
29 <div class="checkbox">
29 <div class="checkbox">
30 ${h.checkbox('rhodecode_use_gravatar','True')}
30 ${h.checkbox('rhodecode_use_gravatar','True')}
31 <label for="rhodecode_use_gravatar">${_('Use Gravatars based avatars')}</label>
31 <label for="rhodecode_use_gravatar">${_('Use Gravatars based avatars')}</label>
32 </div>
32 </div>
33 <span class="help-block">${_('Use gravatar.com as avatar system for RhodeCode accounts. If this is disabled avatars are generated based on initials and email.')}</span>
33 <span class="help-block">${_('Use gravatar.com as avatar system for RhodeCode accounts. If this is disabled avatars are generated based on initials and email.')}</span>
34
34
35 <div class="label">
35 <div class="label">
36 <label for="rhodecode_gravatar_url">${_('Gravatar URL')}</label>
36 <label for="rhodecode_gravatar_url">${_('Gravatar URL')}</label>
37 </div>
37 </div>
38 <div class="input">
38 <div class="input">
39 <div class="field">
39 <div class="field">
40 ${h.text('rhodecode_gravatar_url', size='100%')}
40 ${h.text('rhodecode_gravatar_url', size='100%')}
41 </div>
41 </div>
42
42
43 <div class="field">
43 <div class="field">
44 <span class="help-block">${_('''Gravatar url allows you to use other avatar server application.
44 <span class="help-block">${_('''Gravatar url allows you to use other avatar server application.
45 Following variables of the URL will be replaced accordingly.
45 Following variables of the URL will be replaced accordingly.
46 {scheme} 'http' or 'https' sent from running RhodeCode server,
46 {scheme} 'http' or 'https' sent from running RhodeCode server,
47 {email} user email,
47 {email} user email,
48 {md5email} md5 hash of the user email (like at gravatar.com),
48 {md5email} md5 hash of the user email (like at gravatar.com),
49 {size} size of the image that is expected from the server application,
49 {size} size of the image that is expected from the server application,
50 {netloc} network location/server host of running RhodeCode server''')}</span>
50 {netloc} network location/server host of running RhodeCode server''')}</span>
51 </div>
51 </div>
52 </div>
52 </div>
53 </div>
53 </div>
54 </div>
54 </div>
55
55
56
56
57 <div class="panel panel-default">
57 <div class="panel panel-default">
58 <div class="panel-heading" id="meta-tagging">
58 <div class="panel-heading" id="meta-tagging">
59 <h3 class="panel-title">${_('Meta-Tagging')}</h3>
59 <h3 class="panel-title">${_('Meta-Tagging')}</h3>
60 </div>
60 </div>
61 <div class="panel-body">
61 <div class="panel-body">
62 <div class="checkbox">
62 <div class="checkbox">
63 ${h.checkbox('rhodecode_stylify_metatags','True')}
63 ${h.checkbox('rhodecode_stylify_metatags','True')}
64 <label for="rhodecode_stylify_metatags">${_('Stylify recognised meta tags')}</label>
64 <label for="rhodecode_stylify_metatags">${_('Stylify recognised meta tags')}</label>
65 </div>
65 </div>
66 <span class="help-block">${_('Parses meta tags from repository description field and turns them into colored tags.')}</span>
66 <span class="help-block">${_('Parses meta tags from repository description field and turns them into colored tags.')}</span>
67 <div>
67 <div>
68 <table>
68 <table>
69 <tr><td>[featured] </td><td><span class="metatag" tag="featured">featured</span></td></tr>
69 <tr><td>[featured] </td><td><span class="metatag" tag="featured">featured</span></td></tr>
70 <tr><td>[stale] </td><td><span class="metatag" tag="stale">stale</span></td></tr>
70 <tr><td>[stale] </td><td><span class="metatag" tag="stale">stale</span></td></tr>
71 <tr><td>[dead] </td><td><span class="metatag" tag="dead">dead</span></td></tr>
71 <tr><td>[dead] </td><td><span class="metatag" tag="dead">dead</span></td></tr>
72 <tr><td>[personal] </td><td><span class="metatag" tag="personal">personal</span></td></tr>
72 <tr><td>[personal] </td><td><span class="metatag" tag="personal">personal</span></td></tr>
73
73
74 <tr><td>[lang =&gt; lang] </td><td><span class="metatag" tag="lang" >lang</span></td></tr>
74 <tr><td>[lang =&gt; lang] </td><td><span class="metatag" tag="lang" >lang</span></td></tr>
75
75
76 <tr><td>[license =&gt; License] </td><td><span class="metatag" tag="license"><a href="http://www.opensource.org/licenses/License" >License</a></span></td></tr>
76 <tr><td>[license =&gt; License] </td><td><span class="metatag" tag="license"><a href="http://www.opensource.org/licenses/License" >License</a></span></td></tr>
77 <tr><td>[requires =&gt; Repo] </td><td><span class="metatag" tag="requires" >requires =&gt; <a href="#" >Repo</a></span></td></tr>
77 <tr><td>[requires =&gt; Repo] </td><td><span class="metatag" tag="requires" >requires =&gt; <a href="#" >Repo</a></span></td></tr>
78 <tr><td>[recommends =&gt; Repo] </td><td><span class="metatag" tag="recommends" >recommends =&gt; <a href="#" >Repo</a></span></td></tr>
78 <tr><td>[recommends =&gt; Repo] </td><td><span class="metatag" tag="recommends" >recommends =&gt; <a href="#" >Repo</a></span></td></tr>
79 <tr><td>[see =&gt; URI] </td><td><span class="metatag" tag="see">see =&gt; <a href="#">URI</a> </span></td></tr>
79 <tr><td>[see =&gt; URI] </td><td><span class="metatag" tag="see">see =&gt; <a href="#">URI</a> </span></td></tr>
80 </table>
80 </table>
81 </div>
81 </div>
82 </div>
82 </div>
83 </div>
83 </div>
84
84
85
85
86 <div class="panel panel-default">
86 <div class="panel panel-default">
87 <div class="panel-heading">
87 <div class="panel-heading">
88 <h3 class="panel-title">${_('Dashboard Items')}</h3>
88 <h3 class="panel-title">${_('Dashboard Items')}</h3>
89 </div>
89 </div>
90 <div class="panel-body">
90 <div class="panel-body">
91 <div class="label">
91 <div class="label">
92 <label for="rhodecode_dashboard_items">${_('Main page dashboard items')}</label>
92 <label for="rhodecode_dashboard_items">${_('Main page dashboard items')}</label>
93 </div>
93 </div>
94 <div class="field input">
94 <div class="field input">
95 ${h.text('rhodecode_dashboard_items',size=5)}
95 ${h.text('rhodecode_dashboard_items',size=5)}
96 </div>
96 </div>
97 <div class="field">
97 <div class="field">
98 <span class="help-block">${_('Number of items displayed in the main page dashboard before pagination is shown.')}</span>
98 <span class="help-block">${_('Number of items displayed in the main page dashboard before pagination is shown.')}</span>
99 </div>
99 </div>
100
100
101 <div class="label">
101 <div class="label">
102 <label for="rhodecode_admin_grid_items">${_('Admin pages items')}</label>
102 <label for="rhodecode_admin_grid_items">${_('Admin pages items')}</label>
103 </div>
103 </div>
104 <div class="field input">
104 <div class="field input">
105 ${h.text('rhodecode_admin_grid_items',size=5)}
105 ${h.text('rhodecode_admin_grid_items',size=5)}
106 </div>
106 </div>
107 <div class="field">
107 <div class="field">
108 <span class="help-block">${_('Number of items displayed in the admin pages grids before pagination is shown.')}</span>
108 <span class="help-block">${_('Number of items displayed in the admin pages grids before pagination is shown.')}</span>
109 </div>
109 </div>
110 </div>
110 </div>
111 </div>
111 </div>
112
112
113
113
114
114
115 <div class="panel panel-default">
115 <div class="panel panel-default">
116 <div class="panel-heading" id="commit-id">
116 <div class="panel-heading" id="commit-id">
117 <h3 class="panel-title">${_('Commit ID Style')}</h3>
117 <h3 class="panel-title">${_('Commit ID Style')}</h3>
118 </div>
118 </div>
119 <div class="panel-body">
119 <div class="panel-body">
120 <div class="label">
120 <div class="label">
121 <label for="rhodecode_show_sha_length">${_('Commit sha length')}</label>
121 <label for="rhodecode_show_sha_length">${_('Commit sha length')}</label>
122 </div>
122 </div>
123 <div class="input">
123 <div class="input">
124 <div class="field">
124 <div class="field">
125 ${h.text('rhodecode_show_sha_length',size=5)}
125 ${h.text('rhodecode_show_sha_length',size=5)}
126 </div>
126 </div>
127 <div class="field">
127 <div class="field">
128 <span class="help-block">${_('''Number of chars to show in commit sha displayed in web interface.
128 <span class="help-block">${_('''Number of chars to show in commit sha displayed in web interface.
129 By default it's shown as r123:9043a6a4c226 this value defines the
129 By default it's shown as r123:9043a6a4c226 this value defines the
130 length of the sha after the `r123:` part.''')}</span>
130 length of the sha after the `r123:` part.''')}</span>
131 </div>
131 </div>
132 </div>
132 </div>
133
133
134 <div class="checkbox">
134 <div class="checkbox">
135 ${h.checkbox('rhodecode_show_revision_number','True')}
135 ${h.checkbox('rhodecode_show_revision_number','True')}
136 <label for="rhodecode_show_revision_number">${_('Show commit ID numeric reference')} / ${_('Commit show revision number')}</label>
136 <label for="rhodecode_show_revision_number">${_('Show commit ID numeric reference')} / ${_('Commit show revision number')}</label>
137 </div>
137 </div>
138 <span class="help-block">${_('''Show revision number in commit sha displayed in web interface.
138 <span class="help-block">${_('''Show revision number in commit sha displayed in web interface.
139 By default it's shown as r123:9043a6a4c226 this value defines the
139 By default it's shown as r123:9043a6a4c226 this value defines the
140 if the `r123:` part is shown.''')}</span>
140 if the `r123:` part is shown.''')}</span>
141 </div>
141 </div>
142 </div>
142 </div>
143
143
144
144
145 <div class="panel panel-default">
145 <div class="panel panel-default">
146 <div class="panel-heading" id="icons">
146 <div class="panel-heading" id="icons">
147 <h3 class="panel-title">${_('Icons')}</h3>
147 <h3 class="panel-title">${_('Icons')}</h3>
148 </div>
148 </div>
149 <div class="panel-body">
149 <div class="panel-body">
150 <div class="checkbox">
150 <div class="checkbox">
151 ${h.checkbox('rhodecode_show_public_icon','True')}
151 ${h.checkbox('rhodecode_show_public_icon','True')}
152 <label for="rhodecode_show_public_icon">${_('Show public repo icon on repositories')}</label>
152 <label for="rhodecode_show_public_icon">${_('Show public repo icon on repositories')}</label>
153 </div>
153 </div>
154 <div></div>
154 <div></div>
155
155
156 <div class="checkbox">
156 <div class="checkbox">
157 ${h.checkbox('rhodecode_show_private_icon','True')}
157 ${h.checkbox('rhodecode_show_private_icon','True')}
158 <label for="rhodecode_show_private_icon">${_('Show private repo icon on repositories')}</label>
158 <label for="rhodecode_show_private_icon">${_('Show private repo icon on repositories')}</label>
159 </div>
159 </div>
160 <span class="help-block">${_('Show public/private icons next to repositories names.')}</span>
160 <span class="help-block">${_('Show public/private icons next to repositories names.')}</span>
161 </div>
161 </div>
162 </div>
162 </div>
163
163
164
164
165 <div class="panel panel-default">
165 <div class="panel panel-default">
166 <div class="panel-heading">
166 <div class="panel-heading">
167 <h3 class="panel-title">${_('Markup Renderer')}</h3>
167 <h3 class="panel-title">${_('Markup Renderer')}</h3>
168 </div>
168 </div>
169 <div class="panel-body">
169 <div class="panel-body">
170 <div class="field select">
170 <div class="field select">
171 ${h.select('rhodecode_markup_renderer', '', ['rst', 'markdown'])}
171 ${h.select('rhodecode_markup_renderer', '', ['rst', 'markdown'])}
172 </div>
172 </div>
173 <div class="field">
173 <div class="field">
174 <span class="help-block">${_('Default renderer used to render comments, pull request descriptions and other description elements. After change old entries will still work correctly.')}</span>
174 <span class="help-block">${_('Default renderer used to render comments, pull request descriptions and other description elements. After change old entries will still work correctly.')}</span>
175 </div>
175 </div>
176 </div>
176 </div>
177 </div>
177 </div>
178
178
179 <div class="panel panel-default">
179 <div class="panel panel-default">
180 <div class="panel-heading">
180 <div class="panel-heading">
181 <h3 class="panel-title">${_('Clone URL')}</h3>
181 <h3 class="panel-title">${_('Clone URL')}</h3>
182 </div>
182 </div>
183 <div class="panel-body">
183 <div class="panel-body">
184 <div class="field">
184 <div class="field">
185 ${h.text('rhodecode_clone_uri_tmpl', size=60)}
185 ${h.text('rhodecode_clone_uri_tmpl', size=60)}
186 </div>
186 </div>
187
187
188 <div class="field">
188 <div class="field">
189 <span class="help-block">
189 <span class="help-block">
190 ${_('''Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:
190 ${_('''Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:
191 {scheme} 'http' or 'https' sent from running RhodeCode server,
191 {scheme} 'http' or 'https' sent from running RhodeCode server,
192 {user} current user username,
192 {user} current user username,
193 {netloc} network location/server host of running RhodeCode server,
193 {netloc} network location/server host of running RhodeCode server,
194 {repo} full repository name,
194 {repo} full repository name,
195 {repoid} ID of repository, can be used to contruct clone-by-id''')}
195 {repoid} ID of repository, can be used to contruct clone-by-id''')}
196 </span>
196 </span>
197 </div>
197 </div>
198 </div>
198 </div>
199 </div>
199 </div>
200
200
201 <div class="panel panel-default">
201 <div class="panel panel-default">
202 <div class="panel-heading">
202 <div class="panel-heading">
203 <h3 class="panel-title">${_('Custom Support Link')}</h3>
203 <h3 class="panel-title">${_('Custom Support Link')}</h3>
204 </div>
204 </div>
205 <div class="panel-body">
205 <div class="panel-body">
206 <div class="field">
206 <div class="field">
207 ${h.text('rhodecode_support_url', size=60)}
207 ${h.text('rhodecode_support_url', size=60)}
208 </div>
208 </div>
209 <div class="field">
209 <div class="field">
210 <span class="help-block">
210 <span class="help-block">
211 ${_('''Custom url for the support link located at the bottom.
211 ${_('''Custom url for the support link located at the bottom.
212 The default is set to %(default_url)s. In case there's a need
212 The default is set to %(default_url)s. In case there's a need
213 to change the support link to internal issue tracker, it should be done here.
213 to change the support link to internal issue tracker, it should be done here.
214 ''') % {'default_url': h.url('rhodecode_support')}}
214 ''') % {'default_url': h.url('rhodecode_support')}}
215 </span>
215 </span>
216 </div>
216 </div>
217 </div>
217 </div>
218 </div>
218 </div>
219
219
220 <div class="buttons">
220 <div class="buttons">
221 ${h.submit('save',_('Save settings'),class_="btn")}
221 ${h.submit('save',_('Save settings'),class_="btn")}
222 ${h.reset('reset',_('Reset'),class_="btn")}
222 ${h.reset('reset',_('Reset'),class_="btn")}
223 </div>
223 </div>
224
224
225
225
226 ${h.end_form()}
226 ${h.end_form()}
227
227
228 <script>
228 <script>
229 $(document).ready(function() {
229 $(document).ready(function() {
230 $('#rhodecode_markup_renderer').select2({
230 $('#rhodecode_markup_renderer').select2({
231 containerCssClass: 'drop-menu',
231 containerCssClass: 'drop-menu',
232 dropdownCssClass: 'drop-menu-dropdown',
232 dropdownCssClass: 'drop-menu-dropdown',
233 dropdownAutoWidth: true,
233 dropdownAutoWidth: true,
234 minimumResultsForSearch: -1
234 minimumResultsForSearch: -1
235 });
235 });
236 });
236 });
237 </script>
237 </script>
@@ -1,72 +1,72 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 ${_('Add user group')}
5 ${_('Add user group')}
6 %if c.rhodecode_name:
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
8 %endif
9 </%def>
9 </%def>
10 <%def name="breadcrumbs_links()">
10 <%def name="breadcrumbs_links()">
11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 &raquo;
12 &raquo;
13 ${h.link_to(_('User groups'),h.url('users_groups'))}
13 ${h.link_to(_('User groups'),h.url('users_groups'))}
14 &raquo;
14 &raquo;
15 ${_('Add User Group')}
15 ${_('Add User Group')}
16 </%def>
16 </%def>
17
17
18 <%def name="menu_bar_nav()">
18 <%def name="menu_bar_nav()">
19 ${self.menu_items(active='admin')}
19 ${self.menu_items(active='admin')}
20 </%def>
20 </%def>
21
21
22 <%def name="main()">
22 <%def name="main()">
23 <div class="box main-content">
23 <div class="box main-content">
24 <!-- box / title -->
24 <!-- box / title -->
25 <div class="title">
25 <div class="title">
26 ${self.breadcrumbs()}
26 ${self.breadcrumbs()}
27 </div>
27 </div>
28 <!-- end box / title -->
28 <!-- end box / title -->
29 ${h.secure_form(url('users_groups'))}
29 ${h.secure_form(h.url('users_groups'))}
30 <div class="form">
30 <div class="form">
31 <!-- fields -->
31 <!-- fields -->
32 <div class="fields">
32 <div class="fields">
33 <div class="field">
33 <div class="field">
34 <div class="label">
34 <div class="label">
35 <label for="users_group_name">${_('Group name')}:</label>
35 <label for="users_group_name">${_('Group name')}:</label>
36 </div>
36 </div>
37 <div class="input">
37 <div class="input">
38 ${h.text('users_group_name', class_='medium')}
38 ${h.text('users_group_name', class_='medium')}
39 </div>
39 </div>
40 </div>
40 </div>
41 <div class="field">
41 <div class="field">
42 <div class="label">
42 <div class="label">
43 <label for="user_group_description">${_('Description')}:</label>
43 <label for="user_group_description">${_('Description')}:</label>
44 </div>
44 </div>
45 <div class="textarea editor">
45 <div class="textarea editor">
46 ${h.textarea('user_group_description')}
46 ${h.textarea('user_group_description')}
47 <span class="help-block">${_('Short, optional description for this user group.')}</span>
47 <span class="help-block">${_('Short, optional description for this user group.')}</span>
48 </div>
48 </div>
49 </div>
49 </div>
50 <div class="field">
50 <div class="field">
51 <div class="label">
51 <div class="label">
52 <label for="users_group_active">${_('Active')}:</label>
52 <label for="users_group_active">${_('Active')}:</label>
53 </div>
53 </div>
54 <div class="checkboxes">
54 <div class="checkboxes">
55 ${h.checkbox('users_group_active',value=True, checked='checked')}
55 ${h.checkbox('users_group_active',value=True, checked='checked')}
56 </div>
56 </div>
57 </div>
57 </div>
58
58
59 <div class="buttons">
59 <div class="buttons">
60 ${h.submit('save',_('Save'),class_="btn")}
60 ${h.submit('save',_('Save'),class_="btn")}
61 </div>
61 </div>
62 </div>
62 </div>
63 </div>
63 </div>
64 ${h.end_form()}
64 ${h.end_form()}
65 </div>
65 </div>
66 </%def>
66 </%def>
67
67
68 <script>
68 <script>
69 $(document).ready(function(){
69 $(document).ready(function(){
70 $('#users_group_name').focus();
70 $('#users_group_name').focus();
71 })
71 })
72 </script>
72 </script>
@@ -1,3 +1,3 b''
1 <%namespace name="dpb" file="/base/default_perms_box.mako"/>
1 <%namespace name="dpb" file="/base/default_perms_box.mako"/>
2 ${dpb.default_perms_box(url('edit_user_group_global_perms', user_group_id=c.user_group.users_group_id))}
2 ${dpb.default_perms_box(h.url('edit_user_group_global_perms', user_group_id=c.user_group.users_group_id))}
3
3
@@ -1,134 +1,134 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('User Group Permissions')}</h3>
5 <h3 class="panel-title">${_('User Group Permissions')}</h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 ${h.secure_form(url('edit_user_group_perms', user_group_id=c.user_group.users_group_id),method='put')}
8 ${h.secure_form(h.url('edit_user_group_perms', user_group_id=c.user_group.users_group_id),method='put')}
9 <table id="permissions_manage" class="rctable permissions">
9 <table id="permissions_manage" class="rctable permissions">
10 <tr>
10 <tr>
11 <th class="td-radio">${_('None')}</th>
11 <th class="td-radio">${_('None')}</th>
12 <th class="td-radio">${_('Read')}</th>
12 <th class="td-radio">${_('Read')}</th>
13 <th class="td-radio">${_('Write')}</th>
13 <th class="td-radio">${_('Write')}</th>
14 <th class="td-radio">${_('Admin')}</th>
14 <th class="td-radio">${_('Admin')}</th>
15 <th>${_('User/User Group')}</th>
15 <th>${_('User/User Group')}</th>
16 <th></th>
16 <th></th>
17 </tr>
17 </tr>
18 ## USERS
18 ## USERS
19 %for _user in c.user_group.permissions():
19 %for _user in c.user_group.permissions():
20 %if getattr(_user, 'admin_row', None) or getattr(_user, 'owner_row', None):
20 %if getattr(_user, 'admin_row', None) or getattr(_user, 'owner_row', None):
21 <tr class="perm_admin_row">
21 <tr class="perm_admin_row">
22 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.none', disabled="disabled")}</td>
22 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.none', disabled="disabled")}</td>
23 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.read', disabled="disabled")}</td>
23 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.read', disabled="disabled")}</td>
24 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.write', disabled="disabled")}</td>
24 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.write', disabled="disabled")}</td>
25 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.admin', 'repository.admin', disabled="disabled")}</td>
25 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.admin', 'repository.admin', disabled="disabled")}</td>
26 <td class="td-user">
26 <td class="td-user">
27 ${base.gravatar(_user.email, 16)}
27 ${base.gravatar(_user.email, 16)}
28 <span class="user">
28 <span class="user">
29 ${h.link_to_user(_user.username)}
29 ${h.link_to_user(_user.username)}
30 %if getattr(_user, 'admin_row', None):
30 %if getattr(_user, 'admin_row', None):
31 (${_('super admin')})
31 (${_('super admin')})
32 %endif
32 %endif
33 %if getattr(_user, 'owner_row', None):
33 %if getattr(_user, 'owner_row', None):
34 (${_('owner')})
34 (${_('owner')})
35 %endif
35 %endif
36 </span>
36 </span>
37 </td>
37 </td>
38 <td></td>
38 <td></td>
39 </tr>
39 </tr>
40 %else:
40 %else:
41 ##forbid revoking permission from yourself, except if you're an super admin
41 ##forbid revoking permission from yourself, except if you're an super admin
42 <tr>
42 <tr>
43 %if c.rhodecode_user.user_id != _user.user_id or c.rhodecode_user.is_admin:
43 %if c.rhodecode_user.user_id != _user.user_id or c.rhodecode_user.is_admin:
44 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.none')}</td>
44 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.none')}</td>
45 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.read')}</td>
45 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.read')}</td>
46 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.write')}</td>
46 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.write')}</td>
47 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.admin')}</td>
47 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.admin')}</td>
48 <td class="td-user">
48 <td class="td-user">
49 ${base.gravatar(_user.email, 16)}
49 ${base.gravatar(_user.email, 16)}
50 <span class="user">
50 <span class="user">
51 % if _user.username == h.DEFAULT_USER:
51 % if _user.username == h.DEFAULT_USER:
52 ${h.DEFAULT_USER} <span class="user-perm-help-text"> - ${_('permission for all other users')}</span>
52 ${h.DEFAULT_USER} <span class="user-perm-help-text"> - ${_('permission for all other users')}</span>
53 % else:
53 % else:
54 ${h.link_to_user(_user.username)}
54 ${h.link_to_user(_user.username)}
55 % endif
55 % endif
56 </span>
56 </span>
57 </td>
57 </td>
58 <td class="td-action">
58 <td class="td-action">
59 %if _user.username != h.DEFAULT_USER:
59 %if _user.username != h.DEFAULT_USER:
60 <span class="btn btn-link btn-danger revoke_perm"
60 <span class="btn btn-link btn-danger revoke_perm"
61 member="${_user.user_id}" member_type="user">
61 member="${_user.user_id}" member_type="user">
62 <i class="icon-remove"></i> ${_('revoke')}
62 <i class="icon-remove"></i> ${_('revoke')}
63 </span>
63 </span>
64 %endif
64 %endif
65 </td>
65 </td>
66 %else:
66 %else:
67 ## special case for current user permissions, we make sure he cannot take his own permissions
67 ## special case for current user permissions, we make sure he cannot take his own permissions
68 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.none', disabled="disabled")}</td>
68 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.none', disabled="disabled")}</td>
69 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.read', disabled="disabled")}</td>
69 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.read', disabled="disabled")}</td>
70 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.write', disabled="disabled")}</td>
70 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.write', disabled="disabled")}</td>
71 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.admin', disabled="disabled")}</td>
71 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'usergroup.admin', disabled="disabled")}</td>
72 <td class="td-user">
72 <td class="td-user">
73 ${base.gravatar(_user.email, 16)}
73 ${base.gravatar(_user.email, 16)}
74 <span class="user">
74 <span class="user">
75 % if _user.username == h.DEFAULT_USER:
75 % if _user.username == h.DEFAULT_USER:
76 ${h.DEFAULT_USER} <span class="user-perm-help-text"> - ${_('permission for all other users')}</span>
76 ${h.DEFAULT_USER} <span class="user-perm-help-text"> - ${_('permission for all other users')}</span>
77 % else:
77 % else:
78 ${h.link_to_user(_user.username)}
78 ${h.link_to_user(_user.username)}
79 % endif
79 % endif
80 <span class="user-perm-help-text">(${_('delegated admin')})</span>
80 <span class="user-perm-help-text">(${_('delegated admin')})</span>
81 </span>
81 </span>
82 </td>
82 </td>
83 <td></td>
83 <td></td>
84 %endif
84 %endif
85 </tr>
85 </tr>
86 %endif
86 %endif
87 %endfor
87 %endfor
88
88
89 ## USER GROUPS
89 ## USER GROUPS
90 %for _user_group in c.user_group.permission_user_groups():
90 %for _user_group in c.user_group.permission_user_groups():
91 <tr>
91 <tr>
92 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.none')}</td>
92 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.none')}</td>
93 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.read')}</td>
93 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.read')}</td>
94 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.write')}</td>
94 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.write')}</td>
95 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.admin')}</td>
95 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.admin')}</td>
96 <td class="td-user">
96 <td class="td-user">
97 <i class="icon-group" ></i>
97 <i class="icon-group" ></i>
98 %if h.HasPermissionAny('hg.admin')():
98 %if h.HasPermissionAny('hg.admin')():
99 <a href="${h.url('edit_users_group',user_group_id=_user_group.users_group_id)}">
99 <a href="${h.url('edit_users_group',user_group_id=_user_group.users_group_id)}">
100 ${_user_group.users_group_name}
100 ${_user_group.users_group_name}
101 </a>
101 </a>
102 %else:
102 %else:
103 ${_user_group.users_group_name}
103 ${_user_group.users_group_name}
104 %endif
104 %endif
105 </td>
105 </td>
106 <td class="td-action">
106 <td class="td-action">
107 <span class="btn btn-link btn-danger revoke_perm"
107 <span class="btn btn-link btn-danger revoke_perm"
108 member="${_user_group.users_group_id}" member_type="user_group">
108 member="${_user_group.users_group_id}" member_type="user_group">
109 <i class="icon-remove"></i> ${_('revoke')}
109 <i class="icon-remove"></i> ${_('revoke')}
110 </span>
110 </span>
111 </td>
111 </td>
112 </tr>
112 </tr>
113 %endfor
113 %endfor
114 <tr class="new_members" id="add_perm_input"></tr>
114 <tr class="new_members" id="add_perm_input"></tr>
115 </table>
115 </table>
116 <div id="add_perm" class="link">
116 <div id="add_perm" class="link">
117 ${_('Add new')}
117 ${_('Add new')}
118 </div>
118 </div>
119 <div class="buttons">
119 <div class="buttons">
120 ${h.submit('save',_('Save'),class_="btn btn-primary")}
120 ${h.submit('save',_('Save'),class_="btn btn-primary")}
121 ${h.reset('reset',_('Reset'),class_="btn btn-danger")}
121 ${h.reset('reset',_('Reset'),class_="btn btn-danger")}
122 </div>
122 </div>
123 ${h.end_form()}
123 ${h.end_form()}
124 </div>
124 </div>
125 </div>
125 </div>
126
126
127 <script type="text/javascript">
127 <script type="text/javascript">
128 $('#add_perm').on('click', function(e){
128 $('#add_perm').on('click', function(e){
129 addNewPermInput($(this), 'usergroup');
129 addNewPermInput($(this), 'usergroup');
130 });
130 });
131 $('.revoke_perm').on('click', function(e){
131 $('.revoke_perm').on('click', function(e){
132 markRevokePermInput($(this), 'usergroup');
132 markRevokePermInput($(this), 'usergroup');
133 });
133 });
134 </script>
134 </script>
@@ -1,186 +1,186 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%namespace name="base" file="/base/base.mako"/>
2 <%namespace name="base" file="/base/base.mako"/>
3
3
4 <div class="panel panel-default">
4 <div class="panel panel-default">
5 <div class="panel-heading">
5 <div class="panel-heading">
6 <h3 class="panel-title">${_('User Group: %s') % c.user_group.users_group_name}</h3>
6 <h3 class="panel-title">${_('User Group: %s') % c.user_group.users_group_name}</h3>
7 </div>
7 </div>
8 <div class="panel-body">
8 <div class="panel-body">
9 ${h.secure_form(url('update_users_group', user_group_id=c.user_group.users_group_id),method='put', id='edit_users_group')}
9 ${h.secure_form(h.url('update_users_group', user_group_id=c.user_group.users_group_id),method='put', id='edit_users_group')}
10 <div class="form">
10 <div class="form">
11 <!-- fields -->
11 <!-- fields -->
12 <div class="fields">
12 <div class="fields">
13 <div class="field">
13 <div class="field">
14 <div class="label">
14 <div class="label">
15 <label for="users_group_name">${_('Group name')}:</label>
15 <label for="users_group_name">${_('Group name')}:</label>
16 </div>
16 </div>
17 <div class="input">
17 <div class="input">
18 ${h.text('users_group_name',class_='medium')}
18 ${h.text('users_group_name',class_='medium')}
19 </div>
19 </div>
20 </div>
20 </div>
21
21
22 <div class="field badged-field">
22 <div class="field badged-field">
23 <div class="label">
23 <div class="label">
24 <label for="user">${_('Owner')}:</label>
24 <label for="user">${_('Owner')}:</label>
25 </div>
25 </div>
26 <div class="input">
26 <div class="input">
27 <div class="badge-input-container">
27 <div class="badge-input-container">
28 <div class="user-badge">
28 <div class="user-badge">
29 ${base.gravatar_with_user(c.user_group.user.email, show_disabled=not c.user_group.user.active)}
29 ${base.gravatar_with_user(c.user_group.user.email, show_disabled=not c.user_group.user.active)}
30 </div>
30 </div>
31 <div class="badge-input-wrap">
31 <div class="badge-input-wrap">
32 ${h.text('user', class_="medium", autocomplete="off")}
32 ${h.text('user', class_="medium", autocomplete="off")}
33 </div>
33 </div>
34 </div>
34 </div>
35 <form:error name="user"/>
35 <form:error name="user"/>
36 <p class="help-block">${_('Change owner of this user group.')}</p>
36 <p class="help-block">${_('Change owner of this user group.')}</p>
37 </div>
37 </div>
38 </div>
38 </div>
39
39
40 <div class="field">
40 <div class="field">
41 <div class="label label-textarea">
41 <div class="label label-textarea">
42 <label for="user_group_description">${_('Description')}:</label>
42 <label for="user_group_description">${_('Description')}:</label>
43 </div>
43 </div>
44 <div class="textarea textarea-small editor">
44 <div class="textarea textarea-small editor">
45 ${h.textarea('user_group_description',cols=23,rows=5,class_="medium")}
45 ${h.textarea('user_group_description',cols=23,rows=5,class_="medium")}
46 <span class="help-block">${_('Short, optional description for this user group.')}</span>
46 <span class="help-block">${_('Short, optional description for this user group.')}</span>
47 </div>
47 </div>
48 </div>
48 </div>
49 <div class="field">
49 <div class="field">
50 <div class="label label-checkbox">
50 <div class="label label-checkbox">
51 <label for="users_group_active">${_('Active')}:</label>
51 <label for="users_group_active">${_('Active')}:</label>
52 </div>
52 </div>
53 <div class="checkboxes">
53 <div class="checkboxes">
54 ${h.checkbox('users_group_active',value=True)}
54 ${h.checkbox('users_group_active',value=True)}
55 </div>
55 </div>
56 </div>
56 </div>
57
57
58 <div class="field">
58 <div class="field">
59 <div class="label label-checkbox">
59 <div class="label label-checkbox">
60 <label for="users_group_active">${_('Add members')}:</label>
60 <label for="users_group_active">${_('Add members')}:</label>
61 </div>
61 </div>
62 <div class="input">
62 <div class="input">
63 ${h.text('user_group_add_members', placeholder="user/usergroup", class_="medium")}
63 ${h.text('user_group_add_members', placeholder="user/usergroup", class_="medium")}
64 </div>
64 </div>
65 </div>
65 </div>
66
66
67 <input type="hidden" name="__start__" value="user_group_members:sequence"/>
67 <input type="hidden" name="__start__" value="user_group_members:sequence"/>
68 <table id="group_members_placeholder" class="rctable group_members">
68 <table id="group_members_placeholder" class="rctable group_members">
69 <tr>
69 <tr>
70 <th>${_('Username')}</th>
70 <th>${_('Username')}</th>
71 <th>${_('Action')}</th>
71 <th>${_('Action')}</th>
72 </tr>
72 </tr>
73
73
74 % if c.group_members_obj:
74 % if c.group_members_obj:
75 % for user in c.group_members_obj:
75 % for user in c.group_members_obj:
76 <tr>
76 <tr>
77 <td id="member_user_${user.user_id}" class="td-author">
77 <td id="member_user_${user.user_id}" class="td-author">
78 <div class="group_member">
78 <div class="group_member">
79 ${base.gravatar(user.email, 16)}
79 ${base.gravatar(user.email, 16)}
80 <span class="username user">${h.link_to(h.person(user), h.url( 'edit_user',user_id=user.user_id))}</span>
80 <span class="username user">${h.link_to(h.person(user), h.url( 'edit_user',user_id=user.user_id))}</span>
81 <input type="hidden" name="__start__" value="member:mapping">
81 <input type="hidden" name="__start__" value="member:mapping">
82 <input type="hidden" name="member_user_id" value="${user.user_id}">
82 <input type="hidden" name="member_user_id" value="${user.user_id}">
83 <input type="hidden" name="type" value="existing" id="member_${user.user_id}">
83 <input type="hidden" name="type" value="existing" id="member_${user.user_id}">
84 <input type="hidden" name="__end__" value="member:mapping">
84 <input type="hidden" name="__end__" value="member:mapping">
85 </div>
85 </div>
86 </td>
86 </td>
87 <td class="">
87 <td class="">
88 <div class="usergroup_member_remove action_button" onclick="removeUserGroupMember(${user.user_id}, true)" style="visibility: visible;">
88 <div class="usergroup_member_remove action_button" onclick="removeUserGroupMember(${user.user_id}, true)" style="visibility: visible;">
89 <i class="icon-remove-sign"></i>
89 <i class="icon-remove-sign"></i>
90 </div>
90 </div>
91 </td>
91 </td>
92 </tr>
92 </tr>
93 % endfor
93 % endfor
94
94
95 % else:
95 % else:
96 <tr><td colspan="2">${_('No members yet')}</td></tr>
96 <tr><td colspan="2">${_('No members yet')}</td></tr>
97 % endif
97 % endif
98 </table>
98 </table>
99 <input type="hidden" name="__end__" value="user_group_members:sequence"/>
99 <input type="hidden" name="__end__" value="user_group_members:sequence"/>
100
100
101 <div class="buttons">
101 <div class="buttons">
102 ${h.submit('Save',_('Save'),class_="btn")}
102 ${h.submit('Save',_('Save'),class_="btn")}
103 </div>
103 </div>
104 </div>
104 </div>
105 </div>
105 </div>
106 ${h.end_form()}
106 ${h.end_form()}
107 </div>
107 </div>
108 </div>
108 </div>
109 <script>
109 <script>
110 $(document).ready(function(){
110 $(document).ready(function(){
111 $("#group_parent_id").select2({
111 $("#group_parent_id").select2({
112 'containerCssClass': "drop-menu",
112 'containerCssClass': "drop-menu",
113 'dropdownCssClass': "drop-menu-dropdown",
113 'dropdownCssClass': "drop-menu-dropdown",
114 'dropdownAutoWidth': true
114 'dropdownAutoWidth': true
115 });
115 });
116
116
117 removeUserGroupMember = function(userId){
117 removeUserGroupMember = function(userId){
118 $('#member_'+userId).val('remove');
118 $('#member_'+userId).val('remove');
119 $('#member_user_'+userId).addClass('to-delete');
119 $('#member_user_'+userId).addClass('to-delete');
120 };
120 };
121
121
122 $('#user_group_add_members').autocomplete({
122 $('#user_group_add_members').autocomplete({
123 serviceUrl: pyroutes.url('user_autocomplete_data'),
123 serviceUrl: pyroutes.url('user_autocomplete_data'),
124 minChars:2,
124 minChars:2,
125 maxHeight:400,
125 maxHeight:400,
126 width:300,
126 width:300,
127 deferRequestBy: 300, //miliseconds
127 deferRequestBy: 300, //miliseconds
128 showNoSuggestionNotice: true,
128 showNoSuggestionNotice: true,
129 params: { user_groups:true },
129 params: { user_groups:true },
130 formatResult: autocompleteFormatResult,
130 formatResult: autocompleteFormatResult,
131 lookupFilter: autocompleteFilterResult,
131 lookupFilter: autocompleteFilterResult,
132 onSelect: function(element, suggestion){
132 onSelect: function(element, suggestion){
133
133
134 function addMember(user, fromUserGroup) {
134 function addMember(user, fromUserGroup) {
135 var gravatar = user.icon_link;
135 var gravatar = user.icon_link;
136 var username = user.value_display;
136 var username = user.value_display;
137 var userLink = pyroutes.url('edit_user', {"user_id": user.id});
137 var userLink = pyroutes.url('edit_user', {"user_id": user.id});
138 var uid = user.id;
138 var uid = user.id;
139
139
140 if (fromUserGroup) {
140 if (fromUserGroup) {
141 username = username +" "+ _gettext('(from usergroup {0})'.format(fromUserGroup))
141 username = username +" "+ _gettext('(from usergroup {0})'.format(fromUserGroup))
142 }
142 }
143
143
144 var elem = $(
144 var elem = $(
145 ('<tr>'+
145 ('<tr>'+
146 '<td id="member_user_{6}" class="td-author td-author-new-entry">'+
146 '<td id="member_user_{6}" class="td-author td-author-new-entry">'+
147 '<div class="group_member">'+
147 '<div class="group_member">'+
148 '<img class="gravatar" src="{0}" height="16" width="16">'+
148 '<img class="gravatar" src="{0}" height="16" width="16">'+
149 '<span class="username user"><a href="{1}">{2}</a></span>'+
149 '<span class="username user"><a href="{1}">{2}</a></span>'+
150 '<input type="hidden" name="__start__" value="member:mapping">'+
150 '<input type="hidden" name="__start__" value="member:mapping">'+
151 '<input type="hidden" name="member_user_id" value="{3}">'+
151 '<input type="hidden" name="member_user_id" value="{3}">'+
152 '<input type="hidden" name="type" value="new" id="member_{4}">'+
152 '<input type="hidden" name="type" value="new" id="member_{4}">'+
153 '<input type="hidden" name="__end__" value="member:mapping">'+
153 '<input type="hidden" name="__end__" value="member:mapping">'+
154 '</div>'+
154 '</div>'+
155 '</td>'+
155 '</td>'+
156 '<td class="td-author-new-entry">'+
156 '<td class="td-author-new-entry">'+
157 '<div class="usergroup_member_remove action_button" onclick="removeUserGroupMember({5}, true)" style="visibility: visible;">'+
157 '<div class="usergroup_member_remove action_button" onclick="removeUserGroupMember({5}, true)" style="visibility: visible;">'+
158 '<i class="icon-remove-sign"></i>'+
158 '<i class="icon-remove-sign"></i>'+
159 '</div>'+
159 '</div>'+
160 '</td>'+
160 '</td>'+
161 '</tr>').format(gravatar, userLink, username,
161 '</tr>').format(gravatar, userLink, username,
162 uid, uid, uid, uid)
162 uid, uid, uid, uid)
163 );
163 );
164 $('#group_members_placeholder').append(elem)
164 $('#group_members_placeholder').append(elem)
165 }
165 }
166
166
167 if (suggestion.value_type == 'user_group') {
167 if (suggestion.value_type == 'user_group') {
168 $.getJSON(
168 $.getJSON(
169 pyroutes.url('edit_user_group_members',
169 pyroutes.url('edit_user_group_members',
170 {'user_group_id': suggestion.id}),
170 {'user_group_id': suggestion.id}),
171 function(data) {
171 function(data) {
172 $.each(data.members, function(idx, user) {
172 $.each(data.members, function(idx, user) {
173 addMember(user, suggestion.value)
173 addMember(user, suggestion.value)
174 });
174 });
175 }
175 }
176 );
176 );
177 } else if (suggestion.value_type == 'user') {
177 } else if (suggestion.value_type == 'user') {
178 addMember(suggestion, null);
178 addMember(suggestion, null);
179 }
179 }
180 }
180 }
181 });
181 });
182
182
183
183
184 UsersAutoComplete('user', '${c.rhodecode_user.user_id}');
184 UsersAutoComplete('user', '${c.rhodecode_user.user_id}');
185 })
185 })
186 </script>
186 </script>
@@ -1,147 +1,147 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 ${_('Add user')}
5 ${_('Add user')}
6 %if c.rhodecode_name:
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
8 %endif
9 </%def>
9 </%def>
10 <%def name="breadcrumbs_links()">
10 <%def name="breadcrumbs_links()">
11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
11 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 &raquo;
12 &raquo;
13 ${h.link_to(_('Users'),h.route_path('users'))}
13 ${h.link_to(_('Users'),h.route_path('users'))}
14 &raquo;
14 &raquo;
15 ${_('Add User')}
15 ${_('Add User')}
16 </%def>
16 </%def>
17
17
18 <%def name="menu_bar_nav()">
18 <%def name="menu_bar_nav()">
19 ${self.menu_items(active='admin')}
19 ${self.menu_items(active='admin')}
20 </%def>
20 </%def>
21
21
22 <%def name="main()">
22 <%def name="main()">
23 <div class="box">
23 <div class="box">
24 <!-- box / title -->
24 <!-- box / title -->
25 <div class="title">
25 <div class="title">
26 ${self.breadcrumbs()}
26 ${self.breadcrumbs()}
27 </div>
27 </div>
28 <!-- end box / title -->
28 <!-- end box / title -->
29 ${h.secure_form(url('users'))}
29 ${h.secure_form(h.url('users'))}
30 <div class="form">
30 <div class="form">
31 <!-- fields -->
31 <!-- fields -->
32 <div class="fields">
32 <div class="fields">
33 <div class="field">
33 <div class="field">
34 <div class="label">
34 <div class="label">
35 <label for="username">${_('Username')}:</label>
35 <label for="username">${_('Username')}:</label>
36 </div>
36 </div>
37 <div class="input">
37 <div class="input">
38 ${h.text('username', class_='medium')}
38 ${h.text('username', class_='medium')}
39 </div>
39 </div>
40 </div>
40 </div>
41
41
42 <div class="field">
42 <div class="field">
43 <div class="label">
43 <div class="label">
44 <label for="password">${_('Password')}:</label>
44 <label for="password">${_('Password')}:</label>
45 </div>
45 </div>
46 <div class="input">
46 <div class="input">
47 ${h.password('password', class_='medium')}
47 ${h.password('password', class_='medium')}
48 </div>
48 </div>
49 </div>
49 </div>
50
50
51 <div class="field">
51 <div class="field">
52 <div class="label">
52 <div class="label">
53 <label for="password_confirmation">${_('Password confirmation')}:</label>
53 <label for="password_confirmation">${_('Password confirmation')}:</label>
54 </div>
54 </div>
55 <div class="input">
55 <div class="input">
56 ${h.password('password_confirmation',autocomplete="off", class_='medium')}
56 ${h.password('password_confirmation',autocomplete="off", class_='medium')}
57 <div class="info-block">
57 <div class="info-block">
58 <a id="generate_password" href="#">
58 <a id="generate_password" href="#">
59 <i class="icon-lock"></i> ${_('Generate password')}
59 <i class="icon-lock"></i> ${_('Generate password')}
60 </a>
60 </a>
61 <span id="generate_password_preview"></span>
61 <span id="generate_password_preview"></span>
62 </div>
62 </div>
63 </div>
63 </div>
64 </div>
64 </div>
65
65
66 <div class="field">
66 <div class="field">
67 <div class="label">
67 <div class="label">
68 <label for="firstname">${_('First Name')}:</label>
68 <label for="firstname">${_('First Name')}:</label>
69 </div>
69 </div>
70 <div class="input">
70 <div class="input">
71 ${h.text('firstname', class_='medium')}
71 ${h.text('firstname', class_='medium')}
72 </div>
72 </div>
73 </div>
73 </div>
74
74
75 <div class="field">
75 <div class="field">
76 <div class="label">
76 <div class="label">
77 <label for="lastname">${_('Last Name')}:</label>
77 <label for="lastname">${_('Last Name')}:</label>
78 </div>
78 </div>
79 <div class="input">
79 <div class="input">
80 ${h.text('lastname', class_='medium')}
80 ${h.text('lastname', class_='medium')}
81 </div>
81 </div>
82 </div>
82 </div>
83
83
84 <div class="field">
84 <div class="field">
85 <div class="label">
85 <div class="label">
86 <label for="email">${_('Email')}:</label>
86 <label for="email">${_('Email')}:</label>
87 </div>
87 </div>
88 <div class="input">
88 <div class="input">
89 ${h.text('email', class_='medium')}
89 ${h.text('email', class_='medium')}
90 ${h.hidden('extern_name', c.default_extern_type)}
90 ${h.hidden('extern_name', c.default_extern_type)}
91 ${h.hidden('extern_type', c.default_extern_type)}
91 ${h.hidden('extern_type', c.default_extern_type)}
92 </div>
92 </div>
93 </div>
93 </div>
94
94
95 <div class="field">
95 <div class="field">
96 <div class="label label-checkbox">
96 <div class="label label-checkbox">
97 <label for="active">${_('Active')}:</label>
97 <label for="active">${_('Active')}:</label>
98 </div>
98 </div>
99 <div class="checkboxes">
99 <div class="checkboxes">
100 ${h.checkbox('active',value=True,checked='checked')}
100 ${h.checkbox('active',value=True,checked='checked')}
101 </div>
101 </div>
102 </div>
102 </div>
103
103
104 <div class="field">
104 <div class="field">
105 <div class="label label-checkbox">
105 <div class="label label-checkbox">
106 <label for="password_change">${_('Password change')}:</label>
106 <label for="password_change">${_('Password change')}:</label>
107 </div>
107 </div>
108 <div class="checkboxes">
108 <div class="checkboxes">
109 ${h.checkbox('password_change',value=True)}
109 ${h.checkbox('password_change',value=True)}
110 <span class="help-block">${_('Force user to change his password on the next login')}</span>
110 <span class="help-block">${_('Force user to change his password on the next login')}</span>
111 </div>
111 </div>
112 </div>
112 </div>
113
113
114 <div class="field">
114 <div class="field">
115 <div class="label label-checkbox">
115 <div class="label label-checkbox">
116 <label for="create_repo_group">${_('Add personal repository group')}:</label>
116 <label for="create_repo_group">${_('Add personal repository group')}:</label>
117 </div>
117 </div>
118 <div class="checkboxes">
118 <div class="checkboxes">
119 ${h.checkbox('create_repo_group',value=True, checked=c.default_create_repo_group)}
119 ${h.checkbox('create_repo_group',value=True, checked=c.default_create_repo_group)}
120 <span class="help-block">
120 <span class="help-block">
121 ${_('New group will be created at: `/%(path)s`') % {'path': c.personal_repo_group_name}}<br/>
121 ${_('New group will be created at: `/%(path)s`') % {'path': c.personal_repo_group_name}}<br/>
122 ${_('User will be automatically set as this group owner.')}
122 ${_('User will be automatically set as this group owner.')}
123 </span>
123 </span>
124 </div>
124 </div>
125 </div>
125 </div>
126
126
127 <div class="buttons">
127 <div class="buttons">
128 ${h.submit('save',_('Save'),class_="btn")}
128 ${h.submit('save',_('Save'),class_="btn")}
129 </div>
129 </div>
130 </div>
130 </div>
131 </div>
131 </div>
132 ${h.end_form()}
132 ${h.end_form()}
133 </div>
133 </div>
134 <script>
134 <script>
135 $(document).ready(function(){
135 $(document).ready(function(){
136 $('#username').focus();
136 $('#username').focus();
137
137
138 $('#generate_password').on('click', function(e){
138 $('#generate_password').on('click', function(e){
139 var tmpl = "(${_('generated password:')} {0})";
139 var tmpl = "(${_('generated password:')} {0})";
140 var new_passwd = generatePassword(12);
140 var new_passwd = generatePassword(12);
141 $('#generate_password_preview').html(tmpl.format(new_passwd));
141 $('#generate_password_preview').html(tmpl.format(new_passwd));
142 $('#password').val(new_passwd);
142 $('#password').val(new_passwd);
143 $('#password_confirmation').val(new_passwd);
143 $('#password_confirmation').val(new_passwd);
144 })
144 })
145 })
145 })
146 </script>
146 </script>
147 </%def>
147 </%def>
@@ -1,2 +1,2 b''
1 <%namespace name="dpb" file="/base/default_perms_box.mako"/>
1 <%namespace name="dpb" file="/base/default_perms_box.mako"/>
2 ${dpb.default_perms_box(url('edit_user_global_perms', user_id=c.user.user_id))}
2 ${dpb.default_perms_box(h.url('edit_user_global_perms', user_id=c.user.user_id))}
@@ -1,150 +1,150 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <div class="panel panel-default user-profile">
3 <div class="panel panel-default user-profile">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('User Profile')}</h3>
5 <h3 class="panel-title">${_('User Profile')}</h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 <div class="user-profile-content">
8 <div class="user-profile-content">
9 ${h.secure_form(url('update_user', user_id=c.user.user_id),method='put', class_='form')}
9 ${h.secure_form(h.url('update_user', user_id=c.user.user_id),method='put', class_='form')}
10 <% readonly = None %>
10 <% readonly = None %>
11 <% disabled = "" %>
11 <% disabled = "" %>
12 %if c.extern_type != 'rhodecode':
12 %if c.extern_type != 'rhodecode':
13 <% readonly = "readonly" %>
13 <% readonly = "readonly" %>
14 <% disabled = " disabled" %>
14 <% disabled = " disabled" %>
15 <div class="infoform">
15 <div class="infoform">
16 <div class="fields">
16 <div class="fields">
17 <p>${_('This user was created from external source (%s). Editing some of the settings is limited.' % c.extern_type)}</p>
17 <p>${_('This user was created from external source (%s). Editing some of the settings is limited.' % c.extern_type)}</p>
18 </div>
18 </div>
19 </div>
19 </div>
20 %endif
20 %endif
21 <div class="form">
21 <div class="form">
22 <div class="fields">
22 <div class="fields">
23 <div class="field">
23 <div class="field">
24 <div class="label photo">
24 <div class="label photo">
25 ${_('Photo')}:
25 ${_('Photo')}:
26 </div>
26 </div>
27 <div class="input profile">
27 <div class="input profile">
28 %if c.visual.use_gravatar:
28 %if c.visual.use_gravatar:
29 ${base.gravatar(c.user.email, 100)}
29 ${base.gravatar(c.user.email, 100)}
30 <p class="help-block">${_('Change the avatar at')} <a href="http://gravatar.com">gravatar.com</a>.</p>
30 <p class="help-block">${_('Change the avatar at')} <a href="http://gravatar.com">gravatar.com</a>.</p>
31 %else:
31 %else:
32 ${base.gravatar(c.user.email, 20)}
32 ${base.gravatar(c.user.email, 20)}
33 ${_('Avatars are disabled')}
33 ${_('Avatars are disabled')}
34 %endif
34 %endif
35 </div>
35 </div>
36 </div>
36 </div>
37 <div class="field">
37 <div class="field">
38 <div class="label">
38 <div class="label">
39 ${_('Username')}:
39 ${_('Username')}:
40 </div>
40 </div>
41 <div class="input">
41 <div class="input">
42 ${h.text('username', class_='%s medium' % disabled, readonly=readonly)}
42 ${h.text('username', class_='%s medium' % disabled, readonly=readonly)}
43 </div>
43 </div>
44 </div>
44 </div>
45 <div class="field">
45 <div class="field">
46 <div class="label">
46 <div class="label">
47 <label for="name">${_('First Name')}:</label>
47 <label for="name">${_('First Name')}:</label>
48 </div>
48 </div>
49 <div class="input">
49 <div class="input">
50 ${h.text('firstname', class_="medium")}
50 ${h.text('firstname', class_="medium")}
51 </div>
51 </div>
52 </div>
52 </div>
53
53
54 <div class="field">
54 <div class="field">
55 <div class="label">
55 <div class="label">
56 <label for="lastname">${_('Last Name')}:</label>
56 <label for="lastname">${_('Last Name')}:</label>
57 </div>
57 </div>
58 <div class="input">
58 <div class="input">
59 ${h.text('lastname', class_="medium")}
59 ${h.text('lastname', class_="medium")}
60 </div>
60 </div>
61 </div>
61 </div>
62
62
63 <div class="field">
63 <div class="field">
64 <div class="label">
64 <div class="label">
65 <label for="email">${_('Email')}:</label>
65 <label for="email">${_('Email')}:</label>
66 </div>
66 </div>
67 <div class="input">
67 <div class="input">
68 ## we should be able to edit email !
68 ## we should be able to edit email !
69 ${h.text('email', class_="medium")}
69 ${h.text('email', class_="medium")}
70 </div>
70 </div>
71 </div>
71 </div>
72 <div class="field">
72 <div class="field">
73 <div class="label">
73 <div class="label">
74 ${_('New Password')}:
74 ${_('New Password')}:
75 </div>
75 </div>
76 <div class="input">
76 <div class="input">
77 ${h.password('new_password',class_='%s medium' % disabled,autocomplete="off",readonly=readonly)}
77 ${h.password('new_password',class_='%s medium' % disabled,autocomplete="off",readonly=readonly)}
78 </div>
78 </div>
79 </div>
79 </div>
80 <div class="field">
80 <div class="field">
81 <div class="label">
81 <div class="label">
82 ${_('New Password Confirmation')}:
82 ${_('New Password Confirmation')}:
83 </div>
83 </div>
84 <div class="input">
84 <div class="input">
85 ${h.password('password_confirmation',class_="%s medium" % disabled,autocomplete="off",readonly=readonly)}
85 ${h.password('password_confirmation',class_="%s medium" % disabled,autocomplete="off",readonly=readonly)}
86 </div>
86 </div>
87 </div>
87 </div>
88 <div class="field">
88 <div class="field">
89 <div class="label-text">
89 <div class="label-text">
90 ${_('Active')}:
90 ${_('Active')}:
91 </div>
91 </div>
92 <div class="input user-checkbox">
92 <div class="input user-checkbox">
93 ${h.checkbox('active',value=True)}
93 ${h.checkbox('active',value=True)}
94 </div>
94 </div>
95 </div>
95 </div>
96 <div class="field">
96 <div class="field">
97 <div class="label-text">
97 <div class="label-text">
98 ${_('Super Admin')}:
98 ${_('Super Admin')}:
99 </div>
99 </div>
100 <div class="input user-checkbox">
100 <div class="input user-checkbox">
101 ${h.checkbox('admin',value=True)}
101 ${h.checkbox('admin',value=True)}
102 </div>
102 </div>
103 </div>
103 </div>
104 <div class="field">
104 <div class="field">
105 <div class="label-text">
105 <div class="label-text">
106 ${_('Source of Record')}:
106 ${_('Source of Record')}:
107 </div>
107 </div>
108 <div class="input">
108 <div class="input">
109 <p>${c.extern_type}</p>
109 <p>${c.extern_type}</p>
110 ${h.hidden('extern_type', readonly="readonly")}
110 ${h.hidden('extern_type', readonly="readonly")}
111 </div>
111 </div>
112 </div>
112 </div>
113 <div class="field">
113 <div class="field">
114 <div class="label-text">
114 <div class="label-text">
115 ${_('Name in Source of Record')}:
115 ${_('Name in Source of Record')}:
116 </div>
116 </div>
117 <div class="input">
117 <div class="input">
118 <p>${c.extern_name}</p>
118 <p>${c.extern_name}</p>
119 ${h.hidden('extern_name', readonly="readonly")}
119 ${h.hidden('extern_name', readonly="readonly")}
120 </div>
120 </div>
121 </div>
121 </div>
122 <div class="field">
122 <div class="field">
123 <div class="label">
123 <div class="label">
124 ${_('Language')}:
124 ${_('Language')}:
125 </div>
125 </div>
126 <div class="input">
126 <div class="input">
127 ## allowed_languages is defined in the users.py
127 ## allowed_languages is defined in the users.py
128 ## c.language comes from base.py as a default language
128 ## c.language comes from base.py as a default language
129 ${h.select('language', c.language, c.allowed_languages)}
129 ${h.select('language', c.language, c.allowed_languages)}
130 <p class="help-block">${h.literal(_('Help translate %(rc_link)s into your language.') % {'rc_link': h.link_to('RhodeCode Enterprise', h.route_url('rhodecode_translations'))})}</p>
130 <p class="help-block">${h.literal(_('Help translate %(rc_link)s into your language.') % {'rc_link': h.link_to('RhodeCode Enterprise', h.route_url('rhodecode_translations'))})}</p>
131 </div>
131 </div>
132 </div>
132 </div>
133 <div class="buttons">
133 <div class="buttons">
134 ${h.submit('save', _('Save'), class_="btn")}
134 ${h.submit('save', _('Save'), class_="btn")}
135 ${h.reset('reset', _('Reset'), class_="btn")}
135 ${h.reset('reset', _('Reset'), class_="btn")}
136 </div>
136 </div>
137 </div>
137 </div>
138 </div>
138 </div>
139 ${h.end_form()}
139 ${h.end_form()}
140 </div>
140 </div>
141 </div>
141 </div>
142 </div>
142 </div>
143
143
144 <script>
144 <script>
145 $('#language').select2({
145 $('#language').select2({
146 'containerCssClass': "drop-menu",
146 'containerCssClass': "drop-menu",
147 'dropdownCssClass': "drop-menu-dropdown",
147 'dropdownCssClass': "drop-menu-dropdown",
148 'dropdownAutoWidth': true
148 'dropdownAutoWidth': true
149 });
149 });
150 </script>
150 </script>
@@ -1,156 +1,156 b''
1 ## snippet for displaying default permission box
1 ## snippet for displaying default permission box
2 ## usage:
2 ## usage:
3 ## <%namespace name="dpb" file="/base/default_perms_box.mako"/>
3 ## <%namespace name="dpb" file="/base/default_perms_box.mako"/>
4 ## ${dpb.default_perms_box(<url_to_form>)}
4 ## ${dpb.default_perms_box(<url_to_form>)}
5 ## ${dpb.default_perms_radios()}
5 ## ${dpb.default_perms_radios()}
6
6
7 <%def name="default_perms_radios(global_permissions_template = False, suffix='', **kwargs)">
7 <%def name="default_perms_radios(global_permissions_template = False, suffix='', **kwargs)">
8 <div class="main-content-full-width">
8 <div class="main-content-full-width">
9 <div class="panel panel-default">
9 <div class="panel panel-default">
10
10
11 ## displayed according to checkbox selection
11 ## displayed according to checkbox selection
12 <div class="panel-heading">
12 <div class="panel-heading">
13 %if not global_permissions_template:
13 %if not global_permissions_template:
14 <h3 class="inherit_overlay_default panel-title">${_('Inherited Permissions')}</h3>
14 <h3 class="inherit_overlay_default panel-title">${_('Inherited Permissions')}</h3>
15 <h3 class="inherit_overlay panel-title">${_('Custom Permissions')}</h3>
15 <h3 class="inherit_overlay panel-title">${_('Custom Permissions')}</h3>
16 %else:
16 %else:
17 <h3 class="panel-title">${_('Default Global Permissions')}</h3>
17 <h3 class="panel-title">${_('Default Global Permissions')}</h3>
18 %endif
18 %endif
19 </div>
19 </div>
20
20
21 <div class="panel-body">
21 <div class="panel-body">
22 %if global_permissions_template:
22 %if global_permissions_template:
23 <p>${_('The following options configure the default permissions each user or group will inherit. You can override these permissions for each individual user or user group using individual permissions settings.')}</p>
23 <p>${_('The following options configure the default permissions each user or group will inherit. You can override these permissions for each individual user or user group using individual permissions settings.')}</p>
24 %endif
24 %endif
25 <div class="field">
25 <div class="field">
26 <div class="label">
26 <div class="label">
27 <label for="default_repo_create${suffix}">${_('Repository Creation')}:</label>
27 <label for="default_repo_create${suffix}">${_('Repository Creation')}:</label>
28 </div>
28 </div>
29 <div class="radios">
29 <div class="radios">
30 ${h.radio('default_repo_create' + suffix, c.repo_create_choices[1][0], label=c.repo_create_choices[1][1], **kwargs)}
30 ${h.radio('default_repo_create' + suffix, c.repo_create_choices[1][0], label=c.repo_create_choices[1][1], **kwargs)}
31 ${h.radio('default_repo_create' + suffix, c.repo_create_choices[0][0], label=c.repo_create_choices[0][1], **kwargs)}
31 ${h.radio('default_repo_create' + suffix, c.repo_create_choices[0][0], label=c.repo_create_choices[0][1], **kwargs)}
32 <span class="help-block">${_('Permission to create root level repositories. When disabled, users can still create repositories inside their own repository groups.')}</span>
32 <span class="help-block">${_('Permission to create root level repositories. When disabled, users can still create repositories inside their own repository groups.')}</span>
33 </div>
33 </div>
34 </div>
34 </div>
35 <div class="field">
35 <div class="field">
36 <div class="label">
36 <div class="label">
37 <label for="default_repo_create_on_write${suffix}">${_('Repository Creation With Group Write Access')}:</label>
37 <label for="default_repo_create_on_write${suffix}">${_('Repository Creation With Group Write Access')}:</label>
38 </div>
38 </div>
39 <div class="radios">
39 <div class="radios">
40 ${h.radio('default_repo_create_on_write' + suffix, c.repo_create_on_write_choices[1][0], label=c.repo_create_on_write_choices[1][1], **kwargs)}
40 ${h.radio('default_repo_create_on_write' + suffix, c.repo_create_on_write_choices[1][0], label=c.repo_create_on_write_choices[1][1], **kwargs)}
41 ${h.radio('default_repo_create_on_write' + suffix, c.repo_create_on_write_choices[0][0], label=c.repo_create_on_write_choices[0][1], **kwargs)}
41 ${h.radio('default_repo_create_on_write' + suffix, c.repo_create_on_write_choices[0][0], label=c.repo_create_on_write_choices[0][1], **kwargs)}
42 <span class="help-block">${_('Write permission given on a repository group will allow creating repositories inside that group.')}</span>
42 <span class="help-block">${_('Write permission given on a repository group will allow creating repositories inside that group.')}</span>
43 </div>
43 </div>
44 </div>
44 </div>
45 <div class="field">
45 <div class="field">
46 <div class="label">
46 <div class="label">
47 <label for="default_fork_create${suffix}">${_('Repository Forking')}:</label>
47 <label for="default_fork_create${suffix}">${_('Repository Forking')}:</label>
48 </div>
48 </div>
49 <div class="radios">
49 <div class="radios">
50 ${h.radio('default_fork_create' + suffix, c.fork_choices[1][0], label=c.fork_choices[1][1], **kwargs)}
50 ${h.radio('default_fork_create' + suffix, c.fork_choices[1][0], label=c.fork_choices[1][1], **kwargs)}
51 ${h.radio('default_fork_create' + suffix, c.fork_choices[0][0], label=c.fork_choices[0][1], **kwargs)}
51 ${h.radio('default_fork_create' + suffix, c.fork_choices[0][0], label=c.fork_choices[0][1], **kwargs)}
52 <span class="help-block">${_('Permission to create root level repository forks. When disabled, users can still fork repositories inside their own repository groups.')}</span>
52 <span class="help-block">${_('Permission to create root level repository forks. When disabled, users can still fork repositories inside their own repository groups.')}</span>
53 </div>
53 </div>
54 </div>
54 </div>
55 <div class="field">
55 <div class="field">
56 <div class="label">
56 <div class="label">
57 <label for="default_repo_group_create${suffix}">${_('Repository Group Creation')}:</label>
57 <label for="default_repo_group_create${suffix}">${_('Repository Group Creation')}:</label>
58 </div>
58 </div>
59 <div class="radios">
59 <div class="radios">
60 ${h.radio('default_repo_group_create' + suffix, c.repo_group_create_choices[1][0], label=c.repo_group_create_choices[1][1], **kwargs)}
60 ${h.radio('default_repo_group_create' + suffix, c.repo_group_create_choices[1][0], label=c.repo_group_create_choices[1][1], **kwargs)}
61 ${h.radio('default_repo_group_create' + suffix, c.repo_group_create_choices[0][0], label=c.repo_group_create_choices[0][1], **kwargs)}
61 ${h.radio('default_repo_group_create' + suffix, c.repo_group_create_choices[0][0], label=c.repo_group_create_choices[0][1], **kwargs)}
62 <span class="help-block">${_('Permission to create root level repository groups. When disabled, repository group admins can still create repository subgroups within their repository groups.')}</span>
62 <span class="help-block">${_('Permission to create root level repository groups. When disabled, repository group admins can still create repository subgroups within their repository groups.')}</span>
63 </div>
63 </div>
64 </div>
64 </div>
65 <div class="field">
65 <div class="field">
66 <div class="label">
66 <div class="label">
67 <label for="default_user_group_create${suffix}">${_('User Group Creation')}:</label>
67 <label for="default_user_group_create${suffix}">${_('User Group Creation')}:</label>
68 </div>
68 </div>
69 <div class="radios">
69 <div class="radios">
70 ${h.radio('default_user_group_create' + suffix, c.user_group_create_choices[1][0], label=c.user_group_create_choices[1][1], **kwargs)}
70 ${h.radio('default_user_group_create' + suffix, c.user_group_create_choices[1][0], label=c.user_group_create_choices[1][1], **kwargs)}
71 ${h.radio('default_user_group_create' + suffix, c.user_group_create_choices[0][0], label=c.user_group_create_choices[0][1], **kwargs)}
71 ${h.radio('default_user_group_create' + suffix, c.user_group_create_choices[0][0], label=c.user_group_create_choices[0][1], **kwargs)}
72 <span class="help-block">${_('Permission to allow user group creation.')}</span>
72 <span class="help-block">${_('Permission to allow user group creation.')}</span>
73 </div>
73 </div>
74 </div>
74 </div>
75
75
76 <div class="field">
76 <div class="field">
77 <div class="label">
77 <div class="label">
78 <label for="default_inherit_default_permissions${suffix}">${_('Inherit Permissions From The Default User')}:</label>
78 <label for="default_inherit_default_permissions${suffix}">${_('Inherit Permissions From The Default User')}:</label>
79 </div>
79 </div>
80 <div class="radios">
80 <div class="radios">
81 ${h.radio('default_inherit_default_permissions' + suffix, c.inherit_default_permission_choices[1][0], label=c.inherit_default_permission_choices[1][1], **kwargs)}
81 ${h.radio('default_inherit_default_permissions' + suffix, c.inherit_default_permission_choices[1][0], label=c.inherit_default_permission_choices[1][1], **kwargs)}
82 ${h.radio('default_inherit_default_permissions' + suffix, c.inherit_default_permission_choices[0][0], label=c.inherit_default_permission_choices[0][1], **kwargs)}
82 ${h.radio('default_inherit_default_permissions' + suffix, c.inherit_default_permission_choices[0][0], label=c.inherit_default_permission_choices[0][1], **kwargs)}
83 <span class="help-block">${_('Inherit default permissions from the default user. Turn off this option to force explicit permissions for users, even if they are more restrictive than the default user permissions.')}</span>
83 <span class="help-block">${_('Inherit default permissions from the default user. Turn off this option to force explicit permissions for users, even if they are more restrictive than the default user permissions.')}</span>
84 </div>
84 </div>
85 </div>
85 </div>
86
86
87 <div class="buttons">
87 <div class="buttons">
88 ${h.submit('save',_('Save'),class_="btn")}
88 ${h.submit('save',_('Save'),class_="btn")}
89 ${h.reset('reset',_('Reset'),class_="btn")}
89 ${h.reset('reset',_('Reset'),class_="btn")}
90 </div>
90 </div>
91 </div>
91 </div>
92 </div>
92 </div>
93 </div>
93 </div>
94 </%def>
94 </%def>
95
95
96 <%def name="default_perms_box(form_url)">
96 <%def name="default_perms_box(form_url)">
97 ${h.secure_form(form_url, method='put')}
97 ${h.secure_form(form_url, method='put')}
98 <div class="form">
98 <div class="form">
99 <div class="fields">
99 <div class="fields">
100 <div class="field panel panel-default panel-body">
100 <div class="field panel panel-default panel-body">
101 <div class="label label-checkbox">
101 <div class="label label-checkbox">
102 <label for="inherit_default_permissions">${_('Inherit from default settings')}:</label>
102 <label for="inherit_default_permissions">${_('Inherit from default settings')}:</label>
103 </div>
103 </div>
104 <div class="checkboxes">
104 <div class="checkboxes">
105 ${h.checkbox('inherit_default_permissions',value=True)}
105 ${h.checkbox('inherit_default_permissions',value=True)}
106 <span class="help-block">
106 <span class="help-block">
107 ${h.literal(_('Select to inherit permissions from %s permissions settings, '
107 ${h.literal(_('Select to inherit permissions from %s permissions settings, '
108 'including default IP address whitelist and inheritance of \npermission by members of user groups.')
108 'including default IP address whitelist and inheritance of \npermission by members of user groups.')
109 % h.link_to('default user', url('admin_permissions_global')))}
109 % h.link_to('default user', h.url('admin_permissions_global')))}
110 </span>
110 </span>
111 </div>
111 </div>
112 </div>
112 </div>
113
113
114 ## INHERITED permissions == the user permissions in admin
114 ## INHERITED permissions == the user permissions in admin
115 ## if inherit checkbox is set this is displayed in non-edit mode
115 ## if inherit checkbox is set this is displayed in non-edit mode
116 <div class="inherit_overlay_default">
116 <div class="inherit_overlay_default">
117 ${default_perms_radios(global_permissions_template = False, suffix='_inherited', disabled="disabled")}
117 ${default_perms_radios(global_permissions_template = False, suffix='_inherited', disabled="disabled")}
118 </div>
118 </div>
119
119
120 ## CUSTOM permissions
120 ## CUSTOM permissions
121 <div class="inherit_overlay">
121 <div class="inherit_overlay">
122 ${default_perms_radios(global_permissions_template = False)}
122 ${default_perms_radios(global_permissions_template = False)}
123 </div>
123 </div>
124 </div>
124 </div>
125 </div>
125 </div>
126 ${h.end_form()}
126 ${h.end_form()}
127
127
128
128
129 ## JS
129 ## JS
130 <script>
130 <script>
131 var show_custom_perms = function(inherit_default){
131 var show_custom_perms = function(inherit_default){
132 if(inherit_default) {
132 if(inherit_default) {
133 $('.inherit_overlay_default').show();
133 $('.inherit_overlay_default').show();
134 $('.inherit_overlay').hide();
134 $('.inherit_overlay').hide();
135 }
135 }
136 else {
136 else {
137 $('.inherit_overlay').show();
137 $('.inherit_overlay').show();
138 $('.inherit_overlay_default').hide();
138 $('.inherit_overlay_default').hide();
139 }
139 }
140 };
140 };
141 $(document).ready(function(e){
141 $(document).ready(function(e){
142 var inherit_checkbox = $('#inherit_default_permissions');
142 var inherit_checkbox = $('#inherit_default_permissions');
143 var defaults = inherit_checkbox.prop('checked');
143 var defaults = inherit_checkbox.prop('checked');
144 show_custom_perms(defaults);
144 show_custom_perms(defaults);
145 inherit_checkbox.on('change', function(){
145 inherit_checkbox.on('change', function(){
146 if($(this).prop('checked')){
146 if($(this).prop('checked')){
147 show_custom_perms(true);
147 show_custom_perms(true);
148 }
148 }
149 else{
149 else{
150 show_custom_perms(false);
150 show_custom_perms(false);
151 }
151 }
152 })
152 })
153 })
153 })
154 </script>
154 </script>
155
155
156 </%def>
156 </%def>
@@ -1,351 +1,351 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 <%inherit file="/base/base.mako"/>
3 <%inherit file="/base/base.mako"/>
4 <%namespace name="diff_block" file="/changeset/diff_block.mako"/>
4 <%namespace name="diff_block" file="/changeset/diff_block.mako"/>
5
5
6 <%def name="title()">
6 <%def name="title()">
7 ${_('%s Commit') % c.repo_name} - ${h.show_id(c.commit)}
7 ${_('%s Commit') % c.repo_name} - ${h.show_id(c.commit)}
8 %if c.rhodecode_name:
8 %if c.rhodecode_name:
9 &middot; ${h.branding(c.rhodecode_name)}
9 &middot; ${h.branding(c.rhodecode_name)}
10 %endif
10 %endif
11 </%def>
11 </%def>
12
12
13 <%def name="menu_bar_nav()">
13 <%def name="menu_bar_nav()">
14 ${self.menu_items(active='repositories')}
14 ${self.menu_items(active='repositories')}
15 </%def>
15 </%def>
16
16
17 <%def name="menu_bar_subnav()">
17 <%def name="menu_bar_subnav()">
18 ${self.repo_menu(active='changelog')}
18 ${self.repo_menu(active='changelog')}
19 </%def>
19 </%def>
20
20
21 <%def name="main()">
21 <%def name="main()">
22 <script>
22 <script>
23 // TODO: marcink switch this to pyroutes
23 // TODO: marcink switch this to pyroutes
24 AJAX_COMMENT_DELETE_URL = "${url('changeset_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
24 AJAX_COMMENT_DELETE_URL = "${h.url('changeset_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
25 templateContext.commit_data.commit_id = "${c.commit.raw_id}";
25 templateContext.commit_data.commit_id = "${c.commit.raw_id}";
26 </script>
26 </script>
27 <div class="box">
27 <div class="box">
28 <div class="title">
28 <div class="title">
29 ${self.repo_page_title(c.rhodecode_db_repo)}
29 ${self.repo_page_title(c.rhodecode_db_repo)}
30 </div>
30 </div>
31
31
32 <div id="changeset_compare_view_content" class="summary changeset">
32 <div id="changeset_compare_view_content" class="summary changeset">
33 <div class="summary-detail">
33 <div class="summary-detail">
34 <div class="summary-detail-header">
34 <div class="summary-detail-header">
35 <span class="breadcrumbs files_location">
35 <span class="breadcrumbs files_location">
36 <h4>${_('Commit')}
36 <h4>${_('Commit')}
37 <code>
37 <code>
38 ${h.show_id(c.commit)}
38 ${h.show_id(c.commit)}
39 % if hasattr(c.commit, 'phase'):
39 % if hasattr(c.commit, 'phase'):
40 <span class="tag phase-${c.commit.phase} tooltip" title="${_('Commit phase')}">${c.commit.phase}</span>
40 <span class="tag phase-${c.commit.phase} tooltip" title="${_('Commit phase')}">${c.commit.phase}</span>
41 % endif
41 % endif
42
42
43 ## obsolete commits
43 ## obsolete commits
44 % if hasattr(c.commit, 'obsolete'):
44 % if hasattr(c.commit, 'obsolete'):
45 % if c.commit.obsolete:
45 % if c.commit.obsolete:
46 <span class="tag obsolete-${c.commit.obsolete} tooltip" title="${_('Evolve State')}">${_('obsolete')}</span>
46 <span class="tag obsolete-${c.commit.obsolete} tooltip" title="${_('Evolve State')}">${_('obsolete')}</span>
47 % endif
47 % endif
48 % endif
48 % endif
49
49
50 ## hidden commits
50 ## hidden commits
51 % if hasattr(c.commit, 'hidden'):
51 % if hasattr(c.commit, 'hidden'):
52 % if c.commit.hidden:
52 % if c.commit.hidden:
53 <span class="tag hidden-${c.commit.hidden} tooltip" title="${_('Evolve State')}">${_('hidden')}</span>
53 <span class="tag hidden-${c.commit.hidden} tooltip" title="${_('Evolve State')}">${_('hidden')}</span>
54 % endif
54 % endif
55 % endif
55 % endif
56
56
57 </code>
57 </code>
58 </h4>
58 </h4>
59 </span>
59 </span>
60 <div class="pull-right">
60 <div class="pull-right">
61 <span id="parent_link">
61 <span id="parent_link">
62 <a href="#" title="${_('Parent Commit')}">${_('Parent')}</a>
62 <a href="#" title="${_('Parent Commit')}">${_('Parent')}</a>
63 </span>
63 </span>
64 |
64 |
65 <span id="child_link">
65 <span id="child_link">
66 <a href="#" title="${_('Child Commit')}">${_('Child')}</a>
66 <a href="#" title="${_('Child Commit')}">${_('Child')}</a>
67 </span>
67 </span>
68 </div>
68 </div>
69 </div>
69 </div>
70
70
71 <div class="fieldset">
71 <div class="fieldset">
72 <div class="left-label">
72 <div class="left-label">
73 ${_('Description')}:
73 ${_('Description')}:
74 </div>
74 </div>
75 <div class="right-content">
75 <div class="right-content">
76 <div id="trimmed_message_box" class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
76 <div id="trimmed_message_box" class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div>
77 <div id="message_expand" style="display:none;">
77 <div id="message_expand" style="display:none;">
78 ${_('Expand')}
78 ${_('Expand')}
79 </div>
79 </div>
80 </div>
80 </div>
81 </div>
81 </div>
82
82
83 %if c.statuses:
83 %if c.statuses:
84 <div class="fieldset">
84 <div class="fieldset">
85 <div class="left-label">
85 <div class="left-label">
86 ${_('Commit status')}:
86 ${_('Commit status')}:
87 </div>
87 </div>
88 <div class="right-content">
88 <div class="right-content">
89 <div class="changeset-status-ico">
89 <div class="changeset-status-ico">
90 <div class="${'flag_status %s' % c.statuses[0]} pull-left"></div>
90 <div class="${'flag_status %s' % c.statuses[0]} pull-left"></div>
91 </div>
91 </div>
92 <div title="${_('Commit status')}" class="changeset-status-lbl">[${h.commit_status_lbl(c.statuses[0])}]</div>
92 <div title="${_('Commit status')}" class="changeset-status-lbl">[${h.commit_status_lbl(c.statuses[0])}]</div>
93 </div>
93 </div>
94 </div>
94 </div>
95 %endif
95 %endif
96
96
97 <div class="fieldset">
97 <div class="fieldset">
98 <div class="left-label">
98 <div class="left-label">
99 ${_('References')}:
99 ${_('References')}:
100 </div>
100 </div>
101 <div class="right-content">
101 <div class="right-content">
102 <div class="tags">
102 <div class="tags">
103
103
104 %if c.commit.merge:
104 %if c.commit.merge:
105 <span class="mergetag tag">
105 <span class="mergetag tag">
106 <i class="icon-merge"></i>${_('merge')}
106 <i class="icon-merge"></i>${_('merge')}
107 </span>
107 </span>
108 %endif
108 %endif
109
109
110 %if h.is_hg(c.rhodecode_repo):
110 %if h.is_hg(c.rhodecode_repo):
111 %for book in c.commit.bookmarks:
111 %for book in c.commit.bookmarks:
112 <span class="booktag tag" title="${h.tooltip(_('Bookmark %s') % book)}">
112 <span class="booktag tag" title="${h.tooltip(_('Bookmark %s') % book)}">
113 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-bookmark"></i>${h.shorter(book)}</a>
113 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-bookmark"></i>${h.shorter(book)}</a>
114 </span>
114 </span>
115 %endfor
115 %endfor
116 %endif
116 %endif
117
117
118 %for tag in c.commit.tags:
118 %for tag in c.commit.tags:
119 <span class="tagtag tag" title="${h.tooltip(_('Tag %s') % tag)}">
119 <span class="tagtag tag" title="${h.tooltip(_('Tag %s') % tag)}">
120 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-tag"></i>${tag}</a>
120 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-tag"></i>${tag}</a>
121 </span>
121 </span>
122 %endfor
122 %endfor
123
123
124 %if c.commit.branch:
124 %if c.commit.branch:
125 <span class="branchtag tag" title="${h.tooltip(_('Branch %s') % c.commit.branch)}">
125 <span class="branchtag tag" title="${h.tooltip(_('Branch %s') % c.commit.branch)}">
126 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-code-fork"></i>${h.shorter(c.commit.branch)}</a>
126 <a href="${h.url('files_home',repo_name=c.repo_name,revision=c.commit.raw_id)}"><i class="icon-code-fork"></i>${h.shorter(c.commit.branch)}</a>
127 </span>
127 </span>
128 %endif
128 %endif
129 </div>
129 </div>
130 </div>
130 </div>
131 </div>
131 </div>
132
132
133 <div class="fieldset">
133 <div class="fieldset">
134 <div class="left-label">
134 <div class="left-label">
135 ${_('Diff options')}:
135 ${_('Diff options')}:
136 </div>
136 </div>
137 <div class="right-content">
137 <div class="right-content">
138 <div class="diff-actions">
138 <div class="diff-actions">
139 <a href="${h.url('changeset_raw_home',repo_name=c.repo_name,revision=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Raw diff'))}">
139 <a href="${h.url('changeset_raw_home',repo_name=c.repo_name,revision=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Raw diff'))}">
140 ${_('Raw Diff')}
140 ${_('Raw Diff')}
141 </a>
141 </a>
142 |
142 |
143 <a href="${h.url('changeset_patch_home',repo_name=c.repo_name,revision=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Patch diff'))}">
143 <a href="${h.url('changeset_patch_home',repo_name=c.repo_name,revision=c.commit.raw_id)}" class="tooltip" title="${h.tooltip(_('Patch diff'))}">
144 ${_('Patch Diff')}
144 ${_('Patch Diff')}
145 </a>
145 </a>
146 |
146 |
147 <a href="${h.url('changeset_download_home',repo_name=c.repo_name,revision=c.commit.raw_id,diff='download')}" class="tooltip" title="${h.tooltip(_('Download diff'))}">
147 <a href="${h.url('changeset_download_home',repo_name=c.repo_name,revision=c.commit.raw_id,diff='download')}" class="tooltip" title="${h.tooltip(_('Download diff'))}">
148 ${_('Download Diff')}
148 ${_('Download Diff')}
149 </a>
149 </a>
150 |
150 |
151 ${c.ignorews_url(request.GET)}
151 ${c.ignorews_url(request.GET)}
152 |
152 |
153 ${c.context_url(request.GET)}
153 ${c.context_url(request.GET)}
154 </div>
154 </div>
155 </div>
155 </div>
156 </div>
156 </div>
157
157
158 <div class="fieldset">
158 <div class="fieldset">
159 <div class="left-label">
159 <div class="left-label">
160 ${_('Comments')}:
160 ${_('Comments')}:
161 </div>
161 </div>
162 <div class="right-content">
162 <div class="right-content">
163 <div class="comments-number">
163 <div class="comments-number">
164 %if c.comments:
164 %if c.comments:
165 <a href="#comments">${ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}</a>,
165 <a href="#comments">${ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}</a>,
166 %else:
166 %else:
167 ${ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}
167 ${ungettext("%d Commit comment", "%d Commit comments", len(c.comments)) % len(c.comments)}
168 %endif
168 %endif
169 %if c.inline_cnt:
169 %if c.inline_cnt:
170 <a href="#" onclick="return Rhodecode.comments.nextComment();" id="inline-comments-counter">${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}</a>
170 <a href="#" onclick="return Rhodecode.comments.nextComment();" id="inline-comments-counter">${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}</a>
171 %else:
171 %else:
172 ${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}
172 ${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}
173 %endif
173 %endif
174 </div>
174 </div>
175 </div>
175 </div>
176 </div>
176 </div>
177
177
178 <div class="fieldset">
178 <div class="fieldset">
179 <div class="left-label">
179 <div class="left-label">
180 ${_('Unresolved TODOs')}:
180 ${_('Unresolved TODOs')}:
181 </div>
181 </div>
182 <div class="right-content">
182 <div class="right-content">
183 <div class="comments-number">
183 <div class="comments-number">
184 % if c.unresolved_comments:
184 % if c.unresolved_comments:
185 % for co in c.unresolved_comments:
185 % for co in c.unresolved_comments:
186 <a class="permalink" href="#comment-${co.comment_id}" onclick="Rhodecode.comments.scrollToComment($('#comment-${co.comment_id}'))"> #${co.comment_id}</a>${'' if loop.last else ','}
186 <a class="permalink" href="#comment-${co.comment_id}" onclick="Rhodecode.comments.scrollToComment($('#comment-${co.comment_id}'))"> #${co.comment_id}</a>${'' if loop.last else ','}
187 % endfor
187 % endfor
188 % else:
188 % else:
189 ${_('There are no unresolved TODOs')}
189 ${_('There are no unresolved TODOs')}
190 % endif
190 % endif
191 </div>
191 </div>
192 </div>
192 </div>
193 </div>
193 </div>
194
194
195 </div> <!-- end summary-detail -->
195 </div> <!-- end summary-detail -->
196
196
197 <div id="commit-stats" class="sidebar-right">
197 <div id="commit-stats" class="sidebar-right">
198 <div class="summary-detail-header">
198 <div class="summary-detail-header">
199 <h4 class="item">
199 <h4 class="item">
200 ${_('Author')}
200 ${_('Author')}
201 </h4>
201 </h4>
202 </div>
202 </div>
203 <div class="sidebar-right-content">
203 <div class="sidebar-right-content">
204 ${self.gravatar_with_user(c.commit.author)}
204 ${self.gravatar_with_user(c.commit.author)}
205 <div class="user-inline-data">- ${h.age_component(c.commit.date)}</div>
205 <div class="user-inline-data">- ${h.age_component(c.commit.date)}</div>
206 </div>
206 </div>
207 </div><!-- end sidebar -->
207 </div><!-- end sidebar -->
208 </div> <!-- end summary -->
208 </div> <!-- end summary -->
209 <div class="cs_files">
209 <div class="cs_files">
210 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
210 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
211 ${cbdiffs.render_diffset_menu()}
211 ${cbdiffs.render_diffset_menu()}
212 ${cbdiffs.render_diffset(
212 ${cbdiffs.render_diffset(
213 c.changes[c.commit.raw_id], commit=c.commit, use_comments=True)}
213 c.changes[c.commit.raw_id], commit=c.commit, use_comments=True)}
214 </div>
214 </div>
215
215
216 ## template for inline comment form
216 ## template for inline comment form
217 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
217 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
218
218
219 ## render comments
219 ## render comments
220 ${comment.generate_comments(c.comments)}
220 ${comment.generate_comments(c.comments)}
221
221
222 ## main comment form and it status
222 ## main comment form and it status
223 ${comment.comments(h.url('changeset_comment', repo_name=c.repo_name, revision=c.commit.raw_id),
223 ${comment.comments(h.url('changeset_comment', repo_name=c.repo_name, revision=c.commit.raw_id),
224 h.commit_status(c.rhodecode_db_repo, c.commit.raw_id))}
224 h.commit_status(c.rhodecode_db_repo, c.commit.raw_id))}
225 </div>
225 </div>
226
226
227 ## FORM FOR MAKING JS ACTION AS CHANGESET COMMENTS
227 ## FORM FOR MAKING JS ACTION AS CHANGESET COMMENTS
228 <script type="text/javascript">
228 <script type="text/javascript">
229
229
230 $(document).ready(function() {
230 $(document).ready(function() {
231
231
232 var boxmax = parseInt($('#trimmed_message_box').css('max-height'), 10);
232 var boxmax = parseInt($('#trimmed_message_box').css('max-height'), 10);
233 if($('#trimmed_message_box').height() === boxmax){
233 if($('#trimmed_message_box').height() === boxmax){
234 $('#message_expand').show();
234 $('#message_expand').show();
235 }
235 }
236
236
237 $('#message_expand').on('click', function(e){
237 $('#message_expand').on('click', function(e){
238 $('#trimmed_message_box').css('max-height', 'none');
238 $('#trimmed_message_box').css('max-height', 'none');
239 $(this).hide();
239 $(this).hide();
240 });
240 });
241
241
242 $('.show-inline-comments').on('click', function(e){
242 $('.show-inline-comments').on('click', function(e){
243 var boxid = $(this).attr('data-comment-id');
243 var boxid = $(this).attr('data-comment-id');
244 var button = $(this);
244 var button = $(this);
245
245
246 if(button.hasClass("comments-visible")) {
246 if(button.hasClass("comments-visible")) {
247 $('#{0} .inline-comments'.format(boxid)).each(function(index){
247 $('#{0} .inline-comments'.format(boxid)).each(function(index){
248 $(this).hide();
248 $(this).hide();
249 });
249 });
250 button.removeClass("comments-visible");
250 button.removeClass("comments-visible");
251 } else {
251 } else {
252 $('#{0} .inline-comments'.format(boxid)).each(function(index){
252 $('#{0} .inline-comments'.format(boxid)).each(function(index){
253 $(this).show();
253 $(this).show();
254 });
254 });
255 button.addClass("comments-visible");
255 button.addClass("comments-visible");
256 }
256 }
257 });
257 });
258
258
259
259
260 // next links
260 // next links
261 $('#child_link').on('click', function(e){
261 $('#child_link').on('click', function(e){
262 // fetch via ajax what is going to be the next link, if we have
262 // fetch via ajax what is going to be the next link, if we have
263 // >1 links show them to user to choose
263 // >1 links show them to user to choose
264 if(!$('#child_link').hasClass('disabled')){
264 if(!$('#child_link').hasClass('disabled')){
265 $.ajax({
265 $.ajax({
266 url: '${h.url('changeset_children',repo_name=c.repo_name, revision=c.commit.raw_id)}',
266 url: '${h.url('changeset_children',repo_name=c.repo_name, revision=c.commit.raw_id)}',
267 success: function(data) {
267 success: function(data) {
268 if(data.results.length === 0){
268 if(data.results.length === 0){
269 $('#child_link').html("${_('No Child Commits')}").addClass('disabled');
269 $('#child_link').html("${_('No Child Commits')}").addClass('disabled');
270 }
270 }
271 if(data.results.length === 1){
271 if(data.results.length === 1){
272 var commit = data.results[0];
272 var commit = data.results[0];
273 window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id});
273 window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id});
274 }
274 }
275 else if(data.results.length === 2){
275 else if(data.results.length === 2){
276 $('#child_link').addClass('disabled');
276 $('#child_link').addClass('disabled');
277 $('#child_link').addClass('double');
277 $('#child_link').addClass('double');
278 var _html = '';
278 var _html = '';
279 _html +='<a title="__title__" href="__url__">__rev__</a> '
279 _html +='<a title="__title__" href="__url__">__rev__</a> '
280 .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6)))
280 .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6)))
281 .replace('__title__', data.results[0].message)
281 .replace('__title__', data.results[0].message)
282 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id}));
282 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id}));
283 _html +=' | ';
283 _html +=' | ';
284 _html +='<a title="__title__" href="__url__">__rev__</a> '
284 _html +='<a title="__title__" href="__url__">__rev__</a> '
285 .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6)))
285 .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6)))
286 .replace('__title__', data.results[1].message)
286 .replace('__title__', data.results[1].message)
287 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id}));
287 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id}));
288 $('#child_link').html(_html);
288 $('#child_link').html(_html);
289 }
289 }
290 }
290 }
291 });
291 });
292 e.preventDefault();
292 e.preventDefault();
293 }
293 }
294 });
294 });
295
295
296 // prev links
296 // prev links
297 $('#parent_link').on('click', function(e){
297 $('#parent_link').on('click', function(e){
298 // fetch via ajax what is going to be the next link, if we have
298 // fetch via ajax what is going to be the next link, if we have
299 // >1 links show them to user to choose
299 // >1 links show them to user to choose
300 if(!$('#parent_link').hasClass('disabled')){
300 if(!$('#parent_link').hasClass('disabled')){
301 $.ajax({
301 $.ajax({
302 url: '${h.url("changeset_parents",repo_name=c.repo_name, revision=c.commit.raw_id)}',
302 url: '${h.url("changeset_parents",repo_name=c.repo_name, revision=c.commit.raw_id)}',
303 success: function(data) {
303 success: function(data) {
304 if(data.results.length === 0){
304 if(data.results.length === 0){
305 $('#parent_link').html('${_('No Parent Commits')}').addClass('disabled');
305 $('#parent_link').html('${_('No Parent Commits')}').addClass('disabled');
306 }
306 }
307 if(data.results.length === 1){
307 if(data.results.length === 1){
308 var commit = data.results[0];
308 var commit = data.results[0];
309 window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id});
309 window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id});
310 }
310 }
311 else if(data.results.length === 2){
311 else if(data.results.length === 2){
312 $('#parent_link').addClass('disabled');
312 $('#parent_link').addClass('disabled');
313 $('#parent_link').addClass('double');
313 $('#parent_link').addClass('double');
314 var _html = '';
314 var _html = '';
315 _html +='<a title="__title__" href="__url__">Parent __rev__</a>'
315 _html +='<a title="__title__" href="__url__">Parent __rev__</a>'
316 .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6)))
316 .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6)))
317 .replace('__title__', data.results[0].message)
317 .replace('__title__', data.results[0].message)
318 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id}));
318 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id}));
319 _html +=' | ';
319 _html +=' | ';
320 _html +='<a title="__title__" href="__url__">Parent __rev__</a>'
320 _html +='<a title="__title__" href="__url__">Parent __rev__</a>'
321 .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6)))
321 .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6)))
322 .replace('__title__', data.results[1].message)
322 .replace('__title__', data.results[1].message)
323 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id}));
323 .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id}));
324 $('#parent_link').html(_html);
324 $('#parent_link').html(_html);
325 }
325 }
326 }
326 }
327 });
327 });
328 e.preventDefault();
328 e.preventDefault();
329 }
329 }
330 });
330 });
331
331
332 if (location.hash) {
332 if (location.hash) {
333 var result = splitDelimitedHash(location.hash);
333 var result = splitDelimitedHash(location.hash);
334 var line = $('html').find(result.loc);
334 var line = $('html').find(result.loc);
335 if (line.length > 0){
335 if (line.length > 0){
336 offsetScroll(line, 70);
336 offsetScroll(line, 70);
337 }
337 }
338 }
338 }
339
339
340 // browse tree @ revision
340 // browse tree @ revision
341 $('#files_link').on('click', function(e){
341 $('#files_link').on('click', function(e){
342 window.location = '${h.url('files_home',repo_name=c.repo_name, revision=c.commit.raw_id, f_path='')}';
342 window.location = '${h.url('files_home',repo_name=c.repo_name, revision=c.commit.raw_id, f_path='')}';
343 e.preventDefault();
343 e.preventDefault();
344 });
344 });
345
345
346 // inject comments into their proper positions
346 // inject comments into their proper positions
347 var file_comments = $('.inline-comment-placeholder');
347 var file_comments = $('.inline-comment-placeholder');
348 })
348 })
349 </script>
349 </script>
350
350
351 </%def>
351 </%def>
@@ -1,129 +1,129 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 ${_('Fork repository %s') % c.repo_name}
5 ${_('Fork repository %s') % c.repo_name}
6 %if c.rhodecode_name:
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()">
12 ${_('New Fork')}
12 ${_('New Fork')}
13 </%def>
13 </%def>
14
14
15 <%def name="menu_bar_nav()">
15 <%def name="menu_bar_nav()">
16 ${self.menu_items(active='repositories')}
16 ${self.menu_items(active='repositories')}
17 </%def>
17 </%def>
18
18
19 <%def name="menu_bar_subnav()">
19 <%def name="menu_bar_subnav()">
20 ${self.repo_menu(active='options')}
20 ${self.repo_menu(active='options')}
21 </%def>
21 </%def>
22
22
23 <%def name="main()">
23 <%def name="main()">
24 <div class="box">
24 <div class="box">
25 <div class="title">
25 <div class="title">
26 ${self.repo_page_title(c.rhodecode_db_repo)}
26 ${self.repo_page_title(c.rhodecode_db_repo)}
27 ${self.breadcrumbs()}
27 ${self.breadcrumbs()}
28 </div>
28 </div>
29
29
30 ${h.secure_form(url('repo_fork_create_home',repo_name=c.repo_info.repo_name))}
30 ${h.secure_form(h.url('repo_fork_create_home',repo_name=c.repo_info.repo_name))}
31 <div class="form">
31 <div class="form">
32 <!-- fields -->
32 <!-- fields -->
33 <div class="fields">
33 <div class="fields">
34
34
35 <div class="field">
35 <div class="field">
36 <div class="label">
36 <div class="label">
37 <label for="repo_name">${_('Fork name')}:</label>
37 <label for="repo_name">${_('Fork name')}:</label>
38 </div>
38 </div>
39 <div class="input">
39 <div class="input">
40 ${h.text('repo_name', class_="medium")}
40 ${h.text('repo_name', class_="medium")}
41 ${h.hidden('repo_type',c.repo_info.repo_type)}
41 ${h.hidden('repo_type',c.repo_info.repo_type)}
42 ${h.hidden('fork_parent_id',c.repo_info.repo_id)}
42 ${h.hidden('fork_parent_id',c.repo_info.repo_id)}
43 </div>
43 </div>
44 </div>
44 </div>
45
45
46 <div class="field">
46 <div class="field">
47 <div class="label label-textarea">
47 <div class="label label-textarea">
48 <label for="description">${_('Description')}:</label>
48 <label for="description">${_('Description')}:</label>
49 </div>
49 </div>
50 <div class="textarea-repo textarea text-area editor">
50 <div class="textarea-repo textarea text-area editor">
51 ${h.textarea('description')}
51 ${h.textarea('description')}
52 <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
52 <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
53 </div>
53 </div>
54 </div>
54 </div>
55
55
56 <div class="field">
56 <div class="field">
57 <div class="label">
57 <div class="label">
58 <label for="repo_group">${_('Repository group')}:</label>
58 <label for="repo_group">${_('Repository group')}:</label>
59 </div>
59 </div>
60 <div class="select">
60 <div class="select">
61 ${h.select('repo_group','',c.repo_groups,class_="medium")}
61 ${h.select('repo_group','',c.repo_groups,class_="medium")}
62 % if c.personal_repo_group:
62 % if c.personal_repo_group:
63 <a class="btn" href="#" id="select_my_group" data-personal-group-id="${c.personal_repo_group.group_id}">
63 <a class="btn" href="#" id="select_my_group" data-personal-group-id="${c.personal_repo_group.group_id}">
64 ${_('Select my personal group (%(repo_group_name)s)') % {'repo_group_name': c.personal_repo_group.group_name}}
64 ${_('Select my personal group (%(repo_group_name)s)') % {'repo_group_name': c.personal_repo_group.group_name}}
65 </a>
65 </a>
66 % endif
66 % endif
67 <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
67 <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
68 </div>
68 </div>
69 </div>
69 </div>
70
70
71 <div class="field">
71 <div class="field">
72 <div class="label">
72 <div class="label">
73 <label for="landing_rev">${_('Landing commit')}:</label>
73 <label for="landing_rev">${_('Landing commit')}:</label>
74 </div>
74 </div>
75 <div class="select">
75 <div class="select">
76 ${h.select('landing_rev','',c.landing_revs,class_="medium")}
76 ${h.select('landing_rev','',c.landing_revs,class_="medium")}
77 <span class="help-block">${_('Default commit for files page, downloads, whoosh and readme')}</span>
77 <span class="help-block">${_('Default commit for files page, downloads, whoosh and readme')}</span>
78 </div>
78 </div>
79 </div>
79 </div>
80
80
81 <div class="field">
81 <div class="field">
82 <div class="label label-checkbox">
82 <div class="label label-checkbox">
83 <label for="private">${_('Private')}:</label>
83 <label for="private">${_('Private')}:</label>
84 </div>
84 </div>
85 <div class="checkboxes">
85 <div class="checkboxes">
86 ${h.checkbox('private',value="True")}
86 ${h.checkbox('private',value="True")}
87 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
87 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
88 </div>
88 </div>
89 </div>
89 </div>
90
90
91 <div class="field">
91 <div class="field">
92 <div class="label label-checkbox">
92 <div class="label label-checkbox">
93 <label for="private">${_('Copy permissions')}:</label>
93 <label for="private">${_('Copy permissions')}:</label>
94 </div>
94 </div>
95 <div class="checkboxes">
95 <div class="checkboxes">
96 ${h.checkbox('copy_permissions',value="True", checked="checked")}
96 ${h.checkbox('copy_permissions',value="True", checked="checked")}
97 <span class="help-block">${_('Copy permissions from forked repository')}</span>
97 <span class="help-block">${_('Copy permissions from forked repository')}</span>
98 </div>
98 </div>
99 </div>
99 </div>
100
100
101 <div class="buttons">
101 <div class="buttons">
102 ${h.submit('',_('Fork this Repository'),class_="btn")}
102 ${h.submit('',_('Fork this Repository'),class_="btn")}
103 </div>
103 </div>
104 </div>
104 </div>
105 </div>
105 </div>
106 ${h.end_form()}
106 ${h.end_form()}
107 </div>
107 </div>
108 <script>
108 <script>
109 $(document).ready(function(){
109 $(document).ready(function(){
110 $("#repo_group").select2({
110 $("#repo_group").select2({
111 'dropdownAutoWidth': true,
111 'dropdownAutoWidth': true,
112 'containerCssClass': "drop-menu",
112 'containerCssClass': "drop-menu",
113 'dropdownCssClass': "drop-menu-dropdown",
113 'dropdownCssClass': "drop-menu-dropdown",
114 'width': "resolve"
114 'width': "resolve"
115 });
115 });
116 $("#landing_rev").select2({
116 $("#landing_rev").select2({
117 'containerCssClass': "drop-menu",
117 'containerCssClass': "drop-menu",
118 'dropdownCssClass': "drop-menu-dropdown",
118 'dropdownCssClass': "drop-menu-dropdown",
119 'minimumResultsForSearch': -1
119 'minimumResultsForSearch': -1
120 });
120 });
121 $('#repo_name').focus();
121 $('#repo_name').focus();
122
122
123 $('#select_my_group').on('click', function(e){
123 $('#select_my_group').on('click', function(e){
124 e.preventDefault();
124 e.preventDefault();
125 $("#repo_group").val($(this).data('personalGroupId')).trigger("change");
125 $("#repo_group").val($(this).data('personalGroupId')).trigger("change");
126 })
126 })
127 })
127 })
128 </script>
128 </script>
129 </%def>
129 </%def>
@@ -1,526 +1,526 b''
1 <%inherit file="/base/base.mako"/>
1 <%inherit file="/base/base.mako"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${c.repo_name} ${_('New pull request')}
4 ${c.repo_name} ${_('New pull request')}
5 </%def>
5 </%def>
6
6
7 <%def name="breadcrumbs_links()">
7 <%def name="breadcrumbs_links()">
8 ${_('New pull request')}
8 ${_('New pull request')}
9 </%def>
9 </%def>
10
10
11 <%def name="menu_bar_nav()">
11 <%def name="menu_bar_nav()">
12 ${self.menu_items(active='repositories')}
12 ${self.menu_items(active='repositories')}
13 </%def>
13 </%def>
14
14
15 <%def name="menu_bar_subnav()">
15 <%def name="menu_bar_subnav()">
16 ${self.repo_menu(active='showpullrequest')}
16 ${self.repo_menu(active='showpullrequest')}
17 </%def>
17 </%def>
18
18
19 <%def name="main()">
19 <%def name="main()">
20 <div class="box">
20 <div class="box">
21 <div class="title">
21 <div class="title">
22 ${self.repo_page_title(c.rhodecode_db_repo)}
22 ${self.repo_page_title(c.rhodecode_db_repo)}
23 </div>
23 </div>
24
24
25 ${h.secure_form(url('pullrequest', repo_name=c.repo_name), method='post', id='pull_request_form')}
25 ${h.secure_form(h.url('pullrequest', repo_name=c.repo_name), method='post', id='pull_request_form')}
26
26
27 ${self.breadcrumbs()}
27 ${self.breadcrumbs()}
28
28
29 <div class="box pr-summary">
29 <div class="box pr-summary">
30
30
31 <div class="summary-details block-left">
31 <div class="summary-details block-left">
32
32
33
33
34 <div class="pr-details-title">
34 <div class="pr-details-title">
35 ${_('Pull request summary')}
35 ${_('Pull request summary')}
36 </div>
36 </div>
37
37
38 <div class="form" style="padding-top: 10px">
38 <div class="form" style="padding-top: 10px">
39 <!-- fields -->
39 <!-- fields -->
40
40
41 <div class="fields" >
41 <div class="fields" >
42
42
43 <div class="field">
43 <div class="field">
44 <div class="label">
44 <div class="label">
45 <label for="pullrequest_title">${_('Title')}:</label>
45 <label for="pullrequest_title">${_('Title')}:</label>
46 </div>
46 </div>
47 <div class="input">
47 <div class="input">
48 ${h.text('pullrequest_title', c.default_title, class_="medium autogenerated-title")}
48 ${h.text('pullrequest_title', c.default_title, class_="medium autogenerated-title")}
49 </div>
49 </div>
50 </div>
50 </div>
51
51
52 <div class="field">
52 <div class="field">
53 <div class="label label-textarea">
53 <div class="label label-textarea">
54 <label for="pullrequest_desc">${_('Description')}:</label>
54 <label for="pullrequest_desc">${_('Description')}:</label>
55 </div>
55 </div>
56 <div class="textarea text-area editor">
56 <div class="textarea text-area editor">
57 ${h.textarea('pullrequest_desc',size=30, )}
57 ${h.textarea('pullrequest_desc',size=30, )}
58 <span class="help-block">${_('Write a short description on this pull request')}</span>
58 <span class="help-block">${_('Write a short description on this pull request')}</span>
59 </div>
59 </div>
60 </div>
60 </div>
61
61
62 <div class="field">
62 <div class="field">
63 <div class="label label-textarea">
63 <div class="label label-textarea">
64 <label for="pullrequest_desc">${_('Commit flow')}:</label>
64 <label for="pullrequest_desc">${_('Commit flow')}:</label>
65 </div>
65 </div>
66
66
67 ## TODO: johbo: Abusing the "content" class here to get the
67 ## TODO: johbo: Abusing the "content" class here to get the
68 ## desired effect. Should be replaced by a proper solution.
68 ## desired effect. Should be replaced by a proper solution.
69
69
70 ##ORG
70 ##ORG
71 <div class="content">
71 <div class="content">
72 <strong>${_('Source repository')}:</strong>
72 <strong>${_('Source repository')}:</strong>
73 ${c.rhodecode_db_repo.description}
73 ${c.rhodecode_db_repo.description}
74 </div>
74 </div>
75 <div class="content">
75 <div class="content">
76 ${h.hidden('source_repo')}
76 ${h.hidden('source_repo')}
77 ${h.hidden('source_ref')}
77 ${h.hidden('source_ref')}
78 </div>
78 </div>
79
79
80 ##OTHER, most Probably the PARENT OF THIS FORK
80 ##OTHER, most Probably the PARENT OF THIS FORK
81 <div class="content">
81 <div class="content">
82 ## filled with JS
82 ## filled with JS
83 <div id="target_repo_desc"></div>
83 <div id="target_repo_desc"></div>
84 </div>
84 </div>
85
85
86 <div class="content">
86 <div class="content">
87 ${h.hidden('target_repo')}
87 ${h.hidden('target_repo')}
88 ${h.hidden('target_ref')}
88 ${h.hidden('target_ref')}
89 <span id="target_ref_loading" style="display: none">
89 <span id="target_ref_loading" style="display: none">
90 ${_('Loading refs...')}
90 ${_('Loading refs...')}
91 </span>
91 </span>
92 </div>
92 </div>
93 </div>
93 </div>
94
94
95 <div class="field">
95 <div class="field">
96 <div class="label label-textarea">
96 <div class="label label-textarea">
97 <label for="pullrequest_submit"></label>
97 <label for="pullrequest_submit"></label>
98 </div>
98 </div>
99 <div class="input">
99 <div class="input">
100 <div class="pr-submit-button">
100 <div class="pr-submit-button">
101 ${h.submit('save',_('Submit Pull Request'),class_="btn")}
101 ${h.submit('save',_('Submit Pull Request'),class_="btn")}
102 </div>
102 </div>
103 <div id="pr_open_message"></div>
103 <div id="pr_open_message"></div>
104 </div>
104 </div>
105 </div>
105 </div>
106
106
107 <div class="pr-spacing-container"></div>
107 <div class="pr-spacing-container"></div>
108 </div>
108 </div>
109 </div>
109 </div>
110 </div>
110 </div>
111 <div>
111 <div>
112 ## AUTHOR
112 ## AUTHOR
113 <div class="reviewers-title block-right">
113 <div class="reviewers-title block-right">
114 <div class="pr-details-title">
114 <div class="pr-details-title">
115 ${_('Author of this pull request')}
115 ${_('Author of this pull request')}
116 </div>
116 </div>
117 </div>
117 </div>
118 <div class="block-right pr-details-content reviewers">
118 <div class="block-right pr-details-content reviewers">
119 <ul class="group_members">
119 <ul class="group_members">
120 <li>
120 <li>
121 ${self.gravatar_with_user(c.rhodecode_user.email, 16)}
121 ${self.gravatar_with_user(c.rhodecode_user.email, 16)}
122 </li>
122 </li>
123 </ul>
123 </ul>
124 </div>
124 </div>
125
125
126 ## REVIEW RULES
126 ## REVIEW RULES
127 <div id="review_rules" style="display: none" class="reviewers-title block-right">
127 <div id="review_rules" style="display: none" class="reviewers-title block-right">
128 <div class="pr-details-title">
128 <div class="pr-details-title">
129 ${_('Reviewer rules')}
129 ${_('Reviewer rules')}
130 </div>
130 </div>
131 <div class="pr-reviewer-rules">
131 <div class="pr-reviewer-rules">
132 ## review rules will be appended here, by default reviewers logic
132 ## review rules will be appended here, by default reviewers logic
133 </div>
133 </div>
134 </div>
134 </div>
135
135
136 ## REVIEWERS
136 ## REVIEWERS
137 <div class="reviewers-title block-right">
137 <div class="reviewers-title block-right">
138 <div class="pr-details-title">
138 <div class="pr-details-title">
139 ${_('Pull request reviewers')}
139 ${_('Pull request reviewers')}
140 <span class="calculate-reviewers"> - ${_('loading...')}</span>
140 <span class="calculate-reviewers"> - ${_('loading...')}</span>
141 </div>
141 </div>
142 </div>
142 </div>
143 <div id="reviewers" class="block-right pr-details-content reviewers">
143 <div id="reviewers" class="block-right pr-details-content reviewers">
144 ## members goes here, filled via JS based on initial selection !
144 ## members goes here, filled via JS based on initial selection !
145 <input type="hidden" name="__start__" value="review_members:sequence">
145 <input type="hidden" name="__start__" value="review_members:sequence">
146 <ul id="review_members" class="group_members"></ul>
146 <ul id="review_members" class="group_members"></ul>
147 <input type="hidden" name="__end__" value="review_members:sequence">
147 <input type="hidden" name="__end__" value="review_members:sequence">
148 <div id="add_reviewer_input" class='ac'>
148 <div id="add_reviewer_input" class='ac'>
149 <div class="reviewer_ac">
149 <div class="reviewer_ac">
150 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))}
150 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))}
151 <div id="reviewers_container"></div>
151 <div id="reviewers_container"></div>
152 </div>
152 </div>
153 </div>
153 </div>
154 </div>
154 </div>
155 </div>
155 </div>
156 </div>
156 </div>
157 <div class="box">
157 <div class="box">
158 <div>
158 <div>
159 ## overview pulled by ajax
159 ## overview pulled by ajax
160 <div id="pull_request_overview"></div>
160 <div id="pull_request_overview"></div>
161 </div>
161 </div>
162 </div>
162 </div>
163 ${h.end_form()}
163 ${h.end_form()}
164 </div>
164 </div>
165
165
166 <script type="text/javascript">
166 <script type="text/javascript">
167 $(function(){
167 $(function(){
168 var defaultSourceRepo = '${c.default_repo_data['source_repo_name']}';
168 var defaultSourceRepo = '${c.default_repo_data['source_repo_name']}';
169 var defaultSourceRepoData = ${c.default_repo_data['source_refs_json']|n};
169 var defaultSourceRepoData = ${c.default_repo_data['source_refs_json']|n};
170 var defaultTargetRepo = '${c.default_repo_data['target_repo_name']}';
170 var defaultTargetRepo = '${c.default_repo_data['target_repo_name']}';
171 var defaultTargetRepoData = ${c.default_repo_data['target_refs_json']|n};
171 var defaultTargetRepoData = ${c.default_repo_data['target_refs_json']|n};
172
172
173 var $pullRequestForm = $('#pull_request_form');
173 var $pullRequestForm = $('#pull_request_form');
174 var $sourceRepo = $('#source_repo', $pullRequestForm);
174 var $sourceRepo = $('#source_repo', $pullRequestForm);
175 var $targetRepo = $('#target_repo', $pullRequestForm);
175 var $targetRepo = $('#target_repo', $pullRequestForm);
176 var $sourceRef = $('#source_ref', $pullRequestForm);
176 var $sourceRef = $('#source_ref', $pullRequestForm);
177 var $targetRef = $('#target_ref', $pullRequestForm);
177 var $targetRef = $('#target_ref', $pullRequestForm);
178
178
179 var sourceRepo = function() { return $sourceRepo.eq(0).val() };
179 var sourceRepo = function() { return $sourceRepo.eq(0).val() };
180 var sourceRef = function() { return $sourceRef.eq(0).val().split(':') };
180 var sourceRef = function() { return $sourceRef.eq(0).val().split(':') };
181
181
182 var targetRepo = function() { return $targetRepo.eq(0).val() };
182 var targetRepo = function() { return $targetRepo.eq(0).val() };
183 var targetRef = function() { return $targetRef.eq(0).val().split(':') };
183 var targetRef = function() { return $targetRef.eq(0).val().split(':') };
184
184
185 var calculateContainerWidth = function() {
185 var calculateContainerWidth = function() {
186 var maxWidth = 0;
186 var maxWidth = 0;
187 var repoSelect2Containers = ['#source_repo', '#target_repo'];
187 var repoSelect2Containers = ['#source_repo', '#target_repo'];
188 $.each(repoSelect2Containers, function(idx, value) {
188 $.each(repoSelect2Containers, function(idx, value) {
189 $(value).select2('container').width('auto');
189 $(value).select2('container').width('auto');
190 var curWidth = $(value).select2('container').width();
190 var curWidth = $(value).select2('container').width();
191 if (maxWidth <= curWidth) {
191 if (maxWidth <= curWidth) {
192 maxWidth = curWidth;
192 maxWidth = curWidth;
193 }
193 }
194 $.each(repoSelect2Containers, function(idx, value) {
194 $.each(repoSelect2Containers, function(idx, value) {
195 $(value).select2('container').width(maxWidth + 10);
195 $(value).select2('container').width(maxWidth + 10);
196 });
196 });
197 });
197 });
198 };
198 };
199
199
200 var initRefSelection = function(selectedRef) {
200 var initRefSelection = function(selectedRef) {
201 return function(element, callback) {
201 return function(element, callback) {
202 // translate our select2 id into a text, it's a mapping to show
202 // translate our select2 id into a text, it's a mapping to show
203 // simple label when selecting by internal ID.
203 // simple label when selecting by internal ID.
204 var id, refData;
204 var id, refData;
205 if (selectedRef === undefined) {
205 if (selectedRef === undefined) {
206 id = element.val();
206 id = element.val();
207 refData = element.val().split(':');
207 refData = element.val().split(':');
208 } else {
208 } else {
209 id = selectedRef;
209 id = selectedRef;
210 refData = selectedRef.split(':');
210 refData = selectedRef.split(':');
211 }
211 }
212
212
213 var text = refData[1];
213 var text = refData[1];
214 if (refData[0] === 'rev') {
214 if (refData[0] === 'rev') {
215 text = text.substring(0, 12);
215 text = text.substring(0, 12);
216 }
216 }
217
217
218 var data = {id: id, text: text};
218 var data = {id: id, text: text};
219
219
220 callback(data);
220 callback(data);
221 };
221 };
222 };
222 };
223
223
224 var formatRefSelection = function(item) {
224 var formatRefSelection = function(item) {
225 var prefix = '';
225 var prefix = '';
226 var refData = item.id.split(':');
226 var refData = item.id.split(':');
227 if (refData[0] === 'branch') {
227 if (refData[0] === 'branch') {
228 prefix = '<i class="icon-branch"></i>';
228 prefix = '<i class="icon-branch"></i>';
229 }
229 }
230 else if (refData[0] === 'book') {
230 else if (refData[0] === 'book') {
231 prefix = '<i class="icon-bookmark"></i>';
231 prefix = '<i class="icon-bookmark"></i>';
232 }
232 }
233 else if (refData[0] === 'tag') {
233 else if (refData[0] === 'tag') {
234 prefix = '<i class="icon-tag"></i>';
234 prefix = '<i class="icon-tag"></i>';
235 }
235 }
236
236
237 var originalOption = item.element;
237 var originalOption = item.element;
238 return prefix + item.text;
238 return prefix + item.text;
239 };
239 };
240
240
241 // custom code mirror
241 // custom code mirror
242 var codeMirrorInstance = initPullRequestsCodeMirror('#pullrequest_desc');
242 var codeMirrorInstance = initPullRequestsCodeMirror('#pullrequest_desc');
243
243
244 reviewersController = new ReviewersController();
244 reviewersController = new ReviewersController();
245
245
246 var queryTargetRepo = function(self, query) {
246 var queryTargetRepo = function(self, query) {
247 // cache ALL results if query is empty
247 // cache ALL results if query is empty
248 var cacheKey = query.term || '__';
248 var cacheKey = query.term || '__';
249 var cachedData = self.cachedDataSource[cacheKey];
249 var cachedData = self.cachedDataSource[cacheKey];
250
250
251 if (cachedData) {
251 if (cachedData) {
252 query.callback({results: cachedData.results});
252 query.callback({results: cachedData.results});
253 } else {
253 } else {
254 $.ajax({
254 $.ajax({
255 url: pyroutes.url('pullrequest_repo_destinations', {'repo_name': templateContext.repo_name}),
255 url: pyroutes.url('pullrequest_repo_destinations', {'repo_name': templateContext.repo_name}),
256 data: {query: query.term},
256 data: {query: query.term},
257 dataType: 'json',
257 dataType: 'json',
258 type: 'GET',
258 type: 'GET',
259 success: function(data) {
259 success: function(data) {
260 self.cachedDataSource[cacheKey] = data;
260 self.cachedDataSource[cacheKey] = data;
261 query.callback({results: data.results});
261 query.callback({results: data.results});
262 },
262 },
263 error: function(data, textStatus, errorThrown) {
263 error: function(data, textStatus, errorThrown) {
264 alert(
264 alert(
265 "Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
265 "Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
266 }
266 }
267 });
267 });
268 }
268 }
269 };
269 };
270
270
271 var queryTargetRefs = function(initialData, query) {
271 var queryTargetRefs = function(initialData, query) {
272 var data = {results: []};
272 var data = {results: []};
273 // filter initialData
273 // filter initialData
274 $.each(initialData, function() {
274 $.each(initialData, function() {
275 var section = this.text;
275 var section = this.text;
276 var children = [];
276 var children = [];
277 $.each(this.children, function() {
277 $.each(this.children, function() {
278 if (query.term.length === 0 ||
278 if (query.term.length === 0 ||
279 this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ) {
279 this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ) {
280 children.push({'id': this.id, 'text': this.text})
280 children.push({'id': this.id, 'text': this.text})
281 }
281 }
282 });
282 });
283 data.results.push({'text': section, 'children': children})
283 data.results.push({'text': section, 'children': children})
284 });
284 });
285 query.callback({results: data.results});
285 query.callback({results: data.results});
286 };
286 };
287
287
288 var loadRepoRefDiffPreview = function() {
288 var loadRepoRefDiffPreview = function() {
289
289
290 var url_data = {
290 var url_data = {
291 'repo_name': targetRepo(),
291 'repo_name': targetRepo(),
292 'target_repo': sourceRepo(),
292 'target_repo': sourceRepo(),
293 'source_ref': targetRef()[2],
293 'source_ref': targetRef()[2],
294 'source_ref_type': 'rev',
294 'source_ref_type': 'rev',
295 'target_ref': sourceRef()[2],
295 'target_ref': sourceRef()[2],
296 'target_ref_type': 'rev',
296 'target_ref_type': 'rev',
297 'merge': true,
297 'merge': true,
298 '_': Date.now() // bypass browser caching
298 '_': Date.now() // bypass browser caching
299 }; // gather the source/target ref and repo here
299 }; // gather the source/target ref and repo here
300
300
301 if (sourceRef().length !== 3 || targetRef().length !== 3) {
301 if (sourceRef().length !== 3 || targetRef().length !== 3) {
302 prButtonLock(true, "${_('Please select source and target')}");
302 prButtonLock(true, "${_('Please select source and target')}");
303 return;
303 return;
304 }
304 }
305 var url = pyroutes.url('compare_url', url_data);
305 var url = pyroutes.url('compare_url', url_data);
306
306
307 // lock PR button, so we cannot send PR before it's calculated
307 // lock PR button, so we cannot send PR before it's calculated
308 prButtonLock(true, "${_('Loading compare ...')}", 'compare');
308 prButtonLock(true, "${_('Loading compare ...')}", 'compare');
309
309
310 if (loadRepoRefDiffPreview._currentRequest) {
310 if (loadRepoRefDiffPreview._currentRequest) {
311 loadRepoRefDiffPreview._currentRequest.abort();
311 loadRepoRefDiffPreview._currentRequest.abort();
312 }
312 }
313
313
314 loadRepoRefDiffPreview._currentRequest = $.get(url)
314 loadRepoRefDiffPreview._currentRequest = $.get(url)
315 .error(function(data, textStatus, errorThrown) {
315 .error(function(data, textStatus, errorThrown) {
316 alert(
316 alert(
317 "Error while processing request.\nError code {0} ({1}).".format(
317 "Error while processing request.\nError code {0} ({1}).".format(
318 data.status, data.statusText));
318 data.status, data.statusText));
319 })
319 })
320 .done(function(data) {
320 .done(function(data) {
321 loadRepoRefDiffPreview._currentRequest = null;
321 loadRepoRefDiffPreview._currentRequest = null;
322 $('#pull_request_overview').html(data);
322 $('#pull_request_overview').html(data);
323
323
324 var commitElements = $(data).find('tr[commit_id]');
324 var commitElements = $(data).find('tr[commit_id]');
325
325
326 var prTitleAndDesc = getTitleAndDescription(
326 var prTitleAndDesc = getTitleAndDescription(
327 sourceRef()[1], commitElements, 5);
327 sourceRef()[1], commitElements, 5);
328
328
329 var title = prTitleAndDesc[0];
329 var title = prTitleAndDesc[0];
330 var proposedDescription = prTitleAndDesc[1];
330 var proposedDescription = prTitleAndDesc[1];
331
331
332 var useGeneratedTitle = (
332 var useGeneratedTitle = (
333 $('#pullrequest_title').hasClass('autogenerated-title') ||
333 $('#pullrequest_title').hasClass('autogenerated-title') ||
334 $('#pullrequest_title').val() === "");
334 $('#pullrequest_title').val() === "");
335
335
336 if (title && useGeneratedTitle) {
336 if (title && useGeneratedTitle) {
337 // use generated title if we haven't specified our own
337 // use generated title if we haven't specified our own
338 $('#pullrequest_title').val(title);
338 $('#pullrequest_title').val(title);
339 $('#pullrequest_title').addClass('autogenerated-title');
339 $('#pullrequest_title').addClass('autogenerated-title');
340
340
341 }
341 }
342
342
343 var useGeneratedDescription = (
343 var useGeneratedDescription = (
344 !codeMirrorInstance._userDefinedDesc ||
344 !codeMirrorInstance._userDefinedDesc ||
345 codeMirrorInstance.getValue() === "");
345 codeMirrorInstance.getValue() === "");
346
346
347 if (proposedDescription && useGeneratedDescription) {
347 if (proposedDescription && useGeneratedDescription) {
348 // set proposed content, if we haven't defined our own,
348 // set proposed content, if we haven't defined our own,
349 // or we don't have description written
349 // or we don't have description written
350 codeMirrorInstance._userDefinedDesc = false; // reset state
350 codeMirrorInstance._userDefinedDesc = false; // reset state
351 codeMirrorInstance.setValue(proposedDescription);
351 codeMirrorInstance.setValue(proposedDescription);
352 }
352 }
353
353
354 var msg = '';
354 var msg = '';
355 if (commitElements.length === 1) {
355 if (commitElements.length === 1) {
356 msg = "${ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 1)}";
356 msg = "${ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 1)}";
357 } else {
357 } else {
358 msg = "${ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 2)}";
358 msg = "${ungettext('This pull request will consist of __COMMITS__ commit.', 'This pull request will consist of __COMMITS__ commits.', 2)}";
359 }
359 }
360
360
361 msg += ' <a id="pull_request_overview_url" href="{0}" target="_blank">${_('Show detailed compare.')}</a>'.format(url);
361 msg += ' <a id="pull_request_overview_url" href="{0}" target="_blank">${_('Show detailed compare.')}</a>'.format(url);
362
362
363 if (commitElements.length) {
363 if (commitElements.length) {
364 var commitsLink = '<a href="#pull_request_overview"><strong>{0}</strong></a>'.format(commitElements.length);
364 var commitsLink = '<a href="#pull_request_overview"><strong>{0}</strong></a>'.format(commitElements.length);
365 prButtonLock(false, msg.replace('__COMMITS__', commitsLink), 'compare');
365 prButtonLock(false, msg.replace('__COMMITS__', commitsLink), 'compare');
366 }
366 }
367 else {
367 else {
368 prButtonLock(true, "${_('There are no commits to merge.')}", 'compare');
368 prButtonLock(true, "${_('There are no commits to merge.')}", 'compare');
369 }
369 }
370
370
371
371
372 });
372 });
373 };
373 };
374
374
375 var Select2Box = function(element, overrides) {
375 var Select2Box = function(element, overrides) {
376 var globalDefaults = {
376 var globalDefaults = {
377 dropdownAutoWidth: true,
377 dropdownAutoWidth: true,
378 containerCssClass: "drop-menu",
378 containerCssClass: "drop-menu",
379 dropdownCssClass: "drop-menu-dropdown"
379 dropdownCssClass: "drop-menu-dropdown"
380 };
380 };
381
381
382 var initSelect2 = function(defaultOptions) {
382 var initSelect2 = function(defaultOptions) {
383 var options = jQuery.extend(globalDefaults, defaultOptions, overrides);
383 var options = jQuery.extend(globalDefaults, defaultOptions, overrides);
384 element.select2(options);
384 element.select2(options);
385 };
385 };
386
386
387 return {
387 return {
388 initRef: function() {
388 initRef: function() {
389 var defaultOptions = {
389 var defaultOptions = {
390 minimumResultsForSearch: 5,
390 minimumResultsForSearch: 5,
391 formatSelection: formatRefSelection
391 formatSelection: formatRefSelection
392 };
392 };
393
393
394 initSelect2(defaultOptions);
394 initSelect2(defaultOptions);
395 },
395 },
396
396
397 initRepo: function(defaultValue, readOnly) {
397 initRepo: function(defaultValue, readOnly) {
398 var defaultOptions = {
398 var defaultOptions = {
399 initSelection : function (element, callback) {
399 initSelection : function (element, callback) {
400 var data = {id: defaultValue, text: defaultValue};
400 var data = {id: defaultValue, text: defaultValue};
401 callback(data);
401 callback(data);
402 }
402 }
403 };
403 };
404
404
405 initSelect2(defaultOptions);
405 initSelect2(defaultOptions);
406
406
407 element.select2('val', defaultSourceRepo);
407 element.select2('val', defaultSourceRepo);
408 if (readOnly === true) {
408 if (readOnly === true) {
409 element.select2('readonly', true);
409 element.select2('readonly', true);
410 }
410 }
411 }
411 }
412 };
412 };
413 };
413 };
414
414
415 var initTargetRefs = function(refsData, selectedRef){
415 var initTargetRefs = function(refsData, selectedRef){
416 Select2Box($targetRef, {
416 Select2Box($targetRef, {
417 query: function(query) {
417 query: function(query) {
418 queryTargetRefs(refsData, query);
418 queryTargetRefs(refsData, query);
419 },
419 },
420 initSelection : initRefSelection(selectedRef)
420 initSelection : initRefSelection(selectedRef)
421 }).initRef();
421 }).initRef();
422
422
423 if (!(selectedRef === undefined)) {
423 if (!(selectedRef === undefined)) {
424 $targetRef.select2('val', selectedRef);
424 $targetRef.select2('val', selectedRef);
425 }
425 }
426 };
426 };
427
427
428 var targetRepoChanged = function(repoData) {
428 var targetRepoChanged = function(repoData) {
429 // generate new DESC of target repo displayed next to select
429 // generate new DESC of target repo displayed next to select
430 $('#target_repo_desc').html(
430 $('#target_repo_desc').html(
431 "<strong>${_('Target repository')}</strong>: {0}".format(repoData['description'])
431 "<strong>${_('Target repository')}</strong>: {0}".format(repoData['description'])
432 );
432 );
433
433
434 // generate dynamic select2 for refs.
434 // generate dynamic select2 for refs.
435 initTargetRefs(repoData['refs']['select2_refs'],
435 initTargetRefs(repoData['refs']['select2_refs'],
436 repoData['refs']['selected_ref']);
436 repoData['refs']['selected_ref']);
437
437
438 };
438 };
439
439
440 var sourceRefSelect2 = Select2Box($sourceRef, {
440 var sourceRefSelect2 = Select2Box($sourceRef, {
441 placeholder: "${_('Select commit reference')}",
441 placeholder: "${_('Select commit reference')}",
442 query: function(query) {
442 query: function(query) {
443 var initialData = defaultSourceRepoData['refs']['select2_refs'];
443 var initialData = defaultSourceRepoData['refs']['select2_refs'];
444 queryTargetRefs(initialData, query)
444 queryTargetRefs(initialData, query)
445 },
445 },
446 initSelection: initRefSelection()
446 initSelection: initRefSelection()
447 }
447 }
448 );
448 );
449
449
450 var sourceRepoSelect2 = Select2Box($sourceRepo, {
450 var sourceRepoSelect2 = Select2Box($sourceRepo, {
451 query: function(query) {}
451 query: function(query) {}
452 });
452 });
453
453
454 var targetRepoSelect2 = Select2Box($targetRepo, {
454 var targetRepoSelect2 = Select2Box($targetRepo, {
455 cachedDataSource: {},
455 cachedDataSource: {},
456 query: $.debounce(250, function(query) {
456 query: $.debounce(250, function(query) {
457 queryTargetRepo(this, query);
457 queryTargetRepo(this, query);
458 }),
458 }),
459 formatResult: formatResult
459 formatResult: formatResult
460 });
460 });
461
461
462 sourceRefSelect2.initRef();
462 sourceRefSelect2.initRef();
463
463
464 sourceRepoSelect2.initRepo(defaultSourceRepo, true);
464 sourceRepoSelect2.initRepo(defaultSourceRepo, true);
465
465
466 targetRepoSelect2.initRepo(defaultTargetRepo, false);
466 targetRepoSelect2.initRepo(defaultTargetRepo, false);
467
467
468 $sourceRef.on('change', function(e){
468 $sourceRef.on('change', function(e){
469 loadRepoRefDiffPreview();
469 loadRepoRefDiffPreview();
470 reviewersController.loadDefaultReviewers(
470 reviewersController.loadDefaultReviewers(
471 sourceRepo(), sourceRef(), targetRepo(), targetRef());
471 sourceRepo(), sourceRef(), targetRepo(), targetRef());
472 });
472 });
473
473
474 $targetRef.on('change', function(e){
474 $targetRef.on('change', function(e){
475 loadRepoRefDiffPreview();
475 loadRepoRefDiffPreview();
476 reviewersController.loadDefaultReviewers(
476 reviewersController.loadDefaultReviewers(
477 sourceRepo(), sourceRef(), targetRepo(), targetRef());
477 sourceRepo(), sourceRef(), targetRepo(), targetRef());
478 });
478 });
479
479
480 $targetRepo.on('change', function(e){
480 $targetRepo.on('change', function(e){
481 var repoName = $(this).val();
481 var repoName = $(this).val();
482 calculateContainerWidth();
482 calculateContainerWidth();
483 $targetRef.select2('destroy');
483 $targetRef.select2('destroy');
484 $('#target_ref_loading').show();
484 $('#target_ref_loading').show();
485
485
486 $.ajax({
486 $.ajax({
487 url: pyroutes.url('pullrequest_repo_refs',
487 url: pyroutes.url('pullrequest_repo_refs',
488 {'repo_name': templateContext.repo_name, 'target_repo_name':repoName}),
488 {'repo_name': templateContext.repo_name, 'target_repo_name':repoName}),
489 data: {},
489 data: {},
490 dataType: 'json',
490 dataType: 'json',
491 type: 'GET',
491 type: 'GET',
492 success: function(data) {
492 success: function(data) {
493 $('#target_ref_loading').hide();
493 $('#target_ref_loading').hide();
494 targetRepoChanged(data);
494 targetRepoChanged(data);
495 loadRepoRefDiffPreview();
495 loadRepoRefDiffPreview();
496 },
496 },
497 error: function(data, textStatus, errorThrown) {
497 error: function(data, textStatus, errorThrown) {
498 alert("Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
498 alert("Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText));
499 }
499 }
500 })
500 })
501
501
502 });
502 });
503
503
504 prButtonLock(true, "${_('Please select source and target')}", 'all');
504 prButtonLock(true, "${_('Please select source and target')}", 'all');
505
505
506 // auto-load on init, the target refs select2
506 // auto-load on init, the target refs select2
507 calculateContainerWidth();
507 calculateContainerWidth();
508 targetRepoChanged(defaultTargetRepoData);
508 targetRepoChanged(defaultTargetRepoData);
509
509
510 $('#pullrequest_title').on('keyup', function(e){
510 $('#pullrequest_title').on('keyup', function(e){
511 $(this).removeClass('autogenerated-title');
511 $(this).removeClass('autogenerated-title');
512 });
512 });
513
513
514 % if c.default_source_ref:
514 % if c.default_source_ref:
515 // in case we have a pre-selected value, use it now
515 // in case we have a pre-selected value, use it now
516 $sourceRef.select2('val', '${c.default_source_ref}');
516 $sourceRef.select2('val', '${c.default_source_ref}');
517 loadRepoRefDiffPreview();
517 loadRepoRefDiffPreview();
518 reviewersController.loadDefaultReviewers(
518 reviewersController.loadDefaultReviewers(
519 sourceRepo(), sourceRef(), targetRepo(), targetRef());
519 sourceRepo(), sourceRef(), targetRepo(), targetRef());
520 % endif
520 % endif
521
521
522 ReviewerAutoComplete('#user');
522 ReviewerAutoComplete('#user');
523 });
523 });
524 </script>
524 </script>
525
525
526 </%def>
526 </%def>
@@ -1,63 +1,63 b''
1
1
2 <div class="pull-request-wrap">
2 <div class="pull-request-wrap">
3
3
4 % if c.pr_merge_possible:
4 % if c.pr_merge_possible:
5 <h2 class="merge-status">
5 <h2 class="merge-status">
6 <span class="merge-icon success"><i class="icon-true"></i></span>
6 <span class="merge-icon success"><i class="icon-true"></i></span>
7 ${_('This pull request can be merged automatically.')}
7 ${_('This pull request can be merged automatically.')}
8 </h2>
8 </h2>
9 % else:
9 % else:
10 <h2 class="merge-status">
10 <h2 class="merge-status">
11 <span class="merge-icon warning"><i class="icon-false"></i></span>
11 <span class="merge-icon warning"><i class="icon-false"></i></span>
12 ${_('Merge is not currently possible because of below failed checks.')}
12 ${_('Merge is not currently possible because of below failed checks.')}
13 </h2>
13 </h2>
14 % endif
14 % endif
15
15
16 <ul>
16 <ul>
17 % for pr_check_key, pr_check_details in c.pr_merge_errors.items():
17 % for pr_check_key, pr_check_details in c.pr_merge_errors.items():
18 <% pr_check_type = pr_check_details['error_type'] %>
18 <% pr_check_type = pr_check_details['error_type'] %>
19 <li>
19 <li>
20 <span class="merge-message ${pr_check_type}" data-role="merge-message">
20 <span class="merge-message ${pr_check_type}" data-role="merge-message">
21 - ${pr_check_details['message']}
21 - ${pr_check_details['message']}
22 % if pr_check_key == 'todo':
22 % if pr_check_key == 'todo':
23 % for co in pr_check_details['details']:
23 % for co in pr_check_details['details']:
24 <a class="permalink" href="#comment-${co.comment_id}" onclick="Rhodecode.comments.scrollToComment($('#comment-${co.comment_id}'), 0, ${h.json.dumps(co.outdated)})"> #${co.comment_id}</a>${'' if loop.last else ','}
24 <a class="permalink" href="#comment-${co.comment_id}" onclick="Rhodecode.comments.scrollToComment($('#comment-${co.comment_id}'), 0, ${h.json.dumps(co.outdated)})"> #${co.comment_id}</a>${'' if loop.last else ','}
25 % endfor
25 % endfor
26 % endif
26 % endif
27 </span>
27 </span>
28 </li>
28 </li>
29 % endfor
29 % endfor
30 </ul>
30 </ul>
31
31
32 <div class="pull-request-merge-actions">
32 <div class="pull-request-merge-actions">
33 % if c.allowed_to_merge:
33 % if c.allowed_to_merge:
34 <div class="pull-right">
34 <div class="pull-right">
35 ${h.secure_form(url('pullrequest_merge', repo_name=c.repo_name, pull_request_id=c.pull_request.pull_request_id), id='merge_pull_request_form')}
35 ${h.secure_form(h.url('pullrequest_merge', repo_name=c.repo_name, pull_request_id=c.pull_request.pull_request_id), id='merge_pull_request_form')}
36 <% merge_disabled = ' disabled' if c.pr_merge_possible is False else '' %>
36 <% merge_disabled = ' disabled' if c.pr_merge_possible is False else '' %>
37 <a class="btn" href="#" onclick="refreshMergeChecks(); return false;">${_('refresh checks')}</a>
37 <a class="btn" href="#" onclick="refreshMergeChecks(); return false;">${_('refresh checks')}</a>
38 <input type="submit" id="merge_pull_request" value="${_('Merge Pull Request')}" class="btn${merge_disabled}"${merge_disabled}>
38 <input type="submit" id="merge_pull_request" value="${_('Merge Pull Request')}" class="btn${merge_disabled}"${merge_disabled}>
39 ${h.end_form()}
39 ${h.end_form()}
40 </div>
40 </div>
41 % elif c.rhodecode_user.username != h.DEFAULT_USER:
41 % elif c.rhodecode_user.username != h.DEFAULT_USER:
42 <a class="btn" href="#" onclick="refreshMergeChecks(); return false;">${_('refresh checks')}</a>
42 <a class="btn" href="#" onclick="refreshMergeChecks(); return false;">${_('refresh checks')}</a>
43 <input type="submit" value="${_('Merge Pull Request')}" class="btn disabled" disabled="disabled" title="${_('You are not allowed to merge this pull request.')}">
43 <input type="submit" value="${_('Merge Pull Request')}" class="btn disabled" disabled="disabled" title="${_('You are not allowed to merge this pull request.')}">
44 % else:
44 % else:
45 <input type="submit" value="${_('Login to Merge this Pull Request')}" class="btn disabled" disabled="disabled">
45 <input type="submit" value="${_('Login to Merge this Pull Request')}" class="btn disabled" disabled="disabled">
46 % endif
46 % endif
47 </div>
47 </div>
48
48
49 % if c.allowed_to_close:
49 % if c.allowed_to_close:
50 ## close PR action, injected later next to COMMENT button
50 ## close PR action, injected later next to COMMENT button
51 <div id="close-pull-request-action" style="display: none">
51 <div id="close-pull-request-action" style="display: none">
52 % if c.pull_request_review_status == c.REVIEW_STATUS_APPROVED:
52 % if c.pull_request_review_status == c.REVIEW_STATUS_APPROVED:
53 <a class="btn btn-approved-status" href="#close-as-approved" onclick="closePullRequest('${c.REVIEW_STATUS_APPROVED}'); return false;">
53 <a class="btn btn-approved-status" href="#close-as-approved" onclick="closePullRequest('${c.REVIEW_STATUS_APPROVED}'); return false;">
54 ${_('Close with status {}').format(h.commit_status_lbl(c.REVIEW_STATUS_APPROVED))}
54 ${_('Close with status {}').format(h.commit_status_lbl(c.REVIEW_STATUS_APPROVED))}
55 </a>
55 </a>
56 % else:
56 % else:
57 <a class="btn btn-rejected-status" href="#close-as-rejected" onclick="closePullRequest('${c.REVIEW_STATUS_REJECTED}'); return false;">
57 <a class="btn btn-rejected-status" href="#close-as-rejected" onclick="closePullRequest('${c.REVIEW_STATUS_REJECTED}'); return false;">
58 ${_('Close with status {}').format(h.commit_status_lbl(c.REVIEW_STATUS_REJECTED))}
58 ${_('Close with status {}').format(h.commit_status_lbl(c.REVIEW_STATUS_REJECTED))}
59 </a>
59 </a>
60 % endif
60 % endif
61 </div>
61 </div>
62 % endif
62 % endif
63 </div>
63 </div>
@@ -1,860 +1,860 b''
1 <%inherit file="/base/base.mako"/>
1 <%inherit file="/base/base.mako"/>
2 <%namespace name="base" file="/base/base.mako"/>
2 <%namespace name="base" file="/base/base.mako"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('%s Pull Request #%s') % (c.repo_name, c.pull_request.pull_request_id)}
5 ${_('%s Pull Request #%s') % (c.repo_name, c.pull_request.pull_request_id)}
6 %if c.rhodecode_name:
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()">
12 <span id="pr-title">
12 <span id="pr-title">
13 ${c.pull_request.title}
13 ${c.pull_request.title}
14 %if c.pull_request.is_closed():
14 %if c.pull_request.is_closed():
15 (${_('Closed')})
15 (${_('Closed')})
16 %endif
16 %endif
17 </span>
17 </span>
18 <div id="pr-title-edit" class="input" style="display: none;">
18 <div id="pr-title-edit" class="input" style="display: none;">
19 ${h.text('pullrequest_title', id_="pr-title-input", class_="large", value=c.pull_request.title)}
19 ${h.text('pullrequest_title', id_="pr-title-input", class_="large", value=c.pull_request.title)}
20 </div>
20 </div>
21 </%def>
21 </%def>
22
22
23 <%def name="menu_bar_nav()">
23 <%def name="menu_bar_nav()">
24 ${self.menu_items(active='repositories')}
24 ${self.menu_items(active='repositories')}
25 </%def>
25 </%def>
26
26
27 <%def name="menu_bar_subnav()">
27 <%def name="menu_bar_subnav()">
28 ${self.repo_menu(active='showpullrequest')}
28 ${self.repo_menu(active='showpullrequest')}
29 </%def>
29 </%def>
30
30
31 <%def name="main()">
31 <%def name="main()">
32
32
33 <script type="text/javascript">
33 <script type="text/javascript">
34 // TODO: marcink switch this to pyroutes
34 // TODO: marcink switch this to pyroutes
35 AJAX_COMMENT_DELETE_URL = "${url('pullrequest_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
35 AJAX_COMMENT_DELETE_URL = "${h.url('pullrequest_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}";
36 templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
36 templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
37 </script>
37 </script>
38 <div class="box">
38 <div class="box">
39
39
40 <div class="title">
40 <div class="title">
41 ${self.repo_page_title(c.rhodecode_db_repo)}
41 ${self.repo_page_title(c.rhodecode_db_repo)}
42 </div>
42 </div>
43
43
44 ${self.breadcrumbs()}
44 ${self.breadcrumbs()}
45
45
46 <div class="box pr-summary">
46 <div class="box pr-summary">
47
47
48 <div class="summary-details block-left">
48 <div class="summary-details block-left">
49 <% summary = lambda n:{False:'summary-short'}.get(n) %>
49 <% summary = lambda n:{False:'summary-short'}.get(n) %>
50 <div class="pr-details-title">
50 <div class="pr-details-title">
51 <a href="${h.route_path('pull_requests_global', pull_request_id=c.pull_request.pull_request_id)}">${_('Pull request #%s') % c.pull_request.pull_request_id}</a> ${_('From')} ${h.format_date(c.pull_request.created_on)}
51 <a href="${h.route_path('pull_requests_global', pull_request_id=c.pull_request.pull_request_id)}">${_('Pull request #%s') % c.pull_request.pull_request_id}</a> ${_('From')} ${h.format_date(c.pull_request.created_on)}
52 %if c.allowed_to_update:
52 %if c.allowed_to_update:
53 <div id="delete_pullrequest" class="pull-right action_button ${'' if c.allowed_to_delete else 'disabled' }" style="clear:inherit;padding: 0">
53 <div id="delete_pullrequest" class="pull-right action_button ${'' if c.allowed_to_delete else 'disabled' }" style="clear:inherit;padding: 0">
54 % if c.allowed_to_delete:
54 % if c.allowed_to_delete:
55 ${h.secure_form(url('pullrequest_delete', repo_name=c.pull_request.target_repo.repo_name, pull_request_id=c.pull_request.pull_request_id),method='delete')}
55 ${h.secure_form(h.url('pullrequest_delete', repo_name=c.pull_request.target_repo.repo_name, pull_request_id=c.pull_request.pull_request_id),method='delete')}
56 ${h.submit('remove_%s' % c.pull_request.pull_request_id, _('Delete'),
56 ${h.submit('remove_%s' % c.pull_request.pull_request_id, _('Delete'),
57 class_="btn btn-link btn-danger no-margin",onclick="return confirm('"+_('Confirm to delete this pull request')+"');")}
57 class_="btn btn-link btn-danger no-margin",onclick="return confirm('"+_('Confirm to delete this pull request')+"');")}
58 ${h.end_form()}
58 ${h.end_form()}
59 % else:
59 % else:
60 ${_('Delete')}
60 ${_('Delete')}
61 % endif
61 % endif
62 </div>
62 </div>
63 <div id="open_edit_pullrequest" class="pull-right action_button">${_('Edit')}</div>
63 <div id="open_edit_pullrequest" class="pull-right action_button">${_('Edit')}</div>
64 <div id="close_edit_pullrequest" class="pull-right action_button" style="display: none;padding: 0">${_('Cancel')}</div>
64 <div id="close_edit_pullrequest" class="pull-right action_button" style="display: none;padding: 0">${_('Cancel')}</div>
65 %endif
65 %endif
66 </div>
66 </div>
67
67
68 <div id="summary" class="fields pr-details-content">
68 <div id="summary" class="fields pr-details-content">
69 <div class="field">
69 <div class="field">
70 <div class="label-summary">
70 <div class="label-summary">
71 <label>${_('Source')}:</label>
71 <label>${_('Source')}:</label>
72 </div>
72 </div>
73 <div class="input">
73 <div class="input">
74 <div class="pr-origininfo">
74 <div class="pr-origininfo">
75 ## branch link is only valid if it is a branch
75 ## branch link is only valid if it is a branch
76 <span class="tag">
76 <span class="tag">
77 %if c.pull_request.source_ref_parts.type == 'branch':
77 %if c.pull_request.source_ref_parts.type == 'branch':
78 <a href="${h.url('changelog_home', repo_name=c.pull_request.source_repo.repo_name, branch=c.pull_request.source_ref_parts.name)}">${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}</a>
78 <a href="${h.url('changelog_home', repo_name=c.pull_request.source_repo.repo_name, branch=c.pull_request.source_ref_parts.name)}">${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}</a>
79 %else:
79 %else:
80 ${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}
80 ${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}
81 %endif
81 %endif
82 </span>
82 </span>
83 <span class="clone-url">
83 <span class="clone-url">
84 <a href="${h.route_path('repo_summary', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.clone_url()}</a>
84 <a href="${h.route_path('repo_summary', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.clone_url()}</a>
85 </span>
85 </span>
86 <br/>
86 <br/>
87 % if c.ancestor_commit:
87 % if c.ancestor_commit:
88 ${_('Common ancestor')}:
88 ${_('Common ancestor')}:
89 <code><a href="${h.url('changeset_home', repo_name=c.target_repo.repo_name, revision=c.ancestor_commit.raw_id)}">${h.show_id(c.ancestor_commit)}</a></code>
89 <code><a href="${h.url('changeset_home', repo_name=c.target_repo.repo_name, revision=c.ancestor_commit.raw_id)}">${h.show_id(c.ancestor_commit)}</a></code>
90 % endif
90 % endif
91 </div>
91 </div>
92 <div class="pr-pullinfo">
92 <div class="pr-pullinfo">
93 %if h.is_hg(c.pull_request.source_repo):
93 %if h.is_hg(c.pull_request.source_repo):
94 <input type="text" class="input-monospace" value="hg pull -r ${h.short_id(c.source_ref)} ${c.pull_request.source_repo.clone_url()}" readonly="readonly">
94 <input type="text" class="input-monospace" value="hg pull -r ${h.short_id(c.source_ref)} ${c.pull_request.source_repo.clone_url()}" readonly="readonly">
95 %elif h.is_git(c.pull_request.source_repo):
95 %elif h.is_git(c.pull_request.source_repo):
96 <input type="text" class="input-monospace" value="git pull ${c.pull_request.source_repo.clone_url()} ${c.pull_request.source_ref_parts.name}" readonly="readonly">
96 <input type="text" class="input-monospace" value="git pull ${c.pull_request.source_repo.clone_url()} ${c.pull_request.source_ref_parts.name}" readonly="readonly">
97 %endif
97 %endif
98 </div>
98 </div>
99 </div>
99 </div>
100 </div>
100 </div>
101 <div class="field">
101 <div class="field">
102 <div class="label-summary">
102 <div class="label-summary">
103 <label>${_('Target')}:</label>
103 <label>${_('Target')}:</label>
104 </div>
104 </div>
105 <div class="input">
105 <div class="input">
106 <div class="pr-targetinfo">
106 <div class="pr-targetinfo">
107 ## branch link is only valid if it is a branch
107 ## branch link is only valid if it is a branch
108 <span class="tag">
108 <span class="tag">
109 %if c.pull_request.target_ref_parts.type == 'branch':
109 %if c.pull_request.target_ref_parts.type == 'branch':
110 <a href="${h.url('changelog_home', repo_name=c.pull_request.target_repo.repo_name, branch=c.pull_request.target_ref_parts.name)}">${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}</a>
110 <a href="${h.url('changelog_home', repo_name=c.pull_request.target_repo.repo_name, branch=c.pull_request.target_ref_parts.name)}">${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}</a>
111 %else:
111 %else:
112 ${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}
112 ${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}
113 %endif
113 %endif
114 </span>
114 </span>
115 <span class="clone-url">
115 <span class="clone-url">
116 <a href="${h.route_path('repo_summary', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.clone_url()}</a>
116 <a href="${h.route_path('repo_summary', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.clone_url()}</a>
117 </span>
117 </span>
118 </div>
118 </div>
119 </div>
119 </div>
120 </div>
120 </div>
121
121
122 ## Link to the shadow repository.
122 ## Link to the shadow repository.
123 <div class="field">
123 <div class="field">
124 <div class="label-summary">
124 <div class="label-summary">
125 <label>${_('Merge')}:</label>
125 <label>${_('Merge')}:</label>
126 </div>
126 </div>
127 <div class="input">
127 <div class="input">
128 % if not c.pull_request.is_closed() and c.pull_request.shadow_merge_ref:
128 % if not c.pull_request.is_closed() and c.pull_request.shadow_merge_ref:
129 <div class="pr-mergeinfo">
129 <div class="pr-mergeinfo">
130 %if h.is_hg(c.pull_request.target_repo):
130 %if h.is_hg(c.pull_request.target_repo):
131 <input type="text" class="input-monospace" value="hg clone -u ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly">
131 <input type="text" class="input-monospace" value="hg clone -u ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly">
132 %elif h.is_git(c.pull_request.target_repo):
132 %elif h.is_git(c.pull_request.target_repo):
133 <input type="text" class="input-monospace" value="git clone --branch ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly">
133 <input type="text" class="input-monospace" value="git clone --branch ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly">
134 %endif
134 %endif
135 </div>
135 </div>
136 % else:
136 % else:
137 <div class="">
137 <div class="">
138 ${_('Shadow repository data not available')}.
138 ${_('Shadow repository data not available')}.
139 </div>
139 </div>
140 % endif
140 % endif
141 </div>
141 </div>
142 </div>
142 </div>
143
143
144 <div class="field">
144 <div class="field">
145 <div class="label-summary">
145 <div class="label-summary">
146 <label>${_('Review')}:</label>
146 <label>${_('Review')}:</label>
147 </div>
147 </div>
148 <div class="input">
148 <div class="input">
149 %if c.pull_request_review_status:
149 %if c.pull_request_review_status:
150 <div class="${'flag_status %s' % c.pull_request_review_status} tooltip pull-left"></div>
150 <div class="${'flag_status %s' % c.pull_request_review_status} tooltip pull-left"></div>
151 <span class="changeset-status-lbl tooltip">
151 <span class="changeset-status-lbl tooltip">
152 %if c.pull_request.is_closed():
152 %if c.pull_request.is_closed():
153 ${_('Closed')},
153 ${_('Closed')},
154 %endif
154 %endif
155 ${h.commit_status_lbl(c.pull_request_review_status)}
155 ${h.commit_status_lbl(c.pull_request_review_status)}
156 </span>
156 </span>
157 - ${ungettext('calculated based on %s reviewer vote', 'calculated based on %s reviewers votes', len(c.pull_request_reviewers)) % len(c.pull_request_reviewers)}
157 - ${ungettext('calculated based on %s reviewer vote', 'calculated based on %s reviewers votes', len(c.pull_request_reviewers)) % len(c.pull_request_reviewers)}
158 %endif
158 %endif
159 </div>
159 </div>
160 </div>
160 </div>
161 <div class="field">
161 <div class="field">
162 <div class="pr-description-label label-summary">
162 <div class="pr-description-label label-summary">
163 <label>${_('Description')}:</label>
163 <label>${_('Description')}:</label>
164 </div>
164 </div>
165 <div id="pr-desc" class="input">
165 <div id="pr-desc" class="input">
166 <div class="pr-description">${h.urlify_commit_message(c.pull_request.description, c.repo_name)}</div>
166 <div class="pr-description">${h.urlify_commit_message(c.pull_request.description, c.repo_name)}</div>
167 </div>
167 </div>
168 <div id="pr-desc-edit" class="input textarea editor" style="display: none;">
168 <div id="pr-desc-edit" class="input textarea editor" style="display: none;">
169 <textarea id="pr-description-input" size="30">${c.pull_request.description}</textarea>
169 <textarea id="pr-description-input" size="30">${c.pull_request.description}</textarea>
170 </div>
170 </div>
171 </div>
171 </div>
172
172
173 <div class="field">
173 <div class="field">
174 <div class="label-summary">
174 <div class="label-summary">
175 <label>${_('Versions')}:</label>
175 <label>${_('Versions')}:</label>
176 </div>
176 </div>
177
177
178 <% outdated_comm_count_ver = len(c.inline_versions[None]['outdated']) %>
178 <% outdated_comm_count_ver = len(c.inline_versions[None]['outdated']) %>
179 <% general_outdated_comm_count_ver = len(c.comment_versions[None]['outdated']) %>
179 <% general_outdated_comm_count_ver = len(c.comment_versions[None]['outdated']) %>
180
180
181 <div class="pr-versions">
181 <div class="pr-versions">
182 % if c.show_version_changes:
182 % if c.show_version_changes:
183 <% outdated_comm_count_ver = len(c.inline_versions[c.at_version_num]['outdated']) %>
183 <% outdated_comm_count_ver = len(c.inline_versions[c.at_version_num]['outdated']) %>
184 <% general_outdated_comm_count_ver = len(c.comment_versions[c.at_version_num]['outdated']) %>
184 <% general_outdated_comm_count_ver = len(c.comment_versions[c.at_version_num]['outdated']) %>
185 <a id="show-pr-versions" class="input" onclick="return versionController.toggleVersionView(this)" href="#show-pr-versions"
185 <a id="show-pr-versions" class="input" onclick="return versionController.toggleVersionView(this)" href="#show-pr-versions"
186 data-toggle-on="${ungettext('{} version available for this pull request, show it.', '{} versions available for this pull request, show them.', len(c.versions)).format(len(c.versions))}"
186 data-toggle-on="${ungettext('{} version available for this pull request, show it.', '{} versions available for this pull request, show them.', len(c.versions)).format(len(c.versions))}"
187 data-toggle-off="${_('Hide all versions of this pull request')}">
187 data-toggle-off="${_('Hide all versions of this pull request')}">
188 ${ungettext('{} version available for this pull request, show it.', '{} versions available for this pull request, show them.', len(c.versions)).format(len(c.versions))}
188 ${ungettext('{} version available for this pull request, show it.', '{} versions available for this pull request, show them.', len(c.versions)).format(len(c.versions))}
189 </a>
189 </a>
190 <table>
190 <table>
191 ## SHOW ALL VERSIONS OF PR
191 ## SHOW ALL VERSIONS OF PR
192 <% ver_pr = None %>
192 <% ver_pr = None %>
193
193
194 % for data in reversed(list(enumerate(c.versions, 1))):
194 % for data in reversed(list(enumerate(c.versions, 1))):
195 <% ver_pos = data[0] %>
195 <% ver_pos = data[0] %>
196 <% ver = data[1] %>
196 <% ver = data[1] %>
197 <% ver_pr = ver.pull_request_version_id %>
197 <% ver_pr = ver.pull_request_version_id %>
198 <% display_row = '' if c.at_version and (c.at_version_num == ver_pr or c.from_version_num == ver_pr) else 'none' %>
198 <% display_row = '' if c.at_version and (c.at_version_num == ver_pr or c.from_version_num == ver_pr) else 'none' %>
199
199
200 <tr class="version-pr" style="display: ${display_row}">
200 <tr class="version-pr" style="display: ${display_row}">
201 <td>
201 <td>
202 <code>
202 <code>
203 <a href="${h.url.current(version=ver_pr or 'latest')}">v${ver_pos}</a>
203 <a href="${h.url.current(version=ver_pr or 'latest')}">v${ver_pos}</a>
204 </code>
204 </code>
205 </td>
205 </td>
206 <td>
206 <td>
207 <input ${'checked="checked"' if c.from_version_num == ver_pr else ''} class="compare-radio-button" type="radio" name="ver_source" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/>
207 <input ${'checked="checked"' if c.from_version_num == ver_pr else ''} class="compare-radio-button" type="radio" name="ver_source" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/>
208 <input ${'checked="checked"' if c.at_version_num == ver_pr else ''} class="compare-radio-button" type="radio" name="ver_target" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/>
208 <input ${'checked="checked"' if c.at_version_num == ver_pr else ''} class="compare-radio-button" type="radio" name="ver_target" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/>
209 </td>
209 </td>
210 <td>
210 <td>
211 <% review_status = c.review_versions[ver_pr].status if ver_pr in c.review_versions else 'not_reviewed' %>
211 <% review_status = c.review_versions[ver_pr].status if ver_pr in c.review_versions else 'not_reviewed' %>
212 <div class="${'flag_status %s' % review_status} tooltip pull-left" title="${_('Your review status at this version')}">
212 <div class="${'flag_status %s' % review_status} tooltip pull-left" title="${_('Your review status at this version')}">
213 </div>
213 </div>
214 </td>
214 </td>
215 <td>
215 <td>
216 % if c.at_version_num != ver_pr:
216 % if c.at_version_num != ver_pr:
217 <i class="icon-comment"></i>
217 <i class="icon-comment"></i>
218 <code class="tooltip" title="${_('Comment from pull request version {0}, general:{1} inline:{2}').format(ver_pos, len(c.comment_versions[ver_pr]['at']), len(c.inline_versions[ver_pr]['at']))}">
218 <code class="tooltip" title="${_('Comment from pull request version {0}, general:{1} inline:{2}').format(ver_pos, len(c.comment_versions[ver_pr]['at']), len(c.inline_versions[ver_pr]['at']))}">
219 G:${len(c.comment_versions[ver_pr]['at'])} / I:${len(c.inline_versions[ver_pr]['at'])}
219 G:${len(c.comment_versions[ver_pr]['at'])} / I:${len(c.inline_versions[ver_pr]['at'])}
220 </code>
220 </code>
221 % endif
221 % endif
222 </td>
222 </td>
223 <td>
223 <td>
224 ##<code>${ver.source_ref_parts.commit_id[:6]}</code>
224 ##<code>${ver.source_ref_parts.commit_id[:6]}</code>
225 </td>
225 </td>
226 <td>
226 <td>
227 ${h.age_component(ver.updated_on, time_is_local=True)}
227 ${h.age_component(ver.updated_on, time_is_local=True)}
228 </td>
228 </td>
229 </tr>
229 </tr>
230 % endfor
230 % endfor
231
231
232 <tr>
232 <tr>
233 <td colspan="6">
233 <td colspan="6">
234 <button id="show-version-diff" onclick="return versionController.showVersionDiff()" class="btn btn-sm" style="display: none"
234 <button id="show-version-diff" onclick="return versionController.showVersionDiff()" class="btn btn-sm" style="display: none"
235 data-label-text-locked="${_('select versions to show changes')}"
235 data-label-text-locked="${_('select versions to show changes')}"
236 data-label-text-diff="${_('show changes between versions')}"
236 data-label-text-diff="${_('show changes between versions')}"
237 data-label-text-show="${_('show pull request for this version')}"
237 data-label-text-show="${_('show pull request for this version')}"
238 >
238 >
239 ${_('select versions to show changes')}
239 ${_('select versions to show changes')}
240 </button>
240 </button>
241 </td>
241 </td>
242 </tr>
242 </tr>
243
243
244 ## show comment/inline comments summary
244 ## show comment/inline comments summary
245 <%def name="comments_summary()">
245 <%def name="comments_summary()">
246 <tr>
246 <tr>
247 <td colspan="6" class="comments-summary-td">
247 <td colspan="6" class="comments-summary-td">
248
248
249 % if c.at_version:
249 % if c.at_version:
250 <% inline_comm_count_ver = len(c.inline_versions[c.at_version_num]['display']) %>
250 <% inline_comm_count_ver = len(c.inline_versions[c.at_version_num]['display']) %>
251 <% general_comm_count_ver = len(c.comment_versions[c.at_version_num]['display']) %>
251 <% general_comm_count_ver = len(c.comment_versions[c.at_version_num]['display']) %>
252 ${_('Comments at this version')}:
252 ${_('Comments at this version')}:
253 % else:
253 % else:
254 <% inline_comm_count_ver = len(c.inline_versions[c.at_version_num]['until']) %>
254 <% inline_comm_count_ver = len(c.inline_versions[c.at_version_num]['until']) %>
255 <% general_comm_count_ver = len(c.comment_versions[c.at_version_num]['until']) %>
255 <% general_comm_count_ver = len(c.comment_versions[c.at_version_num]['until']) %>
256 ${_('Comments for this pull request')}:
256 ${_('Comments for this pull request')}:
257 % endif
257 % endif
258
258
259
259
260 %if general_comm_count_ver:
260 %if general_comm_count_ver:
261 <a href="#comments">${_("%d General ") % general_comm_count_ver}</a>
261 <a href="#comments">${_("%d General ") % general_comm_count_ver}</a>
262 %else:
262 %else:
263 ${_("%d General ") % general_comm_count_ver}
263 ${_("%d General ") % general_comm_count_ver}
264 %endif
264 %endif
265
265
266 %if inline_comm_count_ver:
266 %if inline_comm_count_ver:
267 , <a href="#" onclick="return Rhodecode.comments.nextComment();" id="inline-comments-counter">${_("%d Inline") % inline_comm_count_ver}</a>
267 , <a href="#" onclick="return Rhodecode.comments.nextComment();" id="inline-comments-counter">${_("%d Inline") % inline_comm_count_ver}</a>
268 %else:
268 %else:
269 , ${_("%d Inline") % inline_comm_count_ver}
269 , ${_("%d Inline") % inline_comm_count_ver}
270 %endif
270 %endif
271
271
272 %if outdated_comm_count_ver:
272 %if outdated_comm_count_ver:
273 , <a href="#" onclick="showOutdated(); Rhodecode.comments.nextOutdatedComment(); return false;">${_("%d Outdated") % outdated_comm_count_ver}</a>
273 , <a href="#" onclick="showOutdated(); Rhodecode.comments.nextOutdatedComment(); return false;">${_("%d Outdated") % outdated_comm_count_ver}</a>
274 <a href="#" class="showOutdatedComments" onclick="showOutdated(this); return false;"> | ${_('show outdated comments')}</a>
274 <a href="#" class="showOutdatedComments" onclick="showOutdated(this); return false;"> | ${_('show outdated comments')}</a>
275 <a href="#" class="hideOutdatedComments" style="display: none" onclick="hideOutdated(this); return false;"> | ${_('hide outdated comments')}</a>
275 <a href="#" class="hideOutdatedComments" style="display: none" onclick="hideOutdated(this); return false;"> | ${_('hide outdated comments')}</a>
276 %else:
276 %else:
277 , ${_("%d Outdated") % outdated_comm_count_ver}
277 , ${_("%d Outdated") % outdated_comm_count_ver}
278 %endif
278 %endif
279 </td>
279 </td>
280 </tr>
280 </tr>
281 </%def>
281 </%def>
282 ${comments_summary()}
282 ${comments_summary()}
283 </table>
283 </table>
284 % else:
284 % else:
285 <div class="input">
285 <div class="input">
286 ${_('Pull request versions not available')}.
286 ${_('Pull request versions not available')}.
287 </div>
287 </div>
288 <div>
288 <div>
289 <table>
289 <table>
290 ${comments_summary()}
290 ${comments_summary()}
291 </table>
291 </table>
292 </div>
292 </div>
293 % endif
293 % endif
294 </div>
294 </div>
295 </div>
295 </div>
296
296
297 <div id="pr-save" class="field" style="display: none;">
297 <div id="pr-save" class="field" style="display: none;">
298 <div class="label-summary"></div>
298 <div class="label-summary"></div>
299 <div class="input">
299 <div class="input">
300 <span id="edit_pull_request" class="btn btn-small no-margin">${_('Save Changes')}</span>
300 <span id="edit_pull_request" class="btn btn-small no-margin">${_('Save Changes')}</span>
301 </div>
301 </div>
302 </div>
302 </div>
303 </div>
303 </div>
304 </div>
304 </div>
305 <div>
305 <div>
306 ## AUTHOR
306 ## AUTHOR
307 <div class="reviewers-title block-right">
307 <div class="reviewers-title block-right">
308 <div class="pr-details-title">
308 <div class="pr-details-title">
309 ${_('Author of this pull request')}
309 ${_('Author of this pull request')}
310 </div>
310 </div>
311 </div>
311 </div>
312 <div class="block-right pr-details-content reviewers">
312 <div class="block-right pr-details-content reviewers">
313 <ul class="group_members">
313 <ul class="group_members">
314 <li>
314 <li>
315 ${self.gravatar_with_user(c.pull_request.author.email, 16)}
315 ${self.gravatar_with_user(c.pull_request.author.email, 16)}
316 </li>
316 </li>
317 </ul>
317 </ul>
318 </div>
318 </div>
319
319
320 ## REVIEW RULES
320 ## REVIEW RULES
321 <div id="review_rules" style="display: none" class="reviewers-title block-right">
321 <div id="review_rules" style="display: none" class="reviewers-title block-right">
322 <div class="pr-details-title">
322 <div class="pr-details-title">
323 ${_('Reviewer rules')}
323 ${_('Reviewer rules')}
324 %if c.allowed_to_update:
324 %if c.allowed_to_update:
325 <span id="close_edit_reviewers" class="block-right action_button last-item" style="display: none;">${_('Close')}</span>
325 <span id="close_edit_reviewers" class="block-right action_button last-item" style="display: none;">${_('Close')}</span>
326 %endif
326 %endif
327 </div>
327 </div>
328 <div class="pr-reviewer-rules">
328 <div class="pr-reviewer-rules">
329 ## review rules will be appended here, by default reviewers logic
329 ## review rules will be appended here, by default reviewers logic
330 </div>
330 </div>
331 <input id="review_data" type="hidden" name="review_data" value="">
331 <input id="review_data" type="hidden" name="review_data" value="">
332 </div>
332 </div>
333
333
334 ## REVIEWERS
334 ## REVIEWERS
335 <div class="reviewers-title block-right">
335 <div class="reviewers-title block-right">
336 <div class="pr-details-title">
336 <div class="pr-details-title">
337 ${_('Pull request reviewers')}
337 ${_('Pull request reviewers')}
338 %if c.allowed_to_update:
338 %if c.allowed_to_update:
339 <span id="open_edit_reviewers" class="block-right action_button last-item">${_('Edit')}</span>
339 <span id="open_edit_reviewers" class="block-right action_button last-item">${_('Edit')}</span>
340 %endif
340 %endif
341 </div>
341 </div>
342 </div>
342 </div>
343 <div id="reviewers" class="block-right pr-details-content reviewers">
343 <div id="reviewers" class="block-right pr-details-content reviewers">
344 ## members goes here !
344 ## members goes here !
345 <input type="hidden" name="__start__" value="review_members:sequence">
345 <input type="hidden" name="__start__" value="review_members:sequence">
346 <ul id="review_members" class="group_members">
346 <ul id="review_members" class="group_members">
347 %for member,reasons,mandatory,status in c.pull_request_reviewers:
347 %for member,reasons,mandatory,status in c.pull_request_reviewers:
348 <li id="reviewer_${member.user_id}" class="reviewer_entry">
348 <li id="reviewer_${member.user_id}" class="reviewer_entry">
349 <div class="reviewers_member">
349 <div class="reviewers_member">
350 <div class="reviewer_status tooltip" title="${h.tooltip(h.commit_status_lbl(status[0][1].status if status else 'not_reviewed'))}">
350 <div class="reviewer_status tooltip" title="${h.tooltip(h.commit_status_lbl(status[0][1].status if status else 'not_reviewed'))}">
351 <div class="${'flag_status %s' % (status[0][1].status if status else 'not_reviewed')} pull-left reviewer_member_status"></div>
351 <div class="${'flag_status %s' % (status[0][1].status if status else 'not_reviewed')} pull-left reviewer_member_status"></div>
352 </div>
352 </div>
353 <div id="reviewer_${member.user_id}_name" class="reviewer_name">
353 <div id="reviewer_${member.user_id}_name" class="reviewer_name">
354 ${self.gravatar_with_user(member.email, 16)}
354 ${self.gravatar_with_user(member.email, 16)}
355 </div>
355 </div>
356 <input type="hidden" name="__start__" value="reviewer:mapping">
356 <input type="hidden" name="__start__" value="reviewer:mapping">
357 <input type="hidden" name="__start__" value="reasons:sequence">
357 <input type="hidden" name="__start__" value="reasons:sequence">
358 %for reason in reasons:
358 %for reason in reasons:
359 <div class="reviewer_reason">- ${reason}</div>
359 <div class="reviewer_reason">- ${reason}</div>
360 <input type="hidden" name="reason" value="${reason}">
360 <input type="hidden" name="reason" value="${reason}">
361
361
362 %endfor
362 %endfor
363 <input type="hidden" name="__end__" value="reasons:sequence">
363 <input type="hidden" name="__end__" value="reasons:sequence">
364 <input id="reviewer_${member.user_id}_input" type="hidden" value="${member.user_id}" name="user_id" />
364 <input id="reviewer_${member.user_id}_input" type="hidden" value="${member.user_id}" name="user_id" />
365 <input type="hidden" name="mandatory" value="${mandatory}"/>
365 <input type="hidden" name="mandatory" value="${mandatory}"/>
366 <input type="hidden" name="__end__" value="reviewer:mapping">
366 <input type="hidden" name="__end__" value="reviewer:mapping">
367 % if mandatory:
367 % if mandatory:
368 <div class="reviewer_member_mandatory_remove">
368 <div class="reviewer_member_mandatory_remove">
369 <i class="icon-remove-sign"></i>
369 <i class="icon-remove-sign"></i>
370 </div>
370 </div>
371 <div class="reviewer_member_mandatory">
371 <div class="reviewer_member_mandatory">
372 <i class="icon-lock" title="${h.tooltip(_('Mandatory reviewer'))}"></i>
372 <i class="icon-lock" title="${h.tooltip(_('Mandatory reviewer'))}"></i>
373 </div>
373 </div>
374 % else:
374 % else:
375 %if c.allowed_to_update:
375 %if c.allowed_to_update:
376 <div class="reviewer_member_remove action_button" onclick="reviewersController.removeReviewMember(${member.user_id}, true)" style="visibility: hidden;">
376 <div class="reviewer_member_remove action_button" onclick="reviewersController.removeReviewMember(${member.user_id}, true)" style="visibility: hidden;">
377 <i class="icon-remove-sign" ></i>
377 <i class="icon-remove-sign" ></i>
378 </div>
378 </div>
379 %endif
379 %endif
380 % endif
380 % endif
381 </div>
381 </div>
382 </li>
382 </li>
383 %endfor
383 %endfor
384 </ul>
384 </ul>
385 <input type="hidden" name="__end__" value="review_members:sequence">
385 <input type="hidden" name="__end__" value="review_members:sequence">
386
386
387 %if not c.pull_request.is_closed():
387 %if not c.pull_request.is_closed():
388 <div id="add_reviewer" class="ac" style="display: none;">
388 <div id="add_reviewer" class="ac" style="display: none;">
389 %if c.allowed_to_update:
389 %if c.allowed_to_update:
390 % if not c.forbid_adding_reviewers:
390 % if not c.forbid_adding_reviewers:
391 <div id="add_reviewer_input" class="reviewer_ac">
391 <div id="add_reviewer_input" class="reviewer_ac">
392 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))}
392 ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))}
393 <div id="reviewers_container"></div>
393 <div id="reviewers_container"></div>
394 </div>
394 </div>
395 % endif
395 % endif
396 <div class="pull-right">
396 <div class="pull-right">
397 <button id="update_pull_request" class="btn btn-small no-margin">${_('Save Changes')}</button>
397 <button id="update_pull_request" class="btn btn-small no-margin">${_('Save Changes')}</button>
398 </div>
398 </div>
399 %endif
399 %endif
400 </div>
400 </div>
401 %endif
401 %endif
402 </div>
402 </div>
403 </div>
403 </div>
404 </div>
404 </div>
405 <div class="box">
405 <div class="box">
406 ##DIFF
406 ##DIFF
407 <div class="table" >
407 <div class="table" >
408 <div id="changeset_compare_view_content">
408 <div id="changeset_compare_view_content">
409 ##CS
409 ##CS
410 % if c.missing_requirements:
410 % if c.missing_requirements:
411 <div class="box">
411 <div class="box">
412 <div class="alert alert-warning">
412 <div class="alert alert-warning">
413 <div>
413 <div>
414 <strong>${_('Missing requirements:')}</strong>
414 <strong>${_('Missing requirements:')}</strong>
415 ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')}
415 ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')}
416 </div>
416 </div>
417 </div>
417 </div>
418 </div>
418 </div>
419 % elif c.missing_commits:
419 % elif c.missing_commits:
420 <div class="box">
420 <div class="box">
421 <div class="alert alert-warning">
421 <div class="alert alert-warning">
422 <div>
422 <div>
423 <strong>${_('Missing commits')}:</strong>
423 <strong>${_('Missing commits')}:</strong>
424 ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')}
424 ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')}
425 ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')}
425 ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')}
426 </div>
426 </div>
427 </div>
427 </div>
428 </div>
428 </div>
429 % endif
429 % endif
430
430
431 <div class="compare_view_commits_title">
431 <div class="compare_view_commits_title">
432 % if not c.compare_mode:
432 % if not c.compare_mode:
433
433
434 % if c.at_version_pos:
434 % if c.at_version_pos:
435 <h4>
435 <h4>
436 ${_('Showing changes at v%d, commenting is disabled.') % c.at_version_pos}
436 ${_('Showing changes at v%d, commenting is disabled.') % c.at_version_pos}
437 </h4>
437 </h4>
438 % endif
438 % endif
439
439
440 <div class="pull-left">
440 <div class="pull-left">
441 <div class="btn-group">
441 <div class="btn-group">
442 <a
442 <a
443 class="btn"
443 class="btn"
444 href="#"
444 href="#"
445 onclick="$('.compare_select').show();$('.compare_select_hidden').hide(); return false">
445 onclick="$('.compare_select').show();$('.compare_select_hidden').hide(); return false">
446 ${ungettext('Expand %s commit','Expand %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}
446 ${ungettext('Expand %s commit','Expand %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}
447 </a>
447 </a>
448 <a
448 <a
449 class="btn"
449 class="btn"
450 href="#"
450 href="#"
451 onclick="$('.compare_select').hide();$('.compare_select_hidden').show(); return false">
451 onclick="$('.compare_select').hide();$('.compare_select_hidden').show(); return false">
452 ${ungettext('Collapse %s commit','Collapse %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}
452 ${ungettext('Collapse %s commit','Collapse %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}
453 </a>
453 </a>
454 </div>
454 </div>
455 </div>
455 </div>
456
456
457 <div class="pull-right">
457 <div class="pull-right">
458 % if c.allowed_to_update and not c.pull_request.is_closed():
458 % if c.allowed_to_update and not c.pull_request.is_closed():
459 <a id="update_commits" class="btn btn-primary no-margin pull-right">${_('Update commits')}</a>
459 <a id="update_commits" class="btn btn-primary no-margin pull-right">${_('Update commits')}</a>
460 % else:
460 % else:
461 <a class="tooltip btn disabled pull-right" disabled="disabled" title="${_('Update is disabled for current view')}">${_('Update commits')}</a>
461 <a class="tooltip btn disabled pull-right" disabled="disabled" title="${_('Update is disabled for current view')}">${_('Update commits')}</a>
462 % endif
462 % endif
463
463
464 </div>
464 </div>
465 % endif
465 % endif
466 </div>
466 </div>
467
467
468 % if not c.missing_commits:
468 % if not c.missing_commits:
469 % if c.compare_mode:
469 % if c.compare_mode:
470 % if c.at_version:
470 % if c.at_version:
471 <h4>
471 <h4>
472 ${_('Commits and changes between v{ver_from} and {ver_to} of this pull request, commenting is disabled').format(ver_from=c.from_version_pos, ver_to=c.at_version_pos if c.at_version_pos else 'latest')}:
472 ${_('Commits and changes between v{ver_from} and {ver_to} of this pull request, commenting is disabled').format(ver_from=c.from_version_pos, ver_to=c.at_version_pos if c.at_version_pos else 'latest')}:
473 </h4>
473 </h4>
474
474
475 <div class="subtitle-compare">
475 <div class="subtitle-compare">
476 ${_('commits added: {}, removed: {}').format(len(c.commit_changes_summary.added), len(c.commit_changes_summary.removed))}
476 ${_('commits added: {}, removed: {}').format(len(c.commit_changes_summary.added), len(c.commit_changes_summary.removed))}
477 </div>
477 </div>
478
478
479 <div class="container">
479 <div class="container">
480 <table class="rctable compare_view_commits">
480 <table class="rctable compare_view_commits">
481 <tr>
481 <tr>
482 <th></th>
482 <th></th>
483 <th>${_('Time')}</th>
483 <th>${_('Time')}</th>
484 <th>${_('Author')}</th>
484 <th>${_('Author')}</th>
485 <th>${_('Commit')}</th>
485 <th>${_('Commit')}</th>
486 <th></th>
486 <th></th>
487 <th>${_('Description')}</th>
487 <th>${_('Description')}</th>
488 </tr>
488 </tr>
489
489
490 % for c_type, commit in c.commit_changes:
490 % for c_type, commit in c.commit_changes:
491 % if c_type in ['a', 'r']:
491 % if c_type in ['a', 'r']:
492 <%
492 <%
493 if c_type == 'a':
493 if c_type == 'a':
494 cc_title = _('Commit added in displayed changes')
494 cc_title = _('Commit added in displayed changes')
495 elif c_type == 'r':
495 elif c_type == 'r':
496 cc_title = _('Commit removed in displayed changes')
496 cc_title = _('Commit removed in displayed changes')
497 else:
497 else:
498 cc_title = ''
498 cc_title = ''
499 %>
499 %>
500 <tr id="row-${commit.raw_id}" commit_id="${commit.raw_id}" class="compare_select">
500 <tr id="row-${commit.raw_id}" commit_id="${commit.raw_id}" class="compare_select">
501 <td>
501 <td>
502 <div class="commit-change-indicator color-${c_type}-border">
502 <div class="commit-change-indicator color-${c_type}-border">
503 <div class="commit-change-content color-${c_type} tooltip" title="${h.tooltip(cc_title)}">
503 <div class="commit-change-content color-${c_type} tooltip" title="${h.tooltip(cc_title)}">
504 ${c_type.upper()}
504 ${c_type.upper()}
505 </div>
505 </div>
506 </div>
506 </div>
507 </td>
507 </td>
508 <td class="td-time">
508 <td class="td-time">
509 ${h.age_component(commit.date)}
509 ${h.age_component(commit.date)}
510 </td>
510 </td>
511 <td class="td-user">
511 <td class="td-user">
512 ${base.gravatar_with_user(commit.author, 16)}
512 ${base.gravatar_with_user(commit.author, 16)}
513 </td>
513 </td>
514 <td class="td-hash">
514 <td class="td-hash">
515 <code>
515 <code>
516 <a href="${h.url('changeset_home', repo_name=c.target_repo.repo_name, revision=commit.raw_id)}">
516 <a href="${h.url('changeset_home', repo_name=c.target_repo.repo_name, revision=commit.raw_id)}">
517 r${commit.revision}:${h.short_id(commit.raw_id)}
517 r${commit.revision}:${h.short_id(commit.raw_id)}
518 </a>
518 </a>
519 ${h.hidden('revisions', commit.raw_id)}
519 ${h.hidden('revisions', commit.raw_id)}
520 </code>
520 </code>
521 </td>
521 </td>
522 <td class="expand_commit" data-commit-id="${commit.raw_id}" title="${_( 'Expand commit message')}">
522 <td class="expand_commit" data-commit-id="${commit.raw_id}" title="${_( 'Expand commit message')}">
523 <div class="show_more_col">
523 <div class="show_more_col">
524 <i class="show_more"></i>
524 <i class="show_more"></i>
525 </div>
525 </div>
526 </td>
526 </td>
527 <td class="mid td-description">
527 <td class="mid td-description">
528 <div class="log-container truncate-wrap">
528 <div class="log-container truncate-wrap">
529 <div class="message truncate" id="c-${commit.raw_id}" data-message-raw="${commit.message}">
529 <div class="message truncate" id="c-${commit.raw_id}" data-message-raw="${commit.message}">
530 ${h.urlify_commit_message(commit.message, c.repo_name)}
530 ${h.urlify_commit_message(commit.message, c.repo_name)}
531 </div>
531 </div>
532 </div>
532 </div>
533 </td>
533 </td>
534 </tr>
534 </tr>
535 % endif
535 % endif
536 % endfor
536 % endfor
537 </table>
537 </table>
538 </div>
538 </div>
539
539
540 <script>
540 <script>
541 $('.expand_commit').on('click',function(e){
541 $('.expand_commit').on('click',function(e){
542 var target_expand = $(this);
542 var target_expand = $(this);
543 var cid = target_expand.data('commitId');
543 var cid = target_expand.data('commitId');
544
544
545 if (target_expand.hasClass('open')){
545 if (target_expand.hasClass('open')){
546 $('#c-'+cid).css({
546 $('#c-'+cid).css({
547 'height': '1.5em',
547 'height': '1.5em',
548 'white-space': 'nowrap',
548 'white-space': 'nowrap',
549 'text-overflow': 'ellipsis',
549 'text-overflow': 'ellipsis',
550 'overflow':'hidden'
550 'overflow':'hidden'
551 });
551 });
552 target_expand.removeClass('open');
552 target_expand.removeClass('open');
553 }
553 }
554 else {
554 else {
555 $('#c-'+cid).css({
555 $('#c-'+cid).css({
556 'height': 'auto',
556 'height': 'auto',
557 'white-space': 'pre-line',
557 'white-space': 'pre-line',
558 'text-overflow': 'initial',
558 'text-overflow': 'initial',
559 'overflow':'visible'
559 'overflow':'visible'
560 });
560 });
561 target_expand.addClass('open');
561 target_expand.addClass('open');
562 }
562 }
563 });
563 });
564 </script>
564 </script>
565
565
566 % endif
566 % endif
567
567
568 % else:
568 % else:
569 <%include file="/compare/compare_commits.mako" />
569 <%include file="/compare/compare_commits.mako" />
570 % endif
570 % endif
571
571
572 <div class="cs_files">
572 <div class="cs_files">
573 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
573 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
574 ${cbdiffs.render_diffset_menu()}
574 ${cbdiffs.render_diffset_menu()}
575 ${cbdiffs.render_diffset(
575 ${cbdiffs.render_diffset(
576 c.diffset, use_comments=True,
576 c.diffset, use_comments=True,
577 collapse_when_files_over=30,
577 collapse_when_files_over=30,
578 disable_new_comments=not c.allowed_to_comment,
578 disable_new_comments=not c.allowed_to_comment,
579 deleted_files_comments=c.deleted_files_comments)}
579 deleted_files_comments=c.deleted_files_comments)}
580 </div>
580 </div>
581 % else:
581 % else:
582 ## skipping commits we need to clear the view for missing commits
582 ## skipping commits we need to clear the view for missing commits
583 <div style="clear:both;"></div>
583 <div style="clear:both;"></div>
584 % endif
584 % endif
585
585
586 </div>
586 </div>
587 </div>
587 </div>
588
588
589 ## template for inline comment form
589 ## template for inline comment form
590 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
590 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
591
591
592 ## render general comments
592 ## render general comments
593
593
594 <div id="comment-tr-show">
594 <div id="comment-tr-show">
595 <div class="comment">
595 <div class="comment">
596 % if general_outdated_comm_count_ver:
596 % if general_outdated_comm_count_ver:
597 <div class="meta">
597 <div class="meta">
598 % if general_outdated_comm_count_ver == 1:
598 % if general_outdated_comm_count_ver == 1:
599 ${_('there is {num} general comment from older versions').format(num=general_outdated_comm_count_ver)},
599 ${_('there is {num} general comment from older versions').format(num=general_outdated_comm_count_ver)},
600 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show it')}</a>
600 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show it')}</a>
601 % else:
601 % else:
602 ${_('there are {num} general comments from older versions').format(num=general_outdated_comm_count_ver)},
602 ${_('there are {num} general comments from older versions').format(num=general_outdated_comm_count_ver)},
603 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show them')}</a>
603 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show them')}</a>
604 % endif
604 % endif
605 </div>
605 </div>
606 % endif
606 % endif
607 </div>
607 </div>
608 </div>
608 </div>
609
609
610 ${comment.generate_comments(c.comments, include_pull_request=True, is_pull_request=True)}
610 ${comment.generate_comments(c.comments, include_pull_request=True, is_pull_request=True)}
611
611
612 % if not c.pull_request.is_closed():
612 % if not c.pull_request.is_closed():
613 ## merge status, and merge action
613 ## merge status, and merge action
614 <div class="pull-request-merge">
614 <div class="pull-request-merge">
615 <%include file="/pullrequests/pullrequest_merge_checks.mako"/>
615 <%include file="/pullrequests/pullrequest_merge_checks.mako"/>
616 </div>
616 </div>
617
617
618 ## main comment form and it status
618 ## main comment form and it status
619 ${comment.comments(h.url('pullrequest_comment', repo_name=c.repo_name,
619 ${comment.comments(h.url('pullrequest_comment', repo_name=c.repo_name,
620 pull_request_id=c.pull_request.pull_request_id),
620 pull_request_id=c.pull_request.pull_request_id),
621 c.pull_request_review_status,
621 c.pull_request_review_status,
622 is_pull_request=True, change_status=c.allowed_to_change_status)}
622 is_pull_request=True, change_status=c.allowed_to_change_status)}
623 %endif
623 %endif
624
624
625 <script type="text/javascript">
625 <script type="text/javascript">
626 if (location.hash) {
626 if (location.hash) {
627 var result = splitDelimitedHash(location.hash);
627 var result = splitDelimitedHash(location.hash);
628 var line = $('html').find(result.loc);
628 var line = $('html').find(result.loc);
629 // show hidden comments if we use location.hash
629 // show hidden comments if we use location.hash
630 if (line.hasClass('comment-general')) {
630 if (line.hasClass('comment-general')) {
631 $(line).show();
631 $(line).show();
632 } else if (line.hasClass('comment-inline')) {
632 } else if (line.hasClass('comment-inline')) {
633 $(line).show();
633 $(line).show();
634 var $cb = $(line).closest('.cb');
634 var $cb = $(line).closest('.cb');
635 $cb.removeClass('cb-collapsed')
635 $cb.removeClass('cb-collapsed')
636 }
636 }
637 if (line.length > 0){
637 if (line.length > 0){
638 offsetScroll(line, 70);
638 offsetScroll(line, 70);
639 }
639 }
640 }
640 }
641
641
642 versionController = new VersionController();
642 versionController = new VersionController();
643 versionController.init();
643 versionController.init();
644
644
645 reviewersController = new ReviewersController();
645 reviewersController = new ReviewersController();
646
646
647 $(function(){
647 $(function(){
648
648
649 // custom code mirror
649 // custom code mirror
650 var codeMirrorInstance = initPullRequestsCodeMirror('#pr-description-input');
650 var codeMirrorInstance = initPullRequestsCodeMirror('#pr-description-input');
651
651
652 var PRDetails = {
652 var PRDetails = {
653 editButton: $('#open_edit_pullrequest'),
653 editButton: $('#open_edit_pullrequest'),
654 closeButton: $('#close_edit_pullrequest'),
654 closeButton: $('#close_edit_pullrequest'),
655 deleteButton: $('#delete_pullrequest'),
655 deleteButton: $('#delete_pullrequest'),
656 viewFields: $('#pr-desc, #pr-title'),
656 viewFields: $('#pr-desc, #pr-title'),
657 editFields: $('#pr-desc-edit, #pr-title-edit, #pr-save'),
657 editFields: $('#pr-desc-edit, #pr-title-edit, #pr-save'),
658
658
659 init: function() {
659 init: function() {
660 var that = this;
660 var that = this;
661 this.editButton.on('click', function(e) { that.edit(); });
661 this.editButton.on('click', function(e) { that.edit(); });
662 this.closeButton.on('click', function(e) { that.view(); });
662 this.closeButton.on('click', function(e) { that.view(); });
663 },
663 },
664
664
665 edit: function(event) {
665 edit: function(event) {
666 this.viewFields.hide();
666 this.viewFields.hide();
667 this.editButton.hide();
667 this.editButton.hide();
668 this.deleteButton.hide();
668 this.deleteButton.hide();
669 this.closeButton.show();
669 this.closeButton.show();
670 this.editFields.show();
670 this.editFields.show();
671 codeMirrorInstance.refresh();
671 codeMirrorInstance.refresh();
672 },
672 },
673
673
674 view: function(event) {
674 view: function(event) {
675 this.editButton.show();
675 this.editButton.show();
676 this.deleteButton.show();
676 this.deleteButton.show();
677 this.editFields.hide();
677 this.editFields.hide();
678 this.closeButton.hide();
678 this.closeButton.hide();
679 this.viewFields.show();
679 this.viewFields.show();
680 }
680 }
681 };
681 };
682
682
683 var ReviewersPanel = {
683 var ReviewersPanel = {
684 editButton: $('#open_edit_reviewers'),
684 editButton: $('#open_edit_reviewers'),
685 closeButton: $('#close_edit_reviewers'),
685 closeButton: $('#close_edit_reviewers'),
686 addButton: $('#add_reviewer'),
686 addButton: $('#add_reviewer'),
687 removeButtons: $('.reviewer_member_remove,.reviewer_member_mandatory_remove,.reviewer_member_mandatory'),
687 removeButtons: $('.reviewer_member_remove,.reviewer_member_mandatory_remove,.reviewer_member_mandatory'),
688
688
689 init: function() {
689 init: function() {
690 var self = this;
690 var self = this;
691 this.editButton.on('click', function(e) { self.edit(); });
691 this.editButton.on('click', function(e) { self.edit(); });
692 this.closeButton.on('click', function(e) { self.close(); });
692 this.closeButton.on('click', function(e) { self.close(); });
693 },
693 },
694
694
695 edit: function(event) {
695 edit: function(event) {
696 this.editButton.hide();
696 this.editButton.hide();
697 this.closeButton.show();
697 this.closeButton.show();
698 this.addButton.show();
698 this.addButton.show();
699 this.removeButtons.css('visibility', 'visible');
699 this.removeButtons.css('visibility', 'visible');
700 // review rules
700 // review rules
701 reviewersController.loadReviewRules(
701 reviewersController.loadReviewRules(
702 ${c.pull_request.reviewer_data_json | n});
702 ${c.pull_request.reviewer_data_json | n});
703 },
703 },
704
704
705 close: function(event) {
705 close: function(event) {
706 this.editButton.show();
706 this.editButton.show();
707 this.closeButton.hide();
707 this.closeButton.hide();
708 this.addButton.hide();
708 this.addButton.hide();
709 this.removeButtons.css('visibility', 'hidden');
709 this.removeButtons.css('visibility', 'hidden');
710 // hide review rules
710 // hide review rules
711 reviewersController.hideReviewRules()
711 reviewersController.hideReviewRules()
712 }
712 }
713 };
713 };
714
714
715 PRDetails.init();
715 PRDetails.init();
716 ReviewersPanel.init();
716 ReviewersPanel.init();
717
717
718 showOutdated = function(self){
718 showOutdated = function(self){
719 $('.comment-inline.comment-outdated').show();
719 $('.comment-inline.comment-outdated').show();
720 $('.filediff-outdated').show();
720 $('.filediff-outdated').show();
721 $('.showOutdatedComments').hide();
721 $('.showOutdatedComments').hide();
722 $('.hideOutdatedComments').show();
722 $('.hideOutdatedComments').show();
723 };
723 };
724
724
725 hideOutdated = function(self){
725 hideOutdated = function(self){
726 $('.comment-inline.comment-outdated').hide();
726 $('.comment-inline.comment-outdated').hide();
727 $('.filediff-outdated').hide();
727 $('.filediff-outdated').hide();
728 $('.hideOutdatedComments').hide();
728 $('.hideOutdatedComments').hide();
729 $('.showOutdatedComments').show();
729 $('.showOutdatedComments').show();
730 };
730 };
731
731
732 refreshMergeChecks = function(){
732 refreshMergeChecks = function(){
733 var loadUrl = "${h.url.current(merge_checks=1)}";
733 var loadUrl = "${h.url.current(merge_checks=1)}";
734 $('.pull-request-merge').css('opacity', 0.3);
734 $('.pull-request-merge').css('opacity', 0.3);
735 $('.action-buttons-extra').css('opacity', 0.3);
735 $('.action-buttons-extra').css('opacity', 0.3);
736
736
737 $('.pull-request-merge').load(
737 $('.pull-request-merge').load(
738 loadUrl, function() {
738 loadUrl, function() {
739 $('.pull-request-merge').css('opacity', 1);
739 $('.pull-request-merge').css('opacity', 1);
740
740
741 $('.action-buttons-extra').css('opacity', 1);
741 $('.action-buttons-extra').css('opacity', 1);
742 injectCloseAction();
742 injectCloseAction();
743 }
743 }
744 );
744 );
745 };
745 };
746
746
747 injectCloseAction = function() {
747 injectCloseAction = function() {
748 var closeAction = $('#close-pull-request-action').html();
748 var closeAction = $('#close-pull-request-action').html();
749 var $actionButtons = $('.action-buttons-extra');
749 var $actionButtons = $('.action-buttons-extra');
750 // clear the action before
750 // clear the action before
751 $actionButtons.html("");
751 $actionButtons.html("");
752 $actionButtons.html(closeAction);
752 $actionButtons.html(closeAction);
753 };
753 };
754
754
755 closePullRequest = function (status) {
755 closePullRequest = function (status) {
756 // inject closing flag
756 // inject closing flag
757 $('.action-buttons-extra').append('<input type="hidden" class="close-pr-input" id="close_pull_request" value="1">');
757 $('.action-buttons-extra').append('<input type="hidden" class="close-pr-input" id="close_pull_request" value="1">');
758 $(generalCommentForm.statusChange).select2("val", status).trigger('change');
758 $(generalCommentForm.statusChange).select2("val", status).trigger('change');
759 $(generalCommentForm.submitForm).submit();
759 $(generalCommentForm.submitForm).submit();
760 };
760 };
761
761
762 $('#show-outdated-comments').on('click', function(e){
762 $('#show-outdated-comments').on('click', function(e){
763 var button = $(this);
763 var button = $(this);
764 var outdated = $('.comment-outdated');
764 var outdated = $('.comment-outdated');
765
765
766 if (button.html() === "(Show)") {
766 if (button.html() === "(Show)") {
767 button.html("(Hide)");
767 button.html("(Hide)");
768 outdated.show();
768 outdated.show();
769 } else {
769 } else {
770 button.html("(Show)");
770 button.html("(Show)");
771 outdated.hide();
771 outdated.hide();
772 }
772 }
773 });
773 });
774
774
775 $('.show-inline-comments').on('change', function(e){
775 $('.show-inline-comments').on('change', function(e){
776 var show = 'none';
776 var show = 'none';
777 var target = e.currentTarget;
777 var target = e.currentTarget;
778 if(target.checked){
778 if(target.checked){
779 show = ''
779 show = ''
780 }
780 }
781 var boxid = $(target).attr('id_for');
781 var boxid = $(target).attr('id_for');
782 var comments = $('#{0} .inline-comments'.format(boxid));
782 var comments = $('#{0} .inline-comments'.format(boxid));
783 var fn_display = function(idx){
783 var fn_display = function(idx){
784 $(this).css('display', show);
784 $(this).css('display', show);
785 };
785 };
786 $(comments).each(fn_display);
786 $(comments).each(fn_display);
787 var btns = $('#{0} .inline-comments-button'.format(boxid));
787 var btns = $('#{0} .inline-comments-button'.format(boxid));
788 $(btns).each(fn_display);
788 $(btns).each(fn_display);
789 });
789 });
790
790
791 $('#merge_pull_request_form').submit(function() {
791 $('#merge_pull_request_form').submit(function() {
792 if (!$('#merge_pull_request').attr('disabled')) {
792 if (!$('#merge_pull_request').attr('disabled')) {
793 $('#merge_pull_request').attr('disabled', 'disabled');
793 $('#merge_pull_request').attr('disabled', 'disabled');
794 }
794 }
795 return true;
795 return true;
796 });
796 });
797
797
798 $('#edit_pull_request').on('click', function(e){
798 $('#edit_pull_request').on('click', function(e){
799 var title = $('#pr-title-input').val();
799 var title = $('#pr-title-input').val();
800 var description = codeMirrorInstance.getValue();
800 var description = codeMirrorInstance.getValue();
801 editPullRequest(
801 editPullRequest(
802 "${c.repo_name}", "${c.pull_request.pull_request_id}",
802 "${c.repo_name}", "${c.pull_request.pull_request_id}",
803 title, description);
803 title, description);
804 });
804 });
805
805
806 $('#update_pull_request').on('click', function(e){
806 $('#update_pull_request').on('click', function(e){
807 $(this).attr('disabled', 'disabled');
807 $(this).attr('disabled', 'disabled');
808 $(this).addClass('disabled');
808 $(this).addClass('disabled');
809 $(this).html(_gettext('Saving...'));
809 $(this).html(_gettext('Saving...'));
810 reviewersController.updateReviewers(
810 reviewersController.updateReviewers(
811 "${c.repo_name}", "${c.pull_request.pull_request_id}");
811 "${c.repo_name}", "${c.pull_request.pull_request_id}");
812 });
812 });
813
813
814 $('#update_commits').on('click', function(e){
814 $('#update_commits').on('click', function(e){
815 var isDisabled = !$(e.currentTarget).attr('disabled');
815 var isDisabled = !$(e.currentTarget).attr('disabled');
816 $(e.currentTarget).attr('disabled', 'disabled');
816 $(e.currentTarget).attr('disabled', 'disabled');
817 $(e.currentTarget).addClass('disabled');
817 $(e.currentTarget).addClass('disabled');
818 $(e.currentTarget).removeClass('btn-primary');
818 $(e.currentTarget).removeClass('btn-primary');
819 $(e.currentTarget).text(_gettext('Updating...'));
819 $(e.currentTarget).text(_gettext('Updating...'));
820 if(isDisabled){
820 if(isDisabled){
821 updateCommits(
821 updateCommits(
822 "${c.repo_name}", "${c.pull_request.pull_request_id}");
822 "${c.repo_name}", "${c.pull_request.pull_request_id}");
823 }
823 }
824 });
824 });
825 // fixing issue with caches on firefox
825 // fixing issue with caches on firefox
826 $('#update_commits').removeAttr("disabled");
826 $('#update_commits').removeAttr("disabled");
827
827
828 $('.show-inline-comments').on('click', function(e){
828 $('.show-inline-comments').on('click', function(e){
829 var boxid = $(this).attr('data-comment-id');
829 var boxid = $(this).attr('data-comment-id');
830 var button = $(this);
830 var button = $(this);
831
831
832 if(button.hasClass("comments-visible")) {
832 if(button.hasClass("comments-visible")) {
833 $('#{0} .inline-comments'.format(boxid)).each(function(index){
833 $('#{0} .inline-comments'.format(boxid)).each(function(index){
834 $(this).hide();
834 $(this).hide();
835 });
835 });
836 button.removeClass("comments-visible");
836 button.removeClass("comments-visible");
837 } else {
837 } else {
838 $('#{0} .inline-comments'.format(boxid)).each(function(index){
838 $('#{0} .inline-comments'.format(boxid)).each(function(index){
839 $(this).show();
839 $(this).show();
840 });
840 });
841 button.addClass("comments-visible");
841 button.addClass("comments-visible");
842 }
842 }
843 });
843 });
844
844
845 // register submit callback on commentForm form to track TODOs
845 // register submit callback on commentForm form to track TODOs
846 window.commentFormGlobalSubmitSuccessCallback = function(){
846 window.commentFormGlobalSubmitSuccessCallback = function(){
847 refreshMergeChecks();
847 refreshMergeChecks();
848 };
848 };
849 // initial injection
849 // initial injection
850 injectCloseAction();
850 injectCloseAction();
851
851
852 ReviewerAutoComplete('#user');
852 ReviewerAutoComplete('#user');
853
853
854 })
854 })
855 </script>
855 </script>
856
856
857 </div>
857 </div>
858 </div>
858 </div>
859
859
860 </%def>
860 </%def>
General Comments 0
You need to be logged in to leave comments. Login now