Commit 070d28f0 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch '324086-remove-combined-menu-ff' into 'master'

Remove combined_menu feature flag  [RUN ALL RSPEC] [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!65355
parents 50f2fdc7 02179d8f
import Vue from 'vue';
import GlFeatureFlagsPlugin from '~/vue_shared/gl_feature_flags_plugin';
import Translate from '~/vue_shared/translate';
if (process.env.NODE_ENV !== 'production') {
Vue.config.productionTip = false;
}
Vue.use(GlFeatureFlagsPlugin);
Vue.use(Translate);
Vue.config.ignoredElements = ['gl-emoji'];
import $ from 'jquery';
import Vue from 'vue';
import Vuex from 'vuex';
import { createStore } from '~/frequent_items/store';
import VuexModuleProvider from '~/vue_shared/components/vuex_module_provider.vue';
import Translate from '~/vue_shared/translate';
import { FREQUENT_ITEMS_DROPDOWNS } from './constants';
import eventHub from './event_hub';
Vue.use(Vuex);
Vue.use(Translate);
export default function initFrequentItemDropdowns() {
const store = createStore();
FREQUENT_ITEMS_DROPDOWNS.forEach((dropdown) => {
const { namespace, key, vuexModule } = dropdown;
const el = document.getElementById(`js-${namespace}-dropdown`);
const navEl = document.getElementById(`nav-${namespace}-dropdown`);
// Don't do anything if element doesn't exist (No groups dropdown)
// This is for when the user accesses GitLab without logging in
if (!el || !navEl) {
return;
}
import('./components/app.vue')
.then(({ default: FrequentItems }) => {
// eslint-disable-next-line no-new
new Vue({
el,
store,
data() {
const { dataset } = this.$options.el;
const item = {
id: Number(dataset[`${key}Id`]),
name: dataset[`${key}Name`],
namespace: dataset[`${key}Namespace`],
webUrl: dataset[`${key}WebUrl`],
avatarUrl: dataset[`${key}AvatarUrl`] || null,
lastAccessedOn: Date.now(),
};
return {
currentUserName: dataset.userName,
currentItem: item,
};
},
render(createElement) {
return createElement(
VuexModuleProvider,
{
props: {
vuexModule,
},
},
[
createElement(FrequentItems, {
props: {
namespace,
currentUserName: this.currentUserName,
currentItem: this.currentItem,
searchClass: 'gl-display-none gl-sm-display-block',
},
}),
],
);
},
});
})
.catch(() => {});
$(navEl).on('shown.bs.dropdown', () => {
eventHub.$emit(`${namespace}-dropdownOpen`);
});
});
}
......@@ -27,7 +27,6 @@ import { getLocationHash, visitUrl } from './lib/utils/url_utility';
import initFeatureHighlight from './feature_highlight';
import LazyLoader from './lazy_loader';
import initLogoAnimation from './logo';
import initFrequentItemDropdowns from './frequent_items';
import initBreadcrumbs from './breadcrumb';
import initPersistentUserCallouts from './persistent_user_callouts';
import { initUserTracking, initDefaultTrackers } from './tracking';
......@@ -92,7 +91,6 @@ function deferredInitialisation() {
initServicePingConsent();
initUserPopovers();
initBroadcastNotifications();
initFrequentItemDropdowns();
initPersistentUserCallouts();
initDefaultTrackers();
initFeatureHighlight();
......
// With combined_menu feature flag, there's a benefit to splitting up the import
// TODO: With the combined_menu feature flag removed, there's likely a better
// way to slice up the async import (i.e., include trigger in main bundle, but
// async import subviews. Don't do this at the cost of UX).
// See https://gitlab.com/gitlab-org/gitlab/-/issues/336042
const importModule = () => import(/* webpackChunkName: 'top_nav' */ './mount');
const tryMountTopNav = async () => {
......
......@@ -50,12 +50,6 @@
width: 100%;
}
&.frequent-items-dropdown-menu {
padding: 0;
overflow-y: initial;
max-height: initial;
}
// `GlDropdown` specifies the `max-height` of `.gl-new-dropdown-inner`
// as `$dropdown-max-height`, but the `max-height` rule above forces
// the parent `.dropdown-menu` to be _slightly_ too small because of
......@@ -834,61 +828,11 @@
}
}
header.header-content .dropdown-menu.frequent-items-dropdown-menu {
padding: 0;
}
.frequent-items-dropdown-container {
display: flex;
flex-direction: row;
height: $grid-size * 40;
&.with-deprecated-styles {
width: 500px;
height: 354px;
.section-header,
.frequent-items-list-container li.section-empty {
padding: 0 $gl-padding;
}
.search-input-container {
position: relative;
padding: 4px $gl-padding;
.search-icon {
position: absolute;
top: 13px;
right: 25px;
color: $gray-300;
}
}
@include media-breakpoint-down(xs) {
flex-direction: column;
width: 100%;
height: auto;
flex: 1;
.frequent-items-dropdown-sidebar,
.frequent-items-dropdown-content {
width: 100%;
}
.frequent-items-dropdown-sidebar {
border-bottom: 1px solid $border-color;
border-right: 0;
}
}
.frequent-items-list-container {
width: auto;
height: auto;
padding-bottom: 0;
}
}
.frequent-items-dropdown-sidebar,
.frequent-items-dropdown-content {
@include gl-pt-3;
}
......@@ -897,11 +841,6 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu {
color: $almost-black;
}
.frequent-items-dropdown-sidebar {
width: 30%;
border-right: 1px solid $border-color;
}
.frequent-items-dropdown-content {
position: relative;
width: 70%;
......
......@@ -336,9 +336,6 @@ h1 {
.d-none {
display: none !important;
}
.d-inline-block {
display: inline-block !important;
}
.d-block {
display: block !important;
}
......@@ -363,11 +360,6 @@ h1 {
display: block !important;
}
}
@media (min-width: 1200px) {
.d-xl-block {
display: block !important;
}
}
.sr-only {
position: absolute;
width: 1px;
......@@ -1407,10 +1399,6 @@ svg.s16 {
width: 16px;
height: 16px;
}
svg.s18 {
width: 18px;
height: 18px;
}
svg.s32 {
width: 32px;
height: 32px;
......@@ -1499,12 +1487,6 @@ svg.s16 {
height: 16px;
margin-right: 8px;
}
.avatar.s18,
.avatar-container.s18 {
width: 18px;
height: 18px;
margin-right: 8px;
}
.avatar.s32,
.avatar-container.s32 {
width: 32px;
......@@ -1583,9 +1565,6 @@ svg.s16 {
.rect-avatar.s16 {
border-radius: 2px;
}
.rect-avatar.s18 {
border-radius: 2px;
}
.rect-avatar.s32,
.nav-sidebar-inner-scroll
> div.context-header
......
......@@ -317,9 +317,6 @@ h1 {
.d-none {
display: none !important;
}
.d-inline-block {
display: inline-block !important;
}
.d-block {
display: block !important;
}
......@@ -344,11 +341,6 @@ h1 {
display: block !important;
}
}
@media (min-width: 1200px) {
.d-xl-block {
display: block !important;
}
}
.sr-only {
position: absolute;
width: 1px;
......@@ -1388,10 +1380,6 @@ svg.s16 {
width: 16px;
height: 16px;
}
svg.s18 {
width: 18px;
height: 18px;
}
svg.s32 {
width: 32px;
height: 32px;
......@@ -1480,12 +1468,6 @@ svg.s16 {
height: 16px;
margin-right: 8px;
}
.avatar.s18,
.avatar-container.s18 {
width: 18px;
height: 18px;
margin-right: 8px;
}
.avatar.s32,
.avatar-container.s32 {
width: 32px;
......@@ -1564,9 +1546,6 @@ svg.s16 {
.rect-avatar.s16 {
border-radius: 2px;
}
.rect-avatar.s18 {
border-radius: 2px;
}
.rect-avatar.s32,
.nav-sidebar-inner-scroll
> div.context-header
......
......@@ -23,10 +23,6 @@ module DashboardHelper
dashboard_nav_links.include?(link)
end
def any_dashboard_nav_link?(links)
links.any? { |link| dashboard_nav_link?(link) }
end
def has_start_trial?
false
end
......
- has_impersonation_link = header_link?(:admin_impersonation)
- user_status_data = user_status_properties(current_user)
- use_top_nav_redesign = Feature.enabled?(:combined_menu, current_user, default_enabled: :yaml)
%header.navbar.navbar-gitlab.navbar-expand-sm.js-navbar{ data: { qa_selector: 'navbar' } }
%a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content
......@@ -20,24 +19,18 @@
%span.gl-badge.gl-bg-green-500.gl-text-white.gl-rounded-pill.gl-font-weight-bold.gl-py-1
= _('Next')
- if use_top_nav_redesign
.gl-display-none.gl-sm-display-block
= render "layouts/nav/top_nav"
- else
- if current_user
= render "layouts/nav/dashboard"
- else
= render "layouts/nav/explore"
.gl-display-none.gl-sm-display-block
= render "layouts/nav/top_nav"
.navbar-collapse.collapse
%ul.nav.navbar-nav
- if current_user
= render 'layouts/header/new_dropdown', class: ('gl-display-none gl-sm-display-block' if use_top_nav_redesign)
= render 'layouts/header/new_dropdown', class: 'gl-display-none gl-sm-display-block'
- if top_nav_show_search
- search_menu_item = top_nav_search_menu_item_attrs
%li.nav-item.d-none.d-lg-block.m-auto
= render 'layouts/search' unless current_controller?(:search)
%li.nav-item{ class: use_top_nav_redesign ? 'd-none d-sm-inline-block d-lg-none' : 'd-inline-block d-lg-none' }
%li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' }
= link_to search_menu_item.fetch(:href), title: search_menu_item.fetch(:title), aria: { label: search_menu_item.fetch(:title) }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon(search_menu_item.fetch(:icon))
- if header_link?(:issues)
......@@ -118,14 +111,11 @@
- sign_in_text = allow_signup? ? _('Sign in / Register') : _('Sign in')
= link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'gl-button btn btn-default btn-sign-in'
%button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: ('gl-border-none!' if use_top_nav_redesign) }
%button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: 'gl-border-none!', data: { testid: 'top-nav-responsive-toggle' } }
%span.sr-only= _('Toggle navigation')
- if use_top_nav_redesign
%span.more-icon.gl-px-3.gl-font-sm.gl-font-weight-bold
%span.gl-pr-2= _('Menu')
= sprite_icon('hamburger', size: 16)
- else
= sprite_icon('ellipsis_h', size: 12, css_class: 'more-icon')
%span.more-icon.gl-px-3.gl-font-sm.gl-font-weight-bold
%span.gl-pr-2= _('Menu')
= sprite_icon('hamburger', size: 16)
= sprite_icon('close', size: 12, css_class: 'close-icon')
- if display_whats_new?
......
-# WARNING! This file is slated to be removed along with the `combined_menu`
-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
-# Please see [this MR][1] for more context.
-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
%ul.list-unstyled.navbar-sub-nav
- if dashboard_nav_link?(:projects)
= nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects", data: { track_label: "projects_dropdown", track_event: "click_dropdown" } }) do
%button{ type: 'button', data: { toggle: "dropdown" } }
= _('Projects')
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu.frequent-items-dropdown-menu
= render "layouts/nav/projects_dropdown/show"
- if dashboard_nav_link?(:groups)
= nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "d-none d-md-block home dropdown header-groups", data: { track_label: "groups_dropdown", track_event: "click_dropdown" } }) do
%button{ type: 'button', data: { toggle: "dropdown" } }
= _('Groups')
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu.frequent-items-dropdown-menu
= render "layouts/nav/groups_dropdown/show"
- if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets])
= nav_link(html_options: { id: 'nav-more-dropdown', class: "header-more dropdown", data: { track_label: "more_dropdown", track_event: "click_more_link" } }) do
%a{ href: "#", data: { toggle: "dropdown" } }
= _('More')
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu
%ul
- if dashboard_nav_link?(:groups)
%li.d-md-none
= link_to dashboard_groups_path, class: 'dashboard-shortcuts-groups' do
= _('Groups')
- if dashboard_nav_link?(:activity)
= nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity' do
= _('Activity')
- if dashboard_nav_link?(:milestones)
= nav_link(controller: 'dashboard/milestones') do
= link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones' do
= _('Milestones')
- if dashboard_nav_link?(:snippets)
= nav_link(controller: 'dashboard/snippets') do
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets' do
= _('Snippets')
%li.dropdown
= render_if_exists 'dashboard/nav_link_list'
- if current_user.admin?
= nav_link(controller: 'admin/dashboard') do
= link_to admin_root_path, class: 'admin-icon d-xl-none' do
= _('Admin Area')
- if Gitlab::CurrentSettings.admin_mode
- if header_link?(:admin_mode)
= nav_link(controller: 'admin/sessions') do
= link_to destroy_admin_session_path, method: :post, class: 'd-lg-none lock-open-icon' do
= _('Leave Admin Mode')
- elsif current_user.admin?
= nav_link(controller: 'admin/sessions') do
= link_to new_admin_session_path, class: 'd-lg-none lock-icon' do
= _('Enter Admin Mode')
- if Gitlab::Sherlock.enabled?
%li
= link_to sherlock_transactions_path, class: 'admin-icon' do
= _('Sherlock Transactions')
- if current_user.admin?
= nav_link(controller: 'admin/dashboard', html_options: { class: "d-none d-xl-block"}) do
= link_to admin_root_path, class: 'admin-icon', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('admin', size: 18)
- if Gitlab::CurrentSettings.admin_mode
- if header_link?(:admin_mode)
= nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block"}) do
= link_to destroy_admin_session_path, method: :post, title: _('Leave Admin Mode'), aria: { label: _('Leave Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= sprite_icon('lock-open', size: 18)
- elsif current_user.admin?
= nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block"}) do
= link_to new_admin_session_path, title: _('Enter Admin Mode'), aria: { label: _('Enter Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= sprite_icon('lock', size: 18)
-# Shortcut to Dashboard > Projects
- if dashboard_nav_link?(:projects)
%li.hidden
= link_to dashboard_projects_path, class: 'dashboard-shortcuts-projects' do
= _('Projects')
= render_if_exists 'layouts/nav/geo_primary_node_url'
-# WARNING! This file is slated to be removed along with the `combined_menu`
-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
-# Please see [this MR][1] for more context.
-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
%ul.list-unstyled.navbar-sub-nav
- if explore_nav_link?(:projects)
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
= link_to explore_root_path, title: _('Projects'), class: 'dashboard-shortcuts-projects' do
= _('Projects')
- if explore_nav_link?(:groups)
= nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
= link_to explore_groups_path, title: _('Groups'), class: 'dashboard-shortcuts-groups' do
= _('Groups')
- if explore_nav_link?(:snippets)
= nav_link(controller: :snippets) do
= link_to explore_snippets_path, title: _('Snippets'), class: 'dashboard-shortcuts-snippets' do
= _('Snippets')
%li
= link_to _("Help"), help_path, title: _('About GitLab CE')
- return unless Feature.enabled?(:combined_menu, current_user, default_enabled: :yaml)
- top_class = local_assigns.fetch(:class, nil)
- view_model = top_nav_responsive_view_model(project: @project, group: @group)
......
-# WARNING! This file is slated to be removed along with the `combined_menu`
-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
-# Please see [this MR][1] for more context.
-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
- group_meta = { id: @group.id, name: @group.name, namespace: @group.full_name, web_url: group_path(@group), avatar_url: @group.avatar_url } if @group&.persisted?
.frequent-items-dropdown-container.with-deprecated-styles
.frequent-items-dropdown-sidebar
%ul
= nav_link(path: 'dashboard/groups#index') do
= link_to dashboard_groups_path, data: { track_label: "groups_dropdown_your_groups", track_event: "click_link" } do
= _('Your groups')
= nav_link(path: 'groups#explore') do
= link_to explore_groups_path, data: { track_label: "groups_dropdown_explore_groups", track_event: "click_link" } do
= _('Explore groups')
- if current_user.can_create_group?
= nav_link(path: 'groups/new#create-group-pane', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do
= link_to new_group_path(anchor: 'create-group-pane'), data: { track_label: "groups_dropdown_create_group", track_event: "click_link" } do
= _('Create group')
= nav_link(path: 'groups/new#import-group-pane') do
= link_to new_group_path(anchor: 'import-group-pane'), data: { track_label: "groups_dropdown_import_group", track_event: "click_link" } do
= _('Import group')
.frequent-items-dropdown-content
#js-groups-dropdown{ data: { user_name: current_user.username, group: group_meta } }
-# WARNING! This file is slated to be removed along with the `combined_menu`
-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
-# Please see [this MR][1] for more context.
-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
- project_meta = { id: @project.id, name: @project.name, namespace: @project.full_name, web_url: project_path(@project), avatar_url: @project.avatar_url } if @project&.persisted?
.frequent-items-dropdown-container.with-deprecated-styles
.frequent-items-dropdown-sidebar
%ul
= nav_link(path: 'dashboard/projects#index') do
= link_to dashboard_projects_path, data: { track_label: "projects_dropdown_your_projects", track_event: "click_link" } do
= _('Your projects')
= nav_link(path: 'projects#starred') do
= link_to starred_dashboard_projects_path, data: { track_label: "projects_dropdown_starred_projects", track_event: "click_link" } do
= _('Starred projects')
= nav_link(path: 'projects#trending') do
= link_to explore_root_path, data: { track_label: "projects_dropdown_explore_projects", track_event: "click_link" } do
= _('Explore projects')
= nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do
= link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", qa_selector: "create_project_link" } do
= _('Create blank project')
= nav_link(path: 'projects/new#import_project') do
= link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", qa_selector: "import_project_link" } do
= _('Import project')
= nav_link(path: 'projects/new#create_from_template') do
= link_to new_project_path(anchor: 'create_from_template'), data: { track_label: "projects_dropdown_create_from_template", track_event: "click_link" } do
= _('Create from template')
.frequent-items-dropdown-content
#js-projects-dropdown{ data: { user_name: current_user.username, project: project_meta } }
---
name: combined_menu
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56249
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/324086
milestone: '13.10'
type: development
group: group::editor
default_enabled: true
......@@ -336,9 +336,6 @@ h1 {
.d-none {
display: none !important;
}
.d-inline-block {
display: inline-block !important;
}
.d-block {
display: block !important;
}
......@@ -363,11 +360,6 @@ h1 {
display: block !important;
}
}
@media (min-width: 1200px) {
.d-xl-block {
display: block !important;
}
}
.sr-only {
position: absolute;
width: 1px;
......@@ -1407,10 +1399,6 @@ svg.s16 {
width: 16px;
height: 16px;
}
svg.s18 {
width: 18px;
height: 18px;
}
svg.s32 {
width: 32px;
height: 32px;
......@@ -1499,12 +1487,6 @@ svg.s16 {
height: 16px;
margin-right: 8px;
}
.avatar.s18,
.avatar-container.s18 {
width: 18px;
height: 18px;
margin-right: 8px;
}
.avatar.s32,
.avatar-container.s32 {
width: 32px;
......@@ -1583,9 +1565,6 @@ svg.s16 {
.rect-avatar.s16 {
border-radius: 2px;
}
.rect-avatar.s18 {
border-radius: 2px;
}
.rect-avatar.s32,
.nav-sidebar-inner-scroll
> div.context-header
......
......@@ -317,9 +317,6 @@ h1 {
.d-none {
display: none !important;
}
.d-inline-block {
display: inline-block !important;
}
.d-block {
display: block !important;
}
......@@ -344,11 +341,6 @@ h1 {
display: block !important;
}
}
@media (min-width: 1200px) {
.d-xl-block {
display: block !important;
}
}
.sr-only {
position: absolute;
width: 1px;
......@@ -1388,10 +1380,6 @@ svg.s16 {
width: 16px;
height: 16px;
}
svg.s18 {
width: 18px;
height: 18px;
}
svg.s32 {
width: 32px;
height: 32px;
......@@ -1480,12 +1468,6 @@ svg.s16 {
height: 16px;
margin-right: 8px;
}
.avatar.s18,
.avatar-container.s18 {
width: 18px;
height: 18px;
margin-right: 8px;
}
.avatar.s32,
.avatar-container.s32 {
width: 32px;
......@@ -1564,9 +1546,6 @@ svg.s16 {
.rect-avatar.s16 {
border-radius: 2px;
}
.rect-avatar.s18 {
border-radius: 2px;
}
.rect-avatar.s32,
.nav-sidebar-inner-scroll
> div.context-header
......
......@@ -11,7 +11,6 @@ module EE
def build_view_model(builder:, project:, group:)
super
# These come from `ee/app/views/dashboard/_nav_link_list.html.haml`
if dashboard_nav_link?(:environments)
builder.add_primary_menu_item(
id: 'environments',
......@@ -42,7 +41,6 @@ module EE
)
end
# These come from `ee/app/views/layouts/nav/_geo_primary_node_url.html.haml`
if ::Gitlab::Geo.secondary? && ::Gitlab::Geo.primary_node_configured?
builder.add_secondary_menu_item(
id: 'geo',
......
- if any_dashboard_nav_link?([:environments, :operations, :security])
%button#js-dashboards-menu.btn-link{ type: 'button', data: { toggle: 'dropdown' }, 'aria-label': _('Dashboards'), 'aria-haspopup': true, 'aria-expanded': false }
= sprite_icon('dashboard', size: 18)
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu{ 'aria-labelledby': "js-dashboards-menu" }
.dropdown-bold-header
= _('Dashboards')
= render_if_exists 'dashboard/nav_link_list'
-# WARNING! This file is slated to be removed along with the `combined_menu`
-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
-# Please see [this MR][1] for more context.
-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
- if dashboard_nav_link?(:environments)
= link_to operations_environments_path, class: 'dropdown-item', data: { qa_selector: 'environment_link' } do
= _('Environments')
- if dashboard_nav_link?(:operations)
= link_to operations_path, class: 'dropdown-item', data: { qa_selector: 'operations_link' } do
= _('Operations')
- if dashboard_nav_link?(:security)
= link_to security_dashboard_path, class: 'dropdown-item', data: { qa_selector: 'security_link' } do
= _('Security')
-# WARNING! This file is slated to be removed along with the `combined_menu`
-# feature flag. The logic here will be migrated to an upcoming `top_nav_helper`.
-# Please see [this MR][1] for more context.
-# [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587
- if Gitlab::Geo.secondary? && Gitlab::Geo.primary_node_configured?
%li
= link_to Gitlab::Geo.primary_node.url, title: 'Go to primary node', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('location-dot', size: 18)
......@@ -2,52 +2,30 @@
require 'spec_helper'
RSpec.describe 'Operations dropdown navbar EE' do
RSpec.describe 'Operations dropdown navbar EE', :js do
include Spec::Support::Helpers::Features::TopNavSpecHelpers
let(:user) { create(:user) }
let(:project) { create(:project) }
shared_examples 'combined_menu: feature flag examples' do
before do
project.add_maintainer(user)
sign_in(user)
before do
project.add_maintainer(user)
sign_in(user)
stub_licensed_features(operations_dashboard: true)
stub_licensed_features(operations_dashboard: true)
visit project_issues_path(project)
end
it 'has an `Operations` link' do
open_top_nav
expect(page).to have_link('Operations', href: operations_path)
end
it 'has an `Environments` link' do
open_top_nav
expect(page).to have_link('Environments', href: operations_environments_path)
end
visit project_issues_path(project)
end
context 'with combined_menu feature flag on', :js do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
before do
stub_feature_flags(combined_menu: true)
end
it 'has an `Operations` link' do
open_top_nav
it_behaves_like 'combined_menu: feature flag examples'
expect(page).to have_link('Operations', href: operations_path)
end
context 'with combined_menu feature flag off' do
let(:needs_rewrite_for_combined_menu_flag_on) { false }
before do
stub_feature_flags(combined_menu: false)
end
it 'has an `Environments` link' do
open_top_nav
it_behaves_like 'combined_menu: feature flag examples'
expect(page).to have_link('Environments', href: operations_environments_path)
end
end
......@@ -1663,9 +1663,6 @@ msgstr ""
msgid "About GitLab"
msgstr ""
msgid "About GitLab CE"
msgstr ""
msgid "About auto deploy"
msgstr ""
......@@ -9222,9 +9219,6 @@ msgstr ""
msgid "Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to import."
msgstr ""
msgid "Create blank project"
msgstr ""
msgid "Create branch"
msgstr ""
......@@ -9252,9 +9246,6 @@ msgstr ""
msgid "Create from"
msgstr ""
msgid "Create from template"
msgstr ""
msgid "Create group"
msgstr ""
......@@ -9955,9 +9946,6 @@ msgstr ""
msgid "DashboardProjects|Trending"
msgstr ""
msgid "Dashboards"
msgstr ""
msgid "Dashboard|%{firstProject} and %{secondProject}"
msgstr ""
......@@ -16575,9 +16563,6 @@ msgstr ""
msgid "Import from Jira"
msgstr ""
msgid "Import group"
msgstr ""
msgid "Import group from file"
msgstr ""
......@@ -21339,9 +21324,6 @@ msgstr ""
msgid "Months"
msgstr ""
msgid "More"
msgstr ""
msgid "More Information"
msgstr ""
......
......@@ -62,7 +62,6 @@ module QA
module Main
autoload :Banner, 'qa/ee/page/main/banner'
autoload :Menu, 'qa/ee/page/main/menu'
end
module Registration
......
# frozen_string_literal: true
module QA
module EE
module Page
module Main
module Menu
extend QA::Page::PageConcern
def self.included(base)
super
base.view 'ee/app/views/dashboard/_nav_link_list.html.haml' do
element :environment_link
element :operations_link
element :security_link
end
end
end
end
end
end
end
......@@ -49,7 +49,6 @@ const createMainOutput = ({ outFile, cssKeys, type }) => ({
outFile,
htmlPaths: [
path.join(FIXTURES_ROOT, `startup_css/project-${type}.html`),
path.join(FIXTURES_ROOT, `startup_css/project-${type}-legacy-menu.html`),
path.join(FIXTURES_ROOT, `startup_css/project-${type}-legacy-sidebar.html`),
path.join(FIXTURES_ROOT, `startup_css/project-${type}-signed-out.html`),
],
......
......@@ -9,69 +9,47 @@ RSpec.describe 'Admin Mode Logout', :js do
let(:user) { create(:admin) }
shared_examples 'combined_menu: feature flag examples' do
before do
# TODO: This used to use gitlab_sign_in, instead of sign_in, but that is buggy. See
# this issue to look into why: https://gitlab.com/gitlab-org/gitlab/-/issues/331851
sign_in(user)
gitlab_enable_admin_mode_sign_in(user)
visit admin_root_path
end
before do
# TODO: This used to use gitlab_sign_in, instead of sign_in, but that is buggy. See
# this issue to look into why: https://gitlab.com/gitlab-org/gitlab/-/issues/331851
sign_in(user)
gitlab_enable_admin_mode_sign_in(user)
visit admin_root_path
end
it 'disable removes admin mode and redirects to root page' do
gitlab_disable_admin_mode
it 'disable removes admin mode and redirects to root page' do
gitlab_disable_admin_mode
expect(current_path).to eq root_path
expect(current_path).to eq root_path
open_top_nav
open_top_nav
within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
end
it 'disable shows flash notice' do
gitlab_disable_admin_mode
expect(page).to have_selector('.flash-notice')
within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
end
context 'on a read-only instance' do
before do
allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
it 'disable removes admin mode and redirects to root page' do
gitlab_disable_admin_mode
expect(current_path).to eq root_path
open_top_nav
it 'disable shows flash notice' do
gitlab_disable_admin_mode
within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
end
end
expect(page).to have_selector('.flash-notice')
end
context 'with combined_menu feature flag on' do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
context 'on a read-only instance' do
before do
stub_feature_flags(combined_menu: true)
allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
it_behaves_like 'combined_menu: feature flag examples'
end
it 'disable removes admin mode and redirects to root page' do
gitlab_disable_admin_mode
context 'with combined_menu feature flag off' do
let(:needs_rewrite_for_combined_menu_flag_on) { false }
expect(current_path).to eq root_path
before do
stub_feature_flags(combined_menu: false)
end
open_top_nav
it_behaves_like 'combined_menu: feature flag examples'
within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
end
end
end
......@@ -2,48 +2,62 @@
require 'spec_helper'
RSpec.describe 'Admin mode' do
RSpec.describe 'Admin mode', :js do
include MobileHelpers
include Spec::Support::Helpers::Features::TopNavSpecHelpers
include StubENV
let(:admin) { create(:admin) }
shared_examples 'combined_menu: feature flag examples' do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
end
context 'application setting :admin_mode is enabled', :request_store do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
end
context 'application setting :admin_mode is enabled', :request_store do
before do
sign_in(admin)
context 'when not in admin mode' do
it 'has no leave admin mode button' do
visit new_admin_session_path
open_top_nav
page.within('.navbar-sub-nav') do
expect(page).not_to have_link(href: destroy_admin_session_path)
end
end
context 'when not in admin mode' do
it 'has no leave admin mode button' do
visit new_admin_session_path
open_top_nav
it 'can open pages not in admin scope' do
visit new_admin_session_path
open_top_nav_projects
page.within('.navbar-sub-nav') do
expect(page).not_to have_link(href: destroy_admin_session_path)
end
within_top_nav do
click_link('Your projects')
end
it 'can open pages not in admin scope' do
visit new_admin_session_path
open_top_nav_projects
expect(page).to have_current_path(dashboard_projects_path)
end
within_top_nav do
click_link('Your projects')
end
it 'is necessary to provide credentials again before opening pages in admin scope' do
visit general_admin_application_settings_path # admin logged out because not in admin_mode
expect(page).to have_current_path(dashboard_projects_path)
end
expect(page).to have_current_path(new_admin_session_path)
end
it 'can enter admin mode' do
visit new_admin_session_path
it 'is necessary to provide credentials again before opening pages in admin scope' do
visit general_admin_application_settings_path # admin logged out because not in admin_mode
fill_in 'user_password', with: admin.password
expect(page).to have_current_path(new_admin_session_path)
click_button 'Enter Admin Mode'
expect(page).to have_current_path(admin_root_path)
end
context 'on a read-only instance' do
before do
allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
it 'can enter admin mode' do
......@@ -55,151 +69,82 @@ RSpec.describe 'Admin mode' do
expect(page).to have_current_path(admin_root_path)
end
end
end
context 'on a read-only instance' do
before do
allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
it 'can enter admin mode' do
visit new_admin_session_path
fill_in 'user_password', with: admin.password
context 'when in admin_mode' do
before do
gitlab_enable_admin_mode_sign_in(admin)
end
click_button 'Enter Admin Mode'
it 'contains link to leave admin mode' do
open_top_nav
expect(page).to have_current_path(admin_root_path)
end
within_top_nav do
expect(page).to have_link(href: destroy_admin_session_path)
end
end
context 'when in admin_mode' do
before do
gitlab_enable_admin_mode_sign_in(admin)
end
it 'can leave admin mode using main dashboard link' do
gitlab_disable_admin_mode
it 'contains link to leave admin mode' do
open_top_nav
open_top_nav
within_top_nav do
expect(page).to have_link(href: destroy_admin_session_path)
end
within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
end
it 'can leave admin mode using main dashboard link', :js do
gitlab_disable_admin_mode
open_top_nav
it 'can open pages not in admin scope' do
open_top_nav_projects
within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
within_top_nav do
click_link('Your projects')
end
it 'can leave admin mode using dropdown menu on smaller screens', :js do
skip('pending responsive development under :combined_menu feature flag') if Feature.enabled?(:combined_menu, default_enabled: :yaml)
expect(page).to have_current_path(dashboard_projects_path)
end
resize_screen_xs
context 'nav bar' do
it 'shows admin dashboard links on bigger screen' do
visit root_dashboard_path
find('.header-more').click unless Feature.enabled?(:combined_menu, default_enabled: :yaml)
gitlab_disable_admin_mode
open_top_nav
find('.header-more').click unless Feature.enabled?(:combined_menu, default_enabled: :yaml)
expect(page).to have_link(href: new_admin_session_path)
expect(page).to have_link(text: 'Admin', href: admin_root_path, visible: true)
expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
end
end
it 'can open pages not in admin scope' do
open_top_nav_projects
within_top_nav do
click_link('Your projects')
end
expect(page).to have_current_path(dashboard_projects_path)
end
context 'nav bar' do
it 'shows admin dashboard links on bigger screen' do
visit root_dashboard_path
open_top_nav
link_text = Feature.enabled?(:combined_menu, default_enabled: :yaml) ? 'Admin' : 'Admin Area'
expect(page).to have_link(text: link_text, href: admin_root_path, visible: true)
expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
end
it 'relocates admin dashboard links to dropdown list on smaller screen', :js do
skip('pending responsive development under :combined_menu feature flag') if Feature.enabled?(:combined_menu, default_enabled: :yaml)
resize_screen_xs
visit root_dashboard_path
expect(page).not_to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
find('.header-more').click
page.within '.navbar' do
expect(page).to have_link(text: 'Admin Area', href: admin_root_path, visible: true)
expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
end
end
context 'on a read-only instance' do
before do
allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
context 'on a read-only instance' do
before do
allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
it 'can leave admin mode', :js do
gitlab_disable_admin_mode
it 'can leave admin mode' do
gitlab_disable_admin_mode
open_top_nav
open_top_nav
within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
end
end
end
context 'application setting :admin_mode is disabled' do
before do
stub_application_setting(admin_mode: false)
sign_in(admin)
end
it 'shows no admin mode buttons in navbar' do
visit admin_root_path
open_top_nav
expect(page).not_to have_link(href: new_admin_session_path)
expect(page).not_to have_link(href: destroy_admin_session_path)
end
end
end
context 'with combined_menu feature flag on', :js do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
context 'application setting :admin_mode is disabled' do
before do
stub_feature_flags(combined_menu: true)
stub_application_setting(admin_mode: false)
sign_in(admin)
end
it_behaves_like 'combined_menu: feature flag examples'
end
context 'with combined_menu feature flag off' do
let(:needs_rewrite_for_combined_menu_flag_on) { false }
it 'shows no admin mode buttons in navbar' do
visit admin_root_path
open_top_nav
before do
stub_feature_flags(combined_menu: false)
expect(page).not_to have_link(href: new_admin_session_path)
expect(page).not_to have_link(href: destroy_admin_session_path)
end
it_behaves_like 'combined_menu: feature flag examples'
end
end
# frozen_string_literal: true
require 'spec_helper'
# TODO: This entire spec file can be deleted once the combined_menu feature is fully rolled
# out and the flag is removed, because it will then be irrelevant (there will be no more tabs).
# Feature flag removal issue: https://gitlab.com/gitlab-org/gitlab/-/issues/324086
RSpec.describe 'Dashboard Active Tab', :js do
shared_examples 'combined_menu: feature flag examples' do
before do
sign_in(create(:user))
end
shared_examples 'page has active tab' do |title|
it "#{title} tab" do
subject
expect(page).to have_selector('.navbar-sub-nav li.active', count: 1)
expect(find('.navbar-sub-nav li.active')).to have_content(title)
end
end
context 'on dashboard projects' do
it_behaves_like 'page has active tab', 'Projects' do
subject { visit dashboard_projects_path }
end
end
context 'on dashboard groups' do
it_behaves_like 'page has active tab', 'Groups' do
subject { visit dashboard_groups_path }
end
end
end
context 'with combined_menu feature flag off' do
before do
stub_feature_flags(combined_menu: false)
end
it_behaves_like 'combined_menu: feature flag examples'
end
end
......@@ -2,66 +2,44 @@
require 'spec_helper'
RSpec.describe 'The group dashboard' do
RSpec.describe 'The group dashboard', :js do
include ExternalAuthorizationServiceHelpers
include Spec::Support::Helpers::Features::TopNavSpecHelpers
let(:user) { create(:user) }
shared_examples 'combined_menu: feature flag examples' do
before do
sign_in user
end
describe 'The top navigation' do
it 'has all the expected links' do
visit dashboard_groups_path
open_top_nav
within_top_nav do
expect(page).to have_button('Projects')
expect(page).to have_button('Groups')
expect(page).to have_link('Activity')
expect(page).to have_link('Milestones')
expect(page).to have_link('Snippets')
end
end
before do
sign_in user
end
it 'hides some links when an external authorization service is enabled' do
enable_external_authorization_service_check
visit dashboard_groups_path
describe 'The top navigation' do
it 'has all the expected links' do
visit dashboard_groups_path
open_top_nav
open_top_nav
within_top_nav do
expect(page).to have_button('Projects')
expect(page).to have_button('Groups')
expect(page).not_to have_link('Activity')
expect(page).not_to have_link('Milestones')
expect(page).to have_link('Snippets')
end
within_top_nav do
expect(page).to have_button('Projects')
expect(page).to have_button('Groups')
expect(page).to have_link('Activity')
expect(page).to have_link('Milestones')
expect(page).to have_link('Snippets')
end
end
end
context 'with combined_menu feature flag on', :js do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
it 'hides some links when an external authorization service is enabled' do
enable_external_authorization_service_check
visit dashboard_groups_path
before do
stub_feature_flags(combined_menu: true)
end
it_behaves_like 'combined_menu: feature flag examples'
end
open_top_nav
context 'with combined_menu feature flag off' do
let(:needs_rewrite_for_combined_menu_flag_on) { false }
before do
stub_feature_flags(combined_menu: false)
within_top_nav do
expect(page).to have_button('Projects')
expect(page).to have_button('Groups')
expect(page).not_to have_link('Activity')
expect(page).not_to have_link('Milestones')
expect(page).to have_link('Snippets')
end
end
it_behaves_like 'combined_menu: feature flag examples'
end
end
......@@ -3,89 +3,71 @@
require 'spec_helper'
RSpec.describe 'Dashboard shortcuts', :js do
shared_examples 'combined_menu: feature flag examples' do
context 'logged in' do
let(:user) { create(:user) }
let(:project) { create(:project) }
context 'logged in' do
let(:user) { create(:user) }
let(:project) { create(:project) }
before do
project.add_developer(user)
sign_in(user)
visit root_dashboard_path
end
before do
project.add_developer(user)
sign_in(user)
visit root_dashboard_path
end
it 'navigate to tabs' do
find('body').send_keys([:shift, 'I'])
it 'navigate to tabs' do
find('body').send_keys([:shift, 'I'])
check_page_title('Issues')
check_page_title('Issues')
find('body').send_keys([:shift, 'M'])
find('body').send_keys([:shift, 'M'])
check_page_title('Merge requests')
check_page_title('Merge requests')
find('body').send_keys([:shift, 'T'])
find('body').send_keys([:shift, 'T'])
check_page_title('To-Do List')
check_page_title('To-Do List')
find('body').send_keys([:shift, 'G'])
find('body').send_keys([:shift, 'G'])
check_page_title('Groups')
check_page_title('Groups')
find('body').send_keys([:shift, 'P'])
find('body').send_keys([:shift, 'P'])
check_page_title('Projects')
check_page_title('Projects')
find('body').send_keys([:shift, 'A'])
find('body').send_keys([:shift, 'A'])
check_page_title('Activity')
check_page_title('Activity')
find('body').send_keys([:shift, 'L'])
find('body').send_keys([:shift, 'L'])
check_page_title('Milestones')
end
check_page_title('Milestones')
end
end
context 'logged out' do
before do
visit explore_root_path
end
it 'navigate to tabs' do
find('body').send_keys([:shift, 'G'])
context 'logged out' do
before do
visit explore_root_path
end
find('.nothing-here-block')
expect(page).to have_content('No public groups')
it 'navigate to tabs' do
find('body').send_keys([:shift, 'G'])
find('body').send_keys([:shift, 'S'])
find('.nothing-here-block')
expect(page).to have_content('No public groups')
find('.nothing-here-block')
expect(page).to have_content('No snippets found')
find('body').send_keys([:shift, 'S'])
find('body').send_keys([:shift, 'P'])
find('.nothing-here-block')
expect(page).to have_content('No snippets found')
find('.nothing-here-block')
expect(page).to have_content('Explore public groups to find projects to contribute to.')
end
end
find('body').send_keys([:shift, 'P'])
def check_page_title(title)
expect(find('.page-title')).to have_content(title)
find('.nothing-here-block')
expect(page).to have_content('Explore public groups to find projects to contribute to.')
end
end
context 'with combined_menu feature flag on' do
before do
stub_feature_flags(combined_menu: true)
end
it_behaves_like 'combined_menu: feature flag examples'
end
context 'with combined_menu feature flag off' do
before do
stub_feature_flags(combined_menu: false)
end
it_behaves_like 'combined_menu: feature flag examples'
def check_page_title(title)
expect(find('.page-title')).to have_content(title)
end
end
......@@ -7,67 +7,45 @@ RSpec.describe 'Frequently visited items', :js do
let_it_be(:user) { create(:user) }
shared_examples 'combined_menu: feature flag examples' do
before do
sign_in(user)
end
context 'for projects' do
let_it_be(:project) { create(:project, :public) }
before do
sign_in(user)
end
it 'increments localStorage counter when visiting the project' do
visit project_path(project)
open_top_nav_projects
context 'for projects' do
let_it_be(:project) { create(:project, :public) }
frequent_projects = nil
it 'increments localStorage counter when visiting the project' do
visit project_path(project)
open_top_nav_projects
wait_for('localStorage frequent-projects') do
frequent_projects = page.evaluate_script("localStorage['#{user.username}/frequent-projects']")
frequent_projects = nil
frequent_projects.present?
end
wait_for('localStorage frequent-projects') do
frequent_projects = page.evaluate_script("localStorage['#{user.username}/frequent-projects']")
expect(Gitlab::Json.parse(frequent_projects)).to contain_exactly(a_hash_including('id' => project.id, 'frequency' => 1))
frequent_projects.present?
end
end
context 'for groups' do
let_it_be(:group) { create(:group, :public) }
it 'increments localStorage counter when visiting the group' do
visit group_path(group)
open_top_nav_groups
frequent_groups = nil
wait_for('localStorage frequent-groups') do
frequent_groups = page.evaluate_script("localStorage['#{user.username}/frequent-groups']")
frequent_groups.present?
end
expect(Gitlab::Json.parse(frequent_groups)).to contain_exactly(a_hash_including('id' => group.id, 'frequency' => 1))
end
expect(Gitlab::Json.parse(frequent_projects)).to contain_exactly(a_hash_including('id' => project.id, 'frequency' => 1))
end
end
context 'with combined_menu feature flag on' do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
context 'for groups' do
let_it_be(:group) { create(:group, :public) }
before do
stub_feature_flags(combined_menu: true)
end
it 'increments localStorage counter when visiting the group' do
visit group_path(group)
open_top_nav_groups
it_behaves_like 'combined_menu: feature flag examples'
end
frequent_groups = nil
context 'with combined_menu feature flag off' do
let(:needs_rewrite_for_combined_menu_flag_on) { false }
wait_for('localStorage frequent-groups') do
frequent_groups = page.evaluate_script("localStorage['#{user.username}/frequent-groups']")
before do
stub_feature_flags(combined_menu: false)
end
frequent_groups.present?
end
it_behaves_like 'combined_menu: feature flag examples'
expect(Gitlab::Json.parse(frequent_groups)).to contain_exactly(a_hash_including('id' => group.id, 'frequency' => 1))
end
end
end
......@@ -8,8 +8,6 @@ RSpec.describe 'top nav responsive', :js do
let_it_be(:user) { create(:user) }
before do
stub_feature_flags(combined_menu: true)
sign_in(user)
visit explore_projects_path
......
......@@ -6,374 +6,352 @@ RSpec.describe 'New project', :js do
include Select2Helper
include Spec::Support::Helpers::Features::TopNavSpecHelpers
shared_examples 'combined_menu: feature flag examples' do
context 'as a user' do
let(:user) { create(:user) }
context 'as a user' do
let(:user) { create(:user) }
before do
sign_in(user)
end
before do
sign_in(user)
end
it 'shows a message if multiple levels are restricted' do
Gitlab::CurrentSettings.update!(
restricted_visibility_levels: [Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL]
)
it 'shows a message if multiple levels are restricted' do
Gitlab::CurrentSettings.update!(
restricted_visibility_levels: [Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL]
)
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
expect(page).to have_content 'Other visibility settings have been disabled by the administrator.'
end
expect(page).to have_content 'Other visibility settings have been disabled by the administrator.'
end
it 'shows a message if all levels are restricted' do
Gitlab::CurrentSettings.update!(
restricted_visibility_levels: Gitlab::VisibilityLevel.values
)
it 'shows a message if all levels are restricted' do
Gitlab::CurrentSettings.update!(
restricted_visibility_levels: Gitlab::VisibilityLevel.values
)
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
expect(page).to have_content 'Visibility settings have been disabled by the administrator.'
end
expect(page).to have_content 'Visibility settings have been disabled by the administrator.'
end
end
context 'as an admin' do
let(:user) { create(:admin) }
context 'as an admin' do
let(:user) { create(:admin) }
before do
sign_in(user)
end
before do
sign_in(user)
end
it 'shows "New project" page', :js do
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
it 'shows "New project" page', :js do
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
expect(page).to have_content('Project name')
expect(page).to have_content('Project URL')
expect(page).to have_content('Project slug')
expect(page).to have_content('Project name')
expect(page).to have_content('Project URL')
expect(page).to have_content('Project slug')
click_link('New project')
find('[data-qa-panel-name="import_project"]').click
expect(page).to have_link('GitHub')
expect(page).to have_link('Bitbucket')
expect(page).to have_link('GitLab.com')
expect(page).to have_button('Repo by URL')
expect(page).to have_link('GitLab export')
end
describe 'manifest import option' do
before do
visit new_project_path
click_link('New project')
find('[data-qa-panel-name="import_project"]').click
end
expect(page).to have_link('GitHub')
expect(page).to have_link('Bitbucket')
expect(page).to have_link('GitLab.com')
expect(page).to have_button('Repo by URL')
expect(page).to have_link('GitLab export')
it 'has Manifest file' do
expect(page).to have_link('Manifest file')
end
end
describe 'manifest import option' do
before do
visit new_project_path
context 'Visibility level selector', :js do
Gitlab::VisibilityLevel.options.each do |key, level|
it "sets selector to #{key}" do
stub_application_setting(default_project_visibility: level)
find('[data-qa-panel-name="import_project"]').click
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{level}")).to be_checked
end
end
it 'has Manifest file' do
expect(page).to have_link('Manifest file')
it "saves visibility level #{level} on validation error" do
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
choose(key)
click_button('Create project')
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{level}")).to be_checked
end
end
end
context 'Visibility level selector', :js do
Gitlab::VisibilityLevel.options.each do |key, level|
it "sets selector to #{key}" do
stub_application_setting(default_project_visibility: level)
context 'when group visibility is private but default is internal' do
let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{level}")).to be_checked
end
end
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
it "saves visibility level #{level} on validation error" do
visit new_project_path
context 'when admin mode is enabled', :enable_admin_mode do
it 'has private selected' do
visit new_project_path(namespace_id: group.id)
find('[data-qa-panel-name="blank_project"]').click
choose(key)
click_button('Create project')
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{level}")).to be_checked
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
context 'when group visibility is private but default is internal' do
let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
context 'when admin mode is disabled' do
it 'is not allowed' do
visit new_project_path(namespace_id: group.id)
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
expect(page).to have_content('Not Found')
end
end
end
context 'when admin mode is enabled', :enable_admin_mode do
it 'has private selected' do
visit new_project_path(namespace_id: group.id)
find('[data-qa-panel-name="blank_project"]').click
context 'when group visibility is public but user requests private' do
let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
context 'when admin mode is disabled' do
it 'is not allowed' do
visit new_project_path(namespace_id: group.id)
context 'when admin mode is enabled', :enable_admin_mode do
it 'has private selected' do
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
find('[data-qa-panel-name="blank_project"]').click
expect(page).to have_content('Not Found')
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
context 'when group visibility is public but user requests private' do
let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
context 'when admin mode is disabled' do
it 'is not allowed' do
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
expect(page).to have_content('Not Found')
end
end
end
end
context 'when admin mode is enabled', :enable_admin_mode do
it 'has private selected' do
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
find('[data-qa-panel-name="blank_project"]').click
context 'Readme selector' do
it 'shows the initialize with Readme checkbox on "Blank project" tab' do
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
expect(page).to have_css('input#project_initialize_with_readme')
expect(page).to have_content('Initialize repository with a README')
end
context 'when admin mode is disabled' do
it 'is not allowed' do
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
it 'does not show the initialize with Readme checkbox on "Create from template" tab' do
visit new_project_path
find('[data-qa-panel-name="create_from_template"]').click
first('.choose-template').click
expect(page).to have_content('Not Found')
end
end
page.within '.project-fields-form' do
expect(page).not_to have_css('input#project_initialize_with_readme')
expect(page).not_to have_content('Initialize repository with a README')
end
end
context 'Readme selector' do
it 'shows the initialize with Readme checkbox on "Blank project" tab' do
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
it 'does not show the initialize with Readme checkbox on "Import project" tab' do
visit new_project_path
find('[data-qa-panel-name="import_project"]').click
first('.js-import-git-toggle-button').click
expect(page).to have_css('input#project_initialize_with_readme')
expect(page).to have_content('Initialize repository with a README')
page.within '#import-project-pane' do
expect(page).not_to have_css('input#project_initialize_with_readme')
expect(page).not_to have_content('Initialize repository with a README')
end
end
end
it 'does not show the initialize with Readme checkbox on "Create from template" tab' do
context 'Namespace selector' do
context 'with user namespace' do
before do
visit new_project_path
find('[data-qa-panel-name="create_from_template"]').click
first('.choose-template').click
page.within '.project-fields-form' do
expect(page).not_to have_css('input#project_initialize_with_readme')
expect(page).not_to have_content('Initialize repository with a README')
end
find('[data-qa-panel-name="blank_project"]').click
end
it 'does not show the initialize with Readme checkbox on "Import project" tab' do
visit new_project_path
find('[data-qa-panel-name="import_project"]').click
first('.js-import-git-toggle-button').click
page.within '#import-project-pane' do
expect(page).not_to have_css('input#project_initialize_with_readme')
expect(page).not_to have_content('Initialize repository with a README')
it 'selects the user namespace' do
page.within('#blank-project-pane') do
expect(page).to have_select('project[namespace_id]', visible: false, selected: user.username)
end
end
end
context 'Namespace selector' do
context 'with user namespace' do
before do
visit new_project_path
find('[data-qa-panel-name="blank_project"]').click
end
context 'with group namespace' do
let(:group) { create(:group, :private) }
it 'selects the user namespace' do
page.within('#blank-project-pane') do
expect(page).to have_select('project[namespace_id]', visible: false, selected: user.username)
end
end
before do
group.add_owner(user)
visit new_project_path(namespace_id: group.id)
find('[data-qa-panel-name="blank_project"]').click
end
context 'with group namespace' do
let(:group) { create(:group, :private) }
before do
group.add_owner(user)
visit new_project_path(namespace_id: group.id)
find('[data-qa-panel-name="blank_project"]').click
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
expect(page).to have_select('project[namespace_id]', visible: false, selected: group.name)
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
expect(page).to have_select('project[namespace_id]', visible: false, selected: group.name)
end
end
end
context 'with subgroup namespace' do
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
context 'with subgroup namespace' do
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
before do
group.add_maintainer(user)
visit new_project_path(namespace_id: subgroup.id)
find('[data-qa-panel-name="blank_project"]').click
end
before do
group.add_maintainer(user)
visit new_project_path(namespace_id: subgroup.id)
find('[data-qa-panel-name="blank_project"]').click
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
expect(page).to have_select('project[namespace_id]', visible: false, selected: subgroup.full_path)
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
expect(page).to have_select('project[namespace_id]', visible: false, selected: subgroup.full_path)
end
end
end
context 'when changing namespaces dynamically', :js do
let(:public_group) { create(:group, :public) }
let(:internal_group) { create(:group, :internal) }
let(:private_group) { create(:group, :private) }
context 'when changing namespaces dynamically', :js do
let(:public_group) { create(:group, :public) }
let(:internal_group) { create(:group, :internal) }
let(:private_group) { create(:group, :private) }
before do
public_group.add_owner(user)
internal_group.add_owner(user)
private_group.add_owner(user)
visit new_project_path(namespace_id: public_group.id)
find('[data-qa-panel-name="blank_project"]').click
end
before do
public_group.add_owner(user)
internal_group.add_owner(user)
private_group.add_owner(user)
visit new_project_path(namespace_id: public_group.id)
find('[data-qa-panel-name="blank_project"]').click
end
it 'enables the correct visibility options' do
select2(user.namespace_id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
select2(public_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
select2(internal_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
select2(private_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
end
it 'enables the correct visibility options' do
select2(user.namespace_id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
select2(public_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
select2(internal_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
select2(private_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
end
end
end
context 'Import project options', :js do
context 'Import project options', :js do
before do
visit new_project_path
find('[data-qa-panel-name="import_project"]').click
end
context 'from git repository url, "Repo by URL"' do
before do
visit new_project_path
find('[data-qa-panel-name="import_project"]').click
first('.js-import-git-toggle-button').click
end
context 'from git repository url, "Repo by URL"' do
before do
first('.js-import-git-toggle-button').click
end
it 'does not autocomplete sensitive git repo URL' do
autocomplete = find('#project_import_url')['autocomplete']
it 'does not autocomplete sensitive git repo URL' do
autocomplete = find('#project_import_url')['autocomplete']
expect(autocomplete).to eq('off')
end
expect(autocomplete).to eq('off')
end
it 'shows import instructions' do
git_import_instructions = first('.js-toggle-content')
it 'shows import instructions' do
git_import_instructions = first('.js-toggle-content')
expect(git_import_instructions).to be_visible
expect(git_import_instructions).to have_content 'Git repository URL'
end
expect(git_import_instructions).to be_visible
expect(git_import_instructions).to have_content 'Git repository URL'
end
it 'reports error if repo URL does not end with .git' do
fill_in 'project_import_url', with: 'http://foo/bar'
# simulate blur event
find('body').click
it 'reports error if repo URL does not end with .git' do
fill_in 'project_import_url', with: 'http://foo/bar'
# simulate blur event
find('body').click
expect(page).to have_text('A repository URL usually ends in a .git suffix')
end
expect(page).to have_text('A repository URL usually ends in a .git suffix')
end
it 'keeps "Import project" tab open after form validation error' do
collision_project = create(:project, name: 'test-name-collision', namespace: user.namespace)
it 'keeps "Import project" tab open after form validation error' do
collision_project = create(:project, name: 'test-name-collision', namespace: user.namespace)
fill_in 'project_import_url', with: collision_project.http_url_to_repo
fill_in 'project_name', with: collision_project.name
fill_in 'project_import_url', with: collision_project.http_url_to_repo
fill_in 'project_name', with: collision_project.name
click_on 'Create project'
click_on 'Create project'
expect(page).to have_css('#import-project-pane.active')
expect(page).not_to have_css('.toggle-import-form.hide')
end
expect(page).to have_css('#import-project-pane.active')
expect(page).not_to have_css('.toggle-import-form.hide')
end
end
context 'from GitHub' do
before do
first('.js-import-github').click
end
it 'shows import instructions' do
expect(page).to have_content('Authenticate with GitHub')
expect(current_path).to eq new_import_github_path
end
context 'from GitHub' do
before do
first('.js-import-github').click
end
context 'from manifest file' do
before do
first('.import_manifest').click
end
it 'shows import instructions' do
expect(page).to have_content('Manifest file import')
expect(current_path).to eq new_import_manifest_path
end
it 'shows import instructions' do
expect(page).to have_content('Authenticate with GitHub')
expect(current_path).to eq new_import_github_path
end
end
context 'Namespace selector' do
context 'with group with DEVELOPER_MAINTAINER_PROJECT_ACCESS project_creation_level' do
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
before do
group.add_developer(user)
visit new_project_path(namespace_id: group.id)
find('[data-qa-panel-name="blank_project"]').click
end
context 'from manifest file' do
before do
first('.import_manifest').click
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
expect(page).to have_select('project[namespace_id]', visible: false, selected: group.full_path)
end
end
it 'shows import instructions' do
expect(page).to have_content('Manifest file import')
expect(current_path).to eq new_import_manifest_path
end
end
end
end
context 'with combined_menu feature flag on' do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
context 'Namespace selector' do
context 'with group with DEVELOPER_MAINTAINER_PROJECT_ACCESS project_creation_level' do
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
before do
stub_feature_flags(combined_menu: true)
end
it_behaves_like 'combined_menu: feature flag examples'
end
context 'with combined_menu feature flag off' do
let(:needs_rewrite_for_combined_menu_flag_on) { false }
before do
group.add_developer(user)
visit new_project_path(namespace_id: group.id)
find('[data-qa-panel-name="blank_project"]').click
end
before do
stub_feature_flags(combined_menu: false)
it 'selects the group namespace' do
page.within('#blank-project-pane') do
expect(page).to have_select('project[namespace_id]', visible: false, selected: group.full_path)
end
end
end
end
it_behaves_like 'combined_menu: feature flag examples'
end
end
......@@ -10,7 +10,6 @@ RSpec.describe 'Startup CSS fixtures', type: :controller do
render_views
before(:all) do
stub_feature_flags(combined_menu: true)
stub_feature_flags(sidebar_refactor: true)
clean_frontend_fixtures('startup_css/')
end
......@@ -23,17 +22,6 @@ RSpec.describe 'Startup CSS fixtures', type: :controller do
sign_in(user)
end
it "startup_css/project-#{type}-legacy-menu.html" do
stub_feature_flags(combined_menu: false)
get :show, params: {
namespace_id: project.namespace.to_param,
id: project
}
expect(response).to be_successful
end
it "startup_css/project-#{type}.html" do
get :show, params: {
namespace_id: project.namespace.to_param,
......
......@@ -8,38 +8,24 @@ module Spec
module Features
module TopNavSpecHelpers
def open_top_nav
return unless Feature.enabled?(:combined_menu, default_enabled: :yaml)
find('.js-top-nav-dropdown-toggle').click
end
def within_top_nav
if Feature.enabled?(:combined_menu, default_enabled: :yaml)
within('.js-top-nav-dropdown-menu') do
yield
end
else
within('.navbar-sub-nav') do
yield
end
within('.js-top-nav-dropdown-menu') do
yield
end
end
def open_top_nav_projects
if Feature.enabled?(:combined_menu, default_enabled: :yaml)
open_top_nav
open_top_nav
within_top_nav do
click_button('Projects')
end
else
find('#nav-projects-dropdown').click
within_top_nav do
click_button('Projects')
end
end
def open_top_nav_groups
return unless Feature.enabled?(:combined_menu, default_enabled: :yaml)
open_top_nav
within_top_nav do
......
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