diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2017-09-07 13:26:48 +0000 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2017-09-07 13:26:48 +0000 |
commit | b8adc0d0423ac53bf94aeb4361c3eb82a4e905c6 (patch) | |
tree | bee55832212a9f4491dd5500d7654c609d268637 | |
parent | 0c2dc7273819b29efcb77a347af0116aeb5a9927 (diff) | |
parent | e58750dd08d1af7322a1bbdd5bfcc3667d33fc15 (diff) | |
download | gitlab-ce-b8adc0d0423ac53bf94aeb4361c3eb82a4e905c6.tar.gz |
Merge branch 'fly-out-top-level-item' into 'master'
Add top level items to fly-out navigation
Closes #36294
See merge request !13981
-rw-r--r-- | app/assets/javascripts/fly_out_nav.js | 7 | ||||
-rw-r--r-- | app/assets/javascripts/issue.js | 2 | ||||
-rw-r--r-- | app/assets/stylesheets/new_sidebar.scss | 39 | ||||
-rw-r--r-- | app/views/layouts/nav/sidebar/_admin.html.haml | 61 | ||||
-rw-r--r-- | app/views/layouts/nav/sidebar/_group.html.haml | 32 | ||||
-rw-r--r-- | app/views/layouts/nav/sidebar/_profile.html.haml | 61 | ||||
-rw-r--r-- | app/views/layouts/nav/sidebar/_project.html.haml | 45 | ||||
-rw-r--r-- | features/steps/project/fork.rb | 2 | ||||
-rw-r--r-- | features/steps/project/source/markdown_render.rb | 2 | ||||
-rw-r--r-- | features/steps/shared/active_tab.rb | 4 | ||||
-rw-r--r-- | spec/features/admin/admin_active_tab_spec.rb | 4 | ||||
-rw-r--r-- | spec/features/admin/admin_settings_spec.rb | 2 | ||||
-rw-r--r-- | spec/features/groups/members/request_access_spec.rb | 2 | ||||
-rw-r--r-- | spec/javascripts/fly_out_nav_spec.js | 32 | ||||
-rw-r--r-- | spec/javascripts/issue_spec.js | 2 |
15 files changed, 271 insertions, 26 deletions
diff --git a/app/assets/javascripts/fly_out_nav.js b/app/assets/javascripts/fly_out_nav.js index 063155a167a..4b19f7b4188 100644 --- a/app/assets/javascripts/fly_out_nav.js +++ b/app/assets/javascripts/fly_out_nav.js @@ -21,8 +21,10 @@ let headerHeight = 50; export const getHeaderHeight = () => headerHeight; +export const isSidebarCollapsed = () => sidebar && sidebar.classList.contains('sidebar-icons-only'); + export const canShowActiveSubItems = (el) => { - if (el.classList.contains('active') && (sidebar && !sidebar.classList.contains('sidebar-icons-only'))) { + if (el.classList.contains('active') && !isSidebarCollapsed()) { return false; } @@ -100,12 +102,13 @@ export const moveSubItemsToPosition = (el, subItems) => { export const showSubLevelItems = (el) => { const subItems = el.querySelector('.sidebar-sub-level-items'); + const isIconOnly = subItems && subItems.classList.contains('is-fly-out-only'); if (!canShowSubItems() || !canShowActiveSubItems(el)) return; el.classList.add(IS_OVER_CLASS); - if (!subItems) return; + if (!subItems || (!isSidebarCollapsed() && isIconOnly)) return; subItems.style.display = 'block'; el.classList.add(IS_SHOWING_FLY_OUT_CLASS); diff --git a/app/assets/javascripts/issue.js b/app/assets/javascripts/issue.js index 7c4f4da6127..c0bd64814ca 100644 --- a/app/assets/javascripts/issue.js +++ b/app/assets/javascripts/issue.js @@ -73,7 +73,7 @@ class Issue { $(document).trigger('issuable:change', 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; projectIssuesCounter.text(gl.text.addDelimiter(numProjectIssues)); diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index fd5e344d8c9..3082f728ac8 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -106,11 +106,8 @@ $new-sidebar-collapsed-width: 50px; overflow-x: hidden; } - .badge, - .sidebar-context-title { - display: none; - } - + .badge:not(.fly-out-badge), + .sidebar-context-title, .nav-item-name { display: none; } @@ -118,6 +115,10 @@ $new-sidebar-collapsed-width: 50px; .sidebar-top-level-items > li > a { min-height: 44px; } + + .fly-out-top-item { + display: block; + } } &.nav-sidebar-expanded { @@ -179,6 +180,10 @@ $new-sidebar-collapsed-width: 50px; width: 16px; } } + + .fly-out-top-item { + display: none; + } } .nav-sidebar-inner-scroll { @@ -249,7 +254,7 @@ $new-sidebar-collapsed-width: 50px; left: $new-sidebar-width; min-width: 150px; margin-top: -1px; - padding: 8px 1px; + padding: 4px 1px; background-color: $white-light; box-shadow: 2px 1px 3px $dropdown-shadow-color; border: 1px solid $gray-darker; @@ -270,6 +275,13 @@ $new-sidebar-collapsed-width: 50px; margin-top: 1px; } + .divider { + height: 1px; + margin: 4px -1px; + padding: 0; + background-color: $dropdown-divider-color; + } + > .active { box-shadow: none; @@ -309,7 +321,7 @@ $new-sidebar-collapsed-width: 50px; font-weight: $gl-font-weight-bold; } - .sidebar-sub-level-items { + .sidebar-sub-level-items:not(.is-fly-out-only) { display: block; } } @@ -407,6 +419,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 diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml index 3b53117deb6..8ab2b686f86 100644 --- a/app/views/layouts/nav/sidebar/_admin.html.haml +++ b/app/views/layouts/nav/sidebar/_admin.html.haml @@ -14,6 +14,11 @@ Overview %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 = link_to admin_root_path, title: 'Overview' do %span @@ -55,6 +60,11 @@ Monitoring %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 = link_to admin_system_info_path, title: 'System Info' do %span @@ -82,6 +92,11 @@ = custom_icon('messages') %span.nav-item-name 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 = sidebar_link admin_hooks_path, title: _('Hooks') do @@ -89,6 +104,11 @@ = custom_icon('system_hooks') %span.nav-item-name 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 = sidebar_link admin_applications_path, title: _('Applications') do @@ -96,6 +116,11 @@ = custom_icon('applications') %span.nav-item-name 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 = sidebar_link admin_abuse_reports_path, title: _("Abuse Reports") do @@ -104,6 +129,12 @@ %span.nav-item-name Abuse Reports %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)) - if akismet_enabled? = nav_link(controller: :spam_logs) do @@ -112,6 +143,11 @@ = custom_icon('spam_logs') %span.nav-item-name 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: :deploy_keys) do = sidebar_link admin_deploy_keys_path, title: _('Deploy Keys') do @@ -119,6 +155,11 @@ = custom_icon('key') %span.nav-item-name 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 = sidebar_link admin_application_settings_services_path, title: _('Service Templates') do @@ -126,6 +167,11 @@ = custom_icon('service_templates') %span.nav-item-name 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 = sidebar_link admin_labels_path, title: _('Labels') do @@ -133,6 +179,11 @@ = custom_icon('labels') %span.nav-item-name 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 = sidebar_link admin_appearances_path, title: _('Appearances') do @@ -140,6 +191,11 @@ = custom_icon('appearance') %span.nav-item-name 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 = sidebar_link admin_application_settings_path, title: _('Settings') do @@ -147,5 +203,10 @@ = custom_icon('settings') %span.nav-item-name 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' diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index 5a1511b262f..e01dfa7c854 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -1,3 +1,6 @@ +- 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 + .nav-sidebar{ class: ("sidebar-icons-only" if collapsed_sidebar?) } .nav-sidebar-inner-scroll .context-header @@ -15,6 +18,11 @@ Overview %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 = link_to group_path(@group), title: 'Group details' do %span @@ -30,11 +38,16 @@ .nav-icon-container = custom_icon('issues') %span.nav-item-name - - issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute Issues %span.badge.count= number_with_delimiter(issues.count) %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 = link_to issues_group_path(@group), title: 'List' do %span @@ -55,15 +68,25 @@ .nav-icon-container = custom_icon('mr_bold') %span.nav-item-name - - merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute Merge Requests %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 = sidebar_link group_group_members_path(@group), title: _('Members') do .nav-icon-container = custom_icon('members') %span.nav-item-name 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) = nav_link(path: %w[groups#projects groups#edit ci_cd#show]) do = sidebar_link edit_group_path(@group), title: _('Settings') do @@ -72,6 +95,11 @@ %span.nav-item-name Settings %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 = link_to edit_group_path(@group), title: 'General' do %span diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml index ccb6d1492f1..4c26d107ea7 100644 --- a/app/views/layouts/nav/sidebar/_profile.html.haml +++ b/app/views/layouts/nav/sidebar/_profile.html.haml @@ -12,12 +12,22 @@ = custom_icon('profile') %span.nav-item-name 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 = sidebar_link profile_account_path, title: _('Account') do .nav-icon-container = custom_icon('account') %span.nav-item-name 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.user_oauth_applications? = nav_link(controller: 'oauth/applications') do = sidebar_link applications_profile_path, title: _('Applications') do @@ -25,24 +35,44 @@ = custom_icon('applications') %span.nav-item-name 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 = sidebar_link profile_chat_names_path, title: _('Chat') do .nav-icon-container = custom_icon('chat') %span.nav-item-name 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 = sidebar_link profile_personal_access_tokens_path, title: _('Access Tokens') do .nav-icon-container = custom_icon('access_tokens') %span.nav-item-name 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 = sidebar_link profile_emails_path, title: _('Emails') do .nav-icon-container = custom_icon('emails') %span.nav-item-name 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? = nav_link(controller: :passwords) do = sidebar_link edit_profile_password_path, title: _('Password') do @@ -50,36 +80,65 @@ = custom_icon('lock') %span.nav-item-name 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 = sidebar_link profile_notifications_path, title: _('Notifications') do .nav-icon-container = custom_icon('notifications') %span.nav-item-name 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 = sidebar_link profile_keys_path, title: _('SSH Keys') do .nav-icon-container = custom_icon('key') %span.nav-item-name 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 = sidebar_link profile_gpg_keys_path, title: _('GPG Keys') do .nav-icon-container = custom_icon('key_2') %span.nav-item-name 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 = sidebar_link profile_preferences_path, title: _('Preferences') do .nav-icon-container = custom_icon('preferences') %span.nav-item-name 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 = sidebar_link audit_log_profile_path, title: _('Authentication log') do .nav-icon-container = custom_icon('authentication_log') %span.nav-item-name 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') } = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml index 760c4c97c33..27fadc1d952 100644 --- a/app/views/layouts/nav/sidebar/_project.html.haml +++ b/app/views/layouts/nav/sidebar/_project.html.haml @@ -16,6 +16,11 @@ Overview %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 = link_to project_path(@project), title: _('Project details'), class: 'shortcuts-project' do %span= _('Details') @@ -38,6 +43,11 @@ Repository %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 = link_to project_tree_path(@project) do #{ _('Files') } @@ -90,6 +100,14 @@ = number_with_delimiter(@project.open_issues_count) %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 = link_to project_issues_path(@project), title: 'Issues' do %span @@ -133,6 +151,13 @@ Merge Requests %span.badge.count.merge_counter.js-merge-counter = 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 = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts]) do @@ -143,6 +168,11 @@ CI / CD %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 = nav_link(path: ['pipelines#index', 'pipelines#show']) do = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do @@ -180,6 +210,11 @@ = custom_icon('wiki') %span.nav-item-name 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 = nav_link(controller: :snippets) do @@ -188,6 +223,11 @@ = custom_icon('snippets') %span.nav-item-name 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 = nav_link(path: %w[projects#edit project_members#index integrations#show services#edit repository#show ci_cd#show pages#show]) do @@ -200,6 +240,11 @@ %ul.sidebar-sub-level-items - can_edit = can?(current_user, :admin_project, @project) - 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 = link_to edit_project_path(@project), title: 'General' do %span diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb index 3b8d9af96c1..513ccce2f8f 100644 --- a/features/steps/project/fork.rb +++ b/features/steps/project/fork.rb @@ -37,7 +37,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps step 'I goto the Merge Requests page' do page.within '.nav-sidebar' do - click_link "Merge Requests" + first(:link, "Merge Requests").click end end diff --git a/features/steps/project/source/markdown_render.rb b/features/steps/project/source/markdown_render.rb index 243a0f54f7f..f6445b57ec0 100644 --- a/features/steps/project/source/markdown_render.rb +++ b/features/steps/project/source/markdown_render.rb @@ -218,7 +218,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps # Wiki step 'I go to wiki page' do - click_link "Wiki" + first(:link, "Wiki").click expect(current_path).to eq project_wiki_path(@project, "home") end diff --git a/features/steps/shared/active_tab.rb b/features/steps/shared/active_tab.rb index 2bb21a798aa..104d024fee2 100644 --- a/features/steps/shared/active_tab.rb +++ b/features/steps/shared/active_tab.rb @@ -11,7 +11,7 @@ module SharedActiveTab end 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 def ensure_active_sub_nav(content) @@ -23,7 +23,7 @@ module SharedActiveTab end 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 step 'no other sub navs should be active' do diff --git a/spec/features/admin/admin_active_tab_spec.rb b/spec/features/admin/admin_active_tab_spec.rb index 5ff791fc36a..1215908f5ea 100644 --- a/spec/features/admin/admin_active_tab_spec.rb +++ b/spec/features/admin/admin_active_tab_spec.rb @@ -14,8 +14,8 @@ RSpec.describe 'admin active tab' do shared_examples 'page has active sub tab' do |title| it "activates #{title} sub tab" do - expect(page).to have_selector('.sidebar-sub-level-items li.active', count: 1) - expect(page.find('.sidebar-sub-level-items li.active')).to have_content(title) + expect(page).to have_selector('.sidebar-sub-level-items > li.active', count: 2) + expect(page.all('.sidebar-sub-level-items > li.active')[1]).to have_content(title) end end diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 563818e8761..c490dce7ab0 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -48,7 +48,7 @@ feature 'Admin updates settings' do end scenario 'Change Slack Notifications Service template settings' do - click_link 'Service Templates' + first(:link, 'Service Templates').click click_link 'Slack notifications' fill_in 'Webhook', with: 'http://localhost' fill_in 'Username', with: 'test_user' diff --git a/spec/features/groups/members/request_access_spec.rb b/spec/features/groups/members/request_access_spec.rb index 1f3c7fd3859..10389a74703 100644 --- a/spec/features/groups/members/request_access_spec.rb +++ b/spec/features/groups/members/request_access_spec.rb @@ -51,7 +51,7 @@ feature 'Groups > Members > Request access' do expect(group.requesters.exists?(user_id: user)).to be_truthy - click_link 'Members' + first(:link, 'Members').click page.within('.content') do expect(page).not_to have_content(user.name) diff --git a/spec/javascripts/fly_out_nav_spec.js b/spec/javascripts/fly_out_nav_spec.js index 4588bf3d971..f8b37c0edde 100644 --- a/spec/javascripts/fly_out_nav_spec.js +++ b/spec/javascripts/fly_out_nav_spec.js @@ -34,6 +34,8 @@ describe('Fly out sidebar navigation', () => { document.body.innerHTML = ''; breakpointSize = 'lg'; mousePos.length = 0; + + setSidebar(null); }); describe('calculateTop', () => { @@ -242,6 +244,32 @@ describe('Fly out sidebar navigation', () => { ).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', () => { const subItems = el.querySelector('.sidebar-sub-level-items'); showSubLevelItems(el); @@ -283,10 +311,6 @@ describe('Fly out sidebar navigation', () => { }); describe('canShowActiveSubItems', () => { - afterEach(() => { - setSidebar(null); - }); - it('returns true by default', () => { expect( canShowActiveSubItems(el), diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js index 0c8c4d2cea6..60a452f2223 100644 --- a/spec/javascripts/issue_spec.js +++ b/spec/javascripts/issue_spec.js @@ -118,7 +118,7 @@ describe('Issue', function() { this.$triggeredButton = $btn; - this.$projectIssuesCounter = $('.issue_counter'); + this.$projectIssuesCounter = $('.issue_counter').first(); this.$projectIssuesCounter.text('1,001'); this.issueStateDeferred = new jQuery.Deferred(); |