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,25 +294,19 @@ 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
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
page.within '[data-testid="group-buttons"]' do
expect(page).to have_link('New subgroup')
expect(page).not_to have_link('New project')
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)
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)
end
end
it 'new project button is displayed without subgroup creation permission' do
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)
......@@ -321,8 +315,22 @@ RSpec.describe 'Group' do
sign_in(user)
visit group_path(group)
page.within '.group-buttons' do
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
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)
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