Commit cb64643c authored by Peter Leitzen's avatar Peter Leitzen

Merge branch '195979-group-level-analytics-sidebar' into 'master'

Create an Analytics area in the navigation sidebar for groups

See merge request gitlab-org/gitlab!23402
parents 579b7c46 5f4c0e08
......@@ -20,6 +20,10 @@ module AnalyticsNavbarHelper
].compact
end
def group_analytics_navbar_links(group, current_user)
[]
end
private
def navbar_sub_item(args)
......
......@@ -7,7 +7,6 @@ module GroupsHelper
groups#details
groups#activity
groups#subgroups
analytics#show
]
end
......
- navbar_sub_item = project_analytics_navbar_links(@project, current_user).sort_by(&:title)
- all_paths = navbar_sub_item.map(&:path)
- navbar_links = links.sort_by(&:title)
- all_paths = navbar_links.map(&:path)
- if navbar_sub_item.any?
- if navbar_links.any?
= nav_link(path: all_paths) do
= link_to navbar_sub_item.first.link, data: { qa_selector: 'project_analytics_link' } do
= link_to navbar_links.first.link do
.nav-icon-container
= sprite_icon('chart')
%span.nav-item-name
= _('Analytics')
%ul.sidebar-sub-level-items
- navbar_sub_item.each do |menu_item|
- navbar_links.each do |menu_item|
= nav_link(path: menu_item.path) do
= link_to(menu_item.link, menu_item.link_to_options) do
%span= menu_item.title
- should_display_analytics_pages_in_sidebar = Feature.enabled?(:analytics_pages_under_group_analytics_sidebar, @group)
- issues_count = group_issues_count(state: 'opened')
- merge_requests_count = group_merge_requests_count(state: 'opened')
......@@ -11,7 +12,9 @@
= @group.name
%ul.sidebar-top-level-items.qa-group-sidebar
- if group_sidebar_link?(:overview)
= nav_link(path: group_overview_nav_link_paths, html_options: { class: 'home' }) do
- paths = group_overview_nav_link_paths
- paths << 'contribution_analytics#show' unless should_display_analytics_pages_in_sidebar
= nav_link(path: paths, unless: -> { should_display_analytics_pages_in_sidebar && current_path?('groups/contribution_analytics#show') }, html_options: { class: 'home' }) do
= link_to group_path(@group) do
.nav-icon-container
= sprite_icon('home')
......@@ -42,8 +45,9 @@
%span
= _('Activity')
- unless should_display_analytics_pages_in_sidebar
- if group_sidebar_link?(:contribution_analytics)
= nav_link(path: 'analytics#show') do
= nav_link(path: 'contribution_analytics#show') do
= link_to group_contribution_analytics_path(@group), title: _('Contribution Analytics'), data: { placement: 'right', qa_selector: 'contribution_analytics_link' } do
%span
= _('Contribution Analytics')
......@@ -53,7 +57,7 @@
= render_if_exists "layouts/nav/ee/epic_link", group: @group
- if group_sidebar_link?(:issues)
= nav_link(path: group_issues_sub_menu_items) do
= nav_link(path: group_issues_sub_menu_items, unless: -> { should_display_analytics_pages_in_sidebar && current_path?('issues_analytics#show') }) do
= link_to issues_group_path(@group), data: { qa_selector: 'group_issues_item' } do
.nav-icon-container
= sprite_icon('issues')
......@@ -80,6 +84,7 @@
%span
= boards_link_text
- unless should_display_analytics_pages_in_sidebar
= render_if_exists 'layouts/nav/issues_analytics_link'
- if group_sidebar_link?(:labels)
......@@ -126,6 +131,8 @@
= render_if_exists 'groups/sidebar/packages'
= render 'layouts/nav/sidebar/analytics_links', links: group_analytics_navbar_links(@group, current_user)
- if group_sidebar_link?(:group_members)
= nav_link(path: 'group_members#index') do
= link_to group_group_members_path(@group) do
......
......@@ -298,7 +298,7 @@
= render_if_exists 'layouts/nav/sidebar/project_packages_link'
= render 'layouts/nav/sidebar/project_analytics_link'
= render 'layouts/nav/sidebar/analytics_links', links: project_analytics_navbar_links(@project, current_user)
- if project_nav_tab? :wiki
- wiki_url = project_wiki_path(@project, :home)
......
......@@ -12,8 +12,52 @@ module EE
].compact
end
override :group_analytics_navbar_links
def group_analytics_navbar_links(group, current_user)
super + [
contribution_analytics_navbar_link(group, current_user),
group_insights_navbar_link(group, current_user),
issues_analytics_navbar_link(group, current_user)
].compact
end
private
def contribution_analytics_navbar_link(group, current_user)
return unless ::Feature.enabled?(:analytics_pages_under_group_analytics_sidebar, group)
return unless group_sidebar_link?(:contribution_analytics)
navbar_sub_item(
title: _('Contribution Analytics'),
path: 'groups/contribution_analytics#show',
link: group_contribution_analytics_path(group),
link_to_options: { data: { placement: 'right', qa_selector: 'contribution_analytics_link' } }
)
end
def group_insights_navbar_link(group, current_user)
return unless ::Feature.enabled?(:analytics_pages_under_group_analytics_sidebar, group)
return unless group_sidebar_link?(:group_insights)
navbar_sub_item(
title: _('Insights'),
path: 'groups/insights#show',
link: group_insights_path(group),
link_to_options: { class: 'shortcuts-group-insights', data: { qa_selector: 'group_insights_link' } }
)
end
def issues_analytics_navbar_link(group, current_user)
return unless ::Feature.enabled?(:analytics_pages_under_group_analytics_sidebar, group)
return unless group_sidebar_link?(:analytics)
navbar_sub_item(
title: _('Issues Analytics'),
path: 'issues_analytics#show',
link: group_issues_analytics_path(group)
)
end
def insights_navbar_link(project, current_user)
return unless ::Feature.enabled?(:analytics_pages_under_project_analytics_sidebar, project)
return unless project_nav_tab?(:project_insights)
......
......@@ -13,10 +13,14 @@ module EE
override :group_overview_nav_link_paths
def group_overview_nav_link_paths
if ::Feature.enabled?(:analytics_pages_under_group_analytics_sidebar, @group)
super
else
super + %w[
groups/insights#show
]
end
end
override :group_nav_link_paths
def group_nav_link_paths
......
# frozen_string_literal: true
require 'spec_helper'
describe 'Group active tab' do
let(:user) { create :user }
let(:group) { create(:group) }
before do
group.add_maintainer(user)
sign_in(user)
end
def click_tab(title)
page.within '.sidebar-top-level-items > .active' do
click_link(title)
end
end
context 'when `analytics_pages_under_group_analytics_sidebar` feature flag is off' do
before do
stub_feature_flags(analytics_pages_under_group_analytics_sidebar: { enabled: false, thing: group })
end
context 'on group Insights' do
before do
stub_licensed_features(insights: true)
visit group_insights_path(group)
end
it_behaves_like 'page has active tab', _('Group overview')
it_behaves_like 'page has active sub tab', _('Insights')
end
context 'on group Issue Analytics' do
before do
stub_licensed_features(issues_analytics: true)
visit group_issues_analytics_path(group)
end
it_behaves_like 'page has active tab', _('Issues')
it_behaves_like 'page has active sub tab', _('Analytics')
end
context 'on group Contribution Analytics' do
before do
visit group_contribution_analytics_path(group)
end
it_behaves_like 'page has active tab', _('Group overview')
it_behaves_like 'page has active sub tab', _('Contribution Analytics')
end
end
context 'when `analytics_pages_under_group_analytics_sidebar` feature flag is on' do
before do
stub_feature_flags(analytics_pages_under_group_analytics_sidebar: { enabled: true, thing: group })
end
context 'on group Insights' do
before do
stub_licensed_features(insights: true)
visit group_insights_path(group)
end
it_behaves_like 'page has active tab', _('Analytics')
it_behaves_like 'page has active sub tab', _('Insights')
end
context 'on group Issue Analytics' do
before do
stub_licensed_features(issues_analytics: true)
visit group_issues_analytics_path(group)
end
it_behaves_like 'page has active tab', _('Analytics')
it_behaves_like 'page has active sub tab', _('Issues Analytics')
end
context 'on group Contribution Analytics' do
before do
visit group_contribution_analytics_path(group)
end
it_behaves_like 'page has active tab', _('Analytics')
it_behaves_like 'page has active sub tab', _('Contribution Analytics')
end
end
end
......@@ -8,6 +8,8 @@ describe 'Groups > Contribution Analytics', :js do
let(:empty_project) { create(:project, namespace: group) }
before do
stub_feature_flags(analytics_pages_under_group_analytics_sidebar: { enabled: false, thing: group })
group.add_owner(user)
sign_in(user)
end
......
......@@ -10581,6 +10581,9 @@ msgstr ""
msgid "Issues / Merge Requests"
msgstr ""
msgid "Issues Analytics"
msgstr ""
msgid "Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable."
msgstr ""
......
......@@ -7,14 +7,22 @@ describe 'Group navbar' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:analytics_nav_item) do
{
nav_item: _('Analytics'),
nav_sub_items: [
_('Contribution Analytics')
]
}
end
let(:structure) do
[
{
nav_item: _('Group overview'),
nav_sub_items: [
_('Details'),
_('Activity'),
(_('Contribution Analytics') if Gitlab.ee?)
_('Activity')
]
},
{
......@@ -34,6 +42,7 @@ describe 'Group navbar' do
nav_item: _('Kubernetes'),
nav_sub_items: []
},
(analytics_nav_item if Gitlab.ee?),
{
nav_item: _('Members'),
nav_sub_items: []
......
......@@ -59,13 +59,13 @@ describe 'Project navbar' do
_('Environments'),
_('Error Tracking'),
_('Serverless'),
_('Kubernetes'),
_('Auto DevOps')
_('Kubernetes')
]
},
{
nav_item: _('Analytics'),
nav_sub_items: [
_('CI / CD Analytics'),
(_('Code Review') if Gitlab.ee?),
_('Cycle Analytics'),
_('Repository Analytics')
......
# frozen_string_literal: true
RSpec.shared_examples 'verified navigation bar' do
let(:expected_structure) do
structure.compact!
structure.each { |s| s[:nav_sub_items].compact! }
structure
end
it 'renders correctly' do
current_structure = page.find_all('.sidebar-top-level-items > li', class: ['!hidden']).map do |item|
current_structure = page.all('.sidebar-top-level-items > li', class: ['!hidden']).map do |item|
nav_item = item.find_all('a').first.text.gsub(/\s+\d+$/, '') # remove counts at the end
nav_sub_items = item
.find_all('.sidebar-sub-level-items a')
.map(&:text)
.drop(1) # remove the first hidden item
nav_sub_items = item.all('.sidebar-sub-level-items > li', class: ['!fly-out-top-item']).map do |list_item|
list_item.all('a').first.text
end
{ nav_item: nav_item, nav_sub_items: nav_sub_items }
end
structure.each { |s| s[:nav_sub_items].compact! }
expect(current_structure).to eq(structure)
expect(current_structure).to eq(expected_structure)
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