Commit 21c141afb1c53a9180a99d2cca29ffa613eb7e3a
Exists in
master
and in
4 other branches
Merge branch 'notes_refactoring'
Showing
28 changed files
with
131 additions
and
82 deletions
Show diff stats
app/assets/javascripts/note.js
1 | var NoteList = { | 1 | var NoteList = { |
2 | 2 | ||
3 | +notes_path: null, | ||
4 | +target_params: null, | ||
5 | +target_id: 0, | ||
6 | +target_type: null, | ||
3 | first_id: 0, | 7 | first_id: 0, |
4 | last_id: 0, | 8 | last_id: 0, |
5 | -resource_name: null, | ||
6 | disable:false, | 9 | disable:false, |
7 | 10 | ||
8 | init: | 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 | this.initRefresh(); | 18 | this.initRefresh(); |
14 | this.initLoadMore(); | 19 | this.initLoadMore(); |
15 | }, | 20 | }, |
@@ -19,8 +24,8 @@ getOld: | @@ -19,8 +24,8 @@ getOld: | ||
19 | $('.loading').show(); | 24 | $('.loading').show(); |
20 | $.ajax({ | 25 | $.ajax({ |
21 | type: "GET", | 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 | complete: function(){ $('.loading').hide()}, | 29 | complete: function(){ $('.loading').hide()}, |
25 | dataType: "script"}); | 30 | dataType: "script"}); |
26 | }, | 31 | }, |
@@ -56,8 +61,8 @@ getNew: | @@ -56,8 +61,8 @@ getNew: | ||
56 | // refersh notes list | 61 | // refersh notes list |
57 | $.ajax({ | 62 | $.ajax({ |
58 | type: "GET", | 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 | dataType: "script"}); | 66 | dataType: "script"}); |
62 | }, | 67 | }, |
63 | 68 | ||
@@ -66,8 +71,8 @@ refresh: | @@ -66,8 +71,8 @@ refresh: | ||
66 | // refersh notes list | 71 | // refersh notes list |
67 | $.ajax({ | 72 | $.ajax({ |
68 | type: "GET", | 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 | dataType: "script"}); | 76 | dataType: "script"}); |
72 | }, | 77 | }, |
73 | 78 |
app/assets/stylesheets/common.scss
@@ -374,3 +374,10 @@ table a code { | @@ -374,3 +374,10 @@ table a code { | ||
374 | .btn.padded { | 374 | .btn.padded { |
375 | margin-right:3px; | 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,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 | .note:hover .delete-note { display:block; } | 37 | .note:hover .delete-note { display:block; } |
35 | .note {padding: 10px 0; border-bottom: 1px solid #eee; overflow: hidden; display: block;} | 38 | .note {padding: 10px 0; border-bottom: 1px solid #eee; overflow: hidden; display: block;} |
36 | .note img{float: left; margin-right: 10px;} | 39 | .note img{float: left; margin-right: 10px;} |
@@ -53,6 +56,20 @@ p.notify_controls span{ | @@ -53,6 +56,20 @@ p.notify_controls span{ | ||
53 | 56 | ||
54 | tr.line_notes_row { | 57 | tr.line_notes_row { |
55 | border-bottom:1px solid #DDD; | 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 | ul { | 73 | ul { |
57 | margin:0; | 74 | margin:0; |
58 | li { | 75 | li { |
app/controllers/application_controller.rb
@@ -95,18 +95,6 @@ class ApplicationController < ActionController::Base | @@ -95,18 +95,6 @@ class ApplicationController < ActionController::Base | ||
95 | redirect_to @project unless @project.repo_exists? && @project.has_commits? | 95 | redirect_to @project unless @project.repo_exists? && @project.has_commits? |
96 | end | 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 | def no_cache_headers | 98 | def no_cache_headers |
111 | response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate" | 99 | response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate" |
112 | response.headers["Pragma"] = "no-cache" | 100 | response.headers["Pragma"] = "no-cache" |
app/controllers/commits_controller.rb
@@ -29,16 +29,9 @@ class CommitsController < ApplicationController | @@ -29,16 +29,9 @@ class CommitsController < ApplicationController | ||
29 | 29 | ||
30 | git_not_found! and return unless @commit | 30 | git_not_found! and return unless @commit |
31 | 31 | ||
32 | - @notes = project.commit_notes(@commit).fresh.limit(20) | ||
33 | @note = @project.build_commit_note(@commit) | 32 | @note = @project.build_commit_note(@commit) |
34 | - | ||
35 | @comments_allowed = true | 33 | @comments_allowed = true |
36 | @line_notes = project.commit_line_notes(@commit) | 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 | end | 35 | end |
43 | 36 | ||
44 | def compare | 37 | def compare |
app/controllers/issues_controller.rb
@@ -49,7 +49,6 @@ class IssuesController < ApplicationController | @@ -49,7 +49,6 @@ class IssuesController < ApplicationController | ||
49 | end | 49 | end |
50 | 50 | ||
51 | def show | 51 | def show |
52 | - @notes = @issue.notes.inc_author.order("created_at DESC").limit(20) | ||
53 | @note = @project.notes.new(:noteable => @issue) | 52 | @note = @project.notes.new(:noteable => @issue) |
54 | 53 | ||
55 | @commits = if @issue.branch_name && @project.repo.heads.map(&:name).include?(@issue.branch_name) | 54 | @commits = if @issue.branch_name && @project.repo.heads.map(&:name).include?(@issue.branch_name) |
@@ -61,7 +60,7 @@ class IssuesController < ApplicationController | @@ -61,7 +60,7 @@ class IssuesController < ApplicationController | ||
61 | 60 | ||
62 | respond_to do |format| | 61 | respond_to do |format| |
63 | format.html | 62 | format.html |
64 | - format.js { respond_with_notes } | 63 | + format.js |
65 | end | 64 | end |
66 | end | 65 | end |
67 | 66 |
app/controllers/merge_requests_controller.rb
@@ -39,7 +39,6 @@ class MergeRequestsController < ApplicationController | @@ -39,7 +39,6 @@ class MergeRequestsController < ApplicationController | ||
39 | git_not_found! and return | 39 | git_not_found! and return |
40 | end | 40 | end |
41 | 41 | ||
42 | - @notes = @merge_request.notes.inc_author.order("created_at DESC").limit(20) | ||
43 | @note = @project.notes.new(:noteable => @merge_request) | 42 | @note = @project.notes.new(:noteable => @merge_request) |
44 | 43 | ||
45 | @commits = @project.repo. | 44 | @commits = @project.repo. |
@@ -52,14 +51,16 @@ class MergeRequestsController < ApplicationController | @@ -52,14 +51,16 @@ class MergeRequestsController < ApplicationController | ||
52 | 51 | ||
53 | respond_to do |format| | 52 | respond_to do |format| |
54 | format.html | 53 | format.html |
55 | - format.js { respond_with_notes } | 54 | + format.js |
56 | end | 55 | end |
57 | end | 56 | end |
58 | 57 | ||
59 | def diffs | 58 | def diffs |
60 | @diffs = @merge_request.diffs | 59 | @diffs = @merge_request.diffs |
61 | @commit = @merge_request.last_commit | 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 | end | 64 | end |
64 | 65 | ||
65 | def new | 66 | def new |
app/controllers/notes_controller.rb
@@ -9,6 +9,25 @@ class NotesController < ApplicationController | @@ -9,6 +9,25 @@ class NotesController < ApplicationController | ||
9 | 9 | ||
10 | respond_to :js | 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 | def create | 31 | def create |
13 | @note = @project.notes.new(params[:note]) | 32 | @note = @project.notes.new(params[:note]) |
14 | @note.author = current_user | 33 | @note.author = current_user |
@@ -34,4 +53,17 @@ class NotesController < ApplicationController | @@ -34,4 +53,17 @@ class NotesController < ApplicationController | ||
34 | end | 53 | end |
35 | end | 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 | end | 69 | end |
app/controllers/projects_controller.rb
@@ -82,14 +82,10 @@ class ProjectsController < ApplicationController | @@ -82,14 +82,10 @@ class ProjectsController < ApplicationController | ||
82 | 82 | ||
83 | def wall | 83 | def wall |
84 | return render_404 unless @project.wall_enabled | 84 | return render_404 unless @project.wall_enabled |
85 | - | ||
86 | @note = Note.new | 85 | @note = Note.new |
87 | - @notes = @project.common_notes.order("created_at DESC") | ||
88 | - @notes = @notes.fresh.limit(20) | ||
89 | 86 | ||
90 | respond_to do |format| | 87 | respond_to do |format| |
91 | format.html | 88 | format.html |
92 | - format.js { respond_with_notes } | ||
93 | end | 89 | end |
94 | end | 90 | end |
95 | 91 |
app/controllers/snippets_controller.rb
@@ -55,7 +55,6 @@ class SnippetsController < ApplicationController | @@ -55,7 +55,6 @@ class SnippetsController < ApplicationController | ||
55 | end | 55 | end |
56 | 56 | ||
57 | def show | 57 | def show |
58 | - @notes = @snippet.notes | ||
59 | @note = @project.notes.new(:noteable => @snippet) | 58 | @note = @project.notes.new(:noteable => @snippet) |
60 | render_full_content | 59 | render_full_content |
61 | end | 60 | end |
app/views/commits/_text_file.html.haml
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | - if @comments_allowed | 16 | - if @comments_allowed |
17 | - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at).reverse | 17 | - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at).reverse |
18 | - unless comments.empty? | 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 | = render "notes/per_line_show", :note => note | 21 | = render "notes/per_line_show", :note => note |
21 | - @line_notes.reject!{ |n| n == note } | 22 | - @line_notes.reject!{ |n| n == note } |
app/views/commits/show.html.haml
@@ -21,13 +21,13 @@ | @@ -21,13 +21,13 @@ | ||
21 | %p.cgray | 21 | %p.cgray |
22 | Showing #{pluralize(@commit.diffs.count, "changed file")} | 22 | Showing #{pluralize(@commit.diffs.count, "changed file")} |
23 | = render "commits/diffs", :diffs => @commit.diffs | 23 | = render "commits/diffs", :diffs => @commit.diffs |
24 | -= render "notes/notes" | 24 | += render "notes/notes", :tid => @commit.id, :tt => "commit" |
25 | = render "notes/per_line_form" | 25 | = render "notes/per_line_form" |
26 | 26 | ||
27 | 27 | ||
28 | :javascript | 28 | :javascript |
29 | $(document).ready(function(){ | 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 | var form = $(".per_line_form"); | 31 | var form = $(".per_line_form"); |
32 | $(this).parent().parent().after(form); | 32 | $(this).parent().parent().after(form); |
33 | form.find("#note_line_code").val($(this).attr("line_code")); | 33 | form.find("#note_line_code").val($(this).attr("line_code")); |
app/views/commits/show.js.haml
@@ -1 +0,0 @@ | @@ -1 +0,0 @@ | ||
1 | -= render "notes/load" |
app/views/issues/show.html.haml
app/views/issues/show.js.haml
@@ -1 +0,0 @@ | @@ -1 +0,0 @@ | ||
1 | -= render "notes/load" |
app/views/merge_requests/show.html.haml
@@ -63,10 +63,7 @@ | @@ -63,10 +63,7 @@ | ||
63 | %img{:src => "/assets/ajax-loader-facebook.gif", :class => "dashboard-loader"} | 63 | %img{:src => "/assets/ajax-loader-facebook.gif", :class => "dashboard-loader"} |
64 | 64 | ||
65 | .merge-request-notes | 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 | .merge-request-diffs | 68 | .merge-request-diffs |
72 | 69 | ||
@@ -75,3 +72,15 @@ | @@ -75,3 +72,15 @@ | ||
75 | $(function(){ | 72 | $(function(){ |
76 | MergeRequest.init(); | 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 | + }); |
@@ -0,0 +1,9 @@ | @@ -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 | + |
@@ -0,0 +1,8 @@ | @@ -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,7 +2,9 @@ | ||
2 | = render "notes/form" | 2 | = render "notes/form" |
3 | .clear | 3 | .clear |
4 | %hr | 4 | %hr |
5 | -%ul#notes-list= render "notes/notes_list" | 5 | +%ul#notes-list |
6 | +.loading | ||
7 | + | ||
6 | 8 | ||
7 | :javascript | 9 | :javascript |
8 | $('.delete-note').live('ajax:success', function() { | 10 | $('.delete-note').live('ajax:success', function() { |
@@ -22,5 +24,5 @@ | @@ -22,5 +24,5 @@ | ||
22 | $('.attach_holder').show(); | 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/_show.html.haml
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | = time_ago_in_words(note.updated_at) | 6 | = time_ago_in_words(note.updated_at) |
7 | ago | 7 | ago |
8 | - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project) | 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 | %div.note-title | 11 | %div.note-title |
12 | = markdown(note.note) | 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 | :plain | 7 | :plain |
18 | $("#submit_note").removeAttr("disabled"); | 8 | $("#submit_note").removeAttr("disabled"); |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | += render "notes/load" |
app/views/projects/wall.html.haml
app/views/projects/wall.js.haml
@@ -1 +0,0 @@ | @@ -1 +0,0 @@ | ||
1 | -= render "notes/load" |
app/views/snippets/show.html.haml
config/routes.rb
@@ -121,7 +121,7 @@ Gitlab::Application.routes.draw do | @@ -121,7 +121,7 @@ Gitlab::Application.routes.draw do | ||
121 | get :search | 121 | get :search |
122 | end | 122 | end |
123 | end | 123 | end |
124 | - resources :notes, :only => [:create, :destroy] | 124 | + resources :notes, :only => [:index, :create, :destroy] |
125 | end | 125 | end |
126 | root :to => "projects#index" | 126 | root :to => "projects#index" |
127 | end | 127 | end |
spec/requests/projects_wall_spec.rb
@@ -8,7 +8,7 @@ describe "Projects", "Wall" do | @@ -8,7 +8,7 @@ describe "Projects", "Wall" do | ||
8 | project.add_access(@user, :read, :write) | 8 | project.add_access(@user, :read, :write) |
9 | end | 9 | end |
10 | 10 | ||
11 | - describe "View notes on wall" do | 11 | + describe "View notes on wall", :js => true do |
12 | before do | 12 | before do |
13 | Factory :note, :project => project, :note => "Project specs", :author => @user | 13 | Factory :note, :project => project, :note => "Project specs", :author => @user |
14 | visit wall_project_path(project) | 14 | visit wall_project_path(project) |