##// END OF EJS Templates
comments: make dismiss less prominent
milka -
r4587:e0e71538 stable
parent child Browse files
Show More
@@ -1,557 +1,557 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 ## usage:
2 ## usage:
3 ## <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
3 ## <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/>
4 ## ${comment.comment_block(comment)}
4 ## ${comment.comment_block(comment)}
5 ##
5 ##
6 <%namespace name="base" file="/base/base.mako"/>
6 <%namespace name="base" file="/base/base.mako"/>
7
7
8 <%!
8 <%!
9 from rhodecode.lib import html_filters
9 from rhodecode.lib import html_filters
10 %>
10 %>
11
11
12
12
13 <%def name="comment_block(comment, inline=False, active_pattern_entries=None, is_new=False)">
13 <%def name="comment_block(comment, inline=False, active_pattern_entries=None, is_new=False)">
14
14
15 <%
15 <%
16 from rhodecode.model.comment import CommentsModel
16 from rhodecode.model.comment import CommentsModel
17 comment_model = CommentsModel()
17 comment_model = CommentsModel()
18
18
19 comment_ver = comment.get_index_version(getattr(c, 'versions', []))
19 comment_ver = comment.get_index_version(getattr(c, 'versions', []))
20 latest_ver = len(getattr(c, 'versions', []))
20 latest_ver = len(getattr(c, 'versions', []))
21 visible_for_user = True
21 visible_for_user = True
22 if comment.draft:
22 if comment.draft:
23 visible_for_user = comment.user_id == c.rhodecode_user.user_id
23 visible_for_user = comment.user_id == c.rhodecode_user.user_id
24 %>
24 %>
25
25
26 % if inline:
26 % if inline:
27 <% outdated_at_ver = comment.outdated_at_version(c.at_version_num) %>
27 <% outdated_at_ver = comment.outdated_at_version(c.at_version_num) %>
28 % else:
28 % else:
29 <% outdated_at_ver = comment.older_than_version(c.at_version_num) %>
29 <% outdated_at_ver = comment.older_than_version(c.at_version_num) %>
30 % endif
30 % endif
31
31
32 % if visible_for_user:
32 % if visible_for_user:
33 <div class="comment
33 <div class="comment
34 ${'comment-inline' if inline else 'comment-general'}
34 ${'comment-inline' if inline else 'comment-general'}
35 ${'comment-outdated' if outdated_at_ver else 'comment-current'}"
35 ${'comment-outdated' if outdated_at_ver else 'comment-current'}"
36 id="comment-${comment.comment_id}"
36 id="comment-${comment.comment_id}"
37 line="${comment.line_no}"
37 line="${comment.line_no}"
38 data-comment-id="${comment.comment_id}"
38 data-comment-id="${comment.comment_id}"
39 data-comment-type="${comment.comment_type}"
39 data-comment-type="${comment.comment_type}"
40 data-comment-draft=${h.json.dumps(comment.draft)}
40 data-comment-draft=${h.json.dumps(comment.draft)}
41 data-comment-renderer="${comment.renderer}"
41 data-comment-renderer="${comment.renderer}"
42 data-comment-text="${comment.text | html_filters.base64,n}"
42 data-comment-text="${comment.text | html_filters.base64,n}"
43 data-comment-f-path="${comment.f_path}"
43 data-comment-f-path="${comment.f_path}"
44 data-comment-line-no="${comment.line_no}"
44 data-comment-line-no="${comment.line_no}"
45 data-comment-inline=${h.json.dumps(inline)}
45 data-comment-inline=${h.json.dumps(inline)}
46 style="${'display: none;' if outdated_at_ver else ''}">
46 style="${'display: none;' if outdated_at_ver else ''}">
47
47
48 <div class="meta">
48 <div class="meta">
49 <div class="comment-type-label">
49 <div class="comment-type-label">
50 % if comment.draft:
50 % if comment.draft:
51 <div class="tooltip comment-draft" title="${_('Draft comments are only visible to the author until submitted')}.">
51 <div class="tooltip comment-draft" title="${_('Draft comments are only visible to the author until submitted')}.">
52 DRAFT
52 DRAFT
53 </div>
53 </div>
54 % elif is_new:
54 % elif is_new:
55 <div class="tooltip comment-new" title="${_('This comment was added while you browsed this page')}.">
55 <div class="tooltip comment-new" title="${_('This comment was added while you browsed this page')}.">
56 NEW
56 NEW
57 </div>
57 </div>
58 % endif
58 % endif
59
59
60 <div class="comment-label ${comment.comment_type or 'note'}" id="comment-label-${comment.comment_id}">
60 <div class="comment-label ${comment.comment_type or 'note'}" id="comment-label-${comment.comment_id}">
61
61
62 ## TODO COMMENT
62 ## TODO COMMENT
63 % if comment.comment_type == 'todo':
63 % if comment.comment_type == 'todo':
64 % if comment.resolved:
64 % if comment.resolved:
65 <div class="resolved tooltip" title="${_('Resolved by comment #{}').format(comment.resolved.comment_id)}">
65 <div class="resolved tooltip" title="${_('Resolved by comment #{}').format(comment.resolved.comment_id)}">
66 <i class="icon-flag-filled"></i>
66 <i class="icon-flag-filled"></i>
67 <a href="#comment-${comment.resolved.comment_id}">${comment.comment_type}</a>
67 <a href="#comment-${comment.resolved.comment_id}">${comment.comment_type}</a>
68 </div>
68 </div>
69 % else:
69 % else:
70 <div class="resolved tooltip" style="display: none">
70 <div class="resolved tooltip" style="display: none">
71 <span>${comment.comment_type}</span>
71 <span>${comment.comment_type}</span>
72 </div>
72 </div>
73 <div class="resolve tooltip" onclick="return Rhodecode.comments.createResolutionComment(${comment.comment_id});" title="${_('Click to create resolution comment.')}">
73 <div class="resolve tooltip" onclick="return Rhodecode.comments.createResolutionComment(${comment.comment_id});" title="${_('Click to create resolution comment.')}">
74 <i class="icon-flag-filled"></i>
74 <i class="icon-flag-filled"></i>
75 ${comment.comment_type}
75 ${comment.comment_type}
76 </div>
76 </div>
77 % endif
77 % endif
78 ## NOTE COMMENT
78 ## NOTE COMMENT
79 % else:
79 % else:
80 ## RESOLVED NOTE
80 ## RESOLVED NOTE
81 % if comment.resolved_comment:
81 % if comment.resolved_comment:
82 <div class="tooltip" title="${_('This comment resolves TODO #{}').format(comment.resolved_comment.comment_id)}">
82 <div class="tooltip" title="${_('This comment resolves TODO #{}').format(comment.resolved_comment.comment_id)}">
83 fix
83 fix
84 <a href="#comment-${comment.resolved_comment.comment_id}" onclick="Rhodecode.comments.scrollToComment($('#comment-${comment.resolved_comment.comment_id}'), 0, ${h.json.dumps(comment.resolved_comment.outdated)})">
84 <a href="#comment-${comment.resolved_comment.comment_id}" onclick="Rhodecode.comments.scrollToComment($('#comment-${comment.resolved_comment.comment_id}'), 0, ${h.json.dumps(comment.resolved_comment.outdated)})">
85 <span style="text-decoration: line-through">#${comment.resolved_comment.comment_id}</span>
85 <span style="text-decoration: line-through">#${comment.resolved_comment.comment_id}</span>
86 </a>
86 </a>
87 </div>
87 </div>
88 ## STATUS CHANGE NOTE
88 ## STATUS CHANGE NOTE
89 % elif not comment.is_inline and comment.status_change:
89 % elif not comment.is_inline and comment.status_change:
90 <%
90 <%
91 if comment.pull_request:
91 if comment.pull_request:
92 status_change_title = 'Status of review for pull request !{}'.format(comment.pull_request.pull_request_id)
92 status_change_title = 'Status of review for pull request !{}'.format(comment.pull_request.pull_request_id)
93 else:
93 else:
94 status_change_title = 'Status of review for commit {}'.format(h.short_id(comment.commit_id))
94 status_change_title = 'Status of review for commit {}'.format(h.short_id(comment.commit_id))
95 %>
95 %>
96
96
97 <i class="icon-circle review-status-${comment.review_status}"></i>
97 <i class="icon-circle review-status-${comment.review_status}"></i>
98 <div class="changeset-status-lbl tooltip" title="${status_change_title}">
98 <div class="changeset-status-lbl tooltip" title="${status_change_title}">
99 ${comment.review_status_lbl}
99 ${comment.review_status_lbl}
100 </div>
100 </div>
101 % else:
101 % else:
102 <div>
102 <div>
103 <i class="icon-comment"></i>
103 <i class="icon-comment"></i>
104 ${(comment.comment_type or 'note')}
104 ${(comment.comment_type or 'note')}
105 </div>
105 </div>
106 % endif
106 % endif
107 % endif
107 % endif
108
108
109 </div>
109 </div>
110 </div>
110 </div>
111 ## NOTE 0 and .. => because we disable it for now until UI ready
111 ## NOTE 0 and .. => because we disable it for now until UI ready
112 % if 0 and comment.status_change:
112 % if 0 and comment.status_change:
113 <div class="pull-left">
113 <div class="pull-left">
114 <span class="tag authortag tooltip" title="${_('Status from pull request.')}">
114 <span class="tag authortag tooltip" title="${_('Status from pull request.')}">
115 <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 <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)}">
116 ${'!{}'.format(comment.pull_request.pull_request_id)}
116 ${'!{}'.format(comment.pull_request.pull_request_id)}
117 </a>
117 </a>
118 </span>
118 </span>
119 </div>
119 </div>
120 % endif
120 % endif
121 ## Since only author can see drafts, we don't show it
121 ## Since only author can see drafts, we don't show it
122 % if not comment.draft:
122 % if not comment.draft:
123 <div class="author ${'author-inline' if inline else 'author-general'}">
123 <div class="author ${'author-inline' if inline else 'author-general'}">
124 ${base.gravatar_with_user(comment.author.email, 16, tooltip=True)}
124 ${base.gravatar_with_user(comment.author.email, 16, tooltip=True)}
125 </div>
125 </div>
126 % endif
126 % endif
127
127
128 <div class="date">
128 <div class="date">
129 ${h.age_component(comment.modified_at, time_is_local=True)}
129 ${h.age_component(comment.modified_at, time_is_local=True)}
130 </div>
130 </div>
131
131
132 % if comment.pull_request and comment.pull_request.author.user_id == comment.author.user_id:
132 % if comment.pull_request and comment.pull_request.author.user_id == comment.author.user_id:
133 <span class="tag authortag tooltip" title="${_('Pull request author')}">
133 <span class="tag authortag tooltip" title="${_('Pull request author')}">
134 ${_('author')}
134 ${_('author')}
135 </span>
135 </span>
136 % endif
136 % endif
137
137
138 <%
138 <%
139 comment_version_selector = 'comment_versions_{}'.format(comment.comment_id)
139 comment_version_selector = 'comment_versions_{}'.format(comment.comment_id)
140 %>
140 %>
141
141
142 % if comment.history:
142 % if comment.history:
143 <div class="date">
143 <div class="date">
144
144
145 <input id="${comment_version_selector}" name="${comment_version_selector}"
145 <input id="${comment_version_selector}" name="${comment_version_selector}"
146 type="hidden"
146 type="hidden"
147 data-last-version="${comment.history[-1].version}">
147 data-last-version="${comment.history[-1].version}">
148
148
149 <script type="text/javascript">
149 <script type="text/javascript">
150
150
151 var preLoadVersionData = [
151 var preLoadVersionData = [
152 % for comment_history in comment.history:
152 % for comment_history in comment.history:
153 {
153 {
154 id: ${comment_history.comment_history_id},
154 id: ${comment_history.comment_history_id},
155 text: 'v${comment_history.version}',
155 text: 'v${comment_history.version}',
156 action: function () {
156 action: function () {
157 Rhodecode.comments.showVersion(
157 Rhodecode.comments.showVersion(
158 "${comment.comment_id}",
158 "${comment.comment_id}",
159 "${comment_history.comment_history_id}"
159 "${comment_history.comment_history_id}"
160 )
160 )
161 },
161 },
162 comment_version: "${comment_history.version}",
162 comment_version: "${comment_history.version}",
163 comment_author_username: "${comment_history.author.username}",
163 comment_author_username: "${comment_history.author.username}",
164 comment_author_gravatar: "${h.gravatar_url(comment_history.author.email, 16)}",
164 comment_author_gravatar: "${h.gravatar_url(comment_history.author.email, 16)}",
165 comment_created_on: '${h.age_component(comment_history.created_on, time_is_local=True)}',
165 comment_created_on: '${h.age_component(comment_history.created_on, time_is_local=True)}',
166 },
166 },
167 % endfor
167 % endfor
168 ]
168 ]
169 initVersionSelector("#${comment_version_selector}", {results: preLoadVersionData});
169 initVersionSelector("#${comment_version_selector}", {results: preLoadVersionData});
170
170
171 </script>
171 </script>
172
172
173 </div>
173 </div>
174 % else:
174 % else:
175 <div class="date" style="display: none">
175 <div class="date" style="display: none">
176 <input id="${comment_version_selector}" name="${comment_version_selector}"
176 <input id="${comment_version_selector}" name="${comment_version_selector}"
177 type="hidden"
177 type="hidden"
178 data-last-version="0">
178 data-last-version="0">
179 </div>
179 </div>
180 %endif
180 %endif
181
181
182 <div class="comment-links-block">
182 <div class="comment-links-block">
183
183
184 % if inline:
184 % if inline:
185 <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 <a class="pr-version-inline" href="${request.current_route_path(_query=dict(version=comment.pull_request_version_id), _anchor='comment-{}'.format(comment.comment_id))}">
186 % if outdated_at_ver:
186 % if outdated_at_ver:
187 <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 <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>
188 <code class="action-divider">|</code>
188 <code class="action-divider">|</code>
189 % elif comment_ver:
189 % elif comment_ver:
190 <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="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>
191 <code class="action-divider">|</code>
191 <code class="action-divider">|</code>
192 % endif
192 % endif
193 </a>
193 </a>
194 % else:
194 % else:
195 % if comment_ver:
195 % if comment_ver:
196
196
197 % if comment.outdated:
197 % if comment.outdated:
198 <a class="pr-version"
198 <a class="pr-version"
199 href="?version=${comment.pull_request_version_id}#comment-${comment.comment_id}"
199 href="?version=${comment.pull_request_version_id}#comment-${comment.comment_id}"
200 >
200 >
201 ${_('Outdated comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}
201 ${_('Outdated comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}
202 </a>
202 </a>
203 <code class="action-divider">|</code>
203 <code class="action-divider">|</code>
204 % else:
204 % else:
205 <a class="tooltip pr-version"
205 <a class="tooltip pr-version"
206 title="${_('Comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}"
206 title="${_('Comment from pull request version v{0}, latest v{1}').format(comment_ver, latest_ver)}"
207 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 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)}"
208 >
208 >
209 <code class="pr-version-num">${'v{}'.format(comment_ver)}</code>
209 <code class="pr-version-num">${'v{}'.format(comment_ver)}</code>
210 </a>
210 </a>
211 <code class="action-divider">|</code>
211 <code class="action-divider">|</code>
212 % endif
212 % endif
213
213
214 % endif
214 % endif
215 % endif
215 % endif
216
216
217 <details class="details-reset details-inline-block">
217 <details class="details-reset details-inline-block">
218 <summary class="noselect"><i class="icon-options cursor-pointer"></i></summary>
218 <summary class="noselect"><i class="icon-options cursor-pointer"></i></summary>
219 <details-menu class="details-dropdown">
219 <details-menu class="details-dropdown">
220
220
221 <div class="dropdown-item">
221 <div class="dropdown-item">
222 ${_('Comment')} #${comment.comment_id}
222 ${_('Comment')} #${comment.comment_id}
223 <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 <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>
224 </div>
224 </div>
225
225
226 ## show delete comment if it's not a PR (regular comments) or it's PR that is not closed
226 ## show delete comment if it's not a PR (regular comments) or it's PR that is not closed
227 ## only super-admin, repo admin OR comment owner can delete, also hide delete if currently viewed comment is outdated
227 ## only super-admin, repo admin OR comment owner can delete, also hide delete if currently viewed comment is outdated
228 %if not outdated_at_ver and (not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed())):
228 %if not outdated_at_ver and (not comment.pull_request or (comment.pull_request and not comment.pull_request.is_closed())):
229 ## permissions to delete
229 ## permissions to delete
230 %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 %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):
231 <div class="dropdown-divider"></div>
231 <div class="dropdown-divider"></div>
232 <div class="dropdown-item">
232 <div class="dropdown-item">
233 <a onclick="return Rhodecode.comments.editComment(this, '${comment.line_no}', '${comment.f_path}');" class="btn btn-link btn-sm edit-comment">${_('Edit')}</a>
233 <a onclick="return Rhodecode.comments.editComment(this, '${comment.line_no}', '${comment.f_path}');" class="btn btn-link btn-sm edit-comment">${_('Edit')}</a>
234 </div>
234 </div>
235 <div class="dropdown-item">
235 <div class="dropdown-item">
236 <a onclick="return Rhodecode.comments.deleteComment(this);" class="btn btn-link btn-sm btn-danger delete-comment">${_('Delete')}</a>
236 <a onclick="return Rhodecode.comments.deleteComment(this);" class="btn btn-link btn-sm btn-danger delete-comment">${_('Delete')}</a>
237 </div>
237 </div>
238 ## Only available in EE edition
238 ## Only available in EE edition
239 % if comment.draft and c.rhodecode_edition_id == 'EE':
239 % if comment.draft and c.rhodecode_edition_id == 'EE':
240 <div class="dropdown-item">
240 <div class="dropdown-item">
241 <a onclick="return Rhodecode.comments.finalizeDrafts([${comment.comment_id}]);" class="btn btn-link btn-sm finalize-draft-comment">${_('Submit draft')}</a>
241 <a onclick="return Rhodecode.comments.finalizeDrafts([${comment.comment_id}]);" class="btn btn-link btn-sm finalize-draft-comment">${_('Submit draft')}</a>
242 </div>
242 </div>
243 % endif
243 % endif
244 %else:
244 %else:
245 <div class="dropdown-divider"></div>
245 <div class="dropdown-divider"></div>
246 <div class="dropdown-item">
246 <div class="dropdown-item">
247 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Edit')}</a>
247 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Edit')}</a>
248 </div>
248 </div>
249 <div class="dropdown-item">
249 <div class="dropdown-item">
250 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Delete')}</a>
250 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Delete')}</a>
251 </div>
251 </div>
252 %endif
252 %endif
253 %else:
253 %else:
254 <div class="dropdown-divider"></div>
254 <div class="dropdown-divider"></div>
255 <div class="dropdown-item">
255 <div class="dropdown-item">
256 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Edit')}</a>
256 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Edit')}</a>
257 </div>
257 </div>
258 <div class="dropdown-item">
258 <div class="dropdown-item">
259 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Delete')}</a>
259 <a class="tooltip edit-comment link-disabled" disabled="disabled" title="${_('Action unavailable')}">${_('Delete')}</a>
260 </div>
260 </div>
261 %endif
261 %endif
262 </details-menu>
262 </details-menu>
263 </details>
263 </details>
264
264
265 <code class="action-divider">|</code>
265 <code class="action-divider">|</code>
266 % if outdated_at_ver:
266 % if outdated_at_ver:
267 <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.prevOutdatedComment(this);" class="tooltip prev-comment" title="${_('Jump to the previous outdated comment')}"> <i class="icon-angle-left"></i> </a>
268 <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 <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>
269 % else:
269 % else:
270 <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.prevComment(this);" class="tooltip prev-comment" title="${_('Jump to the previous comment')}"> <i class="icon-angle-left"></i></a>
271 <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 <a onclick="return Rhodecode.comments.nextComment(this);" class="tooltip next-comment" title="${_('Jump to the next comment')}"> <i class="icon-angle-right"></i></a>
272 % endif
272 % endif
273
273
274 </div>
274 </div>
275 </div>
275 </div>
276 <div class="text">
276 <div class="text">
277 ${h.render(comment.text, renderer=comment.renderer, mentions=True, repo_name=getattr(c, 'repo_name', None), active_pattern_entries=active_pattern_entries)}
277 ${h.render(comment.text, renderer=comment.renderer, mentions=True, repo_name=getattr(c, 'repo_name', None), active_pattern_entries=active_pattern_entries)}
278 </div>
278 </div>
279
279
280 </div>
280 </div>
281 % endif
281 % endif
282 </%def>
282 </%def>
283
283
284 ## generate main comments
284 ## generate main comments
285 <%def name="generate_comments(comments, include_pull_request=False, is_pull_request=False)">
285 <%def name="generate_comments(comments, include_pull_request=False, is_pull_request=False)">
286 <%
286 <%
287 active_pattern_entries = h.get_active_pattern_entries(getattr(c, 'repo_name', None))
287 active_pattern_entries = h.get_active_pattern_entries(getattr(c, 'repo_name', None))
288 %>
288 %>
289
289
290 <div class="general-comments" id="comments">
290 <div class="general-comments" id="comments">
291 %for comment in comments:
291 %for comment in comments:
292 <div id="comment-tr-${comment.comment_id}">
292 <div id="comment-tr-${comment.comment_id}">
293 ## only render comments that are not from pull request, or from
293 ## only render comments that are not from pull request, or from
294 ## pull request and a status change
294 ## pull request and a status change
295 %if not comment.pull_request or (comment.pull_request and comment.status_change) or include_pull_request:
295 %if not comment.pull_request or (comment.pull_request and comment.status_change) or include_pull_request:
296 ${comment_block(comment, active_pattern_entries=active_pattern_entries)}
296 ${comment_block(comment, active_pattern_entries=active_pattern_entries)}
297 %endif
297 %endif
298 </div>
298 </div>
299 %endfor
299 %endfor
300 ## to anchor ajax comments
300 ## to anchor ajax comments
301 <div id="injected_page_comments"></div>
301 <div id="injected_page_comments"></div>
302 </div>
302 </div>
303 </%def>
303 </%def>
304
304
305
305
306 <%def name="comments(post_url, cur_status, is_pull_request=False, is_compare=False, change_status=True, form_extras=None)">
306 <%def name="comments(post_url, cur_status, is_pull_request=False, is_compare=False, change_status=True, form_extras=None)">
307
307
308 <div class="comments">
308 <div class="comments">
309 <%
309 <%
310 if is_pull_request:
310 if is_pull_request:
311 placeholder = _('Leave a comment on this Pull Request.')
311 placeholder = _('Leave a comment on this Pull Request.')
312 elif is_compare:
312 elif is_compare:
313 placeholder = _('Leave a comment on {} commits in this range.').format(len(form_extras))
313 placeholder = _('Leave a comment on {} commits in this range.').format(len(form_extras))
314 else:
314 else:
315 placeholder = _('Leave a comment on this Commit.')
315 placeholder = _('Leave a comment on this Commit.')
316 %>
316 %>
317
317
318 % if c.rhodecode_user.username != h.DEFAULT_USER:
318 % if c.rhodecode_user.username != h.DEFAULT_USER:
319 <div class="js-template" id="cb-comment-general-form-template">
319 <div class="js-template" id="cb-comment-general-form-template">
320 ## template generated for injection
320 ## template generated for injection
321 ${comment_form(form_type='general', review_statuses=c.commit_statuses, form_extras=form_extras)}
321 ${comment_form(form_type='general', review_statuses=c.commit_statuses, form_extras=form_extras)}
322 </div>
322 </div>
323
323
324 <div id="cb-comment-general-form-placeholder" class="comment-form ac">
324 <div id="cb-comment-general-form-placeholder" class="comment-form ac">
325 ## inject form here
325 ## inject form here
326 </div>
326 </div>
327 <script type="text/javascript">
327 <script type="text/javascript">
328 var resolvesCommentId = null;
328 var resolvesCommentId = null;
329 var generalCommentForm = Rhodecode.comments.createGeneralComment(
329 var generalCommentForm = Rhodecode.comments.createGeneralComment(
330 'general', "${placeholder}", resolvesCommentId);
330 'general', "${placeholder}", resolvesCommentId);
331
331
332 // set custom success callback on rangeCommit
332 // set custom success callback on rangeCommit
333 % if is_compare:
333 % if is_compare:
334 generalCommentForm.setHandleFormSubmit(function(o) {
334 generalCommentForm.setHandleFormSubmit(function(o) {
335 var self = generalCommentForm;
335 var self = generalCommentForm;
336
336
337 var text = self.cm.getValue();
337 var text = self.cm.getValue();
338 var status = self.getCommentStatus();
338 var status = self.getCommentStatus();
339 var commentType = self.getCommentType();
339 var commentType = self.getCommentType();
340 var isDraft = self.getDraftState();
340 var isDraft = self.getDraftState();
341
341
342 if (text === "" && !status) {
342 if (text === "" && !status) {
343 return;
343 return;
344 }
344 }
345
345
346 // we can pick which commits we want to make the comment by
346 // we can pick which commits we want to make the comment by
347 // selecting them via click on preview pane, this will alter the hidden inputs
347 // selecting them via click on preview pane, this will alter the hidden inputs
348 var cherryPicked = $('#changeset_compare_view_content .compare_select.hl').length > 0;
348 var cherryPicked = $('#changeset_compare_view_content .compare_select.hl').length > 0;
349
349
350 var commitIds = [];
350 var commitIds = [];
351 $('#changeset_compare_view_content .compare_select').each(function(el) {
351 $('#changeset_compare_view_content .compare_select').each(function(el) {
352 var commitId = this.id.replace('row-', '');
352 var commitId = this.id.replace('row-', '');
353 if ($(this).hasClass('hl') || !cherryPicked) {
353 if ($(this).hasClass('hl') || !cherryPicked) {
354 $("input[data-commit-id='{0}']".format(commitId)).val(commitId);
354 $("input[data-commit-id='{0}']".format(commitId)).val(commitId);
355 commitIds.push(commitId);
355 commitIds.push(commitId);
356 } else {
356 } else {
357 $("input[data-commit-id='{0}']".format(commitId)).val('')
357 $("input[data-commit-id='{0}']".format(commitId)).val('')
358 }
358 }
359 });
359 });
360
360
361 self.setActionButtonsDisabled(true);
361 self.setActionButtonsDisabled(true);
362 self.cm.setOption("readOnly", true);
362 self.cm.setOption("readOnly", true);
363 var postData = {
363 var postData = {
364 'text': text,
364 'text': text,
365 'changeset_status': status,
365 'changeset_status': status,
366 'comment_type': commentType,
366 'comment_type': commentType,
367 'draft': isDraft,
367 'draft': isDraft,
368 'commit_ids': commitIds,
368 'commit_ids': commitIds,
369 'csrf_token': CSRF_TOKEN
369 'csrf_token': CSRF_TOKEN
370 };
370 };
371
371
372 var submitSuccessCallback = function(o) {
372 var submitSuccessCallback = function(o) {
373 location.reload(true);
373 location.reload(true);
374 };
374 };
375 var submitFailCallback = function(){
375 var submitFailCallback = function(){
376 self.resetCommentFormState(text)
376 self.resetCommentFormState(text)
377 };
377 };
378 self.submitAjaxPOST(
378 self.submitAjaxPOST(
379 self.submitUrl, postData, submitSuccessCallback, submitFailCallback);
379 self.submitUrl, postData, submitSuccessCallback, submitFailCallback);
380 });
380 });
381 % endif
381 % endif
382
382
383 </script>
383 </script>
384 % else:
384 % else:
385 ## form state when not logged in
385 ## form state when not logged in
386 <div class="comment-form ac">
386 <div class="comment-form ac">
387
387
388 <div class="comment-area">
388 <div class="comment-area">
389 <div class="comment-area-header">
389 <div class="comment-area-header">
390 <ul class="nav-links clearfix">
390 <ul class="nav-links clearfix">
391 <li class="active">
391 <li class="active">
392 <a class="disabled" href="#edit-btn" disabled="disabled" onclick="return false">${_('Write')}</a>
392 <a class="disabled" href="#edit-btn" disabled="disabled" onclick="return false">${_('Write')}</a>
393 </li>
393 </li>
394 <li class="">
394 <li class="">
395 <a class="disabled" href="#preview-btn" disabled="disabled" onclick="return false">${_('Preview')}</a>
395 <a class="disabled" href="#preview-btn" disabled="disabled" onclick="return false">${_('Preview')}</a>
396 </li>
396 </li>
397 </ul>
397 </ul>
398 </div>
398 </div>
399
399
400 <div class="comment-area-write" style="display: block;">
400 <div class="comment-area-write" style="display: block;">
401 <div id="edit-container">
401 <div id="edit-container">
402 <div style="padding: 20px 0px 0px 0;">
402 <div style="padding: 20px 0px 0px 0;">
403 ${_('You need to be logged in to leave comments.')}
403 ${_('You need to be logged in to leave comments.')}
404 <a href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">${_('Login now')}</a>
404 <a href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">${_('Login now')}</a>
405 </div>
405 </div>
406 </div>
406 </div>
407 <div id="preview-container" class="clearfix" style="display: none;">
407 <div id="preview-container" class="clearfix" style="display: none;">
408 <div id="preview-box" class="preview-box"></div>
408 <div id="preview-box" class="preview-box"></div>
409 </div>
409 </div>
410 </div>
410 </div>
411
411
412 <div class="comment-area-footer">
412 <div class="comment-area-footer">
413 <div class="toolbar">
413 <div class="toolbar">
414 <div class="toolbar-text">
414 <div class="toolbar-text">
415 </div>
415 </div>
416 </div>
416 </div>
417 </div>
417 </div>
418 </div>
418 </div>
419
419
420 <div class="comment-footer">
420 <div class="comment-footer">
421 </div>
421 </div>
422
422
423 </div>
423 </div>
424 % endif
424 % endif
425
425
426 <script type="text/javascript">
426 <script type="text/javascript">
427 bindToggleButtons();
427 bindToggleButtons();
428 </script>
428 </script>
429 </div>
429 </div>
430 </%def>
430 </%def>
431
431
432
432
433 <%def name="comment_form(form_type, form_id='', lineno_id='{1}', review_statuses=None, form_extras=None)">
433 <%def name="comment_form(form_type, form_id='', lineno_id='{1}', review_statuses=None, form_extras=None)">
434
434
435 ## comment injected based on assumption that user is logged in
435 ## comment injected based on assumption that user is logged in
436 <form ${('id="{}"'.format(form_id) if form_id else '') |n} action="#" method="GET">
436 <form ${('id="{}"'.format(form_id) if form_id else '') |n} action="#" method="GET">
437
437
438 <div class="comment-area">
438 <div class="comment-area">
439 <div class="comment-area-header">
439 <div class="comment-area-header">
440 <div class="pull-left">
440 <div class="pull-left">
441 <ul class="nav-links clearfix">
441 <ul class="nav-links clearfix">
442 <li class="active">
442 <li class="active">
443 <a href="#edit-btn" tabindex="-1" id="edit-btn_${lineno_id}">${_('Write')}</a>
443 <a href="#edit-btn" tabindex="-1" id="edit-btn_${lineno_id}">${_('Write')}</a>
444 </li>
444 </li>
445 <li class="">
445 <li class="">
446 <a href="#preview-btn" tabindex="-1" id="preview-btn_${lineno_id}">${_('Preview')}</a>
446 <a href="#preview-btn" tabindex="-1" id="preview-btn_${lineno_id}">${_('Preview')}</a>
447 </li>
447 </li>
448 </ul>
448 </ul>
449 </div>
449 </div>
450 <div class="pull-right">
450 <div class="pull-right">
451 <span class="comment-area-text">${_('Mark as')}:</span>
451 <span class="comment-area-text">${_('Mark as')}:</span>
452 <select class="comment-type" id="comment_type_${lineno_id}" name="comment_type">
452 <select class="comment-type" id="comment_type_${lineno_id}" name="comment_type">
453 % for val in c.visual.comment_types:
453 % for val in c.visual.comment_types:
454 <option value="${val}">${val.upper()}</option>
454 <option value="${val}">${val.upper()}</option>
455 % endfor
455 % endfor
456 </select>
456 </select>
457 </div>
457 </div>
458 </div>
458 </div>
459
459
460 <div class="comment-area-write" style="display: block;">
460 <div class="comment-area-write" style="display: block;">
461 <div id="edit-container_${lineno_id}" style="margin-top: -1px">
461 <div id="edit-container_${lineno_id}" style="margin-top: -1px">
462 <textarea id="text_${lineno_id}" name="text" class="comment-block-ta ac-input"></textarea>
462 <textarea id="text_${lineno_id}" name="text" class="comment-block-ta ac-input"></textarea>
463 </div>
463 </div>
464 <div id="preview-container_${lineno_id}" class="clearfix" style="display: none;">
464 <div id="preview-container_${lineno_id}" class="clearfix" style="display: none;">
465 <div id="preview-box_${lineno_id}" class="preview-box"></div>
465 <div id="preview-box_${lineno_id}" class="preview-box"></div>
466 </div>
466 </div>
467 </div>
467 </div>
468
468
469 <div class="comment-area-footer comment-attachment-uploader">
469 <div class="comment-area-footer comment-attachment-uploader">
470 <div class="toolbar">
470 <div class="toolbar">
471
471
472 <div class="comment-attachment-text">
472 <div class="comment-attachment-text">
473 <div class="dropzone-text">
473 <div class="dropzone-text">
474 ${_("Drag'n Drop files here or")} <span class="link pick-attachment">${_('Choose your files')}</span>.<br>
474 ${_("Drag'n Drop files here or")} <span class="link pick-attachment">${_('Choose your files')}</span>.<br>
475 </div>
475 </div>
476 <div class="dropzone-upload" style="display:none">
476 <div class="dropzone-upload" style="display:none">
477 <i class="icon-spin animate-spin"></i> ${_('uploading...')}
477 <i class="icon-spin animate-spin"></i> ${_('uploading...')}
478 </div>
478 </div>
479 </div>
479 </div>
480
480
481 ## comments dropzone template, empty on purpose
481 ## comments dropzone template, empty on purpose
482 <div style="display: none" class="comment-attachment-uploader-template">
482 <div style="display: none" class="comment-attachment-uploader-template">
483 <div class="dz-file-preview" style="margin: 0">
483 <div class="dz-file-preview" style="margin: 0">
484 <div class="dz-error-message"></div>
484 <div class="dz-error-message"></div>
485 </div>
485 </div>
486 </div>
486 </div>
487
487
488 </div>
488 </div>
489 </div>
489 </div>
490 </div>
490 </div>
491
491
492 <div class="comment-footer">
492 <div class="comment-footer">
493
493
494 ## inject extra inputs into the form
494 ## inject extra inputs into the form
495 % if form_extras and isinstance(form_extras, (list, tuple)):
495 % if form_extras and isinstance(form_extras, (list, tuple)):
496 <div id="comment_form_extras">
496 <div id="comment_form_extras">
497 % for form_ex_el in form_extras:
497 % for form_ex_el in form_extras:
498 ${form_ex_el|n}
498 ${form_ex_el|n}
499 % endfor
499 % endfor
500 </div>
500 </div>
501 % endif
501 % endif
502
502
503 <div class="action-buttons">
503 <div class="action-buttons">
504 % if form_type != 'inline':
504 % if form_type != 'inline':
505 <div class="action-buttons-extra"></div>
505 <div class="action-buttons-extra"></div>
506 % endif
506 % endif
507
507
508 <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 <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')">
509
509
510 % if form_type == 'inline':
510 % if form_type == 'inline':
511 % if c.rhodecode_edition_id == 'EE':
511 % if c.rhodecode_edition_id == 'EE':
512 ## Disable the button for CE, the "real" validation is in the backend code anyway
512 ## Disable the button for CE, the "real" validation is in the backend code anyway
513 <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 <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')">
514 % else:
514 % else:
515 <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 <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">
516 % endif
516 % endif
517 % endif
517 % endif
518
518
519 % if review_statuses:
519 % if review_statuses:
520 <div class="comment-status-box">
520 <div class="comment-status-box">
521 <select id="change_status_${lineno_id}" name="changeset_status">
521 <select id="change_status_${lineno_id}" name="changeset_status">
522 <option></option> ## Placeholder
522 <option></option> ## Placeholder
523 % for status, lbl in review_statuses:
523 % for status, lbl in review_statuses:
524 <option value="${status}" data-status="${status}">${lbl}</option>
524 <option value="${status}" data-status="${status}">${lbl}</option>
525 %if is_pull_request and change_status and status in ('approved', 'rejected'):
525 %if is_pull_request and change_status and status in ('approved', 'rejected'):
526 <option value="${status}_closed" data-status="${status}">${lbl} & ${_('Closed')}</option>
526 <option value="${status}_closed" data-status="${status}">${lbl} & ${_('Closed')}</option>
527 %endif
527 %endif
528 % endfor
528 % endfor
529 </select>
529 </select>
530 </div>
530 </div>
531 % endif
531 % endif
532
532
533 ## inline for has a file, and line-number together with cancel hide button.
533 ## inline for has a file, and line-number together with cancel hide button.
534 % if form_type == 'inline':
534 % if form_type == 'inline':
535 <input type="hidden" name="f_path" value="{0}">
535 <input type="hidden" name="f_path" value="{0}">
536 <input type="hidden" name="line" value="${lineno_id}">
536 <input type="hidden" name="line" value="${lineno_id}">
537 <span class="cursor-pointer action_button cb-comment-cancel" onclick="return Rhodecode.comments.cancelComment(this);">
537 <span style="opacity: 0.7" class="cursor-pointer cb-comment-cancel" onclick="return Rhodecode.comments.cancelComment(this);">
538 ${_('dismiss')}
538 ${_('dismiss')}
539 </span>
539 </span>
540 % endif
540 % endif
541 </div>
541 </div>
542
542
543 <div class="toolbar-text">
543 <div class="toolbar-text">
544 <% renderer_url = '<a href="%s">%s</a>' % (h.route_url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper()) %>
544 <% renderer_url = '<a href="%s">%s</a>' % (h.route_url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper()) %>
545 <span>${_('{} is supported.').format(renderer_url)|n}
545 <span>${_('{} is supported.').format(renderer_url)|n}
546
546
547 <i class="icon-info-circled tooltip-hovercard"
547 <i class="icon-info-circled tooltip-hovercard"
548 data-hovercard-alt="ALT"
548 data-hovercard-alt="ALT"
549 data-hovercard-url="javascript:commentHelp('${c.visual.default_renderer.upper()}')"
549 data-hovercard-url="javascript:commentHelp('${c.visual.default_renderer.upper()}')"
550 data-comment-json-b64='${h.b64(h.json.dumps({}))}'></i>
550 data-comment-json-b64='${h.b64(h.json.dumps({}))}'></i>
551 </span>
551 </span>
552 </div>
552 </div>
553 </div>
553 </div>
554
554
555 </form>
555 </form>
556
556
557 </%def> No newline at end of file
557 </%def>
General Comments 0
You need to be logged in to leave comments. Login now