Move Labels menu item to project information menu

In this commit we move the menu item "Labels" from the Issues
menu and its own menu when the issues are disabled, to the
project information menu.

That way, we'll show always the labels menu no matter the status
of the issues feature.
parent 6330a060
...@@ -7,86 +7,90 @@ RSpec.describe 'Project navbar' do ...@@ -7,86 +7,90 @@ RSpec.describe 'Project navbar' do
include_context 'project navbar structure' include_context 'project navbar structure'
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) } let_it_be(:project) { create(:project, :repository) }
before do let(:user) { project.owner }
stub_feature_flags(sidebar_refactor: false)
insert_package_nav(_('Operations'))
insert_infrastructure_registry_nav
stub_config(registry: { enabled: false })
project.add_maintainer(user) before do
sign_in(user) sign_in(user)
end end
context 'when issue analytics is available' do context 'when sidebar refactor feature flag is disabled' do
before do before do
stub_licensed_features(issues_analytics: true) stub_feature_flags(sidebar_refactor: false)
insert_package_nav(_('Operations'))
insert_infrastructure_registry_nav
stub_config(registry: { enabled: false })
insert_after_sub_nav_item( insert_after_sub_nav_item(
_('Code Review'), _('Boards'),
within: _('Analytics'), within: _('Issues'),
new_sub_nav_item_name: _('Issue') new_sub_nav_item_name: _('Labels')
) )
visit project_path(project)
end end
it_behaves_like 'verified navigation bar' context 'when issue analytics is available' do
end before do
stub_licensed_features(issues_analytics: true)
context 'when security dashboard is available' do insert_after_sub_nav_item(
let(:security_and_compliance_nav_item) do _('Code Review'),
{ within: _('Analytics'),
nav_item: _('Security & Compliance'), new_sub_nav_item_name: _('Issue')
nav_sub_items: [ )
_('Security Dashboard'),
_('Vulnerability Report'),
s_('OnDemandScans|On-demand Scans'),
_('Configuration'),
_('Audit Events')
]
}
end
before do visit project_path(project)
stub_licensed_features(security_dashboard: true, security_on_demand_scans: true) end
visit project_path(project) it_behaves_like 'verified navigation bar'
end end
it_behaves_like 'verified navigation bar' context 'when security dashboard is available' do
end let(:security_and_compliance_nav_item) do
{
nav_item: _('Security & Compliance'),
nav_sub_items: [
_('Security Dashboard'),
_('Vulnerability Report'),
s_('OnDemandScans|On-demand Scans'),
_('Configuration'),
_('Audit Events')
]
}
end
context 'when packages are available' do before do
before do stub_licensed_features(security_dashboard: true, security_on_demand_scans: true)
stub_config(packages: { enabled: true }, registry: { enabled: false })
stub_feature_flags(sidebar_refactor: false)
visit project_path(project) visit project_path(project)
end
it_behaves_like 'verified navigation bar'
end end
context 'when container registry is available' do context 'when packages are available' do
before do before do
stub_config(registry: { enabled: true }) stub_config(packages: { enabled: true }, registry: { enabled: false })
insert_container_nav
visit project_path(project) visit project_path(project)
end end
it_behaves_like 'verified navigation bar' context 'when container registry is available' do
end before do
end stub_config(registry: { enabled: true })
context 'when requirements is available' do insert_container_nav
before do
stub_licensed_features(requirements: true) visit project_path(project)
end
it_behaves_like 'verified navigation bar'
end
end end
context 'with flag disabled' do context 'when requirements is available' do
before do before do
stub_licensed_features(requirements: true)
insert_after_nav_item( insert_after_nav_item(
_('Merge requests'), _('Merge requests'),
new_nav_item: { new_nav_item: {
...@@ -100,34 +104,59 @@ RSpec.describe 'Project navbar' do ...@@ -100,34 +104,59 @@ RSpec.describe 'Project navbar' do
it_behaves_like 'verified navigation bar' it_behaves_like 'verified navigation bar'
end end
end
context 'when sidebar refactor feature flag is enabled' do
let(:operations_menu_items) do
[
_('Metrics'),
_('Logs'),
_('Tracing'),
_('Error Tracking'),
_('Alerts'),
_('Incidents'),
_('Environments'),
_('Feature Flags'),
_('Product Analytics')
]
end
context 'with flag enabled' do let(:project_information_nav_item) do
let(:operations_menu_items) do {
[ nav_item: _('Project information'),
_('Metrics'), nav_sub_items: [
_('Logs'), _('Activity'),
_('Tracing'), _('Releases'),
_('Error Tracking'), _('Labels')
_('Alerts'),
_('Incidents'),
_('Environments'),
_('Feature Flags'),
_('Product Analytics')
] ]
end }
end
let(:project_information_nav_item) do before do
{ stub_feature_flags(sidebar_refactor: true)
nav_item: _('Project information'), insert_package_nav(_('Operations'))
insert_infrastructure_registry_nav
insert_after_nav_item(
_('Operations'),
new_nav_item: {
nav_item: _('Infrastructure'),
nav_sub_items: [ nav_sub_items: [
_('Activity'), _('Kubernetes clusters'),
_('Releases') _('Serverless platform'),
_('Terraform')
] ]
} }
end )
visit project_path(project)
end
it_behaves_like 'verified navigation bar'
context 'when requirements is available' do
before do before do
stub_feature_flags(sidebar_refactor: true) stub_licensed_features(requirements: true)
insert_after_nav_item( insert_after_nav_item(
_('Merge requests'), _('Merge requests'),
...@@ -137,18 +166,6 @@ RSpec.describe 'Project navbar' do ...@@ -137,18 +166,6 @@ RSpec.describe 'Project navbar' do
} }
) )
insert_after_nav_item(
_('Operations'),
new_nav_item: {
nav_item: _('Infrastructure'),
nav_sub_items: [
_('Kubernetes clusters'),
_('Serverless platform'),
_('Terraform')
]
}
)
visit project_path(project) visit project_path(project)
end end
......
...@@ -98,6 +98,10 @@ module Sidebars ...@@ -98,6 +98,10 @@ module Sidebars
end end
def labels_menu_item def labels_menu_item
if Feature.enabled?(:sidebar_refactor, context.current_user)
return ::Sidebars::NilMenuItem.new(item_id: :labels)
end
::Sidebars::MenuItem.new( ::Sidebars::MenuItem.new(
title: _('Labels'), title: _('Labels'),
link: project_labels_path(context.project), link: project_labels_path(context.project),
......
...@@ -40,6 +40,8 @@ module Sidebars ...@@ -40,6 +40,8 @@ module Sidebars
override :render? override :render?
def render? def render?
return false if Feature.enabled?(:sidebar_refactor, context.current_user)
can?(context.current_user, :read_label, context.project) && !context.project.issues_enabled? can?(context.current_user, :read_label, context.project) && !context.project.issues_enabled?
end end
end end
......
...@@ -9,6 +9,7 @@ module Sidebars ...@@ -9,6 +9,7 @@ module Sidebars
add_item(details_menu_item) add_item(details_menu_item)
add_item(activity_menu_item) add_item(activity_menu_item)
add_item(releases_menu_item) add_item(releases_menu_item)
add_item(labels_menu_item)
true true
end end
...@@ -95,6 +96,19 @@ module Sidebars ...@@ -95,6 +96,19 @@ module Sidebars
container_html_options: { class: 'shortcuts-project-releases' } container_html_options: { class: 'shortcuts-project-releases' }
) )
end end
def labels_menu_item
if Feature.disabled?(:sidebar_refactor, context.current_user)
return ::Sidebars::NilMenuItem.new(item_id: :labels)
end
::Sidebars::MenuItem.new(
title: _('Labels'),
link: project_labels_path(context.project),
active_routes: { controller: :labels },
item_id: :labels
)
end
end end
end end
end end
......
...@@ -69,20 +69,37 @@ RSpec.describe 'Project active tab' do ...@@ -69,20 +69,37 @@ RSpec.describe 'Project active tab' do
end end
context 'on project Issues' do context 'on project Issues' do
let(:feature_flag_value) { true }
before do before do
stub_feature_flags(sidebar_refactor: feature_flag_value)
visit project_issues_path(project) visit project_issues_path(project)
end end
it_behaves_like 'page has active tab', 'Issues' it_behaves_like 'page has active tab', 'Issues'
%w(Milestones Labels).each do |sub_menu| context "on project Issues/Milestones" do
context "on project Issues/#{sub_menu}" do before do
before do click_tab('Milestones')
click_tab(sub_menu) end
end
it_behaves_like 'page has active tab', 'Issues' it_behaves_like 'page has active tab', 'Issues'
it_behaves_like 'page has active sub tab', sub_menu it_behaves_like 'page has active sub tab', 'Milestones'
end
context 'when feature flag is disabled' do
let(:feature_flag_value) { false }
%w(Milestones Labels).each do |sub_menu|
context "on project Issues/#{sub_menu}" do
before do
click_tab(sub_menu)
end
it_behaves_like 'page has active tab', 'Issues'
it_behaves_like 'page has active sub tab', sub_menu
end
end end
end end
end end
......
...@@ -54,17 +54,30 @@ RSpec.describe 'Edit Project Settings' do ...@@ -54,17 +54,30 @@ RSpec.describe 'Edit Project Settings' do
end end
context 'When external issue tracker is enabled and issues disabled on project settings' do context 'When external issue tracker is enabled and issues disabled on project settings' do
it 'hides issues tab and show labels tab' do before do
project.issues_enabled = false project.issues_enabled = false
project.save! project.save!
allow_next_instance_of(Project) do |instance| allow_next_instance_of(Project) do |instance|
allow(instance).to receive(:external_issue_tracker).and_return(JiraService.new) allow(instance).to receive(:external_issue_tracker).and_return(JiraService.new)
end end
end
it 'hides issues tab' do
visit project_path(project) visit project_path(project)
expect(page).not_to have_selector('.shortcuts-issues') expect(page).not_to have_selector('.shortcuts-issues')
expect(page).to have_selector('.shortcuts-labels') expect(page).not_to have_selector('.shortcuts-labels')
end
context 'when feature flag :sidebar_refactor is disabled' do
it 'hides issues tab and show labels tab' do
stub_feature_flags(sidebar_refactor: false)
visit project_path(project)
expect(page).not_to have_selector('.shortcuts-issues')
expect(page).to have_selector('.shortcuts-labels')
end
end end
end end
......
...@@ -8,70 +8,81 @@ RSpec.describe 'Project navbar' do ...@@ -8,70 +8,81 @@ RSpec.describe 'Project navbar' do
include_context 'project navbar structure' include_context 'project navbar structure'
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) } let_it_be(:project) { create(:project, :repository) }
before do let(:user) { project.owner }
stub_feature_flags(sidebar_refactor: false)
insert_package_nav(_('Operations'))
insert_infrastructure_registry_nav
stub_config(registry: { enabled: false })
project.add_maintainer(user) before do
sign_in(user) sign_in(user)
end end
it_behaves_like 'verified navigation bar' do context 'when sidebar refactor feature flag is disabled' do
before do before do
visit project_path(project) stub_feature_flags(sidebar_refactor: false)
insert_package_nav(_('Operations'))
insert_infrastructure_registry_nav
insert_after_sub_nav_item(
_('Boards'),
within: _('Issues'),
new_sub_nav_item_name: _('Labels')
)
stub_config(registry: { enabled: false })
end end
end
context 'when value stream is available' do it_behaves_like 'verified navigation bar' do
before do before do
visit project_path(project) visit project_path(project)
end
end end
it 'redirects to value stream when Analytics item is clicked' do context 'when value stream is available' do
page.within('.sidebar-top-level-items') do before do
find('.shortcuts-analytics').click visit project_path(project)
end end
wait_for_requests it 'redirects to value stream when Analytics item is clicked' do
page.within('.sidebar-top-level-items') do
find('.shortcuts-analytics').click
end
wait_for_requests
expect(page).to have_current_path(project_cycle_analytics_path(project)) expect(page).to have_current_path(project_cycle_analytics_path(project))
end
end end
end
context 'when pages are available' do context 'when pages are available' do
before do before do
stub_config(pages: { enabled: true }) stub_config(pages: { enabled: true })
insert_after_sub_nav_item( insert_after_sub_nav_item(
_('Operations'), _('Operations'),
within: _('Settings'), within: _('Settings'),
new_sub_nav_item_name: _('Pages') new_sub_nav_item_name: _('Pages')
) )
visit project_path(project) visit project_path(project)
end
it_behaves_like 'verified navigation bar'
end end
it_behaves_like 'verified navigation bar' context 'when container registry is available' do
end before do
stub_config(registry: { enabled: true })
context 'when container registry is available' do insert_container_nav
before do
stub_config(registry: { enabled: true })
insert_container_nav visit project_path(project)
end
visit project_path(project) it_behaves_like 'verified navigation bar'
end end
it_behaves_like 'verified navigation bar'
end end
context 'when sidebar refactor feature flag is on' do context 'when sidebar refactor feature flag is enabled' do
let(:operations_menu_items) do let(:operations_menu_items) do
[ [
_('Metrics'), _('Metrics'),
...@@ -91,7 +102,8 @@ RSpec.describe 'Project navbar' do ...@@ -91,7 +102,8 @@ RSpec.describe 'Project navbar' do
nav_item: _('Project information'), nav_item: _('Project information'),
nav_sub_items: [ nav_sub_items: [
_('Activity'), _('Activity'),
_('Releases') _('Releases'),
_('Labels')
] ]
} }
end end
...@@ -99,7 +111,8 @@ RSpec.describe 'Project navbar' do ...@@ -99,7 +111,8 @@ RSpec.describe 'Project navbar' do
before do before do
stub_feature_flags(sidebar_refactor: true) stub_feature_flags(sidebar_refactor: true)
stub_config(registry: { enabled: true }) stub_config(registry: { enabled: true })
insert_package_nav(_('Operations'))
insert_infrastructure_registry_nav
insert_container_nav insert_container_nav
insert_after_sub_nav_item( insert_after_sub_nav_item(
......
...@@ -65,4 +65,22 @@ RSpec.describe Sidebars::Projects::Menus::IssuesMenu do ...@@ -65,4 +65,22 @@ RSpec.describe Sidebars::Projects::Menus::IssuesMenu do
end end
end end
end end
describe 'Menu Items' do
subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } }
describe 'Labels' do
let(:item_id) { :labels }
specify { is_expected.to be_nil }
context 'when feature flag :sidebar_refactor is disabled' do
before do
stub_feature_flags(sidebar_refactor: false)
end
specify { is_expected.not_to be_nil }
end
end
end
end end
...@@ -20,27 +20,41 @@ RSpec.describe Sidebars::Projects::Menus::LabelsMenu do ...@@ -20,27 +20,41 @@ RSpec.describe Sidebars::Projects::Menus::LabelsMenu do
allow(project).to receive(:issues_enabled?).and_return(issues_enabled) allow(project).to receive(:issues_enabled?).and_return(issues_enabled)
end end
context 'when user can read labels' do context 'when feature flag :sidebar_refactor is enabled' do
context 'when issues feature is enabled' do let(:issues_enabled) { false }
it 'returns false' do
expect(subject.render?).to be_falsey it 'returns false' do
end expect(subject.render?).to be_falsey
end end
end
context 'when issues feature is disabled' do context 'when feature flag :sidebar_refactor is disabled' do
let(:issues_enabled) { false } before do
stub_feature_flags(sidebar_refactor: false)
end
it 'returns true' do context 'when user can read labels' do
expect(subject.render?).to be_truthy context 'when issues feature is enabled' do
it 'returns false' do
expect(subject.render?).to be_falsey
end
end
context 'when issues feature is disabled' do
let(:issues_enabled) { false }
it 'returns true' do
expect(subject.render?).to be_truthy
end
end end
end end
end
context 'when user cannot read labels' do context 'when user cannot read labels' do
let(:user) { nil } let(:user) { nil }
it 'returns false' do it 'returns false' do
expect(subject.render?).to be_falsey expect(subject.render?).to be_falsey
end
end end
end end
end end
......
...@@ -8,30 +8,48 @@ RSpec.describe Sidebars::Projects::Menus::ProjectInformationMenu do ...@@ -8,30 +8,48 @@ RSpec.describe Sidebars::Projects::Menus::ProjectInformationMenu do
let(:user) { project.owner } let(:user) { project.owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) } let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
describe 'Releases' do describe 'Menu Items' do
subject { described_class.new(context).renderable_items.index { |e| e.item_id == :releases } } subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } }
context 'when project repository is empty' do describe 'Releases' do
it 'does not include releases menu item' do let(:item_id) { :releases }
allow(project).to receive(:empty_repo?).and_return(true)
is_expected.to be_nil context 'when project repository is empty' do
it 'does not include releases menu item' do
allow(project).to receive(:empty_repo?).and_return(true)
is_expected.to be_nil
end
end end
end
context 'when project repository is not empty' do context 'when project repository is not empty' do
context 'when user can download code' do context 'when user can download code' do
it 'includes releases menu item' do it 'includes releases menu item' do
is_expected.to be_present is_expected.to be_present
end
end
context 'when user cannot download code' do
let(:user) { nil }
it 'does not include releases menu item' do
is_expected.to be_nil
end
end end
end end
end
context 'when user cannot download code' do describe 'Labels' do
let(:user) { nil } let(:item_id) { :labels }
it 'does not include releases menu item' do specify { is_expected.not_to be_nil }
is_expected.to be_nil
context 'when feature flag :sidebar_refactor is disabled' do
before do
stub_feature_flags(sidebar_refactor: false)
end end
specify { is_expected.to be_nil }
end end
end end
end end
......
...@@ -73,7 +73,6 @@ RSpec.shared_context 'project navbar structure' do ...@@ -73,7 +73,6 @@ RSpec.shared_context 'project navbar structure' do
nav_sub_items: [ nav_sub_items: [
_('List'), _('List'),
_('Boards'), _('Boards'),
_('Labels'),
_('Service Desk'), _('Service Desk'),
_('Milestones'), _('Milestones'),
(_('Iterations') if Gitlab.ee?) (_('Iterations') if Gitlab.ee?)
......
...@@ -72,6 +72,27 @@ RSpec.describe 'layouts/nav/sidebar/_project' do ...@@ -72,6 +72,27 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
expect(rendered).to have_link('Releases', href: project_releases_path(project), class: 'shortcuts-project-releases') expect(rendered).to have_link('Releases', href: project_releases_path(project), class: 'shortcuts-project-releases')
end end
end end
describe 'Labels' do
let(:page) { Nokogiri::HTML.parse(rendered) }
it 'has a link to the labels path' do
render
expect(page.at_css('.shortcuts-project').parent.css('[aria-label="Labels"]')).not_to be_empty
expect(rendered).to have_link('Labels', href: project_labels_path(project))
end
context 'when feature flag :sidebar_refactor is disabled' do
it 'does not have the labels menu item' do
stub_feature_flags(sidebar_refactor: false)
render
expect(page.at_css('.shortcuts-project').parent.css('[aria-label="Labels"]')).to be_empty
end
end
end
end end
describe 'Learn GitLab' do describe 'Learn GitLab' do
...@@ -181,10 +202,23 @@ RSpec.describe 'layouts/nav/sidebar/_project' do ...@@ -181,10 +202,23 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end end
describe 'Labels' do describe 'Labels' do
it 'has a link to the labels path' do let(:page) { Nokogiri::HTML.parse(rendered) }
it 'does not have a link to the labels page' do
render render
expect(rendered).to have_link('Labels', href: project_labels_path(project)) expect(page.at_css('.shortcuts-issues').parent.css('[aria-label="Labels"]')).to be_empty
end
context 'when feature flag :sidebar_refactor is disabled' do
it 'has a link to the labels page' do
stub_feature_flags(sidebar_refactor: false)
render
expect(page.at_css('.shortcuts-issues').parent.css('[aria-label="Labels"]')).not_to be_empty
expect(rendered).to have_link('Labels', href: project_labels_path(project))
end
end end
end end
...@@ -248,21 +282,35 @@ RSpec.describe 'layouts/nav/sidebar/_project' do ...@@ -248,21 +282,35 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end end
describe 'Labels' do describe 'Labels' do
context 'when issues are not enabled' do it 'does not show the labels menu' do
it 'has a link to the labels path' do project.project_feature.update!(issues_access_level: ProjectFeature::DISABLED)
project.project_feature.update!(issues_access_level: ProjectFeature::DISABLED)
render render
expect(rendered).to have_link('Labels', href: project_labels_path(project), class: 'shortcuts-labels') expect(rendered).not_to have_link('Labels', href: project_labels_path(project), class: 'shortcuts-labels')
end
end end
context 'when issues are enabled' do context 'when feature flag :sidebar_refactor is disabled' do
it 'does not have a link to the labels path' do before do
render stub_feature_flags(sidebar_refactor: false)
end
context 'when issues are not enabled' do
it 'has a link to the labels path' do
project.project_feature.update!(issues_access_level: ProjectFeature::DISABLED)
expect(rendered).not_to have_link('Labels', href: project_labels_path(project), class: 'shortcuts-labels') render
expect(rendered).to have_link('Labels', href: project_labels_path(project), class: 'shortcuts-labels')
end
end
context 'when issues are enabled' do
it 'does not have a link to the labels path' do
render
expect(rendered).not_to have_link('Labels', href: project_labels_path(project), class: 'shortcuts-labels')
end
end end
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