##// END OF EJS Templates
drafts: show TODO drafts properly....
super-admin -
r4746:55b7721d default
parent child Browse files
Show More
@@ -1,159 +1,168 b''
1 1 ## snippet for sidebar elements
2 2 ## usage:
3 3 ## <%namespace name="sidebar" file="/base/sidebar.mako"/>
4 4 ## ${sidebar.comments_table()}
5 5 <%namespace name="base" file="/base/base.mako"/>
6 6
7 7 <%def name="comments_table(comments, counter_num, todo_comments=False, draft_comments=False, existing_ids=None, is_pr=True)">
8 8 <%
9 9 if todo_comments:
10 10 cls_ = 'todos-content-table'
11 11 def sorter(entry):
12 12 user_id = entry.author.user_id
13 13 resolved = '1' if entry.resolved else '0'
14 14 if user_id == c.rhodecode_user.user_id:
15 15 # own comments first
16 16 user_id = 0
17 17 return '{}'.format(str(entry.comment_id).zfill(10000))
18 18 elif draft_comments:
19 19 cls_ = 'drafts-content-table'
20 20 def sorter(entry):
21 21 return '{}'.format(str(entry.comment_id).zfill(10000))
22 22 else:
23 23 cls_ = 'comments-content-table'
24 24 def sorter(entry):
25 25 return '{}'.format(str(entry.comment_id).zfill(10000))
26 26
27 27 existing_ids = existing_ids or []
28 28
29 29 %>
30 30
31 31 <table class="todo-table ${cls_}" data-total-count="${len(comments)}" data-counter="${counter_num}">
32 32
33 33 % for loop_obj, comment_obj in h.looper(reversed(sorted(comments, key=sorter))):
34 34 <%
35 35 display = ''
36 36 _cls = ''
37 37 ## Extra precaution to not show drafts in the sidebar for todo/comments
38 38 if comment_obj.draft and not draft_comments:
39 39 continue
40 40 %>
41 41
42 42
43 43 <%
44 44 comment_ver_index = comment_obj.get_index_version(getattr(c, 'versions', []))
45 45 prev_comment_ver_index = 0
46 46 if loop_obj.previous:
47 47 prev_comment_ver_index = loop_obj.previous.get_index_version(getattr(c, 'versions', []))
48 48
49 49 ver_info = None
50 50 if getattr(c, 'versions', []):
51 51 ver_info = c.versions[comment_ver_index-1] if comment_ver_index else None
52 52 %>
53 53 <% hidden_at_ver = comment_obj.outdated_at_version_js(c.at_version_num) %>
54 54 <% is_from_old_ver = comment_obj.older_than_version_js(c.at_version_num) %>
55 55 <%
56 56 if (prev_comment_ver_index > comment_ver_index):
57 57 comments_ver_divider = comment_ver_index
58 58 else:
59 59 comments_ver_divider = None
60 60 %>
61 61
62 62 % if todo_comments:
63 63 % if comment_obj.resolved:
64 64 <% _cls = 'resolved-todo' %>
65 65 <% display = 'none' %>
66 66 % endif
67 67 % else:
68 68 ## SKIP TODOs we display them in other area
69 % if comment_obj.is_todo:
69 % if comment_obj.is_todo and not comment_obj.draft:
70 70 <% display = 'none' %>
71 71 % endif
72 72 ## Skip outdated comments
73 73 % if comment_obj.outdated:
74 74 <% display = 'none' %>
75 75 <% _cls = 'hidden-comment' %>
76 76 % endif
77 77 % endif
78 78
79 79 % if not todo_comments and comments_ver_divider:
80 80 <tr class="old-comments-marker">
81 81 <td colspan="3">
82 82 % if ver_info:
83 83 <code>v${comments_ver_divider} ${h.age_component(ver_info.created_on, time_is_local=True, tooltip=False)}</code>
84 84 % else:
85 85 <code>v${comments_ver_divider}</code>
86 86 % endif
87 87 </td>
88 88 </tr>
89 89
90 90 % endif
91 91
92 92 <tr class="${_cls}" style="display: ${display};" data-sidebar-comment-id="${comment_obj.comment_id}">
93 93 % if draft_comments:
94 94 <td style="width: 15px;">
95 95 ${h.checkbox('submit_draft', id=None, value=comment_obj.comment_id)}
96 96 </td>
97 97 % endif
98 98 <td class="td-todo-number">
99 99 <%
100 100 version_info = ''
101 101 if is_pr:
102 102 version_info = (' made in older version (v{})'.format(comment_ver_index) if is_from_old_ver == 'true' else ' made in this version')
103 103 %>
104 104 ## new comments, since refresh
105 105 % if existing_ids and comment_obj.comment_id not in existing_ids:
106 106 <div class="tooltip" style="position: absolute; left: 8px; color: #682668" title="New comment">
107 107 !
108 108 </div>
109 109 % endif
110 110
111 111 <%
112 112 data = h.json.dumps({
113 113 'comment_id': comment_obj.comment_id,
114 114 'version_info': version_info,
115 115 'file_name': comment_obj.f_path,
116 116 'line_no': comment_obj.line_no,
117 117 'outdated': comment_obj.outdated,
118 118 'inline': comment_obj.is_inline,
119 119 'is_todo': comment_obj.is_todo,
120 120 'created_on': h.format_date(comment_obj.created_on),
121 121 'datetime': '{}{}'.format(comment_obj.created_on, h.get_timezone(comment_obj.created_on, time_is_local=True)),
122 122 'review_status': (comment_obj.review_status or '')
123 123 })
124 124
125 icon = ''
126
125 127 if comment_obj.outdated:
126 icon = 'icon-comment-toggle'
128 icon += ' icon-comment-toggle'
127 129 elif comment_obj.is_inline:
128 icon = 'icon-code'
130 icon += ' icon-code'
129 131 else:
130 icon = 'icon-comment'
132 icon += ' icon-comment'
133
134 if comment_obj.draft:
135 if comment_obj.is_todo:
136 icon = 'icon-flag-filled icon-draft'
137 else:
138 icon = 'icon-comment icon-draft'
139
131 140 %>
132 141
133 142 <i id="commentHovercard${comment_obj.comment_id}"
134 143 class="${icon} tooltip-hovercard"
135 144 data-hovercard-url="javascript:sidebarComment(${comment_obj.comment_id})"
136 145 data-comment-json-b64='${h.b64(data)}'>
137 146 </i>
138 147
139 148 </td>
140 149
141 150 <td class="td-todo-gravatar">
142 151 ${base.gravatar(comment_obj.author.email, 16, user=comment_obj.author, tooltip=True, extra_class=['no-margin'])}
143 152 </td>
144 153 <td class="todo-comment-text-wrapper">
145 154 <div class="todo-comment-text ${('todo-resolved' if comment_obj.resolved else '')}">
146 155 <a class="${('todo-resolved' if comment_obj.resolved else '')} permalink"
147 156 href="#comment-${comment_obj.comment_id}"
148 157 onclick="return Rhodecode.comments.scrollToComment($('#comment-${comment_obj.comment_id}'), 0, ${hidden_at_ver})">
149 158
150 159 ${h.chop_at_smart(comment_obj.text, '\n', suffix_if_chopped='...')}
151 160 </a>
152 161 </div>
153 162 </td>
154 163 </tr>
155 164 % endfor
156 165
157 166 </table>
158 167
159 168 </%def> No newline at end of file
@@ -1,278 +1,278 b''
1 1 <%text>
2 2 <div style="display: none">
3 3
4 4 <script>
5 5 var CG = new ColorGenerator();
6 6 </script>
7 7
8 8 <script id="ejs_gravatarWithUser" type="text/template" class="ejsTemplate">
9 9
10 10 <%
11 11 if (size > 16) {
12 12 var gravatar_class = 'gravatar gravatar-large';
13 13 } else {
14 14 var gravatar_class = 'gravatar';
15 15 }
16 16
17 17 if (tooltip) {
18 18 var gravatar_class = gravatar_class + ' tooltip-hovercard';
19 19 }
20 20
21 21 var data_hovercard_alt = username;
22 22
23 23 %>
24 24
25 25 <%
26 26 if (show_disabled) {
27 27 var user_cls = 'user user-disabled';
28 28 } else {
29 29 var user_cls = 'user';
30 30 }
31 31 var data_hovercard_url = pyroutes.url('hovercard_user', {"user_id": user_id})
32 32 %>
33 33
34 34 <div class="rc-user">
35 35 <img class="<%= gravatar_class %>" height="<%= size %>" width="<%= size %>" data-hovercard-url="<%= data_hovercard_url %>" data-hovercard-alt="<%= data_hovercard_alt %>" src="<%- gravatar_url -%>">
36 36 <span class="<%= user_cls %>"> <%- user_link -%> </span>
37 37 </div>
38 38
39 39 </script>
40 40
41 41 <script id="ejs_reviewMemberEntry" type="text/template" class="ejsTemplate">
42 42 <%
43 43 if (create) {
44 44 var edit_visibility = 'visible';
45 45 } else {
46 46 var edit_visibility = 'hidden';
47 47 }
48 48
49 49 if (member.user_group && member.user_group.vote_rule) {
50 50 var reviewGroup = '<i class="icon-user-group"></i>';
51 51 var reviewGroupColor = CG.asRGB(CG.getColor(member.user_group.vote_rule));
52 52 } else {
53 53 var reviewGroup = null;
54 54 var reviewGroupColor = 'transparent';
55 55 }
56 56 var rule_show = rule_show || false;
57 57
58 58 if (rule_show) {
59 59 var rule_visibility = 'table-cell';
60 60 } else {
61 61 var rule_visibility = 'none';
62 62 }
63 63
64 64 %>
65 65
66 66 <tr id="reviewer_<%= member.user_id %>" class="reviewer_entry" tooltip="Review Group" data-reviewer-user-id="<%= member.user_id %>">
67 67
68 68 <% if (create) { %>
69 69 <td style="width: 1px"></td>
70 70 <% } else { %>
71 71 <td style="width: 20px">
72 72 <div class="tooltip presence-state" style="display: none; position: absolute; left: 2px" title="This users is currently at this page">
73 73 <i class="icon-eye" style="color: #0ac878"></i>
74 74 </div>
75 75 <% if (role === 'reviewer') { %>
76 76 <div class="reviewer_status tooltip" title="<%= review_status_label %>">
77 77 <i class="icon-circle review-status-<%= review_status %>"></i>
78 78 </div>
79 79 <% } else if (role === 'observer') { %>
80 80 <div class="tooltip" title="Observer without voting right.">
81 81 <i class="icon-circle-thin"></i>
82 82 </div>
83 83 <% } %>
84 84 </td>
85 85 <% } %>
86 86
87 87
88 88 <% if (mandatory) { %>
89 89 <td style="text-align: right;width: 10px;">
90 90 <div class="reviewer_member_mandatory tooltip" title="Mandatory reviewer">
91 91 <i class="icon-lock"></i>
92 92 </div>
93 93 </td>
94 94
95 95 <% } else { %>
96 96 <td style="text-align: right;width: 10px;">
97 97 <% if (allowed_to_update) { %>
98 98 <div class="<%=role %>_member_remove" onclick="reviewersController.removeMember(<%= member.user_id %>, true)" style="visibility: <%= edit_visibility %>;">
99 99 <i class="icon-remove" style="color: #e85e4d;"></i>
100 100 </div>
101 101 <% } %>
102 102 </td>
103 103 <% } %>
104 104
105 105 <td>
106 106 <div id="reviewer_<%= member.user_id %>_name" class="reviewer_name">
107 107 <%-
108 108 renderTemplate('gravatarWithUser', {
109 109 'size': 16,
110 110 'show_disabled': false,
111 111 'tooltip': true,
112 112 'username': member.username,
113 113 'user_id': member.user_id,
114 114 'user_link': member.user_link,
115 115 'gravatar_url': member.gravatar_link
116 116 })
117 117 %>
118 118 </div>
119 119 <% if (reviewGroup !== null) { %>
120 120 <span class="tooltip" title="Member of review group from rule: `<%= member.user_group.name %>`" style="color: <%= reviewGroupColor %>">
121 121 <%- reviewGroup %>
122 122 </span>
123 123 <% } %>
124 124 </td>
125 125
126 126 </tr>
127 127
128 128 <tr id="reviewer_<%= member.user_id %>_rules">
129 129 <td colspan="4" style="display: <%= rule_visibility %>" class="pr-user-rule-container">
130 130 <input type="hidden" name="__start__" value="reviewer:mapping">
131 131
132 132 <%if (member.user_group && member.user_group.vote_rule) { %>
133 133 <div class="reviewer_reason">
134 134
135 135 <%if (member.user_group.vote_rule == -1) {%>
136 136 - group votes required: ALL
137 137 <%} else {%>
138 138 - group votes required: <%= member.user_group.vote_rule %>
139 139 <%}%>
140 140 </div>
141 141 <%} %>
142 142
143 143 <input type="hidden" name="__start__" value="reasons:sequence">
144 144 <% for (var i = 0; i < reasons.length; i++) { %>
145 145 <% var reason = reasons[i] %>
146 146 <div class="reviewer_reason">- <%= reason %></div>
147 147 <input type="hidden" name="reason" value="<%= reason %>">
148 148 <% } %>
149 149 <input type="hidden" name="__end__" value="reasons:sequence">
150 150
151 151 <input type="hidden" name="__start__" value="rules:sequence">
152 152 <% for (var i = 0; i < member.rules.length; i++) { %>
153 153 <% var rule = member.rules[i] %>
154 154 <input type="hidden" name="rule_id" value="<%= rule %>">
155 155 <% } %>
156 156 <input type="hidden" name="__end__" value="rules:sequence">
157 157
158 158 <input id="reviewer_<%= member.user_id %>_input" type="hidden" value="<%= member.user_id %>" name="user_id" />
159 159 <input type="hidden" name="mandatory" value="<%= mandatory %>"/>
160 160 <input type="hidden" name="role" value="<%= role %>"/>
161 161
162 162 <input type="hidden" name="__end__" value="reviewer:mapping">
163 163 </td>
164 164 </tr>
165 165
166 166 </script>
167 167
168 168 <script id="ejs_commentVersion" type="text/template" class="ejsTemplate">
169 169
170 170 <%
171 171 if (size > 16) {
172 172 var gravatar_class = 'gravatar gravatar-large';
173 173 } else {
174 174 var gravatar_class = 'gravatar';
175 175 }
176 176
177 177 %>
178 178
179 179 <%
180 180 if (show_disabled) {
181 181 var user_cls = 'user user-disabled';
182 182 } else {
183 183 var user_cls = 'user';
184 184 }
185 185
186 186 %>
187 187
188 188 <div style='line-height: 20px'>
189 189 <img style="margin: -3px 0" class="<%= gravatar_class %>" height="<%= size %>" width="<%= size %>" src="<%- gravatar_url -%>">
190 190 <strong><%- user_name -%></strong>, <code>v<%- version -%></code> edited <%- timeago_component -%>
191 191 </div>
192 192
193 193 </script>
194 194
195 195
196 196 <script id="ejs_sideBarCommentHovercard" type="text/template" class="ejsTemplate">
197 197
198 198 <div>
199 199
200 200 <% if (is_todo) { %>
201 201 <% if (inline) { %>
202 202 <strong>Inline</strong> TODO (<code>#<%- comment_id -%></code>) on line: <%= line_no %>
203 203 <% if (version_info) { %>
204 204 <%= version_info %>
205 205 <% } %>
206 206 <br/>
207 207 File: <code><%- file_name -%></code>
208 208 <% } else { %>
209 209 <% if (review_status) { %>
210 210 <i class="icon-circle review-status-<%= review_status %>"></i>
211 211 <% } %>
212 212 <strong>General</strong> TODO (<code>#<%- comment_id -%></code>)
213 213 <% if (version_info) { %>
214 214 <%= version_info %>
215 215 <% } %>
216 216 <% } %>
217 217 <% } else { %>
218 218 <% if (inline) { %>
219 219 <strong>Inline</strong> comment (<code>#<%- comment_id -%></code>) on line: <%= line_no %>
220 220 <% if (version_info) { %>
221 221 <%= version_info %>
222 222 <% } %>
223 223 <br/>
224 224 File: <code><%= file_name -%></code>
225 225 <% } else { %>
226 226 <% if (review_status) { %>
227 227 <i class="icon-circle review-status-<%= review_status %>"></i>
228 228 <% } %>
229 229 <strong>General</strong> comment (<code>#<%- comment_id -%></code>)
230 230 <% if (version_info) { %>
231 231 <%= version_info %>
232 232 <% } %>
233 233 <% } %>
234 234 <% } %>
235 235 <br/>
236 236 Created:
237 237 <time class="timeago" title="<%= created_on %>" datetime="<%= datetime %>"><%= $.timeago(datetime) %></time>
238 238
239 239 <% if (is_todo) { %>
240 <div style="text-align: center; padding-top: 5px">
240 <div style="text-align: left; padding-top: 5px">
241 241 <a class="btn btn-sm" href="#resolveTodo<%- comment_id -%>" onclick="Rhodecode.comments.resolveTodo(this, '<%- comment_id -%>'); return false">
242 242 <strong>Resolve TODO</strong>
243 243 </a>
244 244 </div>
245 245 <% } %>
246 246
247 247 </div>
248 248
249 249 </script>
250 250
251 251 <script id="ejs_commentHelpHovercard" type="text/template" class="ejsTemplate">
252 252
253 253 <div>
254 254 Use <strong>@username</strong> mention syntax to send direct notification to this RhodeCode user.<br/>
255 255 Typing / starts autocomplete for certain action, e.g set review status, or comment type. <br/>
256 256 <br/>
257 257 Use <strong>Cmd/ctrl+enter</strong> to submit comment, or <strong>Shift+Cmd/ctrl+enter</strong> to submit a draft.<br/>
258 258 <br/>
259 259 <strong>Draft comments</strong> are private to the author, and trigger no notification to others.<br/>
260 260 They are permanent until deleted, or converted to regular comments.<br/>
261 261 <br/>
262 262 <br/>
263 263 </div>
264 264
265 265 </script>
266 266
267 267
268 268
269 269 ##// END OF EJS Templates
270 270 </div>
271 271
272 272
273 273 <script>
274 274 // registers the templates into global cache
275 275 registerTemplates();
276 276 </script>
277 277
278 278 </%text>
@@ -1,1061 +1,1060 b''
1 1 <%inherit file="/base/base.mako"/>
2 2 <%namespace name="base" file="/base/base.mako"/>
3 3 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
4 4 <%namespace name="sidebar" file="/base/sidebar.mako"/>
5 5
6 6
7 7 <%def name="title()">
8 8 ${_('{} Pull Request !{}').format(c.repo_name, c.pull_request.pull_request_id)}
9 9 %if c.rhodecode_name:
10 10 &middot; ${h.branding(c.rhodecode_name)}
11 11 %endif
12 12 </%def>
13 13
14 14 <%def name="breadcrumbs_links()">
15 15
16 16 </%def>
17 17
18 18 <%def name="menu_bar_nav()">
19 19 ${self.menu_items(active='repositories')}
20 20 </%def>
21 21
22 22 <%def name="menu_bar_subnav()">
23 23 ${self.repo_menu(active='showpullrequest')}
24 24 </%def>
25 25
26 26
27 27 <%def name="main()">
28 28 ## Container to gather extracted Tickets
29 29 <%
30 30 c.referenced_commit_issues = h.IssuesRegistry()
31 31 c.referenced_desc_issues = h.IssuesRegistry()
32 32 %>
33 33
34 34 <script type="text/javascript">
35 35 templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
36 36 templateContext.pull_request_data.pull_request_version = '${request.GET.get('version', '')}';
37 37 </script>
38 38
39 39 <div class="box">
40 40
41 41 <div class="box pr-summary">
42 42
43 43 <div class="summary-details block-left">
44 44 <div id="pr-title">
45 45 % if c.pull_request.is_closed():
46 46 <span class="pr-title-closed-tag tag">${_('Closed')}</span>
47 47 % endif
48 48 <input class="pr-title-input large disabled" disabled="disabled" name="pullrequest_title" type="text" value="${c.pull_request.title}">
49 49 </div>
50 50 <div id="pr-title-edit" class="input" style="display: none;">
51 51 <input class="pr-title-input large" id="pr-title-input" name="pullrequest_title" type="text" value="${c.pull_request.title}">
52 52 </div>
53 53
54 54 <% summary = lambda n:{False:'summary-short'}.get(n) %>
55 55 <div class="pr-details-title">
56 56 <div class="pull-left">
57 57 <a href="${h.route_path('pull_requests_global', pull_request_id=c.pull_request.pull_request_id)}">${_('Pull request !{}').format(c.pull_request.pull_request_id)}</a>
58 58 ${_('Created on')}
59 59 <span class="tooltip" title="${_('Last updated on')} ${h.format_date(c.pull_request.updated_on)}">${h.format_date(c.pull_request.created_on)},</span>
60 60 <span class="pr-details-title-author-pref">${_('by')}</span>
61 61 </div>
62 62
63 63 <div class="pull-left">
64 64 ${self.gravatar_with_user(c.pull_request.author.email, 16, tooltip=True)}
65 65 </div>
66 66
67 67 %if c.allowed_to_update:
68 68 <div class="pull-right">
69 69 <div id="edit_pull_request" class="action_button pr-save" style="display: none;">${_('Update title & description')}</div>
70 70 <div id="delete_pullrequest" class="action_button pr-save ${('' if c.allowed_to_delete else 'disabled' )}" style="display: none;">
71 71 % if c.allowed_to_delete:
72 72 ${h.secure_form(h.route_path('pullrequest_delete', repo_name=c.pull_request.target_repo.repo_name, pull_request_id=c.pull_request.pull_request_id), request=request)}
73 73 <input class="btn btn-link btn-danger no-margin" id="remove_${c.pull_request.pull_request_id}" name="remove_${c.pull_request.pull_request_id}"
74 74 onclick="submitConfirm(event, this, _gettext('Confirm to delete this pull request'), _gettext('Delete'), '${'!{}'.format(c.pull_request.pull_request_id)}')"
75 75 type="submit" value="${_('Delete pull request')}">
76 76 ${h.end_form()}
77 77 % else:
78 78 <span class="tooltip" title="${_('Not allowed to delete this pull request')}">${_('Delete pull request')}</span>
79 79 % endif
80 80 </div>
81 81 <div id="open_edit_pullrequest" class="action_button">${_('Edit')}</div>
82 82 <div id="close_edit_pullrequest" class="action_button" style="display: none;">${_('Cancel')}</div>
83 83 </div>
84 84
85 85 %endif
86 86 </div>
87 87
88 88 <div id="pr-desc" class="input" title="${_('Rendered using {} renderer').format(c.renderer)}">
89 89 ${h.render(c.pull_request.description, renderer=c.renderer, repo_name=c.repo_name, issues_container_callback=c.referenced_desc_issues())}
90 90 </div>
91 91
92 92 <div id="pr-desc-edit" class="input textarea" style="display: none;">
93 93 <input id="pr-renderer-input" type="hidden" name="description_renderer" value="${c.visual.default_renderer}">
94 94 ${dt.markup_form('pr-description-input', form_text=c.pull_request.description)}
95 95 </div>
96 96
97 97 <div id="summary" class="fields pr-details-content">
98 98
99 99 ## source
100 100 <div class="field">
101 101 <div class="label-pr-detail">
102 102 <label>${_('Commit flow')}:</label>
103 103 </div>
104 104 <div class="input">
105 105 <div class="pr-commit-flow">
106 106 ## Source
107 107 %if c.pull_request.source_ref_parts.type == 'branch':
108 108 <a href="${h.route_path('repo_commits', repo_name=c.pull_request.source_repo.repo_name, _query=dict(branch=c.pull_request.source_ref_parts.name))}"><code class="pr-source-info">${c.pull_request.source_ref_parts.type}:${c.pull_request.source_ref_parts.name}</code></a>
109 109 %else:
110 110 <code class="pr-source-info">${'{}:{}'.format(c.pull_request.source_ref_parts.type, c.pull_request.source_ref_parts.name)}</code>
111 111 %endif
112 112 ${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.repo_name}</a>
113 113 &rarr;
114 114 ## Target
115 115 %if c.pull_request.target_ref_parts.type == 'branch':
116 116 <a href="${h.route_path('repo_commits', repo_name=c.pull_request.target_repo.repo_name, _query=dict(branch=c.pull_request.target_ref_parts.name))}"><code class="pr-target-info">${c.pull_request.target_ref_parts.type}:${c.pull_request.target_ref_parts.name}</code></a>
117 117 %else:
118 118 <code class="pr-target-info">${'{}:{}'.format(c.pull_request.target_ref_parts.type, c.pull_request.target_ref_parts.name)}</code>
119 119 %endif
120 120
121 121 ${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.repo_name}</a>
122 122
123 123 <a class="source-details-action" href="#expand-source-details" onclick="return toggleElement(this, '.source-details')" data-toggle-on='<i class="icon-angle-down">more details</i>' data-toggle-off='<i class="icon-angle-up">less details</i>'>
124 124 <i class="icon-angle-down">more details</i>
125 125 </a>
126 126
127 127 </div>
128 128
129 129 <div class="source-details" style="display: none">
130 130
131 131 <ul>
132 132
133 133 ## common ancestor
134 134 <li>
135 135 ${_('Common ancestor')}:
136 136 % if c.ancestor_commit:
137 137 <a href="${h.route_path('repo_commit', repo_name=c.target_repo.repo_name, commit_id=c.ancestor_commit.raw_id)}">${h.show_id(c.ancestor_commit)}</a>
138 138 % else:
139 139 ${_('not available')}
140 140 % endif
141 141 </li>
142 142
143 143 ## pull url
144 144 <li>
145 145 %if h.is_hg(c.pull_request.source_repo):
146 146 <% clone_url = u'hg pull -r {} {}'.format(h.short_id(c.source_ref), c.pull_request.source_repo.clone_url()) %>
147 147 %elif h.is_git(c.pull_request.source_repo):
148 148 <% clone_url = u'git pull {} {}'.format(c.pull_request.source_repo.clone_url(), c.pull_request.source_ref_parts.name) %>
149 149 %endif
150 150
151 151 <span>${_('Pull changes from source')}</span>: <input type="text" class="input-monospace pr-pullinfo" value="${clone_url}" readonly="readonly">
152 152 <i class="tooltip icon-clipboard clipboard-action pull-right pr-pullinfo-copy" data-clipboard-text="${clone_url}" title="${_('Copy the pull url')}"></i>
153 153 </li>
154 154
155 155 ## Shadow repo
156 156 <li>
157 157 % if not c.pull_request.is_closed() and c.pull_request.shadow_merge_ref:
158 158 %if h.is_hg(c.pull_request.target_repo):
159 159 <% clone_url = 'hg clone --update {} {} pull-request-{}'.format(c.pull_request.shadow_merge_ref.name, c.shadow_clone_url, c.pull_request.pull_request_id) %>
160 160 %elif h.is_git(c.pull_request.target_repo):
161 161 <% clone_url = 'git clone --branch {} {} pull-request-{}'.format(c.pull_request.shadow_merge_ref.name, c.shadow_clone_url, c.pull_request.pull_request_id) %>
162 162 %endif
163 163
164 164 <span class="tooltip" title="${_('Clone repository in its merged state using shadow repository')}">${_('Clone from shadow repository')}</span>: <input type="text" class="input-monospace pr-mergeinfo" value="${clone_url}" readonly="readonly">
165 165 <i class="tooltip icon-clipboard clipboard-action pull-right pr-mergeinfo-copy" data-clipboard-text="${clone_url}" title="${_('Copy the clone url')}"></i>
166 166
167 167 % else:
168 168 <div class="">
169 169 ${_('Shadow repository data not available')}.
170 170 </div>
171 171 % endif
172 172 </li>
173 173
174 174 </ul>
175 175
176 176 </div>
177 177
178 178 </div>
179 179
180 180 </div>
181 181
182 182 ## versions
183 183 <div class="field">
184 184 <div class="label-pr-detail">
185 185 <label>${_('Versions')}:</label>
186 186 </div>
187 187
188 188 <% outdated_comm_count_ver = len(c.inline_versions[None]['outdated']) %>
189 189 <% general_outdated_comm_count_ver = len(c.comment_versions[None]['outdated']) %>
190 190
191 191 <div class="pr-versions">
192 192 % if c.show_version_changes:
193 193 <% outdated_comm_count_ver = len(c.inline_versions[c.at_version_num]['outdated']) %>
194 194 <% general_outdated_comm_count_ver = len(c.comment_versions[c.at_version_num]['outdated']) %>
195 195 ${_ungettext('{} version available for this pull request, ', '{} versions available for this pull request, ', len(c.versions)).format(len(c.versions))}
196 196 <a id="show-pr-versions" onclick="return versionController.toggleVersionView(this)" href="#show-pr-versions"
197 197 data-toggle-on="${_('show versions')}."
198 198 data-toggle-off="${_('hide versions')}.">
199 199 ${_('show versions')}.
200 200 </a>
201 201 <table>
202 202 ## SHOW ALL VERSIONS OF PR
203 203 <% ver_pr = None %>
204 204
205 205 % for data in reversed(list(enumerate(c.versions, 1))):
206 206 <% ver_pos = data[0] %>
207 207 <% ver = data[1] %>
208 208 <% ver_pr = ver.pull_request_version_id %>
209 209 <% display_row = '' if c.at_version and (c.at_version_num == ver_pr or c.from_version_num == ver_pr) else 'none' %>
210 210
211 211 <tr class="version-pr" style="display: ${display_row}">
212 212 <td>
213 213 <code>
214 214 <a href="${request.current_route_path(_query=dict(version=ver_pr or 'latest'))}">v${ver_pos}</a>
215 215 </code>
216 216 </td>
217 217 <td>
218 218 <input ${('checked="checked"' if c.from_version_index == ver_pr else '')} class="compare-radio-button" type="radio" name="ver_source" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/>
219 219 <input ${('checked="checked"' if c.at_version_num == ver_pr else '')} class="compare-radio-button" type="radio" name="ver_target" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/>
220 220 </td>
221 221 <td>
222 222 <% review_status = c.review_versions[ver_pr].status if ver_pr in c.review_versions else 'not_reviewed' %>
223 223 <i class="tooltip icon-circle review-status-${review_status}" title="${_('Your review status at this version')}"></i>
224 224
225 225 </td>
226 226 <td>
227 227 % if c.at_version_num != ver_pr:
228 228 <i class="tooltip icon-comment" title="${_('Comments from pull request version v{0}').format(ver_pos)}"></i>
229 229 <code>
230 230 General:${len(c.comment_versions[ver_pr]['at'])} / Inline:${len(c.inline_versions[ver_pr]['at'])}
231 231 </code>
232 232 % endif
233 233 </td>
234 234 <td>
235 235 ##<code>${ver.source_ref_parts.commit_id[:6]}</code>
236 236 </td>
237 237 <td>
238 238 <code>${h.age_component(ver.updated_on, time_is_local=True, tooltip=False)}</code>
239 239 </td>
240 240 </tr>
241 241 % endfor
242 242
243 243 <tr>
244 244 <td colspan="6">
245 245 <button id="show-version-diff" onclick="return versionController.showVersionDiff()" class="btn btn-sm" style="display: none"
246 246 data-label-text-locked="${_('select versions to show changes')}"
247 247 data-label-text-diff="${_('show changes between versions')}"
248 248 data-label-text-show="${_('show pull request for this version')}"
249 249 >
250 250 ${_('select versions to show changes')}
251 251 </button>
252 252 </td>
253 253 </tr>
254 254 </table>
255 255 % else:
256 256 <div>
257 257 ${_('Pull request versions not available')}.
258 258 </div>
259 259 % endif
260 260 </div>
261 261 </div>
262 262
263 263 </div>
264 264
265 265 </div>
266 266
267 267
268 268 </div>
269 269
270 270 </div>
271 271
272 272 <div class="box">
273 273
274 274 % if c.state_progressing:
275 275
276 276 <h2 style="text-align: center">
277 277 ${_('Cannot show diff when pull request state is changing. Current progress state')}: <span class="tag tag-merge-state-${c.pull_request.state}">${c.pull_request.state}</span><br/>
278 278 ${_('Consider refreshing the page to check if the status transition was finished')}.
279 279
280 280 % if c.is_super_admin or h.HasRepoPermissionAny('repository.admin')(c.repo_name):
281 281 <br/>
282 282 ${_('If you think this is an error try ')}<a href="${h.current_route_path(request, force_state='created')}">forced state reset</a> to <span class="tag tag-merge-state-created">created</span> state.
283 283 % endif
284 284 </h2>
285 285
286 286 % else:
287 287
288 288 ## Diffs rendered here
289 289 <div class="table" >
290 290 <div id="changeset_compare_view_content">
291 291 ##CS
292 292 % if c.missing_requirements:
293 293 <div class="box">
294 294 <div class="alert alert-warning">
295 295 <div>
296 296 <strong>${_('Missing requirements:')}</strong>
297 297 ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')}
298 298 </div>
299 299 </div>
300 300 </div>
301 301 % elif c.missing_commits:
302 302 <div class="box">
303 303 <div class="alert alert-warning">
304 304 <div>
305 305 <strong>${_('Missing commits')}:</strong>
306 306 ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')}<br/>
307 307 ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')}<br/>
308 308 ${_('Consider doing a `force update commits` in case you think this is an error.')}
309 309 </div>
310 310 </div>
311 311 </div>
312 312 % elif c.pr_merge_source_commit.changed and not c.pull_request.is_closed():
313 313 <div class="box">
314 314 <div class="alert alert-info">
315 315 <div>
316 316 <strong>${_('There are new changes for `{}:{}` in source repository, please consider updating this pull request.').format(c.pr_merge_source_commit.ref_spec.type, c.pr_merge_source_commit.ref_spec.name)}</strong>
317 317 </div>
318 318 </div>
319 319 </div>
320 320 % endif
321 321
322 322 <div class="compare_view_commits_title">
323 323 % if not c.compare_mode:
324 324
325 325 % if c.at_version_index:
326 326 <h4>
327 327 ${_('Showing changes at v{}, commenting is disabled.').format(c.at_version_index)}
328 328 </h4>
329 329 % endif
330 330
331 331 <div class="pull-left">
332 332 <div class="btn-group">
333 333 <a class="${('collapsed' if c.collapse_all_commits else '')}" href="#expand-commits" onclick="toggleCommitExpand(this); return false" data-toggle-commits-cnt=${len(c.commit_ranges)} >
334 334 % if c.collapse_all_commits:
335 335 <i class="icon-plus-squared-alt icon-no-margin"></i>
336 336 ${_ungettext('Expand {} commit', 'Expand {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))}
337 337 % else:
338 338 <i class="icon-minus-squared-alt icon-no-margin"></i>
339 339 ${_ungettext('Collapse {} commit', 'Collapse {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))}
340 340 % endif
341 341 </a>
342 342 </div>
343 343 </div>
344 344
345 345 <div class="pull-right">
346 346 % if c.allowed_to_update and not c.pull_request.is_closed():
347 347
348 348 <div class="btn-group btn-group-actions">
349 349 <a id="update_commits" class="btn btn-primary no-margin" onclick="updateController.updateCommits(this); return false">
350 350 ${_('Update commits')}
351 351 </a>
352 352
353 353 <a id="update_commits_switcher" class="tooltip btn btn-primary btn-more-option" data-toggle="dropdown" aria-pressed="false" role="button" title="${_('more update options')}">
354 354 <i class="icon-down"></i>
355 355 </a>
356 356
357 357 <div class="btn-action-switcher-container right-align" id="update-commits-switcher">
358 358 <ul class="btn-action-switcher" role="menu" style="min-width: 300px;">
359 359 <li>
360 360 <a href="#forceUpdate" onclick="updateController.forceUpdateCommits(this); return false">
361 361 ${_('Force update commits')}
362 362 </a>
363 363 <div class="action-help-block">
364 364 ${_('Update commits and force refresh this pull request.')}
365 365 </div>
366 366 </li>
367 367 </ul>
368 368 </div>
369 369 </div>
370 370
371 371 % else:
372 372 <a class="tooltip btn disabled pull-right" disabled="disabled" title="${_('Update is disabled for current view')}">${_('Update commits')}</a>
373 373 % endif
374 374
375 375 </div>
376 376 % endif
377 377 </div>
378 378
379 379 % if not c.missing_commits:
380 380 ## COMPARE RANGE DIFF MODE
381 381 % if c.compare_mode:
382 382 % if c.at_version:
383 383 <h4>
384 384 ${_('Commits and changes between v{ver_from} and {ver_to} of this pull request, commenting is disabled').format(ver_from=c.from_version_index, ver_to=c.at_version_index if c.at_version_index else 'latest')}:
385 385 </h4>
386 386
387 387 <div class="subtitle-compare">
388 388 ${_('commits added: {}, removed: {}').format(len(c.commit_changes_summary.added), len(c.commit_changes_summary.removed))}
389 389 </div>
390 390
391 391 <div class="container">
392 392 <table class="rctable compare_view_commits">
393 393 <tr>
394 394 <th></th>
395 395 <th>${_('Time')}</th>
396 396 <th>${_('Author')}</th>
397 397 <th>${_('Commit')}</th>
398 398 <th></th>
399 399 <th>${_('Description')}</th>
400 400 </tr>
401 401
402 402 % for c_type, commit in c.commit_changes:
403 403 % if c_type in ['a', 'r']:
404 404 <%
405 405 if c_type == 'a':
406 406 cc_title = _('Commit added in displayed changes')
407 407 elif c_type == 'r':
408 408 cc_title = _('Commit removed in displayed changes')
409 409 else:
410 410 cc_title = ''
411 411 %>
412 412 <tr id="row-${commit.raw_id}" commit_id="${commit.raw_id}" class="compare_select">
413 413 <td>
414 414 <div class="commit-change-indicator color-${c_type}-border">
415 415 <div class="commit-change-content color-${c_type} tooltip" title="${h.tooltip(cc_title)}">
416 416 ${c_type.upper()}
417 417 </div>
418 418 </div>
419 419 </td>
420 420 <td class="td-time">
421 421 ${h.age_component(commit.date)}
422 422 </td>
423 423 <td class="td-user">
424 424 ${base.gravatar_with_user(commit.author, 16, tooltip=True)}
425 425 </td>
426 426 <td class="td-hash">
427 427 <code>
428 428 <a href="${h.route_path('repo_commit', repo_name=c.target_repo.repo_name, commit_id=commit.raw_id)}">
429 429 r${commit.idx}:${h.short_id(commit.raw_id)}
430 430 </a>
431 431 ${h.hidden('revisions', commit.raw_id)}
432 432 </code>
433 433 </td>
434 434 <td class="td-message expand_commit" data-commit-id="${commit.raw_id}" title="${_( 'Expand commit message')}" onclick="commitsController.expandCommit(this); return false">
435 435 <i class="icon-expand-linked"></i>
436 436 </td>
437 437 <td class="mid td-description">
438 438 <div class="log-container truncate-wrap">
439 439 <div class="message truncate" id="c-${commit.raw_id}" data-message-raw="${commit.message}">${h.urlify_commit_message(commit.message, c.repo_name, issues_container_callback=c.referenced_commit_issues(commit.serialize()))}</div>
440 440 </div>
441 441 </td>
442 442 </tr>
443 443 % endif
444 444 % endfor
445 445 </table>
446 446 </div>
447 447
448 448 % endif
449 449
450 450 ## Regular DIFF
451 451 % else:
452 452 <%include file="/compare/compare_commits.mako" />
453 453 % endif
454 454
455 455 <div class="cs_files">
456 456 <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/>
457 457
458 458 <%
459 459 pr_menu_data = {
460 460 'outdated_comm_count_ver': outdated_comm_count_ver,
461 461 'pull_request': c.pull_request
462 462 }
463 463 %>
464 464
465 465 ${cbdiffs.render_diffset_menu(c.diffset, range_diff_on=c.range_diff_on, pull_request_menu=pr_menu_data)}
466 466
467 467 % if c.range_diff_on:
468 468 % for commit in c.commit_ranges:
469 469 ${cbdiffs.render_diffset(
470 470 c.changes[commit.raw_id],
471 471 commit=commit, use_comments=True,
472 472 collapse_when_files_over=5,
473 473 disable_new_comments=True,
474 474 deleted_files_comments=c.deleted_files_comments,
475 475 inline_comments=c.inline_comments,
476 476 pull_request_menu=pr_menu_data, show_todos=False)}
477 477 % endfor
478 478 % else:
479 479 ${cbdiffs.render_diffset(
480 480 c.diffset, use_comments=True,
481 481 collapse_when_files_over=30,
482 482 disable_new_comments=not c.allowed_to_comment,
483 483 deleted_files_comments=c.deleted_files_comments,
484 484 inline_comments=c.inline_comments,
485 485 pull_request_menu=pr_menu_data, show_todos=False)}
486 486 % endif
487 487
488 488 </div>
489 489 % else:
490 490 ## skipping commits we need to clear the view for missing commits
491 491 <div style="clear:both;"></div>
492 492 % endif
493 493
494 494 </div>
495 495 </div>
496 496
497 497 ## template for inline comment form
498 498 <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
499 499
500 500 ## comments heading with count
501 501 <div class="comments-heading">
502 502 <i class="icon-comment"></i>
503 503 ${_('General Comments')} ${len(c.comments)}
504 504 </div>
505 505
506 506 ## render general comments
507 507 <div id="comment-tr-show">
508 508 % if general_outdated_comm_count_ver:
509 509 <div class="info-box">
510 510 % if general_outdated_comm_count_ver == 1:
511 511 ${_('there is {num} general comment from older versions').format(num=general_outdated_comm_count_ver)},
512 512 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show it')}</a>
513 513 % else:
514 514 ${_('there are {num} general comments from older versions').format(num=general_outdated_comm_count_ver)},
515 515 <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show them')}</a>
516 516 % endif
517 517 </div>
518 518 % endif
519 519 </div>
520 520
521 521 ${comment.generate_comments(c.comments, include_pull_request=True, is_pull_request=True)}
522 522
523 523 % if not c.pull_request.is_closed():
524 524 ## main comment form and it status
525 525 ${comment.comments(h.route_path('pullrequest_comment_create', repo_name=c.repo_name,
526 526 pull_request_id=c.pull_request.pull_request_id),
527 527 c.pull_request_review_status,
528 528 is_pull_request=True, change_status=c.allowed_to_change_status)}
529 529
530 530 ## merge status, and merge action
531 531 <div class="pull-request-merge">
532 532 <%include file="/pullrequests/pullrequest_merge_checks.mako"/>
533 533 </div>
534 534
535 535 %endif
536 536
537 537 % endif
538 538 </div>
539 539
540 540
541 541 ### NAV SIDEBAR
542 542 <aside class="right-sidebar right-sidebar-expanded" id="pr-nav-sticky" style="display: none">
543 543 <div class="sidenav navbar__inner" >
544 544 ## TOGGLE
545 545 <div class="sidebar-toggle" onclick="toggleSidebar(); return false">
546 546 <a href="#toggleSidebar" class="grey-link-action">
547 547
548 548 </a>
549 549 </div>
550 550
551 551 ## CONTENT
552 552 <div class="sidebar-content">
553 553
554 554 ## Drafts
555 555 % if c.rhodecode_edition_id == 'EE':
556 556 <div id="draftsTable" class="sidebar-element clear-both" style="display: ${'block' if c.draft_comments else 'none'}">
557 557 <div class="tooltip right-sidebar-collapsed-state" style="display: none;" onclick="toggleSidebar(); return false" title="${_('Drafts')}">
558 558 <i class="icon-comment icon-draft"></i>
559 559 <span id="drafts-count">${len(c.draft_comments)}</span>
560 560 </div>
561 561
562 562 <div class="right-sidebar-expanded-state pr-details-title">
563 563 <span style="padding-left: 2px">
564 564 <input name="select_all_drafts" type="checkbox" onclick="selectDraftComments(event)">
565 565 </span>
566 566 <span class="sidebar-heading noselect" onclick="refreshDraftComments(); return false">
567 <i class="icon-comment icon-draft"></i>
568 567 ${_('Drafts')}
569 568 </span>
570 569 <span class="block-right action_button last-item" onclick="submitDrafts(event)">${_('Submit')}</span>
571 570 </div>
572 571
573 572 <div id="drafts" class="right-sidebar-expanded-state pr-details-content reviewers">
574 573 % if c.draft_comments:
575 574 ${sidebar.comments_table(c.draft_comments, len(c.draft_comments), draft_comments=True)}
576 575 % else:
577 576 <table class="drafts-content-table">
578 577 <tr>
579 578 <td>
580 579 ${_('No TODOs yet')}
581 580 </td>
582 581 </tr>
583 582 </table>
584 583 % endif
585 584 </div>
586 585
587 586 </div>
588 587 % endif
589 588
590 589 ## RULES SUMMARY/RULES
591 590 <div class="sidebar-element clear-both">
592 591 <% vote_title = _ungettext(
593 592 'Status calculated based on votes from {} reviewer',
594 593 'Status calculated based on votes from {} reviewers', c.reviewers_count).format(c.reviewers_count)
595 594 %>
596 595
597 596 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="${vote_title}">
598 597 <i class="icon-circle review-status-${c.pull_request_review_status}"></i>
599 598 ${c.reviewers_count}
600 599 </div>
601 600
602 601 ## REVIEWERS
603 602 <div class="right-sidebar-expanded-state pr-details-title">
604 603 <span class="tooltip sidebar-heading" title="${vote_title}">
605 604 <i class="icon-circle review-status-${c.pull_request_review_status}"></i>
606 605 ${_('Reviewers')}
607 606 </span>
608 607
609 608 %if c.allowed_to_update:
610 609 <span id="open_edit_reviewers" class="block-right action_button last-item">${_('Edit')}</span>
611 610 <span id="close_edit_reviewers" class="block-right action_button last-item" style="display: none;">${_('Close')}</span>
612 611 %else:
613 612 <span id="open_edit_reviewers" class="block-right action_button last-item">${_('Show rules')}</span>
614 613 <span id="close_edit_reviewers" class="block-right action_button last-item" style="display: none;">${_('Close')}</span>
615 614 %endif
616 615 </div>
617 616
618 617 <div id="reviewers" class="right-sidebar-expanded-state pr-details-content reviewers">
619 618
620 619 <div id="review_rules" style="display: none" class="">
621 620
622 621 <strong>${_('Reviewer rules')}</strong>
623 622 <div class="pr-reviewer-rules">
624 623 ## review rules will be appended here, by default reviewers logic
625 624 </div>
626 625 <input id="review_data" type="hidden" name="review_data" value="">
627 626 </div>
628 627
629 628 ## members redering block
630 629 <input type="hidden" name="__start__" value="review_members:sequence">
631 630
632 631 <table id="review_members" class="group_members">
633 632 ## This content is loaded via JS and ReviewersPanel
634 633 </table>
635 634
636 635 <input type="hidden" name="__end__" value="review_members:sequence">
637 636 ## end members redering block
638 637
639 638 %if not c.pull_request.is_closed():
640 639 <div id="add_reviewer" class="ac" style="display: none;">
641 640 %if c.allowed_to_update:
642 641 % if not c.forbid_adding_reviewers:
643 642 <div id="add_reviewer_input" class="reviewer_ac" style="width: 240px">
644 643 <input class="ac-input" id="user" name="user" placeholder="${_('Add reviewer or reviewer group')}" type="text" autocomplete="off">
645 644 <div id="reviewers_container"></div>
646 645 </div>
647 646 % endif
648 647 <div class="pull-right" style="margin-bottom: 15px">
649 648 <button data-role="reviewer" id="update_reviewers" class="btn btn-sm no-margin">${_('Save Changes')}</button>
650 649 </div>
651 650 %endif
652 651 </div>
653 652 %endif
654 653 </div>
655 654 </div>
656 655
657 656 ## OBSERVERS
658 657 % if c.rhodecode_edition_id == 'EE':
659 658 <div class="sidebar-element clear-both">
660 659 <% vote_title = _ungettext(
661 660 '{} observer without voting right.',
662 661 '{} observers without voting right.', c.observers_count).format(c.observers_count)
663 662 %>
664 663
665 664 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="${vote_title}">
666 665 <i class="icon-circle-thin"></i>
667 666 ${c.observers_count}
668 667 </div>
669 668
670 669 <div class="right-sidebar-expanded-state pr-details-title">
671 670 <span class="tooltip sidebar-heading" title="${vote_title}">
672 671 <i class="icon-circle-thin"></i>
673 672 ${_('Observers')}
674 673 </span>
675 674 %if c.allowed_to_update:
676 675 <span id="open_edit_observers" class="block-right action_button last-item">${_('Edit')}</span>
677 676 <span id="close_edit_observers" class="block-right action_button last-item" style="display: none;">${_('Close')}</span>
678 677 %endif
679 678 </div>
680 679
681 680 <div id="observers" class="right-sidebar-expanded-state pr-details-content reviewers">
682 681 ## members redering block
683 682 <input type="hidden" name="__start__" value="observer_members:sequence">
684 683
685 684 <table id="observer_members" class="group_members">
686 685 ## This content is loaded via JS and ReviewersPanel
687 686 </table>
688 687
689 688 <input type="hidden" name="__end__" value="observer_members:sequence">
690 689 ## end members redering block
691 690
692 691 %if not c.pull_request.is_closed():
693 692 <div id="add_observer" class="ac" style="display: none;">
694 693 %if c.allowed_to_update:
695 694 % if not c.forbid_adding_reviewers or 1:
696 695 <div id="add_reviewer_input" class="reviewer_ac" style="width: 240px" >
697 696 <input class="ac-input" id="observer" name="observer" placeholder="${_('Add observer or observer group')}" type="text" autocomplete="off">
698 697 <div id="observers_container"></div>
699 698 </div>
700 699 % endif
701 700 <div class="pull-right" style="margin-bottom: 15px">
702 701 <button data-role="observer" id="update_observers" class="btn btn-sm no-margin">${_('Save Changes')}</button>
703 702 </div>
704 703 %endif
705 704 </div>
706 705 %endif
707 706 </div>
708 707 </div>
709 708 % endif
710 709
711 710 ## TODOs
712 711 <div id="todosTable" class="sidebar-element clear-both">
713 712 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="TODOs">
714 713 <i class="icon-flag-filled"></i>
715 714 <span id="todos-count">${len(c.unresolved_comments)}</span>
716 715 </div>
717 716
718 717 <div class="right-sidebar-expanded-state pr-details-title">
719 718 ## Only show unresolved, that is only what matters
720 719 <span class="sidebar-heading noselect" onclick="refreshTODOs(); return false">
721 720 <i class="icon-flag-filled"></i>
722 721 TODOs
723 722 </span>
724 723
725 724 % if not c.at_version:
726 725 % if c.resolved_comments:
727 726 <span class="block-right action_button last-item noselect" onclick="$('.unresolved-todo-text').toggle(); return toggleElement(this, '.resolved-todo');" data-toggle-on="Show resolved" data-toggle-off="Hide resolved">Show resolved</span>
728 727 % else:
729 728 <span class="block-right last-item noselect">Show resolved</span>
730 729 % endif
731 730 % endif
732 731 </div>
733 732
734 733 <div class="right-sidebar-expanded-state pr-details-content">
735 734
736 735 % if c.at_version:
737 736 <table>
738 737 <tr>
739 738 <td class="unresolved-todo-text">${_('TODOs unavailable when browsing versions')}.</td>
740 739 </tr>
741 740 </table>
742 741 % else:
743 742 % if c.unresolved_comments + c.resolved_comments:
744 743 ${sidebar.comments_table(c.unresolved_comments + c.resolved_comments, len(c.unresolved_comments), todo_comments=True)}
745 744 % else:
746 745 <table class="todos-content-table">
747 746 <tr>
748 747 <td>
749 748 ${_('No TODOs yet')}
750 749 </td>
751 750 </tr>
752 751 </table>
753 752 % endif
754 753 % endif
755 754 </div>
756 755 </div>
757 756
758 757 ## COMMENTS
759 758 <div id="commentsTable" class="sidebar-element clear-both">
760 759 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="${_('Comments')}">
761 760 <i class="icon-comment" style="color: #949494"></i>
762 761 <span id="comments-count">${len(c.inline_comments_flat+c.comments)}</span>
763 762 <span class="display-none" id="general-comments-count">${len(c.comments)}</span>
764 763 <span class="display-none" id="inline-comments-count">${len(c.inline_comments_flat)}</span>
765 764 </div>
766 765
767 766 <div class="right-sidebar-expanded-state pr-details-title">
768 767 <span class="sidebar-heading noselect" onclick="refreshComments(); return false">
769 768 <i class="icon-comment" style="color: #949494"></i>
770 769 ${_('Comments')}
771 770
772 771 ## % if outdated_comm_count_ver:
773 772 ## <a href="#" onclick="showOutdated(); Rhodecode.comments.nextOutdatedComment(); return false;">
774 773 ## (${_("{} Outdated").format(outdated_comm_count_ver)})
775 774 ## </a>
776 775 ## <a href="#" class="showOutdatedComments" onclick="showOutdated(this); return false;"> | ${_('show outdated')}</a>
777 776 ## <a href="#" class="hideOutdatedComments" style="display: none" onclick="hideOutdated(this); return false;"> | ${_('hide outdated')}</a>
778 777
779 778 ## % else:
780 779 ## (${_("{} Outdated").format(outdated_comm_count_ver)})
781 780 ## % endif
782 781
783 782 </span>
784 783
785 784 % if outdated_comm_count_ver:
786 785 <span class="block-right action_button last-item noselect" onclick="return toggleElement(this, '.hidden-comment');" data-toggle-on="Show outdated" data-toggle-off="Hide outdated">Show outdated</span>
787 786 % else:
788 787 <span class="block-right last-item noselect">Show hidden</span>
789 788 % endif
790 789
791 790 </div>
792 791
793 792 <div class="right-sidebar-expanded-state pr-details-content">
794 793 % if c.inline_comments_flat + c.comments:
795 794 ${sidebar.comments_table(c.inline_comments_flat + c.comments, len(c.inline_comments_flat+c.comments))}
796 795 % else:
797 796 <table class="comments-content-table">
798 797 <tr>
799 798 <td>
800 799 ${_('No Comments yet')}
801 800 </td>
802 801 </tr>
803 802 </table>
804 803 % endif
805 804 </div>
806 805
807 806 </div>
808 807
809 808 ## Referenced Tickets
810 809 <div class="sidebar-element clear-both">
811 810 <div class="tooltip right-sidebar-collapsed-state" style="display: none" onclick="toggleSidebar(); return false" title="${_('Referenced Tickets')}">
812 811 <i class="icon-info-circled"></i>
813 812 ${(c.referenced_desc_issues.issues_unique_count + c.referenced_commit_issues.issues_unique_count)}
814 813 </div>
815 814
816 815 <div class="right-sidebar-expanded-state pr-details-title">
817 816 <span class="sidebar-heading">
818 817 <i class="icon-info-circled"></i>
819 818 ${_('Referenced Tickets')}
820 819 </span>
821 820 </div>
822 821 <div class="right-sidebar-expanded-state pr-details-content">
823 822 <table>
824 823
825 824 <tr><td><code>${_('In pull request description')}:</code></td></tr>
826 825 % if c.referenced_desc_issues.issues:
827 826
828 827 % for ticket_id, ticket_dict in c.referenced_desc_issues.unique_issues.items():
829 828 <tr>
830 829 <td>
831 830 <a href="${ticket_dict[0].get('url')}">
832 831 ${ticket_id}
833 832 </a>
834 833 </td>
835 834 </tr>
836 835
837 836 % endfor
838 837 % else:
839 838 <tr>
840 839 <td>
841 840 ${_('No Ticket data found.')}
842 841 </td>
843 842 </tr>
844 843 % endif
845 844
846 845 <tr><td style="padding-top: 10px"><code>${_('In commit messages')}:</code></td></tr>
847 846 % if c.referenced_commit_issues.issues:
848 847 % for ticket_id, ticket_dict in c.referenced_commit_issues.unique_issues.items():
849 848 <tr>
850 849 <td>
851 850 <a href="${ticket_dict[0].get('url')}">
852 851 ${ticket_id}
853 852 </a>
854 853 - ${_ungettext('in %s commit', 'in %s commits', len(ticket_dict)) % (len(ticket_dict))}
855 854 </td>
856 855 </tr>
857 856 % endfor
858 857 % else:
859 858 <tr>
860 859 <td>
861 860 ${_('No Ticket data found.')}
862 861 </td>
863 862 </tr>
864 863 % endif
865 864 </table>
866 865
867 866 </div>
868 867 </div>
869 868
870 869 </div>
871 870
872 871 </div>
873 872 </aside>
874 873
875 874 ## This JS needs to be at the end
876 875 <script type="text/javascript">
877 876
878 877 versionController = new VersionController();
879 878 versionController.init();
880 879
881 880 reviewersController = new ReviewersController();
882 881 commitsController = new CommitsController();
883 882 commentsController = new CommentsController();
884 883
885 884 updateController = new UpdatePrController();
886 885
887 886 window.reviewerRulesData = ${c.pull_request_default_reviewers_data_json | n};
888 887 window.setReviewersData = ${c.pull_request_set_reviewers_data_json | n};
889 888 window.setObserversData = ${c.pull_request_set_observers_data_json | n};
890 889
891 890 (function () {
892 891 "use strict";
893 892
894 893 // custom code mirror
895 894 var codeMirrorInstance = $('#pr-description-input').get(0).MarkupForm.cm;
896 895
897 896 PRDetails.init();
898 897 ReviewersPanel.init(reviewersController, reviewerRulesData, setReviewersData);
899 898 ObserversPanel.init(reviewersController, reviewerRulesData, setObserversData);
900 899
901 900 window.showOutdated = function (self) {
902 901 $('.comment-inline.comment-outdated').show();
903 902 $('.filediff-outdated').show();
904 903 $('.showOutdatedComments').hide();
905 904 $('.hideOutdatedComments').show();
906 905 };
907 906
908 907 window.hideOutdated = function (self) {
909 908 $('.comment-inline.comment-outdated').hide();
910 909 $('.filediff-outdated').hide();
911 910 $('.hideOutdatedComments').hide();
912 911 $('.showOutdatedComments').show();
913 912 };
914 913
915 914 window.refreshMergeChecks = function () {
916 915 var loadUrl = "${request.current_route_path(_query=dict(merge_checks=1))}";
917 916 $('.pull-request-merge').css('opacity', 0.3);
918 917 $('.action-buttons-extra').css('opacity', 0.3);
919 918
920 919 $('.pull-request-merge').load(
921 920 loadUrl, function () {
922 921 $('.pull-request-merge').css('opacity', 1);
923 922
924 923 $('.action-buttons-extra').css('opacity', 1);
925 924 }
926 925 );
927 926 };
928 927
929 928 window.submitDrafts = function (event) {
930 929 var target = $(event.currentTarget);
931 930 var callback = function (result) {
932 931 target.removeAttr('onclick').html('saving...');
933 932 }
934 933 var draftIds = [];
935 934 $.each($('[name=submit_draft]:checked'), function (idx, val) {
936 935 draftIds.push(parseInt($(val).val()));
937 936 })
938 937 if (draftIds.length > 0) {
939 938 Rhodecode.comments.finalizeDrafts(draftIds, callback);
940 939 }
941 940 else {
942 941
943 942 }
944 943 }
945 944
946 945 window.selectDraftComments = function (event) {
947 946 var $target = $(event.currentTarget);
948 947 $('[name=submit_draft]').prop('checked', $target.prop('checked'))
949 948 }
950 949
951 950 window.closePullRequest = function (status) {
952 951 if (!confirm(_gettext('Are you sure to close this pull request without merging?'))) {
953 952 return false;
954 953 }
955 954 // inject closing flag
956 955 $('.action-buttons-extra').append('<input type="hidden" class="close-pr-input" id="close_pull_request" value="1">');
957 956 $(generalCommentForm.statusChange).select2("val", status).trigger('change');
958 957 $(generalCommentForm.submitForm).submit();
959 958 };
960 959
961 960 //TODO this functionality is now missing
962 961 $('#show-outdated-comments').on('click', function (e) {
963 962 var button = $(this);
964 963 var outdated = $('.comment-outdated');
965 964
966 965 if (button.html() === "(Show)") {
967 966 button.html("(Hide)");
968 967 outdated.show();
969 968 } else {
970 969 button.html("(Show)");
971 970 outdated.hide();
972 971 }
973 972 });
974 973
975 974 $('#merge_pull_request_form').submit(function () {
976 975 if (!$('#merge_pull_request').attr('disabled')) {
977 976 $('#merge_pull_request').attr('disabled', 'disabled');
978 977 }
979 978 return true;
980 979 });
981 980
982 981 $('#edit_pull_request').on('click', function (e) {
983 982 var title = $('#pr-title-input').val();
984 983 var description = codeMirrorInstance.getValue();
985 984 var renderer = $('#pr-renderer-input').val();
986 985 editPullRequest(
987 986 "${c.repo_name}", "${c.pull_request.pull_request_id}",
988 987 title, description, renderer);
989 988 });
990 989
991 990 var $updateButtons = $('#update_reviewers,#update_observers');
992 991 $updateButtons.on('click', function (e) {
993 992 var role = $(this).data('role');
994 993 $updateButtons.attr('disabled', 'disabled');
995 994 $updateButtons.addClass('disabled');
996 995 $updateButtons.html(_gettext('Saving...'));
997 996 reviewersController.updateReviewers(
998 997 templateContext.repo_name,
999 998 templateContext.pull_request_data.pull_request_id,
1000 999 role
1001 1000 );
1002 1001 });
1003 1002
1004 1003 // fixing issue with caches on firefox
1005 1004 $('#update_commits').removeAttr("disabled");
1006 1005
1007 1006 $('.show-inline-comments').on('click', function (e) {
1008 1007 var boxid = $(this).attr('data-comment-id');
1009 1008 var button = $(this);
1010 1009
1011 1010 if (button.hasClass("comments-visible")) {
1012 1011 $('#{0} .inline-comments'.format(boxid)).each(function (index) {
1013 1012 $(this).hide();
1014 1013 });
1015 1014 button.removeClass("comments-visible");
1016 1015 } else {
1017 1016 $('#{0} .inline-comments'.format(boxid)).each(function (index) {
1018 1017 $(this).show();
1019 1018 });
1020 1019 button.addClass("comments-visible");
1021 1020 }
1022 1021 });
1023 1022
1024 1023 $('.show-inline-comments').on('change', function (e) {
1025 1024 var show = 'none';
1026 1025 var target = e.currentTarget;
1027 1026 if (target.checked) {
1028 1027 show = ''
1029 1028 }
1030 1029 var boxid = $(target).attr('id_for');
1031 1030 var comments = $('#{0} .inline-comments'.format(boxid));
1032 1031 var fn_display = function (idx) {
1033 1032 $(this).css('display', show);
1034 1033 };
1035 1034 $(comments).each(fn_display);
1036 1035 var btns = $('#{0} .inline-comments-button'.format(boxid));
1037 1036 $(btns).each(fn_display);
1038 1037 });
1039 1038
1040 1039 // register submit callback on commentForm form to track TODOs, and refresh mergeChecks conditions
1041 1040 window.commentFormGlobalSubmitSuccessCallback = function (comment) {
1042 1041 if (!comment.draft) {
1043 1042 refreshMergeChecks();
1044 1043 }
1045 1044 };
1046 1045
1047 1046 ReviewerAutoComplete('#user', reviewersController);
1048 1047 ObserverAutoComplete('#observer', reviewersController);
1049 1048
1050 1049 })();
1051 1050
1052 1051 $(document).ready(function () {
1053 1052
1054 1053 var channel = '${c.pr_broadcast_channel}';
1055 1054 new ReviewerPresenceController(channel)
1056 1055 // register globally so inject comment logic can re-use it.
1057 1056 window.commentsController = commentsController;
1058 1057 })
1059 1058 </script>
1060 1059
1061 1060 </%def>
General Comments 0
You need to be logged in to leave comments. Login now