Add teams into Public sections

This commit is contained in:
Andrey Kumanyaev 2013-01-19 21:32:09 +04:00 committed by Dmitriy Zaporozhets
parent 82499a4cbf
commit 695becc4cb
14 changed files with 706 additions and 0 deletions

View file

@ -0,0 +1,113 @@
class TeamsController < ApplicationController
respond_to :html
layout 'user_team', only: [:show, :edit, :update, :destroy, :issues, :merge_requests, :search]
before_filter :user_team, only: [:show, :edit, :update, :destroy, :issues, :merge_requests, :search]
before_filter :projects, only: [:show, :edit, :update, :destroy, :issues, :merge_requests, :search]
# Authorize
before_filter :authorize_manage_user_team!, only: [:edit, :update]
before_filter :authorize_admin_user_team!, only: [:destroy]
def index
@teams = UserTeam.all
end
def show
@events = Event.in_projects(project_ids).limit(20).offset(params[:offset] || 0)
respond_to do |format|
format.html
format.js
format.atom { render layout: false }
end
end
def edit
end
def update
if user_team.update_attributes(params[:user_team])
redirect_to team_path(user_team)
else
render action: :edit
end
end
def destroy
user_team.destroy
redirect_to teams_path
end
def new
@team = UserTeam.new
end
def create
@team = UserTeam.new(params[:user_team])
@team.owner = current_user unless params[:owner]
@team.path = @team.name.dup.parameterize if @team.name
if @team.save
redirect_to team_path(@team)
else
render action: :new
end
end
# Get authored or assigned open merge requests
def merge_requests
@merge_requests = MergeRequest.of_user_team(@user_team)
@merge_requests = FilterContext.new(@merge_requests, params).execute
@merge_requests = @merge_requests.recent.page(params[:page]).per(20)
end
# Get only assigned issues
def issues
@issues = Issue.of_user_team(@user_team)
@issues = FilterContext.new(@issues, params).execute
@issues = @issues.recent.page(params[:page]).per(20)
@issues = @issues.includes(:author, :project)
respond_to do |format|
format.html
format.atom { render layout: false }
end
end
def search
result = SearchContext.new(project_ids, params).execute
@projects = result[:projects]
@merge_requests = result[:merge_requests]
@issues = result[:issues]
@wiki_pages = result[:wiki_pages]
end
protected
def user_team
@user_team ||= UserTeam.find_by_path(params[:id])
end
def projects
@projects ||= user_team.projects.sorted_by_activity
end
def project_ids
projects.map(&:id)
end
def authorize_manage_user_team!
unless user_team.present? or can?(current_user, :manage_user_team, user_team)
return render_404
end
end
def authorize_admin_user_team!
unless user_team.owner == current_user || current_user.admin?
return render_404
end
end
end

View file

@ -0,0 +1,33 @@
= form_tag team_filter_path(entity), method: 'get' do
%fieldset.dashboard-search-filter
= search_field_tag "search", params[:search], { placeholder: 'Search', class: 'search-text-input' }
= button_tag type: 'submit', class: 'btn' do
%i.icon-search
%fieldset
%legend Status:
%ul.nav.nav-pills.nav-stacked
%li{class: ("active" if !params[:status])}
= link_to team_filter_path(entity, status: nil) do
Open
%li{class: ("active" if params[:status] == 'closed')}
= link_to team_filter_path(entity, status: 'closed') do
Closed
%li{class: ("active" if params[:status] == 'all')}
= link_to team_filter_path(entity, status: 'all') do
All
%fieldset
%legend Projects:
%ul.nav.nav-pills.nav-stacked
- @projects.each do |project|
- unless entities_per_project(project, entity).zero?
%li{class: ("active" if params[:project_id] == project.id.to_s)}
= link_to team_filter_path(entity, project_id: project.id) do
= project.name_with_namespace
%small.right= entities_per_project(project, entity)
%fieldset
%hr
= link_to "Reset", team_filter_path(entity), class: 'btn right'

View file

@ -0,0 +1,22 @@
.projects_box
%h5.title
Projects
%small
(#{projects.count})
- if can? current_user, :manage_group, @group
%span.right
= link_to new_project_path(namespace_id: @group.id), class: "btn very_small info" do
%i.icon-plus
New Project
%ul.well-list
- if projects.blank?
%p.nothing_here_message This groups has no projects yet
- projects.each do |project|
%li
= link_to project_path(project), class: dom_class(project) do
%strong.well-title= truncate(project.name, length: 25)
%span.arrow
&rarr;
%span.last_activity
%strong Last activity:
%span= project_last_activity(project)

View file

@ -0,0 +1,19 @@
%ul.nav.nav-tabs
= nav_link(path: 'teams#show') do
= link_to team_path(@user_team), class: "activities-tab tab" do
%i.icon-home
Show
= nav_link(controller: [:members]) do
= link_to team_members_path(@user_team), class: "team-tab tab" do
%i.icon-user
Members
= nav_link(controller: [:projects]) do
= link_to team_projects_path(@user_team), class: "team-tab tab" do
%i.icon-briefcase
Projects
- if can? current_user, :manage_user_team, @user_team
= nav_link(path: 'teams#edit', html_options: {class: 'right'}) do
= link_to edit_team_path(@user_team), class: "stat-tab tab " do
%i.icon-edit
Edit

View file

@ -0,0 +1,32 @@
= render "team_head"
%h3.page_title= "Edit Team #{@user_team.name}"
%hr
= form_for @user_team, url: teams_path do |f|
- if @user_team.errors.any?
.alert-message.block-message.error
%span= @user_team.errors.full_messages.first
.clearfix
= f.label :name do
Team name is
.input
= f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left"
.clearfix
= f.label :path do
Team path is
.input
= f.text_field :path, placeholder: "opensource", class: "xxlarge left"
.clearfix
.input.span3.center
= f.submit 'Save team changes', class: "btn primary"
.input.span3.center
= link_to 'Delete team', team_path(@user_team), method: :delete, confirm: "You are shure?", class: "btn danger"
%hr
.padded
%ul
%li Team is kind of directory for several projects
%li All created teams are private
%li People within a team see only projects they have access to
%li All projects of team will be stored in team directory
%li You will be able to move existing projects into team

View file

@ -0,0 +1,37 @@
%h3.page_title
Teams
%small
list of all teams
= link_to 'New Team', new_team_path, class: "btn small right"
%br
= form_tag search_teams_path, method: :get, class: 'form-inline' do
= text_field_tag :name, params[:name], class: "xlarge"
= submit_tag "Search", class: "btn submit primary"
%table.teams_list
%thead
%tr
%th
Name
%i.icon-sort-down
%th Path
%th Projects
%th Members
%th Owner
%th
- @teams.each do |team|
%tr
%td
%strong= link_to team.name, team_path(team)
%td= team.path
%td= link_to team.projects.count, team_projects_path(team)
%td= link_to team.members.count, team_members_path(team)
%td= link_to team.owner.name, team_member_path(team, team.owner)
%td
- if current_user.can?(:manage_user_team, team)
- if team.owner == current_user
= link_to "Destroy", team_path(team), method: :delete, confirm: "You are shure?", class: "danger btn small right"
= link_to "Edit", edit_team_path(team), class: "btn small right"

View file

@ -0,0 +1,25 @@
= render "team_head"
%h3.page_title
Issues
%small (in Team projects assigned to Team members)
%small.right #{@issues.total_count} issues
%hr
.row
.span3
= render 'filter', entity: 'issue'
.span9
- if @issues.any?
- @issues.group_by(&:project).each do |group|
%div.ui-box
- @project = group[0]
%h5.title
= link_to_project @project
%ul.well-list.issues_table
- group[1].each do |issue|
= render(partial: 'issues/show', locals: {issue: issue})
%hr
= paginate @issues, theme: "gitlab"
- else
%p.nothing_here_message Nothing to show here

View file

@ -0,0 +1,24 @@
%h3.page_title
Merge Requests
%small (authored by or assigned to Team members)
%small.right #{@merge_requests.total_count} merge requests
%hr
.row
.span3
= render 'filter', entity: 'merge_request'
.span9
- if @merge_requests.any?
- @merge_requests.group_by(&:project).each do |group|
.ui-box
- @project = group[0]
%h5.title
= link_to_project @project
%ul.well-list
- group[1].each do |merge_request|
= render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
%hr
= paginate @merge_requests, theme: "gitlab"
- else
%h3.nothing_here_message Nothing to show here

View file

@ -0,0 +1,21 @@
%h3.page_title New Team
%hr
= form_for @team, url: teams_path do |f|
- if @team.errors.any?
.alert-message.block-message.error
%span= @team.errors.full_messages.first
.clearfix
= f.label :name do
Team name is
.input
= f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left"
&nbsp;
= f.submit 'Create team', class: "btn primary"
%hr
.padded
%ul
%li Team is kind of directory for several projects
%li All created teams are private
%li People within a team see only projects they have access to
%li All projects of team will be stored in team directory
%li You will be able to move existing projects into team

View file

@ -0,0 +1,11 @@
= render "team_head"
= form_tag search_team_path(@user_team), method: :get, class: 'form-inline' do |f|
.padded
= label_tag :search do
%strong Looking for
.input
= search_field_tag :search, params[:search], placeholder: "issue 143", class: "input-xxlarge search-text-input", id: "dashboard_search"
= submit_tag 'Search', class: "btn primary wide"
- if params[:search].present?
= render 'search/result'

View file

@ -0,0 +1,30 @@
= render "team_head"
.projects
.activities.span8
= link_to dashboard_path, class: 'btn very_small' do
&larr; To dashboard
&nbsp;
%span.cgray Events and projects are filtered in scope of team
%hr
- if @events.any?
.content_list
- else
%p.nothing_here_message Projects activity will be displayed here
.loading.hide
.side.span4
= render "projects", projects: @projects
%div
%span.rss-icon
= link_to dashboard_path(:atom, { private_token: current_user.private_token }) do
= image_tag "rss_ui.png", title: "feed"
%strong News Feed
%hr
.gitlab-promo
= link_to "Homepage", "http://gitlabhq.com"
= link_to "Blog", "http://blog.gitlabhq.com"
= link_to "@gitlabhq", "https://twitter.com/gitlabhq"
:javascript
$(function(){ Pager.init(20, true); });

View file

@ -130,6 +130,20 @@ Gitlab::Application.routes.draw do
end
end
resources :teams do
member do
get :issues
get :merge_requests
get :search
post :delegate_projects
delete :relegate_project
put :update_access
end
collection do
get :search
end
end
resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create]
devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations }

View file

@ -0,0 +1,250 @@
class Userteams < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedProject
When 'I do not have teams with me' do
UserTeam.with_member(current_user).destroy_all
end
Then 'I should see dashboard page without teams info block' do
page.has_no_css?(".teams_box").must_equal true
end
When 'I have teams with my membership' do
team = create :user_team
team.add_member(current_user, UserTeam.access_roles["Master"], true)
end
Then 'I should see dashboard page with teams information block' do
page.should have_css(".teams_box")
end
When 'exist user teams' do
team = create :user_team
team.add_member(current_user, UserTeam.access_roles["Master"], true)
end
And 'I click on "All teams" link' do
click_link("All Teams")
end
Then 'I should see "All teams" page' do
current_path.should == teams_path
end
And 'I should see exist teams in teams list' do
team = UserTeam.last
find_in_list(".teams_list tr", team).must_equal true
end
When 'I click to "New team" link' do
click_link("New Team")
end
And 'I submit form with new team info' do
fill_in 'name', with: 'gitlab'
click_button 'Create team'
end
Then 'I should be redirected to new team page' do
team = UserTeam.last
current_path.should == team_path(team)
end
When 'I have teams with projects and members' do
team = create :user_team
@project = create :project
team.add_member(current_user, UserTeam.access_roles["Master"], true)
team.assign_to_project(@project, UserTeam.access_roles["Master"])
@event = create(:closed_issue_event, project: @project)
end
When 'I visit team page' do
visit team_path(UserTeam.last)
end
Then 'I should see projects list' do
page.should have_css(".projects_box")
projects_box = find(".projects_box")
projects_box.should have_content(@project.name)
end
And 'project from team has issues assigned to me' do
team = UserTeam.last
team.projects.each do |project|
project.issues << create(:issue, assignee: current_user)
end
end
When 'I visit team issues page' do
team = UserTeam.last
visit issues_team_path(team)
end
Then 'I should see issues from this team assigned to me' do
team = UserTeam.last
team.projects.each do |project|
project.issues.assigned(current_user).each do |issue|
page.should have_content issue.title
end
end
end
Given 'I have team with projects and members' do
team = create :user_team
project = create :project
user = create :user
team.add_member(current_user, UserTeam.access_roles["Master"], true)
team.add_member(user, UserTeam.access_roles["Developer"], false)
team.assign_to_project(project, UserTeam.access_roles["Master"])
end
Given 'project from team has issues assigned to teams members' do
team = UserTeam.last
team.projects.each do |project|
team.members.each do |member|
project.issues << create(:issue, assignee: member)
end
end
end
Then 'I should see issues from this team assigned to teams members' do
team = UserTeam.last
team.projects.each do |project|
team.members.each do |member|
project.issues.assigned(member).each do |issue|
page.should have_content issue.title
end
end
end
end
Given 'project from team has merge requests assigned to me' do
team = UserTeam.last
team.projects.each do |project|
team.members.each do |member|
3.times { project.merge_requests << create(:merge_request, assignee: member) }
end
end
end
When 'I visit team merge requests page' do
team = UserTeam.last
visit merge_requests_team_path(team)
end
Then 'I should see merge requests from this team assigned to me' do
team = UserTeam.last
team.projects.each do |project|
team.members.each do |member|
project.issues.assigned(member).each do |merge_request|
page.should have_content merge_request.title
end
end
end
end
Given 'project from team has merge requests assigned to team members' do
team = UserTeam.last
team.projects.each do |project|
team.members.each do |member|
3.times { project.merge_requests << create(:merge_request, assignee: member) }
end
end
end
Then 'I should see merge requests from this team assigned to me' do
team = UserTeam.last
team.projects.each do |project|
team.members.each do |member|
project.issues.assigned(member).each do |merge_request|
page.should have_content merge_request.title
end
end
end
end
Given 'I have new user "John"' do
create :user, name: "John"
end
When 'I visit team people page' do
team = UserTeam.last
visit team_members_path(team)
end
And 'I select user "John" from list with role "Reporter"' do
pending 'step not implemented'
end
Then 'I should see user "John" in team list' do
user = User.find_by_name("John")
team_members_list = find(".team-table")
team_members_list.should have_content user.name
end
And 'I have my own project without teams' do
project = create :project, creator: current_user
end
And 'I visit my team page' do
team = UserTeam.last
visit team_path(team)
end
When 'I click on link "Projects"' do
click_link "Projects"
end
Then 'I should see form with my own project in avaliable projects list' do
project = current_user.projects.first
projects_select = find("#project_ids")
projects_select.should have_content(project.name)
end
When 'I submit form with selected project and max access' do
project = current_user.projects.first
within "#team_projects" do
select project.name, :from => "project_ids"
select "Reporter", :from => "greatest_project_access"
end
click_button "Add"
end
Then 'I should see my own project in team projects list' do
project = current_user.projects.first
projects = all("table .project")
projects.each do |project_row|
project_row.should have_content(project.name)
end
end
When 'I click link "New Team Member"' do
click_link "New Team Member"
end
protected
def current_team
@user_team ||= Team.first
end
def project
current_team.projects.first
end
def assigned_to_user key, user
project.send(key).where(assignee_id: user)
end
def find_in_list(selector, item)
members_list = all(selector)
entered = false
members_list.each do |member_item|
entered = true if member_item.has_content?(item.name)
end
entered
end
end

View file

@ -0,0 +1,75 @@
Feature: UserTeams
Background:
Given I sign in as a user
And I own project "Shop"
And project "Shop" has push event
Scenario: No teams, no dashboard info block
When I do not have teams with me
And I visit dashboard page
Then I should see dashboard page without teams info block
Scenario: I should see teams info block
When I have teams with my membership
And I visit dashboard page
Then I should see dashboard page with teams information block
Scenario: I should see all teams list
When exist user teams
And I visit dashboard page
And I click on "All teams" link
Then I should see "All teams" page
And I should see exist teams in teams list
Scenario: I should can create new team
When I have teams with my membership
And I visit dashboard page
When I click to "New team" link
And I submit form with new team info
Then I should be redirected to new team page
Scenario: I should see team dashboard list
When I have teams with projects and members
When I visit team page
Then I should see projects list
Scenario: I should see team issues list
Given I have team with projects and members
And project from team has issues assigned to me
When I visit team issues page
Then I should see issues from this team assigned to me
Scenario: I should see teams members issues list
Given I have team with projects and members
Given project from team has issues assigned to teams members
When I visit team issues page
Then I should see issues from this team assigned to teams members
Scenario: I should see team merge requests list
Given I have team with projects and members
Given project from team has merge requests assigned to me
When I visit team merge requests page
Then I should see merge requests from this team assigned to me
Scenario: I should see teams members merge requests list
Given I have team with projects and members
Given project from team has merge requests assigned to team members
When I visit team merge requests page
Then I should see merge requests from this team assigned to me
Scenario: I should add user to projects in Team
Given I have team with projects and members
Given I have new user "John"
When I visit team people page
When I click link "New Team Member"
And I select user "John" from list with role "Reporter"
Then I should see user "John" in team list
Scenario: I should assign my team to my own project
Given I have team with projects and members
And I have my own project without teams
And I visit my team page
When I click on link "Projects"
Then I should see form with my own project in avaliable projects list
When I submit form with selected project and max access
Then I should see my own project in team projects list