Commit cd779e56e1ce799fc6ec25dc2fbc8a3e0f775ee8

Authored by Dmitriy Zaporozhets
1 parent 4107f2cc

dashboard v1

app/controllers/dashboard_controller.rb
1 1 class DashboardController < ApplicationController
  2 + respond_to :js, :html
  3 +
2 4 def index
3 5 @projects = current_user.projects.all
4 6 @active_projects = @projects.select(&:last_activity_date).sort_by(&:last_activity_date).reverse
  7 +
  8 + respond_to do |format|
  9 + format.html
  10 + format.js { no_cache_headers }
  11 + end
  12 + end
  13 +
  14 + def merge_requests
  15 + @projects = current_user.projects.all
  16 + @merge_requests = current_user.assigned_merge_requests.order("created_at DESC").limit(40)
  17 +
  18 + respond_to do |format|
  19 + format.html
  20 + format.js { no_cache_headers }
  21 + end
  22 + end
  23 +
  24 + def issues
  25 + @projects = current_user.projects.all
  26 + @user = current_user
  27 + @issues = current_user.assigned_issues.opened.order("created_at DESC").limit(40)
  28 +
  29 + @issues = @issues.includes(:author, :project)
  30 +
  31 + respond_to do |format|
  32 + format.html
  33 + format.js { no_cache_headers }
  34 + format.atom { render :layout => false }
  35 + end
5 36 end
6 37 end
... ...
app/controllers/user_issues_controller.rb
... ... @@ -1,20 +0,0 @@
1   -class UserIssuesController < ApplicationController
2   - before_filter :authenticate_user!
3   -
4   - respond_to :js, :html
5   -
6   - def index
7   - @projects = current_user.projects.all
8   - @user = current_user
9   - @issues = current_user.assigned_issues.opened
10   -
11   - @issues = @issues.includes(:author, :project)
12   -
13   - respond_to do |format|
14   - format.html
15   - format.js
16   - format.atom { render :layout => false }
17   - end
18   - end
19   -
20   -end
app/controllers/user_merge_requests_controller.rb
... ... @@ -1,8 +0,0 @@
1   -class UserMergeRequestsController < ApplicationController
2   - before_filter :authenticate_user!
3   -
4   - def index
5   - @projects = current_user.projects.all
6   - @merge_requests = current_user.assigned_merge_requests
7   - end
8   -end
app/views/dashboard/_issues_feed.html.haml
1   -#news-feed.news-feed
2   - %div
3   - = link_to dashboard_path, :class => "left" do
4   - .box-arrow
5   - &larr;
6   - %h2{:style => "width:86%; text-align:center"}
7   - Issues
8   - = link_to merge_requests_path, :class => "right" do
9   - .box-arrow
10   - &rarr;
  1 +%div
  2 + = link_to dashboard_path, :remote => true, :class => "left" do
  3 + .box-arrow
  4 + &larr;
  5 + %h2{:style => "width:86%; text-align:center"}
  6 + Issues
  7 + = link_to dashboard_merge_requests_path, :remote => true, :class => "right" do
  8 + .box-arrow
  9 + &rarr;
11 10  
12 11  
  12 +#feeds_content_holder
13 13 .project-box.project-updates.ui-box.ui-box-small.ui-box-big
14 14 .data
15 15 - @issues.each do |update|
16 16 %a.project-update{:href => dashboard_feed_path(update.project, update)}
17 17 = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
18 18 %span.update-title
19   - = dashboard_feed_title(update)
  19 + = truncate update.title, :length => 50
  20 + .right= update.project.name
20 21 %span.update-author
21 22 %strong= update.author_name
22 23 authored
23 24 = time_ago_in_words(update.created_at)
24 25 ago
25 26 .right
26   - - klass = update.class.to_s.split("::").last.downcase
27   - %span.tag{ :class => klass }= klass
  27 + - if update.critical
  28 + %span.tag.high critical
  29 + - if update.today?
  30 + %span.tag.today today
28 31  
... ...
app/views/dashboard/_merge_requests_feed.html.haml
1   -#news-feed.news-feed
2   - %div
3   - = link_to issues_path, :class => "left" do
4   - .box-arrow
5   - &larr;
6   - %h2{:style => "width:86%; text-align:center"}
7   - Merge Requests
8   - = link_to dashboard_path, :class => "right" do
9   - .box-arrow
10   - &rarr;
  1 +%div
  2 + = link_to dashboard_issues_path, :remote => true, :class => "left" do
  3 + .box-arrow
  4 + &larr;
  5 + %h2{:style => "width:86%; text-align:center"}
  6 + Merge Requests
  7 + = link_to dashboard_path, :remote => true, :class => "right" do
  8 + .box-arrow
  9 + &rarr;
11 10  
  11 +#feeds_content_holder
12 12 .project-box.project-updates.ui-box.ui-box-small.ui-box-big
13 13 .data
14 14 - @merge_requests.each do |update|
15   - %a.project-update{:href => dashboard_feed_path(update.project, update)}
  15 + %a.project-update{:href => project_merge_request_path(update.project, update)}
16 16 = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
17 17 %span.update-title
18   - = dashboard_feed_title(update)
  18 + = truncate update.title, :length => 70
  19 + .right= update.project.name
19 20 %span.update-author
20 21 %strong= update.author_name
21 22 authored
22 23 = time_ago_in_words(update.created_at)
23 24 ago
24 25 .right
25   - - klass = update.class.to_s.split("::").last.downcase
26   - %span.tag{ :class => klass }= klass
27   -
  26 + %span.tag.commit= update.source_branch
  27 + &rarr;
  28 + %span.tag.commit= update.target_branch
... ...
app/views/dashboard/_projects_feed.html.haml
1   -#news-feed.news-feed
2   - %div
3   - = link_to merge_requests_path, :class => "left" do
4   - .box-arrow
5   - &larr;
6   - %h2{:style => "width:86%; text-align:center"}
7   - Activities
8   - = link_to issues_path, :class => "right" do
9   - .box-arrow
10   - &rarr;
  1 +%div
  2 + = link_to dashboard_merge_requests_path, :remote => true, :class => "left", :id => "merge_requests_slide" do
  3 + .box-arrow
  4 + &larr;
  5 + %h2{:style => "width:86%; text-align:center"}
  6 + Activities
  7 + = link_to dashboard_issues_path, :remote => true, :class => "right", :id => "issues_slide" do
  8 + .box-arrow
  9 + &rarr;
11 10  
  11 +#feeds_content_holder
12 12 - @active_projects.first(3).each do |project|
13 13 .project-box.project-updates.ui-box.ui-box-small.ui-box-big
14 14 = link_to project, do
... ...
app/views/dashboard/_sidebar.html.haml 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +%aside
  2 + %h4
  3 + - if current_user.can_create_project?
  4 + %a.button-small.button-green{:href => new_project_path} New Project
  5 + Your Projects
  6 + %ol.project-list
  7 + - @projects.each do |project|
  8 + %li
  9 + %a{:href => project_path(project)}
  10 + %span.arrow →
  11 + %span.project-name= project.name
  12 + %span.time
  13 + %strong Last activity:
  14 + = project.last_activity_date ? time_ago_in_words(project.last_activity_date) + " ago" : "Never"
  15 +
... ...
app/views/dashboard/index.html.haml
1 1 - content_for(:body_class, "dashboard-page")
2 2  
3 3 #dashboard-content.dashboard-content.content
4   - %aside
5   - %h4
6   - - if current_user.can_create_project?
7   - %a.button-small.button-green{:href => new_project_path} New Project
8   - Your Projects
9   - %ol.project-list
10   - - @projects.each do |project|
11   - %li
12   - %a{:href => project_path(project)}
13   - %span.arrow →
14   - %span.project-name= project.name
15   - %span.time
16   - %strong Last activity:
17   - = project.last_activity_date ? time_ago_in_words(project.last_activity_date) + " ago" : "Never"
18   - = render "dashboard/projects_feed"
  4 + = render "dashboard/sidebar"
  5 + #news-feed.news-feed= render "dashboard/projects_feed"
... ...
app/views/dashboard/index.js.haml 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +:plain
  2 + $("#feeds_content_holder").hide("slide", { direction: "left" }, 150, function(){
  3 + $("#news-feed").html("#{escape_javascript(render(:partial => "projects_feed"))}");
  4 + $("#feeds_content_holder").show("slide", { direction: "right" }, 150);
  5 + history.pushState({ path: this.path }, '', '#{dashboard_path}')
  6 + });
  7 +
... ...
app/views/dashboard/issues.atom.builder 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +xml.instruct!
  2 +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
  3 + xml.title "#{@user.name} issues"
  4 + xml.link :href => dashboard_issues_url(:atom, :private_token => @user.private_token), :rel => "self", :type => "application/atom+xml"
  5 + xml.link :href => dashboard_issues_url(:private_token => @user.private_token), :rel => "alternate", :type => "text/html"
  6 + xml.id dashboard_issues_url(:private_token => @user.private_token)
  7 + xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
  8 +
  9 + @issues.each do |issue|
  10 + xml.entry do
  11 + xml.id project_issue_url(issue.project, issue)
  12 + xml.link :href => project_issue_url(issue.project, issue)
  13 + xml.title truncate(issue.title, :length => 80)
  14 + xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
  15 + xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(issue.author_email)
  16 + xml.author do |author|
  17 + xml.name issue.author_name
  18 + xml.email issue.author_email
  19 + end
  20 + xml.summary issue.title
  21 + end
  22 + end
  23 +end
  24 +
... ...
app/views/dashboard/issues.html.haml 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +- content_for(:body_class, "dashboard-page")
  2 +
  3 +#dashboard-content.dashboard-content.content
  4 + = render "dashboard/sidebar"
  5 + #news-feed.news-feed= render "dashboard/issues_feed"
... ...
app/views/dashboard/issues.js.haml 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +:plain
  2 + $("#feeds_content_holder").hide("slide", { direction: "left" }, 150, function(){
  3 + $("#news-feed").html("#{escape_javascript(render(:partial => "issues_feed"))}");
  4 + $("#feeds_content_holder").show("slide", { direction: "right" }, 150);
  5 + history.pushState({ path: this.path }, '', '#{dashboard_issues_path}')
  6 + });
  7 +
... ...
app/views/dashboard/merge_requests.html.haml 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +- content_for(:body_class, "dashboard-page")
  2 +
  3 +#dashboard-content.dashboard-content.content
  4 + = render "dashboard/sidebar"
  5 + #news-feed.news-feed= render "dashboard/merge_requests_feed"
... ...
app/views/dashboard/merge_requests.js.haml 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +:plain
  2 + $("#feeds_content_holder").hide("slide", { direction: "left" }, 150, function(){
  3 + $("#news-feed").html("#{escape_javascript(render(:partial => "merge_requests_feed"))}");
  4 + $("#feeds_content_holder").show("slide", { direction: "right" }, 150);
  5 + history.pushState({ path: this.path }, '', '#{dashboard_merge_requests_path}')
  6 + });
  7 +
... ...
app/views/merge_requests/_merge_request.html.haml
... ... @@ -3,9 +3,6 @@
3 3 %span.update-title
4 4 = merge_request.title
5 5 %span.update-author
6   - - if not @project.present?
7   - %strong= merge_request.project.name
8   - = '-'
9 6 %strong= merge_request.author_name
10 7 authored
11 8 = time_ago_in_words(merge_request.created_at)
... ...
app/views/user_issues/index.atom.builder
... ... @@ -1,24 +0,0 @@
1   -xml.instruct!
2   -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
3   - xml.title "#{@user.name} issues"
4   - xml.link :href => issues_url(:atom, :private_token => @user.private_token), :rel => "self", :type => "application/atom+xml"
5   - xml.link :href => issues_url(:private_token => @user.private_token), :rel => "alternate", :type => "text/html"
6   - xml.id issues_url(:private_token => @user.private_token)
7   - xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
8   -
9   - @issues.each do |issue|
10   - xml.entry do
11   - xml.id project_issue_url(issue.project, issue)
12   - xml.link :href => project_issue_url(issue.project, issue)
13   - xml.title truncate(issue.title, :length => 80)
14   - xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
15   - xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(issue.author_email)
16   - xml.author do |author|
17   - xml.name issue.author_name
18   - xml.email issue.author_email
19   - end
20   - xml.summary issue.title
21   - end
22   - end
23   -end
24   -
app/views/user_issues/index.html.haml
... ... @@ -1,18 +0,0 @@
1   -- content_for(:body_class, "dashboard-page")
2   -
3   -#dashboard-content.dashboard-content.content
4   - %aside
5   - %h4
6   - - if current_user.can_create_project?
7   - %a.button-small.button-green{:href => new_project_path} New Project
8   - Your Projects
9   - %ol.project-list
10   - - @projects.each do |project|
11   - %li
12   - %a{:href => project_path(project)}
13   - %span.arrow →
14   - %span.project-name= project.name
15   - %span.time
16   - %strong Last activity:
17   - = project.last_activity_date ? time_ago_in_words(project.last_activity_date) + " ago" : "Never"
18   - = render "dashboard/issues_feed"
app/views/user_merge_requests/index.html.haml
... ... @@ -1,18 +0,0 @@
1   -- content_for(:body_class, "dashboard-page")
2   -
3   -#dashboard-content.dashboard-content.content
4   - %aside
5   - %h4
6   - - if current_user.can_create_project?
7   - %a.button-small.button-green{:href => new_project_path} New Project
8   - Your Projects
9   - %ol.project-list
10   - - @projects.each do |project|
11   - %li
12   - %a{:href => project_path(project)}
13   - %span.arrow →
14   - %span.project-name= project.name
15   - %span.time
16   - %strong Last activity:
17   - = project.last_activity_date ? time_ago_in_words(project.last_activity_date) + " ago" : "Never"
18   - = render "dashboard/merge_requests_feed"
config/routes.rb
1 1 Gitlab::Application.routes.draw do
2 2  
3   - get "user_issues/index"
4 3  
5 4 get 'tags'=> 'tags#index'
6 5 get 'tags/:tag' => 'projects#index'
... ... @@ -22,9 +21,10 @@ Gitlab::Application.routes.draw do
22 21 put "profile/reset_private_token", :to => "profile#reset_private_token"
23 22 put "profile/edit", :to => "profile#social_update"
24 23 get "profile", :to => "profile#show"
  24 +
25 25 get "dashboard", :to => "dashboard#index"
26   - get "issues", :to => "user_issues#index", :as => "issues"
27   - get "merge_requests", :to => "user_merge_requests#index", :as => "merge_requests"
  26 + get "dashboard/issues", :to => "dashboard#issues"
  27 + get "dashboard/merge_requests", :to => "dashboard#merge_requests"
28 28  
29 29 #get "profile/:id", :to => "profile#show"
30 30  
... ...
spec/requests/dashboard_issues_spec.rb 0 → 100644
... ... @@ -0,0 +1,58 @@
  1 +require 'spec_helper'
  2 +
  3 +describe "User Issues Dashboard", :js => true do
  4 + describe "GET /issues" do
  5 + before do
  6 +
  7 + login_as :user
  8 +
  9 + @project1 = Factory :project,
  10 + :path => "project1",
  11 + :code => "TEST1"
  12 +
  13 + @project2 = Factory :project,
  14 + :path => "project2",
  15 + :code => "TEST2"
  16 +
  17 + @project1.add_access(@user, :read, :write)
  18 + @project2.add_access(@user, :read, :write)
  19 +
  20 + @issue1 = Factory :issue,
  21 + :author => @user,
  22 + :assignee => @user,
  23 + :project => @project1
  24 +
  25 + @issue2 = Factory :issue,
  26 + :author => @user,
  27 + :assignee => @user,
  28 + :project => @project2
  29 +
  30 + visit dashboard_path
  31 + click_link "issues_slide"
  32 + end
  33 +
  34 + subject { page }
  35 +
  36 + it { should have_content(@issue1.title[0..10]) }
  37 + it { should have_content(@issue1.project.name) }
  38 + it { should have_content(@issue1.assignee.name) }
  39 +
  40 + it { should have_content(@issue2.title[0..10]) }
  41 + it { should have_content(@issue2.project.name) }
  42 + it { should have_content(@issue2.assignee.name) }
  43 +
  44 + describe "atom feed", :js => false do
  45 + it "should render atom feed via private token" do
  46 + logout
  47 + visit dashboard_issues_path(:atom, :private_token => @user.private_token)
  48 +
  49 + page.response_headers['Content-Type'].should have_content("application/atom+xml")
  50 + page.body.should have_selector("title", :text => "#{@user.name} issues")
  51 + page.body.should have_selector("author email", :text => @issue1.author_email)
  52 + page.body.should have_selector("entry summary", :text => @issue1.title)
  53 + page.body.should have_selector("author email", :text => @issue2.author_email)
  54 + page.body.should have_selector("entry summary", :text => @issue2.title)
  55 + end
  56 + end
  57 + end
  58 +end
... ...
spec/requests/dashboard_merge_requests_spec.rb 0 → 100644
... ... @@ -0,0 +1,48 @@
  1 +require 'spec_helper'
  2 +
  3 +describe "User MergeRequests", :js => true do
  4 + describe "GET /issues" do
  5 + before do
  6 +
  7 + login_as :user
  8 +
  9 + @project1 = Factory :project,
  10 + :path => "project1",
  11 + :code => "TEST1"
  12 +
  13 + @project2 = Factory :project,
  14 + :path => "project2",
  15 + :code => "TEST2"
  16 +
  17 + @project1.add_access(@user, :read, :write)
  18 + @project2.add_access(@user, :read, :write)
  19 +
  20 + @merge_request1 = Factory :merge_request,
  21 + :author => @user,
  22 + :assignee => @user,
  23 + :project => @project1
  24 +
  25 + @merge_request2 = Factory :merge_request,
  26 + :author => @user,
  27 + :assignee => @user,
  28 + :project => @project2
  29 +
  30 + visit dashboard_path
  31 + click_link "merge_requests_slide"
  32 + end
  33 +
  34 + subject { page }
  35 +
  36 + it { should have_content(@merge_request1.title) }
  37 + it { should have_content(@merge_request1.project.name) }
  38 + it { should have_content(@merge_request1.target_branch) }
  39 + it { should have_content(@merge_request1.source_branch) }
  40 + it { should have_content(@merge_request1.assignee.name) }
  41 +
  42 + it { should have_content(@merge_request2.title) }
  43 + it { should have_content(@merge_request2.project.name) }
  44 + it { should have_content(@merge_request2.target_branch) }
  45 + it { should have_content(@merge_request2.source_branch) }
  46 + it { should have_content(@merge_request2.assignee.name) }
  47 + end
  48 +end
... ...
spec/requests/issues_spec.rb
... ... @@ -23,7 +23,7 @@ describe &quot;Issues&quot; do
23 23  
24 24 subject { page }
25 25  
26   - it { should have_content(@issue.title) }
  26 + it { should have_content(@issue.title[0..20]) }
27 27 it { should have_content(@issue.project.name) }
28 28 it { should have_content(@issue.assignee.name) }
29 29  
... ...
spec/requests/user_issues_spec.rb
... ... @@ -1,55 +0,0 @@
1   -require 'spec_helper'
2   -
3   -describe "User Issues Dashboard" do
4   - describe "GET /issues" do
5   - before do
6   -
7   - login_as :user
8   -
9   - @project1 = Factory :project,
10   - :path => "project1",
11   - :code => "TEST1"
12   -
13   - @project2 = Factory :project,
14   - :path => "project2",
15   - :code => "TEST2"
16   -
17   - @project1.add_access(@user, :read, :write)
18   - @project2.add_access(@user, :read, :write)
19   -
20   - @issue1 = Factory :issue,
21   - :author => @user,
22   - :assignee => @user,
23   - :project => @project1
24   -
25   - @issue2 = Factory :issue,
26   - :author => @user,
27   - :assignee => @user,
28   - :project => @project2
29   -
30   - visit issues_path
31   - end
32   -
33   - subject { page }
34   -
35   - it { should have_content(@issue1.title) }
36   - it { should have_content(@issue1.project.name) }
37   - it { should have_content(@issue1.assignee.name) }
38   -
39   - it { should have_content(@issue2.title) }
40   - it { should have_content(@issue2.project.name) }
41   - it { should have_content(@issue2.assignee.name) }
42   -
43   - it "should render atom feed via private token" do
44   - logout
45   - visit issues_path(:atom, :private_token => @user.private_token)
46   -
47   - page.response_headers['Content-Type'].should have_content("application/atom+xml")
48   - page.body.should have_selector("title", :text => "#{@user.name} issues")
49   - page.body.should have_selector("author email", :text => @issue1.author_email)
50   - page.body.should have_selector("entry summary", :text => @issue1.title)
51   - page.body.should have_selector("author email", :text => @issue2.author_email)
52   - page.body.should have_selector("entry summary", :text => @issue2.title)
53   - end
54   - end
55   -end
spec/requests/user_merge_requests_spec.rb
... ... @@ -1,47 +0,0 @@
1   -require 'spec_helper'
2   -
3   -describe "User MergeRequests" do
4   - describe "GET /issues" do
5   - before do
6   -
7   - login_as :user
8   -
9   - @project1 = Factory :project,
10   - :path => "project1",
11   - :code => "TEST1"
12   -
13   - @project2 = Factory :project,
14   - :path => "project2",
15   - :code => "TEST2"
16   -
17   - @project1.add_access(@user, :read, :write)
18   - @project2.add_access(@user, :read, :write)
19   -
20   - @merge_request1 = Factory :merge_request,
21   - :author => @user,
22   - :assignee => @user,
23   - :project => @project1
24   -
25   - @merge_request2 = Factory :merge_request,
26   - :author => @user,
27   - :assignee => @user,
28   - :project => @project2
29   -
30   - visit merge_requests_path
31   - end
32   -
33   - subject { page }
34   -
35   - it { should have_content(@merge_request1.title) }
36   - it { should have_content(@merge_request1.project.name) }
37   - it { should have_content(@merge_request1.target_branch) }
38   - it { should have_content(@merge_request1.source_branch) }
39   - it { should have_content(@merge_request1.assignee.name) }
40   -
41   - it { should have_content(@merge_request2.title) }
42   - it { should have_content(@merge_request2.project.name) }
43   - it { should have_content(@merge_request2.target_branch) }
44   - it { should have_content(@merge_request2.source_branch) }
45   - it { should have_content(@merge_request2.assignee.name) }
46   - end
47   -end