Commit 21c141afb1c53a9180a99d2cca29ffa613eb7e3a

Authored by Dmitriy Zaporozhets
2 parents b1a36b55 292a41cb

Merge branch 'notes_refactoring'

app/assets/javascripts/note.js
1 1 var NoteList = {
2 2  
  3 +notes_path: null,
  4 +target_params: null,
  5 +target_id: 0,
  6 +target_type: null,
3 7 first_id: 0,
4 8 last_id: 0,
5   -resource_name: null,
6 9 disable:false,
7 10  
8 11 init:
9   - function(resource_name, first_id, last_id) {
10   - this.resource_name = resource_name;
11   - this.first_id = first_id;
12   - this.last_id = last_id;
  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 + this.refresh();
13 18 this.initRefresh();
14 19 this.initLoadMore();
15 20 },
... ... @@ -19,8 +24,8 @@ getOld:
19 24 $('.loading').show();
20 25 $.ajax({
21 26 type: "GET",
22   - url: location.href,
23   - data: "first_id=" + this.first_id,
  27 + url: this.notes_path,
  28 + data: "first_id=" + this.first_id + this.target_params,
24 29 complete: function(){ $('.loading').hide()},
25 30 dataType: "script"});
26 31 },
... ... @@ -56,8 +61,8 @@ getNew:
56 61 // refersh notes list
57 62 $.ajax({
58 63 type: "GET",
59   - url: location.href,
60   - data: "last_id=" + this.last_id,
  64 + url: this.notes_path,
  65 + data: "last_id=" + this.last_id + this.target_params,
61 66 dataType: "script"});
62 67 },
63 68  
... ... @@ -66,8 +71,8 @@ refresh:
66 71 // refersh notes list
67 72 $.ajax({
68 73 type: "GET",
69   - url: location.href,
70   - data: "first_id=" + this.first_id + "&last_id=" + this.last_id,
  74 + url: this.notes_path,
  75 + data: "first_id=" + this.first_id + "&last_id=" + this.last_id + this.target_params,
71 76 dataType: "script"});
72 77 },
73 78  
... ...
app/assets/stylesheets/common.scss
... ... @@ -374,3 +374,10 @@ table a code {
374 374 .btn.padded {
375 375 margin-right:3px;
376 376 }
  377 +
  378 +.loading {
  379 + margin:20px auto;
  380 + background: url(ajax-loader-facebook.gif) no-repeat center center;
  381 + width:40px;
  382 + height:40px;
  383 +}
... ...
app/assets/stylesheets/notes.css.scss
... ... @@ -30,7 +30,10 @@
30 30 }
31 31 }
32 32  
33   -.note .delete-note { display:none; }
  33 +.note .delete-note {
  34 + display:none;
  35 + float:right;
  36 +}
34 37 .note:hover .delete-note { display:block; }
35 38 .note {padding: 10px 0; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
36 39 .note img{float: left; margin-right: 10px;}
... ... @@ -53,6 +56,20 @@ p.notify_controls span{
53 56  
54 57 tr.line_notes_row {
55 58 border-bottom:1px solid #DDD;
  59 + &.reply {
  60 + background:#eee;
  61 +
  62 + td {
  63 + padding:7px 10px;
  64 + }
  65 + a.line_note_reply_link {
  66 + @include round-borders-all(4px);
  67 + border-color:#aaa;
  68 + background: #bbb;
  69 + padding: 3px 20px;
  70 + color: white;
  71 + }
  72 + }
56 73 ul {
57 74 margin:0;
58 75 li {
... ...
app/controllers/application_controller.rb
... ... @@ -95,18 +95,6 @@ class ApplicationController < ActionController::Base
95 95 redirect_to @project unless @project.repo_exists? && @project.has_commits?
96 96 end
97 97  
98   - def respond_with_notes
99   - if params[:last_id] && params[:first_id]
100   - @notes = @notes.where("id >= ?", params[:first_id])
101   - elsif params[:last_id]
102   - @notes = @notes.where("id > ?", params[:last_id])
103   - elsif params[:first_id]
104   - @notes = @notes.where("id < ?", params[:first_id])
105   - else
106   - nil
107   - end
108   - end
109   -
110 98 def no_cache_headers
111 99 response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
112 100 response.headers["Pragma"] = "no-cache"
... ...
app/controllers/commits_controller.rb
... ... @@ -29,16 +29,9 @@ class CommitsController &lt; ApplicationController
29 29  
30 30 git_not_found! and return unless @commit
31 31  
32   - @notes = project.commit_notes(@commit).fresh.limit(20)
33 32 @note = @project.build_commit_note(@commit)
34   -
35 33 @comments_allowed = true
36 34 @line_notes = project.commit_line_notes(@commit)
37   -
38   - respond_to do |format|
39   - format.html
40   - format.js { respond_with_notes }
41   - end
42 35 end
43 36  
44 37 def compare
... ...
app/controllers/issues_controller.rb
... ... @@ -49,7 +49,6 @@ class IssuesController &lt; ApplicationController
49 49 end
50 50  
51 51 def show
52   - @notes = @issue.notes.inc_author.order("created_at DESC").limit(20)
53 52 @note = @project.notes.new(:noteable => @issue)
54 53  
55 54 @commits = if @issue.branch_name && @project.repo.heads.map(&:name).include?(@issue.branch_name)
... ... @@ -61,7 +60,7 @@ class IssuesController &lt; ApplicationController
61 60  
62 61 respond_to do |format|
63 62 format.html
64   - format.js { respond_with_notes }
  63 + format.js
65 64 end
66 65 end
67 66  
... ...
app/controllers/merge_requests_controller.rb
... ... @@ -39,7 +39,6 @@ class MergeRequestsController &lt; ApplicationController
39 39 git_not_found! and return
40 40 end
41 41  
42   - @notes = @merge_request.notes.inc_author.order("created_at DESC").limit(20)
43 42 @note = @project.notes.new(:noteable => @merge_request)
44 43  
45 44 @commits = @project.repo.
... ... @@ -52,14 +51,16 @@ class MergeRequestsController &lt; ApplicationController
52 51  
53 52 respond_to do |format|
54 53 format.html
55   - format.js { respond_with_notes }
  54 + format.js
56 55 end
57 56 end
58 57  
59 58 def diffs
60 59 @diffs = @merge_request.diffs
61 60 @commit = @merge_request.last_commit
62   - @line_notes = []
  61 +
  62 + @comments_allowed = true
  63 + @line_notes = @merge_request.notes.where("line_code is not null")
63 64 end
64 65  
65 66 def new
... ...
app/controllers/notes_controller.rb
... ... @@ -9,6 +9,25 @@ class NotesController &lt; ApplicationController
9 9  
10 10 respond_to :js
11 11  
  12 + def index
  13 + @notes = case params[:target_type]
  14 + when "commit"
  15 + then project.commit_notes(project.commit((params[:target_id]))).fresh.limit(20)
  16 + when "snippet"
  17 + then project.snippets.find(params[:target_id]).notes
  18 + when "wall"
  19 + then project.common_notes.order("created_at DESC").fresh.limit(20)
  20 + when "issue"
  21 + then project.issues.find(params[:target_id]).notes.inc_author.order("created_at DESC").limit(20)
  22 + when "merge_request"
  23 + then project.merge_requests.find(params[:target_id]).notes.inc_author.order("created_at DESC").limit(20)
  24 + end
  25 +
  26 + respond_to do |format|
  27 + format.js { respond_with_notes }
  28 + end
  29 + end
  30 +
12 31 def create
13 32 @note = @project.notes.new(params[:note])
14 33 @note.author = current_user
... ... @@ -34,4 +53,17 @@ class NotesController &lt; ApplicationController
34 53 end
35 54 end
36 55  
  56 + protected
  57 +
  58 + def respond_with_notes
  59 + if params[:last_id] && params[:first_id]
  60 + @notes = @notes.where("id >= ?", params[:first_id])
  61 + elsif params[:last_id]
  62 + @notes = @notes.where("id > ?", params[:last_id])
  63 + elsif params[:first_id]
  64 + @notes = @notes.where("id < ?", params[:first_id])
  65 + else
  66 + nil
  67 + end
  68 + end
37 69 end
... ...
app/controllers/projects_controller.rb
... ... @@ -82,14 +82,10 @@ class ProjectsController &lt; ApplicationController
82 82  
83 83 def wall
84 84 return render_404 unless @project.wall_enabled
85   -
86 85 @note = Note.new
87   - @notes = @project.common_notes.order("created_at DESC")
88   - @notes = @notes.fresh.limit(20)
89 86  
90 87 respond_to do |format|
91 88 format.html
92   - format.js { respond_with_notes }
93 89 end
94 90 end
95 91  
... ...
app/controllers/snippets_controller.rb
... ... @@ -55,7 +55,6 @@ class SnippetsController &lt; ApplicationController
55 55 end
56 56  
57 57 def show
58   - @notes = @snippet.notes
59 58 @note = @project.notes.new(:noteable => @snippet)
60 59 render_full_content
61 60 end
... ...
app/views/commits/_text_file.html.haml
... ... @@ -16,6 +16,7 @@
16 16 - if @comments_allowed
17 17 - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at).reverse
18 18 - unless comments.empty?
19   - - comments.each do |note|
  19 + - comments.each_with_index do |note, i|
  20 + = render "notes/reply_button", :line_code => line_code if i.zero?
20 21 = render "notes/per_line_show", :note => note
21 22 - @line_notes.reject!{ |n| n == note }
... ...
app/views/commits/show.html.haml
... ... @@ -21,13 +21,13 @@
21 21 %p.cgray
22 22 Showing #{pluralize(@commit.diffs.count, "changed file")}
23 23 = render "commits/diffs", :diffs => @commit.diffs
24   -= render "notes/notes"
  24 += render "notes/notes", :tid => @commit.id, :tt => "commit"
25 25 = render "notes/per_line_form"
26 26  
27 27  
28 28 :javascript
29 29 $(document).ready(function(){
30   - $(".line_note_link").live("click", function(e) {
  30 + $(".line_note_link, .line_note_reply_link").live("click", function(e) {
31 31 var form = $(".per_line_form");
32 32 $(this).parent().parent().after(form);
33 33 form.find("#note_line_code").val($(this).attr("line_code"));
... ...
app/views/commits/show.js.haml
... ... @@ -1 +0,0 @@
1   -= render "notes/load"
app/views/issues/show.html.haml
... ... @@ -41,5 +41,4 @@
41 41 %div= simple_format @issue.title
42 42  
43 43  
44   -.issue_notes= render "notes/notes"
45   -
  44 +.issue_notes= render "notes/notes", :tid => @issue.id, :tt => "issue"
... ...
app/views/issues/show.js.haml
... ... @@ -1 +0,0 @@
1   -= render "notes/load"
app/views/merge_requests/show.html.haml
... ... @@ -63,10 +63,7 @@
63 63 %img{:src => "/assets/ajax-loader-facebook.gif", :class => "dashboard-loader"}
64 64  
65 65 .merge-request-notes
66   - .merge_request_notes= render "notes/notes"
67   - .loading{ :style => "display:none;"}
68   - %center= image_tag "ajax-loader.gif"
69   - .clear
  66 + .merge_request_notes= render "notes/notes", :tid => @merge_request.id, :tt => "merge_request"
70 67  
71 68 .merge-request-diffs
72 69  
... ... @@ -75,3 +72,15 @@
75 72 $(function(){
76 73 MergeRequest.init();
77 74 })
  75 +
  76 += render "notes/per_line_form"
  77 +:javascript
  78 + $(document).ready(function(){
  79 + $(".line_note_link, .line_note_reply_link").live("click", function(e) {
  80 + var form = $(".per_line_form");
  81 + $(this).parent().parent().after(form);
  82 + form.find("#note_line_code").val($(this).attr("line_code"));
  83 + form.show();
  84 + return false;
  85 + });
  86 + });
... ...
app/views/notes/_create_common.js.haml 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +- if note.valid?
  2 + :plain
  3 + $("#new_note .errors").remove();
  4 + $('#new_note textarea').val("");
  5 + NoteList.prepend(#{note.id}, "#{escape_javascript(render :partial => "notes/show", :locals => {:note => note})}");
  6 +- else
  7 + :plain
  8 + $("#new_note").replaceWith("#{escape_javascript(render('form'))}");
  9 +
... ...
app/views/notes/_create_line.js.haml 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +- if note.valid?
  2 + :plain
  3 + $(".per_line_form").hide();
  4 + $('#new_note 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/_notes.html.haml
... ... @@ -2,7 +2,9 @@
2 2 = render "notes/form"
3 3 .clear
4 4 %hr
5   -%ul#notes-list= render "notes/notes_list"
  5 +%ul#notes-list
  6 +.loading
  7 +
6 8  
7 9 :javascript
8 10 $('.delete-note').live('ajax:success', function() {
... ... @@ -22,5 +24,5 @@
22 24 $('.attach_holder').show();
23 25 });
24 26  
25   - NoteList.init("wall", #{@notes.last.try(:id) || 0}, #{@notes.first.try(:id) || 0});
  27 + NoteList.init("#{tid}", "#{tt}", "#{project_notes_path(@project)}");
26 28 });
... ...
app/views/notes/_reply_button.html.haml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +%tr.line_notes_row.reply
  2 + %td{:colspan => 3}
  3 + = link_to "Reply", "#", :class => "line_note_reply_link", "line_code" => line_code, :title => "Add note for this line"
... ...
app/views/notes/_show.html.haml
... ... @@ -6,7 +6,7 @@
6 6 = time_ago_in_words(note.updated_at)
7 7 ago
8 8 - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project)
9   - = link_to "Remove", [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-note right"
  9 + %strong= link_to "Remove", [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-note btn small"
10 10  
11 11 %div.note-title
12 12 = markdown(note.note)
... ...
app/views/notes/create.js.haml
1   -- if @note.valid?
2   - - if @note.line_code
3   - :plain
4   - $(".per_line_form").hide();
5   - $('#new_note textarea').val("");
6   - $(".#{@note.line_code}").parent().after("#{escape_javascript(render :partial => "notes/per_line_show", :locals => {:note => @note})}");
7   - - else
8   - :plain
9   - $("#new_note .errors").remove();
10   - $('#new_note textarea').val("");
11   - NoteList.prepend(#{@note.id}, "#{escape_javascript(render :partial => "notes/show", :locals => {:note => @note})}");
12   -- else
13   - - unless @note.line_code
14   - :plain
15   - $("#new_note").replaceWith("#{escape_javascript(render('form'))}");
  1 +- if @note.line_code
  2 + = render "create_line", :note => @note
  3 +- else
  4 + = render "create_common", :note => @note
16 5  
  6 +-# Enable submit button
17 7 :plain
18 8 $("#submit_note").removeAttr("disabled");
... ...
app/views/notes/index.js.haml 0 → 100644
... ... @@ -0,0 +1 @@
  1 += render "notes/load"
... ...
app/views/projects/wall.html.haml
1 1 %div.wall_page
2   - = render "notes/notes"
3   -
4   -.loading{ :style => "display:none;"}
5   - %center= image_tag "ajax-loader.gif"
6   -
  2 + = render "notes/notes", :tid => nil, :tt => "wall"
... ...
app/views/projects/wall.js.haml
... ... @@ -1 +0,0 @@
1   -= render "notes/load"
app/views/snippets/show.html.haml
... ... @@ -14,8 +14,5 @@
14 14 .data.no-padding
15 15 :erb
16 16 <%= raw @snippet.colorize %>
17   -.clear
18   -%br
19   -.snippet_notes= render "notes/notes"
20 17  
21   -.clear
  18 += render "notes/notes", :tid => @snippet.id, :tt => "snippet"
... ...
config/routes.rb
... ... @@ -121,7 +121,7 @@ Gitlab::Application.routes.draw do
121 121 get :search
122 122 end
123 123 end
124   - resources :notes, :only => [:create, :destroy]
  124 + resources :notes, :only => [:index, :create, :destroy]
125 125 end
126 126 root :to => "projects#index"
127 127 end
... ...
spec/requests/projects_wall_spec.rb
... ... @@ -8,7 +8,7 @@ describe &quot;Projects&quot;, &quot;Wall&quot; do
8 8 project.add_access(@user, :read, :write)
9 9 end
10 10  
11   - describe "View notes on wall" do
  11 + describe "View notes on wall", :js => true do
12 12 before do
13 13 Factory :note, :project => project, :note => "Project specs", :author => @user
14 14 visit wall_project_path(project)
... ...