.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **tracking_attrs('projects_side_navigation', 'render', 'projects_side_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? :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] : '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 = 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: [:clusters, :user, :gcp]) do = link_to project_clusters_path(@project), title: _('Kubernetes'), class: 'shortcuts-kubernetes' do %span = _('Kubernetes') - if show_cluster_hint .feature-highlight.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 } } - if show_cluster_hint .feature-highlight-popover-content = image_tag 'illustrations/cluster_popover.svg', class: 'feature-highlight-illustration', lazy: false, alt: _('Kubernetes popover') .feature-highlight-popover-sub-content %p= _('Allows you to add and manage Kubernetes clusters.') %p = _('Protip:') = link_to _('Auto DevOps'), help_page_path('topics/autodevops/index.md') %span= _('uses Kubernetes clusters to deploy your code!') %hr %button.gl-button.btn.btn-success.btn-sm.dismiss-feature-highlight{ type: 'button' } %span.gl-mr-2= _("Got it!") = sprite_icon('thumb-up') - 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') = render_if_exists 'projects/invite_members_side_nav_link', project: @project - 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') = render 'shared/sidebar_toggle_button' -# 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'