1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
- has_impersonation_link = header_link?(:admin_impersonation)
- user_status_data = user_status_properties(current_user)
%header.navbar.navbar-gitlab.navbar-expand-sm.js-navbar{ data: { qa_selector: 'navbar' } }
%a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content
.container-fluid
.header-content.js-header-content
.title-container.hide-when-top-nav-responsive-open.gl-transition-medium.gl-display-flex.gl-align-items-stretch.gl-pt-0.gl-mr-3
.title
%span.gl-sr-only GitLab
= link_to root_path, title: _('Dashboard'), id: 'logo', class: 'has-tooltip', **tracking_attrs('main_navigation', 'click_gitlab_logo_link', 'navigation') do
= brand_header_logo
.gl-display-flex.gl-align-items-center
- if Gitlab.com_and_canary?
= gl_badge_tag({ variant: :success, size: :sm }, { href: Gitlab::Saas.canary_toggle_com_url, data: { qa_selector: 'canary_badge_link' }, target: :_blank, rel: 'noopener noreferrer', class: 'canary-badge' }) do
= _('Next')
- if current_user
.gl-display-none.gl-sm-display-block
= render "layouts/nav/top_nav"
- else
- experiment(:logged_out_marketing_header, actor: nil) do |e|
- e.candidate do
= render 'layouts/header/marketing_links'
- e.try(:trial_focused) do
= render 'layouts/header/marketing_links'
- e.control do
.gl-display-none.gl-sm-display-block
= render "layouts/nav/top_nav"
- if top_nav_show_search && Feature.enabled?(:new_navbar_layout)
.navbar-collapse.gl-transition-medium.collapse.gl-mr-auto.global-search-container.hide-when-top-nav-responsive-open
- search_menu_item = top_nav_search_menu_item_attrs
%ul.nav.navbar-nav.gl-w-full.gl-align-items-center
%li.nav-item.header-search-new.gl-display-none.gl-lg-display-block.gl-w-full
- unless current_controller?(:search)
- if Feature.enabled?(:new_header_search)
= render 'layouts/header_search'
- else
= render 'layouts/search'
%li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' }
= link_to search_menu_item.fetch(:href), title: search_menu_item.fetch(:title), aria: { label: search_menu_item.fetch(:title) }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon(search_menu_item.fetch(:icon))
.navbar-collapse.gl-transition-medium.collapse{ class: ('global-search-container' unless Feature.enabled?(:new_navbar_layout)) }
%ul.nav.navbar-nav.gl-w-full.gl-align-items-center.gl-justify-content-end
- if current_user
= render 'layouts/header/new_dropdown', class: 'gl-display-none gl-sm-display-block gl-white-space-nowrap gl-text-right'
- if top_nav_show_search && Feature.disabled?(:new_navbar_layout)
- search_menu_item = top_nav_search_menu_item_attrs
%li.nav-item.header-search-new.gl-display-none.gl-lg-display-block.gl-w-full
- unless current_controller?(:search)
- if Feature.enabled?(:new_header_search)
= render 'layouts/header_search'
- else
= render 'layouts/search'
%li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' }
= link_to search_menu_item.fetch(:href), title: search_menu_item.fetch(:title), aria: { label: search_menu_item.fetch(:title) }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon(search_menu_item.fetch(:icon))
- if header_link?(:issues)
= nav_link(path: 'dashboard#issues', html_options: { class: "user-counter" }) do
= link_to assigned_issues_dashboard_path, title: _('Issues'), class: 'dashboard-shortcuts-issues js-prefetch-document', aria: { label: _('Issues') },
data: { qa_selector: 'issues_shortcut_button', toggle: 'tooltip', placement: 'bottom',
track_label: 'main_navigation',
track_action: 'click_issues_link',
track_property: 'navigation',
container: 'body' } do
= sprite_icon('issues')
- issues_count = assigned_issuables_count(:issues)
= gl_badge_tag({ size: :sm, variant: :success }, { class: "gl-ml-n2 #{(' gl-display-none' if issues_count == 0)}", "aria-label": n_("%d assigned issue", "%d assigned issues", issues_count) % issues_count }) do
= number_with_delimiter(issues_count)
- if header_link?(:merge_requests)
= nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter dropdown" }) do
- top_level_link = assigned_mrs_dashboard_path
= link_to top_level_link, class: 'dashboard-shortcuts-merge_requests has-tooltip', title: _('Merge requests'), aria: { label: _('Merge requests') },
data: { qa_selector: 'merge_requests_shortcut_button',
toggle: "dropdown",
placement: 'bottom',
track_label: 'main_navigation',
track_action: 'click_merge_link',
track_property: 'navigation',
container: 'body' } do
= sprite_icon('git-merge')
= gl_badge_tag({ size: :sm, variant: :warning }, { class: "js-merge-requests-count gl-ml-n2#{(' gl-display-none' if user_merge_requests_counts[:total] == 0)}", "aria-label": n_("%d merge request", "%d merge requests", user_merge_requests_counts[:total]) % user_merge_requests_counts[:total] }) do
= number_with_delimiter(user_merge_requests_counts[:total])
= sprite_icon('chevron-down', css_class: 'caret-down gl-mx-0!')
.dropdown-menu.dropdown-menu-right
%ul
%li.dropdown-header
= _('Merge requests')
%li
= link_to assigned_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center js-prefetch-document' do
= _('Assigned to you')
= gl_badge_tag({ variant: :neutral, size: :sm }, { class: "js-assigned-mr-count gl-ml-auto" }) do
= user_merge_requests_counts[:assigned]
%li
= link_to reviewer_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center js-prefetch-document' do
= _('Review requests for you')
= gl_badge_tag({ variant: :neutral, size: :sm }, { class: "js-reviewer-mr-count gl-ml-auto" }) do
= user_merge_requests_counts[:review_requested]
- if header_link?(:todos)
= nav_link(controller: 'dashboard/todos', html_options: { class: "user-counter" }) do
= link_to dashboard_todos_path, title: _('To-Do List'), aria: { label: _('To-Do List') }, class: 'shortcuts-todos js-prefetch-document',
data: { qa_selector: 'todos_shortcut_button', toggle: 'tooltip', placement: 'bottom',
track_label: 'main_navigation',
track_action: 'click_to_do_link',
track_property: 'navigation',
container: 'body' } do
= sprite_icon('todo-done')
-# The todos' counter badge's visibility is being toggled by adding or removing the .hidden class in Js.
-# We'll eventually migrate to .gl-display-none: https://gitlab.com/gitlab-org/gitlab/-/issues/351792.
= gl_badge_tag({ size: :sm, variant: :info }, { class: "js-todos-count gl-ml-n2#{(' hidden' if todos_pending_count == 0)}", "aria-label": _("Todos count") }) do
= todos_count_format(todos_pending_count)
%li.nav-item.header-help.dropdown.d-none.d-md-block{ data: { track_action: 'click_question_mark_link', track_label: 'main_navigation', track_property: 'navigation', track_experiment: 'cross_stage_fdm' } }
= link_to help_path, class: 'header-help-dropdown-toggle gl-relative', data: { toggle: "dropdown" } do
%span.gl-sr-only
= s_('Nav|Help')
= sprite_icon('question-o')
%span.notification-dot.rounded-circle.gl-absolute
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right
= render 'layouts/header/help_dropdown'
- unless current_user
- experiment(:logged_out_marketing_header, actor: nil) do |e|
- e.candidate do
%li.nav-item.gl-display-none.gl-sm-display-block
= render "layouts/nav/top_nav"
- e.try(:trial_focused) do
%li.nav-item.gl-display-none.gl-sm-display-block
= render "layouts/nav/top_nav"
- e.control {}
- if header_link?(:user_dropdown)
%li.nav-item.header-user.js-nav-user-dropdown.dropdown{ data: { track_label: "profile_dropdown", track_action: "click_dropdown", track_value: "", qa_selector: 'user_menu', testid: 'user-menu' }, class: ('mr-0' if has_impersonation_link) }
= link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do
= render Pajamas::AvatarComponent.new(current_user, size: 24, class: 'header-user-avatar qa-user-avatar')
= render_if_exists 'layouts/header/user_notification_dot', project: project, namespace: group
= sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right
= render 'layouts/header/current_user_dropdown'
- if has_impersonation_link
%li.nav-item.impersonation.ml-0
= link_to admin_impersonation_path, class: 'nav-link impersonation-btn', method: :delete, title: _('Stop impersonation'), aria: { label: _('Stop impersonation') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body', qa_selector: 'stop_impersonation_link' } do
= sprite_icon('incognito', size: 18)
- if header_link?(:sign_in)
- experiment(:logged_out_marketing_header, actor: nil) do |e|
- e.candidate do
%li.nav-item.gl-display-none.gl-sm-display-block
= link_to _('Sign up now'), new_user_registration_path, class: 'gl-button btn btn-default btn-sign-in', data: { track_action: 'click_button', track_experiment: e.name, track_label: 'sign_up_now' }
%li.nav-item.gl-display-none.gl-sm-display-block
= link_to _('Login'), new_session_path(:user, redirect_to_referer: 'yes')
= render 'layouts/header/sign_in_register_button', class: 'gl-sm-display-none'
- e.try(:trial_focused) do
%li.nav-item.gl-display-none.gl-sm-display-block
= link_to _('Get a free trial'), 'https://about.gitlab.com/free-trial/', class: 'gl-button btn btn-default btn-sign-in', data: { track_action: 'click_button', track_experiment: e.name, track_label: 'get_a_free_trial' }
%li.nav-item.gl-display-none.gl-sm-display-block
= link_to _('Sign up'), new_user_registration_path, data: { track_action: 'click_button', track_experiment: e.name, track_label: 'sign_up' }
%li.nav-item.gl-display-none.gl-sm-display-block
= link_to _('Login'), new_session_path(:user, redirect_to_referer: 'yes')
= render 'layouts/header/sign_in_register_button', class: 'gl-sm-display-none'
- e.control do
= render 'layouts/header/sign_in_register_button'
%button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: 'gl-border-none!', data: { testid: 'top-nav-responsive-toggle', qa_selector: 'mobile_navbar_button' } }
%span.sr-only= _('Toggle navigation')
%span.more-icon.gl-px-3.gl-font-sm.gl-font-weight-bold
%span.gl-pr-2= _('Menu')
= sprite_icon('hamburger', size: 16)
= sprite_icon('close', size: 12, css_class: 'close-icon')
- 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 }
|