Merge branch 'fly-out-top-level-item' into 'master'
Add top level items to fly-out navigation Closes #36294 See merge request !13981
This commit is contained in:
commit
b8adc0d042
15 changed files with 271 additions and 26 deletions
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue