Commit 072b2d5de81daa159eee8f8bb05bd94814a1f6c3

Authored by Aleksei Kvitinskii
2 parents 62112dc0 04997592

Implement tags cloud support for projects

app/assets/javascripts/commits.js
@@ -7,3 +7,51 @@ $(document).ready(function(){ @@ -7,3 +7,51 @@ $(document).ready(function(){
7 } 7 }
8 }); 8 });
9 }); 9 });
  10 +
  11 +
  12 +
  13 +var CommitsList = {
  14 +
  15 +ref:null,
  16 +limit:0,
  17 +offset:0,
  18 +
  19 +init:
  20 + function(ref, limit) {
  21 + this.ref=ref;
  22 + this.limit=limit;
  23 + this.offset=limit;
  24 + this.initLoadMore();
  25 + $('.loading').show();
  26 + },
  27 +
  28 +getOld:
  29 + function() {
  30 + $('.loading').show();
  31 + $.ajax({
  32 + type: "GET",
  33 + url: location.href,
  34 + data: "limit=" + this.limit + "&offset=" + this.offset + "&ref=" + this.ref,
  35 + complete: function(){ $('.loading').hide()},
  36 + dataType: "script"});
  37 + },
  38 +
  39 +append:
  40 + function(count, html) {
  41 + $("#commits_list").append(html);
  42 + if(count > 0) {
  43 + this.offset += count;
  44 + this.initLoadMore();
  45 + }
  46 + },
  47 +
  48 +initLoadMore:
  49 + function() {
  50 + $(window).bind('scroll', function(){
  51 + if($(window).scrollTop() == $(document).height() - $(window).height()){
  52 + $(window).unbind('scroll');
  53 + CommitsList.getOld();
  54 + }
  55 + });
  56 + }
  57 +}
app/assets/javascripts/note.js
@@ -31,6 +31,15 @@ append: @@ -31,6 +31,15 @@ append:
31 this.initLoadMore(); 31 this.initLoadMore();
32 }, 32 },
33 33
  34 +replace:
  35 + function(fid, lid, html) {
  36 + this.first_id = fid;
  37 + this.last_id = lid;
  38 + $("#notes-list").html(html);
  39 + this.initLoadMore();
  40 + },
  41 +
  42 +
34 prepend: 43 prepend:
35 function(id, html) { 44 function(id, html) {
36 this.last_id = id; 45 this.last_id = id;
@@ -47,10 +56,23 @@ getNew: @@ -47,10 +56,23 @@ getNew:
47 dataType: "script"}); 56 dataType: "script"});
48 }, 57 },
49 58
  59 +refresh:
  60 + function() {
  61 + // refersh notes list
  62 + $.ajax({
  63 + type: "GET",
  64 + url: location.href,
  65 + data: "first_id=" + this.first_id + "&last_id=" + this.last_id,
  66 + dataType: "script"});
  67 + },
  68 +
  69 +
  70 +
50 initRefresh: 71 initRefresh:
51 function() { 72 function() {
52 // init timer 73 // init timer
53 - var int = setInterval("NoteList.getNew()", 20000); 74 + var intNew = setInterval("NoteList.getNew()", 15000);
  75 + var intRefresh = setInterval("NoteList.refresh()", 90000);
54 }, 76 },
55 77
56 initLoadMore: 78 initLoadMore:
app/assets/stylesheets/projects.css.scss
@@ -52,7 +52,8 @@ @@ -52,7 +52,8 @@
52 background: #eee; 52 background: #eee;
53 } 53 }
54 .diff_file_content { 54 .diff_file_content {
55 - overflow-x: scroll; 55 + overflow:auto;
  56 + overflow-y:hidden;
56 background:#fff; 57 background:#fff;
57 color:#333; 58 color:#333;
58 font-size: 12px; 59 font-size: 12px;
@@ -162,10 +163,6 @@ table.round-borders { @@ -162,10 +163,6 @@ table.round-borders {
162 padding:20px; 163 padding:20px;
163 } 164 }
164 165
165 -//body {  
166 - //background: #eaeaea;  
167 -//}  
168 -  
169 a { 166 a {
170 color: #111; 167 color: #111;
171 } 168 }
@@ -174,9 +171,9 @@ a { @@ -174,9 +171,9 @@ a {
174 .old_line, .new_line { 171 .old_line, .new_line {
175 background:#ECECEC; 172 background:#ECECEC;
176 color:#777; 173 color:#777;
177 - width:15px; 174 + width:30px;
178 float:left; 175 float:left;
179 - padding: 0px 10px; 176 + padding: 0px 5px;
180 border-right: 1px solid #ccc; 177 border-right: 1px solid #ccc;
181 } 178 }
182 } 179 }
@@ -231,43 +228,15 @@ input.ssh_project_url { @@ -231,43 +228,15 @@ input.ssh_project_url {
231 text-align:center; 228 text-align:center;
232 } 229 }
233 230
234 -.day-commits-table li.commit {  
235 - cursor:pointer;  
236 -  
237 - &:hover {  
238 - @include hover-color;  
239 - }  
240 -}  
241 -  
242 -/*  
243 -#FFF6BF  
244 -#FFD324  
245 -*/  
246 -#tree-slider tr.tree-item {  
247 - cursor:pointer;  
248 -  
249 - &:hover {  
250 - @include hover-color;  
251 - td {  
252 - @include hover-color;  
253 - }  
254 - }  
255 -}  
256 #projects-list .project { 231 #projects-list .project {
257 height:50px; 232 height:50px;
258 } 233 }
259 234
  235 +#tree-slider .tree-item,
260 #projects-list .project, 236 #projects-list .project,
261 #snippets-table .snippet, 237 #snippets-table .snippet,
262 #issues-table .issue{ 238 #issues-table .issue{
263 cursor:pointer; 239 cursor:pointer;
264 -  
265 - &:hover {  
266 - @include hover-color;  
267 - td {  
268 - @include hover-color;  
269 - }  
270 - }  
271 } 240 }
272 241
273 .clear { 242 .clear {
@@ -562,6 +531,7 @@ input.ssh_project_url { @@ -562,6 +531,7 @@ input.ssh_project_url {
562 @include round-borders-all(4px); 531 @include round-borders-all(4px);
563 padding:2px 4px; 532 padding:2px 4px;
564 border:none; 533 border:none;
  534 + text-shadow:none;
565 535
566 &.high { 536 &.high {
567 background: #D12F19; 537 background: #D12F19;
@@ -686,6 +656,13 @@ table.highlighttable pre{ @@ -686,6 +656,13 @@ table.highlighttable pre{
686 width:200px; 656 width:200px;
687 } 657 }
688 658
  659 +.issues_filter {
  660 + margin-top:10px;
  661 + .left {
  662 + margin-right:15px;
  663 + }
  664 +}
  665 +
689 body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;} 666 body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
690 body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;} 667 body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
691 body.project-page #notes-list .note img{float: left; margin-right: 10px;} 668 body.project-page #notes-list .note img{float: left; margin-right: 10px;}
app/controllers/application_controller.rb
@@ -82,5 +82,23 @@ class ApplicationController < ActionController::Base @@ -82,5 +82,23 @@ class ApplicationController < ActionController::Base
82 elsif params[:view_style] == "fluid" 82 elsif params[:view_style] == "fluid"
83 cookies[:view_style] = "" 83 cookies[:view_style] = ""
84 end 84 end
  85 +
  86 + @view_mode = if cookies[:view_style] == "collapsed"
  87 + :fixed
  88 + else
  89 + :fluid
  90 + end
  91 + end
  92 +
  93 + def respond_with_notes
  94 + if params[:last_id] && params[:first_id]
  95 + @notes = @notes.where("id >= ?", params[:first_id])
  96 + elsif params[:last_id]
  97 + @notes = @notes.where("id > ?", params[:last_id])
  98 + elsif params[:first_id]
  99 + @notes = @notes.where("id < ?", params[:first_id])
  100 + else
  101 + nil
  102 + end
85 end 103 end
86 end 104 end
app/controllers/commits_controller.rb
@@ -13,11 +13,12 @@ class CommitsController &lt; ApplicationController @@ -13,11 +13,12 @@ class CommitsController &lt; ApplicationController
13 load_refs # load @branch, @tag & @ref 13 load_refs # load @branch, @tag & @ref
14 14
15 @repo = project.repo 15 @repo = project.repo
  16 + limit, offset = (params[:limit] || 20), (params[:offset] || 0)
16 17
17 if params[:path] 18 if params[:path]
18 - @commits = @repo.log(@ref, params[:path], :max_count => params[:limit] || 100, :skip => params[:offset] || 0) 19 + @commits = @repo.log(@ref, params[:path], :max_count => limit, :skip => offset)
19 else 20 else
20 - @commits = @repo.commits(@ref, params[:limit] || 100, params[:offset] || 0) 21 + @commits = @repo.commits(@ref, limit, offset)
21 end 22 end
22 23
23 respond_to do |format| 24 respond_to do |format|
@@ -33,10 +34,7 @@ class CommitsController &lt; ApplicationController @@ -33,10 +34,7 @@ class CommitsController &lt; ApplicationController
33 34
34 respond_to do |format| 35 respond_to do |format|
35 format.html 36 format.html
36 - format.js do  
37 - @notes = @notes.where("id > ?", params[:last_id]) if params[:last_id]  
38 - @notes = @notes.where("id < ?", params[:first_id]) if params[:first_id]  
39 - end 37 + format.js { respond_with_notes }
40 end 38 end
41 end 39 end
42 end 40 end
app/controllers/issues_controller.rb
@@ -40,10 +40,7 @@ class IssuesController &lt; ApplicationController @@ -40,10 +40,7 @@ class IssuesController &lt; ApplicationController
40 40
41 respond_to do |format| 41 respond_to do |format|
42 format.html 42 format.html
43 - format.js do  
44 - @notes = @notes.where("id > ?", params[:last_id]) if params[:last_id]  
45 - @notes = @notes.where("id < ?", params[:first_id]) if params[:first_id]  
46 - end 43 + format.js { respond_with_notes }
47 end 44 end
48 end 45 end
49 46
app/controllers/projects_controller.rb
@@ -92,10 +92,7 @@ class ProjectsController &lt; ApplicationController @@ -92,10 +92,7 @@ class ProjectsController &lt; ApplicationController
92 92
93 respond_to do |format| 93 respond_to do |format|
94 format.html 94 format.html
95 - format.js do  
96 - @notes = @notes.where("id > ?", params[:last_id]) if params[:last_id]  
97 - @notes = @notes.where("id < ?", params[:first_id]) if params[:first_id]  
98 - end 95 + format.js { respond_with_notes }
99 end 96 end
100 end 97 end
101 98
app/views/commits/_commits.html.haml
@@ -22,4 +22,3 @@ @@ -22,4 +22,3 @@
22 %strong= commit.author_name 22 %strong= commit.author_name
23 = time_ago_in_words(commit.committed_date) 23 = time_ago_in_words(commit.committed_date)
24 ago 24 ago
25 -= more_commits_link if @commits.size > 99  
app/views/commits/index.html.haml
@@ -15,4 +15,14 @@ @@ -15,4 +15,14 @@
15 .right= render :partial => "projects/refs", :locals => { :destination => project_commits_path(@project) } 15 .right= render :partial => "projects/refs", :locals => { :destination => project_commits_path(@project) }
16 16
17 %div{:id => dom_id(@project)} 17 %div{:id => dom_id(@project)}
18 - = render "commits" 18 + #commits_list= render "commits"
  19 +.clear
  20 +.loading{ :style => "display:none;"}
  21 + %center= image_tag "ajax-loader.gif"
  22 +
  23 +
  24 +
  25 +:javascript
  26 + $(function(){
  27 + CommitsList.init("#{@ref}", 20);
  28 + });
app/views/commits/index.js.erb
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -$("#more-commits-link").remove();  
2 -$('#<%= dom_id(@project)%>').append('<%= escape_javascript(render("commits")) %>');  
app/views/commits/index.js.haml 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +:plain
  2 + CommitsList.append(#{@commits.count}, "#{escape_javascript(render(:partial => 'commits/commits'))}");
  3 +
app/views/commits/show.html.haml
1 %h3 1 %h3
2 - = "[ #{@commit.committer} ] #{truncate(@commit.safe_message)}" 2 + = "[ #{@commit.author_name} ] #{truncate(@commit.safe_message, :length => 70)}"
3 -#= link_to 'Back', project_commits_path(@project), :class => "button" 3 -#= link_to 'Back', project_commits_path(@project), :class => "button"
4 %table.round-borders 4 %table.round-borders
5 %tr 5 %tr
@@ -9,11 +9,8 @@ @@ -9,11 +9,8 @@
9 %td Author 9 %td Author
10 %td= @commit.author_name 10 %td= @commit.author_name
11 %tr 11 %tr
12 - %td Commiter  
13 - %td= @commit.committer  
14 - %tr  
15 %td Commited Date 12 %td Commited Date
16 - %td= @commit.committed_date 13 + %td= @commit.committed_date.stamp("21 Aug 2011, 11:15pm")
17 %tr 14 %tr
18 %td Message 15 %td Message
19 %td 16 %td
@@ -24,18 +21,7 @@ @@ -24,18 +21,7 @@
24 %td= link_to 'Browse Code', tree_project_path(@project, :commit_id => @commit.id) 21 %td= link_to 'Browse Code', tree_project_path(@project, :commit_id => @commit.id)
25 .clear 22 .clear
26 23
27 -#tabs  
28 - %ul  
29 - %li  
30 - %a{ :href => "#tabs-1" } Diff  
31 - %li  
32 - %a{ :href => "#tabs-2" } Comments  
33 - %span{ :class => "notes_count" }= @notes.count  
34 - %hr  
35 - #tabs-1  
36 - = render "commits/diff"  
37 - #tabs-2  
38 - = render "notes/notes" 24 +%br
39 25
40 -:javascript  
41 - $(function() { $( "#tabs" ).tabs(); }); 26 += render "commits/diff"
  27 += render "notes/notes"
app/views/issues/_show.html.haml
@@ -4,10 +4,11 @@ @@ -4,10 +4,11 @@
4 = image_tag "move.png" , :class => [:handle, :left] 4 = image_tag "move.png" , :class => [:handle, :left]
5 %td 5 %td
6 = image_tag gravatar_icon(issue.assignee.email), :class => "left", :width => 40, :style => "padding:0 5px;" 6 = image_tag gravatar_icon(issue.assignee.email), :class => "left", :width => 40, :style => "padding:0 5px;"
7 - = truncate issue.assignee.name, :lenght => 20 7 + = issue.assignee.name
8 %td ##{issue.id} 8 %td ##{issue.id}
9 %td 9 %td
10 - = truncate(html_escape(issue.title), :length => 60) 10 + = truncate(html_escape(issue.title), :length => 200)
  11 + %br
11 %br 12 %br
12 - if issue.critical 13 - if issue.critical
13 %span.tag.high critical 14 %span.tag.high critical
@@ -27,7 +28,8 @@ @@ -27,7 +28,8 @@
27 - else 28 - else
28 = check_box_tag "closed", 1, issue.closed, :disabled => true 29 = check_box_tag "closed", 1, issue.closed, :disabled => true
29 %td 30 %td
30 - - if can?(current_user, :admin_issue, @project) || issue.author == current_user  
31 - = link_to 'Edit', edit_project_issue_path(@project, issue), :class => "lbutton positive", :remote => true  
32 - - if can?(current_user, :admin_issue, @project) || issue.author == current_user  
33 - = link_to 'Destroy', [@project, issue], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "lbutton delete-issue negative", :id => "destroy_issue_#{issue.id}" 31 + - if @view_mode == :fluid
  32 + - if can?(current_user, :admin_issue, @project) || issue.author == current_user
  33 + = link_to 'Edit', edit_project_issue_path(@project, issue), :class => "lbutton positive", :remote => true
  34 + - if can?(current_user, :admin_issue, @project) || issue.author == current_user
  35 + = link_to 'Destroy', [@project, issue], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "lbutton delete-issue negative", :id => "destroy_issue_#{issue.id}"
app/views/issues/index.html.haml
@@ -7,18 +7,18 @@ @@ -7,18 +7,18 @@
7 = hidden_field_tag :project_id, @project.id, { :id => 'project_id' } 7 = hidden_field_tag :project_id, @project.id, { :id => 'project_id' }
8 = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search' } 8 = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search' }
9 9
10 - .right 10 + .right.issues_filter
11 = form_tag project_issues_path(@project), :method => :get do 11 = form_tag project_issues_path(@project), :method => :get do
12 - .span-2 12 + .left
13 = radio_button_tag :f, 0, (params[:f] || "0") == "0", :onclick => "this.form.submit()", :id => "open_issues", :class => "status" 13 = radio_button_tag :f, 0, (params[:f] || "0") == "0", :onclick => "this.form.submit()", :id => "open_issues", :class => "status"
14 = label_tag "open_issues","Open" 14 = label_tag "open_issues","Open"
15 - .span-2 15 + .left
16 = radio_button_tag :f, 2, params[:f] == "2", :onclick => "this.form.submit()", :id => "closed_issues", :class => "status" 16 = radio_button_tag :f, 2, params[:f] == "2", :onclick => "this.form.submit()", :id => "closed_issues", :class => "status"
17 = label_tag "closed_issues","Closed" 17 = label_tag "closed_issues","Closed"
18 - .span-2 18 + .left
19 = radio_button_tag :f, 3, params[:f] == "3", :onclick => "this.form.submit()", :id => "my_issues", :class => "status" 19 = radio_button_tag :f, 3, params[:f] == "3", :onclick => "this.form.submit()", :id => "my_issues", :class => "status"
20 = label_tag "my_issues","To Me" 20 = label_tag "my_issues","To Me"
21 - .span-2 21 + .left
22 = radio_button_tag :f, 1, params[:f] == "1", :onclick => "this.form.submit()", :id => "all_issues", :class => "status" 22 = radio_button_tag :f, 1, params[:f] == "1", :onclick => "this.form.submit()", :id => "all_issues", :class => "status"
23 = label_tag "all_issues","All" 23 = label_tag "all_issues","All"
24 24
app/views/issues/show.html.haml
1 %h2 1 %h2
2 - = "Issue ##{@issue.id} - #{html_escape(@issue.title)}" 2 + %strong
  3 + Issue
  4 + = "##{@issue.id}"
  5 + &ndash;
  6 + = html_escape(@issue.title)
3 .left.width-65p 7 .left.width-65p
4 .issue_notes= render "notes/notes" 8 .issue_notes= render "notes/notes"
5 9
@@ -9,14 +13,6 @@ @@ -9,14 +13,6 @@
9 .span-8 13 .span-8
10 %table.round-borders 14 %table.round-borders
11 %tr 15 %tr
12 - %td Title:  
13 - %td  
14 - = truncate html_escape(@issue.title)  
15 - %tr  
16 - %td Project  
17 - %td  
18 - %strong= @issue.project.name  
19 - %tr  
20 %td Author: 16 %td Author:
21 %td 17 %td
22 = image_tag gravatar_icon(@issue.author.email), :class => "left", :width => 40, :style => "padding:0 5px;" 18 = image_tag gravatar_icon(@issue.author.email), :class => "left", :width => 40, :style => "padding:0 5px;"
@@ -39,7 +35,7 @@ @@ -39,7 +35,7 @@
39 %tr 35 %tr
40 %td Closed? 36 %td Closed?
41 %td 37 %td
42 - - if can? current_user, :write_issue, @project 38 + - if can? current_user, :write_issue, @issue
43 = form_for([@project, @issue]) do |f| 39 = form_for([@project, @issue]) do |f|
44 = f.check_box :closed, :onclick => "$(this).parent().submit();" 40 = f.check_box :closed, :onclick => "$(this).parent().submit();"
45 = hidden_field_tag :status_only, true 41 = hidden_field_tag :status_only, true
@@ -47,8 +43,9 @@ @@ -47,8 +43,9 @@
47 = check_box_tag "closed", 1, @issue.closed, :disabled => true 43 = check_box_tag "closed", 1, @issue.closed, :disabled => true
48 44
49 45
50 - - if can?(current_user, :admin_issue, @issue) 46 + - if can?(current_user, :write_issue, @issue)
51 .clear 47 .clear
52 - = link_to 'Edit', edit_project_issue_path(@project, @issue), :class => "lbutton positive", :remote => true  
53 - .right= link_to 'Destroy', [@project, @issue], :confirm => 'Are you sure?', :method => :delete, :class => "lbutton delete-issue negative", :id => "destroy_issue_#{@issue.id}" 48 + %br
  49 + = link_to 'Edit', edit_project_issue_path(@project, @issue), :class => "lbutton positive", :remote => true
  50 + .right= link_to 'Destroy', [@project, @issue], :confirm => 'Are you sure?', :method => :delete, :class => "lbutton delete-issue negative", :id => "destroy_issue_#{@issue.id}"
54 .clear 51 .clear
app/views/layouts/application.html.haml
@@ -2,11 +2,7 @@ @@ -2,11 +2,7 @@
2 %html 2 %html
3 %head 3 %head
4 %title 4 %title
5 - GitLab #{" - #{@project.name}" if @project && !@project.new_record?}  
6 - -#= stylesheet_link_tag 'blueprint/screen', :media => "screen, projection"  
7 - -#= stylesheet_link_tag 'blueprint/print', :media => "print"  
8 - -#= stylesheet_link_tag 'blueprint/plugins/buttons/screen', :media => "screen, projection"  
9 - -#= stylesheet_link_tag 'blueprint/plugins/link-icons/screen', :media => "screen, projection" 5 + GitLab
10 = stylesheet_link_tag "application" 6 = stylesheet_link_tag "application"
11 = javascript_include_tag "application" 7 = javascript_include_tag "application"
12 = csrf_meta_tags 8 = csrf_meta_tags
@@ -17,6 +13,5 @@ @@ -17,6 +13,5 @@
17 #container 13 #container
18 = render :partial => "layouts/flash" 14 = render :partial => "layouts/flash"
19 = render :partial => "layouts/head_panel" 15 = render :partial => "layouts/head_panel"
20 - %div{ :id => "main", :role => "main", :class => "container_4" }  
21 - = render :partial => "layouts/page_title"  
22 - = yield 16 + = render :partial => "layouts/page_title"
  17 + = yield
app/views/notes/_load.js.haml
1 - unless @notes.blank? 1 - unless @notes.blank?
2 2
3 - - if params[:last_id] 3 + - if params[:last_id] && params[:first_id]
  4 + :plain
  5 + NoteList.replace(#{@notes.last.id}, #{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
  6 +
  7 +
  8 + - elsif params[:last_id]
4 :plain 9 :plain
5 NoteList.prepend(#{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}"); 10 NoteList.prepend(#{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
6 11
7 - - if params[:first_id] 12 + - elsif params[:first_id]
8 :plain 13 :plain
9 NoteList.append(#{@notes.last.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}"); 14 NoteList.append(#{@notes.last.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
10 15
  16 + - else
  17 + :plain
spec/requests/commits_notes_spec.rb
@@ -12,7 +12,6 @@ describe &quot;Issues&quot; do @@ -12,7 +12,6 @@ describe &quot;Issues&quot; do
12 describe "add new note", :js => true do 12 describe "add new note", :js => true do
13 before do 13 before do
14 visit project_commit_path(project, commit) 14 visit project_commit_path(project, commit)
15 - click_link "Comments" # notes tab  
16 fill_in "note_note", :with => "I commented this commit" 15 fill_in "note_note", :with => "I commented this commit"
17 click_button "Add note" 16 click_button "Add note"
18 end 17 end