diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-20 23:50:22 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-20 23:50:22 +0000 |
commit | 9dc93a4519d9d5d7be48ff274127136236a3adb3 (patch) | |
tree | 70467ae3692a0e35e5ea56bcb803eb512a10bedb /app/views/layouts | |
parent | 4b0f34b6d759d6299322b3a54453e930c6121ff0 (diff) | |
download | gitlab-ce-9dc93a4519d9d5d7be48ff274127136236a3adb3.tar.gz |
Add latest changes from gitlab-org/gitlab@13-11-stable-eev13.11.0-rc43
Diffstat (limited to 'app/views/layouts')
23 files changed, 488 insertions, 511 deletions
diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml index 35fefe40d39..433337602f1 100644 --- a/app/views/layouts/_flash.html.haml +++ b/app/views/layouts/_flash.html.haml @@ -1,5 +1,5 @@ -# We currently only support `alert`, `notice`, `success`, 'toast' -- icons = {'alert' => 'error', 'notice' => 'information-o', 'success' => 'check-circle'}; +- icons = {'alert' => 'error', 'notice' => 'information-o', 'success' => 'check-circle'} .flash-container.flash-container-page.sticky{ data: { qa_selector: 'flash_container' } } - flash.each do |key, value| - if key == 'toast' && value diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 601598d65da..6694ad5968a 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -52,6 +52,8 @@ = stylesheet_link_tag 'performance_bar' if performance_bar_enabled? + -# Rendering this above Gon, to use in JS later + = render 'layouts/header/new_repo_experiment' = Gon::Base.render_data(nonce: content_security_policy_nonce) = javascript_include_tag locale_path unless I18n.locale == :en diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 1f2fcd1c70b..c91d27e3ed1 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -11,6 +11,7 @@ = render "layouts/broadcast" = render "layouts/header/read_only_banner" = render "layouts/header/registration_enabled_callout" + = render "layouts/header/service_templates_deprecation_callout" = render "layouts/nav/classification_level_banner" = yield :flash_message = render "shared/ping_consent" diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index c902c687378..2032d1e95a6 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -25,7 +25,7 @@ = hidden_field_tag :group_id, search_context.for_group? ? search_context.group.id : '', class: 'js-search-group-options', data: search_context.group_metadata = hidden_field_tag :project_id, search_context.for_project? ? search_context.project.id : '', id: 'search_project_id', class: 'js-search-project-options', data: search_context.project_metadata - - if search_context.for_project? + - if search_context.for_project? || search_context.for_group? = hidden_field_tag :scope, search_context.scope = hidden_field_tag :search_code, search_context.code_search? diff --git a/app/views/layouts/errors.html.haml b/app/views/layouts/errors.html.haml index 25fe4c898ca..57260ccedea 100644 --- a/app/views/layouts/errors.html.haml +++ b/app/views/layouts/errors.html.haml @@ -20,4 +20,10 @@ history.back(); }); } + + // We do not have rails_ujs here, so we're manually making a link trigger a form submit. + document.getElementById('sign_out_link').addEventListener('click', function(e) { + e.preventDefault(); + document.getElementById('sign_out_form').submit(); + }); }()); diff --git a/app/views/layouts/group_settings.html.haml b/app/views/layouts/group_settings.html.haml index 9db78ec58e4..c4e5e811280 100644 --- a/app/views/layouts/group_settings.html.haml +++ b/app/views/layouts/group_settings.html.haml @@ -1,4 +1,5 @@ - page_title _("Settings") - nav "group" +- enable_search_settings locals: { container_class: 'gl-my-5' } = render template: "layouts/group" diff --git a/app/views/layouts/header/_current_user_dropdown.html.haml b/app/views/layouts/header/_current_user_dropdown.html.haml index 5ac0db4137f..0251a8b6d7c 100644 --- a/app/views/layouts/header/_current_user_dropdown.html.haml +++ b/app/views/layouts/header/_current_user_dropdown.html.haml @@ -11,7 +11,7 @@ %li.divider - if can?(current_user, :update_user_status, current_user) %li - %button.btn.menu-item.js-set-status-modal-trigger{ type: 'button' } + %button.gl-button.btn.btn-link.menu-item.js-set-status-modal-trigger{ type: 'button' } - if show_status_emoji?(current_user.status) || user_status_set_to_busy?(current_user.status) = s_('SetStatusModal|Edit status') - else diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index c54ad23c094..481e83c9701 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -2,7 +2,7 @@ - user_status_data = user_status_properties(current_user) %header.navbar.navbar-gitlab.navbar-expand-sm.js-navbar{ data: { qa_selector: 'navbar' } } - %a.sr-only.gl-accessibility{ href: "#content-body", tabindex: "1" } Skip to content + %a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content .container-fluid .header-content .title-container @@ -19,10 +19,13 @@ %span.gl-badge.gl-bg-green-500.gl-text-white.gl-rounded-pill.gl-font-weight-bold.gl-py-1 = _('Next') - - if current_user - = render "layouts/nav/dashboard" + - if Feature.enabled?(:combined_menu, current_user, default_enabled: :yaml) + = render "layouts/nav/combined_menu" - else - = render "layouts/nav/explore" + - if current_user + = render "layouts/nav/dashboard" + - else + = render "layouts/nav/explore" .navbar-collapse.collapse %ul.nav.navbar-nav @@ -110,14 +113,15 @@ %li.nav-item %div - sign_in_text = allow_signup? ? _('Sign in / Register') : _('Sign in') - = link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in' + = link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'gl-button btn btn-default btn-sign-in' %button.navbar-toggler.d-block.d-sm-none{ type: 'button' } %span.sr-only= _('Toggle navigation') = sprite_icon('ellipsis_h', size: 12, css_class: 'more-icon js-navbar-toggle-right') = sprite_icon('close', size: 12, css_class: 'close-icon js-navbar-toggle-left') -#whats-new-app{ data: { storage_key: whats_new_storage_key, versions: whats_new_versions, gitlab_dot_com: Gitlab.dev_env_org_or_com? } } +- if display_whats_new? + #whats-new-app{ data: { version_digest: whats_new_version_digest } } - if can?(current_user, :update_user_status, current_user) .js-set-status-modal-wrapper{ data: user_status_data } diff --git a/app/views/layouts/header/_new_dropdown.haml b/app/views/layouts/header/_new_dropdown.html.haml index 1fc9831d271..7b49e6f716e 100644 --- a/app/views/layouts/header/_new_dropdown.haml +++ b/app/views/layouts/header/_new_dropdown.html.haml @@ -1,4 +1,4 @@ -%li.header-new.dropdown{ data: { track_label: "new_dropdown", track_event: "click_dropdown", track_value: "" } } +%li.header-new.dropdown{ data: { track_label: "new_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } } = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", id: "js-onboarding-new-project-link", title: _("New..."), ref: 'tooltip', aria: { label: _("New...") }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do = sprite_icon('plus-square') = sprite_icon('chevron-down', css_class: 'caret-down') @@ -37,8 +37,7 @@ = render 'layouts/header/project_invite_members_new_dropdown_item' %li.divider %li.dropdown-bold-header GitLab - - if current_user.can_create_project? - %li= link_to _('New project'), new_project_path, class: 'qa-global-new-project-link' + = content_for :new_repo_experiment - if current_user.can_create_group? %li= link_to _('New group'), new_group_path - if current_user.can?(:create_snippet) diff --git a/app/views/layouts/header/_new_repo_experiment.html.haml b/app/views/layouts/header/_new_repo_experiment.html.haml new file mode 100644 index 00000000000..73f960844cb --- /dev/null +++ b/app/views/layouts/header/_new_repo_experiment.html.haml @@ -0,0 +1,7 @@ +- content_for :new_repo_experiment do + - if current_user&.can_create_project? + - experiment(:new_repo, user: current_user) do |e| + - e.use do + %li= link_to _('New project'), new_project_path, class: 'qa-global-new-project-link', data: { track_experiment: 'new_repo', track_event: 'click_link', track_label: 'plus_menu_dropdown' } + - e.try do + %li= link_to _('New project/repository'), new_project_path, class: 'qa-global-new-project-link', data: { track_experiment: 'new_repo', track_event: 'click_link', track_label: 'plus_menu_dropdown' } diff --git a/app/views/layouts/header/_read_only_banner.html.haml b/app/views/layouts/header/_read_only_banner.html.haml index f3d563c362f..86c1d34c0b7 100644 --- a/app/views/layouts/header/_read_only_banner.html.haml +++ b/app/views/layouts/header/_read_only_banner.html.haml @@ -2,6 +2,6 @@ - if message .flash-container.flash-container-page .flash-notice - %div{ class: (container_class) } + %div{ class: container_class } %span = message diff --git a/app/views/layouts/header/_service_templates_deprecation_callout.html.haml b/app/views/layouts/header/_service_templates_deprecation_callout.html.haml new file mode 100644 index 00000000000..056d4426d5a --- /dev/null +++ b/app/views/layouts/header/_service_templates_deprecation_callout.html.haml @@ -0,0 +1,21 @@ +- return unless show_service_templates_deprecated_callout? + +- doc_link_start = "<a href=\"#{integrations_help_page_path}\" target='_blank' rel='noopener noreferrer'>".html_safe +- settings_link_start = "<a href=\"#{integrations_admin_application_settings_path}\">".html_safe + +%div{ class: [container_class, @content_class, 'gl-pt-5!'] } + .gl-alert.gl-alert-warning.js-service-templates-deprecated-callout{ role: 'alert', data: { feature_id: UserCalloutsHelper::SERVICE_TEMPLATES_DEPRECATED_CALLOUT, dismiss_endpoint: user_callouts_path } } + = sprite_icon('warning', size: 16, css_class: 'gl-alert-icon') + %button.gl-alert-dismiss.js-close{ type: 'button', aria: { label: _('Close') }, data: { testid: 'close-service-templates-deprecated-callout' } } + = sprite_icon('close', size: 16) + .gl-alert-title + = s_('AdminSettings|Service templates are deprecated and will be removed in GitLab 14.0.') + .gl-alert-body + = html_escape_once(s_('AdminSettings|You should migrate to %{doc_link_start}Project integration management%{link_end}, available at %{settings_link_start}Settings > Integrations.%{link_end}')).html_safe % { doc_link_start: doc_link_start, settings_link_start: settings_link_start, link_end: '</a>'.html_safe } + .gl-alert-actions + = link_to admin_application_settings_services_path, class: 'btn gl-alert-action btn-info btn-md gl-button' do + %span.gl-button-text + = s_('AdminSettings|See affected service templates') + = link_to "https://gitlab.com/gitlab-org/gitlab/-/issues/325905", class: 'btn gl-alert-action btn-default btn-md gl-button', target: '_blank', rel: 'noopener noreferrer' do + %span.gl-button-text + = _('Leave feedback') diff --git a/app/views/layouts/header/_whats_new_dropdown_item.html.haml b/app/views/layouts/header/_whats_new_dropdown_item.html.haml index f79b741ced0..9fe98a54aae 100644 --- a/app/views/layouts/header/_whats_new_dropdown_item.html.haml +++ b/app/views/layouts/header/_whats_new_dropdown_item.html.haml @@ -1,5 +1,6 @@ -%li - %button.gl-justify-content-space-between.gl-align-items-center.js-whats-new-trigger{ type: 'button', data: { storage_key: whats_new_storage_key }, class: 'gl-display-flex!' } - = _("What's new") - %span.js-whats-new-notification-count.whats-new-notification-count - = whats_new_most_recent_release_items_count +- if display_whats_new? + %li + %button.gl-justify-content-space-between.gl-align-items-center.js-whats-new-trigger{ type: 'button', class: 'gl-display-flex!' } + = _("What's new") + %span.js-whats-new-notification-count.whats-new-notification-count + = whats_new_most_recent_release_items_count diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index aeeffb6f4b6..c111714f552 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -9,7 +9,7 @@ = button_tag class: 'toggle-mobile-nav', type: 'button' do %span.sr-only= _("Open sidebar") = sprite_icon('hamburger', size: 18) - .breadcrumbs-links.js-title-container{ data: { qa_selector: 'breadcrumb_links_content' } } + .breadcrumbs-links{ data: { testid: 'breadcrumb-links', qa_selector: 'breadcrumb_links_content' } } %ul.list-unstyled.breadcrumbs-list.js-breadcrumbs-list - unless hide_top_links = header_title @@ -21,7 +21,7 @@ %li %h2.breadcrumbs-sub-title = link_to @breadcrumb_title, breadcrumb_title_link - %script{ type:'application/ld+json' } + %script{ type: 'application/ld+json' } :plain #{schema_breadcrumb_json} = yield :header_content diff --git a/app/views/layouts/nav/_combined_menu.html.haml b/app/views/layouts/nav/_combined_menu.html.haml new file mode 100644 index 00000000000..db5a7012e8f --- /dev/null +++ b/app/views/layouts/nav/_combined_menu.html.haml @@ -0,0 +1,3 @@ +%button{ type: 'button', data: { toggle: "dropdown" } } + = sprite_icon('ellipsis_v') + = _('Projects') diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index 7cbef6b00b1..42e3ae7e717 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -2,7 +2,7 @@ -# https://gitlab.com/gitlab-org/gitlab-foss/issues/49713 for more information. %ul.list-unstyled.navbar-sub-nav - if dashboard_nav_link?(:projects) - = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown", data: { track_label: "projects_dropdown", track_event: "click_dropdown" } }) do + = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown", data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_experiment: "new_repo" } }) do %button{ type: 'button', data: { toggle: "dropdown" } } = _('Projects') = sprite_icon('chevron-down', css_class: 'caret-down') @@ -50,7 +50,7 @@ = nav_link(controller: 'admin/dashboard') do = link_to admin_root_path, class: 'admin-icon qa-admin-area-link d-xl-none' do = _('Admin Area') - - if Feature.enabled?(:user_mode_in_session) + - if Gitlab::CurrentSettings.admin_mode - if header_link?(:admin_mode) = nav_link(controller: 'admin/sessions') do = link_to destroy_admin_session_path, method: :post, class: 'd-lg-none lock-open-icon' do @@ -69,7 +69,7 @@ = link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon('admin', size: 18) - - if Feature.enabled?(:user_mode_in_session) + - if Gitlab::CurrentSettings.admin_mode - if header_link?(:admin_mode) = nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block"}) do = link_to destroy_admin_session_path, method: :post, title: _('Leave Admin Mode'), aria: { label: _('Leave Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do diff --git a/app/views/layouts/nav/projects_dropdown/_show.html.haml b/app/views/layouts/nav/projects_dropdown/_show.html.haml index d8bf64fab64..b95a9cdb00f 100644 --- a/app/views/layouts/nav/projects_dropdown/_show.html.haml +++ b/app/views/layouts/nav/projects_dropdown/_show.html.haml @@ -11,14 +11,21 @@ = nav_link(path: 'projects#trending') do = link_to explore_root_path, data: { track_label: "projects_dropdown_explore_projects", track_event: "click_link" } do = _('Explore projects') - = nav_link(path: 'projects/new#blank_project', - html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }, - data: { track_label: "projects_dropdown_blank_project", track_event: "click_link" }) do - = link_to new_project_path(anchor: 'blank_project') do - = _('Create blank project') - = nav_link(path: 'projects/new#import_project') do - = link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link" } do - = _('Import project') + - experiment(:new_repo, user: current_user) do |e| + - e.use do + = nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do + = link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", track_experiment: "new_repo" } do + = _('Create blank project') + = nav_link(path: 'projects/new#import_project') do + = link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", track_experiment: "new_repo" } do + = _('Import project') + - e.try do + = nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do + = link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", track_experiment: "new_repo" } do + = _('Create blank project/repository') + = nav_link(path: 'projects/new#import_project') do + = link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", track_experiment: "new_repo" } do + = _('Import project/repository') = nav_link(path: 'projects/new#create_from_template') do = link_to new_project_path(anchor: 'create_from_template'), data: { track_label: "projects_dropdown_create_from_template", track_event: "click_link" } do = _('Create from template') diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index 7350db64462..41bec996de1 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -1,9 +1,9 @@ -- issues_count = group_open_issues_count(@group) -- merge_requests_count = group_merge_requests_count(state: 'opened') +- issues_count = cached_issuables_count(@group, type: :issues) +- merge_requests_count = group_open_merge_requests_count(@group) - aside_title = @group.subgroup? ? _('Subgroup navigation') : _('Group navigation') - overview_title = @group.subgroup? ? _('Subgroup overview') : _('Group overview') -%aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **tracking_attrs('groups_side_navigation', 'render', 'groups_side_navigation'), 'aria-label': aside_title } +%aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(@group), 'aria-label': aside_title } .nav-sidebar-inner-scroll .context-header = link_to group_path(@group), title: @group.name do @@ -91,14 +91,14 @@ .nav-icon-container = sprite_icon('git-merge') %span.nav-item-name - = _('Merge Requests') - %span.badge.badge-pill.count= number_with_delimiter(merge_requests_count) + = _('Merge requests') + %span.badge.badge-pill.count= 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.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge= number_with_delimiter(merge_requests_count) + = _('Merge requests') + %span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge= merge_requests_count = render_if_exists "layouts/nav/ee/security_link" # EE-specific @@ -145,7 +145,7 @@ %span.nav-item-name.qa-group-settings-item = _('Settings') %ul.sidebar-sub-level-items.qa-group-sidebar-submenu{ data: { testid: 'group-settings-menu' } } - = nav_link(path: %w[groups#projects groups#edit badges#index ci_cd#show], html_options: { class: "fly-out-top-item" } ) do + = nav_link(path: %w[groups#projects groups#edit badges#index ci_cd#show groups/applications#index], html_options: { class: "fly-out-top-item" } ) do = link_to edit_group_path(@group) do %strong.fly-out-top-item-name = _('Settings') @@ -175,6 +175,11 @@ %span = _('CI/CD') + = nav_link(controller: :applications) do + = link_to group_settings_applications_path(@group), title: _('Applications') do + %span + = _('Applications') + = render 'groups/sidebar/packages_settings' = render_if_exists "groups/ee/settings_nav" diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml index 4ae81d69c16..dda5e6b9636 100644 --- a/app/views/layouts/nav/sidebar/_profile.html.haml +++ b/app/views/layouts/nav/sidebar/_profile.html.haml @@ -1,4 +1,4 @@ -%aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **tracking_attrs('user_side_navigation', 'render', 'user_side_navigation'), 'aria-label': _('User settings') } +%aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(current_user), 'aria-label': _('User settings') } .nav-sidebar-inner-scroll .context-header = link_to profile_path, title: _('Profile Settings') do diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml index 4c331dbd69d..3d0c6baffd5 100644 --- a/app/views/layouts/nav/sidebar/_project.html.haml +++ b/app/views/layouts/nav/sidebar/_project.html.haml @@ -1,469 +1,3 @@ -%aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **tracking_attrs('projects_side_navigation', 'render', 'projects_side_navigation'), 'aria-label': _('Project navigation') } - .nav-sidebar-inner-scroll - .context-header - = link_to project_path(@project), title: @project.name do - .avatar-container.rect-avatar.s40.project-avatar - = project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile', width: 40, height: 40) - .sidebar-context-title - = @project.name - %ul.sidebar-top-level-items.qa-project-sidebar - = nav_link(path: sidebar_projects_paths, html_options: { class: 'home' }) do - = link_to project_path(@project), class: 'shortcuts-project rspec-project-link', data: { qa_selector: 'project_link' } do - .nav-icon-container - = sprite_icon('home') - %span.nav-item-name - = _('Project 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 - = _('Project 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') - - = nav_link(path: 'projects#activity') do - = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity', data: { qa_selector: 'activity_link' } do - %span= _('Activity') - - - if project_nav_tab?(:releases) - = nav_link(controller: :releases) do - = link_to project_releases_path(@project), title: _('Releases'), class: 'shortcuts-project-releases' do - %span= _('Releases') - - - if project_nav_tab? :learn_gitlab - = nav_link(controller: :learn_gitlab, html_options: { class: 'home' }) do - = link_to project_learn_gitlab_path(@project) do - .nav-icon-container - = sprite_icon('home') - %span.nav-item-name - = _('Learn GitLab') - - - if project_nav_tab? :files - = nav_link(controller: sidebar_repository_paths, unless: -> { current_path?('projects/graphs#charts') }) do - = link_to project_tree_path(@project), class: 'shortcuts-tree', data: { qa_selector: "repository_link" } do - .nav-icon-container - = sprite_icon('doc-text') - %span.nav-item-name#js-onboarding-repo-link - = _('Repository') - - %ul.sidebar-sub-level-items - = nav_link(controller: sidebar_repository_paths, 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') - - = nav_link(controller: [:commit, :commits]) do - = link_to project_commits_path(@project, current_ref), id: 'js-onboarding-commits-link' do - = _('Commits') - - = nav_link(html_options: {class: branches_tab_class}) do - = link_to project_branches_path(@project), data: { qa_selector: "branches_link" }, id: 'js-onboarding-branches-link' do - = _('Branches') - - = nav_link(controller: [:tags]) do - = link_to project_tags_path(@project), data: { qa_selector: "tags_link" } do - = _('Tags') - - = nav_link(path: 'graphs#show') do - = link_to project_graph_path(@project, current_ref) do - = _('Contributors') - - = nav_link(controller: %w(network)) do - = link_to project_network_path(@project, current_ref) do - = _('Graph') - - = nav_link(controller: :compare) do - = link_to project_compare_index_path(@project, from: @repository.root_ref, to: current_ref) do - = _('Compare') - - = render_if_exists 'projects/sidebar/repository_locked_files' - - - if project_nav_tab? :issues - = nav_link(controller: @project.issues_enabled? ? ['projects/issues', :labels, :milestones, :boards, :iterations] : 'projects/issues') do - = link_to project_issues_path(@project), class: 'shortcuts-issues qa-issues-item' do - .nav-icon-container - = sprite_icon('issues') - %span.nav-item-name#js-onboarding-issues-link - = _('Issues') - - if @project.issues_enabled? - %span.badge.badge-pill.count.issue_counter - = number_with_delimiter(@project.open_issues_count(current_user)) - - %ul.sidebar-sub-level-items - = nav_link(controller: 'projects/issues', action: :index, 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.badge-pill.count.issue_counter.fly-out-badge - = number_with_delimiter(@project.open_issues_count(current_user)) - %li.divider.fly-out-top-item - = nav_link(controller: :issues, action: :index) do - = link_to project_issues_path(@project), title: _('Issues') do - %span - = _('List') - - = nav_link(controller: :boards) do - = link_to project_boards_path(@project), title: boards_link_text, data: { qa_selector: "issue_boards_link" } do - %span - = boards_link_text - - = nav_link(controller: :labels) do - = link_to project_labels_path(@project), title: _('Labels'), class: 'qa-labels-link' do - %span - = _('Labels') - - = render 'projects/sidebar/issues_service_desk' - - = nav_link(controller: :milestones) do - = link_to project_milestones_path(@project), title: _('Milestones'), class: 'qa-milestones-link' do - %span - = _('Milestones') - - = render_if_exists 'layouts/nav/sidebar/project_iterations_link' - - - if project_nav_tab?(:external_issue_tracker) - - issue_tracker = @project.external_issue_tracker - - if issue_tracker.is_a?(JiraService) && project_jira_issues_integration? - = render_if_exists 'layouts/nav/sidebar/project_jira_issues_link', issue_tracker: issue_tracker - - else - = nav_link do - = link_to issue_tracker.issue_tracker_path, target: '_blank', rel: 'noopener noreferrer', class: 'shortcuts-external_tracker' do - .nav-icon-container - = sprite_icon('external-link') - %span.nav-item-name - = issue_tracker.title - %ul.sidebar-sub-level-items.is-fly-out-only - = nav_link(html_options: { class: "fly-out-top-item" } ) do - = link_to issue_tracker.issue_tracker_path, target: '_blank', rel: 'noopener noreferrer' do - %strong.fly-out-top-item-name - = issue_tracker.title - - - if (project_nav_tab? :labels) && !@project.issues_enabled? - = nav_link(controller: [:labels]) do - = link_to project_labels_path(@project), title: _('Labels'), class: 'shortcuts-labels qa-labels-items' do - .nav-icon-container - = sprite_icon('label') - %span.nav-item-name#js-onboarding-labels-link - = _('Labels') - - - if project_nav_tab? :merge_requests - = nav_link(controller: @project.issues_enabled? ? :merge_requests : [:merge_requests, :milestones]) do - = link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests', data: { qa_selector: 'merge_requests_link' } do - .nav-icon-container - = sprite_icon('git-merge') - %span.nav-item-name#js-onboarding-mr-link - = _('Merge Requests') - %span.badge.badge-pill.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.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge - = number_with_delimiter(@project.open_merge_requests_count) - - = render_if_exists "layouts/nav/requirements_link", project: @project - - - if project_nav_tab? :pipelines - = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases, :pipeline_editor], unless: -> { current_path?('projects/pipelines#charts') }) do - = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines', data: { qa_selector: 'ci_cd_link' } do - .nav-icon-container - = sprite_icon('rocket') - %span.nav-item-name#js-onboarding-pipelines-link - = _('CI/CD') - - %ul.sidebar-sub-level-items - = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases, :pipeline_editor], 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 - %span - = _('Pipelines') - - - if can_view_pipeline_editor?(@project) - = nav_link(controller: :pipeline_editor, action: :show) do - = link_to project_ci_pipeline_editor_path(@project), title: s_('Pipelines|Editor') do - %span - = s_('Pipelines|Editor') - - - if project_nav_tab? :builds - = nav_link(controller: :jobs) do - = link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do - %span - = _('Jobs') - - - if Feature.enabled?(:artifacts_management_page, @project) - = nav_link(controller: :artifacts, action: :index) do - = link_to project_artifacts_path(@project), title: _('Artifacts'), class: 'shortcuts-builds' do - %span - = _('Artifacts') - - - if project_nav_tab?(:pipelines) - = nav_link(controller: :pipeline_schedules) do - = link_to pipeline_schedules_path(@project), title: _('Schedules'), class: 'shortcuts-builds' do - %span - = _('Schedules') - - = render_if_exists "layouts/nav/test_cases_link", project: @project - - - if project_nav_tab? :security_and_compliance - = render_if_exists 'layouts/nav/sidebar/project_security_link' # EE-specific - - - if project_nav_tab? :operations - = nav_link(controller: sidebar_operations_paths) do - = link_to sidebar_operations_link_path, class: 'shortcuts-operations', data: { qa_selector: 'operations_link' } do - .nav-icon-container - = sprite_icon('cloud-gear') - %span.nav-item-name - = _('Operations') - - %ul.sidebar-sub-level-items - = nav_link(controller: sidebar_operations_paths, html_options: { class: "fly-out-top-item" } ) do - = link_to sidebar_operations_link_path do - %strong.fly-out-top-item-name - = _('Operations') - %li.divider.fly-out-top-item - - - if project_nav_tab? :metrics_dashboards - = nav_link(controller: :metrics_dashboard, action: [:show]) do - = link_to project_metrics_dashboard_path(@project), title: _('Metrics'), class: 'shortcuts-metrics', data: { qa_selector: 'operations_metrics_link' } do - %span - = _('Metrics') - - - if project_nav_tab?(:environments) && can?(current_user, :read_pod_logs, @project) - = nav_link(controller: :logs, action: [:index]) do - = link_to project_logs_path(@project), title: _('Logs') do - %span - = _('Logs') - - - if project_nav_tab? :environments - = render "layouts/nav/sidebar/tracing_link" - - - if project_nav_tab?(:error_tracking) - = nav_link(controller: :error_tracking) do - = link_to project_error_tracking_index_path(@project), title: _('Error Tracking') do - %span - = _('Error Tracking') - - - if project_nav_tab?(:alert_management) - = nav_link(controller: :alert_management) do - = link_to project_alert_management_index_path(@project), title: _('Alerts') do - %span - = _('Alerts') - - - if project_nav_tab?(:incidents) - = nav_link(controller: :incidents) do - = link_to project_incidents_path(@project), title: _('Incidents'), data: { qa_selector: 'operations_incidents_link' } do - %span - = _('Incidents') - - = render_if_exists 'projects/sidebar/oncall_schedules' - - - if project_nav_tab? :serverless - = nav_link(controller: :functions) do - = link_to project_serverless_functions_path(@project), title: _('Serverless') do - %span - = _('Serverless') - - - if project_nav_tab? :terraform - = nav_link(controller: :terraform) do - = link_to project_terraform_index_path(@project), title: _('Terraform') do - %span - = _('Terraform') - - - if project_nav_tab? :clusters - - show_cluster_hint = show_gke_cluster_integration_callout?(@project) - = nav_link(controller: [:cluster_agents, :clusters]) do - = link_to project_clusters_path(@project), title: _('Kubernetes'), class: 'shortcuts-kubernetes' do - %span - = _('Kubernetes') - - if show_cluster_hint - .js-feature-highlight{ disabled: true, - data: { trigger: 'manual', - container: 'body', - placement: 'right', - highlight: UserCalloutsHelper::GKE_CLUSTER_INTEGRATION, - highlight_priority: UserCallout.feature_names[:GKE_CLUSTER_INTEGRATION], - dismiss_endpoint: user_callouts_path, - auto_devops_help_path: help_page_path('topics/autodevops/index.md') } } - - if project_nav_tab? :environments - = nav_link(controller: :environments, action: [:index, :folder, :show, :new, :edit, :create, :update, :stop, :terminal]) do - = link_to project_environments_path(@project), title: _('Environments'), class: 'shortcuts-environments qa-operations-environments-link' do - %span - = _('Environments') - - - if project_nav_tab? :feature_flags - = nav_link(controller: :feature_flags) do - = link_to project_feature_flags_path(@project), title: _('Feature Flags'), class: 'shortcuts-feature-flags' do - %span - = _('Feature Flags') - - - if project_nav_tab?(:product_analytics) - = nav_link(controller: :product_analytics) do - = link_to project_product_analytics_path(@project), title: _('Product Analytics') do - %span - = _('Product Analytics') - - = render_if_exists 'layouts/nav/sidebar/project_packages_link' - - - if project_nav_tab? :analytics - = render 'layouts/nav/sidebar/analytics_links', links: project_analytics_navbar_links(@project, current_user) - - - if project_nav_tab?(:confluence) - - confluence_url = project_wikis_confluence_path(@project) - = nav_link do - = link_to confluence_url, class: 'shortcuts-confluence' do - .nav-icon-container - = image_tag 'confluence.svg', alt: _('Confluence') - %span.nav-item-name - = _('Confluence') - %ul.sidebar-sub-level-items.is-fly-out-only - = nav_link(html_options: { class: 'fly-out-top-item' } ) do - = link_to confluence_url, target: '_blank', rel: 'noopener noreferrer' do - %strong.fly-out-top-item-name - = _('Confluence') - - - if project_nav_tab? :wiki - = render 'layouts/nav/sidebar/wiki_link', wiki_url: wiki_path(@project.wiki) - - - if project_nav_tab?(:external_wiki) - - external_wiki_url = @project.external_wiki.external_wiki_url - = nav_link do - = link_to external_wiki_url, class: 'shortcuts-external_wiki' do - .nav-icon-container - = sprite_icon('external-link') - %span.nav-item-name - = _('External Wiki') - %ul.sidebar-sub-level-items.is-fly-out-only - = nav_link(html_options: { class: "fly-out-top-item" } ) do - = link_to external_wiki_url do - %strong.fly-out-top-item-name - = _('External Wiki') - - - if project_nav_tab? :snippets - = nav_link(controller: :snippets) do - = link_to project_snippets_path(@project), class: 'shortcuts-snippets', data: { qa_selector: 'snippets_link' } do - .nav-icon-container - = sprite_icon('snippet') - %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') - - = nav_link(controller: :project_members) do - = link_to project_project_members_path(@project), title: _('Members'), class: 'qa-members-link', id: 'js-onboarding-members-link' do - .nav-icon-container - = sprite_icon('users') - %span.nav-item-name - = _('Members') - %ul.sidebar-sub-level-items.is-fly-out-only - = nav_link(path: %w[members#show], html_options: { class: "fly-out-top-item" } ) do - = link_to project_project_members_path(@project) do - %strong.fly-out-top-item-name - = _('Members') - - - if project_nav_tab? :settings - = nav_link(path: sidebar_settings_paths) do - = link_to edit_project_path(@project) do - .nav-icon-container - = sprite_icon('settings') - %span.nav-item-name.qa-settings-item#js-onboarding-settings-link - = _('Settings') - - %ul.sidebar-sub-level-items - - can_edit = can?(current_user, :admin_project, @project) - - if can_edit - = nav_link(path: sidebar_settings_paths, 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'), class: 'qa-general-settings-link' do - %span - = _('General') - - if can_edit - = nav_link(controller: [:integrations, :services]) do - = link_to project_settings_integrations_path(@project), title: _('Integrations'), data: { qa_selector: 'integrations_settings_link' } do - %span - = _('Integrations') - = nav_link(controller: [:hooks, :hook_logs]) do - = link_to project_hooks_path(@project), title: _('Webhooks'), data: { qa_selector: 'webhooks_settings_link' } do - %span - = _('Webhooks') - - if project_access_token_available?(@project) - = nav_link(controller: [:access_tokens]) do - = link_to project_settings_access_tokens_path(@project), title: _('Access Tokens'), data: { qa_selector: 'access_tokens_settings_link' } do - %span - = _('Access Tokens') - = nav_link(controller: :repository) do - = link_to project_settings_repository_path(@project), title: _('Repository') do - %span - = _('Repository') - - if !@project.archived? && @project.feature_available?(:builds, current_user) - = nav_link(controller: :ci_cd) do - = link_to project_settings_ci_cd_path(@project), title: _('CI/CD') do - %span - = _('CI/CD') - - if settings_operations_available? - = nav_link(controller: [:operations]) do - = link_to project_settings_operations_path(@project), title: _('Operations'), data: { qa_selector: 'operations_settings_link' } do - = _('Operations') - - if @project.pages_available? - = nav_link(controller: :pages) do - = link_to project_pages_path(@project), title: _('Pages') do - %span - = _('Pages') - - -# Shortcut to Project > Activity - %li.hidden - = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity' do - %span - = _('Activity') - - -# Shortcut to Repository > Graph (formerly, Network) - - if project_nav_tab? :network - %li.hidden - = link_to project_network_path(@project, current_ref), title: _('Network'), class: 'shortcuts-network' do - = _('Graph') - - -# Shortcut to Issues > New Issue - - if project_nav_tab?(:issues) - %li.hidden - = link_to new_project_issue_path(@project), class: 'shortcuts-new-issue' do - = _('Create a new issue') - - -# Shortcut to Pipelines > Jobs - - if project_nav_tab? :builds - %li.hidden - = link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do - = _('Jobs') - - -# Shortcut to commits page - - if project_nav_tab? :commits - %li.hidden - = link_to project_commits_path(@project), title: _('Commits'), class: 'shortcuts-commits' do - = _('Commits') - - -# Shortcut to issue boards - - if project_nav_tab?(:issues) - %li.hidden - = link_to _('Issue Boards'), project_boards_path(@project), title: _('Issue Boards'), class: 'shortcuts-issue-boards' - - = render 'shared/sidebar_toggle_button' +-# We're migration the project sidebar to a logical model based structure. If you need to update +-# any of the existing menus, you can find them in app/views/layouts/nav/sidebar/_project_menus.html.haml. += render partial: 'shared/nav/sidebar', object: Sidebars::Projects::Panel.new(project_sidebar_context(@project, current_user, current_ref)) diff --git a/app/views/layouts/nav/sidebar/_project_menus.html.haml b/app/views/layouts/nav/sidebar/_project_menus.html.haml new file mode 100644 index 00000000000..ed072c0f6a2 --- /dev/null +++ b/app/views/layouts/nav/sidebar/_project_menus.html.haml @@ -0,0 +1,380 @@ +- if project_nav_tab? :issues + = nav_link(controller: @project.issues_enabled? ? ['projects/issues', :labels, :milestones, :boards, :iterations] : 'projects/issues') do + = link_to project_issues_path(@project), class: 'shortcuts-issues qa-issues-item' do + .nav-icon-container + = sprite_icon('issues') + %span.nav-item-name#js-onboarding-issues-link + = _('Issues') + - if @project.issues_enabled? + %span.badge.badge-pill.count.issue_counter + = number_with_delimiter(@project.open_issues_count(current_user)) + + %ul.sidebar-sub-level-items + = nav_link(controller: 'projects/issues', action: :index, 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.badge-pill.count.issue_counter.fly-out-badge + = number_with_delimiter(@project.open_issues_count(current_user)) + %li.divider.fly-out-top-item + = nav_link(controller: :issues, action: :index) do + = link_to project_issues_path(@project), title: _('Issues') do + %span + = _('List') + + = nav_link(controller: :boards) do + = link_to project_boards_path(@project), title: boards_link_text, data: { qa_selector: "issue_boards_link" } do + %span + = boards_link_text + + = nav_link(controller: :labels) do + = link_to project_labels_path(@project), title: _('Labels'), class: 'qa-labels-link' do + %span + = _('Labels') + + = render 'projects/sidebar/issues_service_desk' + + = nav_link(controller: :milestones) do + = link_to project_milestones_path(@project), title: _('Milestones'), class: 'qa-milestones-link' do + %span + = _('Milestones') + + = render_if_exists 'layouts/nav/sidebar/project_iterations_link' + +- if project_nav_tab?(:external_issue_tracker) + - issue_tracker = @project.external_issue_tracker + - if issue_tracker.is_a?(JiraService) && project_jira_issues_integration? + = render_if_exists 'layouts/nav/sidebar/project_jira_issues_link', issue_tracker: issue_tracker + - else + = nav_link do + = link_to issue_tracker.issue_tracker_path, target: '_blank', rel: 'noopener noreferrer', class: 'shortcuts-external_tracker' do + .nav-icon-container + = sprite_icon('external-link') + %span.nav-item-name + = issue_tracker.title + %ul.sidebar-sub-level-items.is-fly-out-only + = nav_link(html_options: { class: "fly-out-top-item" } ) do + = link_to issue_tracker.issue_tracker_path, target: '_blank', rel: 'noopener noreferrer' do + %strong.fly-out-top-item-name + = issue_tracker.title + +- if (project_nav_tab? :labels) && !@project.issues_enabled? + = nav_link(controller: [:labels]) do + = link_to project_labels_path(@project), title: _('Labels'), class: 'shortcuts-labels qa-labels-items' do + .nav-icon-container + = sprite_icon('label') + %span.nav-item-name#js-onboarding-labels-link + = _('Labels') + +- if project_nav_tab? :merge_requests + = nav_link(controller: @project.issues_enabled? ? :merge_requests : [:merge_requests, :milestones]) do + = link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests', data: { qa_selector: 'merge_requests_link' } do + .nav-icon-container + = sprite_icon('git-merge') + %span.nav-item-name#js-onboarding-mr-link + = _('Merge requests') + %span.badge.badge-pill.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.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge + = number_with_delimiter(@project.open_merge_requests_count) + += render_if_exists "layouts/nav/requirements_link", project: @project + +- if project_nav_tab? :pipelines + = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases, :pipeline_editor], unless: -> { current_path?('projects/pipelines#charts') }) do + = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines', data: { qa_selector: 'ci_cd_link' } do + .nav-icon-container + = sprite_icon('rocket') + %span.nav-item-name#js-onboarding-pipelines-link + = _('CI/CD') + + %ul.sidebar-sub-level-items + = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases, :pipeline_editor], 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 + %span + = _('Pipelines') + + - if can_view_pipeline_editor?(@project) + = nav_link(controller: :pipeline_editor, action: :show) do + = link_to project_ci_pipeline_editor_path(@project), title: s_('Pipelines|Editor') do + %span + = s_('Pipelines|Editor') + + - if project_nav_tab? :builds + = nav_link(controller: :jobs) do + = link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do + %span + = _('Jobs') + + - if Feature.enabled?(:artifacts_management_page, @project) + = nav_link(controller: :artifacts, action: :index) do + = link_to project_artifacts_path(@project), title: _('Artifacts'), class: 'shortcuts-builds' do + %span + = _('Artifacts') + + - if project_nav_tab?(:pipelines) + = nav_link(controller: :pipeline_schedules) do + = link_to pipeline_schedules_path(@project), title: _('Schedules'), class: 'shortcuts-builds' do + %span + = _('Schedules') + + = render_if_exists "layouts/nav/test_cases_link", project: @project + +- if project_nav_tab? :security_and_compliance + = render_if_exists 'layouts/nav/sidebar/project_security_link' # EE-specific + +- if project_nav_tab? :operations + = nav_link(controller: sidebar_operations_paths) do + = link_to sidebar_operations_link_path, class: 'shortcuts-operations', data: { qa_selector: 'operations_link' } do + .nav-icon-container + = sprite_icon('cloud-gear') + %span.nav-item-name + = _('Operations') + + %ul.sidebar-sub-level-items + = nav_link(controller: sidebar_operations_paths, html_options: { class: "fly-out-top-item" } ) do + = link_to sidebar_operations_link_path do + %strong.fly-out-top-item-name + = _('Operations') + %li.divider.fly-out-top-item + + - if project_nav_tab? :metrics_dashboards + = nav_link(controller: :metrics_dashboard, action: [:show]) do + = link_to project_metrics_dashboard_path(@project), title: _('Metrics'), class: 'shortcuts-metrics', data: { qa_selector: 'operations_metrics_link' } do + %span + = _('Metrics') + + - if project_nav_tab?(:environments) && can?(current_user, :read_pod_logs, @project) + = nav_link(controller: :logs, action: [:index]) do + = link_to project_logs_path(@project), title: _('Logs') do + %span + = _('Logs') + + - if project_nav_tab? :environments + = render "layouts/nav/sidebar/tracing_link" + + - if project_nav_tab?(:error_tracking) + = nav_link(controller: :error_tracking) do + = link_to project_error_tracking_index_path(@project), title: _('Error Tracking') do + %span + = _('Error Tracking') + + - if project_nav_tab?(:alert_management) + = nav_link(controller: :alert_management) do + = link_to project_alert_management_index_path(@project), title: _('Alerts') do + %span + = _('Alerts') + + - if project_nav_tab?(:incidents) + = nav_link(controller: :incidents) do + = link_to project_incidents_path(@project), title: _('Incidents'), data: { qa_selector: 'operations_incidents_link' } do + %span + = _('Incidents') + + = render_if_exists 'projects/sidebar/oncall_schedules' + + - if project_nav_tab? :serverless + = nav_link(controller: :functions) do + = link_to project_serverless_functions_path(@project), title: _('Serverless') do + %span + = _('Serverless') + + - if project_nav_tab? :terraform + = nav_link(controller: :terraform) do + = link_to project_terraform_index_path(@project), title: _('Terraform') do + %span + = _('Terraform') + + - if project_nav_tab? :clusters + - show_cluster_hint = show_gke_cluster_integration_callout?(@project) + = nav_link(controller: [:cluster_agents, :clusters]) do + = link_to project_clusters_path(@project), title: _('Kubernetes'), class: 'shortcuts-kubernetes' do + %span + = _('Kubernetes') + - if show_cluster_hint + .js-feature-highlight{ disabled: true, + data: { trigger: 'manual', + container: 'body', + placement: 'right', + highlight: UserCalloutsHelper::GKE_CLUSTER_INTEGRATION, + highlight_priority: UserCallout.feature_names[:GKE_CLUSTER_INTEGRATION], + dismiss_endpoint: user_callouts_path, + auto_devops_help_path: help_page_path('topics/autodevops/index.md') } } + - if project_nav_tab? :environments + = nav_link(controller: :environments, action: [:index, :folder, :show, :new, :edit, :create, :update, :stop, :terminal]) do + = link_to project_environments_path(@project), title: _('Environments'), class: 'shortcuts-environments qa-operations-environments-link' do + %span + = _('Environments') + + - if project_nav_tab? :feature_flags + = nav_link(controller: :feature_flags) do + = link_to project_feature_flags_path(@project), title: _('Feature Flags'), class: 'shortcuts-feature-flags' do + %span + = _('Feature Flags') + + - if project_nav_tab?(:product_analytics) + = nav_link(controller: :product_analytics) do + = link_to project_product_analytics_path(@project), title: _('Product Analytics') do + %span + = _('Product Analytics') + += render_if_exists 'layouts/nav/sidebar/project_packages_link' + +- if project_nav_tab? :analytics + = render 'layouts/nav/sidebar/analytics_links', links: project_analytics_navbar_links(@project, current_user) + +- if project_nav_tab?(:confluence) + - confluence_url = project_wikis_confluence_path(@project) + = nav_link do + = link_to confluence_url, class: 'shortcuts-confluence' do + .nav-icon-container + = image_tag 'confluence.svg', alt: _('Confluence') + %span.nav-item-name + = _('Confluence') + %ul.sidebar-sub-level-items.is-fly-out-only + = nav_link(html_options: { class: 'fly-out-top-item' } ) do + = link_to confluence_url, target: '_blank', rel: 'noopener noreferrer' do + %strong.fly-out-top-item-name + = _('Confluence') + +- if project_nav_tab? :wiki + = render 'layouts/nav/sidebar/wiki_link', wiki_url: wiki_path(@project.wiki) + +- if project_nav_tab?(:external_wiki) + - external_wiki_url = @project.external_wiki.external_wiki_url + = nav_link do + = link_to external_wiki_url, class: 'shortcuts-external_wiki' do + .nav-icon-container + = sprite_icon('external-link') + %span.nav-item-name + = s_('ExternalWikiService|External wiki') + %ul.sidebar-sub-level-items.is-fly-out-only + = nav_link(html_options: { class: "fly-out-top-item" } ) do + = link_to external_wiki_url do + %strong.fly-out-top-item-name + = s_('ExternalWikiService|External wiki') + +- if project_nav_tab? :snippets + = nav_link(controller: :snippets) do + = link_to project_snippets_path(@project), class: 'shortcuts-snippets', data: { qa_selector: 'snippets_link' } do + .nav-icon-container + = sprite_icon('snippet') + %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') + += nav_link(controller: :project_members) do + = link_to project_project_members_path(@project), title: _('Members'), class: 'qa-members-link', id: 'js-onboarding-members-link' do + .nav-icon-container + = sprite_icon('users') + %span.nav-item-name + = _('Members') + %ul.sidebar-sub-level-items.is-fly-out-only + = nav_link(path: %w[members#show], html_options: { class: "fly-out-top-item" } ) do + = link_to project_project_members_path(@project) do + %strong.fly-out-top-item-name + = _('Members') + +- if project_nav_tab? :settings + = nav_link(path: sidebar_settings_paths) do + = link_to edit_project_path(@project) do + .nav-icon-container + = sprite_icon('settings') + %span.nav-item-name.qa-settings-item#js-onboarding-settings-link + = _('Settings') + + %ul.sidebar-sub-level-items + - can_edit = can?(current_user, :admin_project, @project) + - if can_edit + = nav_link(path: sidebar_settings_paths, 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'), class: 'qa-general-settings-link' do + %span + = _('General') + - if can_edit + = nav_link(controller: [:integrations, :services]) do + = link_to project_settings_integrations_path(@project), title: _('Integrations'), data: { qa_selector: 'integrations_settings_link' } do + %span + = _('Integrations') + = nav_link(controller: [:hooks, :hook_logs]) do + = link_to project_hooks_path(@project), title: _('Webhooks'), data: { qa_selector: 'webhooks_settings_link' } do + %span + = _('Webhooks') + - if can?(current_user, :read_resource_access_tokens, @project) + = nav_link(controller: [:access_tokens]) do + = link_to project_settings_access_tokens_path(@project), title: _('Access Tokens'), data: { qa_selector: 'access_tokens_settings_link' } do + %span + = _('Access Tokens') + = nav_link(controller: :repository) do + = link_to project_settings_repository_path(@project), title: _('Repository') do + %span + = _('Repository') + - if !@project.archived? && @project.feature_available?(:builds, current_user) + = nav_link(controller: :ci_cd) do + = link_to project_settings_ci_cd_path(@project), title: _('CI/CD') do + %span + = _('CI/CD') + - if settings_operations_available? + = nav_link(controller: [:operations]) do + = link_to project_settings_operations_path(@project), title: _('Operations'), data: { qa_selector: 'operations_settings_link' } do + = _('Operations') + - if @project.pages_available? + = nav_link(controller: :pages) do + = link_to project_pages_path(@project), title: _('Pages') do + %span + = _('Pages') + +-# Shortcut to Project > Activity +%li.hidden + = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity' do + %span + = _('Activity') + +-# Shortcut to Repository > Graph (formerly, Network) +- if project_nav_tab? :network + %li.hidden + = link_to project_network_path(@project, current_ref), title: _('Network'), class: 'shortcuts-network' do + = _('Graph') + +-# Shortcut to Issues > New Issue +- if project_nav_tab?(:issues) + %li.hidden + = link_to new_project_issue_path(@project), class: 'shortcuts-new-issue' do + = _('Create a new issue') + +-# Shortcut to Pipelines > Jobs +- if project_nav_tab? :builds + %li.hidden + = link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do + = _('Jobs') + +-# Shortcut to commits page +- if project_nav_tab? :commits + %li.hidden + = link_to project_commits_path(@project), title: _('Commits'), class: 'shortcuts-commits' do + = _('Commits') + +-# Shortcut to issue boards +- if project_nav_tab?(:issues) + %li.hidden + = link_to _('Issue Boards'), project_boards_path(@project), title: _('Issue Boards'), class: 'shortcuts-issue-boards' diff --git a/app/views/layouts/nav/sidebar/_project_packages_link.html.haml b/app/views/layouts/nav/sidebar/_project_packages_link.html.haml index e9989abe5a0..b28468a7969 100644 --- a/app/views/layouts/nav/sidebar/_project_packages_link.html.haml +++ b/app/views/layouts/nav/sidebar/_project_packages_link.html.haml @@ -1,14 +1,14 @@ - packages_link = project_nav_tab?(:packages) ? project_packages_path(@project) : project_container_registry_index_path(@project) - if (project_nav_tab?(:packages) || project_nav_tab?(:container_registry)) - = nav_link controller: [:packages, :repositories] do + = nav_link controller: [:packages, :repositories, :infrastructure_registry] do = link_to packages_link, data: { qa_selector: 'packages_link' } do .nav-icon-container = sprite_icon('package') %span.nav-item-name = _('Packages & Registries') %ul.sidebar-sub-level-items - = nav_link(controller: [:packages, :repositories], html_options: { class: "fly-out-top-item" } ) do + = nav_link(controller: [:packages, :repositories, :infrastructure_registry], html_options: { class: "fly-out-top-item" } ) do = link_to packages_link do %strong.fly-out-top-item-name = _('Packages & Registries') @@ -21,3 +21,7 @@ = nav_link controller: :repositories do = link_to project_container_registry_index_path(@project), class: 'shortcuts-container-registry', title: _('Container Registry') do %span= _('Container Registry') + - if project_nav_tab? :infrastructure_registry + = nav_link controller: :infrastructure_registry do + = link_to project_infrastructure_registry_index_path(@project), title: _('Infrastructure Registry') do + %span= _('Infrastructure Registry') diff --git a/app/views/layouts/project_settings.html.haml b/app/views/layouts/project_settings.html.haml index 93214c2a674..97d9f2fbc78 100644 --- a/app/views/layouts/project_settings.html.haml +++ b/app/views/layouts/project_settings.html.haml @@ -1,4 +1,6 @@ - page_title _("Settings") - nav "project" +- enable_search_settings locals: { container_class: 'gl-my-5' } + = render template: "layouts/project" |