Commit 1d3e3060 authored by Peter Hegman's avatar Peter Hegman Committed by Olena Horal-Koretska

Break "New project" and "New subgroup" buttons out of dropdown

Better UX and allows us to get rid of some legacy JS
parent 25de286a
import { visitUrl } from '../lib/utils/url_utility';
import DropLab from '../droplab/drop_lab';
import ISetter from '../droplab/plugins/input_setter';
const InputSetter = { ...ISetter };
const NEW_PROJECT = 'new-project';
const NEW_SUBGROUP = 'new-subgroup';
export default class NewGroupChild {
constructor(buttonWrapper) {
this.buttonWrapper = buttonWrapper;
this.newGroupChildButton = this.buttonWrapper.querySelector('.js-new-group-child');
this.dropdownToggle = this.buttonWrapper.querySelector('.js-dropdown-toggle');
this.dropdownList = this.buttonWrapper.querySelector('.dropdown-menu');
this.newGroupPath = this.buttonWrapper.dataset.projectPath;
this.subgroupPath = this.buttonWrapper.dataset.subgroupPath;
this.init();
}
init() {
this.initDroplab();
this.bindEvents();
}
initDroplab() {
this.droplab = new DropLab();
this.droplab.init(
this.dropdownToggle,
this.dropdownList,
[InputSetter],
this.getDroplabConfig(),
);
}
getDroplabConfig() {
return {
InputSetter: [
{
input: this.newGroupChildButton,
valueAttribute: 'data-value',
inputAttribute: 'data-action',
},
{
input: this.newGroupChildButton,
valueAttribute: 'data-text',
},
],
};
}
bindEvents() {
this.newGroupChildButton.addEventListener('click', this.onClickNewGroupChildButton.bind(this));
}
onClickNewGroupChildButton(e) {
if (e.target.dataset.action === NEW_PROJECT) {
visitUrl(this.newGroupPath);
} else if (e.target.dataset.action === NEW_SUBGROUP) {
visitUrl(this.subgroupPath);
}
}
}
......@@ -2,7 +2,6 @@
import { getPagePath, getDashPath } from '~/lib/utils/common_utils';
import { ACTIVE_TAB_SHARED, ACTIVE_TAB_ARCHIVED } from '~/groups/constants';
import NewGroupChild from '~/groups/new_group_child';
import notificationsDropdown from '~/notifications_dropdown';
import NotificationsForm from '~/notifications_form';
import ProjectsList from '~/projects_list';
......@@ -11,7 +10,6 @@ import GroupTabs from './group_tabs';
import initInviteMembersBanner from '~/groups/init_invite_members_banner';
export default function initGroupDetails(actionName = 'show') {
const newGroupChildWrapper = document.querySelector('.js-new-project-subgroup');
const loadableActions = [ACTIVE_TAB_SHARED, ACTIVE_TAB_ARCHIVED];
const dashPath = getDashPath();
let action = loadableActions.includes(dashPath) ? dashPath : getPagePath(1);
......@@ -25,8 +23,5 @@ export default function initGroupDetails(actionName = 'show') {
notificationsDropdown();
new ProjectsList();
if (newGroupChildWrapper) {
new NewGroupChild(newGroupChildWrapper);
}
initInviteMembersBanner();
}
......@@ -20,37 +20,16 @@
%span.access-request-links.gl-ml-3
= render 'shared/members/access_request_links', source: @group
.home-panel-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end
.home-panel-buttons.col-md-12.col-lg-6
- if current_user
.group-buttons
= render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn', emails_disabled: emails_disabled
- new_project_label = _("New project")
- new_subgroup_label = _("New subgroup")
- if can_create_projects and can_create_subgroups
.btn-group.new-project-subgroup.droplab-dropdown.home-panel-action-button.gl-mt-3.js-new-project-subgroup.qa-new-project-or-subgroup-dropdown{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } }
%input.btn.btn-success.dropdown-primary.js-new-group-child.qa-new-in-group-button{ type: "button", value: new_project_label, data: { action: "new-project" } }
%button.btn.btn-success.dropdown-toggle.js-dropdown-toggle.qa-new-project-or-subgroup-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } }
= sprite_icon("chevron-down", css_class: "icon dropdown-btn-icon")
%ul#new-project-or-subgroup-dropdown.dropdown-menu.dropdown-menu-right{ data: { dropdown: true } }
%li.droplab-item-selected.qa-new-project-option{ role: "button", data: { value: "new-project", text: new_project_label } }
.menu-item
.icon-container
= sprite_icon("check", css_class: "list-item-checkmark")
.description
%strong= new_project_label
%span= s_("GroupsTree|Create a project in this group.")
%li.divider.droplap-item-ignore
%li.qa-new-subgroup-option{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } }
.menu-item
.icon-container
= sprite_icon("check", css_class: "list-item-checkmark")
.description
%strong= new_subgroup_label
%span= s_("GroupsTree|Create a subgroup in this group.")
- elsif can_create_projects
= link_to new_project_label, new_project_path(namespace_id: @group.id), class: "btn btn-success gl-mt-3"
- elsif can_create_subgroups
= link_to new_subgroup_label, new_group_path(parent_id: @group.id), class: "btn btn-success gl-mt-3"
.gl-display-flex.gl-flex-wrap.gl-lg-justify-content-end.gl-mx-n2{ data: { testid: 'group-buttons' } }
= render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn gl-button gl-sm-w-auto gl-w-full', dropdown_container_class: 'gl-mr-0 gl-px-2 gl-sm-w-auto gl-w-full', emails_disabled: emails_disabled
- if can_create_subgroups
.gl-px-2.gl-sm-w-auto.gl-w-full
= link_to _("New subgroup"), new_group_path(parent_id: @group.id), class: "btn btn-success btn-md gl-button btn-success-secondary gl-mt-3 gl-sm-w-auto gl-w-full", data: { qa_selector: 'new_subgroup_button' }
- if can_create_projects
.gl-px-2.gl-sm-w-auto.gl-w-full
= link_to _("New project"), new_project_path(namespace_id: @group.id), class: "btn btn-success btn-md gl-button gl-mt-3 gl-sm-w-auto gl-w-full", data: { qa_selector: 'new_project_button' }
- if @group.description.present?
.group-home-desc.mt-1
......
......@@ -44,7 +44,7 @@
.project-repo-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end
- if current_user
.d-inline-flex
= render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn-xs', emails_disabled: emails_disabled
= render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn-xs', dropdown_container_class: 'gl-mr-3', emails_disabled: emails_disabled
.count-buttons.d-inline-flex
= render 'projects/buttons/star'
......
- btn_class = local_assigns.fetch(:btn_class, '')
- dropdown_container_class = local_assigns.fetch(:dropdown_container_class, '')
- emails_disabled = local_assigns.fetch(:emails_disabled, false)
- if notification_setting
......@@ -8,8 +9,8 @@
- else
- button_title = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }
.js-notification-dropdown.notification-dropdown.home-panel-action-button.gl-mt-3.gl-mr-3.dropdown.inline
= form_for notification_setting, remote: true, html: { class: "inline notification-form no-label" } do |f|
.js-notification-dropdown.notification-dropdown.home-panel-action-button.gl-mt-3.dropdown.inline{ class: dropdown_container_class }
= form_for notification_setting, remote: true, html: { class: "notification-form no-label" } do |f|
= hidden_setting_source_input(notification_setting)
= hidden_field_tag "hide_label", true
= f.hidden_field :level, class: "notification_setting_level"
......
---
title: Move "New subgroup" and "New project" out of the dropdown into individual buttons
merge_request: 46907
author:
type: changed
......@@ -235,7 +235,7 @@ There are two different ways to add a new project to a group:
- Select a group, and then click **New project**. You can then continue [creating your project](../../gitlab-basics/create-project.md).
![New project](img/create_new_project_from_group.png)
![New project](img/create_new_project_from_group_v13_6.png)
- While you are creating a project, select a group namespace
you've already created from the dropdown menu.
......
......@@ -99,10 +99,9 @@ creation is disabled by an administrator in their settings.
To create a subgroup:
1. In the group's dashboard expand the **New project** split button, select
**New subgroup** and click the **New subgroup** button.
1. In the group's dashboard click the **New subgroup** button.
![Subgroups page](img/create_subgroup_button.png)
![Subgroups page](img/create_subgroup_button_v13_6.png)
1. Create a new group like you would normally do. Notice that the immediate parent group
namespace is fixed under **Group path**. The visibility level can differ from
......
......@@ -13560,12 +13560,6 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
msgid "GroupsTree|Create a project in this group."
msgstr ""
msgid "GroupsTree|Create a subgroup in this group."
msgstr ""
msgid "GroupsTree|Edit group"
msgstr ""
......
......@@ -7,11 +7,8 @@ module QA
include Page::Component::GroupsFilter
view 'app/views/groups/_home_panel.html.haml' do
element :new_project_or_subgroup_dropdown
element :new_project_or_subgroup_dropdown_toggle
element :new_project_option
element :new_subgroup_option
element :new_in_group_button
element :new_project_button
element :new_subgroup_button
end
view 'app/assets/javascripts/groups/constants.js' do
......@@ -26,8 +23,9 @@ module QA
click_link name
end
def has_new_project_or_subgroup_dropdown?
has_element?(:new_project_or_subgroup_dropdown)
def has_new_project_and_new_subgroup_buttons?
has_element?(:new_project_button)
has_element?(:new_subgroup_button)
end
def has_subgroup?(name)
......@@ -35,15 +33,11 @@ module QA
end
def go_to_new_subgroup
select_kind :new_subgroup_option
click_element :new_in_group_button
click_element :new_subgroup_button
end
def go_to_new_project
select_kind :new_project_option
click_element :new_in_group_button
click_element :new_project_button
end
def leave_group
......@@ -51,23 +45,6 @@ module QA
click_element :leave_group_link
end
end
private
def select_kind(kind)
QA::Support::Retrier.retry_on_exception(sleep_interval: 1.0) do
within_element(:new_project_or_subgroup_dropdown) do
# May need to click again because it is possible to click the button quicker than the JS is bound
wait_until(reload: false) do
click_element :new_project_or_subgroup_dropdown_toggle
has_element?(kind)
end
click_element kind
end
end
end
end
end
end
......
......@@ -44,7 +44,7 @@ module QA
# Ensure that the group was actually created
group_show.wait_until(sleep_interval: 1) do
group_show.has_text?(path) &&
group_show.has_new_project_or_subgroup_dropdown?
group_show.has_new_project_and_new_subgroup_buttons?
end
end
end
......
......@@ -81,8 +81,7 @@ RSpec.describe 'Group show page' do
it 'allows creating subgroups' do
visit path
expect(page)
.to have_css("li[data-text='New subgroup']", visible: false)
expect(page).to have_link('New subgroup')
end
end
end
......@@ -102,8 +101,7 @@ RSpec.describe 'Group show page' do
path = group_path(relaxed_group)
visit path
expect(page)
.to have_css("li[data-text='New subgroup']", visible: false)
expect(page).to have_link('New subgroup')
end
end
......@@ -116,9 +114,7 @@ RSpec.describe 'Group show page' do
path = group_path(restricted_group)
visit path
expect(page)
.not_to have_selector("li[data-text='New subgroup']",
visible: false)
expect(page).not_to have_link('New subgroup')
end
end
end
......
......@@ -294,35 +294,43 @@ RSpec.describe 'Group' do
describe 'new subgroup / project button' do
let(:group) { create(:group, project_creation_level: Gitlab::Access::NO_ONE_PROJECT_ACCESS, subgroup_creation_level: Gitlab::Access::OWNER_SUBGROUP_ACCESS) }
it 'new subgroup button is displayed without project creation permission' do
visit group_path(group)
context 'when user has subgroup creation permissions but not project creation permissions' do
it 'only displays "New subgroup" button' do
visit group_path(group)
page.within '.group-buttons' do
expect(page).to have_link('New subgroup')
page.within '[data-testid="group-buttons"]' do
expect(page).to have_link('New subgroup')
expect(page).not_to have_link('New project')
end
end
end
it 'new subgroup button is displayed together with new project button when having project creation permission' do
group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
visit group_path(group)
context 'when user has project creation permissions but not subgroup creation permissions' do
it 'only displays "New project" button' do
group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
user = create(:user)
page.within '.group-buttons' do
expect(page).to have_css("li[data-text='New subgroup']", visible: false)
expect(page).to have_css("li[data-text='New project']", visible: false)
group.add_maintainer(user)
sign_out(:user)
sign_in(user)
visit group_path(group)
page.within '[data-testid="group-buttons"]' do
expect(page).to have_link('New project')
expect(page).not_to have_link('New subgroup')
end
end
end
it 'new project button is displayed without subgroup creation permission' do
group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
user = create(:user)
group.add_maintainer(user)
sign_out(:user)
sign_in(user)
context 'when user has project and subgroup creation permissions' do
it 'displays "New subgroup" and "New project" buttons' do
group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
visit group_path(group)
visit group_path(group)
page.within '.group-buttons' do
expect(page).to have_link('New project')
page.within '[data-testid="group-buttons"]' do
expect(page).to have_link('New subgroup')
expect(page).to have_link('New project')
end
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment