summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFatih Acet <acetfatih@gmail.com>2016-12-09 18:11:47 +0000
committerFatih Acet <acetfatih@gmail.com>2016-12-09 18:11:47 +0000
commit5bb43bb9531422545f974df8a6cf5616b7631f51 (patch)
tree9a38a0888f498def6d26a5ee590963509a1085bd
parentb546fd7bba7434c787debb92e944b34420a0ee4c (diff)
parentfcf332a4fa544d4a5eba200878a7b9298e5b6f6b (diff)
downloadgitlab-ce-5bb43bb9531422545f974df8a6cf5616b7631f51.tar.gz
Merge branch 'members-dropdowns' into 'master'
Updated members dropdowns ## What does this MR do? EE has different dropdowns to allow for group LDAP members to be overridden, this ports the dropdown changes over to reduce conflicts. ## Screenshots (if relevant) ![Screen_Shot_2016-12-07_at_15.28.20](/uploads/6cb6def34015b024dc878aa3b99be4a0/Screen_Shot_2016-12-07_at_15.28.20.png) See merge request !7974
-rw-r--r--app/assets/javascripts/gl_dropdown.js5
-rw-r--r--app/assets/javascripts/members.js.es665
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss5
-rw-r--r--app/assets/stylesheets/pages/members.scss4
-rw-r--r--app/views/groups/group_members/update.js.haml1
-rw-r--r--app/views/projects/group_links/update.js.haml1
-rw-r--r--app/views/projects/project_members/update.js.haml1
-rw-r--r--app/views/shared/members/_group.html.haml21
-rw-r--r--app/views/shared/members/_member.html.haml20
-rw-r--r--changelogs/unreleased/members-dropdowns.yml4
-rw-r--r--features/steps/group/members.rb7
-rw-r--r--features/steps/project/team_management.rb8
-rw-r--r--spec/features/projects/members/group_links_spec.rb9
13 files changed, 131 insertions, 20 deletions
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index 969778dded7..9a91018a8e4 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -650,6 +650,11 @@
} else if(value) {
field = this.dropdown.parent().find("input[name='" + fieldName + "'][value='" + value.toString().replace(/'/g, '\\\'') + "']");
}
+
+ if (this.options.isSelectable && !this.options.isSelectable(selectedObject, el)) {
+ return;
+ }
+
if (el.hasClass(ACTIVE_CLASS)) {
el.removeClass(ACTIVE_CLASS);
if (field && field.length) {
diff --git a/app/assets/javascripts/members.js.es6 b/app/assets/javascripts/members.js.es6
index 895bc10784f..e3f367a11eb 100644
--- a/app/assets/javascripts/members.js.es6
+++ b/app/assets/javascripts/members.js.es6
@@ -1,38 +1,81 @@
-/* eslint-disable */
-((w) => {
- w.gl = w.gl || {};
+/* eslint-disable class-methods-use-this */
+(() => {
+ window.gl = window.gl || {};
class Members {
constructor() {
this.addListeners();
+ this.initGLDropdown();
}
addListeners() {
$('.project_member, .group_member').off('ajax:success').on('ajax:success', this.removeRow);
- $('.js-member-update-control').off('change').on('change', this.formSubmit);
- $('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess);
+ $('.js-member-update-control').off('change').on('change', this.formSubmit.bind(this));
+ $('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess.bind(this));
gl.utils.disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
}
+ initGLDropdown() {
+ $('.js-member-permissions-dropdown').each((i, btn) => {
+ const $btn = $(btn);
+
+ $btn.glDropdown({
+ selectable: true,
+ isSelectable(selected, $el) {
+ return !$el.hasClass('is-active');
+ },
+ fieldName: $btn.data('field-name'),
+ id(selected, $el) {
+ return $el.data('id');
+ },
+ toggleLabel(selected, $el) {
+ return $el.text();
+ },
+ clicked: (selected, $link) => {
+ this.formSubmit(null, $link);
+ },
+ });
+ });
+ }
+
removeRow(e) {
const $target = $(e.target);
if ($target.hasClass('btn-remove')) {
$target.closest('.member')
- .fadeOut(function () {
+ .fadeOut(function fadeOutMemberRow() {
$(this).remove();
});
}
}
- formSubmit() {
- $(this).closest('form').trigger("submit.rails").end().disable();
+ formSubmit(e, $el = null) {
+ const $this = e ? $(e.currentTarget) : $el;
+ const { $toggle, $dateInput } = this.getMemberListItems($this);
+
+ $this.closest('form').trigger('submit.rails');
+
+ $toggle.disable();
+ $dateInput.disable();
}
- formSuccess() {
- $(this).find('.js-member-update-control').enable();
+ formSuccess(e) {
+ const { $toggle, $dateInput } = this.getMemberListItems($(e.currentTarget).closest('.member'));
+
+ $toggle.enable();
+ $dateInput.enable();
+ }
+
+ getMemberListItems($el) {
+ const $memberListItem = $el.is('.member') ? $el : $(`#${$el.data('el-id')}`);
+
+ return {
+ $memberListItem,
+ $toggle: $memberListItem.find('.dropdown-menu-toggle'),
+ $dateInput: $memberListItem.find('.js-access-expiration-date'),
+ };
}
}
gl.Members = Members;
-})(window);
+})();
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 33de652c06f..d5914b900e2 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -42,6 +42,11 @@
border-radius: $border-radius-base;
white-space: nowrap;
+ &[disabled] {
+ background-color: $input-bg-disabled;
+ cursor: not-allowed;
+ }
+
&.no-outline {
outline: 0;
}
diff --git a/app/assets/stylesheets/pages/members.scss b/app/assets/stylesheets/pages/members.scss
index 756efa9c7fa..5f3bbb40ba0 100644
--- a/app/assets/stylesheets/pages/members.scss
+++ b/app/assets/stylesheets/pages/members.scss
@@ -54,6 +54,10 @@
@media (min-width: $screen-sm-min) {
width: 50%;
}
+
+ .dropdown-menu-toggle {
+ width: 100%;
+ }
}
.member-access-text {
diff --git a/app/views/groups/group_members/update.js.haml b/app/views/groups/group_members/update.js.haml
index de8f53b6b52..9d05bff6c4e 100644
--- a/app/views/groups/group_members/update.js.haml
+++ b/app/views/groups/group_members/update.js.haml
@@ -1,3 +1,4 @@
:plain
var $listItem = $('#{escape_javascript(render('shared/members/member', member: @group_member))}');
$("##{dom_id(@group_member)} .list-item-name").replaceWith($listItem.find('.list-item-name'));
+ gl.utils.localTimeAgo($('.js-timeago'), $("##{dom_id(@group_member)}"));
diff --git a/app/views/projects/group_links/update.js.haml b/app/views/projects/group_links/update.js.haml
index af9a5b19060..55520fda494 100644
--- a/app/views/projects/group_links/update.js.haml
+++ b/app/views/projects/group_links/update.js.haml
@@ -1,3 +1,4 @@
:plain
var $listItem = $('#{escape_javascript(render('shared/members/group', group_link: @group_link))}');
$("#group_member_#{@group_link.id} .list-item-name").replaceWith($listItem.find('.list-item-name'));
+ gl.utils.localTimeAgo($('.js-timeago'), $("#group_member_#{@group_link.id}"));
diff --git a/app/views/projects/project_members/update.js.haml b/app/views/projects/project_members/update.js.haml
index 91927181efb..d15f4310ff5 100644
--- a/app/views/projects/project_members/update.js.haml
+++ b/app/views/projects/project_members/update.js.haml
@@ -1,3 +1,4 @@
:plain
var $listItem = $('#{escape_javascript(render('shared/members/member', member: @project_member))}');
$("##{dom_id(@project_member)} .list-item-name").replaceWith($listItem.find('.list-item-name'));
+ gl.utils.localTimeAgo($('.js-timeago'), $("##{dom_id(@project_member)}"));
diff --git a/app/views/shared/members/_group.html.haml b/app/views/shared/members/_group.html.haml
index 1c0346bbc78..8928de9097b 100644
--- a/app/views/shared/members/_group.html.haml
+++ b/app/views/shared/members/_group.html.haml
@@ -1,7 +1,8 @@
- group_link = local_assigns[:group_link]
- group = group_link.group
- can_admin_member = can?(current_user, :admin_project_member, @project)
-%li.member.group_member{ id: "group_member_#{group_link.id}" }
+- dom_id = "group_member_#{group_link.id}"
+%li.member.group_member{ id: dom_id }
%span{ class: "list-item-name" }
= image_tag group_icon(group), class: "avatar s40", alt: ''
%strong
@@ -14,7 +15,23 @@
Expires in #{distance_of_time_in_words_to_now(group_link.expires_at)}
.controls.member-controls
= form_tag namespace_project_group_link_path(@project.namespace, @project, group_link), method: :put, remote: true, class: 'form-horizontal js-edit-member-form' do
- = select_tag 'group_link[group_access]', options_for_select(ProjectGroupLink.access_options, group_link.group_access), class: 'form-control member-form-control append-right-5 js-member-update-control', id: "member_access_level_#{group.id}", disabled: !can_admin_member
+ = hidden_field_tag "group_link[group_access]", group_link.group_access
+ .member-form-control.dropdown.append-right-5
+ %button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button",
+ disabled: !can_admin_member,
+ data: { toggle: "dropdown", field_name: "group_link[group_access]" } }
+ %span.dropdown-toggle-text
+ = group_link.human_access
+ = icon("chevron-down")
+ .dropdown-menu.dropdown-select.dropdown-menu-align-right.dropdown-menu-selectable
+ = dropdown_title("Change permissions")
+ .dropdown-content
+ %ul
+ - Gitlab::Access.options.each do |role, role_id|
+ %li
+ = link_to role, "javascript:void(0)",
+ class: ("is-active" if group_link.group_access == role_id),
+ data: { id: role_id, el_id: dom_id }
.prepend-left-5.clearable-input.member-form-control
= text_field_tag 'group_link[expires_at]', group_link.expires_at, class: 'form-control js-access-expiration-date js-member-update-control', placeholder: 'Expiration date', id: "member_expires_at_#{group.id}", disabled: !can_admin_member
%i.clear-icon.js-clear-input
diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml
index e67f7d5a352..659d4c905fc 100644
--- a/app/views/shared/members/_member.html.haml
+++ b/app/views/shared/members/_member.html.haml
@@ -48,9 +48,25 @@
- if show_controls && (member.respond_to?(:group) && @group) || (member.respond_to?(:project) && @project)
- if user != current_user
= form_for member, remote: true, html: { class: 'form-horizontal js-edit-member-form' } do |f|
- = f.select :access_level, options_for_select(member.class.access_level_roles, member.access_level), {}, class: 'form-control member-form-control append-right-5 js-member-update-control', id: "member_access_level_#{member.id}", disabled: !can_admin_member
+ = f.hidden_field :access_level
+ .member-form-control.dropdown.append-right-5
+ %button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button",
+ disabled: !can_admin_member,
+ data: { toggle: "dropdown", field_name: "#{f.object_name}[access_level]" } }
+ %span.dropdown-toggle-text
+ = member.human_access
+ = icon("chevron-down")
+ .dropdown-menu.dropdown-select.dropdown-menu-align-right.dropdown-menu-selectable
+ = dropdown_title("Change permissions")
+ .dropdown-content
+ %ul
+ - Gitlab::Access.options.each do |role, role_id|
+ %li
+ = link_to role, "javascript:void(0)",
+ class: ("is-active" if member.access_level == role_id),
+ data: { id: role_id, el_id: dom_id(member) }
.prepend-left-5.clearable-input.member-form-control
- = f.text_field :expires_at, class: 'form-control js-access-expiration-date js-member-update-control', placeholder: 'Expiration date', id: "member_expires_at_#{member.id}", disabled: !can_admin_member
+ = f.text_field :expires_at, class: 'form-control js-access-expiration-date js-member-update-control', placeholder: 'Expiration date', id: "member_expires_at_#{member.id}", disabled: !can_admin_member, data: { el_id: dom_id(member) }
%i.clear-icon.js-clear-input
- else
%span.member-access-text= member.human_access
diff --git a/changelogs/unreleased/members-dropdowns.yml b/changelogs/unreleased/members-dropdowns.yml
new file mode 100644
index 00000000000..b15403d6d62
--- /dev/null
+++ b/changelogs/unreleased/members-dropdowns.yml
@@ -0,0 +1,4 @@
+---
+title: Updated members dropdowns
+merge_request:
+author:
diff --git a/features/steps/group/members.rb b/features/steps/group/members.rb
index cefc55d07ab..adaf375453c 100644
--- a/features/steps/group/members.rb
+++ b/features/steps/group/members.rb
@@ -117,7 +117,12 @@ class Spinach::Features::GroupMembers < Spinach::FeatureSteps
member = mary_jane_member
page.within "#group_member_#{member.id}" do
- select 'Developer', from: "member_access_level_#{member.id}"
+ click_button member.human_access
+
+ page.within '.dropdown-menu' do
+ click_link 'Developer'
+ end
+
wait_for_ajax
end
end
diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb
index b21d0849ad1..22d971fadfb 100644
--- a/features/steps/project/team_management.rb
+++ b/features/steps/project/team_management.rb
@@ -65,7 +65,11 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps
user = User.find_by(name: 'Dmitriy')
project_member = project.project_members.find_by(user_id: user.id)
page.within "#project_member_#{project_member.id}" do
- select "Reporter", from: "member_access_level_#{project_member.id}"
+ click_button project_member.human_access
+
+ page.within '.dropdown-menu' do
+ click_link 'Reporter'
+ end
end
end
@@ -144,7 +148,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps
step 'I should see "Opensource" group user listing' do
page.within '.project-members-groups' do
expect(page).to have_content('OpenSource')
- expect(find('select').value).to eq('40')
+ expect(first('.group_member')).to have_content('Master')
end
end
end
diff --git a/spec/features/projects/members/group_links_spec.rb b/spec/features/projects/members/group_links_spec.rb
index cc2f695211c..94995f7cf95 100644
--- a/spec/features/projects/members/group_links_spec.rb
+++ b/spec/features/projects/members/group_links_spec.rb
@@ -16,12 +16,17 @@ feature 'Projects > Members > Anonymous user sees members', feature: true, js: t
end
it 'updates group access level' do
- select 'Guest', from: "member_access_level_#{group.id}"
+ click_button @group_link.human_access
+
+ page.within '.dropdown-menu' do
+ click_link 'Guest'
+ end
+
wait_for_ajax
visit namespace_project_project_members_path(project.namespace, project)
- expect(page).to have_select("member_access_level_#{group.id}", selected: 'Guest')
+ expect(first('.group_member')).to have_content('Guest')
end
it 'updates expiry date' do