Commit 2a957f68 authored by Sean McGivern's avatar Sean McGivern

Merge branch 'master' into issue_928_group_boards

parents 2538fab9 eca1fdc3
...@@ -531,6 +531,7 @@ import initGroupAnalytics from './init_group_analytics'; ...@@ -531,6 +531,7 @@ import initGroupAnalytics from './init_group_analytics';
break; break;
case 'search:show': case 'search:show':
new Search(); new Search();
new UserCallout();
break; break;
case 'projects:mirrors:show': case 'projects:mirrors:show':
case 'projects:mirrors:update': case 'projects:mirrors:update':
......
...@@ -20,8 +20,10 @@ let headerHeight = 50; ...@@ -20,8 +20,10 @@ let headerHeight = 50;
export const getHeaderHeight = () => headerHeight; export const getHeaderHeight = () => headerHeight;
export const isSidebarCollapsed = () => sidebar && sidebar.classList.contains('sidebar-icons-only');
export const canShowActiveSubItems = (el) => { export const canShowActiveSubItems = (el) => {
if (el.classList.contains('active') && (sidebar && !sidebar.classList.contains('sidebar-icons-only'))) { if (el.classList.contains('active') && !isSidebarCollapsed()) {
return false; return false;
} }
...@@ -99,12 +101,13 @@ export const moveSubItemsToPosition = (el, subItems) => { ...@@ -99,12 +101,13 @@ export const moveSubItemsToPosition = (el, subItems) => {
export const showSubLevelItems = (el) => { export const showSubLevelItems = (el) => {
const subItems = el.querySelector('.sidebar-sub-level-items'); const subItems = el.querySelector('.sidebar-sub-level-items');
const isIconOnly = subItems && subItems.classList.contains('is-fly-out-only');
if (!canShowSubItems() || !canShowActiveSubItems(el)) return; if (!canShowSubItems() || !canShowActiveSubItems(el)) return;
el.classList.add(IS_OVER_CLASS); el.classList.add(IS_OVER_CLASS);
if (!subItems) return; if (!subItems || (!isSidebarCollapsed() && isIconOnly)) return;
subItems.style.display = 'block'; subItems.style.display = 'block';
el.classList.add(IS_SHOWING_FLY_OUT_CLASS); el.classList.add(IS_SHOWING_FLY_OUT_CLASS);
......
...@@ -74,7 +74,7 @@ class Issue { ...@@ -74,7 +74,7 @@ class Issue {
this.toggleCloseReopenButton(isClosed); this.toggleCloseReopenButton(isClosed);
let numProjectIssues = Number(projectIssuesCounter.text().replace(/[^\d]/, '')); let numProjectIssues = Number(projectIssuesCounter.first().text().trim().replace(/[^\d]/, ''));
numProjectIssues = isClosed ? numProjectIssues - 1 : numProjectIssues + 1; numProjectIssues = isClosed ? numProjectIssues - 1 : numProjectIssues + 1;
projectIssuesCounter.text(gl.text.addDelimiter(numProjectIssues)); projectIssuesCounter.text(gl.text.addDelimiter(numProjectIssues));
......
...@@ -393,13 +393,3 @@ header.navbar-gitlab-new { ...@@ -393,13 +393,3 @@ header.navbar-gitlab-new {
color: $gl-text-color; color: $gl-text-color;
} }
} }
.top-area {
.nav-controls-new-nav {
.dropdown {
@media (min-width: $screen-sm-min) {
margin-right: 0;
}
}
}
}
...@@ -106,11 +106,8 @@ $new-sidebar-collapsed-width: 50px; ...@@ -106,11 +106,8 @@ $new-sidebar-collapsed-width: 50px;
overflow-x: hidden; overflow-x: hidden;
} }
.badge, .badge:not(.fly-out-badge),
.sidebar-context-title { .sidebar-context-title,
display: none;
}
.nav-item-name { .nav-item-name {
display: none; display: none;
} }
...@@ -118,6 +115,10 @@ $new-sidebar-collapsed-width: 50px; ...@@ -118,6 +115,10 @@ $new-sidebar-collapsed-width: 50px;
.sidebar-top-level-items > li > a { .sidebar-top-level-items > li > a {
min-height: 44px; min-height: 44px;
} }
.fly-out-top-item {
display: block;
}
} }
&.nav-sidebar-expanded { &.nav-sidebar-expanded {
...@@ -179,6 +180,10 @@ $new-sidebar-collapsed-width: 50px; ...@@ -179,6 +180,10 @@ $new-sidebar-collapsed-width: 50px;
width: 16px; width: 16px;
} }
} }
.fly-out-top-item {
display: none;
}
} }
.nav-sidebar-inner-scroll { .nav-sidebar-inner-scroll {
...@@ -249,7 +254,7 @@ $new-sidebar-collapsed-width: 50px; ...@@ -249,7 +254,7 @@ $new-sidebar-collapsed-width: 50px;
left: $new-sidebar-width; left: $new-sidebar-width;
min-width: 150px; min-width: 150px;
margin-top: -1px; margin-top: -1px;
padding: 8px 1px; padding: 4px 1px;
background-color: $white-light; background-color: $white-light;
box-shadow: 2px 1px 3px $dropdown-shadow-color; box-shadow: 2px 1px 3px $dropdown-shadow-color;
border: 1px solid $gray-darker; border: 1px solid $gray-darker;
...@@ -270,6 +275,13 @@ $new-sidebar-collapsed-width: 50px; ...@@ -270,6 +275,13 @@ $new-sidebar-collapsed-width: 50px;
margin-top: 1px; margin-top: 1px;
} }
.divider {
height: 1px;
margin: 4px -1px;
padding: 0;
background-color: $dropdown-divider-color;
}
> .active { > .active {
box-shadow: none; box-shadow: none;
...@@ -309,7 +321,7 @@ $new-sidebar-collapsed-width: 50px; ...@@ -309,7 +321,7 @@ $new-sidebar-collapsed-width: 50px;
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
} }
.sidebar-sub-level-items { .sidebar-sub-level-items:not(.is-fly-out-only) {
display: block; display: block;
} }
} }
...@@ -403,6 +415,19 @@ $new-sidebar-collapsed-width: 50px; ...@@ -403,6 +415,19 @@ $new-sidebar-collapsed-width: 50px;
} }
} }
.fly-out-top-item {
> a {
display: flex;
}
.fly-out-badge {
margin-left: 8px;
}
}
.fly-out-top-item-name {
flex: 1;
}
// Mobile nav // Mobile nav
......
...@@ -46,6 +46,30 @@ ...@@ -46,6 +46,30 @@
margin-top: 56px; margin-top: 56px;
} }
.user-callout.promotion-callout.promotion-advanced-search {
margin: 0;
border-bottom: solid 1px $border-color;
h5 {
margin-top: 0;
}
.bordered-box.content-block {
border: none;
padding: 20px 0;
justify-content: left;
svg {
height: auto;
}
}
.user-callout-copy {
margin-left: 0;
}
}
.promotion-modal { .promotion-modal {
.modal-dialog { .modal-dialog {
......
...@@ -91,5 +91,9 @@ module LicenseHelper ...@@ -91,5 +91,9 @@ module LicenseHelper
!@project.feature_available?(project_feature) && show_promotions? && (callout_id.nil? || show_callout?(callout_id)) !@project.feature_available?(project_feature) && show_promotions? && (callout_id.nil? || show_callout?(callout_id))
end end
def show_advanced_search_promotion?
!current_application_settings.should_check_namespace_plan? && show_promotions? && show_callout?('promote_advanced_search_dismissed') && !License.feature_available?(:elastic_search)
end
extend self extend self
end end
- if current_user.can_create_group?
- content_for :breadcrumbs_extra do
= link_to "New group", new_group_path, class: "btn btn-new"
.top-area .top-area
%ul.nav-links %ul.nav-links
= nav_link(page: dashboard_groups_path) do = nav_link(page: dashboard_groups_path) do
...@@ -10,8 +6,8 @@ ...@@ -10,8 +6,8 @@
= nav_link(page: explore_groups_path) do = nav_link(page: explore_groups_path) do
= link_to explore_groups_path, title: 'Explore public groups' do = link_to explore_groups_path, title: 'Explore public groups' do
Explore public groups Explore public groups
.nav-controls.nav-controls-new-nav .nav-controls
= render 'shared/groups/search_form' = render 'shared/groups/search_form'
= render 'shared/groups/dropdown' = render 'shared/groups/dropdown'
- if current_user.can_create_group? - if current_user.can_create_group?
= link_to "New group", new_group_path, class: "btn btn-new visible-xs" = link_to "New group", new_group_path, class: "btn btn-new"
= content_for :flash_message do = content_for :flash_message do
= render 'shared/project_limit' = render 'shared/project_limit'
- if current_user.can_create_project?
- content_for :breadcrumbs_extra do
= link_to "New project", new_project_path, class: 'btn btn-new'
.top-area.scrolling-tabs-container.inner-page-scroll-tabs .top-area.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left= icon('angle-left') .fade-left= icon('angle-left')
.fade-right= icon('angle-right') .fade-right= icon('angle-right')
...@@ -19,8 +15,8 @@ ...@@ -19,8 +15,8 @@
= link_to explore_root_path, title: 'Explore', data: {placement: 'right'} do = link_to explore_root_path, title: 'Explore', data: {placement: 'right'} do
Explore projects Explore projects
.nav-controls.nav-controls-new-nav .nav-controls
= render 'shared/projects/search_form' = render 'shared/projects/search_form'
= render 'shared/projects/dropdown' = render 'shared/projects/dropdown'
- if current_user.can_create_project? - if current_user.can_create_project?
= link_to "New project", new_project_path, class: "btn btn-new visible-xs" = link_to "New project", new_project_path, class: "btn btn-new"
- if current_user
- content_for :breadcrumbs_extra do
= link_to "New snippet", new_snippet_path, class: "btn btn-new", title: "New snippet"
.top-area .top-area
%ul.nav-links %ul.nav-links
= nav_link(page: dashboard_snippets_path, html_options: {class: 'home'}) do = nav_link(page: dashboard_snippets_path, html_options: {class: 'home'}) do
...@@ -10,3 +6,7 @@ ...@@ -10,3 +6,7 @@
= nav_link(page: explore_snippets_path) do = nav_link(page: explore_snippets_path) do
= link_to explore_snippets_path, title: 'Explore snippets', data: {placement: 'right'} do = link_to explore_snippets_path, title: 'Explore snippets', data: {placement: 'right'} do
Explore Snippets Explore Snippets
- if current_user
.nav-controls.hidden-xs
= link_to "New snippet", new_snippet_path, class: "btn btn-new", title: "New snippet"
...@@ -4,14 +4,9 @@ ...@@ -4,14 +4,9 @@
= content_for :meta_tags do = content_for :meta_tags do
= auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{current_user.name} issues") = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{current_user.name} issues")
- content_for :breadcrumbs_extra do
= link_to params.merge(rss_url_options), class: 'btn has-tooltip append-right-10', title: 'Subscribe' do
= icon('rss')
= render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues', type: :issues
.top-area .top-area
= render 'shared/issuable/nav', type: :issues = render 'shared/issuable/nav', type: :issues
.nav-controls.visible-xs .nav-controls
= link_to params.merge(rss_url_options), class: 'btn has-tooltip', title: 'Subscribe' do = link_to params.merge(rss_url_options), class: 'btn has-tooltip', title: 'Subscribe' do
= icon('rss') = icon('rss')
= render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues', type: :issues = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues', type: :issues
......
...@@ -2,12 +2,9 @@ ...@@ -2,12 +2,9 @@
- page_title "Merge Requests" - page_title "Merge Requests"
- header_title "Merge Requests", merge_requests_dashboard_path(assignee_id: current_user.id) - header_title "Merge Requests", merge_requests_dashboard_path(assignee_id: current_user.id)
- content_for :breadcrumbs_extra do
= render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", with_feature_enabled: 'merge_requests', type: :merge_requests
.top-area .top-area
= render 'shared/issuable/nav', type: :merge_requests = render 'shared/issuable/nav', type: :merge_requests
.nav-controls.visible-xs .nav-controls
= render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", with_feature_enabled: 'merge_requests', type: :merge_requests = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", with_feature_enabled: 'merge_requests', type: :merge_requests
= render 'shared/issuable/filter', type: :merge_requests = render 'shared/issuable/filter', type: :merge_requests
......
...@@ -2,13 +2,10 @@ ...@@ -2,13 +2,10 @@
- page_title 'Milestones' - page_title 'Milestones'
- header_title 'Milestones', dashboard_milestones_path - header_title 'Milestones', dashboard_milestones_path
- content_for :breadcrumbs_extra do
= render 'shared/new_project_item_select', path: 'milestones/new', label: 'New milestone', include_groups: true, type: :milestones
.top-area .top-area
= render 'shared/milestones_filter', counts: @milestone_states = render 'shared/milestones_filter', counts: @milestone_states
.nav-controls.visible-xs .nav-controls
= render 'shared/new_project_item_select', path: 'milestones/new', label: 'New milestone', include_groups: true, type: :milestones = render 'shared/new_project_item_select', path: 'milestones/new', label: 'New milestone', include_groups: true, type: :milestones
.milestones .milestones
......
...@@ -9,18 +9,10 @@ ...@@ -9,18 +9,10 @@
= webpack_bundle_tag 'filtered_search' = webpack_bundle_tag 'filtered_search'
= webpack_bundle_tag 'issues' = webpack_bundle_tag 'issues'
- if group_issues_exists
- content_for :breadcrumbs_extra do
= link_to params.merge(rss_url_options), class: 'btn btn-default append-right-10' do
= icon('rss')
%span.icon-label
Subscribe
= render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues
- if group_issues_exists - if group_issues_exists
.top-area .top-area
= render 'shared/issuable/nav', type: :issues = render 'shared/issuable/nav', type: :issues
.nav-controls.visible-xs .nav-controls
= link_to params.merge(rss_url_options), class: 'btn' do = link_to params.merge(rss_url_options), class: 'btn' do
= icon('rss') = icon('rss')
%span.icon-label %span.icon-label
......
- page_title 'Labels' - page_title 'Labels'
- if can?(current_user, :admin_label, @group)
- content_for :breadcrumbs_extra do
= link_to "New label", new_group_label_path(@group), class: "btn btn-new"
= render "groups/head_issues" = render "groups/head_issues"
...@@ -10,7 +7,7 @@ ...@@ -10,7 +7,7 @@
.nav-text .nav-text
Labels can be applied to issues and merge requests. Group labels are available for any project within the group. Labels can be applied to issues and merge requests. Group labels are available for any project within the group.
.nav-controls.visible-xs .nav-controls
- if can?(current_user, :admin_label, @group) - if can?(current_user, :admin_label, @group)
= link_to "New label", new_group_label_path(@group), class: "btn btn-new" = link_to "New label", new_group_label_path(@group), class: "btn btn-new"
......
...@@ -4,17 +4,13 @@ ...@@ -4,17 +4,13 @@
= webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'common_vue'
= webpack_bundle_tag 'filtered_search' = webpack_bundle_tag 'filtered_search'
- if current_user
- content_for :breadcrumbs_extra do
= render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", type: :merge_requests
- if @group_merge_requests.empty? - if @group_merge_requests.empty?
= render 'shared/empty_states/merge_requests', project_select_button: true = render 'shared/empty_states/merge_requests', project_select_button: true
- else - else
.top-area .top-area
= render 'shared/issuable/nav', type: :merge_requests = render 'shared/issuable/nav', type: :merge_requests
- if current_user - if current_user
.nav-controls.visible-xs .nav-controls
= render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", type: :merge_requests = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", type: :merge_requests
= render 'shared/issuable/search_bar', type: :merge_requests = render 'shared/issuable/search_bar', type: :merge_requests
......
- page_title "Milestones" - page_title "Milestones"
- if can?(current_user, :admin_milestones, @group)
- content_for :breadcrumbs_extra do
= link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new"
= render "groups/head_issues" = render "groups/head_issues"
.top-area .top-area
= render 'shared/milestones_filter', counts: @milestone_states = render 'shared/milestones_filter', counts: @milestone_states
.nav-controls.visible-xs .nav-controls
- if can?(current_user, :admin_milestones, @group) - if can?(current_user, :admin_milestones, @group)
= link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new" = link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new"
......
...@@ -17,6 +17,4 @@ ...@@ -17,6 +17,4 @@
= render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :after = render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :after
%li %li
%h2.breadcrumbs-sub-title= @breadcrumb_title %h2.breadcrumbs-sub-title= @breadcrumb_title
- if content_for?(:breadcrumbs_extra)
.breadcrumbs-extra.hidden-xs= yield :breadcrumbs_extra
= yield :header_content = yield :header_content
...@@ -14,6 +14,11 @@ ...@@ -14,6 +14,11 @@
Overview Overview
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts), html_options: { class: "fly-out-top-item" } ) do
= link_to admin_root_path do
%strong.fly-out-top-item-name
#{ _('Overview') }
%li.divider.fly-out-top-item
= nav_link(controller: :dashboard, html_options: {class: 'home'}) do = nav_link(controller: :dashboard, html_options: {class: 'home'}) do
= link_to admin_root_path, title: 'Overview' do = link_to admin_root_path, title: 'Overview' do
%span %span
...@@ -55,6 +60,11 @@ ...@@ -55,6 +60,11 @@
Monitoring Monitoring
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(controller: %w(conversational_development_index system_info background_jobs logs health_check requests_profiles), html_options: { class: "fly-out-top-item" } ) do
= link_to admin_conversational_development_index_path do
%strong.fly-out-top-item-name
#{ _('Monitoring') }
%li.divider.fly-out-top-item
= nav_link(controller: :system_info) do = nav_link(controller: :system_info) do
= link_to admin_system_info_path, title: 'System Info' do = link_to admin_system_info_path, title: 'System Info' do
%span %span
...@@ -83,6 +93,11 @@ ...@@ -83,6 +93,11 @@
= custom_icon('messages') = custom_icon('messages')
%span.nav-item-name %span.nav-item-name
Messages Messages
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :broadcast_messages, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_broadcast_messages_path do
%strong.fly-out-top-item-name
#{ _('Messages') }
= nav_link(controller: [:hooks, :hook_logs]) do = nav_link(controller: [:hooks, :hook_logs]) do
= sidebar_link admin_hooks_path, title: _('Hooks') do = sidebar_link admin_hooks_path, title: _('Hooks') do
...@@ -90,6 +105,11 @@ ...@@ -90,6 +105,11 @@
= custom_icon('system_hooks') = custom_icon('system_hooks')
%span.nav-item-name %span.nav-item-name
System Hooks System Hooks
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: [:hooks, :hook_logs], html_options: { class: "fly-out-top-item" } ) do
= link_to admin_hooks_path do
%strong.fly-out-top-item-name
#{ _('System Hooks') }
= nav_link(controller: :applications) do = nav_link(controller: :applications) do
= sidebar_link admin_applications_path, title: _('Applications') do = sidebar_link admin_applications_path, title: _('Applications') do
...@@ -97,6 +117,11 @@ ...@@ -97,6 +117,11 @@
= custom_icon('applications') = custom_icon('applications')
%span.nav-item-name %span.nav-item-name
Applications Applications
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :applications, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_applications_path do
%strong.fly-out-top-item-name
#{ _('Applications') }
= nav_link(controller: :abuse_reports) do = nav_link(controller: :abuse_reports) do
= sidebar_link admin_abuse_reports_path, title: _("Abuse Reports") do = sidebar_link admin_abuse_reports_path, title: _("Abuse Reports") do
...@@ -105,6 +130,12 @@ ...@@ -105,6 +130,12 @@
%span.nav-item-name %span.nav-item-name
Abuse Reports Abuse Reports
%span.badge.count= number_with_delimiter(AbuseReport.count(:all)) %span.badge.count= number_with_delimiter(AbuseReport.count(:all))
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :abuse_reports, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_broadcast_messages_path do
%strong.fly-out-top-item-name
#{ _('Abuse Reports') }
%span.badge.count.merge_counter.js-merge-counter.fly-out-badge= number_with_delimiter(AbuseReport.count(:all))
= nav_link(controller: :licenses) do = nav_link(controller: :licenses) do
= sidebar_link admin_license_path, title: _('License') do = sidebar_link admin_license_path, title: _('License') do
...@@ -112,6 +143,11 @@ ...@@ -112,6 +143,11 @@
= custom_icon('license') = custom_icon('license')
%span.nav-item-name %span.nav-item-name
License License
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :licenses, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_license_path do
%strong.fly-out-top-item-name
#{ _('License') }
- if akismet_enabled? - if akismet_enabled?
= nav_link(controller: :spam_logs) do = nav_link(controller: :spam_logs) do
...@@ -120,6 +156,11 @@ ...@@ -120,6 +156,11 @@
= custom_icon('spam_logs') = custom_icon('spam_logs')
%span.nav-item-name %span.nav-item-name
Spam Logs Spam Logs
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :spam_logs, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_spam_logs_path do
%strong.fly-out-top-item-name
#{ _('Spam Logs') }
= nav_link(controller: :push_rules) do = nav_link(controller: :push_rules) do
= sidebar_link admin_push_rule_path, title: _('Push Rules') do = sidebar_link admin_push_rule_path, title: _('Push Rules') do
...@@ -127,6 +168,11 @@ ...@@ -127,6 +168,11 @@
= custom_icon('push_rules') = custom_icon('push_rules')
%span.nav-item-name %span.nav-item-name
Push Rules Push Rules
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :push_rules, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_push_rule_path do
%strong.fly-out-top-item-name
#{ _('Push Rules') }
= nav_link(controller: :geo_nodes) do = nav_link(controller: :geo_nodes) do
= sidebar_link admin_geo_nodes_path, title: _('Geo Nodes') do = sidebar_link admin_geo_nodes_path, title: _('Geo Nodes') do
...@@ -134,6 +180,11 @@ ...@@ -134,6 +180,11 @@
= custom_icon('geo_nodes') = custom_icon('geo_nodes')
%span.nav-item-name %span.nav-item-name
Geo Nodes Geo Nodes
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :geo_nodes, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_geo_nodes_path do
%strong.fly-out-top-item-name
#{ _('Geo Nodes') }
= nav_link(controller: :deploy_keys) do = nav_link(controller: :deploy_keys) do
= sidebar_link admin_deploy_keys_path, title: _('Deploy Keys') do = sidebar_link admin_deploy_keys_path, title: _('Deploy Keys') do
...@@ -141,6 +192,11 @@ ...@@ -141,6 +192,11 @@
= custom_icon('key') = custom_icon('key')
%span.nav-item-name %span.nav-item-name
Deploy Keys Deploy Keys
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :deploy_keys, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_deploy_keys_path do
%strong.fly-out-top-item-name
#{ _('Deploy Keys') }
= nav_link(controller: :services) do = nav_link(controller: :services) do
= sidebar_link admin_application_settings_services_path, title: _('Service Templates') do = sidebar_link admin_application_settings_services_path, title: _('Service Templates') do
...@@ -148,6 +204,11 @@ ...@@ -148,6 +204,11 @@
= custom_icon('service_templates') = custom_icon('service_templates')
%span.nav-item-name %span.nav-item-name
Service Templates Service Templates
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :services, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_application_settings_services_path do
%strong.fly-out-top-item-name
#{ _('Service Templates') }
= nav_link(controller: :labels) do = nav_link(controller: :labels) do
= sidebar_link admin_labels_path, title: _('Labels') do = sidebar_link admin_labels_path, title: _('Labels') do
...@@ -155,6 +216,11 @@ ...@@ -155,6 +216,11 @@
= custom_icon('labels') = custom_icon('labels')
%span.nav-item-name %span.nav-item-name
Labels Labels
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :labels, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_labels_path do
%strong.fly-out-top-item-name
#{ _('Labels') }
= nav_link(controller: :appearances) do = nav_link(controller: :appearances) do
= sidebar_link admin_appearances_path, title: _('Appearances') do = sidebar_link admin_appearances_path, title: _('Appearances') do
...@@ -162,6 +228,11 @@ ...@@ -162,6 +228,11 @@
= custom_icon('appearance') = custom_icon('appearance')
%span.nav-item-name %span.nav-item-name
Appearance Appearance
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :appearances, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_appearances_path do
%strong.fly-out-top-item-name
#{ _('Appearance') }
= nav_link(controller: :application_settings) do = nav_link(controller: :application_settings) do
= sidebar_link admin_application_settings_path, title: _('Settings') do = sidebar_link admin_application_settings_path, title: _('Settings') do
...@@ -169,5 +240,10 @@ ...@@ -169,5 +240,10 @@
= custom_icon('settings') = custom_icon('settings')
%span.nav-item-name %span.nav-item-name
Settings Settings
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :application_settings, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_application_settings_path do
%strong.fly-out-top-item-name
#{ _('Settings') }
= render 'shared/sidebar_toggle_button' = render 'shared/sidebar_toggle_button'
- issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute
- merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute
- issues_sub_menu_items = ['groups#issues', 'labels#index', 'milestones#index'] - issues_sub_menu_items = ['groups#issues', 'labels#index', 'milestones#index']
- if @group.feature_available?(:group_issue_boards) - if @group.feature_available?(:group_issue_boards)
- issues_sub_menu_items.push('boards#index') - issues_sub_menu_items.push('boards#index')
.nav-sidebar{ class: ("sidebar-icons-only" if collapsed_sidebar?) } .nav-sidebar{ class: ("sidebar-icons-only" if collapsed_sidebar?) }
.nav-sidebar-inner-scroll .nav-sidebar-inner-scroll
.context-header .context-header
...@@ -18,6 +21,11 @@ ...@@ -18,6 +21,11 @@
Overview Overview
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: "fly-out-top-item" } ) do
= link_to group_path(@group) do
%strong.fly-out-top-item-name
#{ _('Overview') }
%li.divider.fly-out-top-item
= nav_link(path: ['groups#show', 'groups#subgroups'], html_options: { class: 'home' }) do = nav_link(path: ['groups#show', 'groups#subgroups'], html_options: { class: 'home' }) do
= link_to group_path(@group), title: 'Group details' do = link_to group_path(@group), title: 'Group details' do
%span %span
...@@ -39,11 +47,16 @@ ...@@ -39,11 +47,16 @@
.nav-icon-container .nav-icon-container
= custom_icon('issues') = custom_icon('issues')
%span.nav-item-name %span.nav-item-name
- issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute
Issues Issues
%span.badge.count= number_with_delimiter(issues.count) %span.badge.count= number_with_delimiter(issues.count)
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(path: ['groups#issues', 'labels#index', 'milestones#index'], html_options: { class: "fly-out-top-item" } ) do
= link_to issues_group_path(@group) do
%strong.fly-out-top-item-name
#{ _('Issues') }
%span.badge.count.issue_counter.fly-out-badge= number_with_delimiter(issues.count)
%li.divider.fly-out-top-item
= nav_link(path: 'groups#issues', html_options: { class: 'home' }) do = nav_link(path: 'groups#issues', html_options: { class: 'home' }) do
= link_to issues_group_path(@group), title: 'List' do = link_to issues_group_path(@group), title: 'List' do
%span %span
...@@ -70,15 +83,25 @@ ...@@ -70,15 +83,25 @@
.nav-icon-container .nav-icon-container
= custom_icon('mr_bold') = custom_icon('mr_bold')
%span.nav-item-name %span.nav-item-name
- merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute
Merge Requests Merge Requests
%span.badge.count= number_with_delimiter(merge_requests.count) %span.badge.count= number_with_delimiter(merge_requests.count)
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: 'groups#merge_requests', html_options: { class: "fly-out-top-item" } ) do
= link_to merge_requests_group_path(@group) do
%strong.fly-out-top-item-name
#{ _('Merge Requests') }
%span.badge.count.merge_counter.js-merge-counter.fly-out-badge= number_with_delimiter(merge_requests.count)
= nav_link(path: 'group_members#index') do = nav_link(path: 'group_members#index') do
= sidebar_link group_group_members_path(@group), title: _('Members') do = sidebar_link group_group_members_path(@group), title: _('Members') do
.nav-icon-container .nav-icon-container
= custom_icon('members') = custom_icon('members')
%span.nav-item-name %span.nav-item-name
Members Members
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: 'group_members#index', html_options: { class: "fly-out-top-item" } ) do
= link_to merge_requests_group_path(@group) do
%strong.fly-out-top-item-name
#{ _('Members') }
- if current_user && can?(current_user, :admin_group, @group) - if current_user && can?(current_user, :admin_group, @group)
= nav_link(path: %w[groups#projects groups#edit ci_cd#show ldap_group_links#index hooks#index audit_events#index pipeline_quota#index]) do = nav_link(path: %w[groups#projects groups#edit ci_cd#show ldap_group_links#index hooks#index audit_events#index pipeline_quota#index]) do
= sidebar_link edit_group_path(@group), title: _('Settings') do = sidebar_link edit_group_path(@group), title: _('Settings') do
...@@ -87,6 +110,11 @@ ...@@ -87,6 +110,11 @@
%span.nav-item-name %span.nav-item-name
Settings Settings
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(path: %w[groups#projects groups#edit ci_cd#show], html_options: { class: "fly-out-top-item" } ) do
= link_to edit_group_path(@group) do
%strong.fly-out-top-item-name
#{ _('Settings') }
%li.divider.fly-out-top-item
= nav_link(path: 'groups#edit') do = nav_link(path: 'groups#edit') do
= link_to edit_group_path(@group), title: 'General' do = link_to edit_group_path(@group), title: 'General' do
%span %span
......
...@@ -12,12 +12,22 @@ ...@@ -12,12 +12,22 @@
= custom_icon('profile') = custom_icon('profile')
%span.nav-item-name %span.nav-item-name
Profile Profile
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: 'profiles#show', html_options: { class: "fly-out-top-item" } ) do
= link_to profile_path do
%strong.fly-out-top-item-name
#{ _('Profile') }
= nav_link(controller: [:accounts, :two_factor_auths]) do = nav_link(controller: [:accounts, :two_factor_auths]) do
= sidebar_link profile_account_path, title: _('Account') do = sidebar_link profile_account_path, title: _('Account') do
.nav-icon-container .nav-icon-container
= custom_icon('account') = custom_icon('account')
%span.nav-item-name %span.nav-item-name
Account Account
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: [:accounts, :two_factor_auths], html_options: { class: "fly-out-top-item" } ) do
= link_to profile_account_path do
%strong.fly-out-top-item-name
#{ _('Account') }
- if current_application_settings.should_check_namespace_plan? - if current_application_settings.should_check_namespace_plan?
= nav_link(controller: :billings) do = nav_link(controller: :billings) do
= sidebar_link profile_billings_path, title: _('Billing') do = sidebar_link profile_billings_path, title: _('Billing') do
...@@ -25,6 +35,11 @@ ...@@ -25,6 +35,11 @@
= custom_icon('credit_card') = custom_icon('credit_card')
%span.nav-item-name %span.nav-item-name
Billing Billing
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :billings, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_billings_path do
%strong.fly-out-top-item-name
#{ _('Billing') }
- if current_application_settings.user_oauth_applications? - if current_application_settings.user_oauth_applications?
= nav_link(controller: 'oauth/applications') do = nav_link(controller: 'oauth/applications') do
= sidebar_link applications_profile_path, title: _('Applications') do = sidebar_link applications_profile_path, title: _('Applications') do
...@@ -32,24 +47,44 @@ ...@@ -32,24 +47,44 @@
= custom_icon('applications') = custom_icon('applications')
%span.nav-item-name %span.nav-item-name
Applications Applications
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: 'oauth/applications', html_options: { class: "fly-out-top-item" } ) do
= link_to applications_profile_path do
%strong.fly-out-top-item-name
#{ _('Applications') }
= nav_link(controller: :chat_names) do = nav_link(controller: :chat_names) do
= sidebar_link profile_chat_names_path, title: _('Chat') do = sidebar_link profile_chat_names_path, title: _('Chat') do
.nav-icon-container .nav-icon-container
= custom_icon('chat') = custom_icon('chat')
%span.nav-item-name %span.nav-item-name
Chat Chat
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :chat_names, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_chat_names_path do
%strong.fly-out-top-item-name
#{ _('Chat') }
= nav_link(controller: :personal_access_tokens) do = nav_link(controller: :personal_access_tokens) do
= sidebar_link profile_personal_access_tokens_path, title: _('Access Tokens') do = sidebar_link profile_personal_access_tokens_path, title: _('Access Tokens') do
.nav-icon-container .nav-icon-container
= custom_icon('access_tokens') = custom_icon('access_tokens')
%span.nav-item-name %span.nav-item-name
Access Tokens Access Tokens
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :personal_access_tokens, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_personal_access_tokens_path do
%strong.fly-out-top-item-name
#{ _('Access Tokens') }
= nav_link(controller: :emails) do = nav_link(controller: :emails) do
= sidebar_link profile_emails_path, title: _('Emails') do = sidebar_link profile_emails_path, title: _('Emails') do
.nav-icon-container .nav-icon-container
= custom_icon('emails') = custom_icon('emails')
%span.nav-item-name %span.nav-item-name
Emails Emails
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :emails, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_emails_path do
%strong.fly-out-top-item-name
#{ _('Emails') }
- unless current_user.ldap_user? - unless current_user.ldap_user?
= nav_link(controller: :passwords) do = nav_link(controller: :passwords) do
= sidebar_link edit_profile_password_path, title: _('Password') do = sidebar_link edit_profile_password_path, title: _('Password') do
...@@ -57,41 +92,76 @@ ...@@ -57,41 +92,76 @@
= custom_icon('lock') = custom_icon('lock')
%span.nav-item-name %span.nav-item-name
Password Password
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :passwords, html_options: { class: "fly-out-top-item" } ) do
= link_to edit_profile_password_path do
%strong.fly-out-top-item-name
#{ _('Password') }
= nav_link(controller: :notifications) do = nav_link(controller: :notifications) do
= sidebar_link profile_notifications_path, title: _('Notifications') do = sidebar_link profile_notifications_path, title: _('Notifications') do
.nav-icon-container .nav-icon-container
= custom_icon('notifications') = custom_icon('notifications')
%span.nav-item-name %span.nav-item-name
Notifications Notifications
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :notifications, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_notifications_path do
%strong.fly-out-top-item-name
#{ _('Notifications') }
= nav_link(controller: :keys) do = nav_link(controller: :keys) do
= sidebar_link profile_keys_path, title: _('SSH Keys') do = sidebar_link profile_keys_path, title: _('SSH Keys') do
.nav-icon-container .nav-icon-container
= custom_icon('key') = custom_icon('key')
%span.nav-item-name %span.nav-item-name
SSH Keys SSH Keys
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :keys, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_keys_path do
%strong.fly-out-top-item-name
#{ _('SSH Keys') }
= nav_link(controller: :gpg_keys) do = nav_link(controller: :gpg_keys) do
= sidebar_link profile_gpg_keys_path, title: _('GPG Keys') do = sidebar_link profile_gpg_keys_path, title: _('GPG Keys') do
.nav-icon-container .nav-icon-container
= custom_icon('key_2') = custom_icon('key_2')
%span.nav-item-name %span.nav-item-name
GPG Keys GPG Keys
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :gpg_keys, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_gpg_keys_path do
%strong.fly-out-top-item-name
#{ _('GPG Keys') }
= nav_link(controller: :preferences) do = nav_link(controller: :preferences) do
= sidebar_link profile_preferences_path, title: _('Preferences') do = sidebar_link profile_preferences_path, title: _('Preferences') do
.nav-icon-container .nav-icon-container
= custom_icon('preferences') = custom_icon('preferences')
%span.nav-item-name %span.nav-item-name
Preferences Preferences
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :preferences, html_options: { class: "fly-out-top-item" } ) do
= link_to profile_preferences_path do
%strong.fly-out-top-item-name
#{ _('Preferences') }
= nav_link(path: 'profiles#audit_log') do = nav_link(path: 'profiles#audit_log') do
= sidebar_link audit_log_profile_path, title: _('Authentication log') do = sidebar_link audit_log_profile_path, title: _('Authentication log') do
.nav-icon-container .nav-icon-container
= custom_icon('authentication_log') = custom_icon('authentication_log')
%span.nav-item-name %span.nav-item-name
Authentication log Authentication log
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: 'profiles#audit_log', html_options: { class: "fly-out-top-item" } ) do
= link_to audit_log_profile_path do
%strong.fly-out-top-item-name
#{ _('Authentication Log') }
= nav_link(path: 'profiles#pipeline_quota') do = nav_link(path: 'profiles#pipeline_quota') do
= sidebar_link profile_pipeline_quota_path, title: _('Pipeline quota') do = sidebar_link profile_pipeline_quota_path, title: _('Pipeline quota') do
.nav-icon-container .nav-icon-container
= custom_icon('pipeline') = custom_icon('pipeline')
%span.nav-item-name %span.nav-item-name
Pipeline quota Pipeline quota
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: 'profiles#pipeline_quota', html_options: { class: "fly-out-top-item" } ) do
= link_to profile_pipeline_quota_path do
%strong.fly-out-top-item-name
#{ _('Pipeline quota') }
= render 'shared/sidebar_toggle_button' = render 'shared/sidebar_toggle_button'
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
Overview Overview
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(path: 'projects#show', html_options: { class: "fly-out-top-item" } ) do
= link_to project_path(@project) do
%strong.fly-out-top-item-name
#{ _('Overview') }
%li.divider.fly-out-top-item
= nav_link(path: 'projects#show') do = nav_link(path: 'projects#show') do
= link_to project_path(@project), title: _('Project details'), class: 'shortcuts-project' do = link_to project_path(@project), title: _('Project details'), class: 'shortcuts-project' do
%span= _('Details') %span= _('Details')
...@@ -38,6 +43,11 @@ ...@@ -38,6 +43,11 @@
Repository Repository
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare projects/repositories tags branches releases graphs network), html_options: { class: "fly-out-top-item" } ) do
= link_to project_tree_path(@project) do
%strong.fly-out-top-item-name
#{ _('Repository') }
%li.divider.fly-out-top-item
= nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do
= link_to project_tree_path(@project) do = link_to project_tree_path(@project) do
#{ _('Files') } #{ _('Files') }
...@@ -82,6 +92,11 @@ ...@@ -82,6 +92,11 @@
= custom_icon('container_registry') = custom_icon('container_registry')
%span.nav-item-name %span.nav-item-name
Registry Registry
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: %w[projects/registry/repositories], html_options: { class: "fly-out-top-item" } ) do
= link_to project_container_registry_index_path(@project) do
%strong.fly-out-top-item-name
#{ _('Registry') }
- if project_nav_tab? :issues - if project_nav_tab? :issues
= nav_link(controller: @project.issues_enabled? ? [:issues, :labels, :milestones, :boards] : :issues) do = nav_link(controller: @project.issues_enabled? ? [:issues, :labels, :milestones, :boards] : :issues) do
...@@ -95,6 +110,14 @@ ...@@ -95,6 +110,14 @@
= number_with_delimiter(@project.open_issues_count) = number_with_delimiter(@project.open_issues_count)
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(controller: :issues, html_options: { class: "fly-out-top-item" } ) do
= link_to project_issues_path(@project) do
%strong.fly-out-top-item-name
#{ _('Issues') }
- if @project.issues_enabled?
%span.badge.count.issue_counter.fly-out-badge
= number_with_delimiter(@project.open_issues_count)
%li.divider.fly-out-top-item
= nav_link(controller: :issues) do = nav_link(controller: :issues) do
= link_to project_issues_path(@project), title: 'Issues' do = link_to project_issues_path(@project), title: 'Issues' do
%span %span
...@@ -124,6 +147,13 @@ ...@@ -124,6 +147,13 @@
Merge Requests Merge Requests
%span.badge.count.merge_counter.js-merge-counter %span.badge.count.merge_counter.js-merge-counter
= number_with_delimiter(@project.open_merge_requests_count) = number_with_delimiter(@project.open_merge_requests_count)
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :merge_requests, html_options: { class: "fly-out-top-item" } ) do
= link_to project_merge_requests_path(@project) do
%strong.fly-out-top-item-name
#{ _('Merge Requests') }
%span.badge.count.merge_counter.js-merge-counter.fly-out-badge
= number_with_delimiter(@project.open_merge_requests_count)
- if project_nav_tab? :pipelines - if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts]) do = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts]) do
...@@ -134,6 +164,11 @@ ...@@ -134,6 +164,11 @@
CI / CD CI / CD
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts], html_options: { class: "fly-out-top-item" } ) do
= link_to project_pipelines_path(@project) do
%strong.fly-out-top-item-name
#{ _('CI / CD') }
%li.divider.fly-out-top-item
- if project_nav_tab? :pipelines - if project_nav_tab? :pipelines
= nav_link(path: ['pipelines#index', 'pipelines#show']) do = nav_link(path: ['pipelines#index', 'pipelines#show']) do
= link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
...@@ -171,6 +206,11 @@ ...@@ -171,6 +206,11 @@
= custom_icon('wiki') = custom_icon('wiki')
%span.nav-item-name %span.nav-item-name
Wiki Wiki
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :wikis, html_options: { class: "fly-out-top-item" } ) do
= link_to get_project_wiki_path(@project) do
%strong.fly-out-top-item-name
#{ _('Wiki') }
- if project_nav_tab? :snippets - if project_nav_tab? :snippets
= nav_link(controller: :snippets) do = nav_link(controller: :snippets) do
...@@ -179,6 +219,11 @@ ...@@ -179,6 +219,11 @@
= custom_icon('snippets') = custom_icon('snippets')
%span.nav-item-name %span.nav-item-name
Snippets Snippets
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :snippets, html_options: { class: "fly-out-top-item" } ) do
= link_to project_snippets_path(@project) do
%strong.fly-out-top-item-name
#{ _('Snippets') }
- if project_nav_tab? :settings - if project_nav_tab? :settings
= nav_link(path: %w[projects#edit project_members#index integrations#show services#edit repository#show ci_cd#show pages#show]) do = nav_link(path: %w[projects#edit project_members#index integrations#show services#edit repository#show ci_cd#show pages#show]) do
...@@ -191,6 +236,11 @@ ...@@ -191,6 +236,11 @@
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
- can_edit = can?(current_user, :admin_project, @project) - can_edit = can?(current_user, :admin_project, @project)
- if can_edit - if can_edit
= nav_link(path: %w[projects#edit project_members#index integrations#show services#edit repository#show ci_cd#show pages#show], html_options: { class: "fly-out-top-item" } ) do
= link_to edit_project_path(@project) do
%strong.fly-out-top-item-name
#{ _('Settings') }
%li.divider.fly-out-top-item
= nav_link(path: %w[projects#edit]) do = nav_link(path: %w[projects#edit]) do
= link_to edit_project_path(@project), title: 'General' do = link_to edit_project_path(@project), title: 'General' do
%span %span
......
...@@ -14,9 +14,6 @@ ...@@ -14,9 +14,6 @@
= content_for :meta_tags do = content_for :meta_tags do
= auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@project.name} issues") = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@project.name} issues")
- content_for :breadcrumbs_extra do
= render "projects/issues/nav_btns"
- if project_issues(@project).exists? - if project_issues(@project).exists?
= render 'projects/issues/export_issues/csv_download' = render 'projects/issues/export_issues/csv_download'
...@@ -24,7 +21,7 @@ ...@@ -24,7 +21,7 @@
%div{ class: (container_class) } %div{ class: (container_class) }
.top-area .top-area
= render 'shared/issuable/nav', type: :issues = render 'shared/issuable/nav', type: :issues
.nav-controls.visible-xs .nav-controls
= render "projects/issues/nav_btns" = render "projects/issues/nav_btns"
= render 'shared/issuable/search_bar', type: :issues = render 'shared/issuable/search_bar', type: :issues
......
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
- hide_class = '' - hide_class = ''
- can_admin_label = can?(current_user, :admin_label, @project) - can_admin_label = can?(current_user, :admin_label, @project)
- if can?(current_user, :admin_label, @project)
- content_for :breadcrumbs_extra do
= link_to "New label", new_namespace_project_label_path(@project.namespace, @project), class: "btn btn-new"
= render "shared/mr_head" = render "shared/mr_head"
- if @labels.exists? || @prioritized_labels.exists? - if @labels.exists? || @prioritized_labels.exists?
...@@ -18,7 +14,7 @@ ...@@ -18,7 +14,7 @@
Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging. Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging.
- if can_admin_label - if can_admin_label
.nav-controls.visible-xs .nav-controls
= link_to new_project_label_path(@project), class: "btn btn-new" do = link_to new_project_label_path(@project), class: "btn btn-new" do
New label New label
......
...@@ -12,16 +12,13 @@ ...@@ -12,16 +12,13 @@
= webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'common_vue'
= webpack_bundle_tag 'filtered_search' = webpack_bundle_tag 'filtered_search'
- content_for :breadcrumbs_extra do
= render "projects/merge_requests/nav_btns", merge_project: merge_project, new_merge_request_path: new_merge_request_path
= render 'projects/last_push' = render 'projects/last_push'
- if @project.merge_requests.exists? - if @project.merge_requests.exists?
%div{ class: container_class } %div{ class: container_class }
.top-area .top-area
= render 'shared/issuable/nav', type: :merge_requests = render 'shared/issuable/nav', type: :merge_requests
.nav-controls.visible-xs .nav-controls
= render "projects/merge_requests/nav_btns", merge_project: merge_project, new_merge_request_path: new_merge_request_path = render "projects/merge_requests/nav_btns", merge_project: merge_project, new_merge_request_path: new_merge_request_path
= render 'shared/issuable/search_bar', type: :merge_requests = render 'shared/issuable/search_bar', type: :merge_requests
......
- @no_container = true - @no_container = true
- page_title 'Milestones' - page_title 'Milestones'
- if can?(current_user, :admin_milestone, @project)
- content_for :breadcrumbs_extra do
= link_to "New milestone", new_namespace_project_milestone_path(@project.namespace, @project), class: 'btn btn-new', title: 'New milestone'
= render "shared/mr_head" = render "shared/mr_head"
%div{ class: container_class } %div{ class: container_class }
.top-area .top-area
= render 'shared/milestones_filter', counts: milestone_counts(@project.milestones) = render 'shared/milestones_filter', counts: milestone_counts(@project.milestones)
.nav-controls.nav-controls-new-nav .nav-controls
= render 'shared/milestones_sort_dropdown' = render 'shared/milestones_sort_dropdown'
- if can?(current_user, :admin_milestone, @project) - if can?(current_user, :admin_milestone, @project)
= link_to new_project_milestone_path(@project), class: "btn btn-new visible-xs", title: 'New milestone' do = link_to new_project_milestone_path(@project), class: "btn btn-new", title: 'New milestone' do
New milestone New milestone
.milestones .milestones
......
...@@ -7,10 +7,6 @@ ...@@ -7,10 +7,6 @@
- @no_container = true - @no_container = true
- page_title _("Pipeline Schedules") - page_title _("Pipeline Schedules")
- if can?(current_user, :create_pipeline_schedule, @project)
- content_for :breadcrumbs_extra do
= link_to _('New schedule'), new_namespace_project_pipeline_schedule_path(@project.namespace, @project), class: 'btn btn-create'
= render "projects/pipelines/head" = render "projects/pipelines/head"
%div{ class: container_class } %div{ class: container_class }
...@@ -20,7 +16,7 @@ ...@@ -20,7 +16,7 @@
= render "tabs", schedule_path_proc: schedule_path_proc, all_schedules: @all_schedules, scope: @scope = render "tabs", schedule_path_proc: schedule_path_proc, all_schedules: @all_schedules, scope: @scope
- if can?(current_user, :create_pipeline_schedule, @project) - if can?(current_user, :create_pipeline_schedule, @project)
.nav-controls.visible-xs .nav-controls
= link_to new_project_pipeline_schedule_path(@project), class: 'btn btn-create' do = link_to new_project_pipeline_schedule_path(@project), class: 'btn btn-create' do
%span= _('New schedule') %span= _('New schedule')
......
- page_title "Snippets" - page_title "Snippets"
- if can?(current_user, :create_project_snippet, @project)
- content_for :breadcrumbs_extra do
= link_to "New snippet", new_namespace_project_snippet_path(@project.namespace, @project), class: "btn btn-new", title: "New snippet"
- if current_user - if current_user
.top-area .top-area
- include_private = @project.team.member?(current_user) || current_user.admin? - include_private = @project.team.member?(current_user) || current_user.admin?
= render partial: 'snippets/snippets_scope_menu', locals: { subject: @project, include_private: include_private } = render partial: 'snippets/snippets_scope_menu', locals: { subject: @project, include_private: include_private }
.nav-controls.visible-xs .nav-controls
- if can?(current_user, :create_project_snippet, @project) - if can?(current_user, :create_project_snippet, @project)
= link_to "New snippet", new_project_snippet_path(@project), class: "btn btn-new", title: "New snippet" = link_to "New snippet", new_project_snippet_path(@project), class: "btn btn-new", title: "New snippet"
......
- if @search_objects.empty? - if @search_objects.empty?
= render partial: "search/results/empty" = render partial: "search/results/empty"
= render 'shared/promotions/promote_advanced_search'
- else - else
.row-content-block .row-content-block
= search_entries_info(@search_objects, @scope, @search_term) = search_entries_info(@search_objects, @scope, @search_term)
...@@ -8,7 +9,7 @@ ...@@ -8,7 +9,7 @@
in project #{link_to @project.name_with_namespace, [@project.namespace.becomes(Namespace), @project]} in project #{link_to @project.name_with_namespace, [@project.namespace.becomes(Namespace), @project]}
- elsif @group - elsif @group
in group #{link_to @group.name, @group} in group #{link_to @group.name, @group}
= render 'shared/promotions/promote_advanced_search'
.results.prepend-top-10 .results.prepend-top-10
- if @scope == 'commits' - if @scope == 'commits'
%ul.content-list.commit-list %ul.content-list.commit-list
......
<svg xmlns="http://www.w3.org/2000/svg" width="42" height="42" viewBox="0 0 42 42"><g fill="none" fill-rule="evenodd"><path fill="#E5E5E5" fill-rule="nonzero" d="M21 41.5C9.678 41.5.5 32.322.5 21S9.678.5 21 .5 41.5 9.678 41.5 21 32.322 41.5 21 41.5zm0-1c10.77 0 19.5-8.73 19.5-19.5S31.77 1.5 21 1.5 1.5 10.23 1.5 21 10.23 40.5 21 40.5z"/><path fill="#E1DBF2" d="M20.396 22.846a4 4 0 1 0-2.07-7.727l2.07 7.727z"/><path fill="#6B4FBB" fill-rule="nonzero" d="M23.6 26.43a8.5 8.5 0 1 1 2.828-2.828l3.35 3.348a2 2 0 1 1-2.828 2.828L23.6 26.43zm-.54-3.37a5.5 5.5 0 1 0-7.778-7.777 5.5 5.5 0 0 0 7.779 7.778z"/></g></svg>
\ No newline at end of file
- if show_advanced_search_promotion?
.user-callout.promotion-callout.promotion-advanced-search.js-mr-approval-callout#promote_advanced_search{ data: { uid: 'promote_advanced_search_dismissed' } }
.bordered-box.content-block
%button.btn.btn-default.close.js-close-callout{ type: 'button', 'aria-label' => _('Dismiss Merge Request promotion') }
= icon('times', class: 'dismiss-icon', 'aria-hidden' => 'true')
.svg-container
= custom_icon('icon_search_avatar')
.user-callout-copy
%h5
- if current_application_settings.should_check_namespace_plan?
= _('Upgrade your plan to activate Advanced Global Search.')
- else
= _('Improve search with Advanced Global Search and GitLab Enterprise Edition.')
%p
= _('The Advanced Global Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project.')
= link_to _('Read more'), help_page_path('user/search/advanced_global_search.html'), target: '_blank'
= render 'shared/promotions/promotion_link_project'
...@@ -47,7 +47,7 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps ...@@ -47,7 +47,7 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps
end end
step 'I click new milestone button' do step 'I click new milestone button' do
page.within('.breadcrumbs') do page.within('.nav-controls') do
click_link "New milestone" click_link "New milestone"
end end
end end
......
...@@ -24,7 +24,7 @@ class Spinach::Features::GroupsManagement < Spinach::FeatureSteps ...@@ -24,7 +24,7 @@ class Spinach::Features::GroupsManagement < Spinach::FeatureSteps
step 'I go to "Open" project members page' do step 'I go to "Open" project members page' do
click_link 'Sourcing / Open' click_link 'Sourcing / Open'
page.within('.nav-sidebar') do page.within('.nav-sidebar') do
click_link 'Settings' first(:link, text: 'Settings').click
end end
click_link 'Members' click_link 'Members'
end end
...@@ -38,7 +38,7 @@ class Spinach::Features::GroupsManagement < Spinach::FeatureSteps ...@@ -38,7 +38,7 @@ class Spinach::Features::GroupsManagement < Spinach::FeatureSteps
visit root_path visit root_path
click_link 'Sourcing / Open' click_link 'Sourcing / Open'
page.within('.nav-sidebar') do page.within('.nav-sidebar') do
click_link 'Settings' first(:link, text: 'Settings').click
end end
click_link 'Members' click_link 'Members'
end end
...@@ -47,10 +47,10 @@ class Spinach::Features::GroupsManagement < Spinach::FeatureSteps ...@@ -47,10 +47,10 @@ class Spinach::Features::GroupsManagement < Spinach::FeatureSteps
visit dashboard_groups_path visit dashboard_groups_path
click_link 'Sourcing' click_link 'Sourcing'
page.within '.nav-sidebar' do page.within '.nav-sidebar' do
find('a', text: 'Settings').trigger('click') first(:link, text: 'Settings').click
end end
page.within '.sidebar-top-level-items > .active' do page.within '.sidebar-top-level-items > .active' do
find('a', text: 'General').trigger('click') click_link 'General'
end end
end end
......
...@@ -37,7 +37,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps ...@@ -37,7 +37,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps
step 'I goto the Merge Requests page' do step 'I goto the Merge Requests page' do
page.within '.nav-sidebar' do page.within '.nav-sidebar' do
click_link "Merge Requests" first(:link, "Merge Requests").click
end end
end end
......
...@@ -62,7 +62,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps ...@@ -62,7 +62,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end end
step 'I click link "New issue"' do step 'I click link "New issue"' do
page.within '.breadcrumbs' do page.within '#content-body' do
page.has_link?('New Issue') ? click_link('New Issue') : click_link('New issue') page.has_link?('New Issue') ? click_link('New Issue') : click_link('New issue')
end end
end end
......
...@@ -16,7 +16,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps ...@@ -16,7 +16,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps
end end
step 'I click link "New Milestone"' do step 'I click link "New Milestone"' do
page.within('.breadcrumbs') do page.within('.nav-controls') do
click_link "New milestone" click_link "New milestone"
end end
end end
......
...@@ -14,7 +14,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps ...@@ -14,7 +14,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end end
step 'I click link "New Merge Request"' do step 'I click link "New Merge Request"' do
page.within '.breadcrumbs' do page.within '.nav-controls' do
page.has_link?('New Merge Request') ? click_link("New Merge Request") : click_link('New merge request') page.has_link?('New Merge Request') ? click_link("New Merge Request") : click_link('New merge request')
end end
end end
......
...@@ -23,7 +23,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps ...@@ -23,7 +23,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps
end end
step 'I click link "New snippet"' do step 'I click link "New snippet"' do
page.within '.breadcrumbs' do page.within '.nav-controls' do
first(:link, "New snippet").click first(:link, "New snippet").click
end end
end end
......
...@@ -218,7 +218,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps ...@@ -218,7 +218,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps
# Wiki # Wiki
step 'I go to wiki page' do step 'I go to wiki page' do
click_link "Wiki" first(:link, "Wiki").click
expect(current_path).to eq project_wiki_path(@project, "home") expect(current_path).to eq project_wiki_path(@project, "home")
end end
......
...@@ -11,7 +11,7 @@ module SharedActiveTab ...@@ -11,7 +11,7 @@ module SharedActiveTab
end end
def ensure_active_sub_tab(content) def ensure_active_sub_tab(content)
expect(find('.sidebar-sub-level-items > li.active')).to have_content(content) expect(find('.sidebar-sub-level-items > li.active:not(.fly-out-top-item)')).to have_content(content)
end end
def ensure_active_sub_nav(content) def ensure_active_sub_nav(content)
...@@ -23,7 +23,7 @@ module SharedActiveTab ...@@ -23,7 +23,7 @@ module SharedActiveTab
end end
step 'no other sub tabs should be active' do step 'no other sub tabs should be active' do
expect(page).to have_selector('.sidebar-sub-level-items > li.active', count: 1) expect(page).to have_selector('.sidebar-sub-level-items > li.active:not(.fly-out-top-item)', count: 1)
end end
step 'no other sub navs should be active' do step 'no other sub navs should be active' do
......
...@@ -14,8 +14,8 @@ RSpec.describe 'admin active tab' do ...@@ -14,8 +14,8 @@ RSpec.describe 'admin active tab' do
shared_examples 'page has active sub tab' do |title| shared_examples 'page has active sub tab' do |title|
it "activates #{title} sub tab" do it "activates #{title} sub tab" do
expect(page).to have_selector('.sidebar-sub-level-items li.active', count: 1) expect(page).to have_selector('.sidebar-sub-level-items > li.active', count: 2)
expect(page.find('.sidebar-sub-level-items li.active')).to have_content(title) expect(page.all('.sidebar-sub-level-items > li.active')[1]).to have_content(title)
end end
end end
......
...@@ -71,7 +71,7 @@ feature 'Admin updates settings' do ...@@ -71,7 +71,7 @@ feature 'Admin updates settings' do
end end
scenario 'Change Slack Notifications Service template settings' do scenario 'Change Slack Notifications Service template settings' do
click_link 'Service Templates' first(:link, 'Service Templates').click
click_link 'Slack notifications' click_link 'Slack notifications'
fill_in 'Webhook', with: 'http://localhost' fill_in 'Webhook', with: 'http://localhost'
fill_in 'Username', with: 'test_user' fill_in 'Username', with: 'test_user'
......
...@@ -50,7 +50,7 @@ feature 'Dashboard Issues filtering', :js do ...@@ -50,7 +50,7 @@ feature 'Dashboard Issues filtering', :js do
it 'updates atom feed link' do it 'updates atom feed link' do
visit_issues(milestone_title: '', assignee_id: user.id) visit_issues(milestone_title: '', assignee_id: user.id)
link = find('.breadcrumbs a[title="Subscribe"]') link = find('.nav-controls a[title="Subscribe"]')
params = CGI.parse(URI.parse(link[:href]).query) params = CGI.parse(URI.parse(link[:href]).query)
auto_discovery_link = find('link[type="application/atom+xml"]', visible: false) auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query) auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
......
...@@ -51,7 +51,7 @@ feature 'Groups > Members > Request access' do ...@@ -51,7 +51,7 @@ feature 'Groups > Members > Request access' do
expect(group.requesters.exists?(user_id: user)).to be_truthy expect(group.requesters.exists?(user_id: user)).to be_truthy
click_link 'Members' first(:link, 'Members').click
page.within('.content') do page.within('.content') do
expect(page).not_to have_content(user.name) expect(page).not_to have_content(user.name)
......
...@@ -14,7 +14,7 @@ describe 'Issues csv' do ...@@ -14,7 +14,7 @@ describe 'Issues csv' do
def request_csv(params = {}) def request_csv(params = {})
visit project_issues_path(project, params) visit project_issues_path(project, params)
page.within('.breadcrumbs') do page.within('.nav-controls') do
click_on 'Export as CSV' click_on 'Export as CSV'
end end
click_on 'Export issues' click_on 'Export issues'
......
...@@ -818,7 +818,7 @@ describe 'Filter issues', js: true do ...@@ -818,7 +818,7 @@ describe 'Filter issues', js: true do
it 'updates atom feed link for group issues' do it 'updates atom feed link for group issues' do
visit issues_group_path(group, milestone_title: milestone.title, assignee_id: user.id) visit issues_group_path(group, milestone_title: milestone.title, assignee_id: user.id)
link = find('.breadcrumbs a', text: 'Subscribe') link = find('.nav-controls a', text: 'Subscribe')
params = CGI.parse(URI.parse(link[:href]).query) params = CGI.parse(URI.parse(link[:href]).query)
auto_discovery_link = find('link[type="application/atom+xml"]', visible: false) auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query) auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
......
...@@ -613,7 +613,7 @@ describe 'Issues' do ...@@ -613,7 +613,7 @@ describe 'Issues' do
it 'redirects to signin then back to new issue after signin' do it 'redirects to signin then back to new issue after signin' do
visit project_issues_path(project) visit project_issues_path(project)
page.within '.breadcrumbs' do page.within '.nav-controls' do
click_link 'New issue' click_link 'New issue'
end end
......
...@@ -308,4 +308,40 @@ describe 'Promotions', js: true do ...@@ -308,4 +308,40 @@ describe 'Promotions', js: true do
expect(find('.user-callout-copy')).to have_content 'Add Group Webhooks' expect(find('.user-callout-copy')).to have_content 'Add Group Webhooks'
end end
end end
describe 'for advanced search', js: true do
before do
allow(License).to receive(:current).and_return(nil)
stub_application_setting(check_namespace_plan: false)
sign_in(user)
end
it 'should appear on seearch page' do
visit search_path
fill_in 'search', with: 'chosen'
find('.btn-search').trigger('click')
expect(find('#promote_advanced_search')).to have_content 'Improve search with Advanced Global Search and GitLab Enterprise Edition.'
end
it 'does not show when cookie is set' do
visit search_path
fill_in 'search', with: 'chosen'
find('.btn-search').trigger('click')
within('#promote_advanced_search') do
find('.close').trigger('click')
end
visit search_path
fill_in 'search', with: 'chosen'
find('.btn-search').trigger('click')
expect(page).not_to have_selector('#promote_advanced_search')
end
end
end end
...@@ -32,6 +32,8 @@ describe('Fly out sidebar navigation', () => { ...@@ -32,6 +32,8 @@ describe('Fly out sidebar navigation', () => {
document.body.innerHTML = ''; document.body.innerHTML = '';
breakpointSize = 'lg'; breakpointSize = 'lg';
mousePos.length = 0; mousePos.length = 0;
setSidebar(null);
}); });
describe('calculateTop', () => { describe('calculateTop', () => {
...@@ -240,6 +242,32 @@ describe('Fly out sidebar navigation', () => { ...@@ -240,6 +242,32 @@ describe('Fly out sidebar navigation', () => {
).toBe('block'); ).toBe('block');
}); });
it('shows collapsed only sub-items if icon only sidebar', () => {
const subItems = el.querySelector('.sidebar-sub-level-items');
const sidebar = document.createElement('div');
sidebar.classList.add('sidebar-icons-only');
subItems.classList.add('is-fly-out-only');
setSidebar(sidebar);
showSubLevelItems(el);
expect(
el.querySelector('.sidebar-sub-level-items').style.display,
).toBe('block');
});
it('does not show collapsed only sub-items if icon only sidebar', () => {
const subItems = el.querySelector('.sidebar-sub-level-items');
subItems.classList.add('is-fly-out-only');
showSubLevelItems(el);
expect(
subItems.style.display,
).not.toBe('block');
});
it('sets transform of sub-items', () => { it('sets transform of sub-items', () => {
const subItems = el.querySelector('.sidebar-sub-level-items'); const subItems = el.querySelector('.sidebar-sub-level-items');
showSubLevelItems(el); showSubLevelItems(el);
...@@ -281,10 +309,6 @@ describe('Fly out sidebar navigation', () => { ...@@ -281,10 +309,6 @@ describe('Fly out sidebar navigation', () => {
}); });
describe('canShowActiveSubItems', () => { describe('canShowActiveSubItems', () => {
afterEach(() => {
setSidebar(null);
});
it('returns true by default', () => { it('returns true by default', () => {
expect( expect(
canShowActiveSubItems(el), canShowActiveSubItems(el),
......
...@@ -118,7 +118,7 @@ describe('Issue', function() { ...@@ -118,7 +118,7 @@ describe('Issue', function() {
this.$triggeredButton = $btn; this.$triggeredButton = $btn;
this.$projectIssuesCounter = $('.issue_counter'); this.$projectIssuesCounter = $('.issue_counter').first();
this.$projectIssuesCounter.text('1,001'); this.$projectIssuesCounter.text('1,001');
this.issueStateDeferred = new jQuery.Deferred(); this.issueStateDeferred = new jQuery.Deferred();
......
...@@ -27,7 +27,7 @@ describe 'layouts/nav/sidebar/_project' do ...@@ -27,7 +27,7 @@ describe 'layouts/nav/sidebar/_project' do
it 'highlights only one tab' do it 'highlights only one tab' do
render render
expect(rendered).to have_css('.active', count: 1) expect(rendered).to have_css('.active', count: 2)
end end
it 'highlights container registry tab only' do it 'highlights container registry tab only' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment