Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sidebars')
-rw-r--r--lib/sidebars/concerns/render_if_logged_in.rb11
-rw-r--r--lib/sidebars/concerns/super_sidebar_panel.rb58
-rw-r--r--lib/sidebars/context.rb5
-rw-r--r--lib/sidebars/explore/menus/groups_menu.rb34
-rw-r--r--lib/sidebars/explore/menus/projects_menu.rb34
-rw-r--r--lib/sidebars/explore/menus/snippets_menu.rb34
-rw-r--r--lib/sidebars/explore/menus/topics_menu.rb34
-rw-r--r--lib/sidebars/explore/panel.rb39
-rw-r--r--lib/sidebars/groups/menus/ci_cd_menu.rb5
-rw-r--r--lib/sidebars/groups/menus/group_information_menu.rb10
-rw-r--r--lib/sidebars/groups/menus/invite_team_members_menu.rb46
-rw-r--r--lib/sidebars/groups/menus/issues_menu.rb21
-rw-r--r--lib/sidebars/groups/menus/kubernetes_menu.rb8
-rw-r--r--lib/sidebars/groups/menus/merge_requests_menu.rb11
-rw-r--r--lib/sidebars/groups/menus/observability_menu.rb14
-rw-r--r--lib/sidebars/groups/menus/packages_registries_menu.rb10
-rw-r--r--lib/sidebars/groups/menus/scope_menu.rb12
-rw-r--r--lib/sidebars/groups/menus/settings_menu.rb5
-rw-r--r--lib/sidebars/groups/panel.rb10
-rw-r--r--lib/sidebars/groups/super_sidebar_menus/operations_menu.rb19
-rw-r--r--lib/sidebars/groups/super_sidebar_menus/plan_menu.rb19
-rw-r--r--lib/sidebars/groups/super_sidebar_panel.rb43
-rw-r--r--lib/sidebars/menu.rb45
-rw-r--r--lib/sidebars/menu_item.rb25
-rw-r--r--lib/sidebars/panel.rb11
-rw-r--r--lib/sidebars/projects/menus/analytics_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/ci_cd_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/deployments_menu.rb9
-rw-r--r--lib/sidebars/projects/menus/infrastructure_menu.rb36
-rw-r--r--lib/sidebars/projects/menus/invite_team_members_menu.rb47
-rw-r--r--lib/sidebars/projects/menus/issues_menu.rb16
-rw-r--r--lib/sidebars/projects/menus/merge_requests_menu.rb11
-rw-r--r--lib/sidebars/projects/menus/monitor_menu.rb20
-rw-r--r--lib/sidebars/projects/menus/packages_registries_menu.rb9
-rw-r--r--lib/sidebars/projects/menus/project_information_menu.rb10
-rw-r--r--lib/sidebars/projects/menus/repository_menu.rb9
-rw-r--r--lib/sidebars/projects/menus/scope_menu.rb10
-rw-r--r--lib/sidebars/projects/menus/security_compliance_menu.rb9
-rw-r--r--lib/sidebars/projects/menus/settings_menu.rb5
-rw-r--r--lib/sidebars/projects/menus/snippets_menu.rb9
-rw-r--r--lib/sidebars/projects/menus/wiki_menu.rb8
-rw-r--r--lib/sidebars/projects/panel.rb8
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/operations_menu.rb19
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/plan_menu.rb19
-rw-r--r--lib/sidebars/projects/super_sidebar_panel.rb43
-rw-r--r--lib/sidebars/static_menu.rb13
-rw-r--r--lib/sidebars/uncategorized_menu.rb19
-rw-r--r--lib/sidebars/user_profile/base_menu.rb12
-rw-r--r--lib/sidebars/user_profile/menus/activity_menu.rb24
-rw-r--r--lib/sidebars/user_profile/menus/contributed_projects_menu.rb24
-rw-r--r--lib/sidebars/user_profile/menus/followers_menu.rb38
-rw-r--r--lib/sidebars/user_profile/menus/following_menu.rb38
-rw-r--r--lib/sidebars/user_profile/menus/groups_menu.rb24
-rw-r--r--lib/sidebars/user_profile/menus/overview_menu.rb24
-rw-r--r--lib/sidebars/user_profile/menus/personal_projects_menu.rb24
-rw-r--r--lib/sidebars/user_profile/menus/snippets_menu.rb24
-rw-r--r--lib/sidebars/user_profile/menus/starred_projects_menu.rb24
-rw-r--r--lib/sidebars/user_profile/panel.rb52
-rw-r--r--lib/sidebars/user_settings/menus/access_tokens_menu.rb39
-rw-r--r--lib/sidebars/user_settings/menus/account_menu.rb36
-rw-r--r--lib/sidebars/user_settings/menus/active_sessions_menu.rb31
-rw-r--r--lib/sidebars/user_settings/menus/applications_menu.rb31
-rw-r--r--lib/sidebars/user_settings/menus/authentication_log_menu.rb31
-rw-r--r--lib/sidebars/user_settings/menus/chat_menu.rb31
-rw-r--r--lib/sidebars/user_settings/menus/emails_menu.rb36
-rw-r--r--lib/sidebars/user_settings/menus/gpg_keys_menu.rb31
-rw-r--r--lib/sidebars/user_settings/menus/notifications_menu.rb31
-rw-r--r--lib/sidebars/user_settings/menus/password_menu.rb39
-rw-r--r--lib/sidebars/user_settings/menus/preferences_menu.rb31
-rw-r--r--lib/sidebars/user_settings/menus/profile_menu.rb31
-rw-r--r--lib/sidebars/user_settings/menus/saved_replies_menu.rb42
-rw-r--r--lib/sidebars/user_settings/menus/ssh_keys_menu.rb36
-rw-r--r--lib/sidebars/user_settings/panel.rb51
-rw-r--r--lib/sidebars/your_work/panel.rb9
74 files changed, 1606 insertions, 140 deletions
diff --git a/lib/sidebars/concerns/render_if_logged_in.rb b/lib/sidebars/concerns/render_if_logged_in.rb
new file mode 100644
index 00000000000..221af7df23b
--- /dev/null
+++ b/lib/sidebars/concerns/render_if_logged_in.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Concerns
+ module RenderIfLoggedIn
+ def render?
+ !!context.current_user
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/concerns/super_sidebar_panel.rb b/lib/sidebars/concerns/super_sidebar_panel.rb
new file mode 100644
index 00000000000..5f3607debbc
--- /dev/null
+++ b/lib/sidebars/concerns/super_sidebar_panel.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Concerns
+ # Contains helper methods aid conversion of a "normal" panel
+ # into a Super Sidebar Panel
+ module SuperSidebarPanel
+ # Picks menus from a list and adds them to the current menu list
+ # if they should be picked into the super sidebar
+ def pick_from_old_menus(old_menus)
+ old_menus.select! do |menu|
+ next true unless menu.pick_into_super_sidebar?
+
+ add_menu(menu)
+ false
+ end
+ end
+
+ def transform_old_menus(current_menus, *old_menus)
+ old_menus.each do |menu|
+ next unless menu.render?
+
+ menu.renderable_items.each { |item| add_menu_item_to_super_sidebar_parent(current_menus, item) }
+
+ menu_item_args = menu.serialize_as_menu_item_args
+
+ next if menu_item_args.nil?
+
+ add_menu_item_to_super_sidebar_parent(
+ current_menus, ::Sidebars::MenuItem.new(**menu_item_args)
+ )
+ end
+ end
+
+ private
+
+ # Finds a menu_items super sidebar parent and adds the item to that menu
+ # Handles:
+ # - menu_item.super_sidebar_before, adding before a certain item
+ # - parent == nil, or parent not being part of the panel:
+ # we assume that the menu item hasn't been categorized yet
+ # - parent == ::Sidebars::NilMenuItem, the item explicitly is supposed to be removed
+ def add_menu_item_to_super_sidebar_parent(menus, menu_item)
+ parent = menu_item.super_sidebar_parent || ::Sidebars::UncategorizedMenu
+ return if parent == ::Sidebars::NilMenuItem
+
+ idx = index_of(menus, parent) || index_of(menus, ::Sidebars::UncategorizedMenu)
+ return unless idx
+
+ if menu_item.super_sidebar_before
+ menus[idx].insert_item_before(menu_item.super_sidebar_before, menu_item)
+ else
+ menus[idx].add_item(menu_item)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/context.rb b/lib/sidebars/context.rb
index d9ac2705aaf..b49776bed10 100644
--- a/lib/sidebars/context.rb
+++ b/lib/sidebars/context.rb
@@ -6,16 +6,19 @@
# values where the logic is in helpers.
module Sidebars
class Context
- attr_reader :current_user, :container
+ attr_reader :current_user, :container, :route_is_active, :is_super_sidebar
def initialize(current_user:, container:, **args)
@current_user = current_user
@container = container
+ @is_super_sidebar = false
args.each do |key, value|
singleton_class.public_send(:attr_reader, key) # rubocop:disable GitlabSecurity/PublicSend
instance_variable_set("@#{key}", value)
end
+
+ @route_is_active ||= ->(_) { false }
end
end
end
diff --git a/lib/sidebars/explore/menus/groups_menu.rb b/lib/sidebars/explore/menus/groups_menu.rb
new file mode 100644
index 00000000000..542da0ad7fd
--- /dev/null
+++ b/lib/sidebars/explore/menus/groups_menu.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Explore
+ module Menus
+ class GroupsMenu < ::Sidebars::Menu
+ override :link
+ def link
+ explore_groups_path
+ end
+
+ override :title
+ def title
+ _('Groups')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'group'
+ end
+
+ override :render?
+ def render?
+ true
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: ['explore/groups'] }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/explore/menus/projects_menu.rb b/lib/sidebars/explore/menus/projects_menu.rb
new file mode 100644
index 00000000000..29c35d23b7b
--- /dev/null
+++ b/lib/sidebars/explore/menus/projects_menu.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Explore
+ module Menus
+ class ProjectsMenu < ::Sidebars::Menu
+ override :link
+ def link
+ explore_projects_path
+ end
+
+ override :title
+ def title
+ _('Projects')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'project'
+ end
+
+ override :render?
+ def render?
+ true
+ end
+
+ override :active_routes
+ def active_routes
+ { page: [link, explore_root_path] }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/explore/menus/snippets_menu.rb b/lib/sidebars/explore/menus/snippets_menu.rb
new file mode 100644
index 00000000000..67b852258a7
--- /dev/null
+++ b/lib/sidebars/explore/menus/snippets_menu.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Explore
+ module Menus
+ class SnippetsMenu < ::Sidebars::Menu
+ override :link
+ def link
+ explore_snippets_path
+ end
+
+ override :title
+ def title
+ _('Snippets')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'snippet'
+ end
+
+ override :render?
+ def render?
+ true
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: ['explore/snippets'] }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/explore/menus/topics_menu.rb b/lib/sidebars/explore/menus/topics_menu.rb
new file mode 100644
index 00000000000..5e0a7897873
--- /dev/null
+++ b/lib/sidebars/explore/menus/topics_menu.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Explore
+ module Menus
+ class TopicsMenu < ::Sidebars::Menu
+ override :link
+ def link
+ topics_explore_projects_path
+ end
+
+ override :title
+ def title
+ _('Topics')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'labels'
+ end
+
+ override :render?
+ def render?
+ true
+ end
+
+ override :active_routes
+ def active_routes
+ { page: link, path: 'projects#topic' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/explore/panel.rb b/lib/sidebars/explore/panel.rb
new file mode 100644
index 00000000000..9a585a99705
--- /dev/null
+++ b/lib/sidebars/explore/panel.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Explore
+ class Panel < ::Sidebars::Panel
+ override :configure_menus
+ def configure_menus
+ add_menus
+ end
+
+ override :aria_label
+ def aria_label
+ _('Explore')
+ end
+
+ override :render_raw_scope_menu_partial
+ def render_raw_scope_menu_partial
+ "shared/nav/explore_scope_header"
+ end
+
+ override :super_sidebar_context_header
+ def super_sidebar_context_header
+ {
+ title: aria_label,
+ icon: 'compass'
+ }
+ end
+
+ private
+
+ def add_menus
+ add_menu(Sidebars::Explore::Menus::ProjectsMenu.new(context))
+ add_menu(Sidebars::Explore::Menus::GroupsMenu.new(context))
+ add_menu(Sidebars::Explore::Menus::TopicsMenu.new(context))
+ add_menu(Sidebars::Explore::Menus::SnippetsMenu.new(context))
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/groups/menus/ci_cd_menu.rb b/lib/sidebars/groups/menus/ci_cd_menu.rb
index 0c2995f95e6..f32bc49673f 100644
--- a/lib/sidebars/groups/menus/ci_cd_menu.rb
+++ b/lib/sidebars/groups/menus/ci_cd_menu.rb
@@ -21,6 +21,11 @@ module Sidebars
'rocket'
end
+ override :pick_into_super_sidebar?
+ def pick_into_super_sidebar?
+ true
+ end
+
private
def runners_menu_item
diff --git a/lib/sidebars/groups/menus/group_information_menu.rb b/lib/sidebars/groups/menus/group_information_menu.rb
index 3ce99e14a04..2364ad85cb5 100644
--- a/lib/sidebars/groups/menus/group_information_menu.rb
+++ b/lib/sidebars/groups/menus/group_information_menu.rb
@@ -28,6 +28,11 @@ module Sidebars
{ path: 'groups#subgroups' }
end
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ nil
+ end
+
private
def activity_menu_item
@@ -38,6 +43,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Activity'),
link: activity_group_path(context.group),
+ super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::PlanMenu,
active_routes: { path: 'groups#activity' },
item_id: :activity
)
@@ -51,6 +57,8 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Labels'),
link: group_labels_path(context.group),
+ super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::PlanMenu,
+ super_sidebar_before: :activity,
active_routes: { controller: :labels },
item_id: :labels
)
@@ -64,6 +72,8 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Members'),
link: group_group_members_path(context.group),
+ sprite_icon: context.is_super_sidebar ? 'users' : nil,
+ super_sidebar_parent: ::Sidebars::StaticMenu,
active_routes: { path: 'group_members#index' },
item_id: :members
)
diff --git a/lib/sidebars/groups/menus/invite_team_members_menu.rb b/lib/sidebars/groups/menus/invite_team_members_menu.rb
deleted file mode 100644
index 0779b696061..00000000000
--- a/lib/sidebars/groups/menus/invite_team_members_menu.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-module Sidebars
- module Groups
- module Menus
- class InviteTeamMembersMenu < ::Sidebars::Menu
- override :title
- def title
- s_('InviteMember|Invite members')
- end
-
- override :render?
- def render?
- can?(context.current_user, :admin_group_member, context.group) && all_valid_members.size <= 1
- end
-
- override :menu_partial
- def menu_partial
- 'groups/invite_members_side_nav_link'
- end
-
- override :menu_partial_options
- def menu_partial_options
- {
- group: context.group,
- title: title,
- sidebar_menu: self
- }
- end
-
- override :extra_nav_link_html_options
- def extra_nav_link_html_options
- {
- 'data-test-id': 'side-nav-invite-members'
- }
- end
-
- private
-
- def all_valid_members
- GroupMembersFinder.new(context.group, context.current_user).execute
- end
- end
- end
- end
-end
diff --git a/lib/sidebars/groups/menus/issues_menu.rb b/lib/sidebars/groups/menus/issues_menu.rb
index 4044cb1c716..75bdb617b1a 100644
--- a/lib/sidebars/groups/menus/issues_menu.rb
+++ b/lib/sidebars/groups/menus/issues_menu.rb
@@ -49,12 +49,25 @@ module Sidebars
}
end
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ super.merge({
+ active_routes: list_menu_item.active_routes,
+ sprite_icon: sprite_icon,
+ pill_count: pill_count,
+ has_pill: has_pill?,
+ super_sidebar_parent: ::Sidebars::StaticMenu,
+ item_id: :group_issue_list
+ })
+ end
+
private
def list_menu_item
::Sidebars::MenuItem.new(
title: _('List'),
link: issues_group_path(context.group),
+ super_sidebar_parent: ::Sidebars::NilMenuItem,
active_routes: { path: 'groups#issues' },
container_html_options: { aria: { label: _('Issues') } },
item_id: :issue_list
@@ -66,11 +79,16 @@ module Sidebars
return ::Sidebars::NilMenuItem.new(item_id: :boards)
end
- title = context.group.multiple_issue_boards_available? ? s_('IssueBoards|Boards') : s_('IssueBoards|Board')
+ title = if context.is_super_sidebar
+ context.group.multiple_issue_boards_available? ? s_('Issue boards') : s_('Issue board')
+ else
+ context.group.multiple_issue_boards_available? ? s_('IssueBoards|Boards') : s_('IssueBoards|Board')
+ end
::Sidebars::MenuItem.new(
title: title,
link: group_boards_path(context.group),
+ super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::PlanMenu,
active_routes: { path: %w[boards#index boards#show] },
item_id: :boards
)
@@ -84,6 +102,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Milestones'),
link: group_milestones_path(context.group),
+ super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::PlanMenu,
active_routes: { path: 'milestones#index' },
item_id: :milestones
)
diff --git a/lib/sidebars/groups/menus/kubernetes_menu.rb b/lib/sidebars/groups/menus/kubernetes_menu.rb
index 0d845978a93..a7c14148230 100644
--- a/lib/sidebars/groups/menus/kubernetes_menu.rb
+++ b/lib/sidebars/groups/menus/kubernetes_menu.rb
@@ -38,6 +38,14 @@ module Sidebars
def active_routes
{ controller: :clusters }
end
+
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ super.merge({
+ super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::OperationsMenu,
+ item_id: :group_kubernetes_clusters
+ })
+ end
end
end
end
diff --git a/lib/sidebars/groups/menus/merge_requests_menu.rb b/lib/sidebars/groups/menus/merge_requests_menu.rb
index 050cba07641..5e25c33167c 100644
--- a/lib/sidebars/groups/menus/merge_requests_menu.rb
+++ b/lib/sidebars/groups/menus/merge_requests_menu.rb
@@ -52,6 +52,17 @@ module Sidebars
def active_routes
{ path: 'groups#merge_requests' }
end
+
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ super.merge({
+ sprite_icon: sprite_icon,
+ pill_count: pill_count,
+ has_pill: has_pill?,
+ super_sidebar_parent: ::Sidebars::StaticMenu,
+ item_id: :group_merge_request_list
+ })
+ end
end
end
end
diff --git a/lib/sidebars/groups/menus/observability_menu.rb b/lib/sidebars/groups/menus/observability_menu.rb
index d85efb1a002..570a59f7e55 100644
--- a/lib/sidebars/groups/menus/observability_menu.rb
+++ b/lib/sidebars/groups/menus/observability_menu.rb
@@ -6,8 +6,11 @@ module Sidebars
class ObservabilityMenu < ::Sidebars::Menu
override :configure_menu_items
def configure_menu_items
- add_item(explore_menu_item)
- add_item(datasources_menu_item)
+ add_item(explore_menu_item) if Gitlab::Observability.allowed_for_action?(context.current_user, context.group,
+ :explore)
+
+ add_item(datasources_menu_item) if Gitlab::Observability.allowed_for_action?(context.current_user,
+ context.group, :datasources)
end
override :title
@@ -22,7 +25,12 @@ module Sidebars
override :render?
def render?
- Gitlab::Observability.observability_enabled?(context.current_user, context.group)
+ Gitlab::Observability.allowed_for_action?(context.current_user, context.group, :explore)
+ end
+
+ override :pick_into_super_sidebar?
+ def pick_into_super_sidebar?
+ true
end
private
diff --git a/lib/sidebars/groups/menus/packages_registries_menu.rb b/lib/sidebars/groups/menus/packages_registries_menu.rb
index e115ca669d4..73a67bf1142 100644
--- a/lib/sidebars/groups/menus/packages_registries_menu.rb
+++ b/lib/sidebars/groups/menus/packages_registries_menu.rb
@@ -23,6 +23,11 @@ module Sidebars
'package'
end
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ nil
+ end
+
private
def packages_registry_menu_item
@@ -31,6 +36,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Package Registry'),
link: group_packages_path(context.group),
+ super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: 'groups/packages' },
item_id: :packages_registry
)
@@ -44,6 +50,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Container Registry'),
link: group_container_registries_path(context.group),
+ super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: 'groups/registry/repositories' },
item_id: :container_registry
)
@@ -59,6 +66,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Harbor Registry'),
link: group_harbor_repositories_path(context.group),
+ super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: 'groups/harbor/repositories' },
item_id: :harbor_registry
)
@@ -74,6 +82,8 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Dependency Proxy'),
link: group_dependency_proxy_path(context.group),
+ super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::OperationsMenu,
+ super_sidebar_before: :packages_registry,
active_routes: { controller: 'groups/dependency_proxies' },
item_id: :dependency_proxy
)
diff --git a/lib/sidebars/groups/menus/scope_menu.rb b/lib/sidebars/groups/menus/scope_menu.rb
index 6ce43491343..5505f56a6d3 100644
--- a/lib/sidebars/groups/menus/scope_menu.rb
+++ b/lib/sidebars/groups/menus/scope_menu.rb
@@ -16,7 +16,7 @@ module Sidebars
override :active_routes
def active_routes
- { path: %w[groups#show groups#details] }
+ { path: %w[groups#show groups#details groups#new projects#new] }
end
override :extra_nav_link_html_options
@@ -32,6 +32,16 @@ module Sidebars
def render?
true
end
+
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ super.merge({
+ title: _('Group overview'),
+ sprite_icon: 'group',
+ super_sidebar_parent: ::Sidebars::StaticMenu,
+ item_id: :group_overview
+ })
+ end
end
end
end
diff --git a/lib/sidebars/groups/menus/settings_menu.rb b/lib/sidebars/groups/menus/settings_menu.rb
index 5b81f22c796..76c5f9c16a5 100644
--- a/lib/sidebars/groups/menus/settings_menu.rb
+++ b/lib/sidebars/groups/menus/settings_menu.rb
@@ -47,6 +47,11 @@ module Sidebars
}
end
+ override :pick_into_super_sidebar?
+ def pick_into_super_sidebar?
+ true
+ end
+
private
def general_menu_item
diff --git a/lib/sidebars/groups/panel.rb b/lib/sidebars/groups/panel.rb
index e8b815bdce7..77ca51ddf92 100644
--- a/lib/sidebars/groups/panel.rb
+++ b/lib/sidebars/groups/panel.rb
@@ -16,22 +16,12 @@ module Sidebars
add_menu(Sidebars::Groups::Menus::PackagesRegistriesMenu.new(context))
add_menu(Sidebars::Groups::Menus::CustomerRelationsMenu.new(context))
add_menu(Sidebars::Groups::Menus::SettingsMenu.new(context))
- add_invite_members_menu
end
override :aria_label
def aria_label
context.group.subgroup? ? _('Subgroup navigation') : _('Group navigation')
end
-
- private
-
- def add_invite_members_menu
- experiment(:invite_members_in_side_nav, group: context.group) do |e|
- e.control {}
- e.candidate { add_menu(Sidebars::Groups::Menus::InviteTeamMembersMenu.new(context)) }
- end
- end
end
end
end
diff --git a/lib/sidebars/groups/super_sidebar_menus/operations_menu.rb b/lib/sidebars/groups/super_sidebar_menus/operations_menu.rb
new file mode 100644
index 00000000000..195718e0681
--- /dev/null
+++ b/lib/sidebars/groups/super_sidebar_menus/operations_menu.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Groups
+ module SuperSidebarMenus
+ class OperationsMenu < ::Sidebars::Menu
+ override :title
+ def title
+ _('Operations')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'deployments'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/groups/super_sidebar_menus/plan_menu.rb b/lib/sidebars/groups/super_sidebar_menus/plan_menu.rb
new file mode 100644
index 00000000000..8a90974c0d4
--- /dev/null
+++ b/lib/sidebars/groups/super_sidebar_menus/plan_menu.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Groups
+ module SuperSidebarMenus
+ class PlanMenu < ::Sidebars::Menu
+ override :title
+ def title
+ _('Plan')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'planning'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/groups/super_sidebar_panel.rb b/lib/sidebars/groups/super_sidebar_panel.rb
new file mode 100644
index 00000000000..620f6e78eda
--- /dev/null
+++ b/lib/sidebars/groups/super_sidebar_panel.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Groups
+ class SuperSidebarPanel < ::Sidebars::Groups::Panel
+ include ::Sidebars::Concerns::SuperSidebarPanel
+ extend ::Gitlab::Utils::Override
+
+ override :configure_menus
+ def configure_menus
+ super
+ old_menus = @menus
+ @menus = []
+
+ add_menu(Sidebars::StaticMenu.new(context))
+ add_menu(Sidebars::Groups::SuperSidebarMenus::PlanMenu.new(context))
+
+ pick_from_old_menus(old_menus)
+
+ insert_menu_before(
+ Sidebars::Groups::Menus::ObservabilityMenu,
+ Sidebars::Groups::SuperSidebarMenus::OperationsMenu.new(context)
+ )
+
+ insert_menu_before(
+ Sidebars::Groups::Menus::SettingsMenu,
+ Sidebars::UncategorizedMenu.new(context)
+ )
+
+ transform_old_menus(@menus, @scope_menu, *old_menus)
+ end
+
+ override :super_sidebar_context_header
+ def super_sidebar_context_header
+ {
+ title: context.group.name,
+ avatar: context.group.avatar_url,
+ id: context.group.id
+ }
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/menu.rb b/lib/sidebars/menu.rb
index dfd88c99a0c..03995362ff0 100644
--- a/lib/sidebars/menu.rb
+++ b/lib/sidebars/menu.rb
@@ -66,6 +66,40 @@ module Sidebars
@renderable_items ||= @items.select(&:render?)
end
+ # Returns a tree-like representation of itself and all
+ # renderable menu entries, with additional information
+ # on whether the item(s) have an active route
+ def serialize_for_super_sidebar
+ items = serialize_items_for_super_sidebar
+ is_active = @context.route_is_active.call(active_routes) || items.any? { |item| item[:is_active] }
+
+ {
+ title: title,
+ icon: sprite_icon,
+ link: link,
+ is_active: is_active,
+ pill_count: has_pill? ? pill_count : nil,
+ items: items
+ }
+ end
+
+ # Returns an array of renderable menu entries,
+ # with additional information on whether the item
+ # has an active route
+ def serialize_items_for_super_sidebar
+ # All renderable menu entries
+ renderable_items.map do |entry|
+ entry.serialize_for_super_sidebar.tap do |item|
+ active_routes = item.delete(:active_routes)
+ item[:is_active] = active_routes ? @context.route_is_active.call(active_routes) : false
+ end
+ end
+ end
+
+ def pick_into_super_sidebar?
+ false
+ end
+
# Returns whether the menu has any renderable menu item
def has_renderable_items?
renderable_items.any?
@@ -93,6 +127,17 @@ module Sidebars
end
end
+ # Sometimes we want to convert a top-level Menu (e.g. Wiki/Snippets)
+ # to a MenuItem. This serializer is used in order to enable that conversion
+ def serialize_as_menu_item_args
+ {
+ title: title,
+ link: link,
+ active_routes: active_routes,
+ container_html_options: container_html_options
+ }
+ end
+
private
override :index_of
diff --git a/lib/sidebars/menu_item.rb b/lib/sidebars/menu_item.rb
index efdedf6c3bd..becff240034 100644
--- a/lib/sidebars/menu_item.rb
+++ b/lib/sidebars/menu_item.rb
@@ -4,11 +4,11 @@ module Sidebars
class MenuItem
include ::Sidebars::Concerns::LinkWithHtmlOptions
- attr_reader :title, :link, :active_routes, :item_id, :container_html_options, :sprite_icon, :sprite_icon_html_options, :hint_html_options, :has_pill, :pill_count
+ attr_reader :title, :link, :active_routes, :item_id, :container_html_options, :sprite_icon, :sprite_icon_html_options, :hint_html_options, :has_pill, :pill_count, :super_sidebar_parent, :super_sidebar_before
alias_method :has_pill?, :has_pill
# rubocop: disable Metrics/ParameterLists
- def initialize(title:, link:, active_routes:, item_id: nil, container_html_options: {}, sprite_icon: nil, sprite_icon_html_options: {}, hint_html_options: {}, has_pill: false, pill_count: nil)
+ def initialize(title:, link:, active_routes:, item_id: nil, container_html_options: {}, sprite_icon: nil, sprite_icon_html_options: {}, hint_html_options: {}, has_pill: false, pill_count: nil, super_sidebar_parent: nil, super_sidebar_before: nil)
@title = title
@link = link
@active_routes = active_routes
@@ -19,6 +19,8 @@ module Sidebars
@hint_html_options = hint_html_options
@has_pill = has_pill
@pill_count = pill_count
+ @super_sidebar_before = super_sidebar_before
+ @super_sidebar_parent = super_sidebar_parent
end
# rubocop: enable Metrics/ParameterLists
@@ -30,6 +32,25 @@ module Sidebars
true
end
+ def serialize_for_super_sidebar
+ {
+ title: title,
+ icon: sprite_icon,
+ link: link,
+ active_routes: active_routes,
+ pill_count: has_pill ? pill_count : nil
+ # Check whether support is needed for the following properties,
+ # in order to get feature parity with the HAML renderer
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/391864
+ #
+ # container_html_options
+ # hint_html_options
+ # nav_link_html_options
+ #
+ # item_id
+ }
+ end
+
def nav_link_html_options
{
data: {
diff --git a/lib/sidebars/panel.rb b/lib/sidebars/panel.rb
index 2a172cfffe3..4c0d4caf81e 100644
--- a/lib/sidebars/panel.rb
+++ b/lib/sidebars/panel.rb
@@ -4,7 +4,6 @@ module Sidebars
class Panel
extend ::Gitlab::Utils::Override
include ::Sidebars::Concerns::PositionableList
- include Gitlab::Experiment::Dsl
attr_reader :context, :scope_menu, :hidden_menu
@@ -61,6 +60,16 @@ module Sidebars
@renderable_menus ||= @menus.select(&:render?)
end
+ # Serializes every renderable menu and returns a flattened result
+ def super_sidebar_menu_items
+ @super_sidebar_menu_items ||= renderable_menus
+ .flat_map(&:serialize_for_super_sidebar)
+ end
+
+ def super_sidebar_context_header
+ raise NotImplementedError
+ end
+
def container
context.container
end
diff --git a/lib/sidebars/projects/menus/analytics_menu.rb b/lib/sidebars/projects/menus/analytics_menu.rb
index 643b7ebcd5a..fae2efd91de 100644
--- a/lib/sidebars/projects/menus/analytics_menu.rb
+++ b/lib/sidebars/projects/menus/analytics_menu.rb
@@ -41,6 +41,11 @@ module Sidebars
'chart'
end
+ override :pick_into_super_sidebar?
+ def pick_into_super_sidebar?
+ true
+ end
+
private
def ci_cd_analytics_menu_item
diff --git a/lib/sidebars/projects/menus/ci_cd_menu.rb b/lib/sidebars/projects/menus/ci_cd_menu.rb
index 5df99bb9d84..3d11dba1089 100644
--- a/lib/sidebars/projects/menus/ci_cd_menu.rb
+++ b/lib/sidebars/projects/menus/ci_cd_menu.rb
@@ -39,6 +39,11 @@ module Sidebars
'rocket'
end
+ override :pick_into_super_sidebar?
+ def pick_into_super_sidebar?
+ true
+ end
+
private
def pipelines_menu_item
diff --git a/lib/sidebars/projects/menus/deployments_menu.rb b/lib/sidebars/projects/menus/deployments_menu.rb
index 4d4e65e9795..fa6c70cfd3d 100644
--- a/lib/sidebars/projects/menus/deployments_menu.rb
+++ b/lib/sidebars/projects/menus/deployments_menu.rb
@@ -34,6 +34,11 @@ module Sidebars
'deployments'
end
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ nil
+ end
+
private
def feature_flags_menu_item
@@ -44,6 +49,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Feature Flags'),
link: project_feature_flags_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: :feature_flags },
container_html_options: { class: 'shortcuts-feature-flags' },
item_id: :feature_flags
@@ -58,6 +64,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Environments'),
link: project_environments_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: :environments },
container_html_options: { class: 'shortcuts-environments' },
item_id: :environments
@@ -73,6 +80,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Releases'),
link: project_releases_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
item_id: :releases,
active_routes: { controller: :releases },
container_html_options: { class: 'shortcuts-deployments-releases' }
@@ -87,6 +95,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Pages'),
link: project_pages_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { path: 'pages#show' },
item_id: :pages
)
diff --git a/lib/sidebars/projects/menus/infrastructure_menu.rb b/lib/sidebars/projects/menus/infrastructure_menu.rb
index 04c9ab77729..a7cd920a74c 100644
--- a/lib/sidebars/projects/menus/infrastructure_menu.rb
+++ b/lib/sidebars/projects/menus/infrastructure_menu.rb
@@ -11,6 +11,7 @@ module Sidebars
add_item(kubernetes_menu_item)
add_item(terraform_menu_item)
add_item(google_cloud_menu_item)
+ add_item(aws_menu_item)
true
end
@@ -32,6 +33,11 @@ module Sidebars
'cloud-gear'
end
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ nil
+ end
+
private
def feature_enabled?
@@ -46,6 +52,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Kubernetes clusters'),
link: project_clusters_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: [:cluster_agents, :clusters] },
container_html_options: { class: 'shortcuts-kubernetes' },
hint_html_options: kubernetes_hint_html_options,
@@ -74,11 +81,30 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Terraform'),
link: project_terraform_index_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: :terraform },
item_id: :terraform
)
end
+ def aws_menu_item
+ enabled_for_user = Feature.enabled?(:cloudseed_aws, context.current_user)
+ enabled_for_group = Feature.enabled?(:cloudseed_aws, context.project.group)
+ enabled_for_project = Feature.enabled?(:cloudseed_aws, context.project)
+ feature_is_enabled = enabled_for_user || enabled_for_group || enabled_for_project
+ user_has_permissions = can?(context.current_user, :admin_project_aws, context.project)
+
+ return ::Sidebars::NilMenuItem.new(item_id: :cloudseed_aws) unless feature_is_enabled && user_has_permissions
+
+ ::Sidebars::MenuItem.new(
+ title: _('AWS'),
+ link: '#',
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
+ item_id: :aws,
+ active_routes: { controller: '' }
+ )
+ end
+
def google_cloud_menu_item
enabled_for_user = Feature.enabled?(:incubation_5mp_google_cloud, context.current_user)
enabled_for_group = Feature.enabled?(:incubation_5mp_google_cloud, context.project.group)
@@ -86,13 +112,16 @@ module Sidebars
feature_is_enabled = enabled_for_user || enabled_for_group || enabled_for_project
user_has_permissions = can?(context.current_user, :admin_project_google_cloud, context.project)
- unless feature_is_enabled && user_has_permissions
+ google_oauth2_configured = google_oauth2_configured?
+
+ unless feature_is_enabled && user_has_permissions && google_oauth2_configured
return ::Sidebars::NilMenuItem.new(item_id: :incubation_5mp_google_cloud)
end
::Sidebars::MenuItem.new(
title: _('Google Cloud'),
link: project_google_cloud_configuration_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: %w[
projects/google_cloud/configuration
projects/google_cloud/service_accounts
@@ -103,6 +132,11 @@ module Sidebars
item_id: :google_cloud
)
end
+
+ def google_oauth2_configured?
+ config = Gitlab::Auth::OAuth::Provider.config_for('google_oauth2')
+ config&.present? && config.app_id.present? && config.app_secret.present?
+ end
end
end
end
diff --git a/lib/sidebars/projects/menus/invite_team_members_menu.rb b/lib/sidebars/projects/menus/invite_team_members_menu.rb
deleted file mode 100644
index 0db49f1e12a..00000000000
--- a/lib/sidebars/projects/menus/invite_team_members_menu.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-module Sidebars
- module Projects
- module Menus
- class InviteTeamMembersMenu < ::Sidebars::Menu
- override :title
- def title
- s_('InviteMember|Invite members')
- end
-
- override :render?
- def render?
- can?(context.current_user, :admin_project_member, context.project) && all_valid_members.size <= 1
- end
-
- override :menu_partial
- def menu_partial
- 'projects/invite_members_side_nav_link'
- end
-
- override :menu_partial_options
- def menu_partial_options
- {
- project: context.project,
- title: title,
- sidebar_menu: self
- }
- end
-
- override :extra_nav_link_html_options
- def extra_nav_link_html_options
- {
- 'data-test-id': 'side-nav-invite-members'
- }
- end
-
- private
-
- def all_valid_members
- MembersFinder.new(context.project, context.current_user)
- .execute(include_relations: [:inherited, :direct, :invited_groups])
- end
- end
- end
- end
-end
diff --git a/lib/sidebars/projects/menus/issues_menu.rb b/lib/sidebars/projects/menus/issues_menu.rb
index 51eea3d850d..6904dc129b7 100644
--- a/lib/sidebars/projects/menus/issues_menu.rb
+++ b/lib/sidebars/projects/menus/issues_menu.rb
@@ -68,6 +68,17 @@ module Sidebars
}
end
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ super.merge({
+ sprite_icon: sprite_icon,
+ pill_count: pill_count,
+ has_pill: has_pill?,
+ super_sidebar_parent: ::Sidebars::StaticMenu,
+ item_id: :project_issue_list
+ })
+ end
+
private
def show_issues_menu_items?
@@ -78,6 +89,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('List'),
link: project_issues_path(context.project),
+ super_sidebar_parent: ::Sidebars::NilMenuItem,
active_routes: { path: 'projects/issues#index' },
container_html_options: { aria: { label: _('Issues') } },
item_id: :issue_list
@@ -90,6 +102,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: title,
link: project_boards_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::PlanMenu,
active_routes: { controller: :boards },
item_id: :boards
)
@@ -99,6 +112,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Service Desk'),
link: service_desk_project_issues_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::PlanMenu,
active_routes: { path: 'issues#service_desk' },
item_id: :service_desk
)
@@ -108,6 +122,8 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Milestones'),
link: project_milestones_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::PlanMenu,
+ super_sidebar_before: :service_desk,
active_routes: { controller: :milestones },
item_id: :milestones
)
diff --git a/lib/sidebars/projects/menus/merge_requests_menu.rb b/lib/sidebars/projects/menus/merge_requests_menu.rb
index 3e543872d36..cc7fda0c920 100644
--- a/lib/sidebars/projects/menus/merge_requests_menu.rb
+++ b/lib/sidebars/projects/menus/merge_requests_menu.rb
@@ -64,6 +64,17 @@ module Sidebars
{ controller: ['projects/merge_requests', :milestones] }
end
end
+
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ super.merge({
+ sprite_icon: sprite_icon,
+ pill_count: pill_count,
+ has_pill: has_pill?,
+ super_sidebar_parent: ::Sidebars::StaticMenu,
+ item_id: :project_merge_request_list
+ })
+ end
end
end
end
diff --git a/lib/sidebars/projects/menus/monitor_menu.rb b/lib/sidebars/projects/menus/monitor_menu.rb
index 7d1fa8b8fa7..333112e13b6 100644
--- a/lib/sidebars/projects/menus/monitor_menu.rb
+++ b/lib/sidebars/projects/menus/monitor_menu.rb
@@ -12,7 +12,6 @@ module Sidebars
add_item(error_tracking_menu_item)
add_item(alert_management_menu_item)
add_item(incidents_menu_item)
- add_item(airflow_dashboard_menu_item)
true
end
@@ -39,6 +38,11 @@ module Sidebars
{ controller: [:user, :gcp] }
end
+ override :pick_into_super_sidebar?
+ def pick_into_super_sidebar?
+ true
+ end
+
private
def feature_enabled?
@@ -97,20 +101,6 @@ module Sidebars
item_id: :incidents
)
end
-
- def airflow_dashboard_menu_item
- unless can?(context.current_user, :read_airflow_dags, context.project) &&
- Feature.enabled?(:airflow_dags, context.project)
- return ::Sidebars::NilMenuItem.new(item_id: :airflow)
- end
-
- ::Sidebars::MenuItem.new(
- title: _('Airflow'),
- link: project_airflow_dags_path(context.project),
- active_routes: { path: 'airflow/dags#show' },
- item_id: :airflow_dags
- )
- end
end
end
end
diff --git a/lib/sidebars/projects/menus/packages_registries_menu.rb b/lib/sidebars/projects/menus/packages_registries_menu.rb
index fc7c564574a..d5b590a03aa 100644
--- a/lib/sidebars/projects/menus/packages_registries_menu.rb
+++ b/lib/sidebars/projects/menus/packages_registries_menu.rb
@@ -23,6 +23,11 @@ module Sidebars
'package'
end
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ nil
+ end
+
private
def packages_registry_menu_item
@@ -33,6 +38,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Package Registry'),
link: project_packages_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: :packages },
item_id: :packages_registry,
container_html_options: { class: 'shortcuts-container-registry' }
@@ -47,6 +53,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Container Registry'),
link: project_container_registry_index_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: 'projects/registry/repositories' },
item_id: :container_registry
)
@@ -60,6 +67,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Infrastructure Registry'),
link: project_infrastructure_registry_index_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: :infrastructure_registry },
item_id: :infrastructure_registry
)
@@ -75,6 +83,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Harbor Registry'),
link: project_harbor_repositories_path(context.project),
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { controller: :harbor_registry },
item_id: :harbor_registry
)
diff --git a/lib/sidebars/projects/menus/project_information_menu.rb b/lib/sidebars/projects/menus/project_information_menu.rb
index 44b94ee3522..020de2ff65f 100644
--- a/lib/sidebars/projects/menus/project_information_menu.rb
+++ b/lib/sidebars/projects/menus/project_information_menu.rb
@@ -33,12 +33,18 @@ module Sidebars
'project'
end
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ nil
+ end
+
private
def activity_menu_item
::Sidebars::MenuItem.new(
title: _('Activity'),
link: activity_project_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::PlanMenu,
active_routes: { path: 'projects#activity' },
item_id: :activity,
container_html_options: { class: 'shortcuts-project-activity' }
@@ -53,6 +59,8 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Labels'),
link: project_labels_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::PlanMenu,
+ super_sidebar_before: :activity,
active_routes: { controller: :labels },
item_id: :labels
)
@@ -66,6 +74,8 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Members'),
link: project_project_members_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::PlanMenu,
+ super_sidebar_before: :labels,
active_routes: { controller: :project_members },
item_id: :members,
container_html_options: {
diff --git a/lib/sidebars/projects/menus/repository_menu.rb b/lib/sidebars/projects/menus/repository_menu.rb
index ec91ae741fe..158a29f0b31 100644
--- a/lib/sidebars/projects/menus/repository_menu.rb
+++ b/lib/sidebars/projects/menus/repository_menu.rb
@@ -44,6 +44,11 @@ module Sidebars
'doc-text'
end
+ override :pick_into_super_sidebar?
+ def pick_into_super_sidebar?
+ true
+ end
+
private
def files_menu_item
@@ -92,7 +97,7 @@ module Sidebars
link = project_graph_path(context.project, context.current_ref, ref_type: ref_type_from_context(context))
::Sidebars::MenuItem.new(
- title: _('Contributors'),
+ title: _('Contributor statistics'),
link: link,
active_routes: { path: 'graphs#show' },
item_id: :contributors
@@ -112,7 +117,7 @@ module Sidebars
def compare_menu_item
::Sidebars::MenuItem.new(
- title: _('Compare'),
+ title: _('Compare revisions'),
link: project_compare_index_path(context.project, from: context.project.repository.root_ref, to: context.current_ref),
active_routes: { controller: :compare },
item_id: :compare
diff --git a/lib/sidebars/projects/menus/scope_menu.rb b/lib/sidebars/projects/menus/scope_menu.rb
index 35502c7ea09..7e2286633e5 100644
--- a/lib/sidebars/projects/menus/scope_menu.rb
+++ b/lib/sidebars/projects/menus/scope_menu.rb
@@ -39,6 +39,16 @@ module Sidebars
def render?
true
end
+
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ super.merge({
+ title: _('Project overview'),
+ sprite_icon: 'project',
+ super_sidebar_parent: ::Sidebars::StaticMenu,
+ item_id: :project_overview
+ })
+ end
end
end
end
diff --git a/lib/sidebars/projects/menus/security_compliance_menu.rb b/lib/sidebars/projects/menus/security_compliance_menu.rb
index 9367514cdca..eb713244a7c 100644
--- a/lib/sidebars/projects/menus/security_compliance_menu.rb
+++ b/lib/sidebars/projects/menus/security_compliance_menu.rb
@@ -17,7 +17,7 @@ module Sidebars
override :title
def title
- _('Security & Compliance')
+ _('Security and Compliance')
end
override :sprite_icon
@@ -25,6 +25,11 @@ module Sidebars
'shield'
end
+ override :pick_into_super_sidebar?
+ def pick_into_super_sidebar?
+ true
+ end
+
private
def configuration_menu_item
@@ -33,7 +38,7 @@ module Sidebars
end
::Sidebars::MenuItem.new(
- title: _('Configuration'),
+ title: _('Security configuration'),
link: project_security_configuration_path(context.project),
active_routes: { path: configuration_menu_item_paths },
item_id: :configuration
diff --git a/lib/sidebars/projects/menus/settings_menu.rb b/lib/sidebars/projects/menus/settings_menu.rb
index eea32d8b626..8b6d85e718d 100644
--- a/lib/sidebars/projects/menus/settings_menu.rb
+++ b/lib/sidebars/projects/menus/settings_menu.rb
@@ -44,6 +44,11 @@ module Sidebars
'settings'
end
+ override :pick_into_super_sidebar?
+ def pick_into_super_sidebar?
+ true
+ end
+
private
def general_menu_item
diff --git a/lib/sidebars/projects/menus/snippets_menu.rb b/lib/sidebars/projects/menus/snippets_menu.rb
index 060341b3c51..535f12963b1 100644
--- a/lib/sidebars/projects/menus/snippets_menu.rb
+++ b/lib/sidebars/projects/menus/snippets_menu.rb
@@ -35,6 +35,15 @@ module Sidebars
def active_routes
{ controller: :snippets }
end
+
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ super.deep_merge({
+ super_sidebar_parent: ::Sidebars::Projects::Menus::RepositoryMenu,
+ super_sidebar_before: :contributors,
+ item_id: :project_snippets
+ })
+ end
end
end
end
diff --git a/lib/sidebars/projects/menus/wiki_menu.rb b/lib/sidebars/projects/menus/wiki_menu.rb
index 3980b193fd1..d800dae8be3 100644
--- a/lib/sidebars/projects/menus/wiki_menu.rb
+++ b/lib/sidebars/projects/menus/wiki_menu.rb
@@ -35,6 +35,14 @@ module Sidebars
def active_routes
{ controller: :wikis }
end
+
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ super.merge({
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::PlanMenu,
+ item_id: :project_wiki
+ })
+ end
end
end
end
diff --git a/lib/sidebars/projects/panel.rb b/lib/sidebars/projects/panel.rb
index 9d0f5eb87bd..5d8bc18ac88 100644
--- a/lib/sidebars/projects/panel.rb
+++ b/lib/sidebars/projects/panel.rb
@@ -34,14 +34,6 @@ module Sidebars
add_wiki_menus
add_menu(Sidebars::Projects::Menus::SnippetsMenu.new(context))
add_menu(Sidebars::Projects::Menus::SettingsMenu.new(context))
- add_invite_members_menu
- end
-
- def add_invite_members_menu
- experiment(:invite_members_in_side_nav, group: context.project.group) do |e|
- e.control {}
- e.candidate { add_menu(Sidebars::Projects::Menus::InviteTeamMembersMenu.new(context)) }
- end
end
def add_wiki_menus
diff --git a/lib/sidebars/projects/super_sidebar_menus/operations_menu.rb b/lib/sidebars/projects/super_sidebar_menus/operations_menu.rb
new file mode 100644
index 00000000000..5490aac5a65
--- /dev/null
+++ b/lib/sidebars/projects/super_sidebar_menus/operations_menu.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module SuperSidebarMenus
+ class OperationsMenu < ::Sidebars::Menu
+ override :title
+ def title
+ _('Operations')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'deployments'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/super_sidebar_menus/plan_menu.rb b/lib/sidebars/projects/super_sidebar_menus/plan_menu.rb
new file mode 100644
index 00000000000..ae9b2d826b7
--- /dev/null
+++ b/lib/sidebars/projects/super_sidebar_menus/plan_menu.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module SuperSidebarMenus
+ class PlanMenu < ::Sidebars::Menu
+ override :title
+ def title
+ _('Plan')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'planning'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/super_sidebar_panel.rb b/lib/sidebars/projects/super_sidebar_panel.rb
new file mode 100644
index 00000000000..f76f28eb642
--- /dev/null
+++ b/lib/sidebars/projects/super_sidebar_panel.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ class SuperSidebarPanel < ::Sidebars::Projects::Panel
+ include ::Sidebars::Concerns::SuperSidebarPanel
+ extend ::Gitlab::Utils::Override
+
+ override :configure_menus
+ def configure_menus
+ super
+ old_menus = @menus
+ @menus = []
+
+ add_menu(Sidebars::StaticMenu.new(context))
+ add_menu(Sidebars::Projects::SuperSidebarMenus::PlanMenu.new(context))
+
+ pick_from_old_menus(old_menus)
+
+ insert_menu_before(
+ Sidebars::Projects::Menus::MonitorMenu,
+ Sidebars::Projects::SuperSidebarMenus::OperationsMenu.new(context)
+ )
+
+ insert_menu_before(
+ Sidebars::Projects::Menus::SettingsMenu,
+ Sidebars::UncategorizedMenu.new(context)
+ )
+
+ transform_old_menus(@menus, @scope_menu, *old_menus)
+ end
+
+ override :super_sidebar_context_header
+ def super_sidebar_context_header
+ {
+ title: context.project.name,
+ avatar: context.project.avatar_url,
+ id: context.project.id
+ }
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/static_menu.rb b/lib/sidebars/static_menu.rb
new file mode 100644
index 00000000000..b7ba69b1717
--- /dev/null
+++ b/lib/sidebars/static_menu.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Sidebars
+ # This is a special menu which does not serialize as
+ # a section and instead hoists all of menu items
+ # to be top-level items
+ class StaticMenu < ::Sidebars::Menu
+ override :serialize_for_super_sidebar
+ def serialize_for_super_sidebar
+ serialize_items_for_super_sidebar
+ end
+ end
+end
diff --git a/lib/sidebars/uncategorized_menu.rb b/lib/sidebars/uncategorized_menu.rb
new file mode 100644
index 00000000000..dc9ed8308fa
--- /dev/null
+++ b/lib/sidebars/uncategorized_menu.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sidebars
+ # This Menu is a temporary help while we implement the new menu
+ # categories for everything. Once every Menu Item is categorized,
+ # we can remove this. This should be done before the Super Sidebar
+ # moves out of Alpha.
+ class UncategorizedMenu < ::Sidebars::Menu
+ override :title
+ def title
+ _('Uncategorized')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'question'
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/base_menu.rb b/lib/sidebars/user_profile/base_menu.rb
new file mode 100644
index 00000000000..5594d7c3c65
--- /dev/null
+++ b/lib/sidebars/user_profile/base_menu.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ class BaseMenu < ::Sidebars::Menu
+ override :render?
+ def render?
+ can?(context.current_user, :read_user_profile, context.container)
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/menus/activity_menu.rb b/lib/sidebars/user_profile/menus/activity_menu.rb
new file mode 100644
index 00000000000..95e99a3dcbc
--- /dev/null
+++ b/lib/sidebars/user_profile/menus/activity_menu.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ module Menus
+ class ActivityMenu < ::Sidebars::UserProfile::BaseMenu
+ override :link
+ def link
+ user_activity_path(context.container)
+ end
+
+ override :title
+ def title
+ s_('UserProfile|Activity')
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'users#activity' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/menus/contributed_projects_menu.rb b/lib/sidebars/user_profile/menus/contributed_projects_menu.rb
new file mode 100644
index 00000000000..0644982a143
--- /dev/null
+++ b/lib/sidebars/user_profile/menus/contributed_projects_menu.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ module Menus
+ class ContributedProjectsMenu < ::Sidebars::UserProfile::BaseMenu
+ override :link
+ def link
+ user_contributed_projects_path(context.container)
+ end
+
+ override :title
+ def title
+ s_('UserProfile|Contributed projects')
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'users#contributed' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/menus/followers_menu.rb b/lib/sidebars/user_profile/menus/followers_menu.rb
new file mode 100644
index 00000000000..53411c21a86
--- /dev/null
+++ b/lib/sidebars/user_profile/menus/followers_menu.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ module Menus
+ class FollowersMenu < ::Sidebars::UserProfile::BaseMenu
+ include Gitlab::Utils::StrongMemoize
+
+ override :link
+ def link
+ user_followers_path(context.container)
+ end
+
+ override :title
+ def title
+ s_('UserProfile|Followers')
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'users#followers' }
+ end
+
+ override :has_pill?
+ def has_pill?
+ context.container.followers.any?
+ end
+ strong_memoize_attr :has_pill?
+
+ override :pill_count
+ def pill_count
+ context.container.followers.count
+ end
+ strong_memoize_attr :pill_count
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/menus/following_menu.rb b/lib/sidebars/user_profile/menus/following_menu.rb
new file mode 100644
index 00000000000..5da76a0100a
--- /dev/null
+++ b/lib/sidebars/user_profile/menus/following_menu.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ module Menus
+ class FollowingMenu < ::Sidebars::UserProfile::BaseMenu
+ include Gitlab::Utils::StrongMemoize
+
+ override :link
+ def link
+ user_following_path(context.container)
+ end
+
+ override :title
+ def title
+ s_('UserProfile|Following')
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'users#following' }
+ end
+
+ override :has_pill?
+ def has_pill?
+ context.container.followees.any?
+ end
+ strong_memoize_attr :has_pill?
+
+ override :pill_count
+ def pill_count
+ context.container.followees.count
+ end
+ strong_memoize_attr :pill_count
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/menus/groups_menu.rb b/lib/sidebars/user_profile/menus/groups_menu.rb
new file mode 100644
index 00000000000..38c2c3f042d
--- /dev/null
+++ b/lib/sidebars/user_profile/menus/groups_menu.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ module Menus
+ class GroupsMenu < ::Sidebars::UserProfile::BaseMenu
+ override :link
+ def link
+ user_groups_path(context.container)
+ end
+
+ override :title
+ def title
+ s_('UserProfile|Groups')
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'users#groups' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/menus/overview_menu.rb b/lib/sidebars/user_profile/menus/overview_menu.rb
new file mode 100644
index 00000000000..ebf184e7e4e
--- /dev/null
+++ b/lib/sidebars/user_profile/menus/overview_menu.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ module Menus
+ class OverviewMenu < ::Sidebars::UserProfile::BaseMenu
+ override :link
+ def link
+ user_path(context.container)
+ end
+
+ override :title
+ def title
+ s_('UserProfile|Overview')
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'users#show' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/menus/personal_projects_menu.rb b/lib/sidebars/user_profile/menus/personal_projects_menu.rb
new file mode 100644
index 00000000000..14fcddf2cc2
--- /dev/null
+++ b/lib/sidebars/user_profile/menus/personal_projects_menu.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ module Menus
+ class PersonalProjectsMenu < ::Sidebars::UserProfile::BaseMenu
+ override :link
+ def link
+ user_projects_path(context.container)
+ end
+
+ override :title
+ def title
+ s_('UserProfile|Personal projects')
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'users#projects' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/menus/snippets_menu.rb b/lib/sidebars/user_profile/menus/snippets_menu.rb
new file mode 100644
index 00000000000..a8e5077098c
--- /dev/null
+++ b/lib/sidebars/user_profile/menus/snippets_menu.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ module Menus
+ class SnippetsMenu < ::Sidebars::UserProfile::BaseMenu
+ override :link
+ def link
+ user_snippets_path(context.container)
+ end
+
+ override :title
+ def title
+ s_('UserProfile|Snippets')
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'users#snippets' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/menus/starred_projects_menu.rb b/lib/sidebars/user_profile/menus/starred_projects_menu.rb
new file mode 100644
index 00000000000..762b451f4a1
--- /dev/null
+++ b/lib/sidebars/user_profile/menus/starred_projects_menu.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ module Menus
+ class StarredProjectsMenu < ::Sidebars::UserProfile::BaseMenu
+ override :link
+ def link
+ user_starred_projects_path(context.container)
+ end
+
+ override :title
+ def title
+ s_('UserProfile|Starred projects')
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'users#starred' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_profile/panel.rb b/lib/sidebars/user_profile/panel.rb
new file mode 100644
index 00000000000..9a595fdf64c
--- /dev/null
+++ b/lib/sidebars/user_profile/panel.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserProfile
+ class Panel < ::Sidebars::Panel
+ include UsersHelper
+
+ override :configure_menus
+ def configure_menus
+ add_menus
+ end
+
+ override :aria_label
+ def aria_label
+ s_('UserProfile|User profile navigation')
+ end
+
+ override :super_sidebar_context_header
+ def super_sidebar_context_header
+ @super_sidebar_context_header ||= {
+ title: user_name,
+ avatar: context.container.avatar_url,
+ avatar_shape: 'circle'
+ }
+ end
+
+ private
+
+ def user
+ context.container
+ end
+
+ def user_name
+ return user_display_name(user) if user.blocked? || !user.confirmed?
+
+ user.name
+ end
+
+ def add_menus
+ add_menu(Sidebars::UserProfile::Menus::OverviewMenu.new(context))
+ add_menu(Sidebars::UserProfile::Menus::ActivityMenu.new(context))
+ add_menu(Sidebars::UserProfile::Menus::GroupsMenu.new(context))
+ add_menu(Sidebars::UserProfile::Menus::ContributedProjectsMenu.new(context))
+ add_menu(Sidebars::UserProfile::Menus::PersonalProjectsMenu.new(context))
+ add_menu(Sidebars::UserProfile::Menus::StarredProjectsMenu.new(context))
+ add_menu(Sidebars::UserProfile::Menus::SnippetsMenu.new(context))
+ add_menu(Sidebars::UserProfile::Menus::FollowersMenu.new(context))
+ add_menu(Sidebars::UserProfile::Menus::FollowingMenu.new(context))
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/access_tokens_menu.rb b/lib/sidebars/user_settings/menus/access_tokens_menu.rb
new file mode 100644
index 00000000000..f52be22e044
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/access_tokens_menu.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class AccessTokensMenu < ::Sidebars::Menu
+ override :link
+ def link
+ profile_personal_access_tokens_path
+ end
+
+ override :title
+ def title
+ _('Access Tokens')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'token'
+ end
+
+ override :render?
+ def render?
+ !!context.current_user && !Gitlab::CurrentSettings.personal_access_tokens_disabled?
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :personal_access_tokens }
+ end
+
+ override :extra_container_html_options
+ def extra_container_html_options
+ { 'data-qa-selector': 'access_token_link' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/account_menu.rb b/lib/sidebars/user_settings/menus/account_menu.rb
new file mode 100644
index 00000000000..a26dee83da3
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/account_menu.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class AccountMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ profile_account_path
+ end
+
+ override :title
+ def title
+ _('Account')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'account'
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: [:accounts, :two_factor_auths] }
+ end
+
+ override :extra_container_html_options
+ def extra_container_html_options
+ { 'data-qa-selector': 'profile_account_link' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/active_sessions_menu.rb b/lib/sidebars/user_settings/menus/active_sessions_menu.rb
new file mode 100644
index 00000000000..f806c04e77c
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/active_sessions_menu.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class ActiveSessionsMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ profile_active_sessions_path
+ end
+
+ override :title
+ def title
+ _('Active Sessions')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'monitor-lines'
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :active_sessions }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/applications_menu.rb b/lib/sidebars/user_settings/menus/applications_menu.rb
new file mode 100644
index 00000000000..c71f9a9660b
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/applications_menu.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class ApplicationsMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ applications_profile_path
+ end
+
+ override :title
+ def title
+ _('Applications')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'applications'
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: 'oauth/applications' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/authentication_log_menu.rb b/lib/sidebars/user_settings/menus/authentication_log_menu.rb
new file mode 100644
index 00000000000..c5a27acf1fd
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/authentication_log_menu.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class AuthenticationLogMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ audit_log_profile_path
+ end
+
+ override :title
+ def title
+ _('Authentication Log')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'log'
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'profiles#audit_log' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/chat_menu.rb b/lib/sidebars/user_settings/menus/chat_menu.rb
new file mode 100644
index 00000000000..54795c29b3f
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/chat_menu.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class ChatMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ profile_chat_names_path
+ end
+
+ override :title
+ def title
+ _('Chat')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'comment'
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :chat_names }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/emails_menu.rb b/lib/sidebars/user_settings/menus/emails_menu.rb
new file mode 100644
index 00000000000..3b6b4ae1daf
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/emails_menu.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class EmailsMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ profile_emails_path
+ end
+
+ override :title
+ def title
+ _('Emails')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'mail'
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :emails }
+ end
+
+ override :extra_container_html_options
+ def extra_container_html_options
+ { 'data-qa-selector': 'profile_emails_link' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/gpg_keys_menu.rb b/lib/sidebars/user_settings/menus/gpg_keys_menu.rb
new file mode 100644
index 00000000000..89e447aa277
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/gpg_keys_menu.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class GpgKeysMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ profile_gpg_keys_path
+ end
+
+ override :title
+ def title
+ _('GPG Keys')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'key'
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :gpg_keys }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/notifications_menu.rb b/lib/sidebars/user_settings/menus/notifications_menu.rb
new file mode 100644
index 00000000000..f7ea0de0cc9
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/notifications_menu.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class NotificationsMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ profile_notifications_path
+ end
+
+ override :title
+ def title
+ _('Notifications')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'notifications'
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :notifications }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/password_menu.rb b/lib/sidebars/user_settings/menus/password_menu.rb
new file mode 100644
index 00000000000..9a53e0c727e
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/password_menu.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class PasswordMenu < ::Sidebars::Menu
+ override :link
+ def link
+ edit_profile_password_path
+ end
+
+ override :title
+ def title
+ _('Password')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'lock'
+ end
+
+ override :render?
+ def render?
+ !!context.current_user&.allow_password_authentication?
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :passwords }
+ end
+
+ override :extra_container_html_options
+ def extra_container_html_options
+ { 'data-qa-selector': 'profile_password_link' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/preferences_menu.rb b/lib/sidebars/user_settings/menus/preferences_menu.rb
new file mode 100644
index 00000000000..b6b94ec1ad9
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/preferences_menu.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class PreferencesMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ profile_preferences_path
+ end
+
+ override :title
+ def title
+ _('Preferences')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'preferences'
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :preferences }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/profile_menu.rb b/lib/sidebars/user_settings/menus/profile_menu.rb
new file mode 100644
index 00000000000..73119070586
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/profile_menu.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class ProfileMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ profile_path
+ end
+
+ override :title
+ def title
+ _('Profile')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'profile'
+ end
+
+ override :active_routes
+ def active_routes
+ { path: 'profiles#show' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/saved_replies_menu.rb b/lib/sidebars/user_settings/menus/saved_replies_menu.rb
new file mode 100644
index 00000000000..25c8b2f8eb2
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/saved_replies_menu.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class SavedRepliesMenu < ::Sidebars::Menu
+ include UsersHelper
+
+ override :link
+ def link
+ profile_saved_replies_path
+ end
+
+ override :title
+ def title
+ _('Saved Replies')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'symlink'
+ end
+
+ override :render?
+ def render?
+ !!context.current_user && saved_replies_enabled?
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :saved_replies }
+ end
+
+ private
+
+ def current_user
+ context.current_user
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/menus/ssh_keys_menu.rb b/lib/sidebars/user_settings/menus/ssh_keys_menu.rb
new file mode 100644
index 00000000000..8d92db0147a
--- /dev/null
+++ b/lib/sidebars/user_settings/menus/ssh_keys_menu.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ module Menus
+ class SshKeysMenu < ::Sidebars::Menu
+ include ::Sidebars::Concerns::RenderIfLoggedIn
+
+ override :link
+ def link
+ profile_keys_path
+ end
+
+ override :title
+ def title
+ _('SSH Keys')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'key'
+ end
+
+ override :active_routes
+ def active_routes
+ { controller: :keys }
+ end
+
+ override :extra_container_html_options
+ def extra_container_html_options
+ { 'data-qa-selector': 'ssh_keys_link' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/user_settings/panel.rb b/lib/sidebars/user_settings/panel.rb
new file mode 100644
index 00000000000..14a52a8fb23
--- /dev/null
+++ b/lib/sidebars/user_settings/panel.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module UserSettings
+ class Panel < ::Sidebars::Panel
+ override :configure_menus
+ def configure_menus
+ add_menus
+ end
+
+ override :aria_label
+ def aria_label
+ _('User settings')
+ end
+
+ override :render_raw_scope_menu_partial
+ def render_raw_scope_menu_partial
+ "shared/nav/user_settings_scope_header"
+ end
+
+ override :super_sidebar_context_header
+ def super_sidebar_context_header
+ @super_sidebar_context_header ||= {
+ title: aria_label,
+ avatar: context.current_user.avatar_url
+ }
+ end
+
+ private
+
+ def add_menus
+ add_menu(Sidebars::UserSettings::Menus::ProfileMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::AccountMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::ApplicationsMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::ChatMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::AccessTokensMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::EmailsMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::PasswordMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::NotificationsMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::SshKeysMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::GpgKeysMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::PreferencesMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::SavedRepliesMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::ActiveSessionsMenu.new(context))
+ add_menu(Sidebars::UserSettings::Menus::AuthenticationLogMenu.new(context))
+ end
+ end
+ end
+end
+
+Sidebars::UserSettings::Panel.prepend_mod_with('Sidebars::UserSettings::Panel')
diff --git a/lib/sidebars/your_work/panel.rb b/lib/sidebars/your_work/panel.rb
index 215a2a2da09..5f917976872 100644
--- a/lib/sidebars/your_work/panel.rb
+++ b/lib/sidebars/your_work/panel.rb
@@ -18,6 +18,14 @@ module Sidebars
"shared/nav/your_work_scope_header"
end
+ override :super_sidebar_context_header
+ def super_sidebar_context_header
+ @super_sidebar_context_header ||= {
+ title: aria_label,
+ icon: 'work'
+ }
+ end
+
private
def add_menus
@@ -33,3 +41,4 @@ module Sidebars
end
end
end
+Sidebars::YourWork::Panel.prepend_mod_with('Sidebars::YourWork::Panel')