Merge pull request #2746 from gitlabhq/features/teams
New feature: Teams
This commit is contained in:
commit
aa1f1eb680
|
@ -4,11 +4,11 @@ window.dashboardPage = ->
|
|||
event.preventDefault()
|
||||
toggleFilter $(this)
|
||||
reloadActivities()
|
||||
|
||||
|
||||
reloadActivities = ->
|
||||
$(".content_list").html ''
|
||||
Pager.init 20, true
|
||||
|
||||
|
||||
toggleFilter = (sender) ->
|
||||
sender.parent().toggleClass "inactive"
|
||||
event_filters = $.cookie("event_filter")
|
||||
|
@ -17,11 +17,11 @@ toggleFilter = (sender) ->
|
|||
event_filters = event_filters.split(",")
|
||||
else
|
||||
event_filters = new Array()
|
||||
|
||||
|
||||
index = event_filters.indexOf(filter)
|
||||
if index is -1
|
||||
event_filters.push filter
|
||||
else
|
||||
event_filters.splice index, 1
|
||||
|
||||
|
||||
$.cookie "event_filter", event_filters.join(",")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
# * Filter merge requests
|
||||
#
|
||||
#
|
||||
@merge_requestsPage = ->
|
||||
$('#assignee_id').chosen()
|
||||
$('#milestone_id').chosen()
|
||||
|
@ -8,16 +8,16 @@
|
|||
$(this).closest('form').submit()
|
||||
|
||||
class MergeRequest
|
||||
|
||||
|
||||
constructor: (@opts) ->
|
||||
this.$el = $('.merge-request')
|
||||
@diffs_loaded = false
|
||||
@commits_loaded = false
|
||||
|
||||
|
||||
this.activateTab(@opts.action)
|
||||
|
||||
|
||||
this.bindEvents()
|
||||
|
||||
|
||||
this.initMergeWidget()
|
||||
this.$('.show-all-commits').on 'click', =>
|
||||
this.showAllCommits()
|
||||
|
@ -28,7 +28,7 @@ class MergeRequest
|
|||
|
||||
initMergeWidget: ->
|
||||
this.showState( @opts.current_state )
|
||||
|
||||
|
||||
if this.$('.automerge_widget').length and @opts.check_enable
|
||||
$.get @opts.url_to_automerge_check, (data) =>
|
||||
this.showState( data.state )
|
||||
|
@ -42,12 +42,12 @@ class MergeRequest
|
|||
bindEvents: ->
|
||||
this.$('.nav-tabs').on 'click', 'a', (event) =>
|
||||
a = $(event.currentTarget)
|
||||
|
||||
|
||||
href = a.attr('href')
|
||||
History.replaceState {path: href}, document.title, href
|
||||
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
|
||||
this.$('.nav-tabs').on 'click', 'li', (event) =>
|
||||
this.activateTab($(event.currentTarget).data('action'))
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
@extend .right;
|
||||
|
||||
.groups_box,
|
||||
.teams_box,
|
||||
.projects_box {
|
||||
> .title {
|
||||
padding: 2px 15px;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Provides a base class for Admin controllers to subclass
|
||||
#
|
||||
# Automatically sets the layout and ensures an administrator is logged in
|
||||
class AdminController < ApplicationController
|
||||
class Admin::ApplicationController < ApplicationController
|
||||
layout 'admin'
|
||||
before_filter :authenticate_admin!
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
class Admin::DashboardController < AdminController
|
||||
class Admin::DashboardController < Admin::ApplicationController
|
||||
def index
|
||||
@projects = Project.order("created_at DESC").limit(10)
|
||||
@users = User.order("created_at DESC").limit(10)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class Admin::GroupsController < AdminController
|
||||
class Admin::GroupsController < Admin::ApplicationController
|
||||
before_filter :group, only: [:edit, :show, :update, :destroy, :project_update, :project_teams_update]
|
||||
|
||||
def index
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class Admin::HooksController < AdminController
|
||||
class Admin::HooksController < Admin::ApplicationController
|
||||
def index
|
||||
@hooks = SystemHook.all
|
||||
@hook = SystemHook.new
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
class Admin::LogsController < AdminController
|
||||
class Admin::LogsController < Admin::ApplicationController
|
||||
end
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# Provides a base class for Admin controllers to subclass
|
||||
#
|
||||
# Automatically sets the layout and ensures an administrator is logged in
|
||||
class Admin::Projects::ApplicationController < Admin::ApplicationController
|
||||
|
||||
protected
|
||||
|
||||
def project
|
||||
@project ||= Project.find_by_path(params[:project_id])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
class Admin::Projects::MembersController < Admin::Projects::ApplicationController
|
||||
def edit
|
||||
@member = team_member
|
||||
@project = project
|
||||
@team_member_relation = team_member_relation
|
||||
end
|
||||
|
||||
def update
|
||||
if team_member_relation.update_attributes(params[:team_member])
|
||||
redirect_to [:admin, project], notice: 'Project Access was successfully updated.'
|
||||
else
|
||||
render action: "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
team_member_relation.destroy
|
||||
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def team_member
|
||||
@member ||= project.users.find(params[:id])
|
||||
end
|
||||
|
||||
def team_member_relation
|
||||
team_member.users_projects.find_by_project_id(project)
|
||||
end
|
||||
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
class Admin::ProjectsController < AdminController
|
||||
class Admin::ProjectsController < Admin::ApplicationController
|
||||
before_filter :project, only: [:edit, :show, :update, :destroy, :team_update]
|
||||
|
||||
def index
|
||||
|
@ -29,7 +29,9 @@ class Admin::ProjectsController < AdminController
|
|||
end
|
||||
|
||||
def update
|
||||
status = Projects::UpdateContext.new(project, current_user, params).execute(:admin)
|
||||
project.creator = current_user unless project.creator
|
||||
|
||||
status = ::Projects::UpdateContext.new(project, current_user, params).execute(:admin)
|
||||
|
||||
if status
|
||||
redirect_to [:admin, @project], notice: 'Project was successfully updated.'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class Admin::ResqueController < AdminController
|
||||
class Admin::ResqueController < Admin::ApplicationController
|
||||
def show
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
class Admin::TeamMembersController < AdminController
|
||||
def edit
|
||||
@admin_team_member = UsersProject.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@admin_team_member = UsersProject.find(params[:id])
|
||||
|
||||
if @admin_team_member.update_attributes(params[:team_member])
|
||||
redirect_to [:admin, @admin_team_member.project], notice: 'Project Access was successfully updated.'
|
||||
else
|
||||
render action: "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@admin_team_member = UsersProject.find(params[:id])
|
||||
@admin_team_member.destroy
|
||||
|
||||
redirect_to :back
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
# 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
|
|
@ -0,0 +1,41 @@
|
|||
class Admin::Teams::MembersController < Admin::Teams::ApplicationController
|
||||
def new
|
||||
@users = User.potential_team_members(user_team)
|
||||
@users = UserDecorator.decorate @users
|
||||
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 was 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(params[:id])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
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
|
|
@ -0,0 +1,59 @@
|
|||
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_user_teams_path, notice: 'Team of users was successfully deleted.'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def user_team
|
||||
@team ||= UserTeam.find_by_path(params[:id])
|
||||
end
|
||||
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
class Admin::UsersController < AdminController
|
||||
class Admin::UsersController < Admin::ApplicationController
|
||||
def index
|
||||
@admin_users = User.scoped
|
||||
@admin_users = @admin_users.filter(params[:filter])
|
||||
|
|
|
@ -94,6 +94,14 @@ class ApplicationController < ActionController::Base
|
|||
return access_denied! unless can?(current_user, :download_code, project)
|
||||
end
|
||||
|
||||
def authorize_manage_user_team!
|
||||
return access_denied! unless user_team.present? && can?(current_user, :manage_user_team, user_team)
|
||||
end
|
||||
|
||||
def authorize_admin_user_team!
|
||||
return access_denied! unless user_team.present? && can?(current_user, :admin_user_team, user_team)
|
||||
end
|
||||
|
||||
def access_denied!
|
||||
render "errors/access_denied", layout: "errors", status: 404
|
||||
end
|
||||
|
@ -135,4 +143,5 @@ class ApplicationController < ActionController::Base
|
|||
def dev_tools
|
||||
Rack::MiniProfiler.authorize_request
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -18,6 +18,8 @@ class DashboardController < ApplicationController
|
|||
@projects
|
||||
end
|
||||
|
||||
@teams = (UserTeam.with_member(current_user) + UserTeam.created_by(current_user)).uniq
|
||||
|
||||
@projects = @projects.page(params[:page]).per(30)
|
||||
|
||||
@events = Event.in_projects(current_user.authorized_projects.pluck(:id))
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
class Projects::ApplicationController < ApplicationController
|
||||
|
||||
before_filter :authorize_admin_team_member!
|
||||
|
||||
protected
|
||||
|
||||
def user_team
|
||||
@team ||= UserTeam.find_by_path(params[:id])
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
class Projects::TeamsController < Projects::ApplicationController
|
||||
|
||||
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 avaliable 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
|
||||
|
||||
end
|
|
@ -19,7 +19,7 @@ class ProjectsController < ProjectResourceController
|
|||
end
|
||||
|
||||
def create
|
||||
@project = Projects::CreateContext.new(current_user, params[:project]).execute
|
||||
@project = ::Projects::CreateContext.new(current_user, params[:project]).execute
|
||||
|
||||
respond_to do |format|
|
||||
flash[:notice] = 'Project was successfully created.' if @project.saved?
|
||||
|
@ -35,7 +35,7 @@ class ProjectsController < ProjectResourceController
|
|||
end
|
||||
|
||||
def update
|
||||
status = Projects::UpdateContext.new(project, current_user, params).execute
|
||||
status = ::Projects::UpdateContext.new(project, current_user, params).execute
|
||||
|
||||
respond_to do |format|
|
||||
if status
|
||||
|
|
|
@ -4,15 +4,16 @@ class TeamMembersController < ProjectResourceController
|
|||
before_filter :authorize_admin_project!, except: [:index, :show]
|
||||
|
||||
def index
|
||||
@teams = UserTeam.scoped
|
||||
end
|
||||
|
||||
def show
|
||||
@team_member = project.users_projects.find(params[:id])
|
||||
@events = @team_member.user.recent_events.where(:project_id => @project.id).limit(7)
|
||||
@user_project_relation = project.users_projects.find_by_user_id(member)
|
||||
@events = member.recent_events.in_projects(project).limit(7)
|
||||
end
|
||||
|
||||
def new
|
||||
@team_member = project.users_projects.new
|
||||
@user_project_relation = project.users_projects.new
|
||||
end
|
||||
|
||||
def create
|
||||
|
@ -28,18 +29,18 @@ class TeamMembersController < ProjectResourceController
|
|||
end
|
||||
|
||||
def update
|
||||
@team_member = project.users_projects.find(params[:id])
|
||||
@team_member.update_attributes(params[:team_member])
|
||||
@user_project_relation = project.users_projects.find_by_user_id(member)
|
||||
@user_project_relation.update_attributes(params[:team_member])
|
||||
|
||||
unless @team_member.valid?
|
||||
unless @user_project_relation.valid?
|
||||
flash[:alert] = "User should have at least one role"
|
||||
end
|
||||
redirect_to project_team_index_path(@project)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@team_member = project.users_projects.find(params[:id])
|
||||
@team_member.destroy
|
||||
@user_project_relation = project.users_projects.find_by_user_id(params[:id])
|
||||
@user_project_relation.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to project_team_index_path(@project) }
|
||||
|
@ -54,4 +55,10 @@ class TeamMembersController < ProjectResourceController
|
|||
|
||||
redirect_to project_team_members_path(project), notice: notice
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def member
|
||||
@member ||= User.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
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
|
|
@ -0,0 +1,49 @@
|
|||
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)
|
||||
@users = UserDecorator.decorate @users
|
||||
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 team_members_path(user_team), notice: 'Members was 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 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(params[:id])
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Teams::ProjectsController < Teams::ApplicationController
|
||||
|
||||
skip_before_filter :authorize_manage_user_team!, only: [:index]
|
||||
|
||||
def index
|
||||
@projects = user_team.projects
|
||||
@avaliable_projects = current_user.admin? ? Project.without_team(user_team) : current_user.owned_projects.without_team(user_team)
|
||||
end
|
||||
|
||||
def new
|
||||
user_team
|
||||
@avaliable_projects = current_user.owned_projects.scoped
|
||||
@avaliable_projects = @avaliable_projects.without_team(user_team) if user_team.projects.any?
|
||||
|
||||
redirect_to team_projects_path(user_team), notice: "No avalible projects." unless @avaliable_projects.any?
|
||||
end
|
||||
|
||||
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) }
|
||||
|
||||
# Assign projects to team
|
||||
user_team.assign_to_projects(project_ids, access)
|
||||
|
||||
redirect_to team_projects_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 team_projects_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
|
|
@ -0,0 +1,92 @@
|
|||
class TeamsController < ApplicationController
|
||||
# Authorize
|
||||
before_filter :authorize_manage_user_team!
|
||||
before_filter :authorize_admin_user_team!
|
||||
|
||||
# Skip access control on public section
|
||||
skip_before_filter :authorize_manage_user_team!, only: [:index, :show, :new, :destroy, :create, :search, :issues, :merge_requests]
|
||||
skip_before_filter :authorize_admin_user_team!, only: [:index, :show, :new, :create, :search, :issues, :merge_requests]
|
||||
|
||||
layout 'user_team', only: [:show, :edit, :update, :destroy, :issues, :merge_requests, :search]
|
||||
|
||||
def index
|
||||
@teams = current_user.user_teams.order('name ASC')
|
||||
end
|
||||
|
||||
def show
|
||||
user_team
|
||||
projects
|
||||
@events = Event.in_projects(user_team.project_ids).limit(20).offset(params[:offset] || 0)
|
||||
end
|
||||
|
||||
def edit
|
||||
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 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
|
||||
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
|
||||
|
||||
def search
|
||||
result = SearchContext.new(user_team.project_ids, params).execute
|
||||
|
||||
@projects = result[:projects]
|
||||
@merge_requests = result[:merge_requests]
|
||||
@issues = result[:issues]
|
||||
@wiki_pages = result[:wiki_pages]
|
||||
@teams = result[:teams]
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def projects
|
||||
@projects ||= user_team.projects.sorted_by_activity
|
||||
end
|
||||
|
||||
def user_team
|
||||
@team ||= UserTeam.find_by_path(params[:id])
|
||||
end
|
||||
|
||||
end
|
|
@ -8,4 +8,8 @@ class UserDecorator < ApplicationDecorator
|
|||
def tm_of(project)
|
||||
project.team_member_by_id(self.id)
|
||||
end
|
||||
|
||||
def name_with_email
|
||||
"#{name} (#{email})"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
module Admin::Teams::MembersHelper
|
||||
def member_since(team, member)
|
||||
team.user_team_user_relationships.find_by_user_id(member).created_at
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Admin::Teams::ProjectsHelper
|
||||
def assigned_since(team, project)
|
||||
team.user_team_project_relationships.find_by_project_id(project).created_at
|
||||
end
|
||||
end
|
|
@ -3,8 +3,12 @@ module ProjectsHelper
|
|||
@project.users_projects.sort_by(&:project_access).reverse.group_by(&:project_access)
|
||||
end
|
||||
|
||||
def remove_from_team_message(project, member)
|
||||
"You are going to remove #{member.user_name} from #{project.name}. Are you sure?"
|
||||
def grouper_project_teams(project)
|
||||
@project.user_team_project_relationships.sort_by(&:greatest_access).reverse.group_by(&:greatest_access)
|
||||
end
|
||||
|
||||
def remove_from_project_team_message(project, user)
|
||||
"You are going to remove #{user.name} from #{project.name} project team. Are you sure?"
|
||||
end
|
||||
|
||||
def link_to_project project
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
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
|
|
@ -8,6 +8,7 @@ class Ability
|
|||
when "Snippet" then snippet_abilities(object, subject)
|
||||
when "MergeRequest" then merge_request_abilities(object, subject)
|
||||
when "Group", "Namespace" then group_abilities(object, subject)
|
||||
when "UserTeam" then user_team_abilities(object, subject)
|
||||
else []
|
||||
end
|
||||
end
|
||||
|
@ -110,6 +111,22 @@ class Ability
|
|||
rules.flatten
|
||||
end
|
||||
|
||||
def user_team_abilities user, team
|
||||
rules = []
|
||||
|
||||
# Only group owner and administrators can manage group
|
||||
if team.owner == user || team.admin?(user) || user.admin?
|
||||
rules << [ :manage_user_team ]
|
||||
end
|
||||
|
||||
if team.owner == user || user.admin?
|
||||
rules << [ :admin_user_team ]
|
||||
end
|
||||
|
||||
rules.flatten
|
||||
end
|
||||
|
||||
|
||||
[:issue, :note, :snippet, :merge_request].each do |name|
|
||||
define_method "#{name}_abilities" do |user, subject|
|
||||
if subject.author == user
|
||||
|
|
|
@ -22,6 +22,7 @@ module Issuable
|
|||
scope :opened, where(closed: false)
|
||||
scope :closed, where(closed: true)
|
||||
scope :of_group, ->(group) { where(project_id: group.project_ids) }
|
||||
scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) }
|
||||
scope :assigned, ->(u) { where(assignee_id: u.id)}
|
||||
scope :recent, order("created_at DESC")
|
||||
|
||||
|
|
|
@ -33,28 +33,31 @@ class Project < ActiveRecord::Base
|
|||
attr_accessor :error_code
|
||||
|
||||
# Relations
|
||||
belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'"
|
||||
belongs_to :creator, foreign_key: "creator_id", class_name: "User"
|
||||
belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'"
|
||||
belongs_to :namespace
|
||||
|
||||
belongs_to :creator,
|
||||
class_name: "User",
|
||||
foreign_key: "creator_id"
|
||||
|
||||
has_many :users, through: :users_projects
|
||||
has_many :events, dependent: :destroy
|
||||
has_many :merge_requests, dependent: :destroy
|
||||
has_many :issues, dependent: :destroy, order: "closed, created_at DESC"
|
||||
has_many :milestones, dependent: :destroy
|
||||
has_many :users_projects, dependent: :destroy
|
||||
has_many :notes, dependent: :destroy
|
||||
has_many :snippets, dependent: :destroy
|
||||
has_many :deploy_keys, dependent: :destroy, foreign_key: "project_id", class_name: "Key"
|
||||
has_many :hooks, dependent: :destroy, class_name: "ProjectHook"
|
||||
has_many :wikis, dependent: :destroy
|
||||
has_many :protected_branches, dependent: :destroy
|
||||
has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id'
|
||||
has_one :gitlab_ci_service, dependent: :destroy
|
||||
|
||||
has_many :events, dependent: :destroy
|
||||
has_many :merge_requests, dependent: :destroy
|
||||
has_many :issues, dependent: :destroy, order: "closed, created_at DESC"
|
||||
has_many :milestones, dependent: :destroy
|
||||
has_many :users_projects, dependent: :destroy
|
||||
has_many :notes, dependent: :destroy
|
||||
has_many :snippets, dependent: :destroy
|
||||
has_many :deploy_keys, dependent: :destroy, class_name: "Key", foreign_key: "project_id"
|
||||
has_many :hooks, dependent: :destroy, class_name: "ProjectHook"
|
||||
has_many :wikis, dependent: :destroy
|
||||
has_many :protected_branches, dependent: :destroy
|
||||
has_many :user_team_project_relationships, dependent: :destroy
|
||||
|
||||
has_many :users, through: :users_projects
|
||||
has_many :user_teams, through: :user_team_project_relationships
|
||||
has_many :user_team_user_relationships, through: :user_teams
|
||||
has_many :user_teams_members, through: :user_team_user_relationships
|
||||
|
||||
delegate :name, to: :owner, allow_nil: true, prefix: true
|
||||
|
||||
# Validations
|
||||
|
@ -77,6 +80,8 @@ class Project < ActiveRecord::Base
|
|||
# Scopes
|
||||
scope :without_user, ->(user) { where("id NOT IN (:ids)", ids: user.authorized_projects.map(&:id) ) }
|
||||
scope :not_in_group, ->(group) { where("id NOT IN (:ids)", ids: group.project_ids ) }
|
||||
scope :without_team, ->(team) { where("id NOT IN (:ids)", ids: team.projects.map(&:id)) }
|
||||
scope :in_team, ->(team) { where("id IN (:ids)", ids: team.projects.map(&:id)) }
|
||||
scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) }
|
||||
scope :sorted_by_activity, ->() { order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") }
|
||||
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
|
||||
|
@ -122,7 +127,7 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def team
|
||||
@team ||= Team.new(self)
|
||||
@team ||= ProjectTeam.new(self)
|
||||
end
|
||||
|
||||
def repository
|
||||
|
@ -489,6 +494,11 @@ class Project < ActiveRecord::Base
|
|||
http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
|
||||
end
|
||||
|
||||
def project_access_human(member)
|
||||
project_user_relation = self.users_projects.find_by_user_id(member.id)
|
||||
self.class.access_options.key(project_user_relation.project_access)
|
||||
end
|
||||
|
||||
# Check if current branch name is marked as protected in the system
|
||||
def protected_branch? branch_name
|
||||
protected_branches.map(&:name).include?(branch_name)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class Team
|
||||
class ProjectTeam
|
||||
attr_accessor :project
|
||||
|
||||
def initialize(project)
|
|
@ -45,18 +45,27 @@ class User < ActiveRecord::Base
|
|||
attr_accessor :force_random_password
|
||||
|
||||
# Namespace for personal projects
|
||||
has_one :namespace, class_name: "Namespace", foreign_key: :owner_id, conditions: 'type IS NULL', dependent: :destroy
|
||||
has_many :groups, class_name: "Group", foreign_key: :owner_id
|
||||
has_one :namespace, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace", conditions: 'type IS NULL'
|
||||
|
||||
has_many :keys, dependent: :destroy
|
||||
has_many :users_projects, dependent: :destroy
|
||||
has_many :issues, foreign_key: :author_id, dependent: :destroy
|
||||
has_many :notes, foreign_key: :author_id, dependent: :destroy
|
||||
has_many :merge_requests, foreign_key: :author_id, dependent: :destroy
|
||||
has_many :events, class_name: "Event", foreign_key: :author_id, dependent: :destroy
|
||||
has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC"
|
||||
has_many :assigned_issues, class_name: "Issue", foreign_key: :assignee_id, dependent: :destroy
|
||||
has_many :assigned_merge_requests, class_name: "MergeRequest", foreign_key: :assignee_id, dependent: :destroy
|
||||
has_many :keys, dependent: :destroy
|
||||
has_many :users_projects, dependent: :destroy
|
||||
has_many :issues, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :notes, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :merge_requests, dependent: :destroy, foreign_key: :author_id
|
||||
has_many :events, dependent: :destroy, foreign_key: :author_id, class_name: "Event"
|
||||
has_many :assigned_issues, dependent: :destroy, foreign_key: :assignee_id, class_name: "Issue"
|
||||
has_many :assigned_merge_requests, dependent: :destroy, foreign_key: :assignee_id, class_name: "MergeRequest"
|
||||
|
||||
has_many :groups, class_name: "Group", foreign_key: :owner_id
|
||||
has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC"
|
||||
|
||||
has_many :projects, through: :users_projects
|
||||
|
||||
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
|
||||
|
||||
validates :name, presence: true
|
||||
validates :bio, length: { within: 0..255 }
|
||||
|
@ -80,6 +89,9 @@ class User < ActiveRecord::Base
|
|||
scope :blocked, where(blocked: true)
|
||||
scope :active, where(blocked: false)
|
||||
scope :alphabetically, order('name ASC')
|
||||
scope :in_team, ->(team){ where(id: team.member_ids) }
|
||||
scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) }
|
||||
scope :potential_team_members, ->(team) { team.members.any? ? active : active.not_in_team(team) }
|
||||
|
||||
#
|
||||
# Class methods
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
class UserTeam < ActiveRecord::Base
|
||||
attr_accessible :name, :owner_id, :path
|
||||
|
||||
belongs_to :owner, class_name: User
|
||||
|
||||
has_many :user_team_project_relationships, dependent: :destroy
|
||||
has_many :user_team_user_relationships, dependent: :destroy
|
||||
|
||||
has_many :projects, through: :user_team_project_relationships
|
||||
has_many :members, through: :user_team_user_relationships, source: :user
|
||||
|
||||
validates :name, presence: true, uniqueness: true
|
||||
validates :owner, presence: true
|
||||
validates :path, uniqueness: true, presence: true, length: { within: 1..255 },
|
||||
format: { with: Gitlab::Regex.path_regex,
|
||||
message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
|
||||
|
||||
scope :with_member, ->(user){ joins(:user_team_user_relationships).where(user_team_user_relationships: {user_id: user.id}) }
|
||||
scope :with_project, ->(project){ joins(:user_team_project_relationships).where(user_team_project_relationships: {project_id: project})}
|
||||
scope :without_project, ->(project){ where("user_teams.id NOT IN (:ids)", ids: (a = with_project(project); a.blank? ? 0 : a))}
|
||||
scope :created_by, ->(user){ where(owner_id: user) }
|
||||
|
||||
class << self
|
||||
def search query
|
||||
where("name LIKE :query OR path LIKE :query", query: "%#{query}%")
|
||||
end
|
||||
|
||||
def global_id
|
||||
'GLN'
|
||||
end
|
||||
|
||||
def access_roles
|
||||
UsersProject.access_roles
|
||||
end
|
||||
end
|
||||
|
||||
def to_param
|
||||
path
|
||||
end
|
||||
|
||||
def assign_to_projects(projects, access)
|
||||
projects.each do |project|
|
||||
assign_to_project(project, access)
|
||||
end
|
||||
end
|
||||
|
||||
def assign_to_project(project, access)
|
||||
Gitlab::UserTeamManager.assign(self, project, access)
|
||||
end
|
||||
|
||||
def resign_from_project(project)
|
||||
Gitlab::UserTeamManager.resign(self, project)
|
||||
end
|
||||
|
||||
def add_members(users, access, group_admin)
|
||||
users.each do |user|
|
||||
add_member(user, access, group_admin)
|
||||
end
|
||||
end
|
||||
|
||||
def add_member(user, access, group_admin)
|
||||
Gitlab::UserTeamManager.add_member_into_team(self, user, access, group_admin)
|
||||
end
|
||||
|
||||
def remove_member(user)
|
||||
Gitlab::UserTeamManager.remove_member_from_team(self, user)
|
||||
end
|
||||
|
||||
def update_membership(user, options)
|
||||
Gitlab::UserTeamManager.update_team_user_membership(self, user, options)
|
||||
end
|
||||
|
||||
def update_project_access(project, permission)
|
||||
Gitlab::UserTeamManager.update_project_greates_access(self, project, permission)
|
||||
end
|
||||
|
||||
def max_project_access(project)
|
||||
user_team_project_relationships.find_by_project_id(project).greatest_access
|
||||
end
|
||||
|
||||
def human_max_project_access(project)
|
||||
self.class.access_roles.invert[max_project_access(project)]
|
||||
end
|
||||
|
||||
def default_projects_access(member)
|
||||
user_team_user_relationships.find_by_user_id(member).permission
|
||||
end
|
||||
|
||||
def human_default_projects_access(member)
|
||||
self.class.access_roles.invert[default_projects_access(member)]
|
||||
end
|
||||
|
||||
def admin?(member)
|
||||
user_team_user_relationships.with_user(member).first.group_admin?
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
class UserTeamProjectRelationship < ActiveRecord::Base
|
||||
attr_accessible :greatest_access, :project_id, :user_team_id
|
||||
|
||||
belongs_to :user_team
|
||||
belongs_to :project
|
||||
|
||||
validates :project, presence: true
|
||||
validates :user_team, presence: true
|
||||
validate :check_greatest_access
|
||||
|
||||
scope :with_project, ->(project){ where(project_id: project.id) }
|
||||
|
||||
def team_name
|
||||
user_team.name
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_greatest_access
|
||||
errors.add(:base, :incorrect_access_code) unless correct_access?
|
||||
end
|
||||
|
||||
def correct_access?
|
||||
return false if greatest_access.blank?
|
||||
return true if UsersProject.access_roles.has_value?(greatest_access)
|
||||
false
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
class UserTeamUserRelationship < ActiveRecord::Base
|
||||
attr_accessible :group_admin, :permission, :user_id, :user_team_id
|
||||
|
||||
belongs_to :user_team
|
||||
belongs_to :user
|
||||
|
||||
validates :user_team, presence: true
|
||||
validates :user, presence: true
|
||||
|
||||
scope :with_user, ->(user) { where(user_id: user.id) }
|
||||
|
||||
def user_name
|
||||
user.name
|
||||
end
|
||||
|
||||
def access_human
|
||||
UsersProject.access_roles.invert[permission]
|
||||
end
|
||||
end
|
|
@ -39,7 +39,10 @@ class UsersProject < ActiveRecord::Base
|
|||
scope :reporters, where(project_access: REPORTER)
|
||||
scope :developers, where(project_access: DEVELOPER)
|
||||
scope :masters, where(project_access: MASTER)
|
||||
|
||||
scope :in_project, ->(project) { where(project_id: project.id) }
|
||||
scope :in_projects, ->(projects) { where(project_id: project_ids) }
|
||||
scope :with_user, ->(user) { where(user_id: user.id) }
|
||||
|
||||
class << self
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
= form_for @team_member_relation, as: :team_member, url: admin_project_member_path(@project, @member) do |f|
|
||||
-if @team_member_relation.errors.any?
|
||||
.alert-message.block-message.error
|
||||
%ul
|
||||
- @team_member_relation.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.clearfix
|
||||
%label Project Access:
|
||||
.input
|
||||
= f.select :project_access, options_for_select(Project.access_options, @team_member_relation.project_access), {}, class: "project-access-select chosen span3"
|
||||
|
||||
%br
|
||||
.actions
|
||||
= f.submit 'Save', class: "btn primary"
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -0,0 +1,8 @@
|
|||
%p.slead
|
||||
Edit access for
|
||||
= link_to @member.name, admin_user_path(@member)
|
||||
in
|
||||
= link_to @project.name_with_namespace, admin_project_path(@project)
|
||||
|
||||
%hr
|
||||
= render 'form'
|
|
@ -114,9 +114,9 @@
|
|||
%h5
|
||||
Team
|
||||
%small
|
||||
(#{@project.users_projects.count})
|
||||
(#{@project.users.count})
|
||||
%br
|
||||
%table.zebra-striped
|
||||
%table.zebra-striped.team_members
|
||||
%thead
|
||||
%tr
|
||||
%th Name
|
||||
|
@ -124,13 +124,13 @@
|
|||
%th Repository Access
|
||||
%th
|
||||
|
||||
- @project.users_projects.each do |tm|
|
||||
- @project.users.each do |tm|
|
||||
%tr
|
||||
%td
|
||||
= link_to tm.user_name, admin_user_path(tm.user)
|
||||
%td= tm.project_access_human
|
||||
%td= link_to 'Edit Access', edit_admin_team_member_path(tm), class: "btn small"
|
||||
%td= link_to 'Remove from team', admin_team_member_path(tm), confirm: 'Are you sure?', method: :delete, class: "btn danger small"
|
||||
= link_to tm.name, admin_user_path(tm)
|
||||
%td= @project.project_access_human(tm)
|
||||
%td= link_to 'Edit Access', edit_admin_project_member_path(@project, tm), class: "btn small"
|
||||
%td= link_to 'Remove from team', admin_project_member_path(@project, tm), confirm: 'Are you sure?', method: :delete, class: "btn danger small"
|
||||
|
||||
%br
|
||||
%h5 Add new team member
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
= form_for @admin_team_member, as: :team_member, url: admin_team_member_path(@admin_team_member) do |f|
|
||||
-if @admin_team_member.errors.any?
|
||||
.alert-message.block-message.error
|
||||
%ul
|
||||
- @admin_team_member.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.clearfix
|
||||
%label Project Access:
|
||||
.input
|
||||
= f.select :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), {}, class: "project-access-select chosen span3"
|
||||
|
||||
%br
|
||||
.actions
|
||||
= f.submit 'Save', class: "btn primary"
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -1,8 +0,0 @@
|
|||
%p.slead
|
||||
Edit access for
|
||||
= link_to @admin_team_member.user_name, admin_user_path(@admin_team_member)
|
||||
in
|
||||
= link_to @admin_team_member.project.name_with_namespace, admin_project_path(@admin_team_member)
|
||||
|
||||
%hr
|
||||
= render 'form'
|
|
@ -0,0 +1,23 @@
|
|||
%h3.page_title Rename Team
|
||||
%hr
|
||||
= form_for @team, url: admin_team_path(@team), method: :put do |f|
|
||||
- if @team.errors.any?
|
||||
.alert-message.block-message.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_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 'Rename team', class: "btn danger"
|
||||
= link_to 'Cancel', admin_teams_path, class: "btn cancel-btn"
|
|
@ -0,0 +1,38 @@
|
|||
%h3.page_title
|
||||
Teams
|
||||
%small
|
||||
simple Teams description
|
||||
|
||||
= link_to 'New Team', new_admin_team_path, class: "btn small right"
|
||||
%br
|
||||
|
||||
= form_tag admin_teams_path, method: :get, class: 'form-inline' do
|
||||
= text_field_tag :name, params[:name], class: "xlarge"
|
||||
= submit_tag "Search", class: "btn submit primary"
|
||||
|
||||
%table
|
||||
%thead
|
||||
%tr
|
||||
%th
|
||||
Name
|
||||
%i.icon-sort-down
|
||||
%th Path
|
||||
%th Projects
|
||||
%th Members
|
||||
%th Owner
|
||||
%th.cred Danger Zone!
|
||||
|
||||
- @teams.each do |team|
|
||||
%tr
|
||||
%td
|
||||
%strong= link_to team.name, admin_team_path(team)
|
||||
%td= team.path
|
||||
%td= team.projects.count
|
||||
%td= team.members.count
|
||||
%td
|
||||
= link_to team.owner.name, admin_user_path(team.owner_id)
|
||||
%td.bgred
|
||||
= link_to 'Rename', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn small"
|
||||
= link_to 'Destroy', admin_team_path(team), confirm: "REMOVE #{team.name}? Are you sure?", method: :delete, class: "btn small danger"
|
||||
|
||||
= paginate @teams, theme: "admin"
|
|
@ -0,0 +1,20 @@
|
|||
= form_tag admin_team_member_path(@team, @member), method: :put do
|
||||
-if @member.errors.any?
|
||||
.alert-message.block-message.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 primary"
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -0,0 +1,16 @@
|
|||
%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'
|
|
@ -0,0 +1,29 @@
|
|||
%h3.page_title
|
||||
Team: #{@team.name}
|
||||
|
||||
%fieldset
|
||||
%legend Members (#{@team.members.count})
|
||||
= form_tag admin_team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do
|
||||
%table#members_list
|
||||
%thead
|
||||
%tr
|
||||
%th User name
|
||||
%th Default project access
|
||||
%th Team access
|
||||
%th
|
||||
- @team.members.each do |member|
|
||||
%tr.member
|
||||
%td
|
||||
= link_to [:admin, member] do
|
||||
= member.name
|
||||
%small= "(#{member.email})"
|
||||
%td= @team.human_default_projects_access(member)
|
||||
%td= @team.admin?(member) ? "Admin" : "Member"
|
||||
%td
|
||||
%tr
|
||||
%td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name_with_email), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5'
|
||||
%td= select_tag :default_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" }
|
||||
%td
|
||||
%span= check_box_tag :group_admin
|
||||
%span Admin?
|
||||
%td= submit_tag 'Add', class: "btn primary", id: :add_members_to_team
|
|
@ -0,0 +1,19 @@
|
|||
%h3.page_title New Team
|
||||
%hr
|
||||
= form_for @team, url: admin_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"
|
||||
|
||||
= f.submit 'Create team', class: "btn primary"
|
||||
%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
|
|
@ -0,0 +1,16 @@
|
|||
= form_tag admin_team_project_path(@team, @project), method: :put do
|
||||
-if @project.errors.any?
|
||||
.alert-message.block-message.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 primary"
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -0,0 +1,16 @@
|
|||
%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'
|
|
@ -0,0 +1,23 @@
|
|||
%h3.page_title
|
||||
Team: #{@team.name}
|
||||
|
||||
%fieldset
|
||||
%legend Projects (#{@team.projects.count})
|
||||
= form_tag admin_team_projects_path(@team), id: "assign_projects", class: "bulk_import", method: :post do
|
||||
%table#projects_list
|
||||
%thead
|
||||
%tr
|
||||
%th Project name
|
||||
%th Max access
|
||||
%th
|
||||
- @team.projects.each do |project|
|
||||
%tr.project
|
||||
%td
|
||||
= link_to project.name_with_namespace, [:admin, project]
|
||||
%td
|
||||
%span= @team.human_max_project_access(project)
|
||||
%td
|
||||
%tr
|
||||
%td= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
|
||||
%td= select_tag :greatest_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" }
|
||||
%td= submit_tag 'Add', class: "btn primary", id: :assign_projects_to_team
|
|
@ -0,0 +1,101 @@
|
|||
%h3.page_title
|
||||
Team: #{@team.name}
|
||||
|
||||
%br
|
||||
%table.zebra-striped
|
||||
%thead
|
||||
%tr
|
||||
%th Team
|
||||
%th
|
||||
%tr
|
||||
%td
|
||||
%b
|
||||
Name:
|
||||
%td
|
||||
= @team.name
|
||||
|
||||
= link_to edit_admin_team_path(@team), class: "btn btn-small right" do
|
||||
%i.icon-edit
|
||||
Rename
|
||||
%tr
|
||||
%td
|
||||
%b
|
||||
Owner:
|
||||
%td
|
||||
= @team.owner.name
|
||||
.right
|
||||
= link_to "#", class: "btn btn-small change-owner-link" do
|
||||
%i.icon-edit
|
||||
Change owner
|
||||
|
||||
%tr.change-owner-holder.hide
|
||||
%td.bgred
|
||||
%b.cred
|
||||
New Owner:
|
||||
%td.bgred
|
||||
= form_for @team, url: admin_team_path(@team) do |f|
|
||||
= f.select :owner_id, User.all.map { |user| [user.name, user.id] }, {}, {class: 'chosen'}
|
||||
%div
|
||||
= f.submit 'Change Owner', class: "btn danger"
|
||||
= link_to "Cancel", "#", class: "btn change-owner-cancel-link"
|
||||
|
||||
%fieldset
|
||||
%legend
|
||||
Members (#{@team.members.count})
|
||||
%span= link_to 'Add members', new_admin_team_member_path(@team), class: "btn success small right", id: :add_members_to_team
|
||||
- if @team.members.any?
|
||||
%table#members_list
|
||||
%thead
|
||||
%tr
|
||||
%th User name
|
||||
%th Default project access
|
||||
%th Team access
|
||||
%th.cred.span3 Danger Zone!
|
||||
- @team.members.each do |member|
|
||||
%tr.member{ class: "user_#{member.id}"}
|
||||
%td
|
||||
= link_to [:admin, member] do
|
||||
= member.name
|
||||
%small= "(#{member.email})"
|
||||
%td= @team.human_default_projects_access(member)
|
||||
%td= @team.admin?(member) ? "Admin" : "Member"
|
||||
%td.bgred
|
||||
= link_to 'Edit', edit_admin_team_member_path(@team, member), class: "btn small"
|
||||
|
||||
= link_to 'Remove', admin_team_member_path(@team, member), confirm: 'Remove member from team. Are you sure?', method: :delete, class: "btn danger small", id: "remove_member_#{member.id}"
|
||||
|
||||
%fieldset
|
||||
%legend
|
||||
Projects (#{@team.projects.count})
|
||||
%span= link_to 'Add projects', new_admin_team_project_path(@team), class: "btn success small right", id: :assign_projects_to_team
|
||||
- if @team.projects.any?
|
||||
%table#projects_list
|
||||
%thead
|
||||
%tr
|
||||
%th Project name
|
||||
%th Max access
|
||||
%th.cred.span3 Danger Zone!
|
||||
- @team.projects.each do |project|
|
||||
%tr.project
|
||||
%td
|
||||
= link_to project.name_with_namespace, [:admin, project]
|
||||
%td
|
||||
%span= @team.human_max_project_access(project)
|
||||
%td.bgred
|
||||
= link_to 'Edit', edit_admin_team_project_path(@team, project), class: "btn small"
|
||||
|
||||
= link_to 'Relegate', admin_team_project_path(@team, project), confirm: 'Remove project from team. Are you sure?', method: :delete, class: "btn danger small", id: "relegate_project_#{project.id}"
|
||||
|
||||
:javascript
|
||||
$(function(){
|
||||
var modal = $('.change-owner-holder');
|
||||
$('.change-owner-link').bind("click", function(){
|
||||
$(this).hide();
|
||||
modal.show();
|
||||
});
|
||||
$('.change-owner-cancel-link').bind("click", function(){
|
||||
modal.hide();
|
||||
$('.change-owner-link').show();
|
||||
})
|
||||
})
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
.groups_box
|
||||
.ui-box
|
||||
%h5.title
|
||||
Groups
|
||||
%small
|
||||
|
@ -13,8 +13,6 @@
|
|||
%li
|
||||
= link_to group_path(id: group.path), class: dom_class(group) do
|
||||
%strong.well-title= truncate(group.name, length: 35)
|
||||
%span.arrow
|
||||
→
|
||||
%span.last_activity
|
||||
%strong Projects:
|
||||
%span= current_user.authorized_projects.where(namespace_id: group.id).count
|
||||
%span.right.light
|
||||
- if group.owner == current_user
|
||||
%i.icon-wrench
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
- if @teams.present?
|
||||
= render "teams", teams: @teams
|
||||
- if @groups.present?
|
||||
= render "groups", groups: @groups
|
||||
= render "projects", projects: @projects
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
.ui-box
|
||||
%h5.title
|
||||
Teams
|
||||
%small
|
||||
(#{@teams.count})
|
||||
%span.right
|
||||
= link_to new_team_path, class: "btn very_small info" do
|
||||
%i.icon-plus
|
||||
New Team
|
||||
%ul.well-list
|
||||
- @teams.each do |team|
|
||||
%li
|
||||
= link_to team_path(id: team.path), class: dom_class(team) do
|
||||
%strong.well-title= truncate(team.name, length: 35)
|
||||
%span.right.light
|
||||
- if team.owner == current_user
|
||||
%i.icon-wrench
|
||||
- tm = current_user.user_team_user_relationships.find_by_user_team_id(team.id)
|
||||
- if tm
|
||||
= tm.access_human
|
|
@ -10,6 +10,8 @@
|
|||
= link_to "Stats", admin_root_path
|
||||
= 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
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
= render "layouts/head", title: "#{@group.name}"
|
||||
%body{class: "#{app_theme} application"}
|
||||
= render "layouts/flash"
|
||||
= render "layouts/head_panel", title: "#{@group.name}"
|
||||
= render "layouts/head_panel", title: "group: #{@group.name}"
|
||||
.container
|
||||
%ul.main_menu
|
||||
= nav_link(path: 'groups#show', html_options: {class: 'home'}) do
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
!!! 5
|
||||
%html{ lang: "en"}
|
||||
= render "layouts/head", title: "#{@team.name}"
|
||||
%body{class: "#{app_theme} application"}
|
||||
= render "layouts/flash"
|
||||
= render "layouts/head_panel", title: "team: #{@team.name}"
|
||||
.container
|
||||
%ul.main_menu
|
||||
= nav_link(path: 'teams#show', html_options: {class: 'home'}) do
|
||||
= link_to "Home", team_path(@team), title: "Home"
|
||||
|
||||
= nav_link(path: 'teams#issues') do
|
||||
= link_to issues_team_path(@team) do
|
||||
Issues
|
||||
%span.count= Issue.opened.of_user_team(@team).count
|
||||
|
||||
= nav_link(path: 'teams#merge_requests') do
|
||||
= link_to merge_requests_team_path(@team) do
|
||||
Merge Requests
|
||||
%span.count= MergeRequest.opened.of_user_team(@team).count
|
||||
|
||||
= nav_link(path: 'teams#search') do
|
||||
= link_to "Search", search_team_path(@team)
|
||||
|
||||
= nav_link(controller: [:members]) do
|
||||
= link_to team_members_path(@team), class: "team-tab tab" do
|
||||
Members
|
||||
|
||||
- if can? current_user, :admin_user_team, @team
|
||||
= nav_link(controller: [:projects]) do
|
||||
= link_to team_projects_path(@team), class: "team-tab tab" do
|
||||
%i.icon-briefcase
|
||||
Projects
|
||||
|
||||
= nav_link(path: 'teams#edit') do
|
||||
= link_to edit_team_path(@team), class: "stat-tab tab " do
|
||||
%i.icon-edit
|
||||
Edit Team
|
||||
|
||||
.content= yield
|
|
@ -3,7 +3,7 @@
|
|||
= link_to project_path(@project), class: "activities-tab tab" do
|
||||
%i.icon-home
|
||||
Show
|
||||
= nav_link(controller: :team_members) do
|
||||
= nav_link(controller: [:team_members, :teams]) do
|
||||
= link_to project_team_index_path(@project), class: "team-tab tab" do
|
||||
%i.icon-user
|
||||
Team
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
= render "projects/project_head"
|
||||
|
||||
%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 save-btn"
|
||||
= link_to "Cancel", project_team_index_path(@project), class: "btn cancel-btn"
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
%h3.page_title
|
||||
= "New Team member(s)"
|
||||
%hr
|
||||
= form_for @team_member, as: :team_member, url: project_team_members_path(@project, @team_member) do |f|
|
||||
-if @team_member.errors.any?
|
||||
= form_for @user_project_relation, as: :team_member, url: project_team_members_path(@project) do |f|
|
||||
-if @user_project_relation.errors.any?
|
||||
.alert-message.block-message.error
|
||||
%ul
|
||||
- @team_member.errors.full_messages.each do |msg|
|
||||
- @user_project_relation.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
%h6 1. Choose people you want in the team
|
||||
|
@ -16,7 +16,7 @@
|
|||
%h6 2. Set access level for them
|
||||
.clearfix
|
||||
= f.label :project_access, "Project Access"
|
||||
.input= select_tag :project_access, options_for_select(Project.access_options, @team_member.project_access), class: "project-access-select chosen"
|
||||
.input= select_tag :project_access, options_for_select(Project.access_options, @user_project_relation.project_access), class: "project-access-select chosen"
|
||||
|
||||
.actions
|
||||
= f.submit 'Save', class: "btn save-btn"
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
- user = member.user
|
||||
- allow_admin = can? current_user, :admin_project, @project
|
||||
%li{id: dom_id(member), class: "team_member_row user_#{user.id}"}
|
||||
%li{id: dom_id(user), class: "team_member_row user_#{user.id}"}
|
||||
.row
|
||||
.span6
|
||||
= link_to project_team_member_path(@project, member), title: user.name, class: "dark" do
|
||||
= link_to project_team_member_path(@project, user), title: user.name, class: "dark" do
|
||||
= image_tag gravatar_icon(user.email, 40), class: "avatar s32"
|
||||
= link_to project_team_member_path(@project, member), title: user.name, class: "dark" do
|
||||
= link_to project_team_member_path(@project, user), title: user.name, class: "dark" do
|
||||
%strong= truncate(user.name, lenght: 40)
|
||||
%br
|
||||
%small.cgray= user.email
|
||||
|
@ -13,7 +13,7 @@
|
|||
.span5.right
|
||||
- if allow_admin
|
||||
.left
|
||||
= form_for(member, as: :team_member, url: project_team_member_path(@project, member)) do |f|
|
||||
= form_for(member, as: :team_member, url: project_team_member_path(@project, member.user)) do |f|
|
||||
= f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, class: "medium project-access-select span2"
|
||||
.right
|
||||
- if current_user == user
|
||||
|
@ -23,6 +23,6 @@
|
|||
- elsif user.blocked
|
||||
%span.btn.disabled.blocked Blocked
|
||||
- elsif allow_admin
|
||||
= link_to project_team_member_path(project_id: @project, id: member.id), confirm: remove_from_team_message(@project, member), method: :delete, class: "very_small btn danger" do
|
||||
= link_to project_team_member_path(@project, user), confirm: remove_from_project_team_message(@project, user), method: :delete, class: "very_small btn danger" do
|
||||
%i.icon-minus.icon-white
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
- team = team_rel.user_team
|
||||
- allow_admin = can? current_user, :admin_team_member, @project
|
||||
%li{id: dom_id(team), class: "user_team_row team_#{team.id}"}
|
||||
.row
|
||||
.span6
|
||||
%strong= link_to team.name, team_path(team), title: team.name, class: "dark"
|
||||
%br
|
||||
%small.cgray Members: #{team.members.count}
|
||||
|
||||
.span5.right
|
||||
.right
|
||||
- if allow_admin
|
||||
.left
|
||||
= link_to resign_project_team_path(@project, team), method: :delete, confirm: "Are you shure?", class: "btn danger small" do
|
||||
%i.icon-minus.icon-white
|
|
@ -0,0 +1,16 @@
|
|||
- grouper_project_teams(@project).each do |access, teams|
|
||||
.ui-box
|
||||
%h5.title
|
||||
= UserTeam.access_roles.key(access).pluralize
|
||||
%small= teams.size
|
||||
%ul.well-list
|
||||
- teams.sort_by(&:team_name).each do |tofr|
|
||||
= render(partial: 'team_members/show_team', locals: {team_rel: tofr})
|
||||
|
||||
|
||||
:javascript
|
||||
$(function(){
|
||||
$('.repo-access-select, .project-access-select').live("change", function() {
|
||||
$(this.form).submit();
|
||||
});
|
||||
})
|
|
@ -1,4 +1,4 @@
|
|||
- if @team_member.valid?
|
||||
- if @user_project_relation.valid?
|
||||
:plain
|
||||
$("#new_team_member").hide("slide", { direction: "right" }, 150, function(){
|
||||
$("#team-table").show("slide", { direction: "left" }, 150, function() {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
= "Import team from another project"
|
||||
%hr
|
||||
%p.slead
|
||||
Read more about team import #{link_to "here", '#', class: 'vlink'}.
|
||||
Read more about project team import #{link_to "here", '#', class: 'vlink'}.
|
||||
= form_tag apply_import_project_team_members_path(@project), method: 'post' do
|
||||
%p.slead Choose project you want to use as team source:
|
||||
.padded
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
= render "projects/project_head"
|
||||
%h3.page_title
|
||||
Team Members
|
||||
(#{@project.users_projects.count})
|
||||
(#{@project.users.count})
|
||||
%small
|
||||
Read more about project permissions
|
||||
%strong= link_to "here", help_permissions_path, class: "vlink"
|
||||
|
@ -10,11 +10,24 @@
|
|||
%span.right
|
||||
= link_to import_project_team_members_path(@project), class: "btn small grouped", title: "Import team from another project" do
|
||||
Import team from another project
|
||||
= link_to available_project_teams_path(@project), class: "btn small grouped", title: "Assign project to team of users" do
|
||||
Assign project to Team of users
|
||||
= link_to new_project_team_member_path(@project), class: "btn success small grouped", title: "New Team Member" do
|
||||
New Team Member
|
||||
%hr
|
||||
|
||||
%hr
|
||||
|
||||
.clearfix
|
||||
%div.team-table
|
||||
= render partial: "team_members/team", locals: {project: @project}
|
||||
|
||||
|
||||
%h3.page_title
|
||||
Assigned teams
|
||||
(#{@project.user_teams.count})
|
||||
|
||||
%hr
|
||||
|
||||
.clearfix
|
||||
%div.team-table
|
||||
= render partial: "team_members/teams", locals: {project: @project}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
- allow_admin = can? current_user, :admin_project, @project
|
||||
- user = @team_member.user
|
||||
|
||||
.team_member_show
|
||||
- if can? current_user, :admin_project, @project
|
||||
= link_to 'Remove from team', project_team_member_path(project_id: @project, id: @team_member.id), confirm: 'Are you sure?', method: :delete, class: "right btn danger"
|
||||
= link_to 'Remove from team', project_team_member_path(@project, @member), confirm: 'Are you sure?', method: :delete, class: "right btn danger"
|
||||
.profile_avatar_holder
|
||||
= image_tag gravatar_icon(user.email, 60), class: "borders"
|
||||
= image_tag gravatar_icon(@member.email, 60), class: "borders"
|
||||
%h3.page_title
|
||||
= user.name
|
||||
%small (@#{user.username})
|
||||
= @member.name
|
||||
%small (@#{@member.username})
|
||||
|
||||
%hr
|
||||
.back_link
|
||||
|
@ -21,34 +20,34 @@
|
|||
%table.lite
|
||||
%tr
|
||||
%td Email
|
||||
%td= mail_to user.email
|
||||
%td= mail_to @member.email
|
||||
%tr
|
||||
%td Skype
|
||||
%td= user.skype
|
||||
- unless user.linkedin.blank?
|
||||
%td= @member.skype
|
||||
- unless @member.linkedin.blank?
|
||||
%tr
|
||||
%td LinkedIn
|
||||
%td= user.linkedin
|
||||
- unless user.twitter.blank?
|
||||
%td= @member.linkedin
|
||||
- unless @member.twitter.blank?
|
||||
%tr
|
||||
%td Twitter
|
||||
%td= user.twitter
|
||||
- unless user.bio.blank?
|
||||
%td= @member.twitter
|
||||
- unless @member.bio.blank?
|
||||
%tr
|
||||
%td Bio
|
||||
%td= user.bio
|
||||
%td= @member.bio
|
||||
.span6
|
||||
%table.lite
|
||||
%tr
|
||||
%td Member since
|
||||
%td= @team_member.created_at.stamp("Aug 21, 2011")
|
||||
%td= @user_project_relation.created_at.stamp("Aug 21, 2011")
|
||||
%tr
|
||||
%td
|
||||
Project Access:
|
||||
%small (#{link_to "read more", help_permissions_path, class: "vlink"})
|
||||
%td
|
||||
= form_for(@team_member, as: :team_member, url: project_team_member_path(@project, @team_member)) do |f|
|
||||
= f.select :project_access, options_for_select(Project.access_options, @team_member.project_access), {}, class: "project-access-select", disabled: !allow_admin
|
||||
= form_for(@user_project_relation, as: :team_member, url: project_team_member_path(@project, @member)) do |f|
|
||||
= f.select :project_access, options_for_select(Project.access_options, @user_project_relation.project_access), {}, class: "project-access-select", disabled: !allow_admin
|
||||
%hr
|
||||
= render @events
|
||||
:javascript
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- if @team_member.valid?
|
||||
- if @user_project_relation.valid?
|
||||
:plain
|
||||
$("##{dom_id(@team_member)}").effect("highlight", {color: "#529214"}, 1000);;
|
||||
$("##{dom_id(@user_project_relation)}").effect("highlight", {color: "#529214"}, 1000);;
|
||||
- else
|
||||
:plain
|
||||
$("##{dom_id(@team_member)}").effect("highlight", {color: "#D12F19"}, 1000);;
|
||||
$("##{dom_id(@user_project_relation)}").effect("highlight", {color: "#D12F19"}, 1000);;
|
||||
|
|
|
@ -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'
|
||||
|
|
@ -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 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, length: 25)
|
||||
%span.arrow
|
||||
→
|
||||
%span.last_activity
|
||||
%strong Last activity:
|
||||
%span= project_last_activity(project)
|
|
@ -0,0 +1,24 @@
|
|||
= render "team_head"
|
||||
|
||||
%h3.page_title= "Edit Team #{@team.name}"
|
||||
%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"
|
||||
|
||||
.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(@team), method: :delete, confirm: "You are shure?", class: "btn danger"
|
|
@ -0,0 +1,38 @@
|
|||
%h3.page_title
|
||||
Teams
|
||||
%small
|
||||
list of all teams
|
||||
|
||||
= link_to 'New Team', new_team_path, class: "btn success 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.cred Danger Zone!
|
||||
|
||||
- @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.bgred
|
||||
- if current_user.can?(:manage_user_team, team)
|
||||
= link_to "Edit", edit_team_path(team), class: "btn small"
|
||||
- if current_user.can?(:admin_user_team, team)
|
||||
= link_to "Destroy", team_path(team), method: :delete, confirm: "You are shure?", class: "danger btn small"
|
||||
|
|
@ -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
|
|
@ -0,0 +1,20 @@
|
|||
= form_tag admin_team_member_path(@team, @member), method: :put do
|
||||
-if @member.errors.any?
|
||||
.alert-message.block-message.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 primary"
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -0,0 +1,31 @@
|
|||
- 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
|
||||
.span5
|
||||
= 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.email
|
||||
|
||||
.span6.right
|
||||
- if allow_admin
|
||||
.left.span2
|
||||
= form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f|
|
||||
= f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "medium project-access-select span2"
|
||||
.left.span2
|
||||
%span
|
||||
Admin access
|
||||
= check_box_tag :group_admin
|
||||
.right
|
||||
- if current_user == user
|
||||
%span.btn.disabled This is you!
|
||||
- if @team.owner == user
|
||||
%span.btn.disabled.success Owner
|
||||
- elsif user.blocked
|
||||
%span.btn.disabled.blocked Blocked
|
||||
- elsif allow_admin
|
||||
= link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "very_small btn danger" do
|
||||
%i.icon-minus.icon-white
|
|
@ -0,0 +1,16 @@
|
|||
- grouped_user_team_members(@team).each do |access, members|
|
||||
.ui-box
|
||||
%h5.title
|
||||
= Project.access_options.key(access).pluralize
|
||||
%small= members.size
|
||||
%ul.well-list
|
||||
- members.sort_by(&:user_name).each do |up|
|
||||
= render(partial: 'teams/members/show', locals: {member: up})
|
||||
|
||||
|
||||
:javascript
|
||||
$(function(){
|
||||
$('.repo-access-select, .project-access-select').live("change", function() {
|
||||
$(this.form).submit();
|
||||
});
|
||||
})
|
|
@ -0,0 +1,18 @@
|
|||
= render "teams/team_head"
|
||||
|
||||
%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'
|
|
@ -0,0 +1,19 @@
|
|||
= render "teams/team_head"
|
||||
|
||||
%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.right
|
||||
= link_to new_team_member_path(@team), class: "btn success small grouped", title: "New Team Member" do
|
||||
New Team Member
|
||||
%hr
|
||||
|
||||
|
||||
.clearfix
|
||||
%div.team-table
|
||||
= render partial: "teams/members/team", locals: {project: @team}
|
|
@ -0,0 +1,30 @@
|
|||
= render "teams/team_head"
|
||||
|
||||
%h3.page_title
|
||||
Team: #{@team.name}
|
||||
|
||||
%fieldset
|
||||
%legend Members (#{@team.members.count})
|
||||
= form_tag team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do
|
||||
%table#members_list
|
||||
%thead
|
||||
%tr
|
||||
%th User name
|
||||
%th Default project access
|
||||
%th Team access
|
||||
%th
|
||||
- @team.members.each do |member|
|
||||
%tr.member
|
||||
%td
|
||||
= member.name
|
||||
%small= "(#{member.email})"
|
||||
%td= @team.human_default_projects_access(member)
|
||||
%td= @team.admin?(member) ? "Admin" : "Member"
|
||||
%td
|
||||
%tr
|
||||
%td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name_with_email), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5'
|
||||
%td= select_tag :default_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" }
|
||||
%td
|
||||
%span= check_box_tag :group_admin
|
||||
%span Admin?
|
||||
%td= submit_tag 'Add', class: "btn primary", id: :add_members_to_team
|
|
@ -0,0 +1,62 @@
|
|||
= render "teams/team_head"
|
||||
|
||||
- allow_admin = can? current_user, :admin_project, @project
|
||||
- user = @team_member.user
|
||||
|
||||
.team_member_show
|
||||
- if can? current_user, :admin_project, @project
|
||||
= link_to 'Remove from team', project_team_member_path(project_id: @project, id: @team_member.id), confirm: 'Are you sure?', method: :delete, class: "right btn danger"
|
||||
.profile_avatar_holder
|
||||
= image_tag gravatar_icon(user.email, 60), class: "borders"
|
||||
%h3.page_title
|
||||
= user.name
|
||||
%small (@#{user.username})
|
||||
|
||||
%hr
|
||||
.back_link
|
||||
%br
|
||||
= link_to project_team_index_path(@project), class: "" do
|
||||
← To team list
|
||||
%br
|
||||
.row
|
||||
.span6
|
||||
%table.lite
|
||||
%tr
|
||||
%td Email
|
||||
%td= mail_to user.email
|
||||
%tr
|
||||
%td Skype
|
||||
%td= user.skype
|
||||
- unless user.linkedin.blank?
|
||||
%tr
|
||||
%td LinkedIn
|
||||
%td= user.linkedin
|
||||
- unless user.twitter.blank?
|
||||
%tr
|
||||
%td Twitter
|
||||
%td= user.twitter
|
||||
- unless user.bio.blank?
|
||||
%tr
|
||||
%td Bio
|
||||
%td= user.bio
|
||||
.span6
|
||||
%table.lite
|
||||
%tr
|
||||
%td Member since
|
||||
%td= @team_member.created_at.stamp("Aug 21, 2011")
|
||||
%tr
|
||||
%td
|
||||
Project Access:
|
||||
%small (#{link_to "read more", help_permissions_path, class: "vlink"})
|
||||
%td
|
||||
= form_for(@team_member, as: :team_member, url: project_team_member_path(@project, @team_member)) do |f|
|
||||
= f.select :project_access, options_for_select(Project.access_options, @team_member.project_access), {}, class: "project-access-select", disabled: !allow_admin
|
||||
%hr
|
||||
= render @events
|
||||
:javascript
|
||||
$(function(){
|
||||
$('.repo-access-select, .project-access-select').live("change", function() {
|
||||
$(this.form).submit();
|
||||
});
|
||||
})
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
= render "team_head"
|
||||
|
||||
%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
|
|
@ -0,0 +1,19 @@
|
|||
%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. Ruby Developers", class: "xxlarge left"
|
||||
|
||||
= f.submit 'Create team', class: "btn primary"
|
||||
%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
|
|
@ -0,0 +1,16 @@
|
|||
= form_tag team_project_path(@team, @project), method: :put do
|
||||
-if @project.errors.any?
|
||||
.alert-message.block-message.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 primary"
|
||||
= link_to 'Cancel', :back, class: "btn"
|
|
@ -0,0 +1,18 @@
|
|||
= render "teams/team_head"
|
||||
|
||||
%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'
|
|
@ -0,0 +1,34 @@
|
|||
= render "teams/team_head"
|
||||
|
||||
%h3.page_title
|
||||
Assigned projects (#{@team.projects.count})
|
||||
%small
|
||||
Read more about project permissions
|
||||
%strong= link_to "here", help_permissions_path, class: "vlink"
|
||||
|
||||
- if current_user.can?(:manage_user_team, @team) && @avaliable_projects.any?
|
||||
%span.right
|
||||
= link_to new_team_project_path(@team), class: "btn success small grouped", title: "New Team Member" do
|
||||
Assign project to Team
|
||||
|
||||
%hr
|
||||
|
||||
%table.projects-table
|
||||
%thead
|
||||
%tr
|
||||
%th Project name
|
||||
%th Max access
|
||||
- if current_user.can?(:admin_user_team, @team)
|
||||
%th.span3
|
||||
|
||||
- @team.projects.each do |project|
|
||||
%tr.project
|
||||
%td
|
||||
= link_to project.name_with_namespace, project_path(project)
|
||||
%td
|
||||
%span= @team.human_max_project_access(project)
|
||||
|
||||
- if current_user.can?(:admin_user_team, @team)
|
||||
%td.bgred
|
||||
= link_to 'Edit max access', edit_team_project_path(@team, project), class: "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 danger small"
|
|
@ -0,0 +1,25 @@
|
|||
= render "teams/team_head"
|
||||
|
||||
%h3.page_title
|
||||
Team: #{@team.name}
|
||||
|
||||
%fieldset
|
||||
%legend Projects (#{@team.projects.count})
|
||||
= form_tag team_projects_path(@team), id: "assign_projects", class: "bulk_import", method: :post do
|
||||
%table#projects_list
|
||||
%thead
|
||||
%tr
|
||||
%th Project name
|
||||
%th Max access
|
||||
%th
|
||||
- @team.projects.each do |project|
|
||||
%tr.project
|
||||
%td
|
||||
= link_to project.name_with_namespace, team_project_path(@team, project)
|
||||
%td
|
||||
%span= @team.human_max_project_access(project)
|
||||
%td
|
||||
%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 span5'
|
||||
%td= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles), {class: "project-access-select chosen span3" }
|
||||
%td= submit_tag 'Add', class: "btn primary", id: :assign_projects_to_team
|
|
@ -0,0 +1,11 @@
|
|||
= render "team_head"
|
||||
|
||||
= form_tag search_team_path(@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'
|
|
@ -0,0 +1,30 @@
|
|||
= render "team_head"
|
||||
|
||||
.projects
|
||||
.activities.span8
|
||||
= link_to dashboard_path, class: 'btn very_small' 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
|
||||
= 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); });
|
|
@ -21,7 +21,7 @@ Gitlab::Application.routes.draw do
|
|||
project_root: Gitlab.config.gitolite.repos_path,
|
||||
upload_pack: Gitlab.config.gitolite.upload_pack,
|
||||
receive_pack: Gitlab.config.gitolite.receive_pack
|
||||
}), at: '/', constraints: lambda { |request| /[-\/\w\.-]+\.git\//.match(request.path_info) }
|
||||
}), at: '/', constraints: lambda { |request| /[-\/\w\.]+\.git\//.match(request.path_info) }
|
||||
|
||||
#
|
||||
# Help
|
||||
|
@ -56,6 +56,7 @@ Gitlab::Application.routes.draw do
|
|||
put :unblock
|
||||
end
|
||||
end
|
||||
|
||||
resources :groups, constraints: { id: /[^\/]+/ } do
|
||||
member do
|
||||
put :project_update
|
||||
|
@ -63,18 +64,31 @@ Gitlab::Application.routes.draw do
|
|||
delete :remove_project
|
||||
end
|
||||
end
|
||||
|
||||
resources :teams, constraints: { id: /[^\/]+/ } do
|
||||
scope module: :teams do
|
||||
resources :members, only: [:edit, :update, :destroy, :new, :create]
|
||||
resources :projects, only: [:edit, :update, :destroy, :new, :create], constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }
|
||||
end
|
||||
end
|
||||
|
||||
resources :hooks, only: [:index, :create, :destroy] do
|
||||
get :test
|
||||
end
|
||||
|
||||
resource :logs, only: [:show]
|
||||
resource :resque, controller: 'resque', only: [:show]
|
||||
|
||||
resources :projects, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }, except: [:new, :create] do
|
||||
member do
|
||||
get :team
|
||||
put :team_update
|
||||
end
|
||||
scope module: :projects, constraints: { id: /[^\/]+/ } do
|
||||
resources :members, only: [:edit, :update, :destroy]
|
||||
end
|
||||
end
|
||||
resources :team_members, only: [:edit, :update, :destroy]
|
||||
resources :hooks, only: [:index, :create, :destroy] do
|
||||
get :test
|
||||
end
|
||||
resource :logs, only: [:show]
|
||||
resource :resque, controller: 'resque', only: [:show]
|
||||
|
||||
root to: "dashboard#index"
|
||||
end
|
||||
|
||||
|
@ -108,7 +122,6 @@ Gitlab::Application.routes.draw do
|
|||
get "dashboard/issues" => "dashboard#issues"
|
||||
get "dashboard/merge_requests" => "dashboard#merge_requests"
|
||||
|
||||
|
||||
#
|
||||
# Groups Area
|
||||
#
|
||||
|
@ -122,6 +135,24 @@ Gitlab::Application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Teams Area
|
||||
#
|
||||
resources :teams, constraints: { id: /[^\/]+/ } do
|
||||
member do
|
||||
get :issues
|
||||
get :merge_requests
|
||||
get :search
|
||||
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
|
||||
collection do
|
||||
get :search
|
||||
end
|
||||
end
|
||||
|
||||
resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create]
|
||||
|
||||
devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations }
|
||||
|
@ -238,6 +269,18 @@ 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
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
class CreateUserTeams < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :user_teams do |t|
|
||||
t.string :name
|
||||
t.string :path
|
||||
t.integer :owner_id
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
class CreateUserTeamProjectRelationships < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :user_team_project_relationships do |t|
|
||||
t.integer :project_id
|
||||
t.integer :user_team_id
|
||||
t.integer :greatest_access
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
class CreateUserTeamUserRelationships < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :user_team_user_relationships do |t|
|
||||
t.integer :user_id
|
||||
t.integer :user_team_id
|
||||
t.boolean :group_admin
|
||||
t.integer :permission
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
25
db/schema.rb
25
db/schema.rb
|
@ -213,6 +213,31 @@ ActiveRecord::Schema.define(:version => 20130110172407) do
|
|||
t.string "name"
|
||||
end
|
||||
|
||||
create_table "user_team_project_relationships", :force => true do |t|
|
||||
t.integer "project_id"
|
||||
t.integer "user_team_id"
|
||||
t.integer "greatest_access"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "user_team_user_relationships", :force => true do |t|
|
||||
t.integer "user_id"
|
||||
t.integer "user_team_id"
|
||||
t.boolean "group_admin"
|
||||
t.integer "permission"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "user_teams", :force => true do |t|
|
||||
t.string "name"
|
||||
t.string "path"
|
||||
t.integer "owner_id"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "users", :force => true do |t|
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :default => "", :null => false
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue