Remove all team resources except models. Move models to deprecated directory
This commit is contained in:
parent
670aaaeb9d
commit
439f399bec
60 changed files with 1 additions and 2419 deletions
|
@ -1,11 +0,0 @@
|
|||
# Provides a base class for Admin controllers to subclass
|
||||
#
|
||||
# Automatically sets the layout and ensures an administrator is logged in
|
||||
class Admin::Teams::ApplicationController < Admin::ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def user_team
|
||||
@team = UserTeam.find_by_path(params[:team_id])
|
||||
end
|
||||
end
|
|
@ -1,40 +0,0 @@
|
|||
class Admin::Teams::MembersController < Admin::Teams::ApplicationController
|
||||
def new
|
||||
@users = User.potential_team_members(user_team)
|
||||
end
|
||||
|
||||
def create
|
||||
unless params[:user_ids].blank?
|
||||
user_ids = params[:user_ids]
|
||||
access = params[:default_project_access]
|
||||
is_admin = params[:group_admin]
|
||||
user_team.add_members(user_ids, access, is_admin)
|
||||
end
|
||||
|
||||
redirect_to admin_team_path(user_team), notice: 'Members were successfully added into Team of users.'
|
||||
end
|
||||
|
||||
def edit
|
||||
team_member
|
||||
end
|
||||
|
||||
def update
|
||||
options = {default_projects_access: params[:default_project_access], group_admin: params[:group_admin]}
|
||||
if user_team.update_membership(team_member, options)
|
||||
redirect_to admin_team_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users."
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
user_team.remove_member(team_member)
|
||||
redirect_to admin_team_path(user_team), notice: "Member #{team_member.name} was successfully removed from Team of users."
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def team_member
|
||||
@member ||= user_team.members.find_by_username(params[:id])
|
||||
end
|
||||
end
|
|
@ -1,41 +0,0 @@
|
|||
class Admin::Teams::ProjectsController < Admin::Teams::ApplicationController
|
||||
def new
|
||||
@projects = Project.scoped
|
||||
@projects = @projects.without_team(user_team) if user_team.projects.any?
|
||||
#@projects.reject!(&:empty_repo?)
|
||||
end
|
||||
|
||||
def create
|
||||
unless params[:project_ids].blank?
|
||||
project_ids = params[:project_ids]
|
||||
access = params[:greatest_project_access]
|
||||
user_team.assign_to_projects(project_ids, access)
|
||||
end
|
||||
|
||||
redirect_to admin_team_path(user_team), notice: 'Team of users was successfully assgned to projects.'
|
||||
end
|
||||
|
||||
def edit
|
||||
team_project
|
||||
end
|
||||
|
||||
def update
|
||||
if user_team.update_project_access(team_project, params[:greatest_project_access])
|
||||
redirect_to admin_team_path(user_team), notice: 'Access was successfully updated.'
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
user_team.resign_from_project(team_project)
|
||||
redirect_to admin_team_path(user_team), notice: 'Team of users was successfully reassigned from project.'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def team_project
|
||||
@project ||= user_team.projects.find_with_namespace(params[:id])
|
||||
end
|
||||
|
||||
end
|
|
@ -1,59 +0,0 @@
|
|||
class Admin::TeamsController < Admin::ApplicationController
|
||||
def index
|
||||
@teams = UserTeam.order('name ASC')
|
||||
@teams = @teams.search(params[:name]) if params[:name].present?
|
||||
@teams = @teams.page(params[:page]).per(20)
|
||||
end
|
||||
|
||||
def show
|
||||
user_team
|
||||
end
|
||||
|
||||
def new
|
||||
@team = UserTeam.new
|
||||
end
|
||||
|
||||
def edit
|
||||
user_team
|
||||
end
|
||||
|
||||
def create
|
||||
@team = UserTeam.new(params[:user_team])
|
||||
@team.path = @team.name.dup.parameterize if @team.name
|
||||
@team.owner = current_user
|
||||
|
||||
if @team.save
|
||||
redirect_to admin_team_path(@team), notice: 'Team of users was successfully created.'
|
||||
else
|
||||
render action: "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
user_team_params = params[:user_team].dup
|
||||
owner_id = user_team_params.delete(:owner_id)
|
||||
|
||||
if owner_id
|
||||
user_team.owner = User.find(owner_id)
|
||||
end
|
||||
|
||||
if user_team.update_attributes(user_team_params)
|
||||
redirect_to admin_team_path(user_team), notice: 'Team of users was successfully updated.'
|
||||
else
|
||||
render action: "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
user_team.destroy
|
||||
|
||||
redirect_to admin_teams_path, notice: 'Team of users was successfully deleted.'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def user_team
|
||||
@team ||= UserTeam.find_by_path(params[:id])
|
||||
end
|
||||
|
||||
end
|
|
@ -7,7 +7,6 @@ class DashboardController < ApplicationController
|
|||
def show
|
||||
@groups = current_user.authorized_groups.sort_by(&:human_name)
|
||||
@has_authorized_projects = @projects.count > 0
|
||||
@teams = current_user.authorized_teams
|
||||
@projects_count = @projects.count
|
||||
@projects = @projects.limit(20)
|
||||
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
class Projects::TeamsController < Projects::ApplicationController
|
||||
|
||||
before_filter :authorize_admin_team_member!
|
||||
|
||||
def available
|
||||
@teams = current_user.is_admin? ? UserTeam.scoped : current_user.user_teams
|
||||
@teams = @teams.without_project(project)
|
||||
unless @teams.any?
|
||||
redirect_to project_team_index_path(project), notice: "No available teams for assigment."
|
||||
end
|
||||
end
|
||||
|
||||
def assign
|
||||
unless params[:team_id].blank?
|
||||
team = UserTeam.find(params[:team_id])
|
||||
access = params[:greatest_project_access]
|
||||
team.assign_to_project(project, access)
|
||||
end
|
||||
redirect_to project_team_index_path(project)
|
||||
end
|
||||
|
||||
def resign
|
||||
team = project.user_teams.find_by_path(params[:id])
|
||||
team.resign_from_project(project)
|
||||
|
||||
redirect_to project_team_index_path(project)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def user_team
|
||||
@team ||= UserTeam.find_by_path(params[:id])
|
||||
end
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
class Teams::ApplicationController < ApplicationController
|
||||
|
||||
layout 'user_team'
|
||||
|
||||
before_filter :authorize_manage_user_team!
|
||||
|
||||
protected
|
||||
|
||||
def user_team
|
||||
@team ||= UserTeam.find_by_path(params[:team_id])
|
||||
end
|
||||
|
||||
end
|
|
@ -1,53 +0,0 @@
|
|||
class Teams::MembersController < Teams::ApplicationController
|
||||
|
||||
skip_before_filter :authorize_manage_user_team!, only: [:index]
|
||||
|
||||
def index
|
||||
@members = user_team.members
|
||||
end
|
||||
|
||||
def new
|
||||
@users = User.potential_team_members(user_team)
|
||||
end
|
||||
|
||||
def create
|
||||
unless params[:user_ids].blank?
|
||||
user_ids = params[:user_ids].split(',')
|
||||
access = params[:default_project_access]
|
||||
is_admin = params[:group_admin]
|
||||
user_team.add_members(user_ids, access, is_admin)
|
||||
end
|
||||
|
||||
redirect_to team_members_path(user_team), notice: 'Members were successfully added into Team of users.'
|
||||
end
|
||||
|
||||
def edit
|
||||
team_member
|
||||
end
|
||||
|
||||
def update
|
||||
member_params = params[:team_member]
|
||||
|
||||
options = {
|
||||
default_projects_access: member_params[:permission],
|
||||
group_admin: member_params[:group_admin]
|
||||
}
|
||||
|
||||
if user_team.update_membership(team_member, options)
|
||||
redirect_to team_members_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users."
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
user_team.remove_member(team_member)
|
||||
redirect_to team_path(user_team), notice: "Member #{team_member.name} was successfully removed from Team of users."
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def team_member
|
||||
@member ||= user_team.members.find_by_username(params[:id])
|
||||
end
|
||||
end
|
|
@ -1,40 +0,0 @@
|
|||
class Teams::ProjectsController < Teams::ApplicationController
|
||||
def create
|
||||
redirect_to :back if params[:project_ids].blank?
|
||||
|
||||
project_ids = params[:project_ids]
|
||||
access = params[:greatest_project_access]
|
||||
|
||||
# Reject non-allowed projects
|
||||
allowed_project_ids = current_user.owned_projects.map(&:id)
|
||||
project_ids.select! { |id| allowed_project_ids.include?(id.to_i) }
|
||||
|
||||
# Assign projects to team
|
||||
user_team.assign_to_projects(project_ids, access)
|
||||
|
||||
redirect_to edit_team_path(user_team), notice: 'Team of users was successfully assigned to projects.'
|
||||
end
|
||||
|
||||
def edit
|
||||
team_project
|
||||
end
|
||||
|
||||
def update
|
||||
if user_team.update_project_access(team_project, params[:greatest_project_access])
|
||||
redirect_to edit_team_path(user_team), notice: 'Access was successfully updated.'
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
user_team.resign_from_project(team_project)
|
||||
redirect_to team_projects_path(user_team), notice: 'Team of users was successfully reassigned from project.'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def team_project
|
||||
@project ||= user_team.projects.find_with_namespace(params[:id])
|
||||
end
|
||||
end
|
|
@ -1,93 +0,0 @@
|
|||
class TeamsController < ApplicationController
|
||||
# Authorize
|
||||
before_filter :authorize_create_team!, only: [:new, :create]
|
||||
before_filter :authorize_manage_user_team!, only: [:edit, :update]
|
||||
before_filter :authorize_admin_user_team!, only: [:destroy]
|
||||
|
||||
before_filter :user_team, except: [:new, :create]
|
||||
|
||||
layout :determine_layout
|
||||
|
||||
before_filter :set_title, only: [:new, :create]
|
||||
|
||||
def show
|
||||
projects
|
||||
@events = Event.in_projects(user_team.project_ids).limit(20).offset(params[:offset] || 0)
|
||||
end
|
||||
|
||||
def edit
|
||||
projects
|
||||
@avaliable_projects = current_user.owned_projects.without_team(user_team)
|
||||
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 dashboard_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
|
||||
# Add current user as Master to the team
|
||||
@team.add_members([current_user.id], UsersProject::MASTER, true)
|
||||
|
||||
redirect_to team_path(@team)
|
||||
else
|
||||
render action: :new
|
||||
end
|
||||
end
|
||||
|
||||
# Get authored or assigned open merge requests
|
||||
def merge_requests
|
||||
projects
|
||||
@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
|
||||
projects
|
||||
@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)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def projects
|
||||
@projects ||= user_team.projects.sorted_by_activity
|
||||
end
|
||||
|
||||
def user_team
|
||||
@team ||= current_user.authorized_teams.find_by_path(params[:id])
|
||||
end
|
||||
|
||||
def set_title
|
||||
@title = 'New Team'
|
||||
end
|
||||
|
||||
def determine_layout
|
||||
if [:new, :create].include?(action_name.to_sym)
|
||||
'navless'
|
||||
else
|
||||
'user_team'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -92,7 +92,6 @@ module ApplicationHelper
|
|||
def search_autocomplete_source
|
||||
projects = current_user.authorized_projects.map { |p| { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } }
|
||||
groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } }
|
||||
teams = current_user.authorized_teams.map { |team| { label: "team: #{simple_sanitize(team.name)}", url: team_path(team) } }
|
||||
|
||||
default_nav = [
|
||||
{ label: "My Profile", url: profile_path },
|
||||
|
@ -128,7 +127,7 @@ module ApplicationHelper
|
|||
]
|
||||
end
|
||||
|
||||
[groups, teams, projects, default_nav, project_nav, help_nav].flatten.to_json
|
||||
[groups, projects, default_nav, project_nav, help_nav].flatten.to_json
|
||||
end
|
||||
|
||||
def emoji_autocomplete_source
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
module UserTeamsHelper
|
||||
def team_filter_path(entity, options={})
|
||||
exist_opts = {
|
||||
status: params[:status],
|
||||
project_id: params[:project_id],
|
||||
}
|
||||
|
||||
options = exist_opts.merge(options)
|
||||
|
||||
case entity
|
||||
when 'issue' then
|
||||
issues_team_path(@team, options)
|
||||
when 'merge_request'
|
||||
merge_requests_team_path(@team, options)
|
||||
end
|
||||
end
|
||||
|
||||
def grouped_user_team_members(team)
|
||||
team.user_team_user_relationships.sort_by(&:permission).reverse.group_by(&:permission)
|
||||
end
|
||||
|
||||
def remove_from_user_team_message(team, member)
|
||||
"You are going to remove #{member.name} from #{team.name}. Are you sure?"
|
||||
end
|
||||
end
|
|
@ -11,7 +11,6 @@ class Ability
|
|||
when "PersonalSnippet" then personal_snippet_abilities(user, subject)
|
||||
when "MergeRequest" then merge_request_abilities(user, subject)
|
||||
when "Group", "Namespace" then group_abilities(user, subject)
|
||||
when "UserTeam" then user_team_abilities(user, subject)
|
||||
else []
|
||||
end.concat(global_abilities(user))
|
||||
end
|
||||
|
@ -19,7 +18,6 @@ class Ability
|
|||
def global_abilities(user)
|
||||
rules = []
|
||||
rules << :create_group if user.can_create_group
|
||||
rules << :create_team if user.can_create_team
|
||||
rules
|
||||
end
|
||||
|
||||
|
@ -146,21 +144,6 @@ class Ability
|
|||
rules.flatten
|
||||
end
|
||||
|
||||
def user_team_abilities user, team
|
||||
rules = []
|
||||
|
||||
# Only group owner and administrators can manage team
|
||||
if user.admin? || team.owner == user || team.admin?(user)
|
||||
rules << [ :manage_user_team ]
|
||||
end
|
||||
|
||||
if team.owner == user || user.admin?
|
||||
rules << [ :admin_user_team ]
|
||||
end
|
||||
|
||||
rules.flatten
|
||||
end
|
||||
|
||||
[:issue, :note, :project_snippet, :personal_snippet, :merge_request].each do |name|
|
||||
define_method "#{name}_abilities" do |user, subject|
|
||||
if subject.author == user
|
||||
|
|
|
@ -75,13 +75,6 @@ class User < ActiveRecord::Base
|
|||
has_many :users_groups, dependent: :destroy
|
||||
has_many :groups, through: :users_groups
|
||||
|
||||
# Teams
|
||||
has_many :own_teams, dependent: :destroy, class_name: "UserTeam", foreign_key: :owner_id
|
||||
has_many :user_team_user_relationships, dependent: :destroy
|
||||
has_many :user_teams, through: :user_team_user_relationships
|
||||
has_many :user_team_project_relationships, through: :user_teams
|
||||
has_many :team_projects, through: :user_team_project_relationships
|
||||
|
||||
# Projects
|
||||
has_many :snippets, dependent: :destroy, foreign_key: :author_id, class_name: "Snippet"
|
||||
has_many :users_projects, dependent: :destroy
|
||||
|
@ -235,10 +228,6 @@ class User < ActiveRecord::Base
|
|||
own_groups
|
||||
end
|
||||
|
||||
def owned_teams
|
||||
own_teams
|
||||
end
|
||||
|
||||
# Groups user has access to
|
||||
def authorized_groups
|
||||
@group_ids ||= (groups.pluck(:id) + own_groups.pluck(:id) + authorized_projects.pluck(:namespace_id))
|
||||
|
@ -252,15 +241,6 @@ class User < ActiveRecord::Base
|
|||
Project.where(id: @project_ids)
|
||||
end
|
||||
|
||||
def authorized_teams
|
||||
if admin?
|
||||
UserTeam.scoped
|
||||
else
|
||||
@team_ids ||= (user_teams.pluck(:id) + own_teams.pluck(:id)).uniq
|
||||
UserTeam.where(id: @team_ids)
|
||||
end
|
||||
end
|
||||
|
||||
# Team membership in authorized projects
|
||||
def tm_in_authorized_projects
|
||||
UsersProject.where(project_id: authorized_projects.map(&:id), user_id: self.id)
|
||||
|
|
|
@ -49,10 +49,6 @@
|
|||
.span4
|
||||
%h4 Stats
|
||||
%hr
|
||||
%p
|
||||
Teams
|
||||
%span.light.pull-right
|
||||
= UserTeam.count
|
||||
%p
|
||||
Forks
|
||||
%span.light.pull-right
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
%h3.page_title Edit Team
|
||||
%hr
|
||||
= form_for @team, url: admin_team_path(@team), method: :put do |f|
|
||||
- if @team.errors.any?
|
||||
.alert.alert-error
|
||||
%span= @team.errors.full_messages.first
|
||||
.clearfix.team_name_holder
|
||||
= f.label :name do
|
||||
Team name is
|
||||
.input
|
||||
= f.text_field :name, placeholder: "Example Team", class: "xxlarge"
|
||||
|
||||
.clearfix.team-description-holder
|
||||
= f.label :description, "Details"
|
||||
.input
|
||||
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
|
||||
|
||||
.clearfix.team_name_holder
|
||||
= f.label :path do
|
||||
%span.cred Team path is
|
||||
.input
|
||||
= f.text_field :path, placeholder: "example-team", class: "xxlarge danger"
|
||||
%ul.cred
|
||||
%li It will change web url for access team and team projects.
|
||||
|
||||
.form-actions
|
||||
= f.submit 'Edit team', class: "btn btn-remove"
|
||||
= link_to 'Cancel', admin_teams_path, class: "btn btn-cancel"
|
|
@ -1,48 +0,0 @@
|
|||
%h3.page_title
|
||||
Teams (#{@teams.total_count})
|
||||
%small
|
||||
allow you to organize groups of people that have a common focus. Use teams to simplify the process of assigning roles to groups of people.
|
||||
|
||||
= link_to 'New Team', new_admin_team_path, class: "btn btn-small pull-right"
|
||||
%br
|
||||
|
||||
= form_tag admin_teams_path, method: :get, class: 'form-inline' do
|
||||
= text_field_tag :name, params[:name], class: "span6"
|
||||
= submit_tag "Search", class: "btn submit btn-primary"
|
||||
|
||||
%hr
|
||||
|
||||
%ul.bordered-list
|
||||
- @teams.each do |team|
|
||||
%li
|
||||
.clearfix
|
||||
.pull-right.prepend-top-10
|
||||
= link_to 'Edit', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn btn-small"
|
||||
= link_to 'Destroy', admin_team_path(team), confirm: "REMOVE #{team.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove"
|
||||
|
||||
%h4
|
||||
= link_to admin_team_path(team) do
|
||||
%i.icon-group
|
||||
= team.name
|
||||
|
||||
.clearfix.light.append-bottom-10
|
||||
%span
|
||||
%b Owner:
|
||||
- if team.owner
|
||||
= link_to team.owner.name, admin_user_path(team.owner)
|
||||
- else
|
||||
(deleted)
|
||||
\|
|
||||
%span
|
||||
%b Users:
|
||||
%span.badge= team.members.count
|
||||
\|
|
||||
%span
|
||||
%b Projects:
|
||||
%span.badge= team.projects.count
|
||||
|
||||
.clearfix
|
||||
%p
|
||||
= truncate team.description, length: 150
|
||||
|
||||
= paginate @teams, theme: "gitlab"
|
|
@ -1,20 +0,0 @@
|
|||
= form_tag admin_team_member_path(@team, @member), method: :put do
|
||||
-if @member.errors.any?
|
||||
.alert.alert-error
|
||||
%ul
|
||||
- @member.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.clearfix
|
||||
%label Default access for Team projects:
|
||||
.input
|
||||
= select_tag :default_project_access, options_for_select(UserTeam.access_roles, @team.default_projects_access(@member)), class: "project-access-select chosen span3"
|
||||
.clearfix
|
||||
%label Team admin?
|
||||
.input
|
||||
= check_box_tag :group_admin, true, @team.admin?(@member)
|
||||
|
||||
%br
|
||||
.actions
|
||||
= submit_tag 'Save', class: "btn btn-primary"
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -1,16 +0,0 @@
|
|||
%h3
|
||||
Edit access #{@member.name} in #{@team.name} team
|
||||
|
||||
%hr
|
||||
%table.zebra-striped
|
||||
%tr
|
||||
%td User:
|
||||
%td= @member.name
|
||||
%tr
|
||||
%td Team:
|
||||
%td= @team.name
|
||||
%tr
|
||||
%td Since:
|
||||
%td= member_since(@team, @member).stamp("Nov 11, 2010")
|
||||
|
||||
= render 'form'
|
|
@ -1,27 +0,0 @@
|
|||
%h3.page_title
|
||||
New members for
|
||||
= link_to @team.name, admin_team_path(@team)
|
||||
team
|
||||
%hr
|
||||
= form_tag admin_team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do
|
||||
- if @team.errors.any?
|
||||
.alert.alert-error
|
||||
%span= @team.errors.full_messages.first
|
||||
.clearfix
|
||||
= label_tag :user_ids do
|
||||
Users to add
|
||||
.input
|
||||
= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name_with_username), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5'
|
||||
.clearfix.group-description-holder
|
||||
= label_tag :default_project_access do
|
||||
Default permission in projects
|
||||
.input
|
||||
= select_tag :default_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" }
|
||||
.clearfix
|
||||
= label_tag :group_admin do
|
||||
Is team admin
|
||||
.input
|
||||
= check_box_tag :group_admin
|
||||
.clearfix.form-actions
|
||||
= submit_tag 'Add users into team', class: "btn btn-primary", id: :add_members_to_team
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -1,26 +0,0 @@
|
|||
%h3.page_title New Team
|
||||
%hr
|
||||
= form_for @team, url: admin_teams_path do |f|
|
||||
- if @team.errors.any?
|
||||
.alert.alert-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"
|
||||
|
||||
.clearfix.team-description-holder
|
||||
= f.label :description, "Details"
|
||||
.input
|
||||
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
|
||||
|
||||
.form-actions
|
||||
= f.submit 'Create team', class: "btn btn-create"
|
||||
|
||||
%hr
|
||||
.padded
|
||||
%ul
|
||||
%li All created teams are public (users can view who enter into team and which project are assigned for this team)
|
||||
%li People within a team see only projects they have access to
|
||||
%li You will be able to assign existing projects for team
|
|
@ -1,16 +0,0 @@
|
|||
= form_tag admin_team_project_path(@team, @project), method: :put do
|
||||
-if @project.errors.any?
|
||||
.alert.alert-error
|
||||
%ul
|
||||
- @project.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.clearfix
|
||||
%label Max access for Team members:
|
||||
.input
|
||||
= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles, @team.max_project_access(@project)), class: "project-access-select chosen span3"
|
||||
|
||||
%br
|
||||
.actions
|
||||
= submit_tag 'Save', class: "btn btn-primary"
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -1,16 +0,0 @@
|
|||
%h3
|
||||
Edit max access in #{@project.name} for #{@team.name} team
|
||||
|
||||
%hr
|
||||
%table.zebra-striped
|
||||
%tr
|
||||
%td Project:
|
||||
%td= @project.name
|
||||
%tr
|
||||
%td Team:
|
||||
%td= @team.name
|
||||
%tr
|
||||
%td Since:
|
||||
%td= assigned_since(@team, @project).stamp("Nov 11, 2010")
|
||||
|
||||
= render 'form'
|
|
@ -1,18 +0,0 @@
|
|||
%h3.page_title
|
||||
Team: #{@team.name}
|
||||
%hr
|
||||
= form_tag admin_team_projects_path(@team), id: "assign_projects", class: "bulk_import", method: :post do
|
||||
%h6 Choose Projects you want to assign:
|
||||
.clearfix
|
||||
= label_tag :project_ids, "Projects"
|
||||
.input
|
||||
= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
|
||||
|
||||
%h6 Choose greatest user acces for your team in this projects:
|
||||
.clearfix
|
||||
= label_tag :greatest_project_access, "Greatest Access"
|
||||
.input
|
||||
= select_tag :greatest_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" }
|
||||
|
||||
.form-actions
|
||||
= submit_tag 'Add team to projects', class: "btn btn-create", id: :assign_projects_to_team
|
|
@ -1,96 +0,0 @@
|
|||
%h3.page_title
|
||||
Team: #{@team.name}
|
||||
|
||||
|
||||
= link_to edit_admin_team_path(@team), class: "btn btn-small pull-right" do
|
||||
%i.icon-edit
|
||||
Edit
|
||||
%hr
|
||||
|
||||
|
||||
.row
|
||||
.span6
|
||||
.ui-box
|
||||
%h5.title
|
||||
Team info:
|
||||
%ul.well-list
|
||||
%li
|
||||
%span.light Name:
|
||||
%strong= @team.name
|
||||
%li
|
||||
%span.light Path:
|
||||
%strong
|
||||
= @team.path
|
||||
|
||||
%li
|
||||
%span.light Description:
|
||||
%strong
|
||||
= @team.description
|
||||
|
||||
%li
|
||||
%span.light Owned by:
|
||||
%strong
|
||||
- if @team.owner
|
||||
= link_to @team.owner.name, admin_user_path(@team.owner)
|
||||
- else
|
||||
(deleted)
|
||||
.pull-right
|
||||
= link_to "#", class: "btn btn-small change-owner-link" do
|
||||
%i.icon-edit
|
||||
Change owner
|
||||
%li.change-owner-holder.hide.bgred
|
||||
.form-holder
|
||||
%strong.cred New Owner:
|
||||
= form_for @team, url: admin_team_path(@team) do |f|
|
||||
= users_select_tag(:"user_team[owner_id]")
|
||||
.prepend-top-10
|
||||
= f.submit 'Change Owner', class: "btn btn-remove"
|
||||
= link_to "Cancel", "#", class: "btn change-owner-cancel-link"
|
||||
|
||||
%li
|
||||
%span.light Created at:
|
||||
%strong
|
||||
= @team.created_at.stamp("March 1, 1999")
|
||||
|
||||
.span6
|
||||
.ui-box
|
||||
%h5.title
|
||||
Members (#{@team.members.count})
|
||||
.pull-right
|
||||
= link_to 'Add members', new_admin_team_member_path(@team), class: "btn btn-small", id: :add_members_to_team
|
||||
%ul.well-list#members_list
|
||||
- @team.members.each do |member|
|
||||
%li.member{ class: "user_#{member.id}"}
|
||||
= link_to [:admin, member] do
|
||||
%strong
|
||||
= member.name
|
||||
.pull-right
|
||||
%span.light
|
||||
= @team.human_default_projects_access(member)
|
||||
- if @team.admin?(member)
|
||||
%span.label.label-info Admin
|
||||
|
||||
= link_to 'Edit', edit_admin_team_member_path(@team, member), class: "btn btn-small"
|
||||
|
||||
= link_to 'Remove', admin_team_member_path(@team, member), confirm: 'Remove member from team. Are you sure?', method: :delete, class: "btn btn-remove btn-small", id: "remove_member_#{member.id}"
|
||||
|
||||
|
||||
.ui-box
|
||||
%h5.title
|
||||
Projects (#{@team.projects.count})
|
||||
.pull-right
|
||||
= link_to 'Add projects', new_admin_team_project_path(@team), class: "btn btn-small", id: :assign_projects_to_team
|
||||
%ul.well-list#projects_list
|
||||
- @team.projects.each do |project|
|
||||
%li.project
|
||||
= link_to [:admin, project] do
|
||||
%strong
|
||||
= project.name_with_namespace
|
||||
|
||||
.pull-right
|
||||
%span.light
|
||||
= @team.human_max_project_access(project)
|
||||
|
||||
= link_to 'Edit', edit_admin_team_project_path(@team, project), class: "btn btn-small"
|
||||
|
||||
= link_to 'Relegate', admin_team_project_path(@team, project), confirm: 'Remove project from team. Are you sure?', method: :delete, class: "btn btn-remove small", id: "relegate_project_#{project.id}"
|
|
@ -93,13 +93,6 @@
|
|||
%li
|
||||
%strong= link_to group.name, admin_group_path(group)
|
||||
|
||||
- if @admin_user.owned_teams.present?
|
||||
.ui-box
|
||||
%h5.title Owned teams:
|
||||
%ul.well-list
|
||||
- @admin_user.owned_teams.each do |team|
|
||||
%li
|
||||
%strong= link_to team.name, admin_team_path(team)
|
||||
|
||||
|
||||
.span6
|
||||
|
|
|
@ -3,16 +3,12 @@
|
|||
= link_to 'Projects', '#projects', 'data-toggle' => 'tab', id: 'sidebar-projects-tab'
|
||||
%li
|
||||
= link_to 'Groups', '#groups', 'data-toggle' => 'tab', id: 'sidebar-groups-tab'
|
||||
%li
|
||||
= link_to 'Teams', '#teams', 'data-toggle' => 'tab', id: 'sidebar-teams-tab'
|
||||
|
||||
.tab-content
|
||||
.tab-pane.active#projects
|
||||
= render "projects", projects: @projects
|
||||
.tab-pane#groups
|
||||
= render "groups", groups: @groups
|
||||
.tab-pane#teams
|
||||
= render "teams", teams: @teams
|
||||
|
||||
.prepend-top-20
|
||||
%span.rss-icon
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
%i.icon-home
|
||||
= nav_link(controller: :projects) do
|
||||
= link_to "Projects", admin_projects_path
|
||||
= nav_link(controller: :teams) do
|
||||
= link_to "Teams", admin_teams_path
|
||||
= nav_link(controller: :groups) do
|
||||
= link_to "Groups", admin_groups_path
|
||||
= nav_link(controller: :users) do
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
= render "projects/settings_nav"
|
||||
|
||||
%h3.page_title
|
||||
= "Assign project to team of users"
|
||||
%hr
|
||||
%p.slead
|
||||
Read more about assign to team of users #{link_to "here", '#', class: 'vlink'}.
|
||||
= form_tag assign_project_teams_path(@project), method: 'post' do
|
||||
%p.slead Choose Team of users you want to assign:
|
||||
.padded
|
||||
= label_tag :team_id, "Team"
|
||||
.input= select_tag(:team_id, options_from_collection_for_select(@teams, :id, :name), prompt: "Select team", class: "chosen xxlarge", required: true)
|
||||
%p.slead Choose greatest user acces in team you want to assign:
|
||||
.padded
|
||||
= label_tag :team_ids, "Permission"
|
||||
.input= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles), {class: "project-access-select chosen span3" }
|
||||
|
||||
|
||||
.actions
|
||||
= submit_tag 'Assign', class: "btn btn-create"
|
||||
= link_to "Cancel", project_team_index_path(@project), class: "btn btn-cancel"
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
= 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.pull-right= entities_per_project(project, entity)
|
||||
|
||||
%fieldset
|
||||
%hr
|
||||
= link_to "Reset", team_filter_path(entity), class: 'btn pull-right'
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
.ui-box
|
||||
%h5.title
|
||||
Projects
|
||||
%small
|
||||
(#{projects.count})
|
||||
- if can? current_user, :manage_user_team, @team
|
||||
%span.pull-right
|
||||
= link_to edit_team_path(@team), class: "btn btn-tiny info" do
|
||||
%i.icon-plus
|
||||
Assign Project
|
||||
%ul.well-list
|
||||
- if projects.blank?
|
||||
%p.nothing_here_message This team 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_with_namespace, length: 40)
|
||||
%span.arrow
|
||||
→
|
||||
%span.last_activity
|
||||
%strong Last activity:
|
||||
%span= project_last_activity(project)
|
|
@ -1,74 +0,0 @@
|
|||
.row
|
||||
.span3
|
||||
%ul.nav.nav-pills.nav-stacked
|
||||
%li.active
|
||||
= link_to 'Projects', '#tab-projects', 'data-toggle' => 'tab'
|
||||
%li
|
||||
= link_to 'Edit Team', '#tab-edit', 'data-toggle' => 'tab'
|
||||
- if can? current_user, :admin_user_team, @team
|
||||
%li
|
||||
= link_to 'Remove', '#tab-remove', 'data-toggle' => 'tab'
|
||||
|
||||
.span9
|
||||
.tab-content
|
||||
.tab-pane.active#tab-projects
|
||||
.ui-box.projects-table
|
||||
%h5.title Projects
|
||||
%ul.well-list
|
||||
- @projects.each do |project|
|
||||
%li
|
||||
- if project.public
|
||||
%i.icon-share
|
||||
- else
|
||||
%i.icon-lock.cgreen
|
||||
= link_to project.name_with_namespace, project
|
||||
.pull-right
|
||||
= link_to 'Edit max access', edit_team_project_path(@team, project), class: "btn btn-small"
|
||||
= link_to 'Relegate', team_project_path(@team, project), confirm: 'Remove project from team and move to global namespace. Are you sure?', method: :delete, class: "btn btn-remove small"
|
||||
.form-holder
|
||||
= form_tag team_projects_path(@team), id: "assign_projects", class: "bulk_import", method: :post do
|
||||
%table.headless
|
||||
%tr
|
||||
%td= select_tag :project_ids, options_from_collection_for_select(@avaliable_projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span4'
|
||||
%td= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles), {class: "project-access-select chosen" }
|
||||
%td= submit_tag 'Add Project', class: "btn btn-create", id: :assign_projects_to_team
|
||||
|
||||
|
||||
.tab-pane#tab-edit
|
||||
.ui-box
|
||||
%h5.title Edit Team
|
||||
%div.form-holder
|
||||
= form_for @team, url: team_path(@team) do |f|
|
||||
- if @team.errors.any?
|
||||
.alert.alert-error
|
||||
%span= @team.errors.full_messages.first
|
||||
.clearfix
|
||||
= f.label :name do
|
||||
Team name is
|
||||
.input
|
||||
= f.text_field :name, placeholder: "Ex. OpenSource", class: "xlarge left"
|
||||
|
||||
.clearfix.team-description-holder
|
||||
= f.label :description, "Details"
|
||||
.input
|
||||
= f.text_area :description, maxlength: 250, class: "xlarge js-gfm-input", rows: 4
|
||||
|
||||
.clearfix
|
||||
= f.label :path do
|
||||
Team path is
|
||||
.input
|
||||
= f.text_field :path, placeholder: "opensource", class: "xlarge left"
|
||||
|
||||
.form-actions
|
||||
= f.submit 'Save team changes', class: "btn btn-primary"
|
||||
|
||||
.tab-pane#tab-remove
|
||||
.ui-box.ui-box-danger
|
||||
%h5.title Remove team
|
||||
.ui-box-body
|
||||
%p
|
||||
Remove of team will cause removing members access to projects.
|
||||
%p
|
||||
%strong Removed team can not be restored!
|
||||
|
||||
= link_to 'Remove team', team_path(@team), method: :delete, confirm: "You are sure?", class: "btn btn-remove btn-small"
|
|
@ -1,23 +0,0 @@
|
|||
%h3.page_title
|
||||
Issues
|
||||
%small (in Team projects assigned to Team members)
|
||||
%small.pull-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-list
|
||||
- group[1].each do |issue|
|
||||
= render issue
|
||||
%hr
|
||||
= paginate @issues, theme: "gitlab"
|
||||
- else
|
||||
%p.nothing_here_message Nothing to show here
|
|
@ -1,20 +0,0 @@
|
|||
= form_tag admin_team_member_path(@team, @member), method: :put do
|
||||
-if @member.errors.any?
|
||||
.alert.alert-error
|
||||
%ul
|
||||
- @member.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.clearfix
|
||||
%label Default access for Team projects:
|
||||
.input
|
||||
= select_tag :default_project_access, options_for_select(UserTeam.access_roles, @team.default_projects_access(@member)), class: "project-access-select chosen span3"
|
||||
.clearfix
|
||||
%label Team admin?
|
||||
.input
|
||||
= check_box_tag :group_admin, true, @team.admin?(@member)
|
||||
|
||||
%br
|
||||
.actions
|
||||
= submit_tag 'Save', class: "btn btn-save"
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -1,31 +0,0 @@
|
|||
- user = member.user
|
||||
- allow_admin = can? current_user, :manage_user_team, @team
|
||||
%li{id: dom_id(member), class: "team_member_row user_#{user.id}"}
|
||||
.row
|
||||
.span3
|
||||
= link_to user_path(user.username), title: user.name, class: "dark" do
|
||||
= image_tag gravatar_icon(user.email, 40), class: "avatar s32"
|
||||
= link_to user_path(user.username), title: user.name, class: "dark" do
|
||||
%strong= truncate(user.name, lenght: 40)
|
||||
%br
|
||||
%small.cgray= user.username
|
||||
|
||||
.span5.pull-right
|
||||
- if allow_admin
|
||||
.pull-left
|
||||
= form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f|
|
||||
= label_tag :group_admin do
|
||||
= f.check_box :group_admin, class: 'trigger-submit'
|
||||
%span Admin access
|
||||
|
||||
= f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "span2 trigger-submit"
|
||||
.pull-right
|
||||
- if current_user == user
|
||||
%span.label.label-success This is you!
|
||||
- if @team.owner == user
|
||||
%span.label.label-info Owner
|
||||
- elsif user.blocked?
|
||||
%span.label.label-error Blocked
|
||||
- elsif allow_admin
|
||||
= link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove", title: "Remove from team" do
|
||||
%i.icon-minus.icon-white
|
|
@ -1,10 +0,0 @@
|
|||
- grouped_user_team_members(team).each do |access, members|
|
||||
- access_key = Project.access_options.key(access)
|
||||
- next if params[:type].present? && params[:type] != access_key.tableize
|
||||
.ui-box
|
||||
%h5.title
|
||||
= access_key.pluralize
|
||||
%small= members.size
|
||||
%ul.well-list.team-members
|
||||
- members.sort_by(&:user_name).each do |member|
|
||||
= render 'teams/members/member', member: member
|
|
@ -1,16 +0,0 @@
|
|||
%h3.page_title
|
||||
Edit access #{@member.name} in #{@team.name} team
|
||||
|
||||
%hr
|
||||
%table.zebra-striped
|
||||
%tr
|
||||
%td User:
|
||||
%td= @member.name
|
||||
%tr
|
||||
%td Team:
|
||||
%td= @team.name
|
||||
%tr
|
||||
%td Since:
|
||||
%td= member_since(@team, @member).stamp("Nov 11, 2010")
|
||||
|
||||
= render 'form'
|
|
@ -1,37 +0,0 @@
|
|||
%h3.page_title
|
||||
Team Members
|
||||
(#{@members.count})
|
||||
%small
|
||||
Read more about project permissions
|
||||
%strong= link_to "here", help_permissions_path, class: "vlink"
|
||||
|
||||
- if can? current_user, :manage_user_team, @team
|
||||
%span.pull-right
|
||||
= link_to new_team_member_path(@team), class: "btn btn-primary small grouped", title: "New Team Member" do
|
||||
New Team Member
|
||||
%hr
|
||||
|
||||
|
||||
.row
|
||||
.span3
|
||||
%ul.nav.nav-pills.nav-stacked
|
||||
%li{class: ("active" if !params[:type])}
|
||||
= link_to team_members_path(@team, type: nil) do
|
||||
All
|
||||
%li{class: ("active" if params[:type] == 'masters')}
|
||||
= link_to team_members_path(@team, type: 'masters') do
|
||||
Masters
|
||||
%li{class: ("active" if params[:type] == 'developers')}
|
||||
= link_to team_members_path(@team, type: 'developers') do
|
||||
Developers
|
||||
%li{class: ("active" if params[:type] == 'reporters')}
|
||||
= link_to team_members_path(@team, type: 'reporters') do
|
||||
Reporters
|
||||
%li{class: ("active" if params[:type] == 'guests')}
|
||||
= link_to team_members_path(@team, type: 'guests') do
|
||||
Guests
|
||||
|
||||
.span9
|
||||
.clearfix
|
||||
%div.team-table
|
||||
= render "teams/members/team", team: @team
|
|
@ -1,25 +0,0 @@
|
|||
%h3.page_title
|
||||
Team: #{@team.name}
|
||||
|
||||
%hr
|
||||
|
||||
= form_tag team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do
|
||||
%h6 1. Choose people you want in the team
|
||||
.clearfix
|
||||
= label_tag :user_ids, "People"
|
||||
.input
|
||||
= users_select_tag(:user_ids, multiple: true)
|
||||
|
||||
%h6 2. Set access level for them
|
||||
.clearfix
|
||||
= label_tag :project_access, "Project Access"
|
||||
.input= select_tag :default_project_access, options_for_select(Project.access_options), class: "project-access-select chosen"
|
||||
|
||||
.clearfix
|
||||
= label_tag :group_admin do
|
||||
%span Team Admin?
|
||||
.input= check_box_tag :group_admin
|
||||
|
||||
.actions
|
||||
= submit_tag 'Add users', class: "btn btn-create", id: :add_members_to_team
|
||||
= link_to "Cancel", team_members_path(@team), class: "btn btn-cancel"
|
|
@ -1,24 +0,0 @@
|
|||
%h3.page_title
|
||||
Merge Requests
|
||||
%small (authored by or assigned to Team members)
|
||||
%small.pull-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
|
|
@ -1,37 +0,0 @@
|
|||
= form_for @team, url: teams_path do |f|
|
||||
- if @team.errors.any?
|
||||
.alert.alert-error
|
||||
%span= @team.errors.full_messages.first
|
||||
.clearfix
|
||||
= f.label :name do
|
||||
Team name is
|
||||
.input
|
||||
= f.text_field :name, placeholder: "Ex. Ruby Developers", class: "xxlarge left"
|
||||
|
||||
.clearfix.team-description-holder
|
||||
= f.label :description, "Details"
|
||||
.input
|
||||
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
|
||||
|
||||
|
||||
.clearfix
|
||||
.input
|
||||
%ul
|
||||
%li All created teams are public (users can view who enter into team and which project are assigned for this team)
|
||||
%li People within a team see only projects they have access to
|
||||
%li You will be able to assign existing projects for team
|
||||
.form-actions
|
||||
= f.submit 'Create team', class: "btn btn-create"
|
||||
|
||||
- if current_user.can_create_group?
|
||||
.clearfix
|
||||
.input.light
|
||||
Need a group for several dependent projects?
|
||||
= link_to new_group_path, class: "btn btn-tiny" do
|
||||
Create a group
|
||||
- if current_user.can_create_project?
|
||||
.clearfix
|
||||
.input.light
|
||||
Want to create a project?
|
||||
= link_to new_project_path, class: "btn btn-tiny" do
|
||||
Create a project
|
|
@ -1,16 +0,0 @@
|
|||
= form_tag team_project_path(@team, @project), method: :put do
|
||||
-if @project.errors.any?
|
||||
.alert.alert-error
|
||||
%ul
|
||||
- @project.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.clearfix
|
||||
%label Max access for Team members:
|
||||
.input
|
||||
= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles, @team.max_project_access(@project)), class: "project-access-select chosen span3"
|
||||
|
||||
%br
|
||||
.actions
|
||||
= submit_tag 'Save', class: "btn btn-save"
|
||||
= link_to 'Cancel', :back, class: "btn btn-cancel"
|
|
@ -1,6 +0,0 @@
|
|||
%h3.page_title
|
||||
Edit max access in #{link_to @project.name_with_namespace, @project} for #{link_to(@team.name, team_path(@team))} team
|
||||
|
||||
%hr
|
||||
|
||||
= render 'form'
|
|
@ -1,28 +0,0 @@
|
|||
xml.instruct!
|
||||
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
|
||||
xml.title "Team feed - #{@team.name}"
|
||||
xml.link :href => team_url(@team, :atom), :rel => "self", :type => "application/atom+xml"
|
||||
xml.link :href => team_url(@team), :rel => "alternate", :type => "text/html"
|
||||
xml.id projects_url
|
||||
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
|
||||
|
||||
@events.each do |event|
|
||||
if event.proper?
|
||||
xml.entry do
|
||||
event_link = event_feed_url(event)
|
||||
event_title = event_feed_title(event)
|
||||
|
||||
xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}"
|
||||
xml.link :href => event_link
|
||||
xml.title truncate(event_title, :length => 80)
|
||||
xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(event.author_email)
|
||||
xml.author do |author|
|
||||
xml.name event.author_name
|
||||
xml.email event.author_email
|
||||
end
|
||||
xml.summary event_title
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,25 +0,0 @@
|
|||
.dashboard
|
||||
.activities.span8
|
||||
= link_to dashboard_path, class: 'btn btn-tiny' do
|
||||
← To dashboard
|
||||
|
||||
%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
|
||||
- if @team.description.present?
|
||||
.description-block
|
||||
= @team.description
|
||||
= render "projects", projects: @projects
|
||||
.prepend-top-20
|
||||
= link_to team_path(@team, { format: :atom, private_token: current_user.private_token }), title: "Feed" do
|
||||
%strong
|
||||
%i.icon-rss
|
||||
News Feed
|
||||
|
||||
%hr
|
||||
= render 'shared/promo'
|
|
@ -1,2 +0,0 @@
|
|||
:plain
|
||||
Pager.append(#{@events.count}, "#{escape_javascript(render(@events))}");
|
|
@ -155,20 +155,6 @@ Gitlab::Application.routes.draw do
|
|||
resources :users_groups, only: [:create, :update, :destroy]
|
||||
end
|
||||
|
||||
#
|
||||
# Teams Area
|
||||
#
|
||||
resources :teams, constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} do
|
||||
member do
|
||||
get :issues
|
||||
get :merge_requests
|
||||
end
|
||||
scope module: :teams do
|
||||
resources :members, only: [:index, :new, :create, :edit, :update, :destroy]
|
||||
resources :projects, only: [:index, :new, :create, :edit, :update, :destroy], constraints: { id: /[a-zA-Z.0-9_\-\/]+/ }
|
||||
end
|
||||
end
|
||||
|
||||
resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create]
|
||||
|
||||
devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations }
|
||||
|
@ -307,18 +293,6 @@ Gitlab::Application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
scope module: :projects do
|
||||
resources :teams, only: [] do
|
||||
collection do
|
||||
get :available
|
||||
post :assign
|
||||
end
|
||||
member do
|
||||
delete :resign
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
resources :notes, only: [:index, :create, :destroy] do
|
||||
collection do
|
||||
post :preview
|
||||
|
|
|
@ -1,241 +0,0 @@
|
|||
class Userteams < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedPaths
|
||||
include SharedProject
|
||||
include Select2Helper
|
||||
|
||||
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, owner: current_user
|
||||
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'
|
||||
|
||||
fill_in 'user_team_description', with: 'team description'
|
||||
click_button 'Create team'
|
||||
end
|
||||
|
||||
And 'I should see newly created team' do
|
||||
page.should have_content "gitlab"
|
||||
page.should have_content "team description"
|
||||
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, owner: current_user
|
||||
@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
|
||||
within(".side .ui-box") do
|
||||
page.should have_content(@project.name)
|
||||
end
|
||||
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_to(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, owner: current_user
|
||||
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_to(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|
|
||||
create(:merge_request, assignee: current_user, project: project)
|
||||
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|
|
||||
project.merge_requests.each do |merge_request|
|
||||
page.should have_content merge_request.title
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Given 'project from team has merge requests assigned to team members' do
|
||||
team = UserTeam.last
|
||||
team.projects.each do |project|
|
||||
member = team.members.sample
|
||||
create(:merge_request, assignee: member, project: project)
|
||||
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
|
||||
user = User.find_by_name("John")
|
||||
select2(user.id, from: "#user_ids", multiple: true)
|
||||
within "#team_members" do
|
||||
select "Reporter", from: "default_project_access"
|
||||
end
|
||||
click_button "Add"
|
||||
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, namespace: current_user.namespace
|
||||
end
|
||||
|
||||
And 'I visit my team page' do
|
||||
team = UserTeam.where(owner_id: current_user.id).last
|
||||
visit team_path(team)
|
||||
end
|
||||
|
||||
When 'I click on link "Assign Project"' do
|
||||
click_link "Assign Project"
|
||||
end
|
||||
|
||||
Then 'I should see form with my own project in available projects list' do
|
||||
projects_select = find("#project_ids")
|
||||
projects_select.should have_content(@project.name)
|
||||
end
|
||||
|
||||
When 'I submit form with selected project and max access' do
|
||||
within "#assign_projects" do
|
||||
select @project.name_with_namespace, 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
|
||||
projects = find(".projects-table")
|
||||
projects.should have_content(@project.name)
|
||||
end
|
||||
|
||||
When 'I click link "New Team Member"' do
|
||||
click_link "New Team Member"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def current_team
|
||||
@user_team ||= UserTeam.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
|
|
@ -1,65 +0,0 @@
|
|||
Feature: UserTeams
|
||||
Background:
|
||||
Given I sign in as a user
|
||||
And I own project "Shop"
|
||||
And project "Shop" has push event
|
||||
|
||||
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 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
|
||||
Then I should see newly created team
|
||||
|
||||
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
|
||||
|
||||
@javascript
|
||||
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 "Assign Project"
|
||||
Then I should see form with my own project in available projects list
|
||||
When I submit form with selected project and max access
|
||||
Then I should see my own project in team projects list
|
|
@ -35,7 +35,6 @@ module API
|
|||
mount Notes
|
||||
mount Internal
|
||||
mount SystemHooks
|
||||
mount UserTeams
|
||||
mount ProjectSnippets
|
||||
mount DeployKeys
|
||||
mount ProjectHooks
|
||||
|
|
|
@ -99,10 +99,6 @@ module API
|
|||
expose :id, :title, :key, :created_at
|
||||
end
|
||||
|
||||
class UserTeam < Grape::Entity
|
||||
expose :id, :name, :path, :owner_id
|
||||
end
|
||||
|
||||
class MergeRequest < Grape::Entity
|
||||
expose :id, :target_branch, :source_branch, :project_id, :title, :state
|
||||
expose :author, :assignee, using: Entities::UserBasic
|
||||
|
|
|
@ -1,276 +0,0 @@
|
|||
module API
|
||||
# user_teams API
|
||||
class UserTeams < Grape::API
|
||||
before { authenticate! }
|
||||
|
||||
resource :user_teams do
|
||||
helpers do
|
||||
def handle_team_member_errors(errors)
|
||||
if errors[:permission].any?
|
||||
render_api_error!(errors[:permission], 422)
|
||||
end
|
||||
not_found!
|
||||
end
|
||||
|
||||
def validate_access_level?(level)
|
||||
[UsersProject::GUEST, UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER].include? level.to_i
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Get a user_teams list
|
||||
#
|
||||
# Example Request:
|
||||
# GET /user_teams
|
||||
get do
|
||||
if current_user.admin
|
||||
@user_teams = paginate UserTeam
|
||||
else
|
||||
@user_teams = paginate current_user.user_teams
|
||||
end
|
||||
present @user_teams, with: Entities::UserTeam
|
||||
end
|
||||
|
||||
|
||||
# Create user_team. Available only for admin
|
||||
#
|
||||
# Parameters:
|
||||
# name (required) - The name of the user_team
|
||||
# path (required) - The path of the user_team
|
||||
# Example Request:
|
||||
# POST /user_teams
|
||||
post do
|
||||
authenticated_as_admin!
|
||||
required_attributes! [:name, :path]
|
||||
|
||||
attrs = attributes_for_keys [:name, :path]
|
||||
@user_team = UserTeam.new(attrs)
|
||||
@user_team.owner = current_user
|
||||
|
||||
if @user_team.save
|
||||
present @user_team, with: Entities::UserTeam
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Get a single user_team
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a user_team
|
||||
# Example Request:
|
||||
# GET /user_teams/:id
|
||||
get ":id" do
|
||||
@user_team = UserTeam.find(params[:id])
|
||||
if current_user.admin or current_user.user_teams.include? @user_team
|
||||
present @user_team, with: Entities::UserTeam
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Get user_team members
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a user_team
|
||||
# Example Request:
|
||||
# GET /user_teams/:id/members
|
||||
get ":id/members" do
|
||||
@user_team = UserTeam.find(params[:id])
|
||||
if current_user.admin or current_user.user_teams.include? @user_team
|
||||
@members = paginate @user_team.members
|
||||
present @members, with: Entities::TeamMember, user_team: @user_team
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Add a new user_team member
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a user_team
|
||||
# user_id (required) - The ID of a user
|
||||
# access_level (required) - Project access level
|
||||
# Example Request:
|
||||
# POST /user_teams/:id/members
|
||||
post ":id/members" do
|
||||
authenticated_as_admin!
|
||||
required_attributes! [:user_id, :access_level]
|
||||
|
||||
if not validate_access_level?(params[:access_level])
|
||||
render_api_error!("Wrong access level", 422)
|
||||
end
|
||||
|
||||
@user_team = UserTeam.find(params[:id])
|
||||
if @user_team
|
||||
team_member = @user_team.user_team_user_relationships.find_by_user_id(params[:user_id])
|
||||
# Not existing member
|
||||
if team_member.nil?
|
||||
@user_team.add_member(params[:user_id], params[:access_level], false)
|
||||
team_member = @user_team.user_team_user_relationships.find_by_user_id(params[:user_id])
|
||||
|
||||
if team_member.nil?
|
||||
render_api_error!("Error creating membership", 500)
|
||||
else
|
||||
@member = team_member.user
|
||||
present @member, with: Entities::TeamMember, user_team: @user_team
|
||||
end
|
||||
else
|
||||
render_api_error!("Already exists", 409)
|
||||
end
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Get a single team member from user_team
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a user_team
|
||||
# user_id (required) - The ID of a team member
|
||||
# Example Request:
|
||||
# GET /user_teams/:id/members/:user_id
|
||||
get ":id/members/:user_id" do
|
||||
@user_team = UserTeam.find(params[:id])
|
||||
if current_user.admin or current_user.user_teams.include? @user_team
|
||||
team_member = @user_team.user_team_user_relationships.find_by_user_id(params[:user_id])
|
||||
unless team_member.nil?
|
||||
present team_member.user, with: Entities::TeamMember, user_team: @user_team
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
# Remove a team member from user_team
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a user_team
|
||||
# user_id (required) - The ID of a team member
|
||||
# Example Request:
|
||||
# DELETE /user_teams/:id/members/:user_id
|
||||
delete ":id/members/:user_id" do
|
||||
authenticated_as_admin!
|
||||
|
||||
@user_team = UserTeam.find(params[:id])
|
||||
if @user_team
|
||||
team_member = @user_team.user_team_user_relationships.find_by_user_id(params[:user_id])
|
||||
unless team_member.nil?
|
||||
team_member.destroy
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Get to user_team assigned projects
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a user_team
|
||||
# Example Request:
|
||||
# GET /user_teams/:id/projects
|
||||
get ":id/projects" do
|
||||
@user_team = UserTeam.find(params[:id])
|
||||
if current_user.admin or current_user.user_teams.include? @user_team
|
||||
@projects = paginate @user_team.projects
|
||||
present @projects, with: Entities::TeamProject, user_team: @user_team
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Add a new user_team project
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a user_team
|
||||
# project_id (required) - The ID of a project
|
||||
# greatest_access_level (required) - Project access level
|
||||
# Example Request:
|
||||
# POST /user_teams/:id/projects
|
||||
post ":id/projects" do
|
||||
authenticated_as_admin!
|
||||
required_attributes! [:project_id, :greatest_access_level]
|
||||
|
||||
if not validate_access_level?(params[:greatest_access_level])
|
||||
render_api_error!("Wrong greatest_access_level", 422)
|
||||
end
|
||||
|
||||
@user_team = UserTeam.find(params[:id])
|
||||
if @user_team
|
||||
team_project = @user_team.user_team_project_relationships.find_by_project_id(params[:project_id])
|
||||
|
||||
# No existing project
|
||||
if team_project.nil?
|
||||
@user_team.assign_to_projects([params[:project_id]], params[:greatest_access_level])
|
||||
team_project = @user_team.user_team_project_relationships.find_by_project_id(params[:project_id])
|
||||
if team_project.nil?
|
||||
render_api_error!("Error creating project assignment", 500)
|
||||
else
|
||||
@project = team_project.project
|
||||
present @project, with: Entities::TeamProject, user_team: @user_team
|
||||
end
|
||||
else
|
||||
render_api_error!("Already exists", 409)
|
||||
end
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
# Show a single team project from user_team
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a user_team
|
||||
# project_id (required) - The ID of a project assigned to the team
|
||||
# Example Request:
|
||||
# GET /user_teams/:id/projects/:project_id
|
||||
get ":id/projects/:project_id" do
|
||||
@user_team = UserTeam.find(params[:id])
|
||||
if current_user.admin or current_user.user_teams.include? @user_team
|
||||
team_project = @user_team.user_team_project_relationships.find_by_project_id(params[:project_id])
|
||||
unless team_project.nil?
|
||||
present team_project.project, with: Entities::TeamProject, user_team: @user_team
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
# Remove a team project from user_team
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID of a user_team
|
||||
# project_id (required) - The ID of a project assigned to the team
|
||||
# Example Request:
|
||||
# DELETE /user_teams/:id/projects/:project_id
|
||||
delete ":id/projects/:project_id" do
|
||||
authenticated_as_admin!
|
||||
|
||||
@user_team = UserTeam.find(params[:id])
|
||||
if @user_team
|
||||
team_project = @user_team.user_team_project_relationships.find_by_project_id(params[:project_id])
|
||||
unless team_project.nil?
|
||||
team_project.destroy
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,146 +0,0 @@
|
|||
# UserTeamManager class
|
||||
#
|
||||
# Used for manage User teams with project repositories
|
||||
module Gitlab
|
||||
class UserTeamManager
|
||||
class << self
|
||||
def assign(team, project, access)
|
||||
project = Project.find(project) unless project.is_a? Project
|
||||
searched_project = team.user_team_project_relationships.find_by_project_id(project.id)
|
||||
|
||||
unless searched_project.present?
|
||||
team.user_team_project_relationships.create(project_id: project.id, greatest_access: access)
|
||||
update_team_users_access_in_project(team, project, :added)
|
||||
end
|
||||
end
|
||||
|
||||
def resign(team, project)
|
||||
project = Project.find(project) unless project.is_a? Project
|
||||
|
||||
team.user_team_project_relationships.with_project(project).destroy_all
|
||||
|
||||
update_team_users_access_in_project(team, project, :updated)
|
||||
end
|
||||
|
||||
def update_team_user_membership(team, member, options)
|
||||
updates = {}
|
||||
|
||||
if options[:default_projects_access].present?
|
||||
default_projects_access = options[:default_projects_access].to_s
|
||||
|
||||
if default_projects_access != team.default_projects_access(member).to_s
|
||||
updates[:permission] = default_projects_access
|
||||
end
|
||||
end
|
||||
|
||||
if options[:group_admin].present?
|
||||
group_admin = options[:group_admin].to_s == "1" ? true : false
|
||||
|
||||
if group_admin != team.admin?(member)
|
||||
updates[:group_admin] = group_admin
|
||||
end
|
||||
end
|
||||
|
||||
return true if updates.blank?
|
||||
|
||||
user_team_relationship = team.user_team_user_relationships.find_by_user_id(member)
|
||||
return false unless user_team_relationship.update_attributes(updates)
|
||||
|
||||
rebuild_project_permissions_to_member(team, member) if updates[:permission]
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def update_project_greates_access(team, project, permission)
|
||||
project_relation = team.user_team_project_relationships.find_by_project_id(project)
|
||||
if permission != team.max_project_access(project)
|
||||
if project_relation.update_attributes(greatest_access: permission)
|
||||
update_team_users_access_in_project(team, project, :updated)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def rebuild_project_permissions_to_member(team, member)
|
||||
team.projects.each do |project|
|
||||
update_team_user_access_in_project(team, member, project, :updated)
|
||||
end
|
||||
end
|
||||
|
||||
def update_team_users_access_in_project(team, project, action)
|
||||
members = team.members
|
||||
members.each do |member|
|
||||
update_team_user_access_in_project(team, member, project, action)
|
||||
end
|
||||
end
|
||||
|
||||
def update_team_user_access_in_project(team, user, project, action)
|
||||
granted_access = max_teams_member_permission_in_project(user, project, action)
|
||||
project_team_user = UsersProject.find_by_user_id_and_project_id(user.id, project.id)
|
||||
|
||||
if granted_access.zero?
|
||||
project_team_user.destroy if project_team_user.present?
|
||||
return
|
||||
end
|
||||
|
||||
if project_team_user.present?
|
||||
project_team_user.update_attributes(project_access: granted_access)
|
||||
else
|
||||
project.team << [user, granted_access]
|
||||
end
|
||||
end
|
||||
|
||||
def max_teams_member_permission_in_project(user, project, action = nil, teams = nil)
|
||||
result_access = 0
|
||||
|
||||
teams ||= project.user_teams.with_member(user)
|
||||
|
||||
if action && (action == :added)
|
||||
result_access = project.users_projects.with_user(user).first.project_access if project.users_projects.with_user(user).any?
|
||||
end
|
||||
|
||||
if teams.any?
|
||||
teams.each do |team|
|
||||
granted_access = max_team_member_permission_in_project(team, user, project)
|
||||
result_access = [granted_access, result_access].max
|
||||
end
|
||||
end
|
||||
result_access
|
||||
end
|
||||
|
||||
def max_team_member_permission_in_project(team, user, project)
|
||||
member_access = team.default_projects_access(user)
|
||||
team_access = team.user_team_project_relationships.find_by_project_id(project.id).greatest_access
|
||||
|
||||
[team_access, member_access].min
|
||||
end
|
||||
|
||||
def add_member_into_team(team, user, access, admin)
|
||||
user = User.find(user) unless user.is_a? User
|
||||
|
||||
team.user_team_user_relationships.create(user_id: user.id, permission: access, group_admin: admin)
|
||||
team.projects.each do |project|
|
||||
update_team_user_access_in_project(team, user, project, :added)
|
||||
end
|
||||
end
|
||||
|
||||
def remove_member_from_team(team, user)
|
||||
user = User.find(user) unless user.is_a? User
|
||||
|
||||
team.user_team_user_relationships.with_user(user).destroy_all
|
||||
other_teams = []
|
||||
team.projects.each do |project|
|
||||
other_teams << project.user_teams.with_member(user)
|
||||
end
|
||||
other_teams.uniq
|
||||
unless other_teams.any?
|
||||
UsersProject.in_projects(team.projects).with_user(user).destroy_all
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: user_team_project_relationships
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# user_team_id :integer
|
||||
# greatest_access :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe UserTeamProjectRelationship do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: user_teams
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255)
|
||||
# path :string(255)
|
||||
# owner_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# description :string(255) default(""), not null
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe UserTeam do
|
||||
let(:team) { FactoryGirl.create :user_team }
|
||||
|
||||
context ".add_member" do
|
||||
let(:user) { FactoryGirl.create :user }
|
||||
|
||||
it "should work" do
|
||||
team.add_member(user, UsersProject::DEVELOPER, false)
|
||||
team.members.should include(user)
|
||||
end
|
||||
end
|
||||
|
||||
context ".remove_member" do
|
||||
let(:user) { FactoryGirl.create :user }
|
||||
before { team.add_member(user, UsersProject::DEVELOPER, false) }
|
||||
|
||||
it "should work" do
|
||||
team.remove_member(user)
|
||||
team.members.should_not include(user)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,18 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: user_team_user_relationships
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# user_team_id :integer
|
||||
# group_admin :boolean
|
||||
# permission :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe UserTeamUserRelationship do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
|
@ -1,360 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe API::API do
|
||||
include ApiHelpers
|
||||
|
||||
# Create test objects
|
||||
let(:user1) { create(:user) }
|
||||
let(:user2) { create(:user) }
|
||||
let(:admin) { create(:admin) }
|
||||
let!(:group1) { create(:group, owner: user1) }
|
||||
let!(:group2) { create(:group, owner: user2) }
|
||||
let(:user_team1) { create(:user_team, owner: user1) }
|
||||
let(:user_team2) { create(:user_team, owner: user2) }
|
||||
let!(:project1) { create(:project, creator_id: admin.id) }
|
||||
let!(:project2) { create(:project, creator_id: admin.id) }
|
||||
|
||||
|
||||
before {
|
||||
# Add members to teams
|
||||
user_team1.add_member(user1, UsersProject::MASTER, false)
|
||||
user_team2.add_member(user2, UsersProject::MASTER, false)
|
||||
|
||||
# Add projects to teams
|
||||
user_team1.assign_to_projects([project1.id], UsersProject::MASTER)
|
||||
user_team2.assign_to_projects([project2.id], UsersProject::MASTER)
|
||||
|
||||
}
|
||||
|
||||
describe "GET /user_teams" do
|
||||
context "when unauthenticated" do
|
||||
it "should return authentication error" do
|
||||
get api("/user_teams")
|
||||
response.status.should == 401
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as user" do
|
||||
it "normal user: should return an array of user_teams of user1" do
|
||||
get api("/user_teams", user1)
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.length.should == 1
|
||||
json_response.first['name'].should == user_team1.name
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "admin: should return an array of all user_teams" do
|
||||
get api("/user_teams", admin)
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.length.should == 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /user_teams/:id" do
|
||||
context "when authenticated as user" do
|
||||
it "should return one of user1's user_teams" do
|
||||
get api("/user_teams/#{user_team1.id}", user1)
|
||||
response.status.should == 200
|
||||
json_response['name'] == user_team1.name
|
||||
end
|
||||
|
||||
it "should not return a non existing team" do
|
||||
get api("/user_teams/1328", user1)
|
||||
response.status.should == 404
|
||||
end
|
||||
|
||||
it "should not return a user_team not attached to user1" do
|
||||
get api("/user_teams/#{user_team2.id}", user1)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "should return any existing user_team" do
|
||||
get api("/user_teams/#{user_team2.id}", admin)
|
||||
response.status.should == 200
|
||||
json_response['name'].should == user_team2.name
|
||||
end
|
||||
|
||||
it "should not return a non existing user_team" do
|
||||
get api("/user_teams/1328", admin)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /user_teams" do
|
||||
context "when authenticated as user" do
|
||||
it "should not create user_team" do
|
||||
count_before=UserTeam.count
|
||||
post api("/user_teams", user1), attributes_for(:user_team)
|
||||
response.status.should == 403
|
||||
UserTeam.count.should == count_before
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "should create user_team" do
|
||||
count_before=UserTeam.count
|
||||
post api("/user_teams", admin), attributes_for(:user_team)
|
||||
response.status.should == 201
|
||||
UserTeam.count.should == count_before + 1
|
||||
end
|
||||
|
||||
it "should not create user_team, duplicate" do
|
||||
post api("/user_teams", admin), {:name => "Duplicate Test", :path => user_team2.path}
|
||||
response.status.should == 404
|
||||
end
|
||||
|
||||
it "should return 400 bad request error if name not given" do
|
||||
post api("/user_teams", admin), {:path => user_team2.path}
|
||||
response.status.should == 400
|
||||
end
|
||||
|
||||
it "should return 400 bad request error if path not given" do
|
||||
post api("/user_teams", admin), {:name => 'test'}
|
||||
response.status.should == 400
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Members
|
||||
|
||||
describe "GET /user_teams/:id/members" do
|
||||
context "when authenticated as user" do
|
||||
it "should return user1 as member of user1's user_teams" do
|
||||
get api("/user_teams/#{user_team1.id}/members", user1)
|
||||
response.status.should == 200
|
||||
json_response.first['name'].should == user1.name
|
||||
json_response.first['access_level'].should == UsersProject::MASTER
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "should return member of any existing user_team" do
|
||||
get api("/user_teams/#{user_team2.id}/members", admin)
|
||||
response.status.should == 200
|
||||
json_response.first['name'].should == user2.name
|
||||
json_response.first['access_level'].should == UsersProject::MASTER
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /user_teams/:id/members" do
|
||||
context "when authenticated as user" do
|
||||
it "should not add user2 as member of user_team1" do
|
||||
post api("/user_teams/#{user_team1.id}/members", user1), user_id: user2.id, access_level: UsersProject::MASTER
|
||||
response.status.should == 403
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "should return ok and add new member" do
|
||||
count_before=user_team1.user_team_user_relationships.count
|
||||
post api("/user_teams/#{user_team1.id}/members", admin), user_id: user2.id, access_level: UsersProject::MASTER
|
||||
response.status.should == 201
|
||||
json_response['name'].should == user2.name
|
||||
json_response['access_level'].should == UsersProject::MASTER
|
||||
user_team1.user_team_user_relationships.count.should == count_before + 1
|
||||
end
|
||||
it "should return ok if member already exists" do
|
||||
post api("/user_teams/#{user_team2.id}/members", admin), user_id: user2.id, access_level: UsersProject::MASTER
|
||||
response.status.should == 409
|
||||
end
|
||||
it "should return a 400 error when user id is not given" do
|
||||
post api("/user_teams/#{user_team2.id}/members", admin), access_level: UsersProject::MASTER
|
||||
response.status.should == 400
|
||||
end
|
||||
it "should return a 400 error when access level is not given" do
|
||||
post api("/user_teams/#{user_team2.id}/members", admin), user_id: user2.id
|
||||
response.status.should == 400
|
||||
end
|
||||
|
||||
it "should return a 422 error when access level is not known" do
|
||||
post api("/user_teams/#{user_team2.id}/members", admin), user_id: user1.id, access_level: 1234
|
||||
response.status.should == 422
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# Get single member
|
||||
describe "GET /user_teams/:id/members/:user_id" do
|
||||
context "when authenticated as member" do
|
||||
it "should show user1's membership of user_team1" do
|
||||
get api("/user_teams/#{user_team1.id}/members/#{user1.id}", user1)
|
||||
response.status.should == 200
|
||||
json_response['name'].should == user1.name
|
||||
json_response['access_level'].should == UsersProject::MASTER
|
||||
end
|
||||
it "should show that user2 is not member of user_team1" do
|
||||
get api("/user_teams/#{user_team1.id}/members/#{user2.id}", user1)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as non-member" do
|
||||
it "should not show user1's membership of user_team1" do
|
||||
get api("/user_teams/#{user_team1.id}/members/#{user1.id}", user2)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "should show user1's membership of user_team1" do
|
||||
get api("/user_teams/#{user_team1.id}/members/#{user1.id}", admin)
|
||||
response.status.should == 200
|
||||
json_response['name'].should == user1.name
|
||||
json_response['access_level'].should == UsersProject::MASTER
|
||||
end
|
||||
it "should return a 404 error when user id is not known" do
|
||||
get api("/user_teams/#{user_team2.id}/members/1328", admin)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /user_teams/:id/members/:user_id" do
|
||||
context "when authenticated as user" do
|
||||
it "should not delete user1's membership of user_team1" do
|
||||
delete api("/user_teams/#{user_team1.id}/members/#{user1.id}", user1)
|
||||
response.status.should == 403
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "should delete user1's membership of user_team1" do
|
||||
count_before=user_team1.user_team_user_relationships.count
|
||||
delete api("/user_teams/#{user_team1.id}/members/#{user1.id}", admin)
|
||||
response.status.should == 200
|
||||
user_team1.user_team_user_relationships.count.should == count_before - 1
|
||||
end
|
||||
it "should return a 404 error when user id is not known" do
|
||||
delete api("/user_teams/#{user_team2.id}/members/1328", admin)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Projects
|
||||
|
||||
describe "GET /user_teams/:id/projects" do
|
||||
context "when authenticated as user" do
|
||||
it "should return project1 as assigned to user_team1 as member user1" do
|
||||
get api("/user_teams/#{user_team1.id}/projects", user1)
|
||||
response.status.should == 200
|
||||
json_response.first['name'].should == project1.name
|
||||
json_response.length.should == user_team1.user_team_project_relationships.count
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "should return project2 as assigned to user_team2 as non-member, but admin" do
|
||||
get api("/user_teams/#{user_team2.id}/projects", admin)
|
||||
response.status.should == 200
|
||||
json_response.first['name'].should == project2.name
|
||||
json_response.first['greatest_access_level'].should == UsersProject::MASTER
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /user_teams/:id/projects" do
|
||||
context "when authenticated as admin" do
|
||||
it "should return ok and add new project" do
|
||||
count_before=user_team1.user_team_project_relationships.count
|
||||
post api("/user_teams/#{user_team1.id}/projects", admin),
|
||||
project_id: project2.id,
|
||||
greatest_access_level: UsersProject::MASTER
|
||||
response.status.should == 201
|
||||
json_response['name'].should == project2.name
|
||||
json_response['greatest_access_level'].should == UsersProject::MASTER
|
||||
user_team1.user_team_project_relationships.count.should == count_before + 1
|
||||
end
|
||||
it "should return ok if project already exists" do
|
||||
post api("/user_teams/#{user_team2.id}/projects", admin),
|
||||
project_id: project2.id,
|
||||
greatest_access_level: UsersProject::MASTER
|
||||
response.status.should == 409
|
||||
end
|
||||
it "should return a 400 error when project id is not given" do
|
||||
post api("/user_teams/#{user_team2.id}/projects", admin), greatest_access_level: UsersProject::MASTER
|
||||
response.status.should == 400
|
||||
end
|
||||
it "should return a 400 error when access level is not given" do
|
||||
post api("/user_teams/#{user_team2.id}/projects", admin), project_id: project2.id
|
||||
response.status.should == 400
|
||||
end
|
||||
|
||||
it "should return a 422 error when access level is not known" do
|
||||
post api("/user_teams/#{user_team2.id}/projects", admin),
|
||||
project_id: project2.id,
|
||||
greatest_access_level: 1234
|
||||
response.status.should == 422
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "GET /user_teams/:id/projects/:project_id" do
|
||||
context "when authenticated as member" do
|
||||
it "should show project1's assignment to user_team1" do
|
||||
get api("/user_teams/#{user_team1.id}/projects/#{project1.id}", user1)
|
||||
response.status.should == 200
|
||||
json_response['name'].should == project1.name
|
||||
json_response['greatest_access_level'].should == UsersProject::MASTER
|
||||
end
|
||||
it "should show project2's is not assigned to user_team1" do
|
||||
get api("/user_teams/#{user_team1.id}/projects/#{project2.id}", user1)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as non-member" do
|
||||
it "should not show project1's assignment to user_team1" do
|
||||
get api("/user_teams/#{user_team1.id}/projects/#{project1.id}", user2)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "should show project1's assignment to user_team1" do
|
||||
get api("/user_teams/#{user_team1.id}/projects/#{project1.id}", admin)
|
||||
response.status.should == 200
|
||||
json_response['name'].should == project1.name
|
||||
json_response['greatest_access_level'].should == UsersProject::MASTER
|
||||
end
|
||||
it "should return a 404 error when project id is not known" do
|
||||
get api("/user_teams/#{user_team2.id}/projects/1328", admin)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /user_teams/:id/projects/:project_id" do
|
||||
context "when authenticated as user" do
|
||||
it "should not delete project1's assignment to user_team2" do
|
||||
delete api("/user_teams/#{user_team2.id}/projects/#{project1.id}", user1)
|
||||
response.status.should == 403
|
||||
end
|
||||
end
|
||||
|
||||
context "when authenticated as admin" do
|
||||
it "should delete project1's assignment to user_team1" do
|
||||
count_before=user_team1.user_team_project_relationships.count
|
||||
delete api("/user_teams/#{user_team1.id}/projects/#{project1.id}", admin)
|
||||
response.status.should == 200
|
||||
user_team1.user_team_project_relationships.count.should == count_before - 1
|
||||
end
|
||||
it "should return a 404 error when project id is not known" do
|
||||
delete api("/user_teams/#{user_team2.id}/projects/1328", admin)
|
||||
response.status.should == 404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue