From cff951912734a5aeea0ebb3e4ca01f704004a466 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 20 Dec 2011 08:24:14 +0200 Subject: [PATCH] Dashboard perfomance improved. Filter for projects page --- README.md | 3 - app/assets/javascripts/application.js | 44 +++++++- app/assets/javascripts/commits.js | 93 ++++++++--------- app/assets/javascripts/projects.js | 107 ++++++++++++-------- app/assets/stylesheets/projects.css.scss | 6 ++ app/controllers/dashboard_controller.rb | 2 +- app/controllers/projects_controller.rb | 7 +- app/models/merge_request.rb | 3 +- app/models/project.rb | 23 ++++- app/views/dashboard/_sidebar.html.haml | 2 +- app/views/merge_requests/_commits.html.haml | 2 + app/views/merge_requests/_diffs.html.haml | 2 + app/views/projects/_tile.html.haml | 8 +- app/views/projects/index.html.haml | 16 ++- app/views/projects/index.js.haml | 7 ++ config/initializers/rails_footnotes.rb | 2 - 16 files changed, 215 insertions(+), 112 deletions(-) create mode 100644 app/views/projects/index.js.haml diff --git a/README.md b/README.md index ff81ede3f4b..2287d48263e 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,6 @@ GitLab is a free Project/Repository management application - - - ## Application details rails 3.1 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 93dbd7dd19c..04d4f0bc6cf 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -16,7 +16,7 @@ //= require branch-graph //= require_tree . -$(function(){ +$(document).ready(function(){ $(".one_click_select").live("click", function(){ $(this).select(); }); @@ -27,8 +27,50 @@ $(function(){ $(".account-box").mouseenter(showMenu); $(".account-box").mouseleave(resetMenu); + $("#projects-list .project").live('click', function(e){ + if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") { + location.href = $(this).attr("url"); + e.stopPropagation(); + return false; + } + }); + + $("#issues-table .issue").live('click', function(e){ + if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") { + location.href = $(this).attr("url"); + e.stopPropagation(); + return false; + } + }); + + $(document).keypress(function(e) { + if( $(e.target).is(":input") ) return; + switch(e.which) { + case 115: focusSearch(); + e.preventDefault(); + } + }); + }); +function focusSearch() { + $("#search").focus(); +} + +function taggifyForm(){ + var tag_field = $('#tag_field').tagify(); + + tag_field.tagify('inputField').autocomplete({ + source: '/tags.json' + }); + + $('form').submit( function() { + var tag_field = $('#tag_field') + tag_field.val( tag_field.tagify('serialize') ); + return true; + }); +} + function updatePage(data){ $.ajax({type: "GET", url: location.href, data: data, dataType: "script"}); } diff --git a/app/assets/javascripts/commits.js b/app/assets/javascripts/commits.js index 6e5b2102a68..bb06df55c6e 100644 --- a/app/assets/javascripts/commits.js +++ b/app/assets/javascripts/commits.js @@ -1,55 +1,52 @@ -$(document).ready(function(){ - $(".day-commits-table li.commit").live('click', function(e){ - if(e.target.nodeName != "A") { - location.href = $(this).attr("url"); - e.stopPropagation(); - return false; - } - }); -}); - var CommitsList = { + ref:null, + limit:0, + offset:0, -ref:null, -limit:0, -offset:0, + init: + function(ref, limit) { + $(".day-commits-table li.commit").live('click', function(e){ + if(e.target.nodeName != "A") { + location.href = $(this).attr("url"); + e.stopPropagation(); + return false; + } + }); -init: - function(ref, limit) { - this.ref=ref; - this.limit=limit; - this.offset=limit; - this.initLoadMore(); - $('.loading').show(); - }, - -getOld: - function() { - $('.loading').show(); - $.ajax({ - type: "GET", - url: location.href, - data: "limit=" + this.limit + "&offset=" + this.offset + "&ref=" + this.ref, - complete: function(){ $('.loading').hide()}, - dataType: "script"}); - }, - -append: - function(count, html) { - $("#commits_list").append(html); - if(count > 0) { - this.offset += count; + this.ref=ref; + this.limit=limit; + this.offset=limit; this.initLoadMore(); - } - }, + $('.loading').show(); + }, -initLoadMore: - function() { - $(window).bind('scroll', function(){ - if($(window).scrollTop() == $(document).height() - $(window).height()){ - $(window).unbind('scroll'); - CommitsList.getOld(); + getOld: + function() { + $('.loading').show(); + $.ajax({ + type: "GET", + url: location.href, + data: "limit=" + this.limit + "&offset=" + this.offset + "&ref=" + this.ref, + complete: function(){ $('.loading').hide()}, + dataType: "script"}); + }, + + append: + function(count, html) { + $("#commits_list").append(html); + if(count > 0) { + this.offset += count; + this.initLoadMore(); } - }); - } + }, + + initLoadMore: + function() { + $(window).bind('scroll', function(){ + if($(window).scrollTop() == $(document).height() - $(window).height()){ + $(window).unbind('scroll'); + CommitsList.getOld(); + } + }); + } } diff --git a/app/assets/javascripts/projects.js b/app/assets/javascripts/projects.js index 7d21f061703..a80e593f003 100644 --- a/app/assets/javascripts/projects.js +++ b/app/assets/javascripts/projects.js @@ -1,45 +1,66 @@ -$(document).ready(function(){ - $("#projects-list .project").live('click', function(e){ - if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") { - location.href = $(this).attr("url"); - e.stopPropagation(); - return false; +var ProjectsList = { + limit:0, + offset:0, + + init: + function(limit) { + this.limit=limit; + this.offset=limit; + this.initLoadMore(); + + $('.project_search').keyup(function() { + var terms = $(this).val(); + if (terms.length >= 2 || terms.length == 0) { + url = $('.project_search').parent().attr('action'); + $.ajax({ + type: "GET", + url: location.href, + data: { 'terms': terms, 'replace': true }, + dataType: "script" + }); + } + }); + }, + + getOld: + function() { + $('.loading').show(); + $.ajax({ + type: "GET", + url: location.href, + data: "limit=" + this.limit + "&offset=" + this.offset, + complete: function(){ $('.loading').hide()}, + dataType: "script"}); + }, + + replace: + function(count, html) { + $(".tile").html(html); + if(count == ProjectsList.limit) { + this.offset = count; + this.initLoadMore(); + } else { + this.offset = 0; + } + }, + + append: + function(count, html) { + $(".tile").append(html); + if(count > 0) { + this.offset += count; + this.initLoadMore(); + } + }, + + initLoadMore: + function() { + $(window).bind('scroll', function(){ + if($(window).scrollTop() == $(document).height() - $(window).height()){ + $(window).unbind('scroll'); + $('.loading').show(); + ProjectsList.getOld(); + } + }); } - }); - - $("#issues-table .issue").live('click', function(e){ - if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") { - location.href = $(this).attr("url"); - e.stopPropagation(); - return false; - } - }); - - $(document).keypress(function(e) { - if( $(e.target).is(":input") ) return; - switch(e.which) { - case 115: focusSearch(); - e.preventDefault(); - } - }); - -}); - -function focusSearch() { - $("#search").focus(); } - -function taggifyForm(){ - var tag_field = $('#tag_field').tagify(); - - tag_field.tagify('inputField').autocomplete({ - source: '/tags.json' - }); - - $('form').submit( function() { - var tag_field = $('#tag_field') - tag_field.val( tag_field.tagify('serialize') ); - return true; - }); -} - diff --git a/app/assets/stylesheets/projects.css.scss b/app/assets/stylesheets/projects.css.scss index 366a0d84a40..f1b7ac09b21 100644 --- a/app/assets/stylesheets/projects.css.scss +++ b/app/assets/stylesheets/projects.css.scss @@ -647,3 +647,9 @@ h4.middle-panel { border-radius:3px; float:left; } + +.project_search { + margin: 1.5em 0; + padding: 8px !important; + width: 300px; +} diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 959585adbd6..39c706488e5 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -3,7 +3,7 @@ class DashboardController < ApplicationController def index @projects = current_user.projects.all - @active_projects = @projects.select(&:last_activity_date).sort_by(&:last_activity_date).reverse + @active_projects = @projects.select(&:last_activity_date_cached).sort_by(&:last_activity_date_cached).reverse respond_to do |format| format.html diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 5f4f2524327..f0eafeeb5cf 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -11,9 +11,10 @@ class ProjectsController < ApplicationController before_filter :require_non_empty_project, :only => [:blob, :tree, :graph] def index - source = current_user.projects - source = source.tagged_with(params[:tag]) unless params[:tag].blank? - @projects = source.all + @limit, @offset = (params[:limit] || 16), (params[:offset] || 0) + @projects = current_user.projects + @projects = @projects.where("name LIKE ?", "%#{params[:terms]}%") unless params[:terms].blank? + @projects = @projects.limit(@limit).offset(@offset) end def new diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 67f61235602..8af462427b8 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -35,9 +35,8 @@ class MergeRequest < ActiveRecord::Base end def diffs - commit = project.commit(source_branch) commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)} - diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) + diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue [] end def last_commit diff --git a/app/models/project.rb b/app/models/project.rb index d7c9515ec35..4ffb9c4c7cf 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -52,6 +52,9 @@ class Project < ActiveRecord::Base scope :public_only, where(:private_flag => false) + def self.active + joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC") + end def self.access_options { @@ -195,6 +198,24 @@ class Project < ActiveRecord::Base last_activity.try(:created_at) end + def last_activity_date_cached(expire = 1.hour) + activity_date_key = "project_#{id}_activity_date" + + cached_activities = Rails.cache.read(activity_date_key) + if cached_activities + activity_date = if cached_activities == "Never" + nil + else + cached_activities + end + else + activity_date = last_activity_date + Rails.cache.write(activity_date_key, activity_date || "Never", :expires_in => expire) + end + + activity_date + end + # Get project updates from cache # or calculate. def cached_updates(limit, expire = 2.minutes) @@ -204,7 +225,7 @@ class Project < ActiveRecord::Base activities = cached_activities else activities = updates(limit) - Rails.cache.write(activities_key, activities, :expires_in => 60.seconds) + Rails.cache.write(activities_key, activities, :expires_in => expire) end activities diff --git a/app/views/dashboard/_sidebar.html.haml b/app/views/dashboard/_sidebar.html.haml index 337c1541a3e..9f6378b49a7 100644 --- a/app/views/dashboard/_sidebar.html.haml +++ b/app/views/dashboard/_sidebar.html.haml @@ -11,5 +11,5 @@ %span.project-name= project.name %span.time %strong Last activity: - = project.last_activity_date ? time_ago_in_words(project.last_activity_date) + " ago" : "Never" + = project.last_activity_date_cached ? time_ago_in_words(project.last_activity_date_cached) + " ago" : "Never" diff --git a/app/views/merge_requests/_commits.html.haml b/app/views/merge_requests/_commits.html.haml index 508aa2311f9..c0d7486b704 100644 --- a/app/views/merge_requests/_commits.html.haml +++ b/app/views/merge_requests/_commits.html.haml @@ -15,3 +15,5 @@ ago .clear +- if @commits.empty? + %p.cgray Nothing to merge diff --git a/app/views/merge_requests/_diffs.html.haml b/app/views/merge_requests/_diffs.html.haml index 2ea6c79d25e..ef6b0f1f4f8 100644 --- a/app/views/merge_requests/_diffs.html.haml +++ b/app/views/merge_requests/_diffs.html.haml @@ -20,3 +20,5 @@ %p %center No preview for this file type +- if @diffs.empty? + %p.cgray Nothing to merge diff --git a/app/views/projects/_tile.html.haml b/app/views/projects/_tile.html.haml index a96e0b6b8fb..3bccaaa0b90 100644 --- a/app/views/projects/_tile.html.haml +++ b/app/views/projects/_tile.html.haml @@ -10,10 +10,10 @@ %input{ :value => project.url_to_repo, :class => ['git-url', 'one_click_select', 'text', 'project_list_url'], :readonly => 'readonly' } %p.title.activity %span Last Activity: - - last_note = project.notes.last - = last_note ? last_note.created_at.stamp("24 Aug, 2011") : "Never" - - %p.small-tags= tag_list project + - if project.last_activity_date_cached + = project.last_activity_date_cached.stamp("24 Aug, 2011") + - else + Never .buttons %a.browse-code.button.yellow{:href => tree_project_ref_path(project, project.root_ref)} Browse code diff --git a/app/views/projects/index.html.haml b/app/views/projects/index.html.haml index e5255ae5152..9cbfd9505be 100644 --- a/app/views/projects/index.html.haml +++ b/app/views/projects/index.html.haml @@ -7,13 +7,23 @@ %h2.icon %span Projects + %center + = form_tag projects_path, :method => :get, :remote => true, :id => "projects_search_form" do + = search_field_tag :project_search, nil, { :placeholder => 'Filter projects by name', :class => 'project_search text' } %div.clear - unless @projects.empty? - %div{:class => "tile", :style => view_mode_style("tile")} + %div{:class => "tile"} = render "tile" - %div{:class => "list", :style => view_mode_style("list")} - = render "list" + .clear + .loading{ :style => "display:none;"} + %center= image_tag "ajax-loader.gif" + + - if @projects.count == @limit + :javascript + $(function(){ + ProjectsList.init(16); + }); - else %center.prepend-top %h2 diff --git a/app/views/projects/index.js.haml b/app/views/projects/index.js.haml new file mode 100644 index 00000000000..9b990734f3a --- /dev/null +++ b/app/views/projects/index.js.haml @@ -0,0 +1,7 @@ +- if params[:replace] + :plain + ProjectsList.replace(#{@projects.count}, "#{escape_javascript(render(:partial => 'projects/tile'))}"); +- else + :plain + ProjectsList.append(#{@projects.count}, "#{escape_javascript(render(:partial => 'projects/tile'))}"); + diff --git a/config/initializers/rails_footnotes.rb b/config/initializers/rails_footnotes.rb index db71e39c608..afe6f3ad383 100644 --- a/config/initializers/rails_footnotes.rb +++ b/config/initializers/rails_footnotes.rb @@ -1,5 +1,3 @@ #if defined?(Footnotes) && Rails.env.development? #Footnotes.run! # first of all - - # ... other init code #end