Commit caeb65b1892c8a140d8f72f6aafa3f5fd1d3cbc3

Authored by randx
2 parents a82977c6 07eec9c6

Merge branch 'change-notes-order' of https://github.com/riyad/gitlabhq into riyad-change-notes-order

app/assets/javascripts/note.js
@@ -1,182 +0,0 @@ @@ -1,182 +0,0 @@
1 -var NoteList = {  
2 -  
3 - notes_path: null,  
4 - target_params: null,  
5 - target_id: 0,  
6 - target_type: null,  
7 - first_id: 0,  
8 - last_id: 0,  
9 - disable:false,  
10 -  
11 - init:  
12 - function(tid, tt, path) {  
13 - this.notes_path = path + ".js";  
14 - this.target_id = tid;  
15 - this.target_type = tt;  
16 - this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id;  
17 -  
18 - // get notes  
19 - this.getContent();  
20 -  
21 - // get new notes every n seconds  
22 - this.initRefresh();  
23 -  
24 - $('.delete-note').live('ajax:success', function() {  
25 - $(this).closest('li').fadeOut(); });  
26 -  
27 - $(".note-form-holder").live("ajax:before", function(){  
28 - $(".submit_note").disable()  
29 - })  
30 -  
31 - $(".note-form-holder").live("ajax:complete", function(){  
32 - $(".submit_note").enable()  
33 - })  
34 -  
35 - disableButtonIfEmptyField(".note-text", ".submit_note");  
36 -  
37 - $(".note-text").live("focus", function(){  
38 - $(this).css("height", "80px");  
39 - $('.note_advanced_opts').show();  
40 - });  
41 -  
42 - $("#note_attachment").change(function(e){  
43 - var val = $('.input-file').val();  
44 - var filename = val.replace(/^.*[\\\/]/, '');  
45 - $(".file_name").text(filename);  
46 - });  
47 -  
48 - },  
49 -  
50 -  
51 - /**  
52 - * Load new notes to fresh list called 'new_notes_list':  
53 - * - Replace 'new_notes_list' with new list every n seconds  
54 - * - Append new notes to this list after submit  
55 - */  
56 -  
57 - initRefresh:  
58 - function() {  
59 - // init timer  
60 - var intNew = setInterval("NoteList.getNew()", 10000);  
61 - },  
62 -  
63 - replace:  
64 - function(html) {  
65 - $("#new_notes_list").html(html);  
66 - },  
67 -  
68 - prepend:  
69 - function(id, html) {  
70 - if(id != this.last_id) {  
71 - $("#new_notes_list").prepend(html);  
72 - }  
73 - },  
74 -  
75 - getNew:  
76 - function() {  
77 - // refersh notes list  
78 - $.ajax({  
79 - type: "GET",  
80 - url: this.notes_path,  
81 - data: "last_id=" + this.last_id + this.target_params,  
82 - dataType: "script"});  
83 - },  
84 -  
85 - refresh:  
86 - function() {  
87 - // refersh notes list  
88 - $.ajax({  
89 - type: "GET",  
90 - url: this.notes_path,  
91 - data: "first_id=" + this.first_id + "&last_id=" + this.last_id + this.target_params,  
92 - dataType: "script"});  
93 - },  
94 -  
95 -  
96 - /**  
97 - * Init load of notes:  
98 - * 1. Get content with ajax call  
99 - * 2. Set content of notes list with loaded one  
100 - */  
101 -  
102 -  
103 - getContent:  
104 - function() {  
105 - $.ajax({  
106 - type: "GET",  
107 - url: this.notes_path,  
108 - data: "?" + this.target_params,  
109 - complete: function(){ $('.status').removeClass("loading")},  
110 - beforeSend: function() { $('.status').addClass("loading") },  
111 - dataType: "script"});  
112 - },  
113 -  
114 - setContent:  
115 - function(fid, lid, html) {  
116 - this.last_id = lid;  
117 - this.first_id = fid;  
118 - $("#notes-list").html(html);  
119 -  
120 - // Init infinite scrolling  
121 - this.initLoadMore();  
122 - },  
123 -  
124 -  
125 - /**  
126 - * Paging for old notes when scroll to bottom:  
127 - * 1. Init scroll events with 'initLoadMore'  
128 - * 2. Load onlder notes with 'getOld' method  
129 - * 3. append old notes to bottom of list with 'append'  
130 - *  
131 - */  
132 - getOld:  
133 - function() {  
134 - $('.loading').show();  
135 - $.ajax({  
136 - type: "GET",  
137 - url: this.notes_path,  
138 - data: "first_id=" + this.first_id + this.target_params,  
139 - complete: function(){ $('.status').removeClass("loading")},  
140 - beforeSend: function() { $('.status').addClass("loading") },  
141 - dataType: "script"});  
142 - },  
143 -  
144 - append:  
145 - function(id, html) {  
146 - if(this.first_id == id) {  
147 - this.disable = true;  
148 - } else {  
149 - this.first_id = id;  
150 - $("#notes-list").append(html);  
151 - }  
152 - },  
153 -  
154 - initLoadMore:  
155 - function() {  
156 - $(document).endlessScroll({  
157 - bottomPixels: 400,  
158 - fireDelay: 1000,  
159 - fireOnce:true,  
160 - ceaseFire: function() {  
161 - return NoteList.disable;  
162 - },  
163 - callback: function(i) {  
164 - NoteList.getOld();  
165 - }  
166 - });  
167 - }  
168 -};  
169 -  
170 -var PerLineNotes = {  
171 - init:  
172 - function() {  
173 - $(".line_note_link, .line_note_reply_link").live("click", function(e) {  
174 - var form = $(".per_line_form");  
175 - $(this).closest("tr").after(form);  
176 - form.find("#note_line_code").val($(this).attr("line_code"));  
177 - form.show();  
178 - return false;  
179 - });  
180 - disableButtonIfEmptyField(".line-note-text", ".submit_inline_note");  
181 - }  
182 -}  
app/assets/javascripts/notes.js 0 → 100644
@@ -0,0 +1,251 @@ @@ -0,0 +1,251 @@
  1 +var NoteList = {
  2 +
  3 + notes_path: null,
  4 + target_params: null,
  5 + target_id: 0,
  6 + target_type: null,
  7 + top_id: 0,
  8 + bottom_id: 0,
  9 + loading_more_disabled: false,
  10 + reversed: false,
  11 +
  12 + init:
  13 + function(tid, tt, path) {
  14 + this.notes_path = path + ".js";
  15 + this.target_id = tid;
  16 + this.target_type = tt;
  17 + this.reversed = $("#notes-list").hasClass("reversed");
  18 + this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id;
  19 +
  20 + // get initial set of notes
  21 + this.getContent();
  22 +
  23 + $("#notes-list, #new-notes-list").on("ajax:success", ".delete-note", function() {
  24 + $(this).closest('li').fadeOut();
  25 + });
  26 +
  27 + $(".note-form-holder").on("ajax:before", function(){
  28 + $(".submit_note").disable()
  29 + })
  30 +
  31 + $(".note-form-holder").on("ajax:complete", function(){
  32 + $(".submit_note").enable()
  33 + })
  34 +
  35 + disableButtonIfEmptyField(".note-text", ".submit_note");
  36 +
  37 + $(".note-text").on("focus", function(){
  38 + $(this).css("height", "80px");
  39 + $('.note_advanced_opts').show();
  40 + });
  41 +
  42 + $("#note_attachment").change(function(e){
  43 + var val = $('.input-file').val();
  44 + var filename = val.replace(/^.*[\\\/]/, '');
  45 + $(".file_name").text(filename);
  46 + });
  47 + },
  48 +
  49 +
  50 + /**
  51 + * Handle loading the initial set of notes.
  52 + * And set up loading more notes when scrolling to the bottom of the page.
  53 + */
  54 +
  55 +
  56 + /**
  57 + * Gets an inital set of notes.
  58 + */
  59 + getContent:
  60 + function() {
  61 + $.ajax({
  62 + type: "GET",
  63 + url: this.notes_path,
  64 + data: "?" + this.target_params,
  65 + complete: function(){ $('.notes-status').removeClass("loading")},
  66 + beforeSend: function() { $('.notes-status').addClass("loading") },
  67 + dataType: "script"});
  68 + },
  69 +
  70 + /**
  71 + * Called in response to getContent().
  72 + * Replaces the content of #notes-list with the given html.
  73 + */
  74 + setContent:
  75 + function(first_id, last_id, html) {
  76 + this.top_id = first_id;
  77 + this.bottom_id = last_id;
  78 + $("#notes-list").html(html);
  79 +
  80 + // init infinite scrolling
  81 + this.initLoadMore();
  82 +
  83 + // init getting new notes
  84 + if (this.reversed) {
  85 + this.initRefreshNew();
  86 + }
  87 + },
  88 +
  89 +
  90 + /**
  91 + * Handle loading more notes when scrolling to the bottom of the page.
  92 + * The id of the last note in the list is in this.bottom_id.
  93 + *
  94 + * Set up refreshing only new notes after all notes have been loaded.
  95 + */
  96 +
  97 +
  98 + /**
  99 + * Initializes loading more notes when scrolling to the bottom of the page.
  100 + */
  101 + initLoadMore:
  102 + function() {
  103 + $(document).endlessScroll({
  104 + bottomPixels: 400,
  105 + fireDelay: 1000,
  106 + fireOnce:true,
  107 + ceaseFire: function() {
  108 + return NoteList.loading_more_disabled;
  109 + },
  110 + callback: function(i) {
  111 + NoteList.getMore();
  112 + }
  113 + });
  114 + },
  115 +
  116 + /**
  117 + * Gets an additional set of notes.
  118 + */
  119 + getMore:
  120 + function() {
  121 + // only load more notes if there are no "new" notes
  122 + $('.loading').show();
  123 + $.ajax({
  124 + type: "GET",
  125 + url: this.notes_path,
  126 + data: "loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id + this.target_params,
  127 + complete: function(){ $('.notes-status').removeClass("loading")},
  128 + beforeSend: function() { $('.notes-status').addClass("loading") },
  129 + dataType: "script"});
  130 + },
  131 +
  132 + /**
  133 + * Called in response to getMore().
  134 + * Append notes to #notes-list.
  135 + */
  136 + appendMoreNotes:
  137 + function(id, html) {
  138 + if(id != this.bottom_id) {
  139 + this.bottom_id = id;
  140 + $("#notes-list").append(html);
  141 + }
  142 + },
  143 +
  144 + /**
  145 + * Called in response to getMore().
  146 + * Disables loading more notes when scrolling to the bottom of the page.
  147 + * Initalizes refreshing new notes.
  148 + */
  149 + finishedLoadingMore:
  150 + function() {
  151 + this.loading_more_disabled = true;
  152 +
  153 + // from now on only get new notes
  154 + if (!this.reversed) {
  155 + this.initRefreshNew();
  156 + }
  157 + },
  158 +
  159 +
  160 + /**
  161 + * Handle refreshing and adding of new notes.
  162 + *
  163 + * New notes are all notes that are created after the site has been loaded.
  164 + * The "old" notes are in #notes-list the "new" ones will be in #new-notes-list.
  165 + * The id of the last "old" note is in this.bottom_id.
  166 + */
  167 +
  168 +
  169 + /**
  170 + * Initializes getting new notes every n seconds.
  171 + */
  172 + initRefreshNew:
  173 + function() {
  174 + setInterval("NoteList.getNew()", 10000);
  175 + },
  176 +
  177 + /**
  178 + * Gets the new set of notes.
  179 + */
  180 + getNew:
  181 + function() {
  182 + $.ajax({
  183 + type: "GET",
  184 + url: this.notes_path,
  185 + data: "loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id) + this.target_params,
  186 + dataType: "script"});
  187 + },
  188 +
  189 + /**
  190 + * Called in response to getNew().
  191 + * Replaces the content of #new-notes-list with the given html.
  192 + */
  193 + replaceNewNotes:
  194 + function(html) {
  195 + $("#new-notes-list").html(html);
  196 + },
  197 +
  198 + /**
  199 + * Adds a single note to #new-notes-list.
  200 + */
  201 + appendNewNote:
  202 + function(id, html) {
  203 + if (this.reversed) {
  204 + $("#new-notes-list").prepend(html);
  205 + } else {
  206 + $("#new-notes-list").append(html);
  207 + }
  208 + }
  209 +};
  210 +
  211 +var PerLineNotes = {
  212 + init:
  213 + function() {
  214 + /**
  215 + * Called when clicking on the "add note" or "reply" button for a diff line.
  216 + *
  217 + * Shows the note form below the line.
  218 + * Sets some hidden fields in the form.
  219 + */
  220 + $(".diff_file_content").on("click", ".line_note_link, .line_note_reply_link", function(e) {
  221 + var form = $(".per_line_form");
  222 + $(this).closest("tr").after(form);
  223 + form.find("#note_line_code").val($(this).data("lineCode"));
  224 + form.show();
  225 + return false;
  226 + });
  227 +
  228 + disableButtonIfEmptyField(".line-note-text", ".submit_inline_note");
  229 +
  230 + /**
  231 + * Called in response to successfully deleting a note on a diff line.
  232 + *
  233 + * Removes the actual note from view.
  234 + * Removes the reply button if the last note for that line has been removed.
  235 + */
  236 + $(".diff_file_content").on("ajax:success", ".delete-note", function() {
  237 + var trNote = $(this).closest("tr");
  238 + trNote.fadeOut(function() {
  239 + $(this).remove();
  240 + });
  241 +
  242 + // check if this is the last note for this line
  243 + // elements must really be removed for this to work reliably
  244 + var trLine = trNote.prev();
  245 + var trRpl = trNote.next();
  246 + if (trLine.hasClass("line_holder") && trRpl.hasClass("reply")) {
  247 + trRpl.fadeOut(function() { $(this).remove(); });
  248 + }
  249 + });
  250 + }
  251 +}
app/assets/stylesheets/sections/notes.scss
@@ -3,14 +3,17 @@ @@ -3,14 +3,17 @@
3 * 3 *
4 */ 4 */
5 #notes-list, 5 #notes-list,
6 -#new_notes_list { 6 +#new-notes-list {
7 display:block; 7 display:block;
8 list-style:none; 8 list-style:none;
9 margin:0px; 9 margin:0px;
10 padding:0px; 10 padding:0px;
11 } 11 }
12 12
13 -#new_notes_list li:last-child{ 13 +#new-notes-list:not(.reversed) {
  14 + border-top:1px solid #aaa;
  15 +}
  16 +#new-notes-list.reversed {
14 border-bottom:1px solid #aaa; 17 border-bottom:1px solid #aaa;
15 } 18 }
16 19
@@ -48,7 +51,6 @@ @@ -48,7 +51,6 @@
48 51
49 .note { 52 .note {
50 padding: 8px 0; 53 padding: 8px 0;
51 - border-bottom: 1px solid #eee;  
52 overflow: hidden; 54 overflow: hidden;
53 display: block; 55 display: block;
54 img {float: left; margin-right: 10px;} 56 img {float: left; margin-right: 10px;}
@@ -70,6 +72,18 @@ @@ -70,6 +72,18 @@
70 .delete-note { display:block; } 72 .delete-note { display:block; }
71 } 73 }
72 } 74 }
  75 +#notes-list:not(.reversed) .note,
  76 +#new-notes-list:not(.reversed) .note {
  77 + border-bottom: 1px solid #eee;
  78 +}
  79 +#notes-list.reversed .note,
  80 +#new-notes-list.reversed .note {
  81 + border-top: 1px solid #eee;
  82 +}
  83 +
  84 +.notes-status {
  85 + margin: 18px;
  86 +}
73 87
74 88
75 p.notify_controls input{ 89 p.notify_controls input{
app/contexts/notes/load_context.rb
@@ -3,30 +3,31 @@ module Notes @@ -3,30 +3,31 @@ module Notes
3 def execute 3 def execute
4 target_type = params[:target_type] 4 target_type = params[:target_type]
5 target_id = params[:target_id] 5 target_id = params[:target_id]
6 - first_id = params[:first_id]  
7 - last_id = params[:last_id] 6 + after_id = params[:after_id]
  7 + before_id = params[:before_id]
8 8
9 9
10 @notes = case target_type 10 @notes = case target_type
11 - when "commit"  
12 - then project.commit_notes(project.commit(target_id)).fresh.limit(20)  
13 - when "snippet"  
14 - then project.snippets.find(target_id).notes  
15 - when "wall"  
16 - then project.common_notes.order("created_at DESC").fresh.limit(50) 11 + when "commit"
  12 + project.commit_notes(project.commit(target_id)).fresh.limit(20)
17 when "issue" 13 when "issue"
18 - then project.issues.find(target_id).notes.inc_author.order("created_at DESC").limit(20) 14 + project.issues.find(target_id).notes.inc_author.fresh.limit(20)
19 when "merge_request" 15 when "merge_request"
20 - then project.merge_requests.find(target_id).notes.inc_author.order("created_at DESC").limit(20) 16 + project.merge_requests.find(target_id).notes.inc_author.fresh.limit(20)
  17 + when "snippet"
  18 + project.snippets.find(target_id).notes.fresh
  19 + when "wall"
  20 + # this is the only case, where the order is DESC
  21 + project.common_notes.order("created_at DESC, id DESC").limit(50)
21 when "wiki" 22 when "wiki"
22 - then project.wikis.reverse.map {|w| w.notes.fresh }.flatten[0..20] 23 + project.wikis.reverse.map {|w| w.notes.fresh }.flatten[0..20]
23 end 24 end
24 25
25 - @notes = if last_id  
26 - @notes.where("id > ?", last_id)  
27 - elsif first_id  
28 - @notes.where("id < ?", first_id)  
29 - else 26 + @notes = if after_id
  27 + @notes.where("id > ?", after_id)
  28 + elsif before_id
  29 + @notes.where("id < ?", before_id)
  30 + else
30 @notes 31 @notes
31 end 32 end
32 end 33 end
app/helpers/notes_helper.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +module NotesHelper
  2 + def loading_more_notes?
  3 + params[:loading_more].present?
  4 + end
  5 +
  6 + def loading_new_notes?
  7 + params[:loading_new].present?
  8 + end
  9 +end
app/models/note.rb
@@ -36,7 +36,7 @@ class Note &lt; ActiveRecord::Base @@ -36,7 +36,7 @@ class Note &lt; ActiveRecord::Base
36 scope :today, where("created_at >= :date", date: Date.today) 36 scope :today, where("created_at >= :date", date: Date.today)
37 scope :last_week, where("created_at >= :date", date: (Date.today - 7.days)) 37 scope :last_week, where("created_at >= :date", date: (Date.today - 7.days))
38 scope :since, lambda { |day| where("created_at >= :date", date: (day)) } 38 scope :since, lambda { |day| where("created_at >= :date", date: (day)) }
39 - scope :fresh, order("created_at DESC") 39 + scope :fresh, order("created_at ASC, id ASC")
40 scope :inc_author_project, includes(:project, :author) 40 scope :inc_author_project, includes(:project, :author)
41 scope :inc_author, includes(:author) 41 scope :inc_author, includes(:author)
42 42
app/views/commits/_text_file.html.haml
@@ -13,14 +13,11 @@ @@ -13,14 +13,11 @@
13 %td.old_line 13 %td.old_line
14 = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code 14 = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
15 - if @comments_allowed 15 - if @comments_allowed
16 - = link_to "", "#", class: "line_note_link", "line_code" => line_code, title: "Add note for this line" 16 + = render "notes/per_line_note_link", line_code: line_code
17 %td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code 17 %td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code
18 %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw "#{line} &nbsp;" 18 %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw "#{line} &nbsp;"
19 19
20 - if @comments_allowed 20 - if @comments_allowed
21 - - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at).reverse 21 + - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at)
22 - unless comments.empty? 22 - unless comments.empty?
23 - - comments.each_with_index do |note, i|  
24 - = render "notes/reply_button", line_code: line_code if i.zero?  
25 - = render "notes/per_line_show", note: note  
26 - - @line_notes.reject!{ |n| n == note } 23 + = render "notes/per_line_notes_with_reply", notes: comments
app/views/commits/show.html.haml
1 = render "commits/commit_box" 1 = render "commits/commit_box"
2 = render "commits/diffs", diffs: @commit.diffs 2 = render "commits/diffs", diffs: @commit.diffs
3 -= render "notes/notes", tid: @commit.id, tt: "commit" 3 += render "notes/notes_with_form", tid: @commit.id, tt: "commit"
4 = render "notes/per_line_form" 4 = render "notes/per_line_form"
5 5
6 6
app/views/issues/show.html.haml
@@ -61,4 +61,4 @@ @@ -61,4 +61,4 @@
61 = markdown @issue.description 61 = markdown @issue.description
62 62
63 63
64 -.issue_notes#notes= render "notes/notes", tid: @issue.id, tt: "issue" 64 +.issue_notes#notes= render "notes/notes_with_form", tid: @issue.id, tt: "issue"
app/views/merge_requests/_show.html.haml
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 Diff 16 Diff
17 17
18 .merge_request_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" } 18 .merge_request_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" }
19 - = render("notes/notes", tid: @merge_request.id, tt: "merge_request") 19 + = render("notes/notes_with_form", tid: @merge_request.id, tt: "merge_request")
20 .merge-request-diffs 20 .merge-request-diffs
21 = render "merge_requests/show/diffs" if @diffs 21 = render "merge_requests/show/diffs" if @diffs
22 .status 22 .status
app/views/merge_requests/show.js.haml
1 :plain 1 :plain
2 - $(".merge-request-notes").html("#{escape_javascript(render("notes/notes", tid: @merge_request.id, tt: "merge_request"))}"); 2 + $(".merge-request-notes").html("#{escape_javascript(render notes/notes_with_form", tid: @merge_request.id, tt: "merge_request")}");
app/views/notes/_common_form.html.haml 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +.note-form-holder
  2 + = form_for [@project, @note], remote: "true", multipart: true do |f|
  3 + %h3.page_title Leave a comment
  4 + -if @note.errors.any?
  5 + .alert-message.block-message.error
  6 + - @note.errors.full_messages.each do |msg|
  7 + %div= msg
  8 +
  9 + = f.hidden_field :noteable_id
  10 + = f.hidden_field :noteable_type
  11 + = f.text_area :note, size: 255, class: 'note-text'
  12 + #preview-note.preview_note.hide
  13 + .hint
  14 + .right Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
  15 + .clearfix
  16 +
  17 + .row.note_advanced_opts.hide
  18 + .span3
  19 + = f.submit 'Add Comment', class: "btn success submit_note grouped", id: "submit_note"
  20 + = link_to 'Preview', preview_project_notes_path(@project), class: 'btn grouped', id: 'preview-link'
  21 + .span4.notify_opts
  22 + %h6.left Notify via email:
  23 + = label_tag :notify do
  24 + = check_box_tag :notify, 1, @note.noteable_type != "Commit"
  25 + %span Project team
  26 +
  27 + - if @note.notify_only_author?(current_user)
  28 + = label_tag :notify_author do
  29 + = check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"
  30 + %span Commit author
  31 + .span5.attachments
  32 + %h6.left Attachment:
  33 + %span.file_name File name...
  34 +
  35 + .input.input_file
  36 + %a.file_upload.btn.small Upload File
  37 + = f.file_field :attachment, class: "input-file"
  38 + %span.hint Any file less than 10 MB
  39 +
app/views/notes/_create_common.js.haml
@@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
1 -- if note.valid?  
2 - :plain  
3 - $(".note-form-holder .error").remove();  
4 - $('.note-form-holder textarea').val("");  
5 - $('.note-form-holder #preview-link').text('Preview');  
6 - $('.note-form-holder #preview-note').hide();  
7 - $('.note-form-holder').show();  
8 - NoteList.prepend(#{note.id}, "#{escape_javascript(render partial: "notes/show", locals: {note: note})}");  
9 -- else  
10 - :plain  
11 - $(".note-form-holder").replaceWith("#{escape_javascript(render('form'))}");  
12 -  
app/views/notes/_create_common_note.js.haml 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +- if note.valid?
  2 + :plain
  3 + $(".note-form-holder .error").remove();
  4 + $('.note-form-holder textarea').val("");
  5 + $('.note-form-holder #preview-link').text('Preview');
  6 + $('.note-form-holder #preview-note').hide();
  7 + $('.note-form-holder').show();
  8 + NoteList.appendNewNote(#{note.id}, "#{escape_javascript(render "notes/note", note: note)}");
  9 +
  10 +- else
  11 + :plain
  12 + $(".note-form-holder").replaceWith("#{escape_javascript(render 'form')}");
  13 +
app/views/notes/_create_line.js.haml
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 -- if note.valid?  
2 - :plain  
3 - $(".per_line_form").hide();  
4 - $('.line-note-form-holder textarea').val("");  
5 - $("a.line_note_reply_link[line_code='#{note.line_code}']").closest("tr").remove();  
6 - var trEl = $(".#{note.line_code}").parent();  
7 - trEl.after("#{escape_javascript(render partial: "notes/per_line_show", locals: {note: note})}");  
8 - trEl.after("#{escape_javascript(render partial: "notes/reply_button", locals: {line_code: note.line_code})}");  
app/views/notes/_create_per_line_note.js.haml 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +- if note.valid?
  2 + :plain
  3 + // hide and reset the form
  4 + $(".per_line_form").hide();
  5 + $('.line-note-form-holder textarea').val("");
  6 +
  7 + // find the reply button for this line
  8 + // (might not be there if this is the first note)
  9 + var trRpl = $("a.line_note_reply_link[data-line-code='#{note.line_code}']").closest("tr");
  10 + if (trRpl.size() == 0) {
  11 + // find the commented line ...
  12 + var trEl = $(".#{note.line_code}").parent();
  13 + // ... and insert the note and the reply button after it
  14 + trEl.after("#{escape_javascript(render "notes/per_line_reply_button", line_code: note.line_code)}");
  15 + trEl.after("#{escape_javascript(render "notes/per_line_note", note: note)}");
  16 + } else {
  17 + // instert new note before reply button
  18 + trRpl.before("#{escape_javascript(render "notes/per_line_note", note: note)}");
  19 + }
app/views/notes/_form.html.haml
@@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
1 -.note-form-holder  
2 - = form_for [@project, @note], remote: "true", multipart: true do |f|  
3 - %h3.page_title Leave a comment  
4 - -if @note.errors.any?  
5 - .alert-message.block-message.error  
6 - - @note.errors.full_messages.each do |msg|  
7 - %div= msg  
8 -  
9 - = f.hidden_field :noteable_id  
10 - = f.hidden_field :noteable_type  
11 - = f.text_area :note, size: 255, class: 'note-text'  
12 - #preview-note.preview_note.hide  
13 - .hint  
14 - .right Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.  
15 - .clearfix  
16 -  
17 - .row.note_advanced_opts.hide  
18 - .span3  
19 - = f.submit 'Add Comment', class: "btn success submit_note grouped", id: "submit_note"  
20 - = link_to 'Preview', preview_project_notes_path(@project), class: 'btn grouped', id: 'preview-link'  
21 - .span4.notify_opts  
22 - %h6.left Notify via email:  
23 - = label_tag :notify do  
24 - = check_box_tag :notify, 1, @note.noteable_type != "Commit"  
25 - %span Project team  
26 -  
27 - - if @note.notify_only_author?(current_user)  
28 - = label_tag :notify_author do  
29 - = check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"  
30 - %span Commit author  
31 - .span5.attachments  
32 - %h6.left Attachment:  
33 - %span.file_name File name...  
34 -  
35 - .input.input_file  
36 - %a.file_upload.btn.small Upload File  
37 - = f.file_field :attachment, class: "input-file"  
38 - %span.hint Any file less than 10 MB  
39 -  
app/views/notes/_load.js.haml
@@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
1 -- unless @notes.blank?  
2 - - if params[:last_id]  
3 - :plain  
4 - NoteList.replace("#{escape_javascript(render(partial: 'notes/notes_list'))}");  
5 -  
6 - - elsif params[:first_id]  
7 - :plain  
8 - NoteList.append(#{@notes.last.id}, "#{escape_javascript(render(partial: 'notes/notes_list'))}");  
9 -  
10 - - else  
11 - :plain  
12 - NoteList.setContent(#{@notes.last.id}, #{@notes.first.id}, "#{escape_javascript(render(partial: 'notes/notes_list'))}");  
13 -  
14 -- else  
15 - - if params[:first_id]  
16 - :plain  
17 - NoteList.append(#{params[:first_id]}, "");  
app/views/notes/_note.html.haml 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +%li{id: dom_id(note), class: "note"}
  2 + = image_tag gravatar_icon(note.author.email), class: "avatar s32"
  3 + %div.note-author
  4 + %strong= note.author_name
  5 + = link_to "##{dom_id(note)}", name: dom_id(note) do
  6 + %cite.cgray
  7 + = time_ago_in_words(note.updated_at)
  8 + ago
  9 + - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project)
  10 + = link_to [@project, note], confirm: 'Are you sure?', method: :delete, remote: true, class: "cred delete-note btn very_small" do
  11 + %i.icon-trash
  12 + Remove
  13 +
  14 + %div.note-title
  15 + = preserve do
  16 + = markdown(note.note)
  17 + - if note.attachment.url
  18 + .right
  19 + %div.file
  20 + = link_to note.attachment_identifier, note.attachment.url, target: "_blank"
  21 + .clear
app/views/notes/_notes.html.haml
1 -- if can? current_user, :write_note, @project  
2 - = render "notes/form"  
3 -.clear  
4 -%hr  
5 -%ul#new_notes_list  
6 -%ul#notes-list  
7 -.status 1 +- @notes.each do |note|
  2 + - next unless note.author
  3 + = render "note", note: note
8 4
9 -  
10 -:javascript  
11 - $(function(){  
12 - NoteList.init("#{tid}", "#{tt}", "#{project_notes_path(@project)}");  
13 - });  
app/views/notes/_notes_list.html.haml
@@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
1 -- @notes.each do |note|  
2 - - next unless note.author  
3 - = render partial: "notes/show", locals: {note: note}  
4 -  
app/views/notes/_notes_with_form.html.haml 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +%ul#notes-list
  2 +%ul#new-notes-list
  3 +.notes-status
  4 +
  5 +- if can? current_user, :write_note, @project
  6 + = render "notes/common_form"
  7 +
  8 +:javascript
  9 + $(function(){
  10 + NoteList.init("#{tid}", "#{tt}", "#{project_notes_path(@project)}");
  11 + });
app/views/notes/_per_line_note.html.haml 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +%tr.line_notes_row
  2 + %td{colspan: 3}
  3 + %ul
  4 + = render "notes/note", note: note
  5 +
app/views/notes/_per_line_note_link.html.haml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 += link_to "", "#", class: "line_note_link", data: { line_code: line_code }, title: "Add note for this line"
app/views/notes/_per_line_notes_with_reply.html.haml 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +- notes.each do |note|
  2 + = render "notes/per_line_note", note: note
  3 += render "notes/per_line_reply_button", line_code: notes.first.line_code
app/views/notes/_per_line_reply_button.html.haml 0 → 100644
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 +%tr.line_notes_row.reply
  2 + %td{colspan: 3}
  3 + %i.icon-comment
  4 + = link_to "Reply", "#", class: "line_note_reply_link", data: { line_code: line_code }, title: "Add note for this line"
app/views/notes/_per_line_show.html.haml
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -%tr.line_notes_row  
2 - %td{colspan: 3}  
3 - %ul  
4 - = render partial: "notes/show", locals: {note: note}  
5 -  
app/views/notes/_reply_button.html.haml
@@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
1 -%tr.line_notes_row.reply  
2 - %td{colspan: 3}  
3 - %i.icon-comment  
4 - = link_to "Reply", "#", class: "line_note_reply_link", "line_code" => line_code, title: "Add note for this line"  
app/views/notes/_reversed_notes_with_form.html.haml 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +- if can? current_user, :write_note, @project
  2 + = render "notes/common_form"
  3 +
  4 +%ul.reversed#new-notes-list
  5 +%ul.reversed#notes-list
  6 +.notes-status
  7 +
  8 +:javascript
  9 + $(function(){
  10 + NoteList.init("#{tid}", "#{tt}", "#{project_notes_path(@project)}");
  11 + });
0 \ No newline at end of file 12 \ No newline at end of file
app/views/notes/_show.html.haml
@@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
1 -%li{id: dom_id(note), class: "note"}  
2 - = image_tag gravatar_icon(note.author.email), class: "avatar s32"  
3 - %div.note-author  
4 - %strong= note.author_name  
5 - = link_to "##{dom_id(note)}", name: dom_id(note) do  
6 - %cite.cgray  
7 - = time_ago_in_words(note.updated_at)  
8 - ago  
9 - - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project)  
10 - = link_to [@project, note], confirm: 'Are you sure?', method: :delete, remote: true, class: "cred delete-note btn very_small" do  
11 - %i.icon-trash  
12 - Remove  
13 -  
14 - %div.note-title  
15 - = preserve do  
16 - = markdown(note.note)  
17 - - if note.attachment.url  
18 - .right  
19 - %div.file  
20 - = link_to note.attachment_identifier, note.attachment.url, target: "_blank"  
21 - .clear  
app/views/notes/create.js.haml
1 - if @note.line_code 1 - if @note.line_code
2 - = render "create_line", note: @note 2 + = render "create_per_line_note", note: @note
3 - else 3 - else
4 - = render "create_common", note: @note 4 + = render "create_common_note", note: @note
5 5
6 -# Enable submit button 6 -# Enable submit button
7 :plain 7 :plain
app/views/notes/index.js.haml
1 -= render "notes/load" 1 +- unless @notes.blank?
  2 + - if loading_more_notes?
  3 + :plain
  4 + NoteList.appendMoreNotes(#{@notes.last.id}, "#{escape_javascript(render 'notes/notes')}");
  5 +
  6 + - elsif loading_new_notes?
  7 + :plain
  8 + NoteList.replaceNewNotes("#{escape_javascript(render 'notes/notes')}");
  9 +
  10 + - else
  11 + :plain
  12 + NoteList.setContent(#{@notes.first.id}, #{@notes.last.id}, "#{escape_javascript(render 'notes/notes')}");
  13 +
  14 +- else
  15 + - if loading_more_notes?
  16 + :plain
  17 + NoteList.finishedLoadingMore();
app/views/projects/wall.html.haml
1 %div.wall_page 1 %div.wall_page
2 - = render "notes/notes", tid: nil, tt: "wall" 2 + = render "notes/reversed_notes_with_form", tid: nil, tt: "wall"
app/views/snippets/show.html.haml
@@ -17,4 +17,4 @@ @@ -17,4 +17,4 @@
17 %div{class: current_user.dark_scheme ? "black" : ""} 17 %div{class: current_user.dark_scheme ? "black" : ""}
18 = raw @snippet.colorize(options: { linenos: 'True'}) 18 = raw @snippet.colorize(options: { linenos: 'True'})
19 19
20 -= render "notes/notes", tid: @snippet.id, tt: "snippet" 20 += render "notes/notes_with_form", tid: @snippet.id, tt: "snippet"
app/views/wikis/show.html.haml
@@ -21,4 +21,4 @@ @@ -21,4 +21,4 @@
21 Delete this page 21 Delete this page
22 22
23 %hr 23 %hr
24 -.wiki_notes#notes= render "notes/notes", tid: @wiki.id, tt: "wiki" 24 +.wiki_notes#notes= render "notes/notes_with_form", tid: @wiki.id, tt: "wiki"