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