##// END OF EJS Templates
Implemented preview for comments
marcink -
r3695:45df84d3 beta
parent child Browse files
Show More
@@ -500,6 +500,11 b' def make_map(config):'
500 controller='changeset', revision='tip', action='comment',
500 controller='changeset', revision='tip', action='comment',
501 conditions=dict(function=check_repo))
501 conditions=dict(function=check_repo))
502
502
503 rmap.connect('changeset_comment_preview',
504 '/{repo_name:.*?}/changeset/comment/preview',
505 controller='changeset', action='preview_comment',
506 conditions=dict(function=check_repo, method=["POST"]))
507
503 rmap.connect('changeset_comment_delete',
508 rmap.connect('changeset_comment_delete',
504 '/{repo_name:.*?}/changeset/comment/{comment_id}/delete',
509 '/{repo_name:.*?}/changeset/comment/{comment_id}/delete',
505 controller='changeset', action='delete_comment',
510 controller='changeset', action='delete_comment',
@@ -37,7 +37,8 b' from rhodecode.lib.vcs.exceptions import'
37 ChangesetDoesNotExistError
37 ChangesetDoesNotExistError
38
38
39 import rhodecode.lib.helpers as h
39 import rhodecode.lib.helpers as h
40 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
40 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator,\
41 NotAnonymous
41 from rhodecode.lib.base import BaseRepoController, render
42 from rhodecode.lib.base import BaseRepoController, render
42 from rhodecode.lib.utils import action_logger
43 from rhodecode.lib.utils import action_logger
43 from rhodecode.lib.compat import OrderedDict
44 from rhodecode.lib.compat import OrderedDict
@@ -320,6 +321,7 b' class ChangesetController(BaseRepoContro'
320 def changeset_download(self, revision):
321 def changeset_download(self, revision):
321 return self.index(revision, method='download')
322 return self.index(revision, method='download')
322
323
324 @NotAnonymous()
323 @jsonify
325 @jsonify
324 def comment(self, repo_name, revision):
326 def comment(self, repo_name, revision):
325 status = request.POST.get('changeset_status')
327 status = request.POST.get('changeset_status')
@@ -382,6 +384,16 b' class ChangesetController(BaseRepoContro'
382
384
383 return data
385 return data
384
386
387 @NotAnonymous()
388 def preview_comment(self):
389 if not request.environ.get('HTTP_X_PARTIAL_XHR'):
390 raise HTTPBadRequest()
391 text = request.POST.get('text')
392 if text:
393 return h.rst_w_mentions(text)
394 return ''
395
396 @NotAnonymous()
385 @jsonify
397 @jsonify
386 def delete_comment(self, repo_name, comment_id):
398 def delete_comment(self, repo_name, comment_id):
387 co = ChangesetComment.get(comment_id)
399 co = ChangesetComment.get(comment_id)
@@ -218,6 +218,8 b' div.options a {'
218
218
219 a.permalink {
219 a.permalink {
220 visibility: hidden;
220 visibility: hidden;
221 position: absolute;
222 margin: 3px 4px;
221 }
223 }
222
224
223 a.permalink:hover {
225 a.permalink:hover {
@@ -4297,12 +4299,6 b' div.rst-block pre {'
4297 clear: both
4299 clear: both
4298 }
4300 }
4299
4301
4300 .comment-form .clearfix {
4301 background: #EEE;
4302 -webkit-border-radius: 4px;
4303 border-radius: 4px;
4304 padding: 10px;
4305 }
4306
4302
4307 div.comment-form {
4303 div.comment-form {
4308 margin-top: 20px;
4304 margin-top: 20px;
@@ -4324,6 +4320,13 b' form.comment-form {'
4324 margin-left: 10px;
4320 margin-left: 10px;
4325 }
4321 }
4326
4322
4323 .comment-inline-form .comment-block-ta,
4324 .comment-form .comment-block-ta {
4325 border: 1px solid #ccc;
4326 border-radius: 3px;
4327 box-sizing: border-box;
4328 }
4329
4327 .comment-form-submit {
4330 .comment-form-submit {
4328 margin-top: 5px;
4331 margin-top: 5px;
4329 margin-left: 525px;
4332 margin-left: 525px;
@@ -4338,9 +4341,22 b' form.comment-form {'
4338 }
4341 }
4339
4342
4340 .comment-form .comment-help {
4343 .comment-form .comment-help {
4341 padding: 0px 0px 5px 0px;
4344 padding: 5px 5px 5px 5px;
4342 color: #666;
4345 color: #666;
4343 }
4346 }
4347 .comment-form .comment-help .preview-btn,
4348 .comment-form .comment-help .edit-btn {
4349 float: right;
4350 margin: -6px 0px 0px 0px;
4351 }
4352
4353 .comment-form .preview-box.unloaded,
4354 .comment-inline-form .preview-box.unloaded {
4355 height: 50px;
4356 text-align: center;
4357 padding: 20px;
4358 background-color: #fafafa;
4359 }
4344
4360
4345 .comment-form .comment-button {
4361 .comment-form .comment-button {
4346 padding-top: 5px;
4362 padding-top: 5px;
@@ -4354,7 +4370,7 b' form.comment-form {'
4354
4370
4355 .comment .buttons {
4371 .comment .buttons {
4356 float: right;
4372 float: right;
4357 padding: 2px 2px 0px 0px;
4373 margin: -1px 0px 0px 0px;
4358 }
4374 }
4359
4375
4360
4376
@@ -4364,6 +4380,9 b' form.comment-form {'
4364 }
4380 }
4365
4381
4366 /** comment inline form **/
4382 /** comment inline form **/
4383 .comment-inline-form {
4384 margin: 4px;
4385 }
4367 .comment-inline-form .overlay {
4386 .comment-inline-form .overlay {
4368 display: none;
4387 display: none;
4369 }
4388 }
@@ -4382,11 +4401,13 b' form.comment-form {'
4382 margin-top: 5%;
4401 margin-top: 5%;
4383 }
4402 }
4384
4403
4385 .comment-inline-form .clearfix {
4404 .comment-inline-form .clearfix,
4405 .comment-form .clearfix {
4386 background: #EEE;
4406 background: #EEE;
4387 -webkit-border-radius: 4px;
4407 -webkit-border-radius: 4px;
4388 border-radius: 4px;
4408 border-radius: 4px;
4389 padding: 5px;
4409 padding: 5px;
4410 margin: 0px;
4390 }
4411 }
4391
4412
4392 div.comment-inline-form {
4413 div.comment-inline-form {
@@ -4423,9 +4444,14 b' form.comment-inline-form {'
4423 }
4444 }
4424
4445
4425 .comment-inline-form .comment-help {
4446 .comment-inline-form .comment-help {
4426 padding: 0px 0px 2px 0px;
4447 padding: 5px 5px 5px 5px;
4427 color: #666666;
4448 color: #666;
4428 font-size: 10px;
4449 }
4450
4451 .comment-inline-form .comment-help .preview-btn,
4452 .comment-inline-form .comment-help .edit-btn {
4453 float: right;
4454 margin: -6px 0px 0px 0px;
4429 }
4455 }
4430
4456
4431 .comment-inline-form .comment-button {
4457 .comment-inline-form .comment-button {
@@ -865,6 +865,29 b' var injectInlineForm = function(tr){'
865
865
866 ajaxPOST(submit_url, postData, success);
866 ajaxPOST(submit_url, postData, success);
867 });
867 });
868
869 YUE.on('preview-btn_'+lineno, 'click', function(e){
870 var _text = YUD.get('text_'+lineno).value;
871 if(!_text){
872 return
873 }
874 var post_data = {'text': _text};
875 YUD.addClass('preview-box_'+lineno, 'unloaded');
876 YUD.get('preview-box_'+lineno).innerHTML = _TM['Loading ...'];
877 YUD.setStyle('edit-container_'+lineno, 'display', 'none');
878 YUD.setStyle('preview-container_'+lineno, 'display', '');
879
880 var url = pyroutes.url('changeset_comment_preview', {'repo_name': REPO_NAME});
881 ajaxPOST(url,post_data,function(o){
882 YUD.get('preview-box_'+lineno).innerHTML = o.responseText;
883 YUD.removeClass('preview-box_'+lineno, 'unloaded');
884 })
885 })
886 YUE.on('edit-btn_'+lineno, 'click', function(e){
887 YUD.setStyle('edit-container_'+lineno, 'display', '');
888 YUD.setStyle('preview-container_'+lineno, 'display', 'none');
889 })
890
868
891
869 setTimeout(function(){
892 setTimeout(function(){
870 // callbacks
893 // callbacks
@@ -886,8 +909,11 b' var deleteComment = function(comment_id)'
886 var root = prevElementSibling(prevElementSibling(n));
909 var root = prevElementSibling(prevElementSibling(n));
887 n.parentNode.removeChild(n);
910 n.parentNode.removeChild(n);
888
911
889 // scann nodes, and attach add button to last one
912 // scann nodes, and attach add button to last one only for TR
890 placeAddButton(root);
913 // which are the inline comments
914 if(root && root.tagName == 'TR'){
915 placeAddButton(root);
916 }
891 }
917 }
892 ajaxPOST(url,postData,success);
918 ajaxPOST(url,postData,success);
893 }
919 }
@@ -60,6 +60,10 b''
60
60
61 var TOGGLE_FOLLOW_URL = "${h.url('toggle_following')}";
61 var TOGGLE_FOLLOW_URL = "${h.url('toggle_following')}";
62
62
63 var REPO_NAME = "";
64 %if hasattr(c, 'repo_name'):
65 var REPO_NAME = "${c.repo_name}";
66 %endif
63 </script>
67 </script>
64 <script type="text/javascript" src="${h.url('/js/yui.2.9.js', ver=c.rhodecode_version)}"></script>
68 <script type="text/javascript" src="${h.url('/js/yui.2.9.js', ver=c.rhodecode_version)}"></script>
65 <!--[if lt IE 9]>
69 <!--[if lt IE 9]>
@@ -90,6 +94,7 b''
90 pyroutes.register('toggle_following', "${h.url('toggle_following')}");
94 pyroutes.register('toggle_following', "${h.url('toggle_following')}");
91 pyroutes.register('changeset_info', "${h.url('changeset_info', repo_name='%(repo_name)s', revision='%(revision)s')}", ['repo_name', 'revision']);
95 pyroutes.register('changeset_info', "${h.url('changeset_info', repo_name='%(repo_name)s', revision='%(revision)s')}", ['repo_name', 'revision']);
92 pyroutes.register('repo_size', "${h.url('repo_size', repo_name='%(repo_name)s')}", ['repo_name']);
96 pyroutes.register('repo_size', "${h.url('repo_size', repo_name='%(repo_name)s')}", ['repo_name']);
97 pyroutes.register('changeset_comment_preview', "${h.url('changeset_comment_preview', repo_name='%(repo_name)s')}", ['repo_name']);
93 })
98 })
94 </script>
99 </script>
95 </%def>
100 </%def>
@@ -12,7 +12,7 b''
12 ${co.author.username}
12 ${co.author.username}
13 </div>
13 </div>
14 <div class="date">
14 <div class="date">
15 ${h.age(co.modified_at)} <a class="permalink" href="#comment-${co.comment_id}">&para;</a>
15 ${h.age(co.modified_at)}
16 </div>
16 </div>
17 %if co.status_change:
17 %if co.status_change:
18 <div style="float:left" class="changeset-status-container">
18 <div style="float:left" class="changeset-status-container">
@@ -22,7 +22,7 b''
22 </div>
22 </div>
23 %endif
23 %endif
24
24
25 <div style="float:left;padding:3px 0px 0px 5px">
25 <div style="float:left;padding:4px 0px 0px 5px">
26 <span class="">
26 <span class="">
27 %if co.pull_request:
27 %if co.pull_request:
28 <a href="${h.url('pullrequest_show',repo_name=co.pull_request.other_repo.repo_name,pull_request_id=co.pull_request.pull_request_id)}">
28 <a href="${h.url('pullrequest_show',repo_name=co.pull_request.other_repo.repo_name,pull_request_id=co.pull_request.pull_request_id)}">
@@ -35,11 +35,9 b''
35 %endif
35 %endif
36 </span>
36 </span>
37 </div>
37 </div>
38
38 <a class="permalink" href="#comment-${co.comment_id}">&para;</a>
39 %if h.HasPermissionAny('hg.admin', 'repository.admin')() or co.author.user_id == c.rhodecode_user.user_id:
39 %if h.HasPermissionAny('hg.admin', 'repository.admin')() or co.author.user_id == c.rhodecode_user.user_id:
40 <div class="buttons">
40 <div onClick="deleteComment(${co.comment_id})" class="buttons delete-comment ui-btn small">${_('Delete')}</div>
41 <span onClick="deleteComment(${co.comment_id})" class="delete-comment ui-btn">${_('Delete')}</span>
42 </div>
43 %endif
41 %endif
44 </div>
42 </div>
45 <div class="text">
43 <div class="text">
@@ -56,7 +54,7 b''
56 %if c.rhodecode_user.username != 'default':
54 %if c.rhodecode_user.username != 'default':
57 <div class="overlay"><div class="overlay-text">${_('Submitting...')}</div></div>
55 <div class="overlay"><div class="overlay-text">${_('Submitting...')}</div></div>
58 ${h.form('#', class_='inline-form')}
56 ${h.form('#', class_='inline-form')}
59 <div class="clearfix">
57 <div id="edit-container_{1}" class="clearfix">
60 <div class="comment-help">${_('Commenting on line {1}.')}
58 <div class="comment-help">${_('Commenting on line {1}.')}
61 ${(_('Comments parsed using %s syntax with %s support.') % (
59 ${(_('Comments parsed using %s syntax with %s support.') % (
62 ('<a href="%s">RST</a>' % h.url('rst_help')),
60 ('<a href="%s">RST</a>' % h.url('rst_help')),
@@ -64,9 +62,17 b''
64 )
62 )
65 )|n
63 )|n
66 }
64 }
65 <div id="preview-btn_{1}" class="preview-btn ui-btn small">${_('preview')}</div>
67 </div>
66 </div>
68 <div class="mentions-container" id="mentions_container_{1}"></div>
67 <div class="mentions-container" id="mentions_container_{1}"></div>
69 <textarea id="text_{1}" name="text" class="yui-ac-input"></textarea>
68 <textarea id="text_{1}" name="text" class="comment-block-ta yui-ac-input"></textarea>
69 </div>
70 <div id="preview-container_{1}" class="clearfix" style="display:none">
71 <div class="comment-help">
72 ${_('Comment Preview')}
73 <div id="edit-btn_{1}" class="edit-btn ui-btn small">${_('edit')}</div>
74 </div>
75 <div id="preview-box_{1}" class="preview-box"></div>
70 </div>
76 </div>
71 <div class="comment-button">
77 <div class="comment-button">
72 <input type="hidden" name="f_path" value="{0}">
78 <input type="hidden" name="f_path" value="{0}">
@@ -134,7 +140,7 b''
134 %if c.rhodecode_user.username != 'default':
140 %if c.rhodecode_user.username != 'default':
135 <div class="comment-form ac">
141 <div class="comment-form ac">
136 ${h.form(post_url)}
142 ${h.form(post_url)}
137 <div class="clearfix">
143 <div id="edit-container" class="clearfix">
138 <div class="comment-help">
144 <div class="comment-help">
139 ${(_('Comments parsed using %s syntax with %s support.') % (('<a href="%s">RST</a>' % h.url('rst_help')),
145 ${(_('Comments parsed using %s syntax with %s support.') % (('<a href="%s">RST</a>' % h.url('rst_help')),
140 '<span style="color:#003367" class="tooltip" title="%s">@mention</span>' %
146 '<span style="color:#003367" class="tooltip" title="%s">@mention</span>' %
@@ -143,6 +149,7 b''
143 | <a id="show_changeset_link" onClick="change_status_show();"> ${_('Change status')}</a>
149 | <a id="show_changeset_link" onClick="change_status_show();"> ${_('Change status')}</a>
144 <input id="show_changeset_status_box" type="checkbox" name="change_changeset_status" style="display: none;" />
150 <input id="show_changeset_status_box" type="checkbox" name="change_changeset_status" style="display: none;" />
145 %endif
151 %endif
152 <div id="preview-btn" class="preview-btn ui-btn small">${_('preview')}</div>
146 </div>
153 </div>
147 %if change_status:
154 %if change_status:
148 <div id="status_block_container" class="status-block" style="display:none">
155 <div id="status_block_container" class="status-block" style="display:none">
@@ -155,8 +162,17 b''
155 </div>
162 </div>
156 %endif
163 %endif
157 <div class="mentions-container" id="mentions_container"></div>
164 <div class="mentions-container" id="mentions_container"></div>
158 ${h.textarea('text')}
165 ${h.textarea('text', class_="comment-block-ta")}
159 </div>
166 </div>
167
168 <div id="preview-container" class="clearfix" style="display:none">
169 <div class="comment-help">
170 ${_('Comment Preview')}
171 <div id="edit-btn" class="edit-btn ui-btn small">${_('edit')}</div>
172 </div>
173 <div id="preview-box" class="preview-box"></div>
174 </div>
175
160 <div class="comment-button">
176 <div class="comment-button">
161 ${h.submit('save', _('Comment'), class_="ui-btn large")}
177 ${h.submit('save', _('Comment'), class_="ui-btn large")}
162 %if close_btn and change_status:
178 %if close_btn and change_status:
@@ -185,6 +201,27 b' YUE.onDOMReady(function () {'
185 YUD.addClass('save_close', 'hidden');
201 YUD.addClass('save_close', 'hidden');
186 }
202 }
187 })
203 })
204 YUE.on('preview-btn', 'click', function(e){
205 var _text = YUD.get('text').value;
206 if(!_text){
207 return
208 }
209 var post_data = {'text': _text};
210 YUD.addClass('preview-box', 'unloaded');
211 YUD.get('preview-box').innerHTML = _TM['Loading ...'];
212 YUD.setStyle('edit-container', 'display', 'none');
213 YUD.setStyle('preview-container', 'display', '');
214
215 var url = pyroutes.url('changeset_comment_preview', {'repo_name': '${c.repo_name}'});
216 ajaxPOST(url,post_data,function(o){
217 YUD.get('preview-box').innerHTML = o.responseText;
218 YUD.removeClass('preview-box', 'unloaded');
219 })
220 })
221 YUE.on('edit-btn', 'click', function(e){
222 YUD.setStyle('edit-container', 'display', '');
223 YUD.setStyle('preview-container', 'display', 'none');
224 })
188
225
189 });
226 });
190 </script>
227 </script>
General Comments 0
You need to be logged in to leave comments. Login now