##// END OF EJS Templates
ux: add comments id to comments form so that linking to comments works
dan -
r1184:0e3d172c default
parent child Browse files
Show More
@@ -1,287 +1,289 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 ## usage:
2 ## usage:
3 ## <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
3 ## <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
4 ## ${comment.comment_block(comment)}
4 ## ${comment.comment_block(comment)}
5 ##
5 ##
6 <%namespace name="base" file="/base/base.html"/>
6 <%namespace name="base" file="/base/base.html"/>
7
7
8 <%def name="comment_block(comment, inline=False)">
8 <%def name="comment_block(comment, inline=False)">
9 <div
9 <div
10 class="comment
10 class="comment
11 ${'comment-inline' if inline else ''}
11 ${'comment-inline' if inline else ''}
12 ${'comment-outdated' if comment.outdated else 'comment-current'}"
12 ${'comment-outdated' if comment.outdated else 'comment-current'}"
13 "
13 "
14 id="comment-${comment.comment_id}"
14 id="comment-${comment.comment_id}"
15 line="${comment.line_no}"
15 line="${comment.line_no}"
16 data-comment-id="${comment.comment_id}">
16 data-comment-id="${comment.comment_id}">
17 <div class="meta">
17 <div class="meta">
18 <div class="author">
18 <div class="author">
19 ${base.gravatar_with_user(comment.author.email, 16)}
19 ${base.gravatar_with_user(comment.author.email, 16)}
20 </div>
20 </div>
21 <div class="date">
21 <div class="date">
22 ${h.age_component(comment.modified_at, time_is_local=True)}
22 ${h.age_component(comment.modified_at, time_is_local=True)}
23 </div>
23 </div>
24 <div class="status-change">
24 <div class="status-change">
25 %if comment.pull_request:
25 %if comment.pull_request:
26 <a href="${h.url('pullrequest_show',repo_name=comment.pull_request.target_repo.repo_name,pull_request_id=comment.pull_request.pull_request_id)}">
26 <a href="${h.url('pullrequest_show',repo_name=comment.pull_request.target_repo.repo_name,pull_request_id=comment.pull_request.pull_request_id)}">
27 %if comment.status_change:
27 %if comment.status_change:
28 ${_('Vote on pull request #%s') % comment.pull_request.pull_request_id}:
28 ${_('Vote on pull request #%s') % comment.pull_request.pull_request_id}:
29 %else:
29 %else:
30 ${_('Comment on pull request #%s') % comment.pull_request.pull_request_id}
30 ${_('Comment on pull request #%s') % comment.pull_request.pull_request_id}
31 %endif
31 %endif
32 </a>
32 </a>
33 %else:
33 %else:
34 %if comment.status_change:
34 %if comment.status_change:
35 ${_('Status change on commit')}:
35 ${_('Status change on commit')}:
36 %else:
36 %else:
37 ${_('Comment on commit')}
37 ${_('Comment on commit')}
38 %endif
38 %endif
39 %endif
39 %endif
40 </div>
40 </div>
41 %if comment.status_change:
41 %if comment.status_change:
42 <div class="${'flag_status %s' % comment.status_change[0].status}"></div>
42 <div class="${'flag_status %s' % comment.status_change[0].status}"></div>
43 <div title="${_('Commit status')}" class="changeset-status-lbl">
43 <div title="${_('Commit status')}" class="changeset-status-lbl">
44 ${comment.status_change[0].status_lbl}
44 ${comment.status_change[0].status_lbl}
45 </div>
45 </div>
46 %endif
46 %endif
47 <a class="permalink" href="#comment-${comment.comment_id}"> &para;</a>
47 <a class="permalink" href="#comment-${comment.comment_id}"> &para;</a>
48
48
49
49
50 <div class="comment-links-block">
50 <div class="comment-links-block">
51
51
52 ## show delete comment if it's not a PR (regular comments) or it's PR that is not closed
52 ## show delete comment if it's not a PR (regular comments) or it's PR that is not closed
53 ## only super-admin, repo admin OR comment owner can delete
53 ## only super-admin, repo admin OR comment owner can delete
54 %if not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed()):
54 %if not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed()):
55 %if h.HasPermissionAny('hg.admin')() or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or comment.author.user_id == c.rhodecode_user.user_id:
55 %if h.HasPermissionAny('hg.admin')() or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or comment.author.user_id == c.rhodecode_user.user_id:
56 ## TODO: dan: add edit comment here
56 ## TODO: dan: add edit comment here
57 <a onclick="return Rhodecode.comments.deleteComment(this);" class="delete-comment"> ${_('Delete')}</a> |
57 <a onclick="return Rhodecode.comments.deleteComment(this);" class="delete-comment"> ${_('Delete')}</a> |
58 %if not comment.outdated:
58 %if not comment.outdated:
59 <a onclick="return Rhodecode.comments.prevComment(this);" class="prev-comment"> ${_('Prev')}</a> |
59 <a onclick="return Rhodecode.comments.prevComment(this);" class="prev-comment"> ${_('Prev')}</a> |
60 <a onclick="return Rhodecode.comments.nextComment(this);" class="next-comment"> ${_('Next')}</a>
60 <a onclick="return Rhodecode.comments.nextComment(this);" class="next-comment"> ${_('Next')}</a>
61 %endif
61 %endif
62 %endif
62 %endif
63 %endif
63 %endif
64
64
65 </div>
65 </div>
66 </div>
66 </div>
67 <div class="text">
67 <div class="text">
68 ${comment.render(mentions=True)|n}
68 ${comment.render(mentions=True)|n}
69 </div>
69 </div>
70 </div>
70 </div>
71 </%def>
71 </%def>
72
72
73 <%def name="comment_block_outdated(comment)">
73 <%def name="comment_block_outdated(comment)">
74 <div class="comments" id="comment-${comment.comment_id}">
74 <div class="comments" id="comment-${comment.comment_id}">
75 <div class="comment comment-wrapp">
75 <div class="comment comment-wrapp">
76 <div class="meta">
76 <div class="meta">
77 <div class="author">
77 <div class="author">
78 ${base.gravatar_with_user(comment.author.email, 16)}
78 ${base.gravatar_with_user(comment.author.email, 16)}
79 </div>
79 </div>
80 <div class="date">
80 <div class="date">
81 ${h.age_component(comment.modified_at, time_is_local=True)}
81 ${h.age_component(comment.modified_at, time_is_local=True)}
82 </div>
82 </div>
83 %if comment.status_change:
83 %if comment.status_change:
84 <span class="changeset-status-container">
84 <span class="changeset-status-container">
85 <span class="changeset-status-ico">
85 <span class="changeset-status-ico">
86 <div class="${'flag_status %s' % comment.status_change[0].status}"></div>
86 <div class="${'flag_status %s' % comment.status_change[0].status}"></div>
87 </span>
87 </span>
88 <span title="${_('Commit status')}" class="changeset-status-lbl"> ${comment.status_change[0].status_lbl}</span>
88 <span title="${_('Commit status')}" class="changeset-status-lbl"> ${comment.status_change[0].status_lbl}</span>
89 </span>
89 </span>
90 %endif
90 %endif
91 <a class="permalink" href="#comment-${comment.comment_id}">&para;</a>
91 <a class="permalink" href="#comment-${comment.comment_id}">&para;</a>
92 ## show delete comment if it's not a PR (regular comments) or it's PR that is not closed
92 ## show delete comment if it's not a PR (regular comments) or it's PR that is not closed
93 ## only super-admin, repo admin OR comment owner can delete
93 ## only super-admin, repo admin OR comment owner can delete
94 %if not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed()):
94 %if not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed()):
95 <div class="comment-links-block">
95 <div class="comment-links-block">
96 %if h.HasPermissionAny('hg.admin')() or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or comment.author.user_id == c.rhodecode_user.user_id:
96 %if h.HasPermissionAny('hg.admin')() or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or comment.author.user_id == c.rhodecode_user.user_id:
97 <div data-comment-id=${comment.comment_id} class="delete-comment">${_('Delete')}</div>
97 <div data-comment-id=${comment.comment_id} class="delete-comment">${_('Delete')}</div>
98 %endif
98 %endif
99 </div>
99 </div>
100 %endif
100 %endif
101 </div>
101 </div>
102 <div class="text">
102 <div class="text">
103 ${comment.render(mentions=True)|n}
103 ${comment.render(mentions=True)|n}
104 </div>
104 </div>
105 </div>
105 </div>
106 </div>
106 </div>
107 </%def>
107 </%def>
108
108
109 <%def name="comment_inline_form()">
109 <%def name="comment_inline_form()">
110 <div id="comment-inline-form-template" style="display: none;">
110 <div id="comment-inline-form-template" style="display: none;">
111 <div class="comment-inline-form ac">
111 <div class="comment-inline-form ac">
112 %if c.rhodecode_user.username != h.DEFAULT_USER:
112 %if c.rhodecode_user.username != h.DEFAULT_USER:
113 ${h.form('#', class_='inline-form', method='get')}
113 ${h.form('#', class_='inline-form', method='get')}
114 <div id="edit-container_{1}" class="clearfix">
114 <div id="edit-container_{1}" class="clearfix">
115 <div class="comment-title pull-left">
115 <div class="comment-title pull-left">
116 ${_('Create a comment on line {1}.')}
116 ${_('Create a comment on line {1}.')}
117 </div>
117 </div>
118 <div class="comment-help pull-right">
118 <div class="comment-help pull-right">
119 ${(_('Comments parsed using %s syntax with %s support.') % (
119 ${(_('Comments parsed using %s syntax with %s support.') % (
120 ('<a href="%s">%s</a>' % (h.url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper())),
120 ('<a href="%s">%s</a>' % (h.url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper())),
121 ('<span class="tooltip" title="%s">@mention</span>' % _('Use @username inside this text to send notification to this RhodeCode user'))
121 ('<span class="tooltip" title="%s">@mention</span>' % _('Use @username inside this text to send notification to this RhodeCode user'))
122 )
122 )
123 )|n
123 )|n
124 }
124 }
125 </div>
125 </div>
126 <div style="clear: both"></div>
126 <div style="clear: both"></div>
127 <textarea id="text_{1}" name="text" class="comment-block-ta ac-input"></textarea>
127 <textarea id="text_{1}" name="text" class="comment-block-ta ac-input"></textarea>
128 </div>
128 </div>
129 <div id="preview-container_{1}" class="clearfix" style="display: none;">
129 <div id="preview-container_{1}" class="clearfix" style="display: none;">
130 <div class="comment-help">
130 <div class="comment-help">
131 ${_('Comment preview')}
131 ${_('Comment preview')}
132 </div>
132 </div>
133 <div id="preview-box_{1}" class="preview-box"></div>
133 <div id="preview-box_{1}" class="preview-box"></div>
134 </div>
134 </div>
135 <div class="comment-footer">
135 <div class="comment-footer">
136 <div class="comment-button hide-inline-form-button cancel-button">
136 <div class="comment-button hide-inline-form-button cancel-button">
137 ${h.reset('hide-inline-form', _('Cancel'), class_='btn hide-inline-form', id_="cancel-btn_{1}")}
137 ${h.reset('hide-inline-form', _('Cancel'), class_='btn hide-inline-form', id_="cancel-btn_{1}")}
138 </div>
138 </div>
139 <div class="action-buttons">
139 <div class="action-buttons">
140 <input type="hidden" name="f_path" value="{0}">
140 <input type="hidden" name="f_path" value="{0}">
141 <input type="hidden" name="line" value="{1}">
141 <input type="hidden" name="line" value="{1}">
142 <button id="preview-btn_{1}" class="btn btn-secondary">${_('Preview')}</button>
142 <button id="preview-btn_{1}" class="btn btn-secondary">${_('Preview')}</button>
143 <button id="edit-btn_{1}" class="btn btn-secondary" style="display: none;">${_('Edit')}</button>
143 <button id="edit-btn_{1}" class="btn btn-secondary" style="display: none;">${_('Edit')}</button>
144 ${h.submit('save', _('Comment'), class_='btn btn-success save-inline-form')}
144 ${h.submit('save', _('Comment'), class_='btn btn-success save-inline-form')}
145 </div>
145 </div>
146 ${h.end_form()}
146 ${h.end_form()}
147 </div>
147 </div>
148 %else:
148 %else:
149 ${h.form('', class_='inline-form comment-form-login', method='get')}
149 ${h.form('', class_='inline-form comment-form-login', method='get')}
150 <div class="pull-left">
150 <div class="pull-left">
151 <div class="comment-help pull-right">
151 <div class="comment-help pull-right">
152 ${_('You need to be logged in to comment.')} <a href="${h.route_path('login', _query={'came_from': h.url.current()})}">${_('Login now')}</a>
152 ${_('You need to be logged in to comment.')} <a href="${h.route_path('login', _query={'came_from': h.url.current()})}">${_('Login now')}</a>
153 </div>
153 </div>
154 </div>
154 </div>
155 <div class="comment-button pull-right">
155 <div class="comment-button pull-right">
156 ${h.reset('hide-inline-form', _('Hide'), class_='btn hide-inline-form')}
156 ${h.reset('hide-inline-form', _('Hide'), class_='btn hide-inline-form')}
157 </div>
157 </div>
158 <div class="clearfix"></div>
158 <div class="clearfix"></div>
159 ${h.end_form()}
159 ${h.end_form()}
160 %endif
160 %endif
161 </div>
161 </div>
162 </div>
162 </div>
163 </%def>
163 </%def>
164
164
165
165
166 ## generate main comments
166 ## generate main comments
167 <%def name="generate_comments(include_pull_request=False, is_pull_request=False)">
167 <%def name="generate_comments(include_pull_request=False, is_pull_request=False)">
168 <div id="comments">
168 %for comment in c.comments:
169 %for comment in c.comments:
169 <div id="comment-tr-${comment.comment_id}">
170 <div id="comment-tr-${comment.comment_id}">
170 ## only render comments that are not from pull request, or from
171 ## only render comments that are not from pull request, or from
171 ## pull request and a status change
172 ## pull request and a status change
172 %if not comment.pull_request or (comment.pull_request and comment.status_change) or include_pull_request:
173 %if not comment.pull_request or (comment.pull_request and comment.status_change) or include_pull_request:
173 ${comment_block(comment)}
174 ${comment_block(comment)}
174 %endif
175 %endif
175 </div>
176 </div>
176 %endfor
177 %endfor
177 ## to anchor ajax comments
178 ## to anchor ajax comments
178 <div id="injected_page_comments"></div>
179 <div id="injected_page_comments"></div>
180 </div>
179 </%def>
181 </%def>
180
182
181 ## MAIN COMMENT FORM
183 ## MAIN COMMENT FORM
182 <%def name="comments(post_url, cur_status, is_pull_request=False, is_compare=False, change_status=True, form_extras=None)">
184 <%def name="comments(post_url, cur_status, is_pull_request=False, is_compare=False, change_status=True, form_extras=None)">
183 %if is_compare:
185 %if is_compare:
184 <% form_id = "comments_form_compare" %>
186 <% form_id = "comments_form_compare" %>
185 %else:
187 %else:
186 <% form_id = "comments_form" %>
188 <% form_id = "comments_form" %>
187 %endif
189 %endif
188
190
189
191
190 %if is_pull_request:
192 %if is_pull_request:
191 <div class="pull-request-merge">
193 <div class="pull-request-merge">
192 %if c.allowed_to_merge:
194 %if c.allowed_to_merge:
193 <div class="pull-request-wrap">
195 <div class="pull-request-wrap">
194 <div class="pull-right">
196 <div class="pull-right">
195 ${h.secure_form(url('pullrequest_merge', repo_name=c.repo_name, pull_request_id=c.pull_request.pull_request_id), id='merge_pull_request_form')}
197 ${h.secure_form(url('pullrequest_merge', repo_name=c.repo_name, pull_request_id=c.pull_request.pull_request_id), id='merge_pull_request_form')}
196 <span data-role="merge-message">${c.pr_merge_msg} ${c.approval_msg if c.approval_msg else ''}</span>
198 <span data-role="merge-message">${c.pr_merge_msg} ${c.approval_msg if c.approval_msg else ''}</span>
197 <% merge_disabled = ' disabled' if c.pr_merge_status is False else '' %>
199 <% merge_disabled = ' disabled' if c.pr_merge_status is False else '' %>
198 <input type="submit" id="merge_pull_request" value="${_('Merge Pull Request')}" class="btn${merge_disabled}"${merge_disabled}>
200 <input type="submit" id="merge_pull_request" value="${_('Merge Pull Request')}" class="btn${merge_disabled}"${merge_disabled}>
199 ${h.end_form()}
201 ${h.end_form()}
200 </div>
202 </div>
201 </div>
203 </div>
202 %else:
204 %else:
203 <div class="pull-request-wrap">
205 <div class="pull-request-wrap">
204 <div class="pull-right">
206 <div class="pull-right">
205 <span>${c.pr_merge_msg} ${c.approval_msg if c.approval_msg else ''}</span>
207 <span>${c.pr_merge_msg} ${c.approval_msg if c.approval_msg else ''}</span>
206 </div>
208 </div>
207 </div>
209 </div>
208 %endif
210 %endif
209 </div>
211 </div>
210 %endif
212 %endif
211 <div class="comments">
213 <div class="comments">
212 %if c.rhodecode_user.username != h.DEFAULT_USER:
214 %if c.rhodecode_user.username != h.DEFAULT_USER:
213 <div class="comment-form ac">
215 <div class="comment-form ac">
214 ${h.secure_form(post_url, id_=form_id)}
216 ${h.secure_form(post_url, id_=form_id)}
215 <div id="edit-container" class="clearfix">
217 <div id="edit-container" class="clearfix">
216 <div class="comment-title pull-left">
218 <div class="comment-title pull-left">
217 %if is_pull_request:
219 %if is_pull_request:
218 ${(_('Create a comment on this Pull Request.'))}
220 ${(_('Create a comment on this Pull Request.'))}
219 %elif is_compare:
221 %elif is_compare:
220 ${(_('Create comments on this Commit range.'))}
222 ${(_('Create comments on this Commit range.'))}
221 %else:
223 %else:
222 ${(_('Create a comment on this Commit.'))}
224 ${(_('Create a comment on this Commit.'))}
223 %endif
225 %endif
224 </div>
226 </div>
225 <div class="comment-help pull-right">
227 <div class="comment-help pull-right">
226 ${(_('Comments parsed using %s syntax with %s support.') % (
228 ${(_('Comments parsed using %s syntax with %s support.') % (
227 ('<a href="%s">%s</a>' % (h.url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper())),
229 ('<a href="%s">%s</a>' % (h.url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper())),
228 ('<span class="tooltip" title="%s">@mention</span>' % _('Use @username inside this text to send notification to this RhodeCode user'))
230 ('<span class="tooltip" title="%s">@mention</span>' % _('Use @username inside this text to send notification to this RhodeCode user'))
229 )
231 )
230 )|n
232 )|n
231 }
233 }
232 </div>
234 </div>
233 <div style="clear: both"></div>
235 <div style="clear: both"></div>
234 ${h.textarea('text', class_="comment-block-ta")}
236 ${h.textarea('text', class_="comment-block-ta")}
235 </div>
237 </div>
236
238
237 <div id="preview-container" class="clearfix" style="display: none;">
239 <div id="preview-container" class="clearfix" style="display: none;">
238 <div class="comment-title">
240 <div class="comment-title">
239 ${_('Comment preview')}
241 ${_('Comment preview')}
240 </div>
242 </div>
241 <div id="preview-box" class="preview-box"></div>
243 <div id="preview-box" class="preview-box"></div>
242 </div>
244 </div>
243
245
244 <div id="comment_form_extras">
246 <div id="comment_form_extras">
245 %if form_extras and isinstance(form_extras, (list, tuple)):
247 %if form_extras and isinstance(form_extras, (list, tuple)):
246 % for form_ex_el in form_extras:
248 % for form_ex_el in form_extras:
247 ${form_ex_el|n}
249 ${form_ex_el|n}
248 % endfor
250 % endfor
249 %endif
251 %endif
250 </div>
252 </div>
251 <div class="comment-footer">
253 <div class="comment-footer">
252 %if change_status:
254 %if change_status:
253 <div class="status_box">
255 <div class="status_box">
254 <select id="change_status" name="changeset_status">
256 <select id="change_status" name="changeset_status">
255 <option></option> # Placeholder
257 <option></option> # Placeholder
256 %for status,lbl in c.commit_statuses:
258 %for status,lbl in c.commit_statuses:
257 <option value="${status}" data-status="${status}">${lbl}</option>
259 <option value="${status}" data-status="${status}">${lbl}</option>
258 %if is_pull_request and change_status and status in ('approved', 'rejected'):
260 %if is_pull_request and change_status and status in ('approved', 'rejected'):
259 <option value="${status}_closed" data-status="${status}">${lbl} & ${_('Closed')}</option>
261 <option value="${status}_closed" data-status="${status}">${lbl} & ${_('Closed')}</option>
260 %endif
262 %endif
261 %endfor
263 %endfor
262 </select>
264 </select>
263 </div>
265 </div>
264 %endif
266 %endif
265 <div class="action-buttons">
267 <div class="action-buttons">
266 <button id="preview-btn" class="btn btn-secondary">${_('Preview')}</button>
268 <button id="preview-btn" class="btn btn-secondary">${_('Preview')}</button>
267 <button id="edit-btn" class="btn btn-secondary" style="display:none;">${_('Edit')}</button>
269 <button id="edit-btn" class="btn btn-secondary" style="display:none;">${_('Edit')}</button>
268 <div class="comment-button">${h.submit('save', _('Comment'), class_="btn btn-success comment-button-input")}</div>
270 <div class="comment-button">${h.submit('save', _('Comment'), class_="btn btn-success comment-button-input")}</div>
269 </div>
271 </div>
270 </div>
272 </div>
271 ${h.end_form()}
273 ${h.end_form()}
272 </div>
274 </div>
273 %endif
275 %endif
274 </div>
276 </div>
275 <script>
277 <script>
276 // init active elements of commentForm
278 // init active elements of commentForm
277 var commitId = templateContext.commit_data.commit_id;
279 var commitId = templateContext.commit_data.commit_id;
278 var pullRequestId = templateContext.pull_request_data.pull_request_id;
280 var pullRequestId = templateContext.pull_request_data.pull_request_id;
279 var lineNo;
281 var lineNo;
280
282
281 var mainCommentForm = new CommentForm(
283 var mainCommentForm = new CommentForm(
282 "#${form_id}", commitId, pullRequestId, lineNo, true);
284 "#${form_id}", commitId, pullRequestId, lineNo, true);
283
285
284 mainCommentForm.initStatusChangeSelector();
286 mainCommentForm.initStatusChangeSelector();
285 bindToggleButtons();
287 bindToggleButtons();
286 </script>
288 </script>
287 </%def>
289 </%def>
General Comments 0
You need to be logged in to leave comments. Login now