diff --git a/CHANGELOG b/CHANGELOG index 7bc561b6e06ea50ba23c40113148d048e658079b..dd37ab0c1c7a8c123577a8bad9ef0756e4522903 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -68,6 +68,7 @@ v 7.9.0 (unreleased) - Execute hooks and services when branch or tag is created or deleted through web interface. - Block and unblock user if he/she was blocked/unblocked in Active Directory - Raise recommended number of unicorn workers from 2 to 3 + - Use same layout and interactivity for project members as group members. v 7.8.4 - Fix issue_tracker_id substitution in custom issue trackers diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index e1015a63d52deb0f8a95cb853e7ebc929e450f37..edf482f33d8ffd0a362c6ee1aeba1e80900b8a85 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 0000000000000000000000000000000000000000..896ba7e53eefeec6e78b1effb252255c7378c8cb --- /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 af8e90eb1a9e4bdd6cb19935a810b314123d1001..876eea72e8a79f919aa8cd1914e6bf68e46481f8 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 e359aa450257c54db12e0fa2f1de0e5b995a0d01..747559516707bf1e75f638f8b5bc15af46437979 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 e338abeac4c4980a9b7ab89e7b9e20b1be8539e3..9d9adaa467f16559ce65873769a54c341894f28e 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 @@ def update 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 b827639978c51cae26442b5c3d1dceefb0a81eea..ed14f4e1f3baa9689c8d000381dc67179560a7f3 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 7f27f2bb7345ae20a7af2e49eddd5a2b12e8454e..a73b8fa212a6c4b408e73ba87ae8e45c728ba840 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 b083cf5d8c599a7bcb9c07f9b63024e17b1e5145..2df51c97a22ca805922977360c64f1da3ac4cdfb 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 @@ def update 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 @@ def destroy 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 7e336803fbb1a284d59f48bccf27c06c00501235..7af3c077182228637d1691653336fcc6ea4f5caf 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 @@ def issues 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 433c19189afa45be1ceebe160ecdd463801f65ba..3fdcbbab61b531633827a36f336393e9d185f137 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -14,9 +14,9 @@ def update @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 0000000000000000000000000000000000000000..4ab15db01f7cec123564b3e43acc7b2bafaa98f6 --- /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 f8a248ed7291dff3a48a43c62eb9e17d3f899b4d..0000000000000000000000000000000000000000 --- 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 cb82903769794a022fab21d2f232c6c6dd37937f..7d3fcfa70370a243cb2b8f569d141fd7228711d7 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -60,7 +60,7 @@ def project_autocomplete { 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 7a401a274d34d31a01a2636d8c84349af1a3b65b..a1d263d9d3a92369fa5083e4d33290923b21ac94 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -89,7 +89,7 @@ def current_path?(path) 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 8c09389985e2f54219c6fb76931a12fcecbdacdd..26f43bf955e8b7d2ea559547f6c9cea5d72fa663 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 890417e780dcbf64f9b6d508126ea28a3e862962..855134dd39badbc7d410f025d720acc6d75b2271 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -14,7 +14,7 @@ def allowed(user, subject) 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 @@ def not_auth_abilities(user, subject) :read_issue, :read_milestone, :read_project_snippet, - :read_team_member, + :read_project_member, :read_merge_request, :read_note, :download_code @@ -119,7 +119,7 @@ def project_guest_rules :read_issue, :read_milestone, :read_project_snippet, - :read_team_member, + :read_project_member, :read_merge_request, :read_note, :write_project, @@ -166,7 +166,7 @@ def project_master_rules :admin_issue, :admin_milestone, :admin_project_snippet, - :admin_team_member, + :admin_project_member, :admin_merge_request, :admin_note, :admin_wiki, @@ -248,17 +248,17 @@ def namespace_abilities(user, namespace) 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 19e43ebd788c9ca2708073f9679bbf895fd72f4f..6e1020513875aba4f1af2d3e21f8a9d37d25850e 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 e4791d0f0aaf9643943467a3ad04c351081ed4d3..6b13e0ff30ba251fe1953a462a8989e6952a3d92 100644 --- a/app/models/members/project_member.rb +++ b/app/models/members/project_member.rb @@ -116,14 +116,14 @@ def owner? 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 f758126cfebd3292ee084b63e37399953fc3c2c7..4cbdc6122971c75879e9373db5d9c515b0f790c7 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 c45338bf4eb1ce3b8a3cc8c3a427af62d9c67804..1d1ae569fc23f80c6a6c001c6da5e1116e991f9f 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -157,7 +157,6 @@ def set_last_activity_at 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 @@ def owner 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 bc9c3ce58f68d92c8d133eea61f801ba342005c3..d4a07caf9efdbeaace3fd12d5f049df7b7fa90c9 100644 --- a/app/models/project_team.rb +++ b/app/models/project_team.rb @@ -31,16 +31,16 @@ def find(user_id) 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 @@ def masters 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 @@ def import(source_project) 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 0d40ac8309e08326f9ce32ffeb1d99a2b19d301a..ba325132df8973fa2192da2b015a54c7dc737a68 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 @@ def name_with_username 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 0063b7ce40c69ecf7088c46dbf244795fc96cf29..fb411c3e23d19a473e0ab2174912b48ba9712217 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -162,20 +162,20 @@ def new_note(note) 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 @@ def project_watchers(project) 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 @@ def project_member_notification(project, notification_level=nil) 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 @@ def select_project_member_setting(project, global_setting, users_global_level_wa 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 @@ def reject_muted_users(users, project = nil) 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 @@ def reject_mention_users(users, project = nil) 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 f6f9aceef95c4d12c7442ae9a91af48b25369b98..bcbacbff5628e9a913a93c1e58681d525f1cd85c 100644 --- a/app/services/projects/participants_service.rb +++ b/app/services/projects/participants_service.rb @@ -12,8 +12,8 @@ def execute(note_type, note_id) 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 a28eae38925d540289be489dd5f8c2bb1bbeb9e6..7d292118075efa50b0b60e858f78849ea3c3349b 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 ebb3b3a636e6f69358cf98cfc4e1c971147b4b8f..077ee569085d3044f3e62455d7a078e47004ca59 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 5cf423ead88ec384f70ee7cf0cf7c976abdc44f4..0a2934d3bdacb4afea2cf161c7768efb8d33f728 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 c232644b0210eb4f1810a59620cd6462f64bd62e..165db214d750dda1a20a8be5113921ba0cd76c17 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 5bef796c5a2cef805e03128d7ed22973bb14dcc6..3d120c5cdd7f0ea2fb9231db09aa9eb77579c2d6 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 similarity index 71% rename from app/views/groups/_new_group_member.html.haml rename to app/views/groups/group_members/_new_group_member.html.haml index 345c0555a36ede9b0a44a9bc07834fda476840e1..c4c29bb2e8d51c31c0676747587b87a52e7a7dad 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 similarity index 92% rename from app/views/groups/members.html.haml rename to app/views/groups/group_members/index.html.haml index 688c22e962474d9e6c252ee6bb1af0b949a0dd4b..0d501fe7bd37be44261cab3f060f80e53fb56609 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 3b8c26ed39101abc4bf1b5360a58486ac281323f..dd1fa3840d5b233675db462946de57e0b400d54b 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 ddd3df19eec4f9ff6efd5258cd09b87613ef0c53..32fe0e37df872764b53622cba16cb8d8045cd640 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 823ebf7734729d361ecd52239c9dbb2a29bde90b..f1916d624b6b35d9fabe1808660022197e8b324d 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 331bb98d5c94ab22439e93c8617a00b59f5cdc7f..ef9617bfc16ad3d47aa75524e5d28a379ca1639b 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 6cf5c81c19e0e7071e0b271b78377f573f3ec82f..273e72f8a4dfc26bf133cbc98afeee4c4107b6a0 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 2d5120f283b1eec25e02d533ca93c1c36a85fa12..f4f4c2662cf597a0e81d4ba0dfb1e9a142bfa9a4 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 7fc3d44034f47ff397d5fd3462b2bf4690287ea5..281a84a3d3c84ddc77a0ec4a8249883eba47a64e 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 0000000000000000000000000000000000000000..b050be1d21b554b17fbfa58fdfafaea5ff363ff8 --- /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 0000000000000000000000000000000000000000..0f824bdabf8fd03ae72bdf8fa237d9d24afecb4b --- /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 0000000000000000000000000000000000000000..368d9419de348f63f995a2a619229b530aefc7b0 --- /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 0000000000000000000000000000000000000000..615c425e59ae2967a6ba90f5d7ff6ad8bd83103d --- /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 similarity index 66% rename from app/views/projects/team_members/import.html.haml rename to app/views/projects/project_members/import.html.haml index 9e31d47117edd4f0778d3b529469662d013b4b37..293754cd0c0fa180a5f80dec6fdb78738d88306a 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 0000000000000000000000000000000000000000..36a6f6a15547d9d05737d5ff08f475a198531dae --- /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 0000000000000000000000000000000000000000..811b1858821c93518116a449322dc0b161954f77 --- /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 166b6362a07aa3db781fc1075851f0931a5db762..0000000000000000000000000000000000000000 --- 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 12bd828a5e766cdc2fd88369bb072ea019b9499c..0000000000000000000000000000000000000000 --- 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 0e5b8176132a91ad02c981f9e4e0c9cf8024b9fa..0000000000000000000000000000000000000000 --- 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 1a755bbd5609e07882140d20f378e4fdbcdc99cb..0000000000000000000000000000000000000000 --- 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" - - = 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 fcc879a58dffe11d7e9bf87ea59a6665b8aa08d5..0000000000000000000000000000000000000000 --- 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 b1bc3ba0eba684a146b503fa89225bda4614e840..0000000000000000000000000000000000000000 --- 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 c68fe9574a2526a4fb136c22bd2d1428919aad4b..0000000000000000000000000000000000000000 --- 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);; diff --git a/config/routes.rb b/config/routes.rb index 889995e92a64f431e5925274c9c34def068cd55b..dd70ad2fa0d8bed410355ed428422e632c52aaeb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -136,7 +136,7 @@ resources :groups, constraints: { id: /[^\/]+/ } do member do - put :project_teams_update + put :members_update end end @@ -215,11 +215,7 @@ scope module: :dashboard do resources :milestones, only: [:index, :show] - resources :groups, only: [:index] do - member do - delete :leave - end - end + resources :groups, only: [:index] resources :projects, only: [] do collection do @@ -236,12 +232,14 @@ member do get :issues get :merge_requests - get :members get :projects end scope module: :groups do - resources :group_members, only: [:create, :update, :destroy] + resources :group_members, only: [:index, :create, :update, :destroy] do + delete :leave, on: :collection + end + resource :avatar, only: [:destroy] resources :milestones, only: [:index, :show, :update] end @@ -425,7 +423,6 @@ end end - resources :team, controller: 'team_members', only: [:index] resources :milestones, except: [:destroy], constraints: { id: /\d+/ } do member do put :sort_issues @@ -445,7 +442,7 @@ end end - resources :team_members, except: [:index, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ } do + resources :project_members, except: [:new, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ } do collection do delete :leave diff --git a/features/project/team_management.feature b/features/project/team_management.feature index 86ea6cd6e9139037f633d8cd781de95d11042069..22393622bb94daad9d226a1def4a4da4fd092a64 100644 --- a/features/project/team_management.feature +++ b/features/project/team_management.feature @@ -13,7 +13,7 @@ Feature: Project Team Management @javascript Scenario: Add user to project - Given I click link "New Team Member" + Given I click link "Add members" And I select "Mike" as "Reporter" Then I should see "Mike" in team list as "Reporter" diff --git a/features/steps/admin/groups.rb b/features/steps/admin/groups.rb index 6bcec48be885bc8d7a719ba1f4f010c271a2bb5f..721460b93710f11b4df29fc7a5c213aaeadb6b3f 100644 --- a/features/steps/admin/groups.rb +++ b/features/steps/admin/groups.rb @@ -38,7 +38,7 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps When 'I select user "John Doe" from user list as "Reporter"' do select2(user_john.id, from: "#user_ids", multiple: true) - within "#new_team_member" do + within "#new_project_member" do select "Reporter", from: "access_level" end click_button "Add users to group" diff --git a/features/steps/explore/groups.rb b/features/steps/explore/groups.rb index ccbf6cda07e174e74bb3fad1bea074f744bbdc07..0c2127d4c4b3ba7133c1fdb68bf9d2fec1713dd8 100644 --- a/features/steps/explore/groups.rb +++ b/features/steps/explore/groups.rb @@ -35,7 +35,7 @@ class Spinach::Features::ExploreGroups < Spinach::FeatureSteps end step 'I visit group "TestGroup" members page' do - visit members_group_path(Group.find_by(name: "TestGroup")) + visit group_group_members_path(Group.find_by(name: "TestGroup")) end step 'I should not see project "Enterprise" items' do diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb index 7907f2a6fe3e21f984d281e3862c861b9e0bfa3e..0eefe2b56887708169b9bcd0a874b826dc02b448 100644 --- a/features/steps/project/team_management.rb +++ b/features/steps/project/team_management.rb @@ -15,18 +15,18 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps page.should have_content(user.username) end - step 'I click link "New Team Member"' do - click_link "New project member" + step 'I click link "Add members"' do + find(:css, 'button.btn-new').click end step 'I select "Mike" as "Reporter"' do user = User.find_by(name: "Mike") - select2(user.id, from: "#user_ids", multiple: true) - within "#new_project_member" do + within ".users-project-form" do + select2(user.id, from: "#user_ids", multiple: true) select "Reporter", from: "access_level" end - click_button "Add users" + click_button "Add users to project" end step 'I should see "Mike" in team list as "Reporter"' do @@ -42,9 +42,13 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps end step 'I change "Sam" role to "Reporter"' do - user = User.find_by(name: "Sam") - within "#user_#{user.id}" do + project = Project.find_by(name: "Shop") + user = User.find_by(name: 'Sam') + project_member = project.project_members.find_by(user_id: user.id) + within "#project_member_#{project_member.id}" do + click_button "Edit access level" select "Reporter", from: "project_member_access_level" + click_button "Save" end end @@ -100,7 +104,10 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps end step 'I click cancel link for "Sam"' do - within "#user_#{User.find_by(name: 'Sam').id}" do + project = Project.find_by(name: "Shop") + user = User.find_by(name: 'Sam') + project_member = project.project_members.find_by(user_id: user.id) + within "#project_member_#{project_member.id}" do click_link('Remove user from team') end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index bb6c336d7cd63feb22119d3eccec9d1f60cdeb27..e3cf1b92cda3bb508293ace1e13fc791c57ddb32 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -32,7 +32,7 @@ module SharedPaths end step 'I visit group "Owned" members page' do - visit members_group_path(Group.find_by(name:"Owned")) + visit group_group_members_path(Group.find_by(name:"Owned")) end step 'I visit group "Owned" settings page' do @@ -52,7 +52,7 @@ module SharedPaths end step 'I visit group "Guest" members page' do - visit members_group_path(Group.find_by(name:"Guest")) + visit group_group_members_path(Group.find_by(name:"Guest")) end step 'I visit group "Guest" settings page' do @@ -386,7 +386,7 @@ module SharedPaths end step 'I visit project "Shop" team page' do - visit namespace_project_team_index_path(project.namespace, project) + visit namespace_project_project_members_path(project.namespace, project) end step 'I visit project wiki page' do diff --git a/lib/api/group_members.rb b/lib/api/group_members.rb index c9c9ccbcb2e77708a4e3cca05c21ada82efd0f70..ed54c7f6ff058942b2d24b1900058bc1570583bb 100644 --- a/lib/api/group_members.rb +++ b/lib/api/group_members.rb @@ -53,14 +53,14 @@ class GroupMembers < Grape::API authorize! :manage_group, group required_attributes! [:access_level] - team_member = group.group_members.find_by(user_id: params[:user_id]) - not_found!('User can not be found') if team_member.nil? + group_member = group.group_members.find_by(user_id: params[:user_id]) + not_found!('User can not be found') if group_member.nil? - if team_member.update_attributes(access_level: params[:access_level]) - @member = team_member.user + if group_member.update_attributes(access_level: params[:access_level]) + @member = group_member.user present @member, with: Entities::GroupMember, group: group else - handle_member_errors team_member.errors + handle_member_errors group_member.errors end end diff --git a/lib/api/project_members.rb b/lib/api/project_members.rb index 73cf062155b889d277799f30dffdf9ef3639e3ea..c756bb479fc2bc01507b99a50b30fb6bc4f0e974 100644 --- a/lib/api/project_members.rb +++ b/lib/api/project_members.rb @@ -46,19 +46,19 @@ class ProjectMembers < Grape::API required_attributes! [:user_id, :access_level] # either the user is already a team member or a new one - team_member = user_project.team_member_by_id(params[:user_id]) - if team_member.nil? - team_member = user_project.project_members.new( + project_member = user_project.project_member_by_id(params[:user_id]) + if project_member.nil? + project_member = user_project.project_members.new( user_id: params[:user_id], access_level: params[:access_level] ) end - if team_member.save - @member = team_member.user + if project_member.save + @member = project_member.user present @member, with: Entities::ProjectMember, project: user_project else - handle_member_errors team_member.errors + handle_member_errors project_member.errors end end @@ -74,14 +74,14 @@ class ProjectMembers < Grape::API authorize! :admin_project, user_project required_attributes! [:access_level] - team_member = user_project.project_members.find_by(user_id: params[:user_id]) - not_found!("User can not be found") if team_member.nil? + project_member = user_project.project_members.find_by(user_id: params[:user_id]) + not_found!("User can not be found") if project_member.nil? - if team_member.update_attributes(access_level: params[:access_level]) - @member = team_member.user + if project_member.update_attributes(access_level: params[:access_level]) + @member = project_member.user present @member, with: Entities::ProjectMember, project: user_project else - handle_member_errors team_member.errors + handle_member_errors project_member.errors end end @@ -94,9 +94,9 @@ class ProjectMembers < Grape::API # DELETE /projects/:id/members/:user_id delete ":id/members/:user_id" do authorize! :admin_project, user_project - team_member = user_project.project_members.find_by(user_id: params[:user_id]) - unless team_member.nil? - team_member.destroy + project_member = user_project.project_members.find_by(user_id: params[:user_id]) + unless project_member.nil? + project_member.destroy else { message: "Access revoked", id: params[:user_id].to_i } end diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 2dfa18da482b7ff5fabafa88e99c55842b970fa4..c3a8d90ef54b33efeb24fc61821285ac84af0e1e 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -200,7 +200,7 @@ def reference_link(type, identifier, project = @project, prefix_text = nil) def reference_user(identifier, project = @project, _ = nil) options = html_options.merge( - class: "gfm gfm-team_member #{html_options[:class]}" + class: "gfm gfm-project_member #{html_options[:class]}" ) if identifier == "all" diff --git a/spec/features/security/group/group_access_spec.rb b/spec/features/security/group/group_access_spec.rb index e0c5cbf4d3d47e0081d7d1d0c02f52f380416fd9..63793149459ab2b4a01a164628f443ced51d0f06 100644 --- a/spec/features/security/group/group_access_spec.rb +++ b/spec/features/security/group/group_access_spec.rb @@ -59,8 +59,8 @@ it { is_expected.to be_denied_for :visitor } end - describe "GET /groups/:path/members" do - subject { members_group_path(group) } + describe "GET /groups/:path/group_members" do + subject { group_group_members_path(group) } it { is_expected.to be_allowed_for owner } it { is_expected.to be_allowed_for master } diff --git a/spec/features/security/group/internal_group_access_spec.rb b/spec/features/security/group/internal_group_access_spec.rb index 5279a1bc13ae0bcc20400cd88f10fc8c788224d2..d17a7412e43874c3ea826e3520958d20f154b7b7 100644 --- a/spec/features/security/group/internal_group_access_spec.rb +++ b/spec/features/security/group/internal_group_access_spec.rb @@ -55,8 +55,8 @@ it { is_expected.to be_denied_for :visitor } end - describe "GET /groups/:path/members" do - subject { members_group_path(group) } + describe "GET /groups/:path/group_members" do + subject { group_group_members_path(group) } it { is_expected.to be_allowed_for owner } it { is_expected.to be_allowed_for master } diff --git a/spec/features/security/group/mixed_group_access_spec.rb b/spec/features/security/group/mixed_group_access_spec.rb index efd14858b980dfc472fb780d78b8924046456a14..b3db7b5dea4404337e9eba20df6d6a85f9395efd 100644 --- a/spec/features/security/group/mixed_group_access_spec.rb +++ b/spec/features/security/group/mixed_group_access_spec.rb @@ -56,8 +56,8 @@ it { is_expected.to be_allowed_for :visitor } end - describe "GET /groups/:path/members" do - subject { members_group_path(group) } + describe "GET /groups/:path/group_members" do + subject { group_group_members_path(group) } it { is_expected.to be_allowed_for owner } it { is_expected.to be_allowed_for master } diff --git a/spec/features/security/group/public_group_access_spec.rb b/spec/features/security/group/public_group_access_spec.rb index c7e3d0a8a404fbc41d6843c92212639d539078ac..c16f0c0d1e1d004c7276c426a9f49b01d2b381fb 100644 --- a/spec/features/security/group/public_group_access_spec.rb +++ b/spec/features/security/group/public_group_access_spec.rb @@ -55,8 +55,8 @@ it { is_expected.to be_allowed_for :visitor } end - describe "GET /groups/:path/members" do - subject { members_group_path(group) } + describe "GET /groups/:path/group_members" do + subject { group_group_members_path(group) } it { is_expected.to be_allowed_for owner } it { is_expected.to be_allowed_for master } diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb index 322697bced894cc93db462b14d324e0693771af8..8d1bfd2522337eef7eff0a7f7baf9b88755e8ff0 100644 --- a/spec/features/security/project/internal_access_spec.rb +++ b/spec/features/security/project/internal_access_spec.rb @@ -79,8 +79,8 @@ it { is_expected.to be_denied_for :visitor } end - describe "GET /:project_path/team" do - subject { namespace_project_team_index_path(project.namespace, project) } + describe "GET /:project_path/project_members" do + subject { namespace_project_project_members_path(project.namespace, project) } it { is_expected.to be_allowed_for master } it { is_expected.to be_denied_for reporter } diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb index ea146c3f0e45083035081838651a6fb325938fe1..9021ff331868772b533d7485235fd786e1d3ecb7 100644 --- a/spec/features/security/project/private_access_spec.rb +++ b/spec/features/security/project/private_access_spec.rb @@ -79,8 +79,8 @@ it { is_expected.to be_denied_for :visitor } end - describe "GET /:project_path/team" do - subject { namespace_project_team_index_path(project.namespace, project) } + describe "GET /:project_path/project_members" do + subject { namespace_project_project_members_path(project.namespace, project) } it { is_expected.to be_allowed_for master } it { is_expected.to be_denied_for reporter } diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb index 8ee9199ff290156273bdec6c674453d2543d2276..6ec190ed777e81a323a5c966777eecae8ad991b1 100644 --- a/spec/features/security/project/public_access_spec.rb +++ b/spec/features/security/project/public_access_spec.rb @@ -84,8 +84,8 @@ it { is_expected.to be_allowed_for :visitor } end - describe "GET /:project_path/team" do - subject { namespace_project_team_index_path(project.namespace, project) } + describe "GET /:project_path/project_members" do + subject { namespace_project_project_members_path(project.namespace, project) } it { is_expected.to be_allowed_for master } it { is_expected.to be_denied_for reporter } diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index fd80c6152214eb689d385ca4711db94b42d41f8f..6ba27b536e4f9cb69c4d517166f06f73027b055c 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -180,7 +180,7 @@ def url_helper(image_name) end it "should include standard gfm classes" do - expect(gfm(actual)).to match(/class="\s?gfm gfm-team_member\s?"/) + expect(gfm(actual)).to match(/class="\s?gfm gfm-project_member\s?"/) end end diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb index e04f1741b24a20f92eab21924383db233074c58f..e206c11f33ae43bb117f1d899307cd60de1a8e08 100644 --- a/spec/models/members/group_member_spec.rb +++ b/spec/models/members/group_member_spec.rb @@ -28,18 +28,18 @@ describe "#after_update" do before do - @membership = create :group_member - @membership.stub(notification_service: double('NotificationService').as_null_object) + @group_member = create :group_member + @group_member.stub(notification_service: double('NotificationService').as_null_object) end it "should send email to user" do - expect(@membership).to receive(:notification_service) - @membership.update_attribute(:access_level, GroupMember::MASTER) + expect(@group_member).to receive(:notification_service) + @group_member.update_attribute(:access_level, GroupMember::MASTER) end it "does not send an email when the access level has not changed" do - expect(@membership).not_to receive(:notification_service) - @membership.update_attribute(:access_level, GroupMember::OWNER) + expect(@group_member).not_to receive(:notification_service) + @group_member.update_attribute(:access_level, GroupMember::OWNER) end end end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 4308a765b5682525fe53bb5e0498fe908f024d56..d9bd91f59901352348f0bb50f7109667d8994af8 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -338,17 +338,14 @@ end end -# project_team_members GET /:project_id/team_members(.:format) team_members#index -# POST /:project_id/team_members(.:format) team_members#create -# new_project_team_member GET /:project_id/team_members/new(.:format) team_members#new -# edit_project_team_member GET /:project_id/team_members/:id/edit(.:format) team_members#edit -# project_team_member GET /:project_id/team_members/:id(.:format) team_members#show -# PUT /:project_id/team_members/:id(.:format) team_members#update -# DELETE /:project_id/team_members/:id(.:format) team_members#destroy -describe Projects::TeamMembersController, 'routing' do +# project_project_members GET /:project_id/project_members(.:format) project_members#index +# POST /:project_id/project_members(.:format) project_members#create +# PUT /:project_id/project_members/:id(.:format) project_members#update +# DELETE /:project_id/project_members/:id(.:format) project_members#destroy +describe Projects::ProjectMembersController, 'routing' do it_behaves_like 'RESTful project resources' do - let(:actions) { [:new, :create, :update, :destroy] } - let(:controller) { 'team_members' } + let(:actions) { [:index, :create, :update, :destroy] } + let(:controller) { 'project_members' } end end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 2074f8e7f78e5176dae29e1927bccd6014b41e4f..34737348d41fd8de61f9d7de696555b14725edcd 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -69,9 +69,9 @@ user_project = note.project.project_members.find_by_user_id(@u_watcher.id) user_project.notification_level = Notification::N_PARTICIPATING user_project.save - user_group = note.project.group.group_members.find_by_user_id(@u_watcher.id) - user_group.notification_level = Notification::N_GLOBAL - user_group.save + group_member = note.project.group.group_members.find_by_user_id(@u_watcher.id) + group_member.notification_level = Notification::N_GLOBAL + group_member.save end it do