Commit 8e0126e9 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'issue_dashboard' into improved_dashboard

parents 2677bc3a 2b896ea6
...@@ -351,7 +351,7 @@ header h1.logo a{ ...@@ -351,7 +351,7 @@ header h1.logo a{
text-indent: -1000em; text-indent: -1000em;
} }
header nav{border-radius: 4px; box-shadow: 0 1px 2px black; width: 294px; margin: auto; header nav{border-radius: 4px; box-shadow: 0 1px 2px black; width: 392px; margin: auto;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595d63), to(#31363e)); background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595d63), to(#31363e));
background-image: -webkit-linear-gradient(#595d63 6.6%, #31363e); background-image: -webkit-linear-gradient(#595d63 6.6%, #31363e);
background-image: -moz-linear-gradient(#595d63 6.6%, #31363e); background-image: -moz-linear-gradient(#595d63 6.6%, #31363e);
...@@ -398,6 +398,7 @@ header nav a span{width: 20px; height: 20px; display: inline-block; background: ...@@ -398,6 +398,7 @@ header nav a span{width: 20px; height: 20px; display: inline-block; background:
header nav a.dashboard span{background: url('images.png') no-repeat -161px 0;} header nav a.dashboard span{background: url('images.png') no-repeat -161px 0;}
header nav a.admin span{background: url('images.png') no-repeat -184px 0;} header nav a.admin span{background: url('images.png') no-repeat -184px 0;}
header nav a.project span{background: url('images.png') no-repeat -209px -1px; top: 7px} header nav a.project span{background: url('images.png') no-repeat -209px -1px; top: 7px}
header nav a.issues span{background: url('images.png') no-repeat -209px -1px; top: 7px}
header .login-top{float: right; width: 180px; header .login-top{float: right; width: 180px;
background-image: -webkit-gradient(linear, 0 0, 0 62, color-stop(0.032, #464c56), to(#363c45)); background-image: -webkit-gradient(linear, 0 0, 0 62, color-stop(0.032, #464c56), to(#363c45));
......
class UserIssuesController < ApplicationController
before_filter :authenticate_user!
layout "user"
respond_to :js, :html
def index
@user = current_user
@issues = current_user.assigned_issues.opened
@issues = @issues.includes(:author, :project)
respond_to do |format|
format.html
format.js
format.atom { render :layout => false }
end
end
end
class UserMergeRequestsController < ApplicationController
before_filter :authenticate_user!
layout "user"
def index
@merge_requests = current_user.assigned_merge_requests
end
end
module UserIssuesHelper
end
module UserMergeRequestsHelper
end
...@@ -25,6 +25,15 @@ class User < ActiveRecord::Base ...@@ -25,6 +25,15 @@ class User < ActiveRecord::Base
:foreign_key => :assignee_id, :foreign_key => :assignee_id,
:dependent => :destroy :dependent => :destroy
has_many :merge_requests,
:foreign_key => :author_id,
:dependent => :destroy
has_many :assigned_merge_requests,
:class_name => "MergeRequest",
:foreign_key => :assignee_id,
:dependent => :destroy
before_create :ensure_authentication_token before_create :ensure_authentication_token
alias_attribute :private_token, :authentication_token alias_attribute :private_token, :authentication_token
scope :not_in_project, lambda { |project| where("id not in (:ids)", :ids => project.users.map(&:id) ) } scope :not_in_project, lambda { |project| where("id not in (:ids)", :ids => project.users.map(&:id) ) }
......
- @issues.critical.each do |issue| - @issues.critical.each do |issue|
= render(:partial => 'show', :locals => {:issue => issue}) = render(:partial => 'issues/show', :locals => {:issue => issue})
- @issues.non_critical.each do |issue| - @issues.non_critical.each do |issue|
= render(:partial => 'show', :locals => {:issue => issue}) = render(:partial => 'issues/show', :locals => {:issue => issue})
%tr{ :id => dom_id(issue), :class => "issue #{issue.critical ? "critical" : ""}", :url => project_issue_path(@project, issue) } %tr{ :id => dom_id(issue), :class => "issue #{issue.critical ? "critical" : ""}", :url => project_issue_path(issue.project, issue) }
%td %td
%strong.issue-number{:class => sort_class}= "##{issue.id}" %strong.issue-number{:class => sort_class}= "##{issue.id}"
%span %span
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
%br %br
%br %br
%div.note-author %div.note-author
- if not @project.present?
%strong= issue.project.name
= '-'
%strong= issue.assignee.name %strong= issue.assignee.name
%cite.cgray %cite.cgray
= time_ago_in_words(issue.created_at) = time_ago_in_words(issue.created_at)
...@@ -17,10 +20,10 @@ ...@@ -17,10 +20,10 @@
.right.action-links .right.action-links
- if can? current_user, :write_issue, issue - if can? current_user, :write_issue, issue
- if issue.closed - if issue.closed
= link_to 'Reopen', project_issue_path(@project, issue, :issue => {:closed => false }, :status_only => true), :method => :put, :class => "cgray", :remote => true = link_to 'Reopen', project_issue_path(issue.project, issue, :issue => {:closed => false }, :status_only => true), :method => :put, :class => "cgray", :remote => true
- else - else
= link_to 'Resolve', project_issue_path(@project, issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "cgray", :remote => true = link_to 'Resolve', project_issue_path(issue.project, issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "cgray", :remote => true
- if can? current_user, :write_issue, issue - if can? current_user, :write_issue, issue
= link_to 'Edit', edit_project_issue_path(@project, issue), :class => "cgray edit-issue-link", :remote => true = link_to 'Edit', edit_project_issue_path(issue.project, issue), :class => "cgray edit-issue-link", :remote => true
- if can?(current_user, :admin_issue, @project) || issue.author == current_user - if can?(current_user, :admin_issue, @project) || issue.author == current_user
= link_to 'Remove', [@project, issue], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-issue negative", :id => "destroy_issue_#{issue.id}" = link_to 'Remove', [issue.project, issue], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-issue negative", :id => "destroy_issue_#{issue.id}"
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
<%= link_to dashboard_path, :class => current_page?(root_path) ? "current dashboard" : "dashboard" do %> <%= link_to dashboard_path, :class => current_page?(root_path) ? "current dashboard" : "dashboard" do %>
<span></span>Dashboard <span></span>Dashboard
<% end %> <% end %>
<%= link_to issues_path, :class => current_page?(issues_path) ? "current issues" : "issues" do %>
<span></span>Issues
<% end %>
<%= link_to projects_path, :class => current_page?(projects_path) ? "current project" : "project" do %> <%= link_to projects_path, :class => current_page?(projects_path) ? "current project" : "project" do %>
<span></span>Projects <span></span>Projects
<% end %> <% end %>
......
!!!
%html
%head
%title
GitLab #{" - #{current_user.name}"}
= stylesheet_link_tag "application"
= javascript_include_tag "application"
= csrf_meta_tags
= javascript_tag do
REQ_URI = "#{request.env["REQUEST_URI"]}";
REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
%body{ :class => body_class('project-page'), :id => yield(:boyd_id)}
= render :partial => "layouts/flash"
#container
= render :partial => "layouts/head_panel"
.project-container
.project-sidebar
.fixed
%aside
= link_to issues_path, :class => current_page?(issues_path) ? "current" : nil do
Issues
- unless current_user.assigned_issues.empty?
%span{ :class => "number" }= current_user.assigned_issues.count
= link_to merge_requests_path, :class => current_page?(merge_requests_path) ? "current" : nil do
Merge Requests
- unless current_user.assigned_merge_requests.empty?
%span{ :class => "number" }= current_user.assigned_merge_requests.count
.project-content
= yield
%a.update-item{:href => project_merge_request_path(@project, merge_request)} %a.update-item{:href => project_merge_request_path(merge_request.project, merge_request)}
= image_tag gravatar_icon(merge_request.author_email), :class => "left", :width => 40 = image_tag gravatar_icon(merge_request.author_email), :class => "left", :width => 40
%span.update-title %span.update-title
= merge_request.title = merge_request.title
%span.update-author %span.update-author
- if not @project.present?
%strong= merge_request.project.name
= '-'
%strong= merge_request.author_name %strong= merge_request.author_name
authored authored
= time_ago_in_words(merge_request.created_at) = time_ago_in_words(merge_request.created_at)
......
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@user.name} issues"
xml.link :href => issues_url(:atom, :private_token => @user.private_token), :rel => "self", :type => "application/atom+xml"
xml.link :href => issues_url(:private_token => @user.private_token), :rel => "alternate", :type => "text/html"
xml.id issues_url(:private_token => @user.private_token)
xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any?
@issues.each do |issue|
xml.entry do
xml.id project_issue_url(issue.project, issue)
xml.link :href => project_issue_url(issue.project, issue)
xml.title truncate(issue.title, :length => 80)
xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(issue.author_email)
xml.author do |author|
xml.name issue.author_name
xml.email issue.author_email
end
xml.summary issue.title
end
end
end
%div#issues-table-holder
%table.round-borders#issues-table
%thead
%th
.top_panel_issues
%h2 Issues assigned to me
= render 'issues/issues'
%br
- if @merge_requests.opened.count > 0
%div{ :class => "update-data ui-box ui-box-small ui-box-big" }
%h3
%span.tag.open Open
.data
= render @merge_requests.opened
.clear
%br
Gitlab::Application.routes.draw do Gitlab::Application.routes.draw do
get "user_issues/index"
get 'tags'=> 'tags#index' get 'tags'=> 'tags#index'
get 'tags/:tag' => 'projects#index' get 'tags/:tag' => 'projects#index'
...@@ -21,6 +23,9 @@ Gitlab::Application.routes.draw do ...@@ -21,6 +23,9 @@ Gitlab::Application.routes.draw do
put "profile/edit", :to => "profile#social_update" put "profile/edit", :to => "profile#social_update"
get "profile", :to => "profile#show" get "profile", :to => "profile#show"
get "dashboard", :to => "dashboard#index" get "dashboard", :to => "dashboard#index"
get "issues", :to => "user_issues#index", :as => "issues"
get "merge_requests", :to => "user_merge_requests#index", :as => "merge_requests"
#get "profile/:id", :to => "profile#show" #get "profile/:id", :to => "profile#show"
resources :projects, :only => [:new, :create, :index] resources :projects, :only => [:new, :create, :index]
......
...@@ -13,18 +13,6 @@ ...@@ -13,18 +13,6 @@
ActiveRecord::Schema.define(:version => 20111207211728) do ActiveRecord::Schema.define(:version => 20111207211728) do
create_table "features", :force => true do |t|
t.string "name"
t.string "branch_name"
t.integer "assignee_id"
t.integer "author_id"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "version"
t.integer "status", :default => 0, :null => false
end
create_table "issues", :force => true do |t| create_table "issues", :force => true do |t|
t.string "title" t.string "title"
t.integer "assignee_id" t.integer "assignee_id"
......
...@@ -6,6 +6,8 @@ describe User do ...@@ -6,6 +6,8 @@ describe User do
it { should have_many(:users_projects) } it { should have_many(:users_projects) }
it { should have_many(:issues) } it { should have_many(:issues) }
it { should have_many(:assigned_issues) } it { should have_many(:assigned_issues) }
it { should have_many(:merge_requests) }
it { should have_many(:assigned_merge_requests) }
end end
describe "Respond to" do describe "Respond to" do
......
require 'spec_helper'
describe "User Issues Dashboard" do
describe "GET /issues" do
before do
login_as :user
@project1 = Factory :project,
:path => "project1",
:code => "TEST1"
@project2 = Factory :project,
:path => "project2",
:code => "TEST2"
@project1.add_access(@user, :read, :write)
@project2.add_access(@user, :read, :write)
@issue1 = Factory :issue,
:author => @user,
:assignee => @user,
:project => @project1
@issue2 = Factory :issue,
:author => @user,
:assignee => @user,
:project => @project2
visit issues_path
end
subject { page }
it { should have_content(@issue1.title) }
it { should have_content(@issue1.project.name) }
it { should have_content(@issue1.assignee.name) }
it { should have_content(@issue2.title) }
it { should have_content(@issue2.project.name) }
it { should have_content(@issue2.assignee.name) }
it "should render atom feed via private token" do
logout
visit issues_path(:atom, :private_token => @user.private_token)
page.response_headers['Content-Type'].should have_content("application/atom+xml")
page.body.should have_selector("title", :text => "#{@user.name} issues")
page.body.should have_selector("author email", :text => @issue1.author_email)
page.body.should have_selector("entry summary", :text => @issue1.title)
page.body.should have_selector("author email", :text => @issue2.author_email)
page.body.should have_selector("entry summary", :text => @issue2.title)
end
end
end
require 'spec_helper'
describe "User MergeRequests" do
describe "GET /issues" do
before do
login_as :user
@project1 = Factory :project,
:path => "project1",
:code => "TEST1"
@project2 = Factory :project,
:path => "project2",
:code => "TEST2"
@project1.add_access(@user, :read, :write)
@project2.add_access(@user, :read, :write)
@merge_request1 = Factory :merge_request,
:author => @user,
:assignee => @user,
:project => @project1
@merge_request2 = Factory :merge_request,
:author => @user,
:assignee => @user,
:project => @project2
visit merge_requests_path
end
subject { page }
it { should have_content(@merge_request1.title) }
it { should have_content(@merge_request1.project.name) }
it { should have_content(@merge_request1.target_branch) }
it { should have_content(@merge_request1.source_branch) }
it { should have_content(@merge_request1.assignee.name) }
it { should have_content(@merge_request2.title) }
it { should have_content(@merge_request2.project.name) }
it { should have_content(@merge_request2.target_branch) }
it { should have_content(@merge_request2.source_branch) }
it { should have_content(@merge_request2.assignee.name) }
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment