Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dzaporozhets@gitlab.com>2015-03-16 09:44:53 +0300
committerDmitriy Zaporozhets <dzaporozhets@gitlab.com>2015-03-16 09:44:53 +0300
commitaad3cbeec52cf5bbb5a2c724eeb9b946be6f0fe9 (patch)
tree0abaf6993de9f7625a416f6e7259d9ad45c8c15b /app
parent60df262c38d7c235b483cc1c4beb12f793e0e58a (diff)
parent584580e5156020e639b2a578c332ae92e38b3a5c (diff)
Merge branch 'team-members' into 'master'
Use same layout and interactivity for project members as group members and make code more consistent. It's probably easiest to review the commits one by one, but keep in mind that later commits sometimes touch the same place as earlier ones, so look at the complete diff to add comments. The project members page and group members page now look and work the same, with an inline "Add members" form, member search and editing of access levels and deleting without page refresh. Before: ![Screen_Shot_2015-03-13_at_16.50.39](https://dev.gitlab.org/gitlab/gitlabhq/uploads/2cd023c48de0a643ce04df965f39e1f5/Screen_Shot_2015-03-13_at_16.50.39.png) After: ![Screen_Shot_2015-03-13_at_16.50.02](https://dev.gitlab.org/gitlab/gitlabhq/uploads/fdef480daf2859ed74f5641af1f337b3/Screen_Shot_2015-03-13_at_16.50.02.png) See merge request !1695
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee8
-rw-r--r--app/assets/javascripts/project_members.js.coffee4
-rw-r--r--app/assets/stylesheets/generic/common.scss2
-rw-r--r--app/assets/stylesheets/pages/projects.scss2
-rw-r--r--app/controllers/admin/groups_controller.rb4
-rw-r--r--app/controllers/dashboard/groups_controller.rb18
-rw-r--r--app/controllers/groups/application_controller.rb18
-rw-r--r--app/controllers/groups/group_members_controller.rb40
-rw-r--r--app/controllers/groups_controller.rb15
-rw-r--r--app/controllers/profiles/notifications_controller.rb6
-rw-r--r--app/controllers/projects/project_members_controller.rb88
-rw-r--r--app/controllers/projects/team_members_controller.rb73
-rw-r--r--app/helpers/search_helper.rb2
-rw-r--r--app/helpers/tab_helper.rb2
-rw-r--r--app/mailers/emails/groups.rb8
-rw-r--r--app/models/ability.rb16
-rw-r--r--app/models/issue.rb1
-rw-r--r--app/models/members/project_member.rb4
-rw-r--r--app/models/merge_request.rb1
-rw-r--r--app/models/project.rb5
-rw-r--r--app/models/project_team.rb42
-rw-r--r--app/models/user.rb5
-rw-r--r--app/services/notification_service.rb46
-rw-r--r--app/services/projects/participants_service.rb4
-rw-r--r--app/views/admin/groups/show.html.haml2
-rw-r--r--app/views/admin/projects/show.html.haml6
-rw-r--r--app/views/admin/users/show.html.haml24
-rw-r--r--app/views/dashboard/groups/index.html.haml14
-rw-r--r--app/views/groups/group_members/_group_member.html.haml9
-rw-r--r--app/views/groups/group_members/_new_group_member.html.haml (renamed from app/views/groups/_new_group_member.html.haml)4
-rw-r--r--app/views/groups/group_members/index.html.haml (renamed from app/views/groups/members.html.haml)4
-rw-r--r--app/views/groups/projects.html.haml2
-rw-r--r--app/views/layouts/nav/_group.html.haml4
-rw-r--r--app/views/notify/group_access_granted_email.html.haml2
-rw-r--r--app/views/notify/group_access_granted_email.text.erb2
-rw-r--r--app/views/profiles/notifications/show.html.haml6
-rw-r--r--app/views/projects/_dropdown.html.haml4
-rw-r--r--app/views/projects/_settings_nav.html.haml4
-rw-r--r--app/views/projects/project_members/_group_members.html.haml15
-rw-r--r--app/views/projects/project_members/_new_project_member.html.haml15
-rw-r--r--app/views/projects/project_members/_project_member.html.haml34
-rw-r--r--app/views/projects/project_members/_team.html.haml11
-rw-r--r--app/views/projects/project_members/import.html.haml (renamed from app/views/projects/team_members/import.html.haml)4
-rw-r--r--app/views/projects/project_members/index.html.haml35
-rw-r--r--app/views/projects/project_members/update.js.haml3
-rw-r--r--app/views/projects/team_members/_form.html.haml29
-rw-r--r--app/views/projects/team_members/_group_members.html.haml14
-rw-r--r--app/views/projects/team_members/_team.html.haml9
-rw-r--r--app/views/projects/team_members/_team_member.html.haml18
-rw-r--r--app/views/projects/team_members/index.html.haml16
-rw-r--r--app/views/projects/team_members/new.html.haml1
-rw-r--r--app/views/projects/team_members/update.js.haml6
52 files changed, 382 insertions, 329 deletions
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index e1015a63d52..edf482f33d8 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -73,9 +73,12 @@ class Dispatcher
new Activities()
shortcut_handler = new ShortcutsNavigation()
new ProjectsList()
- when 'groups:members'
+ when 'groups:group_members:index'
new GroupMembers()
new UsersSelect()
+ when 'projects:project_members:index'
+ new ProjectMembers()
+ new UsersSelect()
when 'groups:new', 'groups:edit', 'admin:groups:edit'
new GroupAvatar()
when 'projects:tree:show'
@@ -127,9 +130,8 @@ class Dispatcher
new DropzoneInput($('.wiki-form'))
when 'snippets', 'labels', 'graphs'
shortcut_handler = new ShortcutsNavigation()
- when 'team_members', 'deploy_keys', 'hooks', 'services', 'protected_branches'
+ when 'project_members', 'deploy_keys', 'hooks', 'services', 'protected_branches'
shortcut_handler = new ShortcutsNavigation()
- new UsersSelect()
# If we haven't installed a custom shortcut handler, install the default one
diff --git a/app/assets/javascripts/project_members.js.coffee b/app/assets/javascripts/project_members.js.coffee
new file mode 100644
index 00000000000..896ba7e53ee
--- /dev/null
+++ b/app/assets/javascripts/project_members.js.coffee
@@ -0,0 +1,4 @@
+class @ProjectMembers
+ constructor: ->
+ $('li.project_member').bind 'ajax:success', ->
+ $(this).fadeOut()
diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss
index af8e90eb1a9..876eea72e8a 100644
--- a/app/assets/stylesheets/generic/common.scss
+++ b/app/assets/stylesheets/generic/common.scss
@@ -167,7 +167,7 @@ li.note {
background-color: inherit;
}
-.team_member_show {
+.project_member_show {
td:first-child {
color: #aaa;
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index e359aa45025..74755951670 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -156,7 +156,7 @@ ul.nav.nav-projects-tabs {
}
}
-.team_member_row form {
+.project_member_row form {
margin: 0px;
}
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index e338abeac4c..9d9adaa467f 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -1,5 +1,5 @@
class Admin::GroupsController < Admin::ApplicationController
- before_filter :group, only: [:edit, :show, :update, :destroy, :project_update, :project_teams_update]
+ before_filter :group, only: [:edit, :show, :update, :destroy, :project_update, :members_update]
def index
@groups = Group.all
@@ -40,7 +40,7 @@ class Admin::GroupsController < Admin::ApplicationController
end
end
- def project_teams_update
+ def members_update
@group.add_users(params[:user_ids].split(','), params[:access_level])
redirect_to [:admin, @group], notice: 'Users were successfully added.'
diff --git a/app/controllers/dashboard/groups_controller.rb b/app/controllers/dashboard/groups_controller.rb
index b827639978c..ed14f4e1f3b 100644
--- a/app/controllers/dashboard/groups_controller.rb
+++ b/app/controllers/dashboard/groups_controller.rb
@@ -1,21 +1,5 @@
class Dashboard::GroupsController < ApplicationController
def index
- @user_groups = current_user.group_members.page(params[:page]).per(PER_PAGE)
- end
-
- def leave
- @users_group = group.group_members.where(user_id: current_user.id).first
- if can?(current_user, :destroy, @users_group)
- @users_group.destroy
- redirect_to(dashboard_groups_path, info: "You left #{group.name} group.")
- else
- return render_403
- end
- end
-
- private
-
- def group
- @group ||= Group.find_by(path: params[:id])
+ @group_members = current_user.group_members.page(params[:page]).per(PER_PAGE)
end
end
diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb
index 7f27f2bb734..a73b8fa212a 100644
--- a/app/controllers/groups/application_controller.rb
+++ b/app/controllers/groups/application_controller.rb
@@ -2,9 +2,27 @@ class Groups::ApplicationController < ApplicationController
private
+ def authorize_read_group!
+ unless @group and can?(current_user, :read_group, @group)
+ if current_user.nil?
+ return authenticate_user!
+ else
+ return render_404
+ end
+ end
+ end
+
def authorize_admin_group!
unless can?(current_user, :manage_group, group)
return render_404
end
end
+
+ def determine_layout
+ if current_user
+ 'group'
+ else
+ 'public_group'
+ end
+ end
end
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb
index b083cf5d8c5..2df51c97a22 100644
--- a/app/controllers/groups/group_members_controller.rb
+++ b/app/controllers/groups/group_members_controller.rb
@@ -1,15 +1,30 @@
class Groups::GroupMembersController < Groups::ApplicationController
+ skip_before_filter :authenticate_user!, only: [:index]
before_filter :group
# Authorize
- before_filter :authorize_admin_group!
+ before_filter :authorize_read_group!
+ before_filter :authorize_admin_group!, except: [:index, :leave]
- layout 'group'
+ layout :determine_layout
+
+ def index
+ @project = @group.projects.find(params[:project_id]) if params[:project_id]
+ @members = @group.group_members
+
+ if params[:search].present?
+ users = @group.users.search(params[:search]).to_a
+ @members = @members.where(user_id: users)
+ end
+
+ @members = @members.order('access_level DESC').page(params[:page]).per(50)
+ @group_member = GroupMember.new
+ end
def create
@group.add_users(params[:user_ids].split(','), params[:access_level])
- redirect_to members_group_path(@group), notice: 'Users were successfully added.'
+ redirect_to group_group_members_path(@group), notice: 'Users were successfully added.'
end
def update
@@ -18,12 +33,12 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
def destroy
- @users_group = @group.group_members.find(params[:id])
+ @group_member = @group.group_members.find(params[:id])
- if can?(current_user, :destroy, @users_group) # May fail if last owner.
- @users_group.destroy
+ if can?(current_user, :destroy_group_member, @group_member) # May fail if last owner.
+ @group_member.destroy
respond_to do |format|
- format.html { redirect_to members_group_path(@group), notice: 'User was successfully removed from group.' }
+ format.html { redirect_to group_group_members_path(@group), notice: 'User was successfully removed from group.' }
format.js { render nothing: true }
end
else
@@ -31,6 +46,17 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
end
+ def leave
+ @group_member = @group.group_members.where(user_id: current_user.id).first
+
+ if can?(current_user, :destroy_group_member, @group_member)
+ @group_member.destroy
+ redirect_to(dashboard_groups_path, info: "You left #{group.name} group.")
+ else
+ return render_403
+ end
+ end
+
protected
def group
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 7e336803fbb..7af3c077182 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -1,5 +1,5 @@
class GroupsController < Groups::ApplicationController
- skip_before_filter :authenticate_user!, only: [:show, :issues, :members, :merge_requests]
+ skip_before_filter :authenticate_user!, only: [:show, :issues, :merge_requests]
respond_to :html
before_filter :group, except: [:new, :create]
@@ -67,19 +67,6 @@ class GroupsController < Groups::ApplicationController
end
end
- def members
- @project = group.projects.find(params[:project_id]) if params[:project_id]
- @members = group.group_members
-
- if params[:search].present?
- users = group.users.search(params[:search]).to_a
- @members = @members.where(user_id: users)
- end
-
- @members = @members.order('access_level DESC').page(params[:page]).per(50)
- @users_group = GroupMember.new
- end
-
def edit
end
diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb
index 433c19189af..3fdcbbab61b 100644
--- a/app/controllers/profiles/notifications_controller.rb
+++ b/app/controllers/profiles/notifications_controller.rb
@@ -14,9 +14,9 @@ class Profiles::NotificationsController < ApplicationController
@saved = if type == 'global'
current_user.update_attributes(user_params)
elsif type == 'group'
- users_group = current_user.group_members.find(params[:notification_id])
- users_group.notification_level = params[:notification_level]
- users_group.save
+ group_member = current_user.group_members.find(params[:notification_id])
+ group_member.notification_level = params[:notification_level]
+ group_member.save
else
project_member = current_user.project_members.find(params[:notification_id])
project_member.notification_level = params[:notification_level]
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
new file mode 100644
index 00000000000..4ab15db01f7
--- /dev/null
+++ b/app/controllers/projects/project_members_controller.rb
@@ -0,0 +1,88 @@
+class Projects::ProjectMembersController < Projects::ApplicationController
+ # Authorize
+ before_filter :authorize_admin_project!, except: :leave
+
+ layout "project_settings"
+
+ def index
+ @project_members = @project.project_members
+
+ if params[:search].present?
+ users = @project.users.search(params[:search]).to_a
+ @project_members = @project_members.where(user_id: users)
+ end
+
+ @project_members = @project_members.order('access_level DESC')
+
+ @group = @project.group
+ if @group
+ @group_members = @group.group_members
+
+ if params[:search].present?
+ users = @group.users.search(params[:search]).to_a
+ @group_members = @group_members.where(user_id: users)
+ end
+
+ @group_members = @group_members.order('access_level DESC').limit(20)
+ end
+
+ @project_member = @project.project_members.new
+ end
+
+ def new
+ @project_member = @project.project_members.new
+ end
+
+ def create
+ users = User.where(id: params[:user_ids].split(','))
+ @project.team << [users, params[:access_level]]
+
+ redirect_to namespace_project_project_members_path(@project.namespace, @project)
+ end
+
+ def update
+ @project_member = @project.project_members.find_by(user_id: member)
+ @project_member.update_attributes(member_params)
+ end
+
+ def destroy
+ @project_member = @project.project_members.find_by(user_id: member)
+ @project_member.destroy
+
+ respond_to do |format|
+ format.html do
+ redirect_to namespace_project_project_members_path(@project.namespace,
+ @project)
+ end
+ format.js { render nothing: true }
+ end
+ end
+
+ def leave
+ @project.project_members.find_by(user_id: current_user).destroy
+
+ respond_to do |format|
+ format.html { redirect_to :back }
+ format.js { render nothing: true }
+ end
+ end
+
+ def apply_import
+ giver = Project.find(params[:source_project_id])
+ status = @project.team.import(giver)
+ notice = status ? "Successfully imported" : "Import failed"
+
+ redirect_to(namespace_project_project_members_path(project.namespace, project),
+ notice: notice)
+ end
+
+ protected
+
+ def member
+ @member ||= User.find_by(username: params[:id])
+ end
+
+ def member_params
+ params.require(:project_member).permit(:user_id, :access_level)
+ end
+end
diff --git a/app/controllers/projects/team_members_controller.rb b/app/controllers/projects/team_members_controller.rb
deleted file mode 100644
index f8a248ed729..00000000000
--- a/app/controllers/projects/team_members_controller.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-class Projects::TeamMembersController < Projects::ApplicationController
- # Authorize
- before_filter :authorize_admin_project!, except: :leave
-
- layout "project_settings"
-
- def index
- @group = @project.group
- @project_members = @project.project_members.order('access_level DESC')
- end
-
- def new
- @user_project_relation = @project.project_members.new
- end
-
- def create
- users = User.where(id: params[:user_ids].split(','))
- @project.team << [users, params[:access_level]]
-
- redirect_to namespace_project_team_index_path(@project.namespace, @project)
- end
-
- def update
- @user_project_relation = @project.project_members.find_by(user_id: member)
- @user_project_relation.update_attributes(member_params)
-
- unless @user_project_relation.valid?
- flash[:alert] = "User should have at least one role"
- end
- redirect_to namespace_project_team_index_path(@project.namespace, @project)
- end
-
- def destroy
- @user_project_relation = @project.project_members.find_by(user_id: member)
- @user_project_relation.destroy
-
- respond_to do |format|
- format.html do
- redirect_to namespace_project_team_index_path(@project.namespace,
- @project)
- end
- format.js { render nothing: true }
- end
- end
-
- def leave
- @project.project_members.find_by(user_id: current_user).destroy
-
- respond_to do |format|
- format.html { redirect_to :back }
- format.js { render nothing: true }
- end
- end
-
- def apply_import
- giver = Project.find(params[:source_project_id])
- status = @project.team.import(giver)
- notice = status ? "Successfully imported" : "Import failed"
-
- redirect_to(namespace_project_team_index_path(project.namespace, project),
- notice: notice)
- end
-
- protected
-
- def member
- @member ||= User.find_by(username: params[:id])
- end
-
- def member_params
- params.require(:project_member).permit(:user_id, :access_level)
- end
-end
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index cb829037697..7d3fcfa7037 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -60,7 +60,7 @@ module SearchHelper
{ label: "#{prefix} - Merge Requests", url: namespace_project_merge_requests_path(@project.namespace, @project) },
{ label: "#{prefix} - Milestones", url: namespace_project_milestones_path(@project.namespace, @project) },
{ label: "#{prefix} - Snippets", url: namespace_project_snippets_path(@project.namespace, @project) },
- { label: "#{prefix} - Team", url: namespace_project_team_index_path(@project.namespace, @project) },
+ { label: "#{prefix} - Members", url: namespace_project_project_members_path(@project.namespace, @project) },
{ label: "#{prefix} - Wiki", url: namespace_project_wikis_path(@project.namespace, @project) },
]
else
diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb
index 7a401a274d3..a1d263d9d3a 100644
--- a/app/helpers/tab_helper.rb
+++ b/app/helpers/tab_helper.rb
@@ -89,7 +89,7 @@ module TabHelper
def project_tab_class
return "active" if current_page?(controller: "/projects", action: :edit, id: @project)
- if ['services', 'hooks', 'deploy_keys', 'team_members', 'protected_branches'].include? controller.controller_name
+ if ['services', 'hooks', 'deploy_keys', 'project_members', 'protected_branches'].include? controller.controller_name
"active"
end
end
diff --git a/app/mailers/emails/groups.rb b/app/mailers/emails/groups.rb
index 8c09389985e..26f43bf955e 100644
--- a/app/mailers/emails/groups.rb
+++ b/app/mailers/emails/groups.rb
@@ -1,10 +1,10 @@
module Emails
module Groups
- def group_access_granted_email(user_group_id)
- @membership = GroupMember.find(user_group_id)
- @group = @membership.group
+ def group_access_granted_email(group_member_id)
+ @group_member = GroupMember.find(group_member_id)
+ @group = @group_member.group
@target_url = group_url(@group)
- mail(to: @membership.user.email,
+ mail(to: @group_member.user.email,
subject: subject("Access to group was granted"))
end
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 890417e780d..855134dd39b 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -14,7 +14,7 @@ class Ability
when "MergeRequest" then merge_request_abilities(user, subject)
when "Group" then group_abilities(user, subject)
when "Namespace" then namespace_abilities(user, subject)
- when "GroupMember" then users_group_abilities(user, subject)
+ when "GroupMember" then group_member_abilities(user, subject)
else []
end.concat(global_abilities(user))
end
@@ -37,7 +37,7 @@ class Ability
:read_issue,
:read_milestone,
:read_project_snippet,
- :read_team_member,
+ :read_project_member,
:read_merge_request,
:read_note,
:download_code
@@ -119,7 +119,7 @@ class Ability
:read_issue,
:read_milestone,
:read_project_snippet,
- :read_team_member,
+ :read_project_member,
:read_merge_request,
:read_note,
:write_project,
@@ -166,7 +166,7 @@ class Ability
:admin_issue,
:admin_milestone,
:admin_project_snippet,
- :admin_team_member,
+ :admin_project_member,
:admin_merge_request,
:admin_note,
:admin_wiki,
@@ -248,17 +248,17 @@ class Ability
end
end
- def users_group_abilities(user, subject)
+ def group_member_abilities(user, subject)
rules = []
target_user = subject.user
group = subject.group
can_manage = group_abilities(user, group).include?(:manage_group)
if can_manage && (user != target_user)
- rules << :modify
- rules << :destroy
+ rules << :modify_group_member
+ rules << :destroy_group_member
end
if !group.last_owner?(user) && (can_manage || (user == target_user))
- rules << :destroy
+ rules << :destroy_group_member
end
rules
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 19e43ebd788..6e102051387 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -32,7 +32,6 @@ class Issue < ActiveRecord::Base
validates :project, presence: 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 :cared, ->(user) { where(assignee_id: user) }
scope :open_for, ->(user) { opened.assigned_to(user) }
diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb
index e4791d0f0aa..6b13e0ff30b 100644
--- a/app/models/members/project_member.rb
+++ b/app/models/members/project_member.rb
@@ -116,14 +116,14 @@ class ProjectMember < Member
def post_create_hook
unless owner?
event_service.join_project(self.project, self.user)
- notification_service.new_team_member(self)
+ notification_service.new_project_member(self)
end
system_hook_service.execute_hooks_for(self, :create)
end
def post_update_hook
- notification_service.update_team_member(self) if self.access_level_changed?
+ notification_service.update_project_member(self) if self.access_level_changed?
end
def post_destroy_hook
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index f758126cfeb..4cbdc612297 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -115,7 +115,6 @@ class MergeRequest < ActiveRecord::Base
validate :validate_fork
scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.project_ids) }
- scope :of_user_team, ->(team) { where("(source_project_id in (:team_project_ids) OR target_project_id in (:team_project_ids) AND assignee_id in (:team_member_ids))", team_project_ids: team.project_ids, team_member_ids: team.member_ids) }
scope :merged, -> { with_state(:merged) }
scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) }
scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) }
diff --git a/app/models/project.rb b/app/models/project.rb
index c45338bf4eb..1d1ae569fc2 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -157,7 +157,6 @@ class Project < ActiveRecord::Base
scope :without_user, ->(user) { where('projects.id NOT IN (:ids)', ids: user.authorized_projects.map(&:id) ) }
scope :without_team, ->(team) { team.projects.present? ? where('projects.id NOT IN (:ids)', ids: team.projects.map(&:id)) : scoped }
scope :not_in_group, ->(group) { where('projects.id NOT IN (:ids)', ids: group.project_ids ) }
- scope :in_team, ->(team) { where('projects.id IN (:ids)', ids: team.projects.map(&:id)) }
scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) }
scope :in_group_namespace, -> { joins(:group) }
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
@@ -445,13 +444,13 @@ class Project < ActiveRecord::Base
end
end
- def team_member_by_name_or_email(name = nil, email = nil)
+ def project_member_by_name_or_email(name = nil, email = nil)
user = users.where('name like ? or email like ?', name, email).first
project_members.where(user: user) if user
end
# Get Team Member record by user id
- def team_member_by_id(user_id)
+ def project_member_by_id(user_id)
project_members.find_by(user_id: user_id)
end
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index bc9c3ce58f6..d4a07caf9ef 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -31,16 +31,16 @@ class ProjectTeam
user
end
- def find_tm(user_id)
- tm = project.project_members.find_by(user_id: user_id)
+ def find_member(user_id)
+ member = project.project_members.find_by(user_id: user_id)
# If user is not in project members
# we should check for group membership
- if group && !tm
- tm = group.group_members.find_by(user_id: user_id)
+ if group && !member
+ member = group.group_members.find_by(user_id: user_id)
end
- tm
+ member
end
def add_user(user, access)
@@ -91,24 +91,24 @@ class ProjectTeam
def import(source_project)
target_project = project
- source_team = source_project.project_members.to_a
+ source_members = source_project.project_members.to_a
target_user_ids = target_project.project_members.pluck(:user_id)
- source_team.reject! do |tm|
+ source_members.reject! do |member|
# Skip if user already present in team
- target_user_ids.include?(tm.user_id)
+ target_user_ids.include?(member.user_id)
end
- source_team.map! do |tm|
- new_tm = tm.dup
- new_tm.id = nil
- new_tm.source = target_project
- new_tm
+ source_members.map! do |member|
+ new_member = member.dup
+ new_member.id = nil
+ new_member.source = target_project
+ new_member
end
ProjectMember.transaction do
- source_team.each do |tm|
- tm.save
+ source_members.each do |member|
+ member.save
end
end
@@ -118,26 +118,26 @@ class ProjectTeam
end
def guest?(user)
- max_tm_access(user.id) == Gitlab::Access::GUEST
+ max_member_access(user.id) == Gitlab::Access::GUEST
end
def reporter?(user)
- max_tm_access(user.id) == Gitlab::Access::REPORTER
+ max_member_access(user.id) == Gitlab::Access::REPORTER
end
def developer?(user)
- max_tm_access(user.id) == Gitlab::Access::DEVELOPER
+ max_member_access(user.id) == Gitlab::Access::DEVELOPER
end
def master?(user)
- max_tm_access(user.id) == Gitlab::Access::MASTER
+ max_member_access(user.id) == Gitlab::Access::MASTER
end
def member?(user_id)
- !!find_tm(user_id)
+ !!find_member(user_id)
end
- def max_tm_access(user_id)
+ def max_member_access(user_id)
access = []
access << project.project_members.find_by(user_id: user_id).try(:access_field)
diff --git a/app/models/user.rb b/app/models/user.rb
index 0d40ac8309e..ba325132df8 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -169,11 +169,8 @@ class User < ActiveRecord::Base
scope :admins, -> { where(admin: true) }
scope :blocked, -> { with_state(:blocked) }
scope :active, -> { with_state(:active) }
- 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 :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all }
scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') }
- scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active }
#
# Class methods
@@ -407,7 +404,7 @@ class User < ActiveRecord::Base
end
def tm_of(project)
- project.team_member_by_id(self.id)
+ project.project_member_by_id(self.id)
end
def already_forked?(project)
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 0063b7ce40c..fb411c3e23d 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -162,20 +162,20 @@ class NotificationService
end
end
- def new_team_member(project_member)
+ def new_project_member(project_member)
mailer.project_access_granted_email(project_member.id)
end
- def update_team_member(project_member)
+ def update_project_member(project_member)
mailer.project_access_granted_email(project_member.id)
end
- def new_group_member(users_group)
- mailer.group_access_granted_email(users_group.id)
+ def new_group_member(group_member)
+ mailer.group_access_granted_email(group_member.id)
end
- def update_group_member(users_group)
- mailer.group_access_granted_email(users_group.id)
+ def update_group_member(group_member)
+ mailer.group_access_granted_email(group_member.id)
end
def project_was_moved(project)
@@ -194,11 +194,11 @@ class NotificationService
project_members = project_member_notification(project)
users_with_project_level_global = project_member_notification(project, Notification::N_GLOBAL)
- users_with_group_level_global = users_group_notification(project, Notification::N_GLOBAL)
+ users_with_group_level_global = group_member_notification(project, Notification::N_GLOBAL)
users = users_with_global_level_watch([users_with_project_level_global, users_with_group_level_global].flatten.uniq)
users_with_project_setting = select_project_member_setting(project, users_with_project_level_global, users)
- users_with_group_setting = select_users_group_setting(project, project_members, users_with_group_level_global, users)
+ users_with_group_setting = select_group_member_setting(project, project_members, users_with_group_level_global, users)
User.where(id: users_with_project_setting.concat(users_with_group_setting).uniq).to_a
end
@@ -213,7 +213,7 @@ class NotificationService
end
end
- def users_group_notification(project, notification_level)
+ def group_member_notification(project, notification_level)
if project.group
project.group.group_members.where(notification_level: notification_level).pluck(:user_id)
else
@@ -243,8 +243,8 @@ class NotificationService
end
# Build a list of users based on group notification settings
- def select_users_group_setting(project, project_members, global_setting, users_global_level_watch)
- uids = users_group_notification(project, Notification::N_WATCH)
+ def select_group_member_setting(project, project_members, global_setting, users_global_level_watch)
+ uids = group_member_notification(project, Notification::N_WATCH)
# Group setting is watch, add to users list if user is not project member
users = []
@@ -273,20 +273,20 @@ class NotificationService
users.reject do |user|
next user.notification.disabled? unless project
- tm = project.project_members.find_by(user_id: user.id)
+ member = project.project_members.find_by(user_id: user.id)
- if !tm && project.group
- tm = project.group.group_members.find_by(user_id: user.id)
+ if !member && project.group
+ member = project.group.group_members.find_by(user_id: user.id)
end
# reject users who globally disabled notification and has no membership
- next user.notification.disabled? unless tm
+ next user.notification.disabled? unless member
# reject users who disabled notification in project
- next true if tm.notification.disabled?
+ next true if member.notification.disabled?
# reject users who have N_GLOBAL in project and disabled in global settings
- tm.notification.global? && user.notification.disabled?
+ member.notification.global? && user.notification.disabled?
end
end
@@ -297,20 +297,20 @@ class NotificationService
users.reject do |user|
next user.notification.mention? unless project
- tm = project.project_members.find_by(user_id: user.id)
+ member = project.project_members.find_by(user_id: user.id)
- if !tm && project.group
- tm = project.group.group_members.find_by(user_id: user.id)
+ if !member && project.group
+ member = project.group.group_members.find_by(user_id: user.id)
end
# reject users who globally set mention notification and has no membership
- next user.notification.mention? unless tm
+ next user.notification.mention? unless member
# reject users who set mention notification in project
- next true if tm.notification.mention?
+ next true if member.notification.mention?
# reject users who have N_MENTION in project and disabled in global settings
- tm.notification.global? && user.notification.mention?
+ member.notification.global? && user.notification.mention?
end
end
diff --git a/app/services/projects/participants_service.rb b/app/services/projects/participants_service.rb
index f6f9aceef95..bcbacbff562 100644
--- a/app/services/projects/participants_service.rb
+++ b/app/services/projects/participants_service.rb
@@ -12,8 +12,8 @@ module Projects
else
[]
end
- team_members = sorted(@project.team.members)
- participants = all_members + groups + team_members + participating
+ project_members = sorted(@project.team.members)
+ participants = all_members + groups + project_members + participating
participants.uniq
end
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index a28eae38925..7d292118075 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -58,7 +58,7 @@
Read more about project permissions
%strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
- = form_tag project_teams_update_admin_group_path(@group), id: "new_team_member", class: "bulk_import", method: :put do
+ = form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do
%div
= users_select_tag(:user_ids, multiple: true)
%div.prepend-top-10
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index ebb3b3a636e..077ee569085 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -111,10 +111,10 @@
%small
(#{@project.users.count})
.pull-right
- = link_to namespace_project_team_index_path(@project.namespace, @project), class: "btn btn-xs" do
+ = link_to namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-xs" do
%i.fa.fa-pencil-square-o
Manage Access
- %ul.well-list.team_members
+ %ul.well-list.project_members
- @project_members.each do |project_member|
- user = project_member.user
%li.project_member
@@ -126,7 +126,7 @@
%span.light Owner
- else
%span.light= project_member.human_access
- = link_to namespace_project_team_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, remote: true, class: "btn btn-sm btn-remove" do
+ = link_to namespace_project_project_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, remote: true, class: "btn btn-sm btn-remove" do
%i.fa.fa-times
.panel-footer
= paginate @project_members, param_name: 'project_members_page', theme: 'gitlab'
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 5cf423ead88..0a2934d3bda 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -174,15 +174,15 @@
.panel.panel-default
.panel-heading Groups:
%ul.well-list
- - @user.group_members.each do |user_group|
- - group = user_group.group
+ - @user.group_members.each do |group_member|
+ - group = group_member.group
%li.group_member
- %span{class: ("list-item-name" unless user_group.owner?)}
+ %span{class: ("list-item-name" unless group_member.owner?)}
%strong= link_to group.name, admin_group_path(group)
.pull-right
- %span.light= user_group.human_access
- - unless user_group.owner?
- = link_to group_group_member_path(group, user_group), data: { confirm: remove_user_from_group_message(group, @user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do
+ %span.light= group_member.human_access
+ - unless group_member.owner?
+ = link_to group_group_member_path(group, group_member), data: { confirm: remove_user_from_group_message(group, @user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do
%i.fa.fa-times.fa-inverse
- else
.nothing-here-block This user has no groups.
@@ -207,21 +207,21 @@
.panel-heading Joined projects (#{@joined_projects.count})
%ul.well-list
- @joined_projects.sort_by(&:name_with_namespace).each do |project|
- - tm = project.team.find_tm(@user.id)
+ - member = project.team.find_member(@user.id)
%li.project_member
.list-item-name
= link_to admin_namespace_project_path(project.namespace, project), class: dom_class(project) do
= project.name_with_namespace
- - if tm
+ - if member
.pull-right
- - if tm.owner?
+ - if member.owner?
%span.light Owner
- else
- %span.light= tm.human_access
+ %span.light= member.human_access
- - if tm.respond_to? :project
- = link_to namespace_project_team_member_path(project.namespace, project, @user), data: { confirm: remove_from_project_team_message(project, @user) }, remote: true, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from project' do
+ - if member.respond_to? :project
+ = link_to namespace_project_project_member_path(project.namespace, project, @user), data: { confirm: remove_from_project_team_message(project, @user) }, remote: true, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from project' do
%i.fa.fa-times
#ssh-keys.tab-pane
= render 'profiles/keys/key_table', admin: true
diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml
index c232644b021..165db214d75 100644
--- a/app/views/dashboard/groups/index.html.haml
+++ b/app/views/dashboard/groups/index.html.haml
@@ -11,10 +11,10 @@
.panel.panel-default
.panel-heading
%strong Groups
- (#{@user_groups.count})
+ (#{@group_members.count})
%ul.well-list
- - @user_groups.each do |user_group|
- - group = user_group.group
+ - @group_members.each do |group_member|
+ - group = group_member.group
%li
.pull-right
- if can?(current_user, :manage_group, group)
@@ -22,8 +22,8 @@
%i.fa.fa-cogs
Settings
- - if can?(current_user, :destroy, user_group)
- = link_to leave_dashboard_group_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Remove user from group' do
+ - if can?(current_user, :destroy_group_member, group_member)
+ = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Remove user from group' do
%i.fa.fa-sign-out
Leave
@@ -32,9 +32,9 @@
%strong= group.name
as
- %strong #{user_group.human_access}
+ %strong #{group_member.human_access}
%div.light
#{pluralize(group.projects.count, "project")}, #{pluralize(group.users.count, "user")}
-= paginate @user_groups
+= paginate @group_members
diff --git a/app/views/groups/group_members/_group_member.html.haml b/app/views/groups/group_members/_group_member.html.haml
index 5bef796c5a2..3d120c5cdd7 100644
--- a/app/views/groups/group_members/_group_member.html.haml
+++ b/app/views/groups/group_members/_group_member.html.haml
@@ -1,6 +1,7 @@
- user = member.user
- return unless user
- show_roles = true if show_roles.nil?
+
%li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)}
%span{class: ("list-item-name" if show_controls)}
= image_tag avatar_icon(user.email, 16), class: "avatar s16"
@@ -16,13 +17,13 @@
%span.pull-right
%strong= member.human_access
- if show_controls
- - if can?(current_user, :modify, member)
+ - if can?(current_user, :modify_group_member, member)
= button_tag class: "btn-xs btn js-toggle-button",
title: 'Edit access level', type: 'button' do
%i.fa.fa-pencil-square-o
- - if can?(current_user, :destroy, member)
- - if current_user == member.user
- = link_to leave_dashboard_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from group' do
+ - if can?(current_user, :destroy_group_member, member)
+ - if current_user == user
+ = link_to leave_group_group_members_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from group' do
%i.fa.fa-minus.fa-inverse
- else
= link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do
diff --git a/app/views/groups/_new_group_member.html.haml b/app/views/groups/group_members/_new_group_member.html.haml
index 345c0555a36..c4c29bb2e8d 100644
--- a/app/views/groups/_new_group_member.html.haml
+++ b/app/views/groups/group_members/_new_group_member.html.haml
@@ -1,4 +1,4 @@
-= form_for @users_group, url: group_group_members_path(@group), html: { class: 'form-horizontal users-group-form' } do |f|
+= form_for @group_member, url: group_group_members_path(@group), html: { class: 'form-horizontal users-group-form' } do |f|
.form-group
= f.label :user_ids, "People", class: 'control-label'
.col-sm-10= users_select_tag(:user_ids, multiple: true, class: 'input-large')
@@ -6,7 +6,7 @@
.form-group
= f.label :access_level, "Group Access", class: 'control-label'
.col-sm-10
- = select_tag :access_level, options_for_select(GroupMember.access_level_roles, @users_group.access_level), class: "project-access-select select2"
+ = select_tag :access_level, options_for_select(GroupMember.access_level_roles, @group_member.access_level), class: "project-access-select select2"
.help-block
Read more about role permissions
%strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
diff --git a/app/views/groups/members.html.haml b/app/views/groups/group_members/index.html.haml
index 688c22e9624..0d501fe7bd3 100644
--- a/app/views/groups/members.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -1,4 +1,5 @@
- show_roles = should_user_see_group_roles?(current_user, @group)
+
%h3.page-title
Group members
- if show_roles
@@ -10,7 +11,7 @@
%hr
.clearfix.js-toggle-container
- = form_tag members_group_path(@group), method: :get, class: 'form-inline member-search-form' do
+ = form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do
.form-group
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input input-mn-300' }
= button_tag 'Search', class: 'btn'
@@ -33,6 +34,7 @@
%ul.well-list
- @members.each do |member|
= render 'groups/group_members/group_member', member: member, show_roles: show_roles, show_controls: true
+
= paginate @members, theme: 'gitlab'
:coffeescript
diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml
index 3b8c26ed391..dd1fa3840d5 100644
--- a/app/views/groups/projects.html.haml
+++ b/app/views/groups/projects.html.haml
@@ -16,7 +16,7 @@
%span.label.label-gray
= repository_size(project)
.pull-right
- = link_to 'Members', namespace_project_team_index_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm"
+ = link_to 'Members', namespace_project_project_members_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm"
= link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm"
= link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-sm btn-remove"
- if @projects.blank?
diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml
index ddd3df19eec..32fe0e37df8 100644
--- a/app/views/layouts/nav/_group.html.haml
+++ b/app/views/layouts/nav/_group.html.haml
@@ -24,8 +24,8 @@
Merge Requests
- if current_user
%span.count= MergeRequest.opened.of_group(@group).count
- = nav_link(path: 'groups#members') do
- = link_to members_group_path(@group), title: 'Members' do
+ = nav_link(controller: [:group_members]) do
+ = link_to group_group_members_path(@group), title: 'Members' do
%i.fa.fa-users
%span
Members
diff --git a/app/views/notify/group_access_granted_email.html.haml b/app/views/notify/group_access_granted_email.html.haml
index 823ebf77347..f1916d624b6 100644
--- a/app/views/notify/group_access_granted_email.html.haml
+++ b/app/views/notify/group_access_granted_email.html.haml
@@ -1,4 +1,4 @@
%p
- = "You have been granted #{@membership.human_access} access to group"
+ = "You have been granted #{@group_member.human_access} access to group"
= link_to group_url(@group) do
= @group.name
diff --git a/app/views/notify/group_access_granted_email.text.erb b/app/views/notify/group_access_granted_email.text.erb
index 331bb98d5c9..ef9617bfc16 100644
--- a/app/views/notify/group_access_granted_email.text.erb
+++ b/app/views/notify/group_access_granted_email.text.erb
@@ -1,4 +1,4 @@
-You have been granted <%= @membership.human_access %> access to group <%= @group.name %>
+You have been granted <%= @group_member.human_access %> access to group <%= @group.name %>
<%= url_for(group_url(@group)) %>
diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml
index 6cf5c81c19e..273e72f8a4d 100644
--- a/app/views/profiles/notifications/show.html.haml
+++ b/app/views/profiles/notifications/show.html.haml
@@ -62,9 +62,9 @@
By default, all projects and groups will use the notification level set above.
%h4 Groups:
%ul.bordered-list
- - @group_members.each do |users_group|
- - notification = Notification.new(users_group)
- = render 'settings', type: 'group', membership: users_group, notification: notification
+ - @group_members.each do |group_member|
+ - notification = Notification.new(group_member)
+ = render 'settings', type: 'group', membership: group_member, notification: notification
.col-md-6
%p
diff --git a/app/views/projects/_dropdown.html.haml b/app/views/projects/_dropdown.html.haml
index 2d5120f283b..f4f4c2662cf 100644
--- a/app/views/projects/_dropdown.html.haml
+++ b/app/views/projects/_dropdown.html.haml
@@ -15,9 +15,9 @@
%li
= link_to new_namespace_project_snippet_path(@project.namespace, @project), title: "New Snippet" do
New snippet
- - if can?(current_user, :admin_team_member, @project)
+ - if can?(current_user, :admin_project_member, @project)
%li
- = link_to new_namespace_project_team_member_path(@project.namespace, @project), title: "New project member" do
+ = link_to namespace_project_project_members_path(@project.namespace, @project), title: "New project member" do
New project member
- if can? current_user, :push_code, @project
%li.divider
diff --git a/app/views/projects/_settings_nav.html.haml b/app/views/projects/_settings_nav.html.haml
index 7fc3d44034f..281a84a3d3c 100644
--- a/app/views/projects/_settings_nav.html.haml
+++ b/app/views/projects/_settings_nav.html.haml
@@ -4,8 +4,8 @@
%i.fa.fa-pencil-square-o
%span
Project
- = nav_link(controller: [:team_members, :teams]) do
- = link_to namespace_project_team_index_path(@project.namespace, @project), title: 'Members', class: "team-tab tab" do
+ = nav_link(controller: [:project_members, :teams]) do
+ = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: "team-tab tab" do
%i.fa.fa-users
%span
Members
diff --git a/app/views/projects/project_members/_group_members.html.haml b/app/views/projects/project_members/_group_members.html.haml
new file mode 100644
index 00000000000..b050be1d21b
--- /dev/null
+++ b/app/views/projects/project_members/_group_members.html.haml
@@ -0,0 +1,15 @@
+.panel.panel-default
+ .panel-heading
+ %strong #{@group.name}
+ group members
+ %small
+ (#{members.count})
+ .pull-right
+ = link_to group_group_members_path(@group), class: 'btn btn-sm' do
+ %i.fa.fa-pencil-square-o
+ %ul.well-list
+ - members.each do |member|
+ = render 'groups/group_members/group_member', member: member, show_controls: false
+ - if members.count > 20
+ %li
+ and #{members.count - 20} more. For full list visit #{link_to 'group members page', group_group_members_path(@group)}
diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml
new file mode 100644
index 00000000000..0f824bdabf8
--- /dev/null
+++ b/app/views/projects/project_members/_new_project_member.html.haml
@@ -0,0 +1,15 @@
+= form_for @project_member, as: :project_member, url: namespace_project_project_members_path(@project.namespace, @project), html: { class: 'form-horizontal users-project-form' } do |f|
+ .form-group
+ = f.label :user_ids, "People", class: 'control-label'
+ .col-sm-10= users_select_tag(:user_ids, multiple: true, class: 'input-large')
+
+ .form-group
+ = f.label :access_level, "Project Access", class: 'control-label'
+ .col-sm-10
+ = select_tag :access_level, options_for_select(ProjectMember.access_roles, @project_member.access_level), class: "project-access-select select2"
+ .help-block
+ Read more about role permissions
+ %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
+
+ .form-actions
+ = f.submit 'Add users to project', class: "btn btn-create"
diff --git a/app/views/projects/project_members/_project_member.html.haml b/app/views/projects/project_members/_project_member.html.haml
new file mode 100644
index 00000000000..368d9419de3
--- /dev/null
+++ b/app/views/projects/project_members/_project_member.html.haml
@@ -0,0 +1,34 @@
+- user = member.user
+- return unless user
+
+%li{class: "#{dom_class(member)} js-toggle-container project_member_row access-#{member.human_access.downcase}", id: dom_id(member)}
+ %span.list-item-name
+ = image_tag avatar_icon(user.email, 16), class: "avatar s16"
+ %strong= user.name
+ %span.cgray= user.username
+ - if user == current_user
+ %span.label.label-success It's you
+ - if user.blocked?
+ %label.label.label-danger
+ %strong Blocked
+
+ - if current_user_can_admin_project
+ - unless @project.personal? && user == current_user
+ .pull-right
+ %strong= member.human_access
+ = button_tag class: "btn-xs btn js-toggle-button",
+ title: 'Edit access level', type: 'button' do
+ %i.fa.fa-pencil-square-o
+
+ - if current_user == user
+ = link_to leave_namespace_project_project_members_path(@project.namespace, @project), data: { confirm: "Leave project?"}, method: :delete, class: "btn-xs btn btn-remove", title: 'Leave project' do
+ %i.fa.fa-minus.fa-inverse
+ - else
+ = link_to namespace_project_project_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from team' do
+ %i.fa.fa-minus.fa-inverse
+
+ .edit-member.hide.js-toggle-content
+ = form_for member, as: :project_member, url: namespace_project_project_member_path(@project.namespace, @project, member.user), remote: true do |f|
+ .alert.prepend-top-20
+ = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level)
+ = f.submit 'Save', class: 'btn btn-save btn-sm'
diff --git a/app/views/projects/project_members/_team.html.haml b/app/views/projects/project_members/_team.html.haml
new file mode 100644
index 00000000000..615c425e59a
--- /dev/null
+++ b/app/views/projects/project_members/_team.html.haml
@@ -0,0 +1,11 @@
+- can_admin_project = can?(current_user, :admin_project, @project)
+
+.panel.panel-default.prepend-top-20
+ .panel-heading
+ %strong #{@project.name}
+ project members
+ %small
+ (#{members.count})
+ %ul.well-list
+ - members.each do |project_member|
+ = render 'project_member', member: project_member, current_user_can_admin_project: can_admin_project
diff --git a/app/views/projects/team_members/import.html.haml b/app/views/projects/project_members/import.html.haml
index 9e31d47117e..293754cd0c0 100644
--- a/app/views/projects/team_members/import.html.haml
+++ b/app/views/projects/project_members/import.html.haml
@@ -3,12 +3,12 @@
%p.light
Only project members will be imported. Group members will be skipped.
%hr
-= form_tag apply_import_namespace_project_team_members_path(@project.namespace, @project), method: 'post', class: 'form-horizontal' do
+= form_tag apply_import_namespace_project_project_members_path(@project.namespace, @project), method: 'post', class: 'form-horizontal' do
.form-group
= label_tag :source_project_id, "Project", class: 'control-label'
.col-sm-10= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "select2 lg", required: true)
.form-actions
= button_tag 'Import project members', class: "btn btn-create"
- = link_to "Cancel", namespace_project_team_index_path(@project.namespace, @project), class: "btn btn-cancel"
+ = link_to "Cancel", namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-cancel"
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
new file mode 100644
index 00000000000..36a6f6a1554
--- /dev/null
+++ b/app/views/projects/project_members/index.html.haml
@@ -0,0 +1,35 @@
+%h3.page-title
+ Users with access to this project
+
+%p.light
+ Read more about project permissions
+ %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
+
+%hr
+
+.clearfix.js-toggle-container
+ = form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do
+ .form-group
+ = search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input input-mn-300' }
+ = button_tag 'Search', class: 'btn'
+
+ - if can?(current_user, :admin_project_member, @project)
+ %span.pull-right
+ = button_tag class: 'btn btn-new btn-grouped js-toggle-button', type: 'button' do
+ Add members
+ %i.fa.fa-chevron-down
+ = link_to import_namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do
+ Import members
+
+ .js-toggle-content.hide.new-group-member-holder
+ = render "new_project_member"
+
+= render "team", members: @project_members
+
+- if @group
+ = render "group_members", members: @group_members
+
+:coffeescript
+ $('form.member-search-form').on 'submit', (event) ->
+ event.preventDefault()
+ Turbolinks.visit @.action + '?' + $(@).serialize()
diff --git a/app/views/projects/project_members/update.js.haml b/app/views/projects/project_members/update.js.haml
new file mode 100644
index 00000000000..811b1858821
--- /dev/null
+++ b/app/views/projects/project_members/update.js.haml
@@ -0,0 +1,3 @@
+- can_admin_project = can?(current_user, :admin_project, @project)
+:plain
+ $("##{dom_id(@project_member)}").replaceWith('#{escape_javascript(render("project_member", member: @project_member, current_user_can_admin_project: can_admin_project))}');
diff --git a/app/views/projects/team_members/_form.html.haml b/app/views/projects/team_members/_form.html.haml
deleted file mode 100644
index 166b6362a07..00000000000
--- a/app/views/projects/team_members/_form.html.haml
+++ /dev/null
@@ -1,29 +0,0 @@
-%h3.page-title
- New project member(s)
-
-= form_for @user_project_relation, as: :project_member, url: namespace_project_team_members_path(@project.namespace, @project), html: { class: "form-horizontal users-project-form" } do |f|
- -if @user_project_relation.errors.any?
- .alert.alert-danger
- %ul
- - @user_project_relation.errors.full_messages.each do |msg|
- %li= msg
-
- %p 1. Choose people you want in the project
- .form-group
- = f.label :user_ids, "People", class: 'control-label'
- .col-sm-10
- = users_select_tag(:user_ids, multiple: true)
-
- %p 2. Set access level for them
- .form-group
- = f.label :access_level, "Project Access", class: 'control-label'
- .col-sm-10
- = select_tag :access_level, options_for_select(Gitlab::Access.options, @user_project_relation.access_level), class: "project-access-select select2"
- .help-block
- Read more about role permissions
- %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
-
-
- .form-actions
- = f.submit 'Add users', class: "btn btn-create"
- = link_to "Cancel", namespace_project_team_index_path(@project.namespace, @project), class: "btn btn-cancel"
diff --git a/app/views/projects/team_members/_group_members.html.haml b/app/views/projects/team_members/_group_members.html.haml
deleted file mode 100644
index 12bd828a5e7..00000000000
--- a/app/views/projects/team_members/_group_members.html.haml
+++ /dev/null
@@ -1,14 +0,0 @@
-- group_users_count = @group.group_members.count
-.panel.panel-default
- .panel-heading
- %strong #{@group.name}
- group members (#{group_users_count})
- .pull-right
- = link_to members_group_path(@group), class: 'btn btn-sm' do
- %i.fa.fa-pencil-square-o
- %ul.well-list
- - @group.group_members.order('access_level DESC').limit(20).each do |member|
- = render 'groups/group_members/group_member', member: member, show_controls: false
- - if group_users_count > 20
- %li
- and #{group_users_count - 20} more. For full list visit #{link_to 'group members page', members_group_path(@group)}
diff --git a/app/views/projects/team_members/_team.html.haml b/app/views/projects/team_members/_team.html.haml
deleted file mode 100644
index 0e5b8176132..00000000000
--- a/app/views/projects/team_members/_team.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-.team-table
- - can_admin_project = (can? current_user, :admin_project, @project)
- .panel.panel-default
- .panel-heading
- %strong #{@project.name}
- project members (#{members.count})
- %ul.well-list
- - members.each do |team_member|
- = render 'team_member', member: team_member, current_user_can_admin_project: can_admin_project
diff --git a/app/views/projects/team_members/_team_member.html.haml b/app/views/projects/team_members/_team_member.html.haml
deleted file mode 100644
index 1a755bbd560..00000000000
--- a/app/views/projects/team_members/_team_member.html.haml
+++ /dev/null
@@ -1,18 +0,0 @@
-- user = member.user
-%li{id: dom_id(user), class: "team_member_row access-#{member.human_access.downcase}"}
- .pull-right
- - if current_user_can_admin_project
- - unless @project.personal? && user == current_user
- .pull-left
- = form_for(member, as: :project_member, url: namespace_project_team_member_path(@project.namespace, @project, member.user)) do |f|
- = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level), {}, class: "trigger-submit"
- &nbsp;
- = link_to namespace_project_team_member_path(@project.namespace, @project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from team' do
- %i.fa.fa-minus.fa-inverse
- = image_tag avatar_icon(user.email, 32), class: "avatar s32"
- %p
- %strong= user.name
- - if user.blocked?
- %label.label.label-danger
- %strong Blocked
- %span.cgray= user.username
diff --git a/app/views/projects/team_members/index.html.haml b/app/views/projects/team_members/index.html.haml
deleted file mode 100644
index fcc879a58df..00000000000
--- a/app/views/projects/team_members/index.html.haml
+++ /dev/null
@@ -1,16 +0,0 @@
-%h3.page-title
- Users with access to this project
-
- - if can? current_user, :admin_team_member, @project
- %span.pull-right
- = link_to new_namespace_project_team_member_path(@project.namespace, @project), class: "btn btn-new btn-grouped", title: "New project member" do
- New project member
- = link_to import_namespace_project_team_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do
- Import members
-
-%p.light
- Read more about project permissions
- %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
-= render "team", members: @project_members
-- if @group
- = render "group_members"
diff --git a/app/views/projects/team_members/new.html.haml b/app/views/projects/team_members/new.html.haml
deleted file mode 100644
index b1bc3ba0eba..00000000000
--- a/app/views/projects/team_members/new.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render "form"
diff --git a/app/views/projects/team_members/update.js.haml b/app/views/projects/team_members/update.js.haml
deleted file mode 100644
index c68fe9574a2..00000000000
--- a/app/views/projects/team_members/update.js.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-- if @user_project_relation.valid?
- :plain
- $("##{dom_id(@user_project_relation)}").effect("highlight", {color: "#529214"}, 1000);;
-- else
- :plain
- $("##{dom_id(@user_project_relation)}").effect("highlight", {color: "#D12F19"}, 1000);;