##// END OF EJS Templates
#415: Adding comment to changeset causes reload...
marcink -
r2187:b61e5401 beta
parent child Browse files
Show More
@@ -0,0 +1,2 b''
1 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
2 ${comment.comment_block(c.co)} No newline at end of file
@@ -359,16 +359,25 b' class ChangesetController(BaseRepoContro'
359 359
360 360 return render('changeset/raw_changeset.html')
361 361
362 @jsonify
362 363 def comment(self, repo_name, revision):
363 ChangesetCommentsModel().create(text=request.POST.get('text'),
364 repo_id=c.rhodecode_db_repo.repo_id,
365 user_id=c.rhodecode_user.user_id,
366 revision=revision,
367 f_path=request.POST.get('f_path'),
368 line_no=request.POST.get('line'))
364 comm = ChangesetCommentsModel().create(
365 text=request.POST.get('text'),
366 repo_id=c.rhodecode_db_repo.repo_id,
367 user_id=c.rhodecode_user.user_id,
368 revision=revision,
369 f_path=request.POST.get('f_path'),
370 line_no=request.POST.get('line')
371 )
369 372 Session.commit()
370 return redirect(h.url('changeset_home', repo_name=repo_name,
371 revision=revision))
373 data = {
374 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
375 }
376 if comm:
377 c.co = comm
378 data.update(comm.get_dict())
379 data.update({'rendered_text': render('changeset/changeset_comment_block.html')})
380 return data
372 381
373 382 @jsonify
374 383 def delete_comment(self, repo_name, comment_id):
@@ -142,7 +142,9 b' class ChangesetCommentsModel(BaseModel):'
142 142 .filter(ChangesetComment.repo_id == repo_id)\
143 143 .filter(ChangesetComment.revision == revision)\
144 144 .filter(ChangesetComment.line_no != None)\
145 .filter(ChangesetComment.f_path != None).all()
145 .filter(ChangesetComment.f_path != None)\
146 .order_by(ChangesetComment.comment_id.asc())\
147 .all()
146 148
147 149 paths = defaultdict(lambda: defaultdict(list))
148 150
@@ -3966,6 +3966,7 b' form.comment-form {'
3966 3966
3967 3967 .comment .buttons {
3968 3968 float: right;
3969 padding:2px 2px 0px 0px;
3969 3970 }
3970 3971
3971 3972
@@ -3975,6 +3976,23 b' form.comment-form {'
3975 3976 }
3976 3977
3977 3978 /** comment inline form **/
3979 .comment-inline-form .overlay{
3980 display: none;
3981 }
3982 .comment-inline-form .overlay.submitting{
3983 display:block;
3984 background: none repeat scroll 0 0 white;
3985 font-size: 16px;
3986 opacity: 0.5;
3987 position: absolute;
3988 text-align: center;
3989 vertical-align: top;
3990
3991 }
3992 .comment-inline-form .overlay.submitting .overlay-text{
3993 width:100%;
3994 margin-top:5%;
3995 }
3978 3996
3979 3997 .comment-inline-form .clearfix{
3980 3998 background: #EEE;
@@ -3987,6 +4005,7 b' form.comment-form {'
3987 4005 div.comment-inline-form {
3988 4006 margin-top: 5px;
3989 4007 padding:2px 6px 8px 6px;
4008
3990 4009 }
3991 4010
3992 4011 .comment-inline-form strong {
@@ -4047,6 +4066,10 b' form.comment-inline-form {'
4047 4066 margin: 3px 3px 5px 5px;
4048 4067 background-color: #FAFAFA;
4049 4068 }
4069 .inline-comments .add-comment {
4070 padding: 2px 4px 8px 5px;
4071 }
4072
4050 4073 .inline-comments .comment-wrapp{
4051 4074 padding:1px;
4052 4075 }
@@ -4078,7 +4101,7 b' form.comment-inline-form {'
4078 4101 font-size: 16px;
4079 4102 }
4080 4103 .inline-comments-button .add-comment{
4081 margin:10px 5px !important;
4104 margin:2px 0px 8px 5px !important
4082 4105 }
4083 4106 .notifications{
4084 4107 border-radius: 4px 4px 4px 4px;
@@ -195,6 +195,31 b' function ypjax(url,container,s_call,f_ca'
195 195
196 196 };
197 197
198 var ajaxPOST = function(url,postData,success) {
199 var toQueryString = function(o) {
200 if(typeof o !== 'object') {
201 return false;
202 }
203 var _p, _qs = [];
204 for(_p in o) {
205 _qs.push(encodeURIComponent(_p) + '=' + encodeURIComponent(o[_p]));
206 }
207 return _qs.join('&');
208 };
209
210 var sUrl = url;
211 var callback = {
212 success: success,
213 failure: function (o) {
214 alert("error");
215 },
216 };
217 var postData = toQueryString(postData);
218 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
219 return request;
220 };
221
222
198 223 /**
199 224 * tooltip activate
200 225 */
@@ -300,33 +325,25 b' var q_filter = function(target,nodes,dis'
300 325 }
301 326 };
302 327
303 var ajaxPOST = function(url,postData,success) {
304 var sUrl = url;
305 var callback = {
306 success: success,
307 failure: function (o) {
308 alert("error");
309 },
310 };
311 var postData = postData;
312 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
328 var tableTr = function(cls,body){
329 var tr = document.createElement('tr');
330 YUD.addClass(tr, cls);
331
332
333 var cont = new YAHOO.util.Element(body);
334 var comment_id = fromHTML(body).children[0].id.split('comment-')[1];
335 tr.id = 'comment-tr-{0}'.format(comment_id);
336 tr.innerHTML = '<td class="lineno-inline new-inline"></td>'+
337 '<td class="lineno-inline old-inline"></td>'+
338 '<td>{0}</td>'.format(body);
339 return tr;
313 340 };
314 341
315
316 342 /** comments **/
317 343 var removeInlineForm = function(form) {
318 344 form.parentNode.removeChild(form);
319 345 };
320 346
321 var tableTr = function(cls,body){
322 var form = document.createElement('tr');
323 YUD.addClass(form, cls);
324 form.innerHTML = '<td class="lineno-inline new-inline"></td>'+
325 '<td class="lineno-inline old-inline"></td>'+
326 '<td>{0}</td>'.format(body);
327 return form;
328 };
329
330 347 var createInlineForm = function(parent_tr, f_path, line) {
331 348 var tmpl = YUD.get('comment-inline-form-template').innerHTML;
332 349 tmpl = tmpl.format(f_path, line);
@@ -337,12 +354,27 b' var createInlineForm = function(parent_t'
337 354 var form_hide_button = new YAHOO.util.Element(form.getElementsByClassName('hide-inline-form')[0]);
338 355 form_hide_button.on('click', function(e) {
339 356 var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
357 if(YUD.hasClass(newtr.nextElementSibling,'inline-comments-button')){
358 YUD.setStyle(newtr.nextElementSibling,'display','');
359 }
340 360 removeInlineForm(newtr);
341 361 YUD.removeClass(parent_tr, 'form-open');
362
342 363 });
364
343 365 return form
344 366 };
367
368 /**
369 * Inject inline comment for on given TR this tr should be always an .line
370 * tr containing the line. Code will detect comment, and always put the comment
371 * block at the very bottom
372 */
345 373 var injectInlineForm = function(tr){
374 if(!YUD.hasClass(tr, 'line')){
375 return
376 }
377 var submit_url = AJAX_COMMENT_URL;
346 378 if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context') || YUD.hasClass(tr,'no-comment')){
347 379 return
348 380 }
@@ -350,20 +382,92 b' var injectInlineForm = function(tr){'
350 382 var node = tr.parentNode.parentNode.parentNode.getElementsByClassName('full_f_path')[0];
351 383 var f_path = YUD.getAttribute(node,'path');
352 384 var lineno = getLineNo(tr);
353 var form = createInlineForm(tr, f_path, lineno);
354 var target_tr = tr;
355 if(YUD.hasClass(YUD.getNextSibling(tr),'inline-comments')){
356 target_tr = YUD.getNextSibling(tr);
357 }
358 YUD.insertAfter(form,target_tr);
385 var form = createInlineForm(tr, f_path, lineno, submit_url);
386
387 var parent = tr;
388 while (1){
389 var n = parent.nextElementSibling;
390 // next element are comments !
391 if(YUD.hasClass(n,'inline-comments')){
392 parent = n;
393 }
394 else{
395 break;
396 }
397 }
398 YUD.insertAfter(form,parent);
399
359 400 YUD.get('text_'+lineno).focus();
401 var f = YUD.get(form);
402
403 var overlay = f.getElementsByClassName('overlay')[0];
404 var _form = f.getElementsByClassName('inline-form')[0];
405
406 form.on('submit',function(e){
407 YUE.preventDefault(e);
408
409 //ajax submit
410 var text = YUD.get('text_'+lineno).value;
411 var postData = {
412 'text':text,
413 'f_path':f_path,
414 'line':lineno
415 };
416
417 if(lineno === undefined){
418 alert('missing line !');
419 return
420 }
421 if(f_path === undefined){
422 alert('missing file path !');
423 return
424 }
425
426 var success = function(o){
427 YUD.removeClass(tr, 'form-open');
428 removeInlineForm(f);
429 var json_data = JSON.parse(o.responseText);
430 renderInlineComment(json_data);
431 };
432
433 if (YUD.hasClass(overlay,'overlay')){
434 var w = _form.offsetWidth;
435 var h = _form.offsetHeight;
436 YUD.setStyle(overlay,'width',w+'px');
437 YUD.setStyle(overlay,'height',h+'px');
438 }
439 YUD.addClass(overlay, 'submitting');
440
441 ajaxPOST(submit_url, postData, success);
442 });
443
360 444 tooltip_activate();
361 445 };
362 446
363 var createInlineAddButton = function(tr,label){
364 var html = '<div class="add-comment"><span class="ui-btn">{0}</span></div>'.format(label);
365
366 var add = new YAHOO.util.Element(tableTr('inline-comments-button',html));
447 var deleteComment = function(comment_id){
448 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__',comment_id);
449 var postData = {'_method':'delete'};
450 var success = function(o){
451 var n = YUD.get('comment-tr-'+comment_id);
452 var root = n.previousElementSibling.previousElementSibling;
453 n.parentNode.removeChild(n);
454
455 // scann nodes, and attach add button to last one
456 placeAddButton(root);
457 }
458 ajaxPOST(url,postData,success);
459 }
460
461
462 var createInlineAddButton = function(tr){
463
464 var label = TRANSLATION_MAP['add another comment'];
465
466 var html_el = document.createElement('div');
467 YUD.addClass(html_el, 'add-comment');
468 html_el.innerHTML = '<span class="ui-btn">{0}</span>'.format(label);
469
470 var add = new YAHOO.util.Element(html_el);
367 471 add.on('click', function(e) {
368 472 injectInlineForm(tr);
369 473 });
@@ -384,6 +488,103 b' var getLineNo = function(tr) {'
384 488 return line
385 489 };
386 490
491 var placeAddButton = function(target_tr){
492 if(!target_tr){
493 return
494 }
495 var last_node = target_tr;
496 //scann
497 while (1){
498 var n = last_node.nextElementSibling;
499 // next element are comments !
500 if(YUD.hasClass(n,'inline-comments')){
501 last_node = n;
502 //also remove the comment button from previos
503 var comment_add_buttons = last_node.getElementsByClassName('add-comment');
504 for(var i=0;i<comment_add_buttons.length;i++){
505 var b = comment_add_buttons[i];
506 b.parentNode.removeChild(b);
507 }
508 }
509 else{
510 break;
511 }
512 }
513
514 var add = createInlineAddButton(target_tr);
515 // get the comment div
516 var comment_block = last_node.getElementsByClassName('comment')[0];
517 // attach add button
518 YUD.insertAfter(add,comment_block);
519 }
520
521 /**
522 * Places the inline comment into the changeset block in proper line position
523 */
524 var placeInline = function(target_container,lineno,html){
525 var lineid = "{0}_{1}".format(target_container,lineno);
526 var target_line = YUD.get(lineid);
527 var comment = new YAHOO.util.Element(tableTr('inline-comments',html))
528
529 // check if there are comments already !
530 var parent = target_line.parentNode;
531 var root_parent = parent;
532 while (1){
533 var n = parent.nextElementSibling;
534 // next element are comments !
535 if(YUD.hasClass(n,'inline-comments')){
536 parent = n;
537 }
538 else{
539 break;
540 }
541 }
542 // put in the comment at the bottom
543 YUD.insertAfter(comment,parent);
544
545 // scann nodes, and attach add button to last one
546 placeAddButton(root_parent);
547
548 return target_line;
549 }
550
551 /**
552 * make a single inline comment and place it inside
553 */
554 var renderInlineComment = function(json_data){
555 try{
556 var html = json_data['rendered_text'];
557 var lineno = json_data['line_no'];
558 var target_id = json_data['target_id'];
559 placeInline(target_id, lineno, html);
560
561 }catch(e){
562 console.log(e);
563 }
564 }
565
566 /**
567 * Iterates over all the inlines, and places them inside proper blocks of data
568 */
569 var renderInlineComments = function(file_comments){
570 for (f in file_comments){
571 // holding all comments for a FILE
572 var box = file_comments[f];
573
574 var target_id = YUD.getAttribute(box,'target_id');
575 // actually comments with line numbers
576 var comments = box.children;
577 for(var i=0; i<comments.length; i++){
578 var data = {
579 'rendered_text': comments[i].outerHTML,
580 'line_no': YUD.getAttribute(comments[i],'line'),
581 'target_id': target_id
582 }
583 renderInlineComment(data);
584 }
585 }
586 }
587
387 588
388 589 var fileBrowserListeners = function(current_url, node_list_url, url_base,
389 590 truncated_lbl, nomatch_lbl){
@@ -47,9 +47,13 b''
47 47
48 48 <script type="text/javascript">
49 49 var follow_base_url = "${h.url('toggle_following')}";
50 var stop_follow_text = "${_('Stop following this repository')}";
51 var start_follow_text = "${_('Start following this repository')}";
52
50
51 //JS translations map
52 var TRANSLATION_MAP = {
53 'add another comment':'${_("add another comment")}',
54 'Stop following this repository':"${_('Stop following this repository')}",
55 'Start following this repository':"${_('Start following this repository')}",
56 };
53 57
54 58 var onSuccessFollow = function(target){
55 59 var f = YUD.get(target.id);
@@ -57,7 +61,7 b''
57 61
58 62 if(f.getAttribute('class')=='follow'){
59 63 f.setAttribute('class','following');
60 f.setAttribute('title',stop_follow_text);
64 f.setAttribute('title',TRANSLATION_MAP['Stop following this repository']);
61 65
62 66 if(f_cnt){
63 67 var cnt = Number(f_cnt.innerHTML)+1;
@@ -66,7 +70,7 b''
66 70 }
67 71 else{
68 72 f.setAttribute('class','follow');
69 f.setAttribute('title',start_follow_text);
73 f.setAttribute('title',TRANSLATION_MAP['Start following this repository']);
70 74 if(f_cnt){
71 75 var cnt = Number(f_cnt.innerHTML)+1;
72 76 f_cnt.innerHTML = cnt;
@@ -122,22 +122,12 b''
122 122 <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
123 123 ${comment.comment_inline_form(c.changeset)}
124 124
125 ## render comments
125 126 ${comment.comments(c.changeset)}
126
127 127 <script type="text/javascript">
128 var deleteComment = function(comment_id){
129
130 var url = "${url('changeset_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}".replace('__COMMENT_ID__',comment_id);
131 var postData = '_method=delete';
132 var success = function(o){
133 var n = YUD.get('comment-'+comment_id);
134 n.parentNode.removeChild(n);
135 }
136 ajaxPOST(url,postData,success);
137 }
138
139 128 YUE.onDOMReady(function(){
140
129 AJAX_COMMENT_URL = "${url('changeset_comment',repo_name=c.repo_name,revision=c.changeset.raw_id)}";
130 AJAX_COMMENT_DELETE_URL = "${url('changeset_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}"
141 131 YUE.on(YUQ('.show-inline-comments'),'change',function(e){
142 132 var show = 'none';
143 133 var target = e.currentTarget;
@@ -162,28 +152,7 b''
162 152
163 153 // inject comments into they proper positions
164 154 var file_comments = YUQ('.inline-comment-placeholder');
165
166 for (f in file_comments){
167 var box = file_comments[f];
168 var inlines = box.children;
169 for(var i=0; i<inlines.length; i++){
170 try{
171
172 var inline = inlines[i];
173 var lineno = YUD.getAttribute(inlines[i],'line');
174 var lineid = "{0}_{1}".format(YUD.getAttribute(inline,'target_id'),lineno);
175 var target_line = YUD.get(lineid);
176
177 var add = createInlineAddButton(target_line.parentNode,'${_("add another comment")}');
178 YUD.insertAfter(add,target_line.parentNode);
179
180 var comment = new YAHOO.util.Element(tableTr('inline-comments',inline.innerHTML))
181 YUD.insertAfter(comment,target_line.parentNode);
182 }catch(e){
183 console.log(e);
184 }
185 }
186 }
155 renderInlineComments(file_comments);
187 156 })
188 157
189 158 </script>
@@ -4,7 +4,7 b''
4 4 ## ${comment.comment_block(co)}
5 5 ##
6 6 <%def name="comment_block(co)">
7 <div class="comment" id="comment-${co.comment_id}">
7 <div class="comment" id="comment-${co.comment_id}" line="${co.line_no}">
8 8 <div class="comment-wrapp">
9 9 <div class="meta">
10 10 <span class="user">
@@ -32,7 +32,8 b''
32 32 <div id='comment-inline-form-template' style="display:none">
33 33 <div class="comment-inline-form">
34 34 %if c.rhodecode_user.username != 'default':
35 ${h.form(h.url('changeset_comment', repo_name=c.repo_name, revision=changeset.raw_id))}
35 <div class="overlay"><div class="overlay-text">${_('Submitting...')}</div></div>
36 ${h.form(h.url('changeset_comment', repo_name=c.repo_name, revision=changeset.raw_id),class_='inline-form')}
36 37 <div class="clearfix">
37 38 <div class="comment-help">${_('Commenting on line')} {1}. ${_('Comments parsed using')}
38 39 <a href="${h.url('rst_help')}">RST</a> ${_('syntax')} ${_('with')}
@@ -43,7 +44,7 b''
43 44 <div class="comment-button">
44 45 <input type="hidden" name="f_path" value="{0}">
45 46 <input type="hidden" name="line" value="{1}">
46 ${h.submit('save', _('Comment'), class_='ui-btn')}
47 ${h.submit('save', _('Comment'), class_='ui-btn save-inline-form')}
47 48 ${h.reset('hide-inline-form', _('Hide'), class_='ui-btn hide-inline-form')}
48 49 </div>
49 50 ${h.end_form()}
@@ -64,23 +65,27 b''
64 65 </%def>
65 66
66 67
67 <%def name="comments(changeset)">
68
69 <div class="comments">
68 <%def name="inlines(changeset)">
70 69 <div class="comments-number">${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})</div>
71
72 70 %for path, lines in c.inline_comments:
73 <div style="display:none" class="inline-comment-placeholder" path="${path}" target_id="${h.FID(changeset.raw_id,path)}">
74 71 % for line,comments in lines.iteritems():
75 <div class="inline-comment-placeholder-line" line="${line}" target_id="${h.safeid(h.safe_unicode(path))}">
72 <div style="display:none" class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}">
76 73 %for co in comments:
77 74 ${comment_block(co)}
78 75 %endfor
79 76 </div>
80 77 %endfor
81 </div>
82 78 %endfor
79
80 </%def>
83 81
82 <%def name="comments(changeset)">
83
84 <div class="comments">
85 <div id="inline-comments-container">
86 ${inlines(changeset)}
87 </div>
88
84 89 %for co in c.comments:
85 90 ${comment_block(co)}
86 91 %endfor
General Comments 0
You need to be logged in to leave comments. Login now