Dashboard perfomance improved. Filter for projects page
This commit is contained in:
parent
6d5c969872
commit
cff9519127
16 changed files with 215 additions and 112 deletions
|
@ -3,9 +3,6 @@
|
||||||
GitLab is a free Project/Repository management application
|
GitLab is a free Project/Repository management application
|
||||||
|
|
||||||
|
|
||||||
<img src="http://gitlabhq.com/front.png" width="900" height="471">
|
|
||||||
|
|
||||||
|
|
||||||
## Application details
|
## Application details
|
||||||
|
|
||||||
rails 3.1
|
rails 3.1
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//= require branch-graph
|
//= require branch-graph
|
||||||
//= require_tree .
|
//= require_tree .
|
||||||
|
|
||||||
$(function(){
|
$(document).ready(function(){
|
||||||
$(".one_click_select").live("click", function(){
|
$(".one_click_select").live("click", function(){
|
||||||
$(this).select();
|
$(this).select();
|
||||||
});
|
});
|
||||||
|
@ -27,8 +27,50 @@ $(function(){
|
||||||
$(".account-box").mouseenter(showMenu);
|
$(".account-box").mouseenter(showMenu);
|
||||||
$(".account-box").mouseleave(resetMenu);
|
$(".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){
|
function updatePage(data){
|
||||||
$.ajax({type: "GET", url: location.href, data: data, dataType: "script"});
|
$.ajax({type: "GET", url: location.href, data: data, dataType: "script"});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
$(document).ready(function(){
|
var CommitsList = {
|
||||||
|
ref:null,
|
||||||
|
limit:0,
|
||||||
|
offset:0,
|
||||||
|
|
||||||
|
init:
|
||||||
|
function(ref, limit) {
|
||||||
$(".day-commits-table li.commit").live('click', function(e){
|
$(".day-commits-table li.commit").live('click', function(e){
|
||||||
if(e.target.nodeName != "A") {
|
if(e.target.nodeName != "A") {
|
||||||
location.href = $(this).attr("url");
|
location.href = $(this).attr("url");
|
||||||
|
@ -6,16 +12,7 @@ $(document).ready(function(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
var CommitsList = {
|
|
||||||
|
|
||||||
ref:null,
|
|
||||||
limit:0,
|
|
||||||
offset:0,
|
|
||||||
|
|
||||||
init:
|
|
||||||
function(ref, limit) {
|
|
||||||
this.ref=ref;
|
this.ref=ref;
|
||||||
this.limit=limit;
|
this.limit=limit;
|
||||||
this.offset=limit;
|
this.offset=limit;
|
||||||
|
|
|
@ -1,45 +1,66 @@
|
||||||
$(document).ready(function(){
|
var ProjectsList = {
|
||||||
$("#projects-list .project").live('click', function(e){
|
limit:0,
|
||||||
if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") {
|
offset:0,
|
||||||
location.href = $(this).attr("url");
|
|
||||||
e.stopPropagation();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#issues-table .issue").live('click', function(e){
|
init:
|
||||||
if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") {
|
function(limit) {
|
||||||
location.href = $(this).attr("url");
|
this.limit=limit;
|
||||||
e.stopPropagation();
|
this.offset=limit;
|
||||||
return false;
|
this.initLoadMore();
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).keypress(function(e) {
|
$('.project_search').keyup(function() {
|
||||||
if( $(e.target).is(":input") ) return;
|
var terms = $(this).val();
|
||||||
switch(e.which) {
|
if (terms.length >= 2 || terms.length == 0) {
|
||||||
case 115: focusSearch();
|
url = $('.project_search').parent().attr('action');
|
||||||
e.preventDefault();
|
$.ajax({
|
||||||
}
|
type: "GET",
|
||||||
});
|
url: location.href,
|
||||||
|
data: { 'terms': terms, 'replace': true },
|
||||||
});
|
dataType: "script"
|
||||||
|
|
||||||
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;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -647,3 +647,9 @@ h4.middle-panel {
|
||||||
border-radius:3px;
|
border-radius:3px;
|
||||||
float:left;
|
float:left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.project_search {
|
||||||
|
margin: 1.5em 0;
|
||||||
|
padding: 8px !important;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ class DashboardController < ApplicationController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@projects = current_user.projects.all
|
@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|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
|
|
|
@ -11,9 +11,10 @@ class ProjectsController < ApplicationController
|
||||||
before_filter :require_non_empty_project, :only => [:blob, :tree, :graph]
|
before_filter :require_non_empty_project, :only => [:blob, :tree, :graph]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
source = current_user.projects
|
@limit, @offset = (params[:limit] || 16), (params[:offset] || 0)
|
||||||
source = source.tagged_with(params[:tag]) unless params[:tag].blank?
|
@projects = current_user.projects
|
||||||
@projects = source.all
|
@projects = @projects.where("name LIKE ?", "%#{params[:terms]}%") unless params[:terms].blank?
|
||||||
|
@projects = @projects.limit(@limit).offset(@offset)
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
|
|
|
@ -35,9 +35,8 @@ class MergeRequest < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def diffs
|
def diffs
|
||||||
commit = project.commit(source_branch)
|
|
||||||
commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)}
|
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
|
end
|
||||||
|
|
||||||
def last_commit
|
def last_commit
|
||||||
|
|
|
@ -52,6 +52,9 @@ class Project < ActiveRecord::Base
|
||||||
|
|
||||||
scope :public_only, where(:private_flag => false)
|
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
|
def self.access_options
|
||||||
{
|
{
|
||||||
|
@ -195,6 +198,24 @@ class Project < ActiveRecord::Base
|
||||||
last_activity.try(:created_at)
|
last_activity.try(:created_at)
|
||||||
end
|
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
|
# Get project updates from cache
|
||||||
# or calculate.
|
# or calculate.
|
||||||
def cached_updates(limit, expire = 2.minutes)
|
def cached_updates(limit, expire = 2.minutes)
|
||||||
|
@ -204,7 +225,7 @@ class Project < ActiveRecord::Base
|
||||||
activities = cached_activities
|
activities = cached_activities
|
||||||
else
|
else
|
||||||
activities = updates(limit)
|
activities = updates(limit)
|
||||||
Rails.cache.write(activities_key, activities, :expires_in => 60.seconds)
|
Rails.cache.write(activities_key, activities, :expires_in => expire)
|
||||||
end
|
end
|
||||||
|
|
||||||
activities
|
activities
|
||||||
|
|
|
@ -11,5 +11,5 @@
|
||||||
%span.project-name= project.name
|
%span.project-name= project.name
|
||||||
%span.time
|
%span.time
|
||||||
%strong Last activity:
|
%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"
|
||||||
|
|
||||||
|
|
|
@ -15,3 +15,5 @@
|
||||||
ago
|
ago
|
||||||
.clear
|
.clear
|
||||||
|
|
||||||
|
- if @commits.empty?
|
||||||
|
%p.cgray Nothing to merge
|
||||||
|
|
|
@ -20,3 +20,5 @@
|
||||||
%p
|
%p
|
||||||
%center No preview for this file type
|
%center No preview for this file type
|
||||||
|
|
||||||
|
- if @diffs.empty?
|
||||||
|
%p.cgray Nothing to merge
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
%input{ :value => project.url_to_repo, :class => ['git-url', 'one_click_select', 'text', 'project_list_url'], :readonly => 'readonly' }
|
%input{ :value => project.url_to_repo, :class => ['git-url', 'one_click_select', 'text', 'project_list_url'], :readonly => 'readonly' }
|
||||||
%p.title.activity
|
%p.title.activity
|
||||||
%span Last Activity:
|
%span Last Activity:
|
||||||
- last_note = project.notes.last
|
- if project.last_activity_date_cached
|
||||||
= last_note ? last_note.created_at.stamp("24 Aug, 2011") : "Never"
|
= project.last_activity_date_cached.stamp("24 Aug, 2011")
|
||||||
|
- else
|
||||||
%p.small-tags= tag_list project
|
Never
|
||||||
|
|
||||||
.buttons
|
.buttons
|
||||||
%a.browse-code.button.yellow{:href => tree_project_ref_path(project, project.root_ref)} Browse code
|
%a.browse-code.button.yellow{:href => tree_project_ref_path(project, project.root_ref)} Browse code
|
||||||
|
|
|
@ -7,13 +7,23 @@
|
||||||
%h2.icon
|
%h2.icon
|
||||||
%span
|
%span
|
||||||
Projects
|
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
|
%div.clear
|
||||||
- unless @projects.empty?
|
- unless @projects.empty?
|
||||||
%div{:class => "tile", :style => view_mode_style("tile")}
|
%div{:class => "tile"}
|
||||||
= render "tile"
|
= render "tile"
|
||||||
%div{:class => "list", :style => view_mode_style("list")}
|
.clear
|
||||||
= render "list"
|
.loading{ :style => "display:none;"}
|
||||||
|
%center= image_tag "ajax-loader.gif"
|
||||||
|
|
||||||
|
- if @projects.count == @limit
|
||||||
|
:javascript
|
||||||
|
$(function(){
|
||||||
|
ProjectsList.init(16);
|
||||||
|
});
|
||||||
- else
|
- else
|
||||||
%center.prepend-top
|
%center.prepend-top
|
||||||
%h2
|
%h2
|
||||||
|
|
7
app/views/projects/index.js.haml
Normal file
7
app/views/projects/index.js.haml
Normal file
|
@ -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'))}");
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#if defined?(Footnotes) && Rails.env.development?
|
#if defined?(Footnotes) && Rails.env.development?
|
||||||
#Footnotes.run! # first of all
|
#Footnotes.run! # first of all
|
||||||
|
|
||||||
# ... other init code
|
|
||||||
#end
|
#end
|
||||||
|
|
Loading…
Reference in a new issue