diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-20 08:43:02 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-20 08:43:02 +0000 |
commit | d9ab72d6080f594d0b3cae15f14b3ef2c6c638cb (patch) | |
tree | 2341ef426af70ad1e289c38036737e04b0aa5007 /app/views | |
parent | d6e514dd13db8947884cd58fe2a9c2a063400a9b (diff) | |
download | gitlab-ce-d9ab72d6080f594d0b3cae15f14b3ef2c6c638cb.tar.gz |
Add latest changes from gitlab-org/gitlab@14-4-stable-eev14.4.0-rc42
Diffstat (limited to 'app/views')
160 files changed, 845 insertions, 790 deletions
diff --git a/app/views/admin/application_settings/_abuse.html.haml b/app/views/admin/application_settings/_abuse.html.haml index fab3ce584f0..96fb848b568 100644 --- a/app/views/admin/application_settings/_abuse.html.haml +++ b/app/views/admin/application_settings/_abuse.html.haml @@ -5,7 +5,5 @@ .form-group = f.label :abuse_notification_email, _('Abuse reports notification email'), class: 'label-bold' = f.text_field :abuse_notification_email, class: 'form-control gl-form-input' - .form-text.text-muted - = _('Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.') = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/_account_and_limit.html.haml b/app/views/admin/application_settings/_account_and_limit.html.haml index eb30efabb98..19c38d7be62 100644 --- a/app/views/admin/application_settings/_account_and_limit.html.haml +++ b/app/views/admin/application_settings/_account_and_limit.html.haml @@ -23,11 +23,11 @@ .form-group = f.label :max_import_size, _('Maximum import size (MB)'), class: 'label-light' = f.number_field :max_import_size, class: 'form-control gl-form-input qa-receive-max-import-size-field', title: _('Maximum size of import files.'), data: { toggle: 'tooltip', container: 'body' } - %span.form-text.text-muted= _('0 for unlimited, only effective with remote storage enabled.') + %span.form-text.text-muted= _('Only effective when remote storage is enabled. Set to 0 for no size limit.') .form-group = f.label :session_expire_delay, _('Session duration (minutes)'), class: 'label-light' = f.number_field :session_expire_delay, class: 'form-control gl-form-input', title: _('Maximum duration of a session.'), data: { toggle: 'tooltip', container: 'body' } - %span.form-text.text-muted#session_expire_delay_help_block= _('GitLab restart is required to apply changes.') + %span.form-text.text-muted#session_expire_delay_help_block= _('Restart GitLab to apply changes.') = render_if_exists 'admin/application_settings/git_two_factor_session_expiry', form: f = render_if_exists 'admin/application_settings/personal_access_token_expiration_policy', form: f @@ -45,13 +45,13 @@ .form-check = f.check_box :user_default_external, class: 'form-check-input' = f.label :user_default_external, class: 'form-check-label' do - = _('Newly registered users will by default be external') + = _('Newly-registered users are external by default') .gl-mt-3 = _('Internal users') = f.text_field :user_default_internal_regex, placeholder: _('Regex pattern'), class: 'form-control gl-form-input gl-mt-2' .help-block - = _('Specify an e-mail address regex pattern to identify default internal users.') - = link_to _('More information'), help_page_path('user/permissions', anchor: 'setting-new-users-to-external'), + = _('Specify an email address regex pattern to identify default internal users.') + = link_to _('Learn more'), help_page_path('user/permissions', anchor: 'setting-new-users-to-external'), target: '_blank' - unless Gitlab.com? .form-group @@ -59,11 +59,13 @@ .form-check = f.check_box :deactivate_dormant_users, class: 'form-check-input' = f.label :deactivate_dormant_users, class: 'form-check-label' do - = _('Deactivate dormant users after 90 days of inactivity. Users can return to active status by signing in to their account. While inactive, a user is not counted as an active user in the instance.') - = link_to _('More information'), help_page_path('user/admin_area/moderate_users', anchor: 'automatically-deactivate-dormant-users'), target: '_blank' + = _('Deactivate dormant users after 90 days of inactivity') + .help-block + = _('Users can reactivate their account by signing in.') + = link_to _('Learn more'), help_page_path('user/admin_area/moderate_users', anchor: 'automatically-deactivate-dormant-users'), target: '_blank' .form-group = f.label :personal_access_token_prefix, _('Personal Access Token prefix'), class: 'label-light' - = f.text_field :personal_access_token_prefix, placeholder: _('Max 20 characters'), class: 'form-control gl-form-input' + = f.text_field :personal_access_token_prefix, placeholder: _('Maximum 20 characters'), class: 'form-control gl-form-input' .form-group = f.label :user_show_add_ssh_key_message, _('Prompt users to upload SSH keys'), class: 'label-bold' .form-check diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml index fea116bd419..8026ec4702b 100644 --- a/app/views/admin/application_settings/_ci_cd.html.haml +++ b/app/views/admin/application_settings/_ci_cd.html.haml @@ -69,5 +69,12 @@ %p.form-text.text-muted = _("The default CI/CD configuration file and path for new projects.").html_safe = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'specify-a-custom-cicd-configuration-file'), target: '_blank' + .form-group + .form-check + = f.check_box :suggest_pipeline_enabled, class: 'form-check-input' + = f.label :suggest_pipeline_enabled, class: 'form-check-label' do + = s_('AdminSettings|Enable pipeline suggestion banner') + .form-text.text-muted + = s_('AdminSettings|Display a banner on merge requests in projects with no pipelines to initiate steps to add a .gitlab-ci.yml file.') = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/_files_limits.html.haml b/app/views/admin/application_settings/_files_limits.html.haml deleted file mode 100644 index 9cd12fa1caa..00000000000 --- a/app/views/admin/application_settings/_files_limits.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -= gitlab_ui_form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-files-limits-settings'), html: { class: 'fieldset-form' } do |f| - = form_errors(@application_setting) - - %fieldset - %legend.h5.gl-border-none - = _('Unauthenticated API request rate limit') - .form-group - = f.gitlab_ui_checkbox_component :throttle_unauthenticated_files_api_enabled, - _('Enable unauthenticated API request rate limit'), - help_text: _('Helps reduce request volume (e.g. from crawlers or abusive bots)'), - checkbox_options: { data: { qa_selector: 'throttle_unauthenticated_files_api_checkbox' } } - .form-group - = f.label :throttle_unauthenticated_files_api_requests_per_period, 'Max unauthenticated API requests per period per IP', class: 'label-bold' - = f.number_field :throttle_unauthenticated_files_api_requests_per_period, class: 'form-control gl-form-input' - .form-group - = f.label :throttle_unauthenticated_files_api_period_in_seconds, 'Unauthenticated API rate limit period in seconds', class: 'label-bold' - = f.number_field :throttle_unauthenticated_files_api_period_in_seconds, class: 'form-control gl-form-input' - - %fieldset - %legend.h5.gl-border-none - = _('Authenticated API request rate limit') - .form-group - = f.gitlab_ui_checkbox_component :throttle_authenticated_files_api_enabled, - _('Enable authenticated API request rate limit'), - help_text: _('Helps reduce request volume (e.g. from crawlers or abusive bots)'), - checkbox_options: { data: { qa_selector: 'throttle_authenticated_files_api_checkbox' } } - .form-group - = f.label :throttle_authenticated_files_api_requests_per_period, 'Max authenticated API requests per period per user', class: 'label-bold' - = f.number_field :throttle_authenticated_files_api_requests_per_period, class: 'form-control gl-form-input' - .form-group - = f.label :throttle_authenticated_files_api_period_in_seconds, 'Authenticated API rate limit period in seconds', class: 'label-bold' - = f.number_field :throttle_authenticated_files_api_period_in_seconds, class: 'form-control gl-form-input' - - = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/admin/application_settings/_help_page.html.haml b/app/views/admin/application_settings/_help_page.html.haml index ecf3203df9a..cd7eaa1896a 100644 --- a/app/views/admin/application_settings/_help_page.html.haml +++ b/app/views/admin/application_settings/_help_page.html.haml @@ -18,11 +18,10 @@ = f.text_field :help_page_support_url, class: 'form-control gl-form-input', placeholder: 'https://company.example.com/getting-help', :'aria-describedby' => 'support_help_block' %span.form-text.text-muted#support_help_block= _('Alternate support URL for Help page and Help dropdown.') - - if show_documentation_base_url_field? - .form-group - = f.label :help_page_documentation_base_url, _('Documentation pages URL'), class: 'label-bold' - = f.text_field :help_page_documentation_base_url, class: 'form-control gl-form-input', placeholder: 'https://docs.gitlab.com' - - docs_link_url = help_page_path('user/admin_area/settings/help_page', anchor: 'destination-requirements') - - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url } - %span.form-text.text-muted#support_help_block= html_escape(_('Requests for pages at %{code_start}%{help_text_url}%{code_end} redirect to the URL. The destination must meet certain requirements. %{docs_link_start}Learn more.%{docs_link_end}')) % { code_start: '<code>'.html_safe, help_text_url: help_url, code_end: '</code>'.html_safe, docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe } + .form-group + = f.label :help_page_documentation_base_url, _('Documentation pages URL'), class: 'gl-font-weight-bold' + = f.text_field :help_page_documentation_base_url, class: 'form-control gl-form-input', placeholder: 'https://docs.gitlab.com' + - docs_link_url = help_page_path('user/admin_area/settings/help_page', anchor: 'destination-requirements') + - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url } + %span.form-text.text-muted#support_help_block= html_escape(_('Requests for pages at %{code_start}%{help_text_url}%{code_end} redirect to the URL. The destination must meet certain requirements. %{docs_link_start}Learn more.%{docs_link_end}')) % { code_start: '<code>'.html_safe, help_text_url: help_url, code_end: '</code>'.html_safe, docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe } = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/_mailgun.html.haml b/app/views/admin/application_settings/_mailgun.html.haml index 40b4d5cac6d..ad9e84ffdab 100644 --- a/app/views/admin/application_settings/_mailgun.html.haml +++ b/app/views/admin/application_settings/_mailgun.html.haml @@ -6,7 +6,7 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded ? _('Collapse') : _('Expand') %p - = _('Configure the %{link} integration.').html_safe % { link: link_to(_('Mailgun events'), 'https://documentation.mailgun.com/en/latest/user_manual.html#webhooks', target: '_blank') } + = _('Configure the %{link} integration.').html_safe % { link: link_to(_('Mailgun events'), 'https://documentation.mailgun.com/en/latest/user_manual.html#webhooks', target: '_blank', rel: 'noopener noreferrer') } .settings-content = form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-mailgun-settings'), html: { class: 'fieldset-form', id: 'mailgun-settings' } do |f| = form_errors(@application_setting) if expanded diff --git a/app/views/admin/application_settings/_network_rate_limits.html.haml b/app/views/admin/application_settings/_network_rate_limits.html.haml new file mode 100644 index 00000000000..f1857a9749a --- /dev/null +++ b/app/views/admin/application_settings/_network_rate_limits.html.haml @@ -0,0 +1,33 @@ += gitlab_ui_form_for @application_setting, url: network_admin_application_settings_path(anchor: anchor), html: { class: 'fieldset-form' } do |f| + = form_errors(@application_setting) + + %fieldset + = _("Rate limits can help reduce request volume (like from crawlers or abusive bots).") + + %fieldset + .form-group + = f.gitlab_ui_checkbox_component :"throttle_unauthenticated_#{setting_fragment}_enabled", + _('Enable unauthenticated API request rate limit'), + checkbox_options: { data: { qa_selector: "throttle_unauthenticated_#{setting_fragment}_checkbox" } }, + label_options: { class: 'label-bold' } + .form-group + = f.label :"throttle_unauthenticated_#{setting_fragment}_requests_per_period", _('Maximum unauthenticated API requests per rate limit period per IP'), class: 'label-bold' + = f.number_field :"throttle_unauthenticated_#{setting_fragment}_requests_per_period", class: 'form-control gl-form-input' + .form-group + = f.label :"throttle_unauthenticated_#{setting_fragment}_period_in_seconds", _('Unauthenticated API rate limit period in seconds'), class: 'label-bold' + = f.number_field :"throttle_unauthenticated_#{setting_fragment}_period_in_seconds", class: 'form-control gl-form-input' + + %fieldset + .form-group + = f.gitlab_ui_checkbox_component :"throttle_authenticated_#{setting_fragment}_enabled", + _('Enable authenticated API request rate limit'), + checkbox_options: { data: { qa_selector: "throttle_authenticated_#{setting_fragment}_checkbox" } }, + label_options: { class: 'label-bold' } + .form-group + = f.label :"throttle_authenticated_#{setting_fragment}_requests_per_period", _('Maximum authenticated API requests per rate limit period per user'), class: 'label-bold' + = f.number_field :"throttle_authenticated_#{setting_fragment}_requests_per_period", class: 'form-control gl-form-input' + .form-group + = f.label :"throttle_authenticated_#{setting_fragment}_period_in_seconds", _('Authenticated API rate limit period in seconds'), class: 'label-bold' + = f.number_field :"throttle_authenticated_#{setting_fragment}_period_in_seconds", class: 'form-control gl-form-input' + + = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/admin/application_settings/_package_registry_limits.html.haml b/app/views/admin/application_settings/_package_registry_limits.html.haml deleted file mode 100644 index 8769171c9e0..00000000000 --- a/app/views/admin/application_settings/_package_registry_limits.html.haml +++ /dev/null @@ -1,32 +0,0 @@ -= form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-packages-limits-settings'), html: { class: 'fieldset-form' } do |f| - = form_errors(@application_setting) - - %fieldset - = _("The package registry rate limits can help reduce request volume (like from crawlers or abusive bots).") - - %fieldset - .form-group - .form-check - = f.check_box :throttle_unauthenticated_packages_api_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_unauthenticated_packages_api_checkbox' } - = f.label :throttle_unauthenticated_packages_api_enabled, class: 'form-check-label label-bold' do - = _('Enable unauthenticated API request rate limit') - .form-group - = f.label :throttle_unauthenticated_packages_api_requests_per_period, _('Maximum unauthenticated API requests per rate limit period per IP'), class: 'label-bold' - = f.number_field :throttle_unauthenticated_packages_api_requests_per_period, class: 'form-control gl-form-input' - .form-group - = f.label :throttle_unauthenticated_packages_api_period_in_seconds, _('Unauthenticated API rate limit period in seconds'), class: 'label-bold' - = f.number_field :throttle_unauthenticated_packages_api_period_in_seconds, class: 'form-control gl-form-input' - %hr - .form-group - .form-check - = f.check_box :throttle_authenticated_packages_api_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_packages_api_checkbox' } - = f.label :throttle_authenticated_packages_api_enabled, class: 'form-check-label label-bold' do - = _('Enable authenticated API request rate limit') - .form-group - = f.label :throttle_authenticated_packages_api_requests_per_period, _('Maximum authenticated API requests per rate limit period per user'), class: 'label-bold' - = f.number_field :throttle_authenticated_packages_api_requests_per_period, class: 'form-control gl-form-input' - .form-group - = f.label :throttle_authenticated_packages_api_period_in_seconds, _('Authenticated API rate limit period in seconds'), class: 'label-bold' - = f.number_field :throttle_authenticated_packages_api_period_in_seconds, class: 'form-control gl-form-input' - - = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/admin/application_settings/_performance.html.haml b/app/views/admin/application_settings/_performance.html.haml index 50fc11ec7f3..82e56cf8b81 100644 --- a/app/views/admin/application_settings/_performance.html.haml +++ b/app/views/admin/application_settings/_performance.html.haml @@ -6,29 +6,24 @@ .form-check = f.check_box :authorized_keys_enabled, class: 'form-check-input' = f.label :authorized_keys_enabled, class: 'form-check-label' do - = _('Write to "authorized_keys" file') + = _('Use authorized_keys file to authenticate SSH keys') .form-text.text-muted - By default, we write to the "authorized_keys" file to support Git - over SSH without additional configuration. GitLab can be optimized - to authenticate SSH keys via the database file. Only uncheck this - if you have configured your OpenSSH server to use the - AuthorizedKeysCommand. Click on the help icon for more details. - = link_to sprite_icon('question-o'), help_page_path('administration/operations/fast_ssh_key_lookup') - + = _('Authenticate user SSH keys without requiring additional configuration. Performance of GitLab can be improved by using the GitLab database instead.') + = link_to _('How do I configure authentication using the GitLab database?'), help_page_path('administration/operations/fast_ssh_key_lookup'), target: '_blank', rel: 'noopener noreferrer' .form-group = f.label :raw_blob_request_limit, _('Raw blob request rate limit per minute'), class: 'label-bold' = f.number_field :raw_blob_request_limit, class: 'form-control gl-form-input' .form-text.text-muted - = _('Highest number of requests per minute for each raw path, default to 300. To disable throttling set to 0.') + = _('Maximum number of requests per minute for each raw path (default is 300). Set to 0 to disable throttling.') .form-group = f.label :push_event_hooks_limit, class: 'label-bold' = f.number_field :push_event_hooks_limit, class: 'form-control gl-form-input' .form-text.text-muted - = _("Number of changes (branches or tags) in a single push to determine whether webhooks and services will be fired or not. Webhooks and services won't be submitted if it surpasses that value.") + = _('Maximum number of changes (branches or tags) in a single push for which webhooks and services trigger (default is 3).') .form-group = f.label :push_event_activities_limit, class: 'label-bold' = f.number_field :push_event_activities_limit, class: 'form-control gl-form-input' .form-text.text-muted - = _('Number of changes (branches or tags) in a single push to determine whether individual push events or bulk push event will be created. Bulk push event will be created if it surpasses that value.') + = _('Threshold number of changes (branches or tags) in a single push above which a bulk push event is created (default is 3).') = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/_snowplow.html.haml b/app/views/admin/application_settings/_snowplow.html.haml index 8c98778147e..756c0e770a6 100644 --- a/app/views/admin/application_settings/_snowplow.html.haml +++ b/app/views/admin/application_settings/_snowplow.html.haml @@ -7,7 +7,7 @@ = expanded ? _('Collapse') : _('Expand') %p - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('development/snowplow/index') } - = html_escape(_('Configure %{link} to track events. %{link_start}Learn more.%{link_end}')) % { link: link_to('Snowplow', 'https://snowplowanalytics.com/', target: '_blank').html_safe, link_start: link_start, link_end: '</a>'.html_safe } + = html_escape(_('Configure %{link} to track events. %{link_start}Learn more.%{link_end}')) % { link: link_to('Snowplow', 'https://snowplowanalytics.com/', target: '_blank', rel: 'noopener noreferrer').html_safe, link_start: link_start, link_end: '</a>'.html_safe } .settings-content = form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-snowplow-settings'), html: { class: 'fieldset-form', id: 'snowplow-settings' } do |f| = form_errors(@application_setting) if expanded diff --git a/app/views/admin/application_settings/_spam.html.haml b/app/views/admin/application_settings/_spam.html.haml index 011bce3ca99..53ca4d4aa79 100644 --- a/app/views/admin/application_settings/_spam.html.haml +++ b/app/views/admin/application_settings/_spam.html.haml @@ -2,6 +2,11 @@ = form_errors(@application_setting) %fieldset + %h5 + = _('reCAPTCHA') + %p + = _('reCAPTCHA helps prevent credential stuffing.') + = link_to _('Only reCAPTCHA v2 is supported:'), 'https://developers.google.com/recaptcha/docs/versions', target: '_blank', rel: 'noopener noreferrer' .form-group .form-check = f.check_box :recaptcha_enabled, class: 'form-check-input' @@ -9,25 +14,31 @@ = _("Enable reCAPTCHA") %span.form-text.text-muted#recaptcha_help_block = _('Helps prevent bots from creating accounts.') + = link_to _('How do I configure it?'), help_page_path('integration/recaptcha.md'), target: '_blank', rel: 'noopener noreferrer' .form-group .form-check = f.check_box :login_recaptcha_protection_enabled, class: 'form-check-input' = f.label :login_recaptcha_protection_enabled, class: 'form-check-label' do - = _("Enable reCAPTCHA for login") + = _('Enable reCAPTCHA for login.') %span.form-text.text-muted#recaptcha_help_block = _('Helps prevent bots from brute-force attacks.') .form-group - = f.label :recaptcha_site_key, _('reCAPTCHA Site Key'), class: 'label-bold' + = f.label :recaptcha_site_key, _('reCAPTCHA site key'), class: 'label-bold' = f.text_field :recaptcha_site_key, class: 'form-control gl-form-input' .form-text.text-muted = _("Generate site and private keys at") %a{ href: 'http://www.google.com/recaptcha', target: 'blank' } http://www.google.com/recaptcha .form-group - = f.label :recaptcha_private_key, _('reCAPTCHA Private Key'), class: 'label-bold' - .form-group + = f.label :recaptcha_private_key, _('reCAPTCHA private key'), class: 'label-bold' = f.text_field :recaptcha_private_key, class: 'form-control gl-form-input' + %h5 + = _('Invisible Captcha') + %p + = _('Invisible Captcha helps prevent the creation of spam accounts. It adds a honeypot field and time-sensitive form submission to the account signup form.') + = link_to _('Read their documentation.'), 'https://github.com/markets/invisible_captcha', target: '_blank', rel: 'noopener noreferrer' + .form-group .form-check = f.check_box :invisible_captcha_enabled, class: 'form-check-input' @@ -36,12 +47,18 @@ %span.form-text.text-muted = _('Helps prevent bots from creating accounts.') + %h5 + = _('Akismet') + %p + = _('Akismet helps prevent the creation of spam issues in public projects.') + = link_to _('How do I configure Akismet?'), help_page_path('integration/akismet.md'), target: '_blank', rel: 'noopener noreferrer' + .form-group .form-check = f.check_box :akismet_enabled, class: 'form-check-input' = f.label :akismet_enabled, class: 'form-check-label' do Enable Akismet - %span.form-text.text-muted#akismet_help_block= _("Helps prevent bots from creating issues") + %span.form-text.text-muted#akismet_help_block= _("Helps prevent bots from creating issues.") .form-group = f.label :akismet_api_key, _('Akismet API Key'), class: 'label-bold' @@ -50,25 +67,31 @@ Generate API key at %a{ href: 'http://www.akismet.com', target: 'blank' } http://www.akismet.com + %h5 + = _('IP address restrictions') + .form-group .form-check = f.check_box :unique_ips_limit_enabled, class: 'form-check-input' = f.label :unique_ips_limit_enabled, class: 'form-check-label' do - = _("Limit sign in from multiple ips") + = _("Limit sign in from multiple IP addresses") %span.form-text.text-muted#unique_ip_help_block - = _("Helps prevent malicious users hide their activity") + = _("Helps prevent malicious users hide their activity.") .form-group - = f.label :unique_ips_limit_per_user, _('IPs per user'), class: 'label-bold' + = f.label :unique_ips_limit_per_user, _('IP addresses per user'), class: 'label-bold' = f.number_field :unique_ips_limit_per_user, class: 'form-control gl-form-input' .form-text.text-muted - = _("Maximum number of unique IPs per user") + = _("Maximum number of unique IP addresses per user.") .form-group - = f.label :unique_ips_limit_time_window, _('IP expiration time'), class: 'label-bold' + = f.label :unique_ips_limit_time_window, _('IP address expiration time'), class: 'label-bold' = f.number_field :unique_ips_limit_time_window, class: 'form-control gl-form-input' .form-text.text-muted - = _("How many seconds an IP will be counted towards the limit") + = _("How many seconds an IP counts toward the IP address limit.") + + %h5 + = _('Spam Check') .form-group .form-check @@ -79,8 +102,8 @@ = f.label :spam_check_endpoint_url, _('URL of the external Spam Check endpoint'), class: 'label-bold' = f.text_field :spam_check_endpoint_url, class: 'form-control gl-form-input' .form-group - = f.label :spam_check_api_key, _('Spam Check API Key'), class: 'gl-font-weight-bold' + = f.label :spam_check_api_key, _('Spam Check API key'), class: 'gl-font-weight-bold' = f.text_field :spam_check_api_key, class: 'form-control gl-form-input' - .form-text.text-muted= _('The API key used by GitLab for accessing the Spam Check service endpoint') + .form-text.text-muted= _('The API key used by GitLab for accessing the Spam Check service endpoint.') = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/_terminal.html.haml b/app/views/admin/application_settings/_terminal.html.haml index d6e31a24cf6..c53f63e124b 100644 --- a/app/views/admin/application_settings/_terminal.html.haml +++ b/app/views/admin/application_settings/_terminal.html.haml @@ -6,5 +6,5 @@ = f.label :terminal_max_session_time, _('Max session time'), class: 'label-bold' = f.number_field :terminal_max_session_time, class: 'form-control gl-form-input' .form-text.text-muted - = _('Maximum time for web terminal websocket connection (in seconds). 0 for unlimited.') + = _('Maximum time, in seconds, for a web terminal websocket connection. 0 for unlimited.') = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/_usage.html.haml b/app/views/admin/application_settings/_usage.html.haml index ddd0abb4c34..5bdad50c161 100644 --- a/app/views/admin/application_settings/_usage.html.haml +++ b/app/views/admin/application_settings/_usage.html.haml @@ -10,21 +10,21 @@ = f.label :version_check_enabled, class: 'form-check-label' do = _("Enable version check") .form-text.text-muted - = _("GitLab will inform you if a new version is available.") - = _("%{link_start}Learn more%{link_end} about what information is shared with GitLab Inc.").html_safe % { link_start: "<a href='#{help_page_path("user/admin_area/settings/usage_statistics", anchor: "version-check")}'>".html_safe, link_end: '</a>'.html_safe } + = _("GitLab informs you if a new version is available.") + = _("%{link_start}What information does GitLab Inc. collect?%{link_end}").html_safe % { link_start: "<a href='#{help_page_path("user/admin_area/settings/usage_statistics", anchor: "version-check")}'>".html_safe, link_end: '</a>'.html_safe } .form-group - can_be_configured = @application_setting.usage_ping_can_be_configured? .form-check = f.check_box :usage_ping_enabled, disabled: !can_be_configured, class: 'form-check-input' = f.label :usage_ping_enabled, class: 'form-check-label' do - = _('Enable service ping') + = _('Enable Service Ping') .form-text.text-muted - if can_be_configured - %p.mb-2= _('To help improve GitLab and its user experience, GitLab will periodically collect usage information.') + %p.mb-2= _('To help improve GitLab and its user experience, GitLab periodically collects usage information.') - - service_ping_path = help_page_path('user/admin_area/settings/usage_statistics', anchor: 'service-ping') + - service_ping_path = help_page_path('development/service_ping/index.md') - service_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: service_ping_path } - %p.mb-2= s_('%{service_ping_link_start}Learn more%{service_ping_link_end} about what information is shared with GitLab Inc.').html_safe % { service_ping_link_start: service_ping_link_start, service_ping_link_end: '</a>'.html_safe } + %p.mb-2= s_('%{service_ping_link_start}What information is shared with GitLab Inc.?%{service_ping_link_end}').html_safe % { service_ping_link_start: service_ping_link_start, service_ping_link_end: '</a>'.html_safe } %button.gl-button.btn.btn-default.js-payload-preview-trigger{ type: 'button', data: { payload_selector: ".#{payload_class}" } } .gl-spinner.js-spinner.gl-display-none.gl-mr-2 @@ -46,15 +46,23 @@ - if usage_ping_enabled %p.gl-mb-3.text-muted{ id: 'service_ping_features_helper_text' }= _('You can enable Registration Features because Service Ping is enabled. To continue using Registration Features in the future, you will also need to register with GitLab via a new cloud licensing service.') - else - %p.gl-mb-3.text-muted{ id: 'service_ping_features_helper_text' }= _('To enable Registration Features, make sure "Enable service ping" is checked.') + %p.gl-mb-3.text-muted{ id: 'service_ping_features_helper_text' }= _('To enable Registration Features, first enable Service Ping.') %p.gl-mb-3.text-muted= _('Registration Features include:') .form-text - email_from_gitlab_path = help_page_path('tools/email.md') + - repo_size_limit_path = help_page_path('user/admin_area/settings/account_and_limit_settings.md', anchor: 'repository-size-limit') + - restrict_ip_path = help_page_path('user/group/index.md', anchor: 'restrict-group-access-by-ip-address') - link_end = '</a>'.html_safe - email_from_gitlab_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: email_from_gitlab_path } + - repo_size_limit_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: repo_size_limit_path } + - restrict_ip_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: restrict_ip_path } %ul %li = _('Email from GitLab - email users right from the Admin Area. %{link_start}Learn more%{link_end}.').html_safe % { link_start: email_from_gitlab_link, link_end: link_end } + %li + = _('Limit project size at a global, group, and project level. %{link_start}Learn more%{link_end}.').html_safe % { link_start: repo_size_limit_link, link_end: link_end } + %li + = _('Restrict group access by IP address. %{link_start}Learn more%{link_end}.').html_safe % { link_start: restrict_ip_link, link_end: link_end } = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/appearances/preview_sign_in.html.haml b/app/views/admin/application_settings/appearances/preview_sign_in.html.haml index 77c37abbeef..2e4ab714048 100644 --- a/app/views/admin/application_settings/appearances/preview_sign_in.html.haml +++ b/app/views/admin/application_settings/appearances/preview_sign_in.html.haml @@ -1,12 +1,13 @@ = render 'devise/shared/tab_single', tab_title: _('Sign in preview') .login-box %form.gl-show-field-errors + - title = _('This form is disabled in preview') .form-group = label_tag :login - = text_field_tag :login, nil, class: "form-control gl-form-input top", title: _('Please provide your username or email address.') + = text_field_tag :login, nil, disabled: true, class: "form-control gl-form-input top", title: title .form-group = label_tag :password - = password_field_tag :password, nil, class: "form-control gl-form-input bottom", title: _('This field is required.') + = password_field_tag :password, nil, disabled: true, class: "form-control gl-form-input bottom", title: title .form-group - = button_tag _("Sign in"), class: "btn gl-button btn-confirm", type: "button" + = button_tag _("Sign in"), disabled: true, class: "btn gl-button btn-confirm", type: "button", title: title diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml index 9102769cc6e..a72c96bb577 100644 --- a/app/views/admin/application_settings/general.html.haml +++ b/app/views/admin/application_settings/general.html.haml @@ -79,7 +79,8 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Set max session time for web terminal.') + = _('Set the maximum session time for a web terminal.') + = link_to _('How do I use a web terminal?'), help_page_path('ci/environments/index.md', anchor: 'web-terminals'), target: '_blank', rel: 'noopener noreferrer' .settings-content = render 'terminal' diff --git a/app/views/admin/application_settings/metrics_and_profiling.html.haml b/app/views/admin/application_settings/metrics_and_profiling.html.haml index f1e37c76130..6087551d7c7 100644 --- a/app/views/admin/application_settings/metrics_and_profiling.html.haml +++ b/app/views/admin/application_settings/metrics_and_profiling.html.haml @@ -49,7 +49,7 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Enable or disable version check and service ping.') + = _('Enable or disable version check and Service Ping.') .settings-content = render 'usage' diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml index 8dff2bc36cb..58e3f3f1136 100644 --- a/app/views/admin/application_settings/network.html.haml +++ b/app/views/admin/application_settings/network.html.haml @@ -35,9 +35,10 @@ = _('Set rate limits for package registry API requests that supersede the general user and IP rate limits.') = link_to _('Learn more.'), help_page_path('user/admin_area/settings/package_registry_rate_limits.md'), target: '_blank', rel: 'noopener noreferrer' .settings-content - = render 'package_registry_limits' + = render partial: 'network_rate_limits', locals: { anchor: 'js-packages-limits-settings', setting_fragment: 'packages_api' } + - if Feature.enabled?(:files_api_throttling, default_enabled: :yaml) - %section.settings.as-files-limits.no-animate#js-files-limits-settings{ class: ('expanded' if expanded_by_default?), data: { testid: 'files-limits-settings' } } + %section.settings.as-files-limits.no-animate#js-files-limits-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 = _('Files API Rate Limits') @@ -46,7 +47,19 @@ %p = _('Configure specific limits for Files API requests that supersede the general user and IP rate limits.') .settings-content - = render 'files_limits' + = render partial: 'network_rate_limits', locals: { anchor: 'js-files-limits-settings', setting_fragment: 'files_api' } + +%section.settings.as-deprecated-limits.no-animate#js-deprecated-limits-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Deprecated API rate limits') + %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Configure specific limits for deprecated API requests that supersede the general user and IP rate limits.') + = link_to _('Which API requests are affected?'), help_page_path('user/admin_area/settings/deprecated_api_rate_limits.md'), target: '_blank', rel: 'noopener noreferrer' + .settings-content + = render partial: 'network_rate_limits', locals: { anchor: 'js-deprecated-limits-settings', setting_fragment: 'deprecated_api' } %section.settings.as-git-lfs-limits.no-animate#js-git-lfs-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'git_lfs_limits_content' } } .settings-header diff --git a/app/views/admin/application_settings/reporting.html.haml b/app/views/admin/application_settings/reporting.html.haml index 914a09ff5db..d2e118f0624 100644 --- a/app/views/admin/application_settings/reporting.html.haml +++ b/app/views/admin/application_settings/reporting.html.haml @@ -9,9 +9,7 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - - recaptcha_v2_link_url = 'https://developers.google.com/recaptcha/docs/versions' - - recaptcha_v2_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: recaptcha_v2_link_url } - = _('Enable reCAPTCHA, Invisible Captcha, Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}').html_safe % { recaptcha_v2_link_start: recaptcha_v2_link_start, recaptcha_v2_link_end: '</a>'.html_safe } + = _('Configure CAPTCHAs, IP address limits, and other anti-spam measures.') .settings-content = render 'spam' @@ -22,6 +20,7 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Set notification email for abuse reports.') + = _('Receive notification of abuse reports by email.') + = link_to _('Learn more.'), help_page_path('user/admin_area/review_abuse_reports.md'), target: '_blank', rel: 'noopener noreferrer' .settings-content = render 'abuse' diff --git a/app/views/admin/dashboard/_security_newsletter_callout.html.haml b/app/views/admin/dashboard/_security_newsletter_callout.html.haml new file mode 100644 index 00000000000..ece0f7ca4d9 --- /dev/null +++ b/app/views/admin/dashboard/_security_newsletter_callout.html.haml @@ -0,0 +1,14 @@ +- return unless show_security_newsletter_user_callout? + += render 'shared/global_alert', + title: s_('AdminArea|Get security updates from GitLab and stay up to date'), + variant: :tip, + alert_class: 'js-security-newsletter-callout', + is_contained: true, + alert_data: { feature_id: UserCalloutsHelper::SECURITY_NEWSLETTER_CALLOUT, dismiss_endpoint: user_callouts_path, defer_links: 'true' }, + close_button_data: { testid: 'close-security-newsletter-callout' } do + .gl-alert-body + = s_('AdminArea|Sign up for the GitLab Security Newsletter to get notified for security updates.') + .gl-alert-actions + = link_to 'https://about.gitlab.com/company/preference-center/', target: '_blank', rel: 'noreferrer noopener', class: 'deferred-link gl-alert-action btn-confirm btn-md gl-button' do + = s_('AdminArea|Sign up for the GitLab newsletter') diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 97b3a757a3f..681e7ccb613 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -4,6 +4,7 @@ - billable_users_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer nofollow">'.html_safe % { url: billable_users_url } = render_if_exists 'shared/qrtly_reconciliation_alert' += render 'admin/dashboard/security_newsletter_callout' - if @notices - @notices.each do |notice| diff --git a/app/views/admin/hook_logs/_index.html.haml b/app/views/admin/hook_logs/_index.html.haml index a7f947f96ea..6a46b0b3510 100644 --- a/app/views/admin/hook_logs/_index.html.haml +++ b/app/views/admin/hook_logs/_index.html.haml @@ -1,37 +1,11 @@ +- docs_link_url = help_page_path('user/project/integrations/webhooks', anchor: 'troubleshoot-webhooks') +- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url } +- link_end = '</a>'.html_safe + .row.gl-mt-3.gl-mb-3 .col-lg-3 %h4.gl-mt-0 - = _('Recent Deliveries') - %p= _('When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong.') + = _('Recent events') + %p= _('GitLab events trigger webhooks. Use the request details of a webhook to help troubleshoot problems. %{link_start}How do I troubleshoot?%{link_end}').html_safe % { link_start: link_start, link_end: link_end } .col-lg-9 - - if hook_logs.present? - %table.table - %thead - %tr - %th= _('Status') - %th= _('Trigger') - %th= _('URL') - %th= _('Elapsed time') - %th= _('Request time') - %th - - hook_logs.each do |hook_log| - %tr - %td - = render partial: 'shared/hook_logs/status_label', locals: { hook_log: hook_log } - %td.d-none.d-sm-block - %span.badge.badge-gray.deploy-project-label - = hook_log.trigger.singularize.titleize - %td - = truncate(hook_log.url, length: 50) - %td.light - #{number_with_precision(hook_log.execution_duration, precision: 2)} sec - %td.light - = time_ago_with_tooltip(hook_log.created_at) - %td - = link_to _('View details'), admin_hook_hook_log_path(hook, hook_log) - - = paginate hook_logs, theme: 'gitlab' - - - else - .settings-message.text-center - = _("You don't have any webhooks deliveries") + = render partial: 'shared/hook_logs/recent_deliveries_table', locals: { hook: hook, hook_logs: hook_logs } diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index 5ebfd296e2b..f947e174990 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -1,33 +1,24 @@ - page_title _('Projects') - params[:visibility_level] ||= [] -- active_tab_classes = 'active gl-tab-nav-item-active gl-tab-nav-item-active-indigo' .top-area.scrolling-tabs-container.inner-page-scroll-tabs - %ul.nav.gl-tabs-nav.gl-overflow-x-auto.gl-display-flex.gl-flex-grow-1.gl-flex-shrink-1.gl-border-b-0.gl-flex-nowrap.gl-webkit-scrollbar-display-none - = nav_link(html_options: { class: "nav-item" } ) do - = link_to _('All'), admin_projects_path, class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level].empty?}" - = nav_link(html_options: { class: "nav-item" } ) do - = link_to _('Private'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE), class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level] == Gitlab::VisibilityLevel::PRIVATE.to_s}" - = nav_link(html_options: { class: "nav-item" } ) do - = link_to _('Internal'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL), class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level] == Gitlab::VisibilityLevel::INTERNAL.to_s}" - = nav_link(html_options: { class: "nav-item" } ) do - = link_to _('Public'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC), class: "nav-link gl-tab-nav-item #{active_tab_classes if params[:visibility_level] == Gitlab::VisibilityLevel::PUBLIC.to_s}" + = gl_tabs_nav({ class: 'gl-border-b-0 gl-overflow-x-auto gl-flex-grow-1 gl-flex-nowrap gl-webkit-scrollbar-display-none' }) do + = gl_tab_link_to _('All'), admin_projects_path(visibility_level: nil), { item_active: params[:visibility_level].empty? } + = gl_tab_link_to _('Private'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + = gl_tab_link_to _('Internal'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + = gl_tab_link_to _('Public'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC) .nav-controls .search-holder = render 'shared/projects/search_form', autofocus: true, admin_view: true - .dropdown - - toggle_text = _('Namespace') - - if params[:namespace_id].present? - = hidden_field_tag :namespace_id, params[:namespace_id] - - namespace = Namespace.find(params[:namespace_id]) - - toggle_text = "#{namespace.kind}: #{namespace.full_path}" - = dropdown_toggle(toggle_text, { toggle: 'dropdown', is_filter: 'true' }, { toggle_class: 'js-namespace-select large' }) - .dropdown-menu.dropdown-select.dropdown-menu-right - = dropdown_title(_('Namespaces')) - = dropdown_filter(_("Search for Namespace")) - = dropdown_content - = dropdown_loading + - current_namespace = _('Namespace') + - if params[:namespace_id].present? + - namespace = Namespace.find(params[:namespace_id]) + - current_namespace = "#{namespace.kind}: #{namespace.full_path}" + %button.dropdown-menu-toggle.btn.btn-default.btn-md.gl-button.js-namespace-select{ data: { show_any: 'true', field_name: 'namespace_id', placeholder: current_namespace, update_location: 'true' }, type: 'button' } + %span.gl-new-dropdown-button-text + = current_namespace + = render 'shared/projects/dropdown' = link_to new_project_path, class: 'gl-button btn btn-confirm' do = _('New Project') diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 1a87b21351c..3069aab2710 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -143,13 +143,10 @@ .col-sm-3.col-form-label = f.label :new_namespace_id, _("Namespace") .col-sm-9 - .dropdown - = dropdown_toggle(_('Search for Namespace'), { toggle: 'dropdown', field_name: 'new_namespace_id' }, { toggle_class: 'js-namespace-select large' }) - .dropdown-menu.dropdown-select - = dropdown_title(_('Namespaces')) - = dropdown_filter(_('Search for Namespace')) - = dropdown_content - = dropdown_loading + - placeholder = _('Search for Namespace') + %button.dropdown-menu-toggle.btn.btn-default.btn-md.gl-button.js-namespace-select{ data: { field_name: 'new_namespace_id', placeholder: placeholder }, type: 'button' } + %span.gl-new-dropdown-button-text + = placeholder .form-group.row .offset-sm-3.col-sm-9 diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml index 59523ed3a0c..808b2bb4f8e 100644 --- a/app/views/admin/runners/show.html.haml +++ b/app/views/admin/runners/show.html.haml @@ -9,7 +9,7 @@ .row .col-md-6 %h4= _('Restrict projects for this runner') - - if @runner.projects.any? + - if @runner.runner_projects.any? %table.table{ data: { testid: 'assigned-projects' } } %thead %tr diff --git a/app/views/admin/serverless/domains/_form.html.haml b/app/views/admin/serverless/domains/_form.html.haml deleted file mode 100644 index a3e1ccc5d4a..00000000000 --- a/app/views/admin/serverless/domains/_form.html.haml +++ /dev/null @@ -1,99 +0,0 @@ -- form_name = 'js-serverless-domain-settings' -- form_url = @domain.persisted? ? admin_serverless_domain_path(@domain.id, anchor: form_name) : admin_serverless_domains_path(anchor: form_name) -- show_certificate_card = @domain.persisted? && @domain.errors.blank? -= form_for @domain, url: form_url, html: { class: 'fieldset-form' } do |f| - = form_errors(@domain) - - %fieldset - - if @domain.persisted? - - dns_record = "*.#{@domain.domain} CNAME #{Settings.pages.host}." - - verification_record = "#{@domain.verification_domain} TXT #{@domain.keyed_verification_code}" - .form-group.row - .col-sm-6.position-relative - = f.label :domain, _('Domain'), class: 'label-bold' - = f.text_field :domain, class: 'form-control has-floating-status-badge', readonly: true - .status-badge.floating-status-badge - - text, status = @domain.unverified? ? [_('Unverified'), 'badge-danger'] : [_('Verified'), 'badge-success'] - .badge{ class: status } - = text - = link_to sprite_icon("redo"), verify_admin_serverless_domain_path(@domain.id), method: :post, class: "gl-button btn has-tooltip", title: _("Retry verification") - - .col-sm-6 - = f.label :serverless_domain_dns, _('DNS'), class: 'label-bold' - .input-group - = text_field_tag :serverless_domain_dns, dns_record , class: "monospace js-select-on-focus form-control", readonly: true - .input-group-append - = clipboard_button(target: '#serverless_domain_dns', class: 'btn-default input-group-text d-none d-sm-block') - - .col-sm-12.form-text.text-muted - = _("To access this domain create a new DNS record") - - .form-group - = f.label :serverless_domain_verification, _('Verification status'), class: 'label-bold' - .input-group - = text_field_tag :serverless_domain_verification, verification_record, class: "monospace js-select-on-focus form-control", readonly: true - .input-group-append - = clipboard_button(target: '#serverless_domain_verification', class: 'btn-default d-none d-sm-block') - %p.form-text.text-muted - - link_to_help = link_to(_('verify ownership'), help_page_path('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: '4-verify-the-domains-ownership')) - = _("To %{link_to_help} of your domain, add the above key to a TXT record within your DNS configuration.").html_safe % { link_to_help: link_to_help } - - - else - .form-group - = f.label :domain, _('Domain'), class: 'label-bold' - = f.text_field :domain, class: 'form-control' - - - if show_certificate_card - .card.js-domain-cert-show - .card-header - = _('Certificate') - .d-flex.justify-content-between.align-items-center.p-3 - %span - = @domain.subject || _('missing') - %button.gl-button.btn.btn-danger.btn-sm.js-domain-cert-replace-btn{ type: 'button' } - = _('Replace') - - .js-domain-cert-inputs{ class: ('hidden' if show_certificate_card) } - .form-group - = f.label :user_provided_certificate, _('Certificate (PEM)'), class: 'label-bold' - = f.text_area :user_provided_certificate, rows: 5, class: 'form-control', value: '' - %span.form-text.text-muted - = _("Upload a certificate for your domain with all intermediates") - .form-group - = f.label :user_provided_key, _('Key (PEM)'), class: 'label-bold' - = f.text_area :user_provided_key, rows: 5, class: 'form-control', value: '' - %span.form-text.text-muted - = _("Upload a private key for your certificate") - - = f.submit @domain.persisted? ? _('Save changes') : _('Add domain'), class: "gl-button btn btn-confirm js-serverless-domain-submit", disabled: @domain.persisted? - - if @domain.persisted? - %button.gl-button.btn.btn-danger{ type: 'button', data: { toggle: 'modal', target: "#modal-delete-domain" } } - = _('Delete domain') - --# haml-lint:disable NoPlainNodes -- if @domain.persisted? - - domain_attached = @domain.serverless_domain_clusters.count > 0 - .modal{ id: "modal-delete-domain", tabindex: -1 } - .modal-dialog - .modal-content - .modal-header - %h3.page-title= _('Delete serverless domain?') - %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": "true" } × - - .modal-body - - if domain_attached - = _("You must disassociate %{domain} from all clusters it is attached to before deletion.").html_safe % { domain: "<code>#{@domain.domain}</code>".html_safe } - - else - = _("You are about to delete %{domain} from your instance. This domain will no longer be available to any Knative application.").html_safe % { domain: "<code>#{@domain.domain}</code>".html_safe } - - .modal-footer - %a{ href: '#', data: { dismiss: 'modal' }, class: 'gl-button btn btn-default' } - = _('Cancel') - - = link_to _('Delete domain'), - admin_serverless_domain_path(@domain.id), - title: _('Delete'), - method: :delete, - class: "gl-button btn btn-danger", - disabled: domain_attached diff --git a/app/views/admin/serverless/domains/index.html.haml b/app/views/admin/serverless/domains/index.html.haml deleted file mode 100644 index c2b6baed4de..00000000000 --- a/app/views/admin/serverless/domains/index.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -- breadcrumb_title _("Operations") -- page_title _("Operations") -- @content_class = "limit-container-width" unless fluid_layout - --# normally expanded_by_default? is used here, but since this is the only panel --# in this settings page, let's leave it always open by default -- expanded = true - -%section.settings.as-serverless-domain.no-animate#js-serverless-domain-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - = _('Serverless domain') - %button.gl-button.btn.btn-default.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p - = _('Set an instance-wide domain that will be available to all clusters when installing Knative.') - .settings-content - - if Gitlab.config.pages.enabled - = render 'form' - - else - .card - .card-header - = s_('GitLabPages|Domains') - .nothing-here-block - = s_("GitLabPages|Support for domains and certificates is disabled. Ask your system's administrator to enable it.") diff --git a/app/views/admin/sessions/_new_base.html.haml b/app/views/admin/sessions/_new_base.html.haml index 47ef4f26889..c9b002a4dd2 100644 --- a/app/views/admin/sessions/_new_base.html.haml +++ b/app/views/admin/sessions/_new_base.html.haml @@ -1,7 +1,7 @@ = form_tag(admin_session_path, method: :post, class: 'new_user gl-show-field-errors', 'aria-live': 'assertive') do .form-group = label_tag :user_password, _('Password'), class: 'label-bold' - = password_field_tag 'user[password]', nil, class: 'form-control', required: true, title: _('This field is required.'), data: { qa_selector: 'password_field' } + = password_field_tag 'user[password]', nil, class: 'form-control', autocomplete: 'current-password', required: true, title: _('This field is required.'), data: { qa_selector: 'password_field' } .submit-container.move-submit-down = submit_tag _('Enter Admin Mode'), class: 'gl-button btn btn-success', data: { qa_selector: 'enter_admin_mode_button' } diff --git a/app/views/admin/topics/_form.html.haml b/app/views/admin/topics/_form.html.haml new file mode 100644 index 00000000000..21a1d74a8c6 --- /dev/null +++ b/app/views/admin/topics/_form.html.haml @@ -0,0 +1,40 @@ += gitlab_ui_form_for @topic, url: url, html: { multipart: true, class: 'js-project-topic-form gl-show-field-errors common-note-form js-quick-submit js-requires-input' }, authenticity_token: true do |f| + = form_errors(@topic) + + .form-group + = f.label :name do + = _("Topic name") + = f.text_field :name, placeholder: _('My topic'), class: 'form-control input-lg', data: { qa_selector: 'topic_name_field' }, + required: true, + title: _('Please fill in a name for your topic.'), + autofocus: true + + .form-group + = f.label :description, _("Description") + = render layout: 'shared/md_preview', locals: { url: preview_markdown_admin_topics_path, referenced_users: false } do + = render 'shared/zen', f: f, attr: :description, + classes: 'note-textarea', + placeholder: _('Write a description…'), + supports_quick_actions: false, + supports_autocomplete: false, + qa_selector: 'topic_form_description' + = render 'shared/notes/hints', supports_file_upload: false + + .form-group.gl-mt-3.gl-mb-3 + = f.label :avatar, _('Topic avatar'), class: 'gl-display-block' + - if @topic.avatar? + .avatar-container.rect-avatar.s90 + = topic_icon(@topic, alt: _('Topic avatar'), class: 'avatar topic-avatar s90') + = render 'shared/choose_avatar_button', f: f + - if @topic.avatar? + = link_to _('Remove avatar'), admin_topic_avatar_path(@topic), data: { confirm: _('Avatar will be removed. Are you sure?')}, method: :delete, class: 'gl-button btn btn-danger-secondary gl-mt-2' + + - if @topic.new_record? + .form-actions + = f.submit _('Create topic'), class: "gl-button btn btn-confirm" + = link_to _('Cancel'), admin_topics_path, class: "gl-button btn btn-default btn-cancel" + + - else + .form-actions + = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } + = link_to _('Cancel'), admin_topics_path, class: "gl-button btn btn-cancel" diff --git a/app/views/admin/topics/_topic.html.haml b/app/views/admin/topics/_topic.html.haml new file mode 100644 index 00000000000..abf3cffa422 --- /dev/null +++ b/app/views/admin/topics/_topic.html.haml @@ -0,0 +1,17 @@ +- topic = local_assigns.fetch(:topic) + +%li.topic-row.gl-py-3.gl-align-items-center{ class: 'gl-display-flex!', data: { qa_selector: 'topic_row_content' } } + .avatar-container.rect-avatar.s40.gl-flex-shrink-0 + = topic_icon(topic, class: "avatar s40") + + .gl-min-w-0.gl-flex-grow-1 + .title + = topic.name + + .stats.gl-text-gray-500.gl-flex-shrink-0.gl-display-none.gl-sm-display-flex + %span.gl-ml-5.has-tooltip{ title: n_('%d project', '%d projects', topic.total_projects_count) % topic.total_projects_count } + = sprite_icon('bookmark', css_class: 'gl-vertical-align-text-bottom') + = number_with_delimiter(topic.total_projects_count) + + .controls.gl-flex-shrink-0.gl-ml-5 + = link_to _('Edit'), edit_admin_topic_path(topic), id: "edit_#{dom_id(topic)}", class: 'btn gl-button btn-default' diff --git a/app/views/admin/topics/edit.html.haml b/app/views/admin/topics/edit.html.haml new file mode 100644 index 00000000000..4416bb0fe18 --- /dev/null +++ b/app/views/admin/topics/edit.html.haml @@ -0,0 +1,4 @@ +- page_title _("Edit"), @topic.name, _("Topics") +%h3.page-title= _('Edit topic: %{topic_name}') % { topic_name: @topic.name } +%hr += render 'form', url: admin_topic_path(@topic) diff --git a/app/views/admin/topics/index.html.haml b/app/views/admin/topics/index.html.haml new file mode 100644 index 00000000000..6485b8aa411 --- /dev/null +++ b/app/views/admin/topics/index.html.haml @@ -0,0 +1,19 @@ +- page_title _("Topics") + += form_tag admin_topics_path, method: :get do |f| + .gl-py-3.gl-display-flex.gl-flex-direction-column-reverse.gl-md-flex-direction-row.gl-border-b-solid.gl-border-gray-100.gl-border-b-1 + .gl-flex-grow-1.gl-mt-3.gl-md-mt-0 + .inline.gl-w-full.gl-md-w-auto + - search = params.fetch(:search, nil) + .search-field-holder + = search_field_tag :search, search, class: "form-control gl-form-input search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: _('Search by name'), data: { qa_selector: 'topic_search_field' } + = sprite_icon('search', css_class: 'search-icon') + .nav-controls + = link_to new_admin_topic_path, class: "gl-button btn btn-confirm gl-w-full gl-md-w-auto" do + = _('New topic') +%ul.content-list + = render partial: 'topic', collection: @topics + += paginate_collection @topics +- if @topics.empty? + = render 'shared/empty_states/topics' diff --git a/app/views/admin/topics/new.html.haml b/app/views/admin/topics/new.html.haml new file mode 100644 index 00000000000..8b4a8ac269e --- /dev/null +++ b/app/views/admin/topics/new.html.haml @@ -0,0 +1,4 @@ +- page_title _("New topic") +%h3.page-title= _('New topic') +%hr += render 'form', url: admin_topics_path(@topic) diff --git a/app/views/admin/users/_access_levels.html.haml b/app/views/admin/users/_access_levels.html.haml index aeb274fe2cb..6a5f07dd2db 100644 --- a/app/views/admin/users/_access_levels.html.haml +++ b/app/views/admin/users/_access_levels.html.haml @@ -19,22 +19,20 @@ .col-sm-10 - editing_current_user = (current_user == @user) - = f.radio_button :access_level, :regular, disabled: editing_current_user - = f.label :access_level_regular, class: 'font-weight-bold' do - = s_('AdminUsers|Regular') - %p.light - = s_('AdminUsers|Regular users have access to their groups and projects') + = f.gitlab_ui_radio_component :access_level, :regular, + s_('AdminUsers|Regular'), + radio_options: { disabled: editing_current_user }, + help_text: s_('AdminUsers|Regular users have access to their groups and projects.') = render_if_exists 'admin/users/auditor_access_level_radio', f: f, disabled: editing_current_user - = f.radio_button :access_level, :admin, disabled: editing_current_user - = f.label :access_level_admin, class: 'font-weight-bold' do - = s_('AdminUsers|Admin') - %p.light - = s_('AdminUsers|Administrators have access to all groups, projects and users and can manage all features in this installation') - - if editing_current_user - %p.light - = s_('AdminUsers|You cannot remove your own admin rights.') + - help_text = s_('AdminUsers|Administrators have access to all groups, projects and users and can manage all features in this installation.') + - help_text += ' ' + s_('AdminUsers|You cannot remove your own admin rights.') if editing_current_user + = f.gitlab_ui_radio_component :access_level, :admin, + s_('AdminUsers|Admin'), + radio_options: { disabled: editing_current_user }, + help_text: help_text + .form-group.row .col-sm-2.col-form-label.gl-pt-0 diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 9d62c19e2fc..3869a2b6dcd 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -1,5 +1,5 @@ .user_new - = form_for [:admin, @user], html: { class: 'fieldset-form' } do |f| + = gitlab_ui_form_for [:admin, @user], html: { class: 'fieldset-form' } do |f| = form_errors(@user) %fieldset @@ -39,12 +39,12 @@ .col-sm-2.col-form-label = f.label :password .col-sm-10 - = f.password_field :password, disabled: f.object.force_random_password, class: 'form-control gl-form-input' + = f.password_field :password, disabled: f.object.force_random_password, autocomplete: 'new-password', class: 'form-control gl-form-input' .form-group.row .col-sm-2.col-form-label = f.label :password_confirmation .col-sm-10 - = f.password_field :password_confirmation, disabled: f.object.force_random_password, class: 'form-control gl-form-input' + = f.password_field :password_confirmation, disabled: f.object.force_random_password, autocomplete: 'new-password', class: 'form-control gl-form-input' = render partial: 'access_levels', locals: { f: f } diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml index f4b1a2853f1..bafb2085589 100644 --- a/app/views/admin/users/_head.html.haml +++ b/app/views/admin/users/_head.html.haml @@ -33,16 +33,11 @@ - if can_force_email_confirmation?(@user) %button.btn.gl-button.btn-info.js-confirm-modal-button{ data: confirm_user_data(@user) } = _('Confirm user') -%ul.nav-links.nav.nav-tabs - = nav_link(path: 'users#show') do - = link_to _("Account"), admin_user_path(@user) - = nav_link(path: 'users#projects') do - = link_to _("Groups and projects"), projects_admin_user_path(@user) - = nav_link(path: 'users#keys') do - = link_to _("SSH keys"), keys_admin_user_path(@user) - = nav_link(controller: :identities) do - = link_to _("Identities"), admin_user_identities_path(@user) += gl_tabs_nav do + = gl_tab_link_to _("Account"), admin_user_path(@user) + = gl_tab_link_to _("Groups and projects"), projects_admin_user_path(@user) + = gl_tab_link_to _("SSH keys"), keys_admin_user_path(@user) + = gl_tab_link_to _("Identities"), admin_user_identities_path(@user) - if impersonation_enabled? - = nav_link(controller: :impersonation_tokens) do - = link_to _("Impersonation Tokens"), admin_user_impersonation_tokens_path(@user) + = gl_tab_link_to _("Impersonation Tokens"), admin_user_impersonation_tokens_path(@user) .gl-mb-3 diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index ad8d9d1f04f..2a9b4694e7b 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -61,7 +61,6 @@ = _('Disabled') = render_if_exists 'admin/namespace_plan_info', namespace: @user.namespace - = render_if_exists 'admin/users/credit_card_info', user: @user %li %span.light= _('External User:') @@ -139,6 +138,8 @@ = render_if_exists 'namespaces/shared_runner_status', namespace: @user.namespace + = render_if_exists 'admin/users/credit_card_info', user: @user, link_to_match_page: true + = render 'shared/custom_attributes', custom_attributes: @user.custom_attributes -# Rendered on desktop only so order of cards can be different on desktop vs mobile diff --git a/app/views/authentication/_authenticate.html.haml b/app/views/authentication/_authenticate.html.haml index 5a2ae3f44c2..7dcec50573f 100644 --- a/app/views/authentication/_authenticate.html.haml +++ b/app/views/authentication/_authenticate.html.haml @@ -1,14 +1,17 @@ #js-authenticate-token-2fa %a.gl-button.btn.btn-block.btn-confirm#js-login-2fa-device{ href: '#' }= _("Sign in via 2FA code") +-# haml-lint:disable InlineJavaScript %script#js-authenticate-token-2fa-in-progress{ type: "text/template" } %p= _("Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now.") +-# haml-lint:disable InlineJavaScript %script#js-authenticate-token-2fa-error{ type: "text/template" } %div %p <%= error_message %> (<%= error_name %>) %a.btn.btn-default.gl-button.btn-block#js-token-2fa-try-again= _("Try again?") +-# haml-lint:disable InlineJavaScript %script#js-authenticate-token-2fa-authenticated{ type: "text/template" } %div %p= _("We heard back from your device. You have been authenticated.") diff --git a/app/views/authentication/_register.html.haml b/app/views/authentication/_register.html.haml index 678fd3c8e8c..5eed969ed35 100644 --- a/app/views/authentication/_register.html.haml +++ b/app/views/authentication/_register.html.haml @@ -1,8 +1,10 @@ #js-register-token-2fa +-# haml-lint:disable InlineJavaScript %script#js-register-2fa-message{ type: "text/template" } %p <%= message %> +-# haml-lint:disable InlineJavaScript %script#js-register-token-2fa-setup{ type: "text/template" } - if current_user.two_factor_otp_enabled? .row.gl-mb-3 @@ -17,12 +19,14 @@ .col-md-8 %p= _("You need to register a two-factor authentication app before you can set up a device.") +-# haml-lint:disable InlineJavaScript %script#js-register-token-2fa-error{ type: "text/template" } %div %p %span <%= error_message %> (<%= error_name %>) %a.btn.btn-default.gl-button#js-token-2fa-try-again= _("Try again?") +-# haml-lint:disable InlineJavaScript %script#js-register-token-2fa-registered{ type: "text/template" } .row.gl-mb-3 .col-md-12 diff --git a/app/views/clusters/clusters/_advanced_settings_tab.html.haml b/app/views/clusters/clusters/_advanced_settings_tab.html.haml index b491a64e43d..8c9d98604dd 100644 --- a/app/views/clusters/clusters/_advanced_settings_tab.html.haml +++ b/app/views/clusters/clusters/_advanced_settings_tab.html.haml @@ -1,6 +1,5 @@ - active = params[:tab] == 'settings' - if can_admin_cluster?(current_user, @cluster) - %li.nav-item{ role: 'presentation' } - %a#cluster-settings-tab.nav-link{ class: active_when(active), href: clusterable.cluster_path(@cluster.id, params: {tab: 'settings'}) } - %span= _('Advanced Settings') + = gl_tab_link_to clusterable.cluster_path(@cluster.id, params: { tab: 'settings' }), { item_active: active } do + = _('Advanced Settings') diff --git a/app/views/clusters/clusters/_details_tab.html.haml b/app/views/clusters/clusters/_details_tab.html.haml index 564c5103d34..734910686e7 100644 --- a/app/views/clusters/clusters/_details_tab.html.haml +++ b/app/views/clusters/clusters/_details_tab.html.haml @@ -1,5 +1,4 @@ - active = params[:tab] == 'details' || !params[:tab].present? -%li.nav-item{ role: 'presentation' } - %a#cluster-details-tab.nav-link.qa-details{ class: active_when(active), href: clusterable.cluster_path(@cluster.id, params: {tab: 'details'}) } - %span= _('Details') += gl_tab_link_to clusterable.cluster_path(@cluster.id, params: { tab: 'details' }), { item_active: active } do + = _('Details') diff --git a/app/views/clusters/clusters/_health_tab.html.haml b/app/views/clusters/clusters/_health_tab.html.haml index fda392693f6..4292066cc6f 100644 --- a/app/views/clusters/clusters/_health_tab.html.haml +++ b/app/views/clusters/clusters/_health_tab.html.haml @@ -1,5 +1,4 @@ - active = params[:tab] == 'health' -%li.nav-item{ role: 'presentation' } - %a#cluster-health-tab.nav-link.qa-health{ class: active_when(active), href: clusterable.cluster_path(@cluster.id, params: {tab: 'health'}) } - %span= _('Health') += gl_tab_link_to clusterable.cluster_path(@cluster.id, params: { tab: 'health' }), { item_active: active, data: { testid: 'cluster-health-tab' } } do + = _('Health') diff --git a/app/views/clusters/clusters/_integrations_tab.html.haml b/app/views/clusters/clusters/_integrations_tab.html.haml index 77b8b6ca3e6..e229c1fbe1e 100644 --- a/app/views/clusters/clusters/_integrations_tab.html.haml +++ b/app/views/clusters/clusters/_integrations_tab.html.haml @@ -1,6 +1,4 @@ -- tab_name = 'integrations' -- active = params[:tab] == tab_name +- active = params[:tab] == 'integrations' -%li.nav-item{ role: 'presentation' } - %a#cluster-apps-tab.nav-link{ class: active_when(active), href: clusterable.cluster_path(@cluster.id, params: {tab: tab_name}) } - %span= _('Integrations') += gl_tab_link_to clusterable.cluster_path(@cluster.id, params: { tab: 'integrations' }), { item_active: active } do + = _('Integrations') diff --git a/app/views/clusters/clusters/_namespace.html.haml b/app/views/clusters/clusters/_namespace.html.haml index 9b728e7a89b..6412972e195 100644 --- a/app/views/clusters/clusters/_namespace.html.haml +++ b/app/views/clusters/clusters/_namespace.html.haml @@ -1,7 +1,6 @@ - managed_namespace_help_text = s_('ClusterIntegration|Set a prefix for your namespaces. If not set, defaults to your project path. If modified, existing environments will use their current namespaces until the cluster cache is cleared.') - non_managed_namespace_help_text = s_('ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals.') -- managed_namespace_help_link = link_to _('More information'), help_page_path('user/project/clusters/index.md', - anchor: 'gitlab-managed-clusters'), target: '_blank' +- managed_namespace_help_link = link_to _('More information'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank' .js-namespace-prefixed = platform_field.text_field :namespace, diff --git a/app/views/clusters/clusters/aws/_new.html.haml b/app/views/clusters/clusters/aws/_new.html.haml index 93db7db06b3..f6d50410e9a 100644 --- a/app/views/clusters/clusters/aws/_new.html.haml +++ b/app/views/clusters/clusters/aws/_new.html.haml @@ -12,6 +12,6 @@ 'role-arn' => @aws_role.role_arn, 'instance-types' => @instance_types, 'kubernetes-integration-help-path' => help_page_path('user/project/clusters/index'), - 'account-and-external-ids-help-path' => help_page_path('user/project/clusters/add_eks_clusters.md', anchor: 'create-a-new-certificate-based-eks-cluster'), - 'create-role-arn-help-path' => help_page_path('user/project/clusters/add_eks_clusters.md', anchor: 'create-a-new-certificate-based-eks-cluster'), + 'account-and-external-ids-help-path' => help_page_path('user/project/clusters/add_eks_clusters.md', anchor: 'how-to-create-a-new-cluster-on-eks-through-cluster-certificates-deprecated'), + 'create-role-arn-help-path' => help_page_path('user/project/clusters/add_eks_clusters.md', anchor: 'how-to-create-a-new-cluster-on-eks-through-cluster-certificates-deprecated'), 'external-link-icon' => sprite_icon('external-link') } } diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml index 0a482f1eb01..2a09d8d8cc0 100644 --- a/app/views/clusters/clusters/show.html.haml +++ b/app/views/clusters/clusters/show.html.haml @@ -15,7 +15,7 @@ provider_type: @cluster.provider_type, help_path: help_page_path('user/project/clusters/index.md'), environments_help_path: help_page_path('ci/environments/index.md', anchor: 'create-a-static-environment'), - clusters_help_path: help_page_path('user/project/clusters/index.md', anchor: 'deploying-to-a-kubernetes-cluster'), + clusters_help_path: help_page_path('user/project/clusters/deploy_to_cluster.md'), deploy_boards_help_path: help_page_path('user/project/deploy_boards.md', anchor: 'enabling-deploy-boards'), cluster_id: @cluster.id } } @@ -24,11 +24,10 @@ .js-serverless-survey-banner{ data: { user_name: current_user.name, user_email: current_user.email } } - .d-flex.my-3 - %p.badge.badge-light.p-2.mr-2 + %h4.gl-my-5 + = @cluster.name + %span.badge.badge-info.badge-pill.gl-badge.md.gl-vertical-align-middle = cluster_type_label(@cluster.cluster_type) - %h4.m-0 - = @cluster.name = render 'banner' @@ -42,12 +41,12 @@ - if cluster_created?(@cluster) .js-toggle-container - %ul.nav-links.mobile-separator.nav.nav-tabs{ role: 'tablist' } - = render 'details_tab' + = gl_tabs_nav do + = render 'clusters/clusters/details_tab' = render_if_exists 'clusters/clusters/environments_tab' = render 'clusters/clusters/health_tab' - = render 'integrations_tab' - = render 'advanced_settings_tab' + = render 'clusters/clusters/integrations_tab' + = render 'clusters/clusters/advanced_settings_tab' .tab-content.py-3 .tab-pane.active{ role: 'tabpanel' } diff --git a/app/views/dashboard/_activity_head.html.haml b/app/views/dashboard/_activity_head.html.haml index 0daadd20f54..c65b947d1ba 100644 --- a/app/views/dashboard/_activity_head.html.haml +++ b/app/views/dashboard/_activity_head.html.haml @@ -2,13 +2,7 @@ %h1.page-title= _('Activity') .top-area - %ul.nav-links.nav.nav-tabs - %li{ class: active_when(params[:filter].nil?) }> - = link_to activity_dashboard_path, class: 'shortcuts-activity', data: {placement: 'right'} do - = _('Your projects') - %li{ class: active_when(params[:filter] == 'starred') }> - = link_to activity_dashboard_path(filter: 'starred'), data: {placement: 'right'} do - = _('Starred projects') - %li{ class: active_when(params[:filter] == 'followed') }> - = link_to activity_dashboard_path(filter: 'followed'), data: {placement: 'right'} do - = _('Followed users') + = gl_tabs_nav({ class: 'gl-border-b-0', data: { testid: 'dashboard-activity-tabs' } }) do + = gl_tab_link_to _("Your projects"), activity_dashboard_path, { item_active: params[:filter].nil? } + = gl_tab_link_to _("Starred projects"), activity_dashboard_path(filter: 'starred') + = gl_tab_link_to _("Followed users"), activity_dashboard_path(filter: 'followed') diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml index b92f35c108c..7b1d25b9b43 100644 --- a/app/views/dashboard/_groups_head.html.haml +++ b/app/views/dashboard/_groups_head.html.haml @@ -6,13 +6,9 @@ = link_to _("New group"), new_group_path, class: "gl-button btn btn-confirm", data: { testid: "new-group-button" } .top-area - %ul.nav-links.mobile-separator.nav.nav-tabs - = nav_link(page: dashboard_groups_path) do - = link_to dashboard_groups_path, title: _("Your groups") do - Your groups - = nav_link(page: explore_groups_path) do - = link_to explore_groups_path, title: _("Explore public groups") do - Explore public groups + = gl_tabs_nav({ class: 'gl-flex-grow-1 gl-border-0' }) do + = gl_tab_link_to _("Your groups"), dashboard_groups_path + = gl_tab_link_to _("Explore public groups"), explore_groups_path .nav-controls = render 'shared/groups/search_form' = render 'shared/groups/dropdown' diff --git a/app/views/devise/confirmations/almost_there.haml b/app/views/devise/confirmations/almost_there.haml index 037b2f247c1..9fb0fb734f9 100644 --- a/app/views/devise/confirmations/almost_there.haml +++ b/app/views/devise/confirmations/almost_there.haml @@ -1,16 +1,15 @@ - user_email = "(#{params[:email]})" if params[:email].present? +- request_link_start = '<a href="%{new_user_confirmation_path}">'.html_safe % { new_user_confirmation_path: new_user_confirmation_path } +- request_link_end = '</a>'.html_safe .well-confirmation.gl-text-center.gl-mb-6 %h1.gl-mt-0 = _("Almost there...") - %p.lead.gl-mb-6 + %p{ class: 'gl-mb-6 gl-font-lg!' } = _('Please check your email %{email} to confirm your account') % { email: user_email } %hr - if Gitlab::CurrentSettings.after_sign_up_text.present? .well-confirmation.gl-text-center = markdown_field(Gitlab::CurrentSettings, :after_sign_up_text) -%p.text-center - = _("No confirmation email received? Please check your spam folder or") -.gl-mb-6.prepend-top-20.gl-text-center - %a.gl-link{ href: new_user_confirmation_path } - = _("Request new confirmation email") +%p.gl-text-center + = _("No confirmation email received? Check your spam folder or %{request_link_start}request new confirmation email%{request_link_end}.").html_safe % { request_link_start: request_link_start, request_link_end: request_link_end } diff --git a/app/views/devise/mailer/_confirmation_instructions_secondary.text.erb b/app/views/devise/mailer/_confirmation_instructions_secondary.text.erb index ab46aaaca1a..32e88047a9c 100644 --- a/app/views/devise/mailer/_confirmation_instructions_secondary.text.erb +++ b/app/views/devise/mailer/_confirmation_instructions_secondary.text.erb @@ -1,4 +1,4 @@ -<%= _(" %{name}, confirm your email address now! ") % { name: @resource.user.name } %> +<%= _("%{name}, confirm your email address now!") % { name: @resource.user.name } %> <%= _("Use the link below to confirm your email address (%{email})") % { email: @resource.email } %> diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml index 10c04423589..56bd30fac73 100644 --- a/app/views/devise/passwords/edit.html.haml +++ b/app/views/devise/passwords/edit.html.haml @@ -7,10 +7,10 @@ = f.hidden_field :reset_password_token .form-group = f.label _('New password'), for: "user_password" - = f.password_field :password, class: "form-control gl-form-input top", required: true, title: _('This field is required.'), data: { qa_selector: 'password_field'} + = f.password_field :password, autocomplete: 'new-password', class: "form-control gl-form-input top", required: true, title: _('This field is required.'), data: { qa_selector: 'password_field'} .form-group = f.label _('Confirm new password'), for: "user_password_confirmation" - = f.password_field :password_confirmation, class: "form-control gl-form-input bottom", title: _('This field is required.'), data: { qa_selector: 'password_confirmation_field' }, required: true + = f.password_field :password_confirmation, autocomplete: 'new-password', class: "form-control gl-form-input bottom", title: _('This field is required.'), data: { qa_selector: 'password_confirmation_field' }, required: true .clearfix = f.submit _("Change your password"), class: "gl-button btn btn-confirm", data: { qa_selector: 'change_password_button' } diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 4ec3fcde337..87108c8ea78 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -2,6 +2,7 @@ - add_page_specific_style 'page_bundles/signup' - content_for :page_specific_javascripts do = render "layouts/google_tag_manager_head" + = render "layouts/one_trust" = render "layouts/google_tag_manager_body" .signup-page diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index 82c0df354d4..b40373ecc37 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -4,12 +4,12 @@ = f.text_field :login, value: @invite_email, class: 'form-control gl-form-input top', autofocus: 'autofocus', autocapitalize: 'off', autocorrect: 'off', required: true, title: _('This field is required.'), data: { qa_selector: 'login_field' } .form-group = f.label :password, class: 'label-bold' - = f.password_field :password, class: 'form-control gl-form-input bottom', required: true, title: _('This field is required.'), data: { qa_selector: 'password_field' } + = f.password_field :password, class: 'form-control gl-form-input bottom', autocomplete: 'current-password', required: true, title: _('This field is required.'), data: { qa_selector: 'password_field' } - if devise_mapping.rememberable? - .remember-me + %div %label{ for: 'user_remember_me' } - = f.check_box :remember_me, class: 'remember-me-checkbox' - %span Remember me + = f.check_box :remember_me + %span= _('Remember me') .float-right - if unconfirmed_email? = link_to _('Resend confirmation email'), new_user_confirmation_path diff --git a/app/views/devise/sessions/_new_crowd.html.haml b/app/views/devise/sessions/_new_crowd.html.haml index 769268748f4..fb4c011dd49 100644 --- a/app/views/devise/sessions/_new_crowd.html.haml +++ b/app/views/devise/sessions/_new_crowd.html.haml @@ -4,7 +4,7 @@ = text_field_tag :username, nil, { class: "form-control top", title: _("This field is required."), autofocus: "autofocus", required: true } .form-group = label_tag :password - = password_field_tag :password, nil, { class: "form-control bottom", title: _("This field is required."), required: true } + = password_field_tag :password, nil, { autocomplete: 'current-password', class: "form-control bottom", title: _("This field is required."), required: true } - if devise_mapping.rememberable? .remember-me %label{ for: "remember_me" } diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml index f599a652b71..fea58779c17 100644 --- a/app/views/devise/sessions/_new_ldap.html.haml +++ b/app/views/devise/sessions/_new_ldap.html.haml @@ -8,7 +8,7 @@ = text_field_tag :username, nil, { class: "form-control gl-form-input top", title: _("This field is required."), autofocus: "autofocus", data: { qa_selector: 'username_field' }, required: true } .form-group = label_tag :password - = password_field_tag :password, nil, { class: "form-control gl-form-input bottom", title: _("This field is required."), data: { qa_selector: 'password_field' }, required: true } + = password_field_tag :password, nil, { autocomplete: 'current-password', class: "form-control gl-form-input bottom", title: _("This field is required."), data: { qa_selector: 'password_field' }, required: true } - if !hide_remember_me && devise_mapping.rememberable? .remember-me %label{ for: "remember_me" } diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index 74f3e3e7e34..da6232b2a2b 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -1,6 +1,7 @@ - page_title _("Sign in") - content_for :page_specific_javascripts do = render "layouts/google_tag_manager_head" + = render "layouts/one_trust" = render "layouts/google_tag_manager_body" #signin-container diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml index 1752a43b032..bd7fe41ae8d 100644 --- a/app/views/devise/shared/_omniauth_box.html.haml +++ b/app/views/devise/shared/_omniauth_box.html.haml @@ -1,20 +1,20 @@ - hide_remember_me = local_assigns.fetch(:hide_remember_me, false) .omniauth-container.gl-mt-5 - %label.label-bold.d-block + %label.gl-font-weight-bold = _('Sign in with') - providers = enabled_button_based_providers - .d-flex.justify-content-between.flex-wrap + .gl-display-flex.gl-justify-content-between.gl-flex-wrap - providers.each do |provider| - has_icon = provider_has_icon?(provider) - = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn gl-button btn-default omniauth-btn oauth-login #{qa_class_for_provider(provider)}", form: { class: 'gl-w-full' } do + = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn gl-button btn-default gl-w-full js-oauth-login #{qa_class_for_provider(provider)}", form: { class: 'gl-w-full gl-mb-3' } do - if has_icon = provider_image_tag(provider) %span.gl-button-text = label_for_provider(provider) - unless hide_remember_me - %fieldset.remember-me + %fieldset %label - = check_box_tag :remember_me, nil, false, class: 'remember-me-checkbox' + = check_box_tag :remember_me, nil, false %span = _('Remember me') diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml index f9649875538..15143684b8b 100644 --- a/app/views/devise/shared/_signup_box.html.haml +++ b/app/views/devise/shared/_signup_box.html.haml @@ -53,6 +53,7 @@ = f.password_field :password, class: 'form-control gl-form-input bottom', data: { qa_selector: 'new_user_password_field' }, + autocomplete: 'new-password', required: true, pattern: ".{#{@minimum_password_length},}", title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length } diff --git a/app/views/devise/shared/_signup_omniauth_provider_list.haml b/app/views/devise/shared/_signup_omniauth_provider_list.haml index 43e0802ee2a..c24e8770f05 100644 --- a/app/views/devise/shared/_signup_omniauth_provider_list.haml +++ b/app/views/devise/shared/_signup_omniauth_provider_list.haml @@ -1,9 +1,9 @@ -%label.label-bold.d-block +%label.gl-font-weight-bold = _("Create an account using:") -.d-flex.justify-content-between.flex-wrap +.gl-display-flex.gl-justify-content-between.gl-flex-wrap - providers.each do |provider| - = link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn gl-button btn-default gl-display-flex gl-align-items-center gl-text-left gl-mb-2 gl-p-2 omniauth-btn oauth-login #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do + = link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn gl-button btn-default gl-w-full gl-mb-3 js-oauth-login #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do - if provider_has_icon?(provider) = provider_image_tag(provider) - %span.ml-2 + %span.gl-button-text = label_for_provider(provider) diff --git a/app/views/devise/shared/_signup_omniauth_providers.haml b/app/views/devise/shared/_signup_omniauth_providers.haml index a653d44d694..30a54ab86a6 100644 --- a/app/views/devise/shared/_signup_omniauth_providers.haml +++ b/app/views/devise/shared/_signup_omniauth_providers.haml @@ -1,3 +1,3 @@ -.omniauth-divider.d-flex.align-items-center.text-center +.omniauth-divider.gl-display-flex.gl-align-items-center = _("or") = render 'devise/shared/signup_omniauth_provider_list', providers: enabled_button_based_providers diff --git a/app/views/devise/shared/_signup_omniauth_providers_top.haml b/app/views/devise/shared/_signup_omniauth_providers_top.haml index 9a2629443ed..8eb22c0b023 100644 --- a/app/views/devise/shared/_signup_omniauth_providers_top.haml +++ b/app/views/devise/shared/_signup_omniauth_providers_top.haml @@ -1,3 +1,3 @@ = render 'devise/shared/signup_omniauth_provider_list', providers: popular_enabled_button_based_providers -.omniauth-divider.d-flex.align-items-center.text-center +.omniauth-divider.gl-display-flex.gl-align-items-center = _("or") diff --git a/app/views/groups/_group_admin_settings.html.haml b/app/views/groups/_group_admin_settings.html.haml index ea191449fe3..ab6861b5f24 100644 --- a/app/views/groups/_group_admin_settings.html.haml +++ b/app/views/groups/_group_admin_settings.html.haml @@ -36,4 +36,4 @@ .offset-sm-2.col-sm-10 .form-check = f.text_field :two_factor_grace_period, class: 'form-control' - .form-text.text-muted= _("Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication") + .form-text.text-muted= _("Time (in hours) that users are allowed to skip forced configuration of two-factor authentication.") diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml index 0352f366f5d..e530d9c60b6 100644 --- a/app/views/groups/_home_panel.html.haml +++ b/app/views/groups/_home_panel.html.haml @@ -5,17 +5,19 @@ .group-home-panel .row.mb-3 .home-panel-title-row.col-md-12.col-lg-6.d-flex - .avatar-container.rect-avatar.s64.home-panel-avatar.gl-mr-3.float-none + .avatar-container.rect-avatar.s64.home-panel-avatar.gl-flex-shrink-0.float-none{ class: 'gl-mr-3!' } = group_icon(@group, class: 'avatar avatar-tile s64', width: 64, height: 64, itemprop: 'logo') .d-flex.flex-column.flex-wrap.align-items-baseline .d-inline-flex.align-items-baseline - %h1.home-panel-title.gl-mt-3.gl-mb-2{ itemprop: 'name' } + %h1.home-panel-title.gl-mt-3.gl-mb-2.gl-ml-3{ itemprop: 'name' } = @group.name %span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) } = visibility_level_icon(@group.visibility_level, options: {class: 'icon'}) - .home-panel-metadata.text-secondary - %span - = _("Group ID: %{group_id}") % { group_id: @group.id } + .home-panel-metadata.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal + - if can?(current_user, :read_group, @group) + - button_class = "btn gl-button btn-sm btn-tertiary btn-default-tertiary home-panel-metadata" + - button_text = s_('GroupPage|Group ID: %{group_id}') % { group_id: @group.id } + = clipboard_button(title: s_('GroupPage|Copy group ID'), text: @group.id, hide_button_icon: true, button_text: button_text, class: button_class, qa_selector: 'group_id_content', itemprop: 'identifier') - if current_user %span.gl-ml-3 = render 'shared/members/access_request_links', source: @group diff --git a/app/views/groups/_import_group_from_another_instance_panel.html.haml b/app/views/groups/_import_group_from_another_instance_panel.html.haml index 2b9277c67e9..06a86c2465f 100644 --- a/app/views/groups/_import_group_from_another_instance_panel.html.haml +++ b/app/views/groups/_import_group_from_another_instance_panel.html.haml @@ -1,16 +1,15 @@ = form_with url: configure_import_bulk_imports_path, class: 'group-form gl-show-field-errors' do |f| .gl-border-l-solid.gl-border-r-solid.gl-border-gray-100.gl-border-1.gl-p-5 - %h4.gl-display-flex - = s_('GroupsNew|Import groups from another instance of GitLab') - %span.badge.badge-info.badge-pill.gl-badge.md.gl-ml-3 - = _('Beta') + .gl-display-flex.gl-align-items-center + %h4.gl-display-flex + = s_('GroupsNew|Import groups from another instance of GitLab') + = link_to _('History'), history_import_bulk_imports_path, class: 'gl-link gl-ml-auto' .gl-alert.gl-alert-warning{ role: 'alert' } = sprite_icon('warning', css_class: 'gl-icon s16 gl-alert-icon gl-alert-icon-no-title') .gl-alert-body - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/group/import/index.md') } - - feedback_link_start = '<a href="https://gitlab.com/gitlab-org/gitlab/-/issues/284495" target="_blank" rel="noopener noreferrer">'.html_safe - - link_end = '</a>'.html_safe - = s_('GroupsNew|Not all related objects are migrated, as %{docs_link_start}described here%{docs_link_end}. Please %{feedback_link_start}leave feedback%{feedback_link_end} on this feature.').html_safe % { docs_link_start: docs_link_start, docs_link_end: link_end, feedback_link_start: feedback_link_start, feedback_link_end: link_end } + - docs_link_end = '</a>'.html_safe + = s_('GroupsNew|Not all related objects are migrated. %{docs_link_start}More info%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: docs_link_end } %p.gl-mt-3 = s_('GroupsNew|Provide credentials for another instance of GitLab to import your groups directly.') .form-group.gl-display-flex.gl-flex-direction-column diff --git a/app/views/groups/dependency_proxies/_url.html.haml b/app/views/groups/dependency_proxies/_url.html.haml deleted file mode 100644 index 9a76da63a72..00000000000 --- a/app/views/groups/dependency_proxies/_url.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -- proxy_url = @group.dependency_proxy_image_prefix - -%h5.prepend-top-20= _('Dependency proxy image prefix') - -.row - .col-lg-8.col-md-12.input-group - = text_field_tag :url, "#{proxy_url}", class: 'js-dependency-proxy-url form-control', readonly: true - = clipboard_button(text: "#{proxy_url}", title: _("Copy %{proxy_url}") % { proxy_url: proxy_url }) - -.row - .col-12.help-block.gl-mt-3{ data: { qa_selector: 'dependency_proxy_count' } } - = _('Contains %{count} blobs of images (%{size})') % { count: @blobs_count, size: number_to_human_size(@blobs_total_size) } diff --git a/app/views/groups/dependency_proxies/show.html.haml b/app/views/groups/dependency_proxies/show.html.haml index 177018af830..8936c4dcbb4 100644 --- a/app/views/groups/dependency_proxies/show.html.haml +++ b/app/views/groups/dependency_proxies/show.html.haml @@ -1,30 +1,5 @@ - page_title _("Dependency Proxy") +- dependency_proxy_available = Feature.enabled?(:dependency_proxy_for_private_groups, default_enabled: true) || @group.public? -.settings-header - %h4= _('Dependency proxy') - - %p - - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('user/packages/dependency_proxy/index') } - = _('Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe } - -- if Feature.enabled?(:dependency_proxy_for_private_groups, default_enabled: true) || @group.public? - - if can?(current_user, :admin_dependency_proxy, @group) - = form_for(@dependency_proxy, method: :put, url: group_dependency_proxy_path(@group)) do |f| - .form-group - %h5.prepend-top-20= _('Enable proxy') - .js-dependency-proxy-toggle-area - = render "shared/buttons/project_feature_toggle", is_checked: @dependency_proxy.enabled?, label: s_("DependencyProxy|Toggle Dependency Proxy"), data: { qa_selector: 'dependency_proxy_setting_toggle' } do - = f.hidden_field :enabled, { class: 'js-project-feature-toggle-input'} - - - if @dependency_proxy.enabled - = render 'groups/dependency_proxies/url' - - - else - - if @dependency_proxy.enabled - = render 'groups/dependency_proxies/url' -- else - .gl-alert.gl-alert-info - .gl-alert-container - = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-content - = _('Dependency proxy feature is limited to public groups for now.') +#js-dependency-proxy{ data: { group_path: @group.full_path, + dependency_proxy_available: dependency_proxy_available.to_s } } diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 6e355d31204..420771257c9 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -1,5 +1,5 @@ -- breadcrumb_title _("General Settings") -- page_title _("General Settings") +- breadcrumb_title _("General settings") +- page_title _("General settings") - @content_class = "limit-container-width" unless fluid_layout - expanded = expanded_by_default? @@ -13,6 +13,7 @@ = _('Collapse') %p = _('Update your group name, description, avatar, and visibility.') + = link_to s_('Learn more about groups.'), help_page_path('user/group/index') .settings-content = render 'groups/settings/general' @@ -23,7 +24,7 @@ %button.btn.gl-button.js-settings-toggle{ type: 'button' } = expanded ? _('Collapse') : _('Expand') %p - = _('Advanced permissions, Large File Storage and Two-Factor authentication settings.') + = _('Configure advanced permissions, Large File Storage, and two-factor authentication settings.') .settings-content = render 'groups/settings/permissions' diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 1f746484b7d..0c6776a6038 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -6,7 +6,7 @@ = auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@group.name} issues") - if Feature.enabled?(:vue_issues_list, @group, default_enabled: :yaml) - .js-issues-list{ data: group_issues_list_data(@group, current_user, @issues) } + .js-issues-list{ data: group_issues_list_data(@group, current_user, @issues, @projects) } - if @can_bulk_update = render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :issues - else diff --git a/app/views/groups/registry/repositories/index.html.haml b/app/views/groups/registry/repositories/index.html.haml index fa6bd021e45..2901c8fa46b 100644 --- a/app/views/groups/registry/repositories/index.html.haml +++ b/app/views/groups/registry/repositories/index.html.haml @@ -16,7 +16,8 @@ is_group_page: "true", "group_path": @group.full_path, "gid_prefix": container_repository_gid_prefix, - character_error: @character_error.to_s, + connection_error: (!!@connection_error).to_s, + invalid_path_error: (!!@invalid_path_error).to_s, user_callouts_path: user_callouts_path, user_callout_id: UserCalloutsHelper::UNFINISHED_TAG_CLEANUP_CALLOUT, show_unfinished_tag_cleanup_callout: show_unfinished_tag_cleanup_callout?.to_s } } diff --git a/app/views/groups/runners/_runner.html.haml b/app/views/groups/runners/_runner.html.haml index 66ffef98553..a76701ea5d2 100644 --- a/app/views/groups/runners/_runner.html.haml +++ b/app/views/groups/runners/_runner.html.haml @@ -39,7 +39,7 @@ - if runner.group_type? = _('n/a') - else - = runner.projects.count(:all) + = runner.runner_projects.count(:all) .table-section.section-5 .table-mobile-header{ role: 'rowheader' }= _('Jobs') diff --git a/app/views/groups/settings/_general.html.haml b/app/views/groups/settings/_general.html.haml index 7a2d5c91af6..ed76a9fe253 100644 --- a/app/views/groups/settings/_general.html.haml +++ b/app/views/groups/settings/_general.html.haml @@ -14,8 +14,9 @@ .row.gl-mt-3 .form-group.col-md-9 - = f.label :description, _('Group description (optional)'), class: 'label-bold' + = f.label :description, _('Group description'), class: 'label-bold' = f.text_area :description, class: 'form-control', rows: 3, maxlength: 250 + .form-text.text-muted= _('Optional.') = render_if_exists 'shared/repository_size_limit_setting', form: f, type: :group diff --git a/app/views/groups/settings/_lfs.html.haml b/app/views/groups/settings/_lfs.html.haml index 1255a2901ea..9f04b579a97 100644 --- a/app/views/groups/settings/_lfs.html.haml +++ b/app/views/groups/settings/_lfs.html.haml @@ -3,10 +3,10 @@ %h5= _('Large File Storage') -%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe } +%p= s_('%{docs_link_start}What is Large File Storage?%{docs_link_end}').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe } .form-group.gl-mb-3 = f.gitlab_ui_checkbox_component :lfs_enabled, _('Allow projects within this group to use Git LFS'), - help_text: _('This setting can be overridden in each project.'), + help_text: _('Can be overridden in each project.'), checkbox_options: { checked: @group.lfs_enabled?, data: { qa_selector: 'lfs_checkbox' } } diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml index 8f428909e60..eb38aa43881 100644 --- a/app/views/groups/settings/_permissions.html.haml +++ b/app/views/groups/settings/_permissions.html.haml @@ -7,7 +7,7 @@ - if @group.root? .form-group.gl-mb-3 = f.gitlab_ui_checkbox_component :prevent_sharing_groups_outside_hierarchy, - s_('GroupSettings|Prevent members from sending invitations to groups outside of %{group} and its subgroups.').html_safe % { group: link_to_group(@group) }, + s_('GroupSettings|Prevent members from sending invitations to groups outside of %{group} and its subgroups').html_safe % { group: link_to_group(@group) }, help_text: prevent_sharing_groups_outside_hierarchy_help_text(@group), checkbox_options: { disabled: !can_change_prevent_sharing_groups_outside_hierarchy?(@group) } @@ -21,13 +21,13 @@ = f.gitlab_ui_checkbox_component :emails_disabled, s_('GroupSettings|Disable email notifications'), checkbox_options: { checked: @group.emails_disabled?, disabled: !can_disable_group_emails?(@group) }, - help_text: s_('GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects.') + help_text: s_('GroupSettings|Overrides user notification preferences for all members of the group, subgroups, and projects.') .form-group.gl-mb-3 = f.gitlab_ui_checkbox_component :mentions_disabled, s_('GroupSettings|Disable group mentions'), checkbox_options: { checked: @group.mentions_disabled? }, - help_text: s_('GroupSettings|This setting will prevent group members from being notified if the group is mentioned.') + help_text: s_('GroupSettings|Prevents group members from being notified if the group is mentioned.') = render 'groups/settings/project_access_token_creation', f: f, group: @group = render_if_exists 'groups/settings/delayed_project_removal', f: f, group: @group diff --git a/app/views/groups/settings/_two_factor_auth.html.haml b/app/views/groups/settings/_two_factor_auth.html.haml index 8204cafcb44..f86bcb24e63 100644 --- a/app/views/groups/settings/_two_factor_auth.html.haml +++ b/app/views/groups/settings/_two_factor_auth.html.haml @@ -4,16 +4,16 @@ %h5= _('Two-factor authentication') -%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe } +%p= s_('%{docs_link_start}What is two-factor authentication?%{docs_link_end}').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe } .form-group = f.gitlab_ui_checkbox_component :require_two_factor_authentication, - _('Require all users in this group to setup two-factor authentication'), + _('Require all users in this group to set up two-factor authentication'), checkbox_options: { data: { qa_selector: 'require_2fa_checkbox' } } .form-group - = f.label :two_factor_grace_period, _('Time before enforced'), class: 'label-bold' - = f.text_field :two_factor_grace_period, class: 'form-control form-control-sm w-auto' - .form-text.text-muted= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication') + = f.label :two_factor_grace_period, _('Time before enforced') + = f.text_field :two_factor_grace_period, class: 'form-control form-control-sm w-auto gl-form-input gl-mb-3' + .form-text.text-muted= _('Time (in hours) that users are allowed to skip forced configuration of two-factor authentication.') - unless group.has_parent? .form-group = f.gitlab_ui_checkbox_component :allow_mfa_for_subgroups, diff --git a/app/views/groups/settings/packages_and_registries/show.html.haml b/app/views/groups/settings/packages_and_registries/show.html.haml index 1a12ad4902b..7be6dc73c49 100644 --- a/app/views/groups/settings/packages_and_registries/show.html.haml +++ b/app/views/groups/settings/packages_and_registries/show.html.haml @@ -1,5 +1,8 @@ - breadcrumb_title _('Packages & Registries') - page_title _('Packages & Registries') - @content_class = 'limit-container-width' unless fluid_layout +- dependency_proxy_available = Feature.enabled?(:dependency_proxy_for_private_groups, default_enabled: true) || @group.public? -%section#js-packages-and-registries-settings{ data: { default_expanded: expanded_by_default?.to_s, group_path: @group.full_path } } +%section#js-packages-and-registries-settings{ data: { default_expanded: expanded_by_default?.to_s, + group_path: @group.full_path, + dependency_proxy_available: dependency_proxy_available.to_s } } diff --git a/app/views/help/instance_configuration/_gitlab_pages.html.haml b/app/views/help/instance_configuration/_gitlab_pages.html.haml index 51835c202d6..1d8958c93e8 100644 --- a/app/views/help/instance_configuration/_gitlab_pages.html.haml +++ b/app/views/help/instance_configuration/_gitlab_pages.html.haml @@ -7,7 +7,7 @@ = _('GitLab Pages') %p - - link_to_gitlab_pages = link_to(_('GitLab Pages'), gitlab_pages[:url], target: '_blank') + - link_to_gitlab_pages = link_to(_('GitLab Pages'), gitlab_pages[:url], target: '_blank', rel: 'noopener noreferrer') = _('Below are the settings for %{link_to_gitlab_pages}.').html_safe % { link_to_gitlab_pages: link_to_gitlab_pages } .table-responsive %table diff --git a/app/views/help/instance_configuration/_rate_limits.html.haml b/app/views/help/instance_configuration/_rate_limits.html.haml index d72bd845c5b..ed71b5a609c 100644 --- a/app/views/help/instance_configuration/_rate_limits.html.haml +++ b/app/views/help/instance_configuration/_rate_limits.html.haml @@ -24,6 +24,7 @@ = render 'help/instance_configuration/rate_limit_row', title: _('Protected Paths: requests'), rate_limit: rate_limits[:protected_paths] = render 'help/instance_configuration/rate_limit_row', title: _('Package Registry: unauthenticated API requests'), rate_limit: rate_limits[:unauthenticated_packages_api], public_visible: true = render 'help/instance_configuration/rate_limit_row', title: _('Package Registry: authenticated API requests'), rate_limit: rate_limits[:authenticated_packages_api] + = render 'help/instance_configuration/rate_limit_row', title: _('Authenticated Git LFS requests'), rate_limit: rate_limits[:authenticated_git_lfs_api] = render 'help/instance_configuration/rate_limit_row', title: _('Issue creation requests'), rate_limit: rate_limits[:issue_creation] = render 'help/instance_configuration/rate_limit_row', title: _('Note creation requests'), rate_limit: rate_limits[:note_creation] = render 'help/instance_configuration/rate_limit_row', title: _('Project export requests'), rate_limit: rate_limits[:project_export] diff --git a/app/views/import/_githubish_status.html.haml b/app/views/import/_githubish_status.html.haml index 02a8f3142c6..8f18d68fd55 100644 --- a/app/views/import/_githubish_status.html.haml +++ b/app/views/import/_githubish_status.html.haml @@ -6,7 +6,7 @@ - provider_title = Gitlab::ImportSources.title(provider) - header_title _("New project"), new_project_path -- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project') #import-projects-mount-element{ data: { provider: provider, provider_title: provider_title, can_select_namespace: current_user.can_select_namespace?.to_s, diff --git a/app/views/import/bitbucket_server/new.html.haml b/app/views/import/bitbucket_server/new.html.haml index ce6bdd7a2fb..721447186a6 100644 --- a/app/views/import/bitbucket_server/new.html.haml +++ b/app/views/import/bitbucket_server/new.html.haml @@ -1,6 +1,6 @@ - page_title _('Bitbucket Server Import') - header_title _("New project"), new_project_path -- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project') %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center diff --git a/app/views/import/bulk_imports/history.html.haml b/app/views/import/bulk_imports/history.html.haml new file mode 100644 index 00000000000..80eb0c7a764 --- /dev/null +++ b/app/views/import/bulk_imports/history.html.haml @@ -0,0 +1,6 @@ +- add_to_breadcrumbs _('New group'), new_group_path +- add_to_breadcrumbs _('Import group'), new_group_path(anchor: 'import-group-pane') +- add_page_specific_style 'page_bundles/import' +- page_title _('Import history') + +#import-history-mount-element diff --git a/app/views/import/fogbugz/new.html.haml b/app/views/import/fogbugz/new.html.haml index 51156797270..d716d08529c 100644 --- a/app/views/import/fogbugz/new.html.haml +++ b/app/views/import/fogbugz/new.html.haml @@ -1,6 +1,6 @@ - page_title _("FogBugz Import") - header_title _("New project"), new_project_path -- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project') %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center diff --git a/app/views/import/fogbugz/new_user_map.html.haml b/app/views/import/fogbugz/new_user_map.html.haml index 4281d77e833..93572e14a65 100644 --- a/app/views/import/fogbugz/new_user_map.html.haml +++ b/app/views/import/fogbugz/new_user_map.html.haml @@ -1,6 +1,6 @@ - page_title _('User map'), _('FogBugz import') - header_title _("New project"), new_project_path -- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project') %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center diff --git a/app/views/import/gitea/new.html.haml b/app/views/import/gitea/new.html.haml index 288ae5f1cec..de717ce87eb 100644 --- a/app/views/import/gitea/new.html.haml +++ b/app/views/import/gitea/new.html.haml @@ -1,6 +1,6 @@ - page_title _("Gitea Import") - header_title _("New project"), new_project_path -- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project') %h3.page-title = custom_icon('gitea_logo') diff --git a/app/views/import/github/new.html.haml b/app/views/import/github/new.html.haml index 3407f9202bf..3f7f929f766 100644 --- a/app/views/import/github/new.html.haml +++ b/app/views/import/github/new.html.haml @@ -1,7 +1,7 @@ - title = _('Authenticate with GitHub') - page_title title - header_title _("New project"), new_project_path -- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project') %h3.page-title = title diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index 028268482cd..533d0d13be3 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -1,6 +1,6 @@ - page_title _("GitLab Import") - header_title _("New project"), new_project_path -- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project') %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center diff --git a/app/views/import/manifest/new.html.haml b/app/views/import/manifest/new.html.haml index bfaff3bb300..a949e14e273 100644 --- a/app/views/import/manifest/new.html.haml +++ b/app/views/import/manifest/new.html.haml @@ -1,6 +1,6 @@ - page_title _("Manifest file import") - header_title _("New project"), new_project_path -- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project') %h3.page-title diff --git a/app/views/import/phabricator/new.html.haml b/app/views/import/phabricator/new.html.haml index 9596fdb615a..0249dc446e4 100644 --- a/app/views/import/phabricator/new.html.haml +++ b/app/views/import/phabricator/new.html.haml @@ -1,6 +1,6 @@ - page_title _('Phabricator Server Import') - header_title _("New project"), new_project_path -- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project') +- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project') %h3.page-title.d-flex .gl-display-flex.gl-align-items-center.gl-justify-content-center diff --git a/app/views/layouts/_one_trust.html.haml b/app/views/layouts/_one_trust.html.haml new file mode 100644 index 00000000000..4fab017d273 --- /dev/null +++ b/app/views/layouts/_one_trust.html.haml @@ -0,0 +1,16 @@ +- if one_trust_enabled? + - one_trust_id = sanitize(extra_config.one_trust_id, scrubber: Rails::Html::TextOnlyScrubber.new) + + <!-- OneTrust --> + = javascript_include_tag "https://cdn.cookielaw.org/consent/#{one_trust_id}/OtAutoBlock.js" + = javascript_tag nonce: content_security_policy_nonce do + :plain + const oneTrustScript = document.createElement('script'); + oneTrustScript.src = 'https://cdn.cookielaw.org/scripttemplates/otSDKStub.js'; + oneTrustScript.dataset.domainScript = '#{one_trust_id}'; + oneTrustScript.nonce = '#{content_security_policy_nonce}' + oneTrustScript.charset = 'UTF-8'; + oneTrustScript.defer = true; + document.head.appendChild(oneTrustScript); + + function OptanonWrapper() { } diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index ec2904245d3..dff1b5e3d04 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -17,6 +17,7 @@ = render_two_factor_auth_recovery_settings_check = render_if_exists "layouts/header/ee_subscribable_banner" = render_if_exists "shared/namespace_storage_limit_alert" + = render_if_exists "shared/namespace_user_cap_reached_alert" = render_if_exists "shared/new_user_signups_cap_reached_alert" = yield :page_level_alert = yield :customize_homepage_banner diff --git a/app/views/layouts/_startup_js.html.haml b/app/views/layouts/_startup_js.html.haml index 35cd191c600..0bf9c16b0d2 100644 --- a/app/views/layouts/_startup_js.html.haml +++ b/app/views/layouts/_startup_js.html.haml @@ -8,20 +8,30 @@ if (gl.startup_calls && window.fetch) { Object.keys(gl.startup_calls).forEach(apiCall => { - // fetch won’t send cookies in older browsers, unless you set the credentials init option. - // We set to `same-origin` which is default value in modern browsers. - // See https://github.com/whatwg/fetch/pull/585 for more information. - gl.startup_calls[apiCall] = { - fetchCall: fetch(apiCall, { credentials: 'same-origin' }) + gl.startup_calls[apiCall] = { + fetchCall: fetch(apiCall, { + // Emulate XHR for Rails AJAX request checks + headers: { + 'X-Requested-With': 'XMLHttpRequest' + }, + // fetch won’t send cookies in older browsers, unless you set the credentials init option. + // We set to `same-origin` which is default value in modern browsers. + // See https://github.com/whatwg/fetch/pull/585 for more information. + credentials: 'same-origin' + }) }; }); } if (gl.startup_graphql_calls && window.fetch) { + const headers = #{page_startup_graphql_headers.to_json}; const url = `#{api_graphql_url}` const opts = { method: "POST", - headers: { "Content-Type": "application/json", 'X-CSRF-Token': "#{form_authenticity_token}" }, + headers: { + "Content-Type": "application/json", + ...headers, + } }; gl.startup_graphql_calls = gl.startup_graphql_calls.map(call => ({ diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 3e7155b2c0e..8d28823bfa4 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -34,7 +34,8 @@ #js-header-search.header-search{ data: { 'search-context' => search_context.to_json, 'search-path' => search_path, 'issues-path' => issues_dashboard_path, - 'mr-path' => merge_requests_dashboard_path } } + 'mr-path' => merge_requests_dashboard_path, + 'autocomplete-path' => search_autocomplete_path } } %input{ type: "text", placeholder: _('Search or jump to...'), class: 'form-control gl-form-input' } - else = render 'layouts/search' diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index c111714f552..02a37dac158 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -19,8 +19,9 @@ = render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :after - unless @skip_current_level_breadcrumb %li - %h2.breadcrumbs-sub-title + %h2.breadcrumbs-sub-title{ data: { qa_selector: 'breadcrumb_sub_title_content' } } = link_to @breadcrumb_title, breadcrumb_title_link + -# haml-lint:disable InlineJavaScript %script{ type: 'application/ld+json' } :plain #{schema_breadcrumb_json} diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml index d0b73a3364a..842fb23d24a 100644 --- a/app/views/layouts/nav/sidebar/_admin.html.haml +++ b/app/views/layouts/nav/sidebar/_admin.html.haml @@ -1,13 +1,13 @@ %aside.nav-sidebar.qa-admin-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), 'aria-label': _('Admin navigation') } .nav-sidebar-inner-scroll .context-header - = link_to admin_root_path, title: _('Admin Overview') do + = link_to admin_root_path, title: _('Admin Overview'), class: 'has-tooltip', data: { container: 'body', placement: 'right' } do %span{ class: ['avatar-container', 'settings-avatar', 'rect-avatar', 's32'] } = sprite_icon('admin', size: 18) %span.sidebar-context-title = _('Admin Area') %ul.sidebar-top-level-items{ data: { qa_selector: 'admin_sidebar_overview_submenu_content' } } - = nav_link(controller: %w(dashboard admin admin/projects users groups jobs runners gitaly_servers cohorts), html_options: {class: 'home'}) do + = nav_link(controller: %w(dashboard admin admin/projects users groups admin/topics jobs runners gitaly_servers cohorts), html_options: {class: 'home'}) do = link_to admin_root_path, class: 'has-sub-items' do .nav-icon-container = sprite_icon('overview') @@ -35,6 +35,10 @@ = link_to admin_groups_path, title: _('Groups'), data: { qa_selector: 'groups_overview_link' } do %span = _('Groups') + = nav_link(controller: [:admin, 'admin/topics']) do + = link_to admin_topics_path, title: _('Topics'), data: { qa_selector: 'topics_overview_link' } do + %span + = _('Topics') = nav_link path: 'jobs#index' do = link_to admin_jobs_path, title: _('Jobs') do %span @@ -257,11 +261,6 @@ = link_to ci_cd_admin_application_settings_path, title: _('CI/CD') do %span = _('CI/CD') - - if Feature.enabled?(:serverless_domain) - = nav_link(path: 'application_settings#operations') do - = link_to admin_serverless_domains_path, title: _('Operations') do - %span - = _('Operations') = nav_link(path: 'application_settings#reporting') do = link_to reporting_admin_application_settings_path, title: _('Reporting') do %span diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml index 4db1e532ba5..16c0c00ad3f 100644 --- a/app/views/layouts/nav/sidebar/_profile.html.haml +++ b/app/views/layouts/nav/sidebar/_profile.html.haml @@ -1,7 +1,7 @@ %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 + = link_to profile_path, title: _('Profile Settings'), class: 'has-tooltip', data: { container: 'body', placement: 'right' } do %span{ class: ['avatar-container', 'settings-avatar', 's32'] } = image_tag avatar_icon_for_user(current_user, 32), class: ['avatar', 'avatar-tile', 'js-sidebar-user-avatar', 's32'], alt: current_user.name, data: { testid: 'sidebar-user-avatar' } %span.sidebar-context-title= _('User Settings') diff --git a/app/views/profiles/_email_settings.html.haml b/app/views/profiles/_email_settings.html.haml index bc678c2c429..1057e96f442 100644 --- a/app/views/profiles/_email_settings.html.haml +++ b/app/views/profiles/_email_settings.html.haml @@ -3,8 +3,11 @@ - email_change_disabled = local_assigns.fetch(:email_change_disabled, nil) - read_only_help_text = readonly ? s_("Profiles|Your email address was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:email) } : user_email_help_text(@user) - help_text = email_change_disabled ? s_("Your account uses dedicated credentials for the \"%{group_name}\" group and can only be updated through SSO.") % { group_name: @user.managing_group.name } : read_only_help_text +- password_automatically_set = @user.password_automatically_set? = form.text_field :email, required: true, class: 'input-lg gl-form-input', value: (@user.email unless @user.temp_oauth_email?), help: help_text.html_safe, readonly: readonly || email_change_disabled +- unless password_automatically_set + = hidden_field_tag 'user[validation_password]', :validation_password, class: 'js-password-prompt-field', help: s_("Profiles|Enter your password to confirm the email change") = form.select :public_email, options_for_select(@user.public_verified_emails, selected: @user.public_email), { help: s_("Profiles|This email will be displayed on your public profile"), include_blank: s_("Profiles|Do not show on profile") }, control_class: 'select2 input-lg', disabled: email_change_disabled diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml index 2cc919fc70e..5d3e0720176 100644 --- a/app/views/profiles/passwords/edit.html.haml +++ b/app/views/profiles/passwords/edit.html.haml @@ -19,16 +19,16 @@ - unless @user.password_automatically_set? .form-group - = f.label :current_password, _('Current password'), class: 'label-bold' - = f.password_field :current_password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' } + = f.label :password, _('Current password'), class: 'label-bold' + = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' } %p.form-text.text-muted = _('You must provide your current password in order to change it.') .form-group - = f.label :password, _('New password'), class: 'label-bold' - = f.password_field :password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' } + = f.label :new_password, _('New password'), class: 'label-bold' + = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' } .form-group = f.label :password_confirmation, _('Password confirmation'), class: 'label-bold' - = f.password_field :password_confirmation, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' } + = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' } .gl-mt-3.gl-mb-3 = f.submit _('Save password'), class: "gl-button btn btn-confirm gl-mr-3", data: { qa_selector: 'save_password_button' } - unless @user.password_automatically_set? diff --git a/app/views/profiles/passwords/new.html.haml b/app/views/profiles/passwords/new.html.haml index 7780ffe0cb4..9154c94abb6 100644 --- a/app/views/profiles/passwords/new.html.haml +++ b/app/views/profiles/passwords/new.html.haml @@ -14,18 +14,18 @@ - unless @user.password_automatically_set? .form-group.row .col-sm-2.col-form-label - = f.label :current_password, _('Current password') + = f.label :password, _('Current password') .col-sm-10 - = f.password_field :current_password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' } + = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' } .form-group.row .col-sm-2.col-form-label - = f.label :password, _('New password') + = f.label :new_password, _('New password') .col-sm-10 - = f.password_field :password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' } + = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' } .form-group.row .col-sm-2.col-form-label = f.label :password_confirmation, _('Password confirmation') .col-sm-10 - = f.password_field :password_confirmation, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' } + = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' } .form-actions = f.submit _('Set new password'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'set_new_password_button' } diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 0bb4859dd1e..3e41f107e04 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -5,7 +5,7 @@ - availability = availability_values - custom_emoji = show_status_emoji?(@user.status) -= bootstrap_form_for @user, url: profile_path, method: :put, html: { multipart: true, class: 'edit-user gl-mt-3 js-quick-submit gl-show-field-errors' }, authenticity_token: true do |f| += bootstrap_form_for @user, url: profile_path, method: :put, html: { multipart: true, class: 'edit-user gl-mt-3 js-quick-submit gl-show-field-errors js-password-prompt-form', remote: true }, authenticity_token: true do |f| = form_errors(@user) .row.js-search-settings-section @@ -80,7 +80,7 @@ %p= s_("Profiles|Set your local time zone") .col-lg-8 %h5= _("Time zone") - = dropdown_tag(_("Select a time zone"), options: { toggle_class: 'gl-button btn js-timezone-dropdown input-lg', title: _("Select a time zone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } ) + = dropdown_tag(_("Select a time zone"), options: { toggle_class: 'gl-button btn js-timezone-dropdown input-lg gl-w-full!', title: _("Select a time zone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } ) %input.hidden{ :type => 'hidden', :id => 'user_timezone', :name => 'user[timezone]', value: @user.timezone } .col-lg-12 %hr @@ -124,9 +124,11 @@ .help-block = s_("Profiles|Choose to show contributions of private projects on your public profile without any project, repository or organization information") %hr - = f.submit s_("Profiles|Update profile settings"), class: 'gl-button btn btn-confirm gl-mr-3' + = f.submit s_("Profiles|Update profile settings"), class: 'gl-button btn btn-confirm gl-mr-3 js-password-prompt-btn' = link_to _("Cancel"), user_path(current_user), class: 'gl-button btn btn-default btn-cancel' +#password-prompt-modal + .modal.modal-profile-crop{ data: { cropper_css_path: ActionController::Base.helpers.stylesheet_path('lazy_bundles/cropper.css') } } .modal-dialog .modal-content diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml index bd3cb7e60f0..00df8608957 100644 --- a/app/views/profiles/two_factor_auths/show.html.haml +++ b/app/views/profiles/two_factor_auths/show.html.haml @@ -50,7 +50,7 @@ - if current_password_required? .form-group = label_tag :current_password, _('Current password'), class: 'label-bold' - = password_field_tag :current_password, nil, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' } + = password_field_tag :current_password, nil, autocomplete: 'current-password', required: true, class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' } %p.form-text.text-muted = _('Your current password is required to register a two-factor authenticator app.') .gl-mt-3 diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml index 597a22bf34a..cdcc98552f9 100644 --- a/app/views/projects/_files.html.haml +++ b/app/views/projects/_files.html.haml @@ -20,5 +20,6 @@ = render 'stat_anchor_list', anchors: @project.statistics_buttons(show_auto_devops_callout: show_auto_devops_callout), project_buttons: true #js-tree-list{ data: vue_file_list_data(project, ref) } - - if can_edit_tree? + - if !Feature.enabled?(:new_dir_modal, default_enabled: :yaml) && can_edit_tree? = render 'projects/blob/new_dir' + diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index f2cee618849..1f2c16324fb 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -45,11 +45,10 @@ - if can?(current_user, :download_code, @project) = cache_if(cache_enabled, [@project, :download_code], expires_in: 1.minute) do %nav.project-stats - .nav-links.quick-links - - if @project.empty_repo? - = render 'stat_anchor_list', anchors: @project.empty_repo_statistics_anchors - - else - = render 'stat_anchor_list', anchors: @project.statistics_anchors(show_auto_devops_callout: show_auto_devops_callout) + - if @project.empty_repo? + = render 'stat_anchor_list', anchors: @project.empty_repo_statistics_anchors + - else + = render 'stat_anchor_list', anchors: @project.statistics_anchors(show_auto_devops_callout: show_auto_devops_callout) .home-panel-home-desc.mt-1 - if @project.description.present? diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml index 815a3cf6966..81d9726fcdc 100644 --- a/app/views/projects/_import_project_pane.html.haml +++ b/app/views/projects/_import_project_pane.html.haml @@ -83,7 +83,7 @@ .js-toggle-content.toggle-import-form{ class: ('hide' if active_tab != 'import') } - = form_for @project, html: { class: 'new_project' } do |f| + = form_for @project, html: { class: 'new_project gl-show-field-errors' } do |f| %hr = render "shared/import_form", f: f = render 'projects/new_project_fields', f: f, project_name_id: "import-url-name", hide_init_with_readme: true, track_label: track_label diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml index fb7a7ef8985..256c3ebad0a 100644 --- a/app/views/projects/_new_project_fields.html.haml +++ b/app/views/projects/_new_project_fields.html.haml @@ -16,7 +16,12 @@ - if current_user.can_select_namespace? - namespace_id = namespace_id_from(params) - if Feature.enabled?(:paginatable_namespace_drop_down_for_project_creation, current_user, default_enabled: :yaml) - .js-vue-new-project-url-select{ data: { namespace_full_path: GroupFinder.new(current_user).execute(id: namespace_id)&.full_path, namespace_id: namespace_id, root_url: root_url, track_label: track_label } } + .js-vue-new-project-url-select{ data: { namespace_full_path: GroupFinder.new(current_user).execute(id: namespace_id)&.full_path, + namespace_id: namespace_id, + root_url: root_url, + track_label: track_label, + user_namespace_full_path: current_user.namespace.full_path, + user_namespace_id: current_user.namespace.id } } - else .input-group-prepend.flex-shrink-0.has-tooltip{ title: root_url } .input-group-text @@ -53,15 +58,36 @@ = render 'shared/visibility_level', f: f, visibility_level: visibility_level.to_i, can_change_visibility_level: true, form_model: @project, with_label: false - if !hide_init_with_readme - .form-group.row.initialize-with-readme-setting - %div{ :class => "col-sm-12" } - .form-check - = check_box_tag 'project[initialize_with_readme]', '1', true, class: 'form-check-input', data: { qa_selector: "initialize_with_readme_checkbox", track_label: "#{track_label}", track_action: "activate_form_input", track_property: "init_with_readme", track_value: "" } - = label_tag 'project[initialize_with_readme]', class: 'form-check-label' do - .option-title - %strong= s_('ProjectsNew|Initialize repository with a README') - .option-description - = s_('ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository.') + = f.label :project_configuration, class: 'label-bold' do + = s_('ProjectsNew|Project Configuration') + + .form-group + .form-check.gl-mb-3 + = check_box_tag 'project[initialize_with_readme]', '1', true, class: 'form-check-input', data: { qa_selector: 'initialize_with_readme_checkbox', track_label: track_label, track_action: 'activate_form_input', track_property: 'init_with_readme' } + = label_tag 'project[initialize_with_readme]', s_('ProjectsNew|Initialize repository with a README'), class: 'form-check-label' + .form-text.text-muted + = s_('ProjectsNew|Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository.') + + - experiment(:new_project_sast_enabled, user: current_user) do |e| + - e.try do + .form-group + .form-check.gl-mb-3 + = check_box_tag 'project[initialize_with_sast]', '1', true, class: 'form-check-input', data: { track_experiment: e.name, track_label: track_label, track_action: 'activate_form_input', track_property: 'init_with_sast' } + = label_tag 'project[initialize_with_sast]', class: 'form-check-label' do + = s_('ProjectsNew|Enable Static Application Security Testing (SAST)') + .form-text.text-muted + = s_('ProjectsNew|Analyze your source code for known security vulnerabilities.') + = link_to _('Learn more.'), help_page_path('user/application_security/sast/index'), target: '_blank', rel: 'noopener noreferrer', data: { track_action: 'followed', track_experiment: e.name } + - e.try(:free_indicator) do + .form-group + .form-check.gl-mb-3 + = check_box_tag 'project[initialize_with_sast]', '1', true, class: 'form-check-input', data: { track_experiment: e.name, track_label: track_label, track_action: 'activate_form_input', track_property: 'init_with_sast' } + = label_tag 'project[initialize_with_sast]', class: 'form-check-label' do + = s_('ProjectsNew|Enable Static Application Security Testing (SAST)') + %span.badge.badge-info.badge-pill.gl-badge.sm= _('Free') + .form-text.text-muted + = s_('ProjectsNew|Analyze your source code for known security vulnerabilities.') + = link_to _('Learn more.'), help_page_path('user/application_security/sast/index'), target: '_blank', rel: 'noopener noreferrer', data: { track_action: 'followed', track_experiment: e.name } = f.submit _('Create project'), class: "btn gl-button btn-confirm", data: { track_label: "#{track_label}", track_action: "click_button", track_property: "create_project", track_value: "" } = link_to _('Cancel'), dashboard_projects_path, class: 'btn gl-button btn-default btn-cancel', data: { track_label: "#{track_label}", track_action: "click_button", track_property: "cancel", track_value: "" } diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml index 66e9badbafb..168b240c657 100644 --- a/app/views/projects/blob/show.html.haml +++ b/app/views/projects/blob/show.html.haml @@ -18,3 +18,4 @@ = render 'projects/blob/upload', title: title, placeholder: title, button_title: 'Replace file', form_path: project_update_blob_path(@project, @id), method: :put = render partial: 'pipeline_tour_success' if show_suggest_pipeline_creation_celebration? += render 'shared/web_ide_path' diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml index b1d465d0e75..6733db69c34 100644 --- a/app/views/projects/branches/index.html.haml +++ b/app/views/projects/branches/index.html.haml @@ -1,19 +1,12 @@ - page_title _('Branches') - add_to_breadcrumbs(_('Repository'), project_tree_path(@project)) -.top-area.adjust - %ul.nav-links.issues-state-filters.nav.nav-tabs - %li{ class: active_when(@mode == 'overview') }> - = link_to s_('Branches|Overview'), project_branches_path(@project), title: s_('Branches|Show overview of the branches') - - %li{ class: active_when(@mode == 'active') }> - = link_to s_('Branches|Active'), project_branches_filtered_path(@project, state: 'active'), title: s_('Branches|Show active branches') - - %li{ class: active_when(@mode == 'stale') }> - = link_to s_('Branches|Stale'), project_branches_filtered_path(@project, state: 'stale'), title: s_('Branches|Show stale branches') - - %li{ class: active_when(!%w[overview active stale].include?(@mode)) }> - = link_to s_('Branches|All'), project_branches_filtered_path(@project, state: 'all'), title: s_('Branches|Show all branches') +.top-area.gl-border-0 + = gl_tabs_nav({ class: 'gl-flex-grow-1 gl-border-b-0' }) do + = gl_tab_link_to s_('Branches|Overview'), project_branches_path(@project), { item_active: @mode == 'overview', title: s_('Branches|Show overview of the branches') } + = gl_tab_link_to s_('Branches|Active'), project_branches_filtered_path(@project, state: 'active'), { title: s_('Branches|Show active branches') } + = gl_tab_link_to s_('Branches|Stale'), project_branches_filtered_path(@project, state: 'stale'), { title: s_('Branches|Show stale branches') } + = gl_tab_link_to s_('Branches|All'), project_branches_filtered_path(@project, state: 'all'), { item_active: !%w[overview active stale].include?(@mode), title: s_('Branches|Show all branches') } .nav-controls #js-branches-sort-dropdown{ data: { project_branches_filtered_path: project_branches_path(@project, state: 'all'), sort_options: branches_sort_options_hash.to_json, mode: @mode } } @@ -38,7 +31,10 @@ %h5 = s_('Branches|Protected branches can be managed in %{project_settings_link}.').html_safe % { project_settings_link: project_settings_link } -- if @mode == 'overview' && (@active_branches.any? || @stale_branches.any?) +- if @gitaly_unavailable + = render 'shared/errors/gitaly_unavailable', reason: s_('Branches|Unable to load branches') + +- elsif @mode == 'overview' && (@active_branches.any? || @stale_branches.any?) = render "projects/branches/panel", branches: @active_branches, state: 'active', panel_title: s_('Branches|Active branches'), show_more_text: s_('Branches|Show more active branches'), project: @project, overview_max_branches: @overview_max_branches = render "projects/branches/panel", branches: @stale_branches, state: 'stale', panel_title: s_('Branches|Stale branches'), show_more_text: s_('Branches|Show more stale branches'), project: @project, overview_max_branches: @overview_max_branches diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml index 27858932e5e..8ee7910de4b 100644 --- a/app/views/projects/branches/new.html.haml +++ b/app/views/projects/branches/new.html.haml @@ -31,4 +31,5 @@ .form-actions = button_tag 'Create branch', class: 'gl-button btn btn-confirm' = link_to _('Cancel'), project_branches_path(@project), class: 'gl-button btn btn-default btn-cancel' +-# haml-lint:disable InlineJavaScript %script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe diff --git a/app/views/projects/ci/pipeline_editor/show.html.haml b/app/views/projects/ci/pipeline_editor/show.html.haml index 674765e9f89..ce6f7553ab4 100644 --- a/app/views/projects/ci/pipeline_editor/show.html.haml +++ b/app/views/projects/ci/pipeline_editor/show.html.haml @@ -1,3 +1,5 @@ +- add_page_specific_style 'page_bundles/pipelines' + - page_title s_('Pipelines|Pipeline Editor') - content_for :prefetch_asset_tags do - webpack_preload_asset_tag('monaco') diff --git a/app/views/projects/cluster_agents/show.html.haml b/app/views/projects/cluster_agents/show.html.haml new file mode 100644 index 00000000000..a2d3426d99c --- /dev/null +++ b/app/views/projects/cluster_agents/show.html.haml @@ -0,0 +1,4 @@ +- add_to_breadcrumbs _('Kubernetes'), project_clusters_path(@project) +- page_title @agent_name + +#js-cluster-agent-details{ data: js_cluster_agent_details_data(@agent_name, @project) } diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index bc0d14743b9..62ed50f5a0c 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -39,8 +39,14 @@ .committer - commit_author_link = commit_author_link(commit, avatar: false, size: 24) - - commit_timeago = time_ago_with_tooltip(commit.authored_date, placement: 'bottom') - - commit_text = _('%{commit_author_link} authored %{commit_timeago}') % { commit_author_link: commit_author_link, commit_timeago: commit_timeago } + - commit_authored_timeago = time_ago_with_tooltip(commit.authored_date, placement: 'bottom') + - if commit.different_committer? && commit.committer + - commit_committer_link = commit_committer_link(commit) + - commit_committer_timeago = time_ago_with_tooltip(commit.committed_date, placement: 'bottom') + - commit_committer_avatar = commit_committer_avatar(commit.committer, size: 18, has_tooltip: false) + - commit_text = _('%{commit_author_link} authored %{commit_authored_timeago} and %{commit_committer_avatar} %{commit_committer_link} committed %{commit_committer_timeago}') % { commit_author_link: commit_author_link, commit_authored_timeago: commit_authored_timeago, commit_committer_avatar: commit_committer_avatar, commit_committer_link: commit_committer_link, commit_committer_timeago: commit_committer_timeago } + - else + - commit_text = _('%{commit_author_link} authored %{commit_authored_timeago}') % { commit_author_link: commit_author_link, commit_authored_timeago: commit_authored_timeago } #{ commit_text.html_safe } = render_if_exists 'projects/commits/project_namespace', show_project_name: show_project_name, project: project diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml index 8270477ed3f..57dfcb8cf4a 100644 --- a/app/views/projects/deployments/_deployment.html.haml +++ b/app/views/projects/deployments/_deployment.html.haml @@ -27,7 +27,7 @@ = link_to deployment_path(deployment), class: 'build-link' do #{deployment.deployable.name} (##{deployment.deployable.id}) - else - .badge.badge-info.suggestion-help-hover{ title: s_('Deployment|This deployment was created using the API') } + .badge.badge-info.gl-cursor-help{ title: s_('Deployment|This deployment was created using the API') } = s_('Deployment|API') .table-section.section-10{ role: 'gridcell' } diff --git a/app/views/projects/feature_flags/edit.html.haml b/app/views/projects/feature_flags/edit.html.haml index c1c9f58265d..ac8c0575077 100644 --- a/app/views/projects/feature_flags/edit.html.haml +++ b/app/views/projects/feature_flags/edit.html.haml @@ -4,10 +4,4 @@ - breadcrumb_title @feature_flag.name - page_title s_('FeatureFlags|Edit Feature Flag') -#js-edit-feature-flag{ data: { endpoint: project_feature_flag_path(@project, @feature_flag), - project_id: @project.id, - feature_flags_path: project_feature_flags_path(@project), - environments_endpoint: search_project_environments_path(@project, format: :json), - strategy_type_docs_page_path: help_page_path('operations/feature_flags', anchor: 'feature-flag-strategies'), - environments_scope_docs_path: help_page_path('ci/environments/index.md', anchor: 'scope-environments-with-specs'), - feature_flag_issues_endpoint: feature_flag_issues_links_endpoint(@project, @feature_flag, current_user) } } +#js-edit-feature-flag{ data: edit_feature_flag_data } diff --git a/app/views/projects/google_cloud/index.html.haml b/app/views/projects/google_cloud/index.html.haml new file mode 100644 index 00000000000..4fc66e17810 --- /dev/null +++ b/app/views/projects/google_cloud/index.html.haml @@ -0,0 +1,83 @@ +- breadcrumb_title _('Google Cloud') +- page_title _('Google Cloud') + +- @content_class = "limit-container-width" unless fluid_layout + +#js-google-cloud + + %h1.gl-font-size-h1 Google Cloud + + %section#js-section-google-cloud-service-accounts + + %h2.gl-font-size-h2 Service Accounts + + %p= _('Service Accounts keys are required to authorize GitLab to deploy your Google Cloud project.') + + %table.table.b-table.gl-table + + %thead + %tr + %th Environment + %th GCP Project ID + %th Service Account Key + + %tbody + + %tr + %td * + %td serving-salutes-453 + %td ..... + + %tr + %td production + %td crimson-corey-234 + %td ..... + + %tr + %td review/* + %td roving-river-379 + %td ..... + + %a.gl-button.btn.btn-primary= _('Add new service account') + + %br + + %section#js-section-google-cloud-deployments + + .row.row-fluid + + .col-lg-4 + %h2.gl-font-size-h2 Deployments + %p= _('Google Cloud offers several deployment targets. Select the one most suitable for your project.') + %p + = _('Deployments to Google Kubernetes Engine can be ') + %a{ href: '#' }= _('managed') + = _('in Infrastructure :: Kubernetes clusters') + + .col-lg-8 + + %br + + .gl-card.gl-mb-6 + .gl-card-body + .gl-display-flex.gl-align-items-baseline + %strong.gl-font-lg App Engine + .gl-ml-auto.gl-text-gray-500 Disabled + %p= _('App Engine description and apps that are suitable for this deployment target') + %button.gl-button.btn.btn-default= _('Configure via Merge Request') + + .gl-card.gl-mb-6 + .gl-card-body + .gl-display-flex.gl-align-items-baseline + %strong.gl-font-lg Cloud Functions + .gl-ml-auto.gl-text-gray-500 Disabled + %p= _('Cloud Functions description and apps that are suitable for this deployment target') + %button.gl-button.btn.btn-default= _('Configure via Merge Request') + + .gl-card.gl-mb-6 + .gl-card-body + .gl-display-flex.gl-align-items-baseline + %strong.gl-font-lg Cloud Run + .gl-ml-auto.gl-text-gray-500 Disabled + %p= _('Cloud Run description and apps that are suitable for this deployment target') + %button.gl-button.btn.btn-default= _('Configure via Merge Request') diff --git a/app/views/projects/hook_logs/_index.html.haml b/app/views/projects/hook_logs/_index.html.haml index ee4dbf5c05c..6a46b0b3510 100644 --- a/app/views/projects/hook_logs/_index.html.haml +++ b/app/views/projects/hook_logs/_index.html.haml @@ -1,37 +1,11 @@ -.row.gl-mt-7.gl-mb-3 +- docs_link_url = help_page_path('user/project/integrations/webhooks', anchor: 'troubleshoot-webhooks') +- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url } +- link_end = '</a>'.html_safe + +.row.gl-mt-3.gl-mb-3 .col-lg-3 %h4.gl-mt-0 - Recent Deliveries - %p When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong. + = _('Recent events') + %p= _('GitLab events trigger webhooks. Use the request details of a webhook to help troubleshoot problems. %{link_start}How do I troubleshoot?%{link_end}').html_safe % { link_start: link_start, link_end: link_end } .col-lg-9 - - if hook_logs.present? - %table.table - %thead - %tr - %th Status - %th Trigger - %th URL - %th Elapsed time - %th Request time - %th - - hook_logs.each do |hook_log| - %tr - %td - = render partial: 'shared/hook_logs/status_label', locals: { hook_log: hook_log } - %td.d-none.d-sm-block - %span.badge.badge-gray.deploy-project-label - = hook_log.trigger.singularize.titleize - %td - = truncate(hook_log.url, length: 50) - %td.light - #{number_with_precision(hook_log.execution_duration, precision: 2)} sec - %td.light - = time_ago_with_tooltip(hook_log.created_at) - %td - = link_to 'View details', hook_log.present.details_path - - = paginate hook_logs, theme: 'gitlab' - - - else - .settings-message.text-center - You don't have any webhooks deliveries + = render partial: 'shared/hook_logs/recent_deliveries_table', locals: { hook: hook, hook_logs: hook_logs } diff --git a/app/views/projects/hook_logs/show.html.haml b/app/views/projects/hook_logs/show.html.haml index ebe179c3454..86dfa1929d6 100644 --- a/app/views/projects/hook_logs/show.html.haml +++ b/app/views/projects/hook_logs/show.html.haml @@ -5,8 +5,8 @@ .row.gl-mt-3.gl-mb-3 .col-lg-3 %h4.gl-mt-0 - Request details + = _("Request details") .col-lg-9 - = link_to 'Resend Request', @hook_log.present.retry_path, method: :post, class: "btn gl-button btn-default float-right gl-ml-3" + = link_to _('Resend Request'), @hook_log.present.retry_path, method: :post, class: "btn gl-button btn-default float-right gl-ml-3" = render partial: 'shared/hook_logs/content', locals: { hook_log: @hook_log } diff --git a/app/views/projects/issues/_nav_btns.html.haml b/app/views/projects/issues/_nav_btns.html.haml index 0d69f6f69aa..8d16c3d978f 100644 --- a/app/views/projects/issues/_nav_btns.html.haml +++ b/app/views/projects/issues/_nav_btns.html.haml @@ -5,11 +5,11 @@ - can_edit = can?(current_user, :admin_project, @project) - notification_email = @current_user.present? ? @current_user.notification_email_or_default : nil -.nav-controls.issues-nav-controls +.nav-controls.issues-nav-controls.gl-font-size-0 - if show_feed_buttons = render 'shared/issuable/feed_buttons' - .js-csv-import-export-buttons{ data: { show_export_button: show_export_button.to_s, show_import_button: show_import_button.to_s, issuable_type: issuable_type, issuable_count: issuables_count_for_state(issuable_type.to_sym, params[:state]), email: notification_email, export_csv_path: export_csv_project_issues_path(@project, request.query_parameters), import_csv_issues_path: import_csv_namespace_project_issues_path, container_class: 'gl-mr-3', can_edit: can_edit.to_s, project_import_jira_path: project_import_jira_path(@project) } } + .js-csv-import-export-buttons{ data: { show_export_button: show_export_button.to_s, show_import_button: show_import_button.to_s, issuable_type: issuable_type, issuable_count: issuables_count_for_state(issuable_type.to_sym, params[:state]), email: notification_email, export_csv_path: export_csv_project_issues_path(@project, request.query_parameters), import_csv_issues_path: import_csv_namespace_project_issues_path, container_class: 'gl-mr-3', can_edit: can_edit.to_s, project_import_jira_path: project_import_jira_path(@project), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes) } } - if @can_bulk_update = button_tag _("Edit issues"), class: "gl-button btn btn-default gl-mr-3 js-bulk-update-toggle" @@ -18,4 +18,3 @@ issue: { milestone_id: finder.milestones.first.try(:id) }), class: "gl-button btn btn-confirm", id: "new_issue_link" - diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml index 0604e89be6e..c47257eec4a 100644 --- a/app/views/projects/issues/_related_branches.html.haml +++ b/app/views/projects/issues/_related_branches.html.haml @@ -1,9 +1,9 @@ - if @related_branches.any? - %h2.related-branches-title + %h2.gl-font-lg = pluralize(@related_branches.size, 'Related Branch') %ul.unstyled-list.related-merge-requests - @related_branches.each do |branch| - %li + %li.gl-display-flex.gl-align-items-center - if branch[:pipeline_status].present? %span.related-branch-ci-status = render 'ci/status/icon', status: branch[:pipeline_status] diff --git a/app/views/projects/issues/_related_issues.html.haml b/app/views/projects/issues/_related_issues.html.haml index d131d20f079..bab37609c20 100644 --- a/app/views/projects/issues/_related_issues.html.haml +++ b/app/views/projects/issues/_related_issues.html.haml @@ -3,4 +3,3 @@ can_add_related_issues: "#{can?(current_user, :admin_issue_link, @issue)}", help_path: help_page_path('user/project/issues/related_issues'), show_categorized_issues: "false" } } - - render('projects/issues/related_issues_block') diff --git a/app/views/projects/issues/_related_issues_block.html.haml b/app/views/projects/issues/_related_issues_block.html.haml deleted file mode 100644 index 8d986b64b1d..00000000000 --- a/app/views/projects/issues/_related_issues_block.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -.related-issues-block - .card.card-slim - .card-header.panel-empty-heading.border-bottom-0 - %h3.card-title.mt-0.mb-0.h5 - = _('Linked issues') diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml index 5a983fb5565..0e8de3c2bb8 100644 --- a/app/views/projects/merge_requests/_mr_title.html.haml +++ b/app/views/projects/merge_requests/_mr_title.html.haml @@ -32,20 +32,20 @@ .dropdown-menu.dropdown-menu-right %ul - if can_update_merge_request - %li= link_to 'Edit', edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + %li= link_to _('Edit'), edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) - if @merge_request.opened? %li = link_to @merge_request.work_in_progress? ? _('Mark as ready') : _('Mark as draft'), toggle_draft_merge_request_path(@merge_request), method: :put, class: "js-draft-toggle-button" %li{ class: [merge_request_button_visibility(@merge_request, true), 'js-close-item'] } - = link_to 'Close', merge_request_path(@merge_request, merge_request: { state_event: :close }), method: :put, title: 'Close merge request' + = link_to _('Close'), merge_request_path(@merge_request, merge_request: { state_event: :close }), method: :put, title: 'Close merge request' - if can_reopen_merge_request %li{ class: merge_request_button_visibility(@merge_request, false) } - = link_to 'Reopen', merge_request_path(@merge_request, merge_request: { state_event: :reopen }), method: :put, title: 'Reopen merge request' + = link_to _('Reopen'), merge_request_path(@merge_request, merge_request: { state_event: :reopen }), method: :put, title: 'Reopen merge request' - unless @merge_request.merged? || current_user == @merge_request.author - %li= link_to 'Report abuse', new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request)) + %li= link_to _('Report abuse'), new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request)) - if can_update_merge_request - = link_to 'Edit', edit_project_merge_request_path(@project, @merge_request), class: "d-none d-md-block btn gl-button btn-default btn-grouped js-issuable-edit", data: { qa_selector: "edit_button" } + = link_to _('Edit'), edit_project_merge_request_path(@project, @merge_request), class: "d-none d-md-block btn gl-button btn-default btn-grouped js-issuable-edit", data: { qa_selector: "edit_button" } - if can_update_merge_request && !are_close_and_open_buttons_hidden = render 'projects/merge_requests/close_reopen_draft_report_toggle' diff --git a/app/views/projects/merge_requests/_nav_btns.html.haml b/app/views/projects/merge_requests/_nav_btns.html.haml index b34cf23634c..00d12423eb9 100644 --- a/app/views/projects/merge_requests/_nav_btns.html.haml +++ b/app/views/projects/merge_requests/_nav_btns.html.haml @@ -5,7 +5,7 @@ .js-csv-import-export-buttons{ data: { show_export_button: "true", issuable_type: issuable_type, issuable_count: issuables_count_for_state(issuable_type.to_sym, params[:state]), email: notification_email, export_csv_path: export_csv_project_merge_requests_path(@project, request.query_parameters), container_class: 'gl-mr-3' } } - if @can_bulk_update - = button_tag "Edit merge requests", class: "gl-button btn btn-default gl-mr-3 js-bulk-update-toggle" + = button_tag _("Edit merge requests"), class: "gl-button btn btn-default gl-mr-3 js-bulk-update-toggle" - if merge_project - = link_to new_merge_request_path, class: "gl-button btn btn-confirm", title: "New merge request" do - New merge request + = link_to new_merge_request_path, class: "gl-button btn btn-confirm", title: _("New merge request") do + = _('New merge request') diff --git a/app/views/projects/merge_requests/_widget.html.haml b/app/views/projects/merge_requests/_widget.html.haml index 47a0d05fc65..459742c3b81 100644 --- a/app/views/projects/merge_requests/_widget.html.haml +++ b/app/views/projects/merge_requests/_widget.html.haml @@ -19,6 +19,6 @@ window.gl.mrWidgetData.pipelines_empty_svg_path = '#{image_path('illustrations/pipelines_empty.svg')}'; window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("user/project/merge_requests/code_quality", anchor: "code-quality-reports")}'; window.gl.mrWidgetData.false_positive_doc_url = '#{help_page_path('user/application_security/vulnerabilities/index')}'; - window.gl.mrWidgetData.can_view_false_positive = '#{(Feature.enabled?(:vulnerability_flags, default_enabled: :yaml) && @merge_request.project.licensed_feature_available?(:sast_fp_reduction)).to_s}'; + window.gl.mrWidgetData.can_view_false_positive = '#{@merge_request.project.licensed_feature_available?(:sast_fp_reduction).to_s}'; #js-vue-mr-widget.mr-widget diff --git a/app/views/projects/merge_requests/conflicts/show.html.haml b/app/views/projects/merge_requests/conflicts/show.html.haml index ee296258d04..5ba42ca7610 100644 --- a/app/views/projects/merge_requests/conflicts/show.html.haml +++ b/app/views/projects/merge_requests/conflicts/show.html.haml @@ -6,7 +6,7 @@ .merge-request-details.issuable-details = render "projects/merge_requests/mr_box" -= render 'shared/issuable/sidebar', issuable_sidebar: @issuable_sidebar, assignees: @merge_request.assignees, source_branch: @merge_request.source_branch += render 'shared/issuable/sidebar', issuable_sidebar: @issuable_sidebar, assignees: @merge_request.assignees, reviewers: @merge_request.reviewers, source_branch: @merge_request.source_branch #conflicts{ data: { conflicts_path: conflicts_project_merge_request_path(@merge_request.project, @merge_request, format: :json), resolve_conflicts_path: resolve_conflicts_project_merge_request_path(@merge_request.project, @merge_request), diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml index 7e260a03c5d..2154ef6b596 100644 --- a/app/views/projects/merge_requests/show.html.haml +++ b/app/views/projects/merge_requests/show.html.haml @@ -49,6 +49,7 @@ = render "projects/merge_requests/tabs/pane", id: "notes", class: "notes voting_notes" do .row %section.col-md-12 + -# haml-lint:disable InlineJavaScript %script.js-notes-data{ type: "application/json" }= initial_notes_data(true).to_json.html_safe .issuable-discussion.js-vue-notes-event - if @merge_request.description.present? @@ -98,3 +99,4 @@ = render 'projects/invite_members_modal', project: @project - if Gitlab::CurrentSettings.gitpod_enabled && !current_user&.gitpod_enabled = render 'shared/gitpod/enable_gitpod_modal' += render 'shared/web_ide_path' diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml index b89aa9d402e..d253ab8e32b 100644 --- a/app/views/projects/mirrors/_mirror_repos.html.haml +++ b/app/views/projects/mirrors/_mirror_repos.html.haml @@ -10,7 +10,7 @@ = expanded ? _('Collapse') : _('Expand') %p = _('Set up your project to automatically push and/or pull changes to/from another repository. Branches, tags, and commits will be synced automatically.') - = link_to _('How do I mirror repositories?'), help_page_path('user/project/repository/repository_mirroring'), target: '_blank', rel: 'noopener noreferrer' + = link_to _('How do I mirror repositories?'), help_page_path('user/project/repository/mirror/index.md'), target: '_blank', rel: 'noopener noreferrer' .settings-content - if mirror_settings_enabled @@ -32,7 +32,7 @@ = label_tag :only_protected_branches, _('Mirror only protected branches'), class: 'form-check-label' .form-text.text-muted = _('If enabled, only protected branches will be mirrored.') - = link_to _('Learn more.'), help_page_path('user/project/repository/repository_mirroring', anchor: 'mirror-only-protected-branches'), target: '_blank', rel: 'noopener noreferrer' + = link_to _('Learn more.'), help_page_path('user/project/repository/mirror/index.md', anchor: 'mirror-only-protected-branches'), target: '_blank', rel: 'noopener noreferrer' .panel-footer = f.submit _('Mirror repository'), class: 'gl-button btn btn-confirm js-mirror-submit qa-mirror-repository-button', name: :update_remote_mirror diff --git a/app/views/projects/mirrors/_mirror_repos_push.html.haml b/app/views/projects/mirrors/_mirror_repos_push.html.haml index b3e0f71bf19..339c5d82919 100644 --- a/app/views/projects/mirrors/_mirror_repos_push.html.haml +++ b/app/views/projects/mirrors/_mirror_repos_push.html.haml @@ -12,4 +12,4 @@ = label_tag :keep_divergent_refs, _('Keep divergent refs'), class: 'form-check-label' .form-text.text-muted - link_opening_tag = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe - = html_escape(_('Do not force push over diverged refs. After the mirror is created, this setting can only be modified using the API. %{mirroring_docs_link_start}Learn more about this option%{link_closing_tag} and %{mirroring_api_docs_link_start}the API.%{link_closing_tag}')) % { mirroring_docs_link_start: link_opening_tag % {url: help_page_path('user/project/repository/repository_mirroring', anchor: 'keep-divergent-refs')}, mirroring_api_docs_link_start: link_opening_tag % {url: help_page_path('api/remote_mirrors')}, link_closing_tag: '</a>'.html_safe } + = html_escape(_('Do not force push over diverged refs. After the mirror is created, this setting can only be modified using the API. %{mirroring_docs_link_start}Learn more about this option%{link_closing_tag} and %{mirroring_api_docs_link_start}the API.%{link_closing_tag}')) % { mirroring_docs_link_start: link_opening_tag % {url: help_page_path('user/project/repository/mirror/push.md', anchor: 'keep-divergent-refs')}, mirroring_api_docs_link_start: link_opening_tag % {url: help_page_path('api/remote_mirrors')}, link_closing_tag: '</a>'.html_safe } diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml index 23606e24563..93afddce779 100644 --- a/app/views/projects/pipelines/_with_tabs.html.haml +++ b/app/views/projects/pipelines/_with_tabs.html.haml @@ -70,10 +70,10 @@ = link_to retry_project_job_path(build.project, build, return_to: request.original_url), method: :post, title: _('Retry'), class: 'gl-button btn btn-default btn-icon' do = sprite_icon('repeat', css_class: 'gl-icon') - if can?(current_user, :read_build, job) - %tr.build-trace-row.responsive-table-border-end + %tr.build-log-row.responsive-table-border-end %td - %td.responsive-table-cell.build-trace-container{ colspan: 4 } - %pre.build-trace.build-trace-rounded + %td.responsive-table-cell.build-log-container{ colspan: 4 } + %pre.build-log.build-log-rounded %code.bash.js-build-output = build_summary(build) diff --git a/app/views/projects/product_analytics/test.html.haml b/app/views/projects/product_analytics/test.html.haml index 60d897ee138..3204cd5fbbe 100644 --- a/app/views/projects/product_analytics/test.html.haml +++ b/app/views/projects/product_analytics/test.html.haml @@ -12,5 +12,6 @@ %code = @event.as_json_wo_empty +-# haml-lint:disable InlineJavaScript :javascript #{render 'tracker'} diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml index bdb5f021b70..cfdbf3410b1 100644 --- a/app/views/projects/registry/repositories/index.html.haml +++ b/app/views/projects/registry/repositories/index.html.haml @@ -20,7 +20,8 @@ "is_admin": current_user&.admin.to_s, "show_cleanup_policy_on_alert": show_cleanup_policy_on_alert(@project).to_s, "cleanup_policies_settings_path": project_settings_packages_and_registries_path(@project), - character_error: @character_error.to_s, + connection_error: (!!@connection_error).to_s, + invalid_path_error: (!!@invalid_path_error).to_s, user_callouts_path: user_callouts_path, user_callout_id: UserCalloutsHelper::UNFINISHED_TAG_CLEANUP_CALLOUT, show_unfinished_tag_cleanup_callout: show_unfinished_tag_cleanup_callout?.to_s, } } diff --git a/app/views/projects/settings/operations/_error_tracking.html.haml b/app/views/projects/settings/operations/_error_tracking.html.haml index 6b2a1468eec..23b1ec4dea3 100644 --- a/app/views/projects/settings/operations/_error_tracking.html.haml +++ b/app/views/projects/settings/operations/_error_tracking.html.haml @@ -18,4 +18,5 @@ api_host: setting.api_host, enabled: setting.enabled.to_json, integrated: setting.integrated.to_json, + gitlab_dsn: setting.gitlab_dsn, token: setting.token.present? ? '*' * 12 : nil } } diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index 8ef53c40b11..3e6acdb130a 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -3,7 +3,7 @@ - breadcrumb_title @snippet.to_reference - page_title "#{@snippet.title} (#{@snippet.to_reference})", _("Snippets") -#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id, 'report-abuse-path': snippet_report_abuse_path(@snippet) } } +#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id, 'report-abuse-path': snippet_report_abuse_path(@snippet), 'can-report-spam': @snippet.submittable_as_spam_by?(current_user).to_s } } .row-content-block.top-block.content-component-block = render 'award_emoji/awards_block', awardable: @snippet, inline: true, api_awards_path: project_snippets_award_api_path(@snippet) diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml index 79205a51d71..d3cc409df1d 100644 --- a/app/views/projects/tags/index.html.haml +++ b/app/views/projects/tags/index.html.haml @@ -18,6 +18,9 @@ = render_if_exists 'projects/commits/mirror_status' + - if @tags_loading_error + = render 'shared/errors/gitaly_unavailable', reason: s_('TagsPage|Unable to load tags') + .tags - if @tags.any? %ul.flex-list.content-list diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml index fe00772d1d6..4281152225a 100644 --- a/app/views/projects/tags/new.html.haml +++ b/app/views/projects/tags/new.html.haml @@ -54,4 +54,5 @@ .form-actions.gl-display-flex = button_tag s_('TagsPage|Create tag'), class: 'gl-button btn btn-confirm gl-mr-3', data: { qa_selector: "create_tag_button" } = link_to s_('TagsPage|Cancel'), project_tags_path(@project), class: 'gl-button btn btn-default btn-cancel' +-# haml-lint:disable InlineJavaScript %script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml index 2d0c4cc20a0..1553eda1cfb 100644 --- a/app/views/projects/tree/show.html.haml +++ b/app/views/projects/tree/show.html.haml @@ -11,3 +11,4 @@ = render 'projects/last_push' = render 'projects/files', commit: @last_commit, project: @project, ref: @ref, content_url: project_tree_path(@project, @id) += render 'shared/web_ide_path' diff --git a/app/views/projects/usage_quotas/index.html.haml b/app/views/projects/usage_quotas/index.html.haml index dfd46af0499..6c7cccfb9b1 100644 --- a/app/views/projects/usage_quotas/index.html.haml +++ b/app/views/projects/usage_quotas/index.html.haml @@ -6,7 +6,7 @@ .row .col-sm-12 = s_('UsageQuota|Usage of project resources across the %{strong_start}%{project_name}%{strong_end} project').html_safe % { strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe, project_name: @project.name } + '.' - %a{ href: help_page_path('user/usage_quotas.md') } + %a{ href: help_page_path('user/usage_quotas.md'), target: '_blank', rel: 'noopener noreferrer' } = s_('UsageQuota|Learn more about usage quotas') + '.' .top-area.scrolling-tabs-container.inner-page-scroll-tabs diff --git a/app/views/search/results/_issuable.html.haml b/app/views/search/results/_issuable.html.haml index 5645fbfb238..41058034d6f 100644 --- a/app/views/search/results/_issuable.html.haml +++ b/app/views/search/results/_issuable.html.haml @@ -13,7 +13,8 @@ = highlight_and_truncate_issuable(issuable, @search_term, @search_highlight) .col-sm-3.gl-mt-3.gl-sm-mt-0.gl-text-right - if issuable.respond_to?(:upvotes_count) && issuable.upvotes_count > 0 - %li.issuable-upvotes.gl-list-style-none.has-tooltip{ title: _('Upvotes') } - = sprite_icon('thumb-up', css_class: "gl-vertical-align-middle") - = issuable.upvotes_count + %li.issuable-upvotes.gl-list-style-none + %span.has-tooltip{ title: _('Upvotes') } + = sprite_icon('thumb-up', css_class: "gl-vertical-align-middle") + = issuable.upvotes_count %span.gl-text-gray-500= sprintf(s_('updated %{time_ago}'), { time_ago: time_ago_with_tooltip(issuable.updated_at, placement: 'bottom') }).html_safe diff --git a/app/views/shared/_import_form.html.haml b/app/views/shared/_import_form.html.haml index f03314563cb..3ab2b969b75 100644 --- a/app/views/shared/_import_form.html.haml +++ b/app/views/shared/_import_form.html.haml @@ -9,17 +9,12 @@ = f.text_field :import_url, value: import_url.sanitized_url, autocomplete: 'off', class: 'form-control gl-form-input', placeholder: 'https://gitlab.company.com/group/project.git', required: true = render 'shared/global_alert', - variant: :warning, - alert_class: 'gl-mt-3 js-import-url-warning hide', + variant: :danger, + alert_class: 'gl-mt-3 js-import-url-error hide', dismissible: false, close_button_class: 'js-close-2fa-enabled-success-alert' do .gl-alert-body - = s_('Import|A repository URL usually ends in a .git suffix, although this is not required. Double check to make sure your repository URL is correct.') - - .gl-alert.gl-alert-not-dismissible.gl-alert-warning.gl-mt-3.hide#project_import_url_warning - .gl-alert-container - = sprite_icon('warning-solid', css_class: 'gl-icon s16 gl-alert-icon gl-alert-icon-no-title') - .gl-alert-content{ role: 'alert' } + = s_('Import|There is not a valid Git repository at this URL. If your HTTP repository is not publicly accessible, verify your credentials.') .row .form-group.col-md-6 = f.label :import_url_user, class: 'label-bold' do diff --git a/app/views/shared/_milestones_filter.html.haml b/app/views/shared/_milestones_filter.html.haml index eb50960202a..117ed212fd9 100644 --- a/app/views/shared/_milestones_filter.html.haml +++ b/app/views/shared/_milestones_filter.html.haml @@ -1,13 +1,15 @@ -%ul.nav-links.mobile-separator.nav.nav-tabs - %li{ class: milestone_class_for_state(params[:state], 'opened', true) }> - = link_to milestones_filter_path(state: 'opened') do - = _('Open') - %span.badge.badge-pill= counts[:opened] - %li{ class: milestone_class_for_state(params[:state], 'closed') }> - = link_to milestones_filter_path(state: 'closed', sort: 'due_date_desc') do - = _('Closed') - %span.badge.badge-pill= counts[:closed] - %li{ class: milestone_class_for_state(params[:state], 'all') }> - = link_to milestones_filter_path(state: 'all', sort: 'due_date_desc') do - = _('All') - %span.badge.badge-pill= counts[:all] +- count_badge_classes = 'badge badge-muted badge-pill gl-badge gl-tab-counter-badge sm gl-display-none gl-sm-display-inline-flex' + += gl_tabs_nav( {class: 'gl-border-b-0 gl-flex-grow-1', data: { testid: 'milestones-filter' } } ) do + = gl_tab_link_to milestones_filter_path(state: 'opened'), { item_active: params[:state].blank? || params[:state] == 'opened' } do + = _('Open') + %span{ class: count_badge_classes } + = counts[:opened] + = gl_tab_link_to milestones_filter_path(state: 'closed', sort: 'due_date_desc'), { item_active: params[:state] == 'closed' } do + = _('Closed') + %span{ class: count_badge_classes } + = counts[:closed] + = gl_tab_link_to milestones_filter_path(state: 'all', sort: 'due_date_desc'), { item_active: params[:state] == 'all' } do + = _('All') + %span{ class: count_badge_classes } + = counts[:all] diff --git a/app/views/shared/_web_ide_path.html.haml b/app/views/shared/_web_ide_path.html.haml new file mode 100644 index 00000000000..73d00bcd408 --- /dev/null +++ b/app/views/shared/_web_ide_path.html.haml @@ -0,0 +1,4 @@ += javascript_tag do + :plain + window.gl = window.gl || {}; + window.gl.webIDEPath = '#{web_ide_url}' diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml index 98752345074..165564c5666 100644 --- a/app/views/shared/boards/_show.html.haml +++ b/app/views/shared/boards/_show.html.haml @@ -2,7 +2,7 @@ - @no_breadcrumb_container = true - @no_container = true - @content_wrapper_class = "#{@content_wrapper_class} gl-relative" -- @content_class = "issue-boards-content js-focus-mode-board" +- @content_class = "js-focus-mode-board" - is_epic_board = board.to_type == "EpicBoard" - if is_epic_board - breadcrumb_title _("Epic Boards") diff --git a/app/views/shared/builds/_build_output.html.haml b/app/views/shared/builds/_build_output.html.haml index 380fac4d0e4..a3b7d4926f8 100644 --- a/app/views/shared/builds/_build_output.html.haml +++ b/app/views/shared/builds/_build_output.html.haml @@ -1,4 +1,4 @@ -%pre.build-trace#build-trace +%pre.build-log %code.bash.js-build-output .build-loader-animation.js-build-refresh .dot diff --git a/app/views/shared/builds/_tabs.html.haml b/app/views/shared/builds/_tabs.html.haml index 4973309edf5..498e9cc33ce 100644 --- a/app/views/shared/builds/_tabs.html.haml +++ b/app/views/shared/builds/_tabs.html.haml @@ -1,24 +1,19 @@ -%ul.nav-links.mobile-separator.nav.nav-tabs - %li{ class: active_when(scope.nil?) }> - = link_to build_path_proc.call(nil) do - All - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm.js-totalbuilds-count - = limited_counter_with_delimiter(all_builds) +- count_badge_classes = 'badge badge-muted badge-pill gl-badge gl-tab-counter-badge sm gl-display-none gl-sm-display-inline-flex' - %li{ class: active_when(scope == 'pending') }> - = link_to build_path_proc.call('pending') do - Pending - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm - = limited_counter_with_delimiter(all_builds.pending) - - %li{ class: active_when(scope == 'running') }> - = link_to build_path_proc.call('running') do - Running - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm - = limited_counter_with_delimiter(all_builds.running) - - %li{ class: active_when(scope == 'finished') }> - = link_to build_path_proc.call('finished') do - Finished - %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm - = limited_counter_with_delimiter(all_builds.finished) += gl_tabs_nav( {class: 'gl-border-b-0 gl-flex-grow-1', data: { testid: 'jobs-tabs' } } ) do + = gl_tab_link_to build_path_proc.call(nil), { item_active: scope.nil? } do + = _('All') + %span{ class: count_badge_classes } + = limited_counter_with_delimiter(all_builds) + = gl_tab_link_to build_path_proc.call('pending'), { item_active: scope == 'pending' } do + = _('Pending') + %span{ class: count_badge_classes } + = limited_counter_with_delimiter(all_builds.pending) + = gl_tab_link_to build_path_proc.call('running'), { item_active: scope == 'running' } do + = _('Running') + %span{ class: count_badge_classes } + = limited_counter_with_delimiter(all_builds.running) + = gl_tab_link_to build_path_proc.call('finished'), { item_active: scope == 'finished' } do + = _('Finished') + %span{ class: count_badge_classes } + = limited_counter_with_delimiter(all_builds.finished) diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml index 652da4b396a..e049afbc40b 100644 --- a/app/views/shared/deploy_tokens/_form.html.haml +++ b/app/views/shared/deploy_tokens/_form.html.haml @@ -4,7 +4,6 @@ = s_('DeployTokens|Create a new deploy token for all projects in this group. %{link_start}What are deploy tokens?%{link_end}').html_safe % { link_start: group_deploy_tokens_help_link_start, link_end: '</a>'.html_safe } = form_for token, url: create_deploy_token_path(group_or_project, anchor: 'js-deploy-tokens'), method: :post, remote: Feature.enabled?(:ajax_new_deploy_token, group_or_project) do |f| - = form_errors(token) .form-group = f.label :name, class: 'label-bold' diff --git a/app/views/shared/empty_states/_topics.html.haml b/app/views/shared/empty_states/_topics.html.haml new file mode 100644 index 00000000000..fd82a853037 --- /dev/null +++ b/app/views/shared/empty_states/_topics.html.haml @@ -0,0 +1,7 @@ +.row.empty-state + .col-12 + .svg-content + = image_tag 'illustrations/labels.svg', data: { qa_selector: 'svg_content' } + .text-content.gl-text-center.gl-pt-0! + %h4= _('There are no topics to show.') + %p= _('Add topics to projects to help users find them.') diff --git a/app/views/shared/errors/_gitaly_unavailable.html.haml b/app/views/shared/errors/_gitaly_unavailable.html.haml new file mode 100644 index 00000000000..96a68cbcdc6 --- /dev/null +++ b/app/views/shared/errors/_gitaly_unavailable.html.haml @@ -0,0 +1,8 @@ +.gl-alert.gl-alert-danger.gl-mb-5.gl-mt-5 + .gl-alert-container + = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-content + .gl-alert-title + = reason + .gl-alert-body + = s_('The git server, Gitaly, is not available at this time. Please contact your administrator.') diff --git a/app/views/shared/hook_logs/_recent_deliveries_table.html.haml b/app/views/shared/hook_logs/_recent_deliveries_table.html.haml new file mode 100644 index 00000000000..31ef8560781 --- /dev/null +++ b/app/views/shared/hook_logs/_recent_deliveries_table.html.haml @@ -0,0 +1,34 @@ +%table.gl-table.gl-w-full + %thead + %tr + %th= _('Status') + %th.d-none.d-sm-table-cell= _('Trigger') + %th= _('Elapsed time') + %th= _('Request time') + %th + + - if hook_logs.present? + - hook_logs.each do |hook_log| + %tr + %td + = render partial: 'shared/hook_logs/status_label', locals: { hook_log: hook_log } + %td.d-none.d-sm-table-cell + %span.badge.badge-pill.gl-badge.badge-muted.sm + = hook_log.trigger.singularize.titleize + %td + #{number_with_precision(hook_log.execution_duration, precision: 2)} sec + %td + = time_ago_with_tooltip(hook_log.created_at) + %td + = link_to _('View details'), hook_log_path(hook, hook_log) + + +- if hook_logs.present? + = paginate hook_logs, theme: 'gitlab' +- else + .gl-text-center.gl-mt-7 + %h4= _('No webhook events') + %p + %span.gl-display-block= _('Webhook events will be displayed here.') + %span= _('Use the %{strongStart}Test%{strongEnd} option above to create an event.').html_safe % { strongStart: '<strong>'.html_safe, strongEnd: '</strong>'.html_safe } + diff --git a/app/views/shared/hook_logs/_status_label.html.haml b/app/views/shared/hook_logs/_status_label.html.haml index dfa5ecee448..b930074303c 100644 --- a/app/views/shared/hook_logs/_status_label.html.haml +++ b/app/views/shared/hook_logs/_status_label.html.haml @@ -1,3 +1,3 @@ - label_status = hook_log.success? ? 'badge-success' : 'badge-danger' -%span{ class: "badge #{label_status}" } +%span{ class: "badge badge-pill gl-badge sm #{label_status}" } = hook_log.internal_error? ? _('Error') : hook_log.response_status diff --git a/app/views/shared/integrations/_tabs.html.haml b/app/views/shared/integrations/_tabs.html.haml index 553401e47bd..d6ca0bd7d1e 100644 --- a/app/views/shared/integrations/_tabs.html.haml +++ b/app/views/shared/integrations/_tabs.html.haml @@ -1,18 +1,11 @@ -- active_tab = local_assigns.fetch(:active_tab, 'edit') -- active_classes = 'gl-tab-nav-item-active gl-tab-nav-item-active-indigo active' -- tabs = integration_tabs(integration: integration) - -- if tabs.length <= 1 - = yield -- else +- if integration.instance_level? .tabs.gl-tabs %div - %ul.nav.gl-tabs-nav{ role: 'tablist' } - - tabs.each do |tab| - %li.nav-item{ role: 'presentation' } - %a.nav-link.gl-tab-nav-item{ role: 'tab', class: (active_classes if tab[:key] == active_tab), href: tab[:href] } - = tab[:text] + = gl_tabs_nav({ class: 'gl-mb-5' }) do + = gl_tab_link_to _('Settings'), scoped_edit_integration_path(integration) + = gl_tab_link_to s_('Integrations|Projects using custom settings'), scoped_overrides_integration_path(integration) - .tab-content.gl-tab-content - .tab-pane.gl-pt-3.active{ role: 'tabpanel' } - = yield + = yield + +- else + = yield diff --git a/app/views/shared/issuable/_nav.html.haml b/app/views/shared/issuable/_nav.html.haml index cff50eef88b..4a33f625347 100644 --- a/app/views/shared/issuable/_nav.html.haml +++ b/app/views/shared/issuable/_nav.html.haml @@ -2,22 +2,16 @@ - page_context_word = type.to_s.humanize(capitalize: false) - display_count = local_assigns.fetch(:display_count, true) -%ul.nav-links.issues-state-filters.mobile-separator.nav.nav-tabs - %li{ class: active_when(params[:state] == 'opened') }> - = link_to page_filter_path(state: 'opened'), id: 'state-opened', title: _("Filter by %{page_context_word} that are currently open.") % { page_context_word: page_context_word }, data: { state: 'opened' } do - #{issuables_state_counter_text(type, :opened, display_count)} - += gl_tabs_nav({ class: 'issues-state-filters gl-border-b-0 gl-flex-grow-1' }) do + = gl_tab_link_to page_filter_path(state: 'opened'), { item_active: params[:state] == 'opened', id: 'state-opened', title: _("Filter by %{page_context_word} that are currently open.") % { page_context_word: page_context_word }, data: { state: 'opened' } } do + #{issuables_state_counter_text(type, :opened, display_count)} - if type == :merge_requests - %li{ class: active_when(params[:state] == 'merged') }> - = link_to page_filter_path(state: 'merged'), id: 'state-merged', title: _('Filter by merge requests that are currently merged.'), data: { state: 'merged' } do - #{issuables_state_counter_text(type, :merged, display_count)} - - %li{ class: active_when(params[:state] == 'closed') }> - = link_to page_filter_path(state: 'closed'), id: 'state-closed', title: _('Filter by merge requests that are currently closed and unmerged.'), data: { state: 'closed' } do - #{issuables_state_counter_text(type, :closed, display_count)} + = gl_tab_link_to page_filter_path(state: 'merged'), item_active: params[:state] == 'merged', id: 'state-merged', title: _('Filter by merge requests that are currently merged.'), data: { state: 'merged' } do + #{issuables_state_counter_text(type, :merged, display_count)} + = gl_tab_link_to page_filter_path(state: 'closed'), item_active: params[:state] == 'closed', id: 'state-closed', title: _('Filter by merge requests that are currently closed and unmerged.'), data: { state: 'closed' } do + #{issuables_state_counter_text(type, :closed, display_count)} - else - %li{ class: active_when(params[:state] == 'closed') }> - = link_to page_filter_path(state: 'closed'), id: 'state-closed', title: _('Filter by issues that are currently closed.'), data: { state: 'closed', qa_selector: 'closed_issues_link' } do - #{issuables_state_counter_text(type, :closed, display_count)} + = gl_tab_link_to page_filter_path(state: 'closed'), item_active: params[:state] == 'closed', id: 'state-closed', title: _('Filter by issues that are currently closed.'), data: { state: 'closed', qa_selector: 'closed_issues_link' } do + #{issuables_state_counter_text(type, :closed, display_count)} = render 'shared/issuable/nav_links/all', page_context_word: page_context_word, counter: issuables_state_counter_text(type, :all, display_count) diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index e6c4b3f4814..81a7581d392 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -19,7 +19,7 @@ - if params[:search].present? = hidden_field_tag :search, params[:search] - if @can_bulk_update - .check-all-holder.d-none.d-sm-block.hidden + .check-all-holder.gl-display-none.gl-sm-display-block.hidden.gl-float-left.gl-mr-5.gl-line-height-36 - checkbox_id = 'check-all-issues' %label.gl-sr-only{ for: checkbox_id }= _('Select all') = check_box_tag checkbox_id, nil, false, class: "check-all-issues left" diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 1e8724c3448..62539bfeffd 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -7,6 +7,7 @@ - can_edit_issuable = issuable_sidebar.dig(:current_user, :can_edit) - add_page_startup_api_call "#{issuable_sidebar[:issuable_json_path]}?serializer=sidebar_extras" - reviewers = local_assigns.fetch(:reviewers, nil) +- in_group_context_with_iterations = @project.group.present? && issuable_sidebar[:supports_iterations] %aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: signed_in }, issuable_type: issuable_type }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite', 'aria-label': issuable_type } .issuable-sidebar @@ -28,11 +29,11 @@ = render_if_exists 'shared/issuable/sidebar_item_epic', issuable_sidebar: issuable_sidebar, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type - if issuable_sidebar[:supports_milestone] - .block.milestone{ :class => ("gl-border-b-0!" if issuable_sidebar[:supports_iterations]), data: { qa_selector: 'milestone_block' } } + .block.milestone{ :class => ("gl-border-b-0!" if in_group_context_with_iterations), data: { qa_selector: 'milestone_block' } } .js-milestone-select{ data: { can_edit: can_edit_issuable.to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } } - - if @project.group.present? && issuable_sidebar[:supports_iterations] - .block{ class: 'gl-pt-0!', data: { qa_selector: 'iteration_container' } } + - if in_group_context_with_iterations + .block{ class: 'gl-pt-0! gl-collapse-empty', data: { qa_selector: 'iteration_container', testid: 'iteration_container' } }< = render_if_exists 'shared/issuable/iteration_select', can_edit: can_edit_issuable.to_s, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type - if issuable_sidebar[:supports_time_tracking] @@ -55,11 +56,13 @@ .js-sidebar-status-entry-point{ data: sidebar_status_data(issuable_sidebar, @project) } - if issuable_sidebar.has_key?(:confidential) + -# haml-lint:disable InlineJavaScript %script#js-confidential-issue-data{ type: "application/json" }= { is_confidential: issuable_sidebar[:confidential], is_editable: can_edit_issuable }.to_json.html_safe #js-confidential-entry-point = render_if_exists 'shared/issuable/sidebar_cve_id_request', issuable_sidebar: issuable_sidebar + -# haml-lint:disable InlineJavaScript %script#js-lock-issue-data{ type: "application/json" }= { is_locked: !!issuable_sidebar[:discussion_locked], is_editable: can_edit_issuable }.to_json.html_safe #js-lock-entry-point @@ -72,7 +75,7 @@ #js-reference-entry-point - if issuable_type == 'merge_request' .sub-block.js-sidebar-source-branch - .sidebar-collapsed-icon.dont-change-state + .sidebar-collapsed-icon.js-dont-change-state = clipboard_button(text: source_branch, title: _('Copy branch name'), placement: "left", boundary: 'viewport') .gl-display-flex.gl-align-items-center.gl-justify-content-space-between.gl-mb-2.hide-collapsed %span.gl-overflow-hidden.gl-text-overflow-ellipsis.gl-white-space-nowrap diff --git a/app/views/shared/issuable/nav_links/_all.html.haml b/app/views/shared/issuable/nav_links/_all.html.haml index c92a50bcb70..7afa194d5db 100644 --- a/app/views/shared/issuable/nav_links/_all.html.haml +++ b/app/views/shared/issuable/nav_links/_all.html.haml @@ -1,6 +1,5 @@ - page_context_word = local_assigns.fetch(:page_context_word) - counter = local_assigns.fetch(:counter) -%li{ class: active_when(params[:state] == 'all') }> - = link_to page_filter_path(state: 'all'), id: 'state-all', title: "Show all #{page_context_word}.", data: { state: 'all' } do - #{counter} += gl_tab_link_to page_filter_path(state: 'all'), item_active: params[:state] == 'all', id: 'state-all', title: _("Show all %{issuable_type}.") % { issuable_type: page_context_word }, data: { state: 'all' } do + #{counter} diff --git a/app/views/shared/issue_type/_emoji_block.html.haml b/app/views/shared/issue_type/_emoji_block.html.haml index 26d30341999..d2c851a4e49 100644 --- a/app/views/shared/issue_type/_emoji_block.html.haml +++ b/app/views/shared/issue_type/_emoji_block.html.haml @@ -4,7 +4,7 @@ .row.gl-m-0.gl-justify-content-space-between .js-noteable-awards = render 'award_emoji/awards_block', awardable: issuable, inline: true, api_awards_path: api_awards_path - .new-branch-col.gl-my-2 + .new-branch-col.gl-my-2.gl-font-size-0 = render_if_exists "projects/issues/timeline_toggle", issuable: issuable #js-vue-sort-issue-discussions #js-vue-discussion-filter{ data: { default_filter: current_user&.notes_filter_for(issuable), notes_filters: UserPreference.notes_filters.to_json } } diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml index 56b2b0d5801..c66ba5ba2e1 100644 --- a/app/views/shared/milestones/_sidebar.html.haml +++ b/app/views/shared/milestones/_sidebar.html.haml @@ -161,11 +161,11 @@ - milestone_ref = milestone.try(:to_reference, full: true) - if milestone_ref.present? .block.reference - .sidebar-collapsed-icon.dont-change-state + .sidebar-collapsed-icon.js-dont-change-state = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport') .cross-project-reference.hide-collapsed - %span + %span.gl-display-inline-block.gl-text-truncate = s_('MilestoneSidebar|Reference:') %span{ title: milestone_ref } = milestone_ref - = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport') + = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport', class: 'btn-clipboard btn-transparent gl-float-right gl-bg-gray-10') diff --git a/app/views/shared/notes/_comment_button.html.haml b/app/views/shared/notes/_comment_button.html.haml index d0a2d97df0f..3e880a36e29 100644 --- a/app/views/shared/notes/_comment_button.html.haml +++ b/app/views/shared/notes/_comment_button.html.haml @@ -1,31 +1,4 @@ - noteable_name = @note.noteable.human_class_name -.float-left.btn-group.gl-sm-mr-3.droplab-dropdown.comment-type-dropdown.js-comment-type-dropdown +.js-comment-type-dropdown.float-left.gl-sm-mr-3{ data: { noteable_name: noteable_name } } %input.btn.gl-button.btn-confirm.js-comment-button.js-comment-submit-button{ type: 'submit', value: _('Comment'), data: { qa_selector: 'comment_button' } } - - - if @note.can_be_discussion_note? - = button_tag type: 'button', class: 'gl-button btn dropdown-toggle btn-confirm js-note-new-discussion js-disable-on-submit', data: { 'dropdown-trigger' => '#resolvable-comment-menu' }, 'aria-label' => _('Open comment type dropdown') do - = sprite_icon('chevron-down') - - %ul#resolvable-comment-menu.dropdown-menu.dropdown-open-top{ data: { dropdown: true } } - %li#comment.droplab-item-selected{ data: { value: '', 'submit-text' => _('Comment'), 'close-text' => _("Comment & close %{noteable_name}") % { noteable_name: noteable_name }, 'reopen-text' => _("Comment & reopen %{noteable_name}") % { noteable_name: noteable_name } } } - %button.btn.gl-button.btn-default-tertiary - = sprite_icon('check', css_class: 'icon') - .description - %strong= _("Comment") - %p - = _("Add a general comment to this %{noteable_name}.") % { noteable_name: noteable_name } - - %li.divider.droplab-item-ignore - - %li#discussion{ data: { value: 'DiscussionNote', 'submit-text' => _('Start thread'), 'close-text' => _("Start thread & close %{noteable_name}") % { noteable_name: noteable_name }, 'reopen-text' => _("Start thread & reopen %{noteable_name}") % { noteable_name: noteable_name } } } - %button.btn.gl-button.btn-default-tertiary - = sprite_icon('check', css_class: 'icon') - .description - %strong= _("Start thread") - %p - = succeed '.' do - - if @note.noteable.supports_resolvable_notes? - = _('Discuss a specific suggestion or question that needs to be resolved') - - else - = _('Discuss a specific suggestion or question') diff --git a/app/views/shared/notes/_hints.html.haml b/app/views/shared/notes/_hints.html.haml index a03e8446f5d..6231f817704 100644 --- a/app/views/shared/notes/_hints.html.haml +++ b/app/views/shared/notes/_hints.html.haml @@ -1,4 +1,5 @@ - supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false) +- supports_file_upload = local_assigns.fetch(:supports_file_upload, true) .comment-toolbar.clearfix .toolbar-text = link_to _('Markdown'), help_page_path('user/markdown'), target: '_blank' @@ -10,33 +11,34 @@ is supported - %span.uploading-container - %span.uploading-progress-container.hide - = sprite_icon('media', css_class: 'gl-icon gl-vertical-align-text-bottom') - %span.attaching-file-message - -# Populated by app/assets/javascripts/dropzone_input.js - %span.uploading-progress 0% - = loading_icon(css_class: 'align-text-bottom gl-mr-2') - - %span.uploading-error-container.hide - %span.uploading-error-icon + - if supports_file_upload + %span.uploading-container + %span.uploading-progress-container.hide = sprite_icon('media', css_class: 'gl-icon gl-vertical-align-text-bottom') - %span.uploading-error-message - -# Populated by app/assets/javascripts/dropzone_input.js - %button.btn.gl-button.btn-link.gl-vertical-align-baseline.retry-uploading-link - %span.gl-button-text - = _("Try again") - = _("or") - %button.btn.gl-button.btn-link.attach-new-file.markdown-selector.gl-vertical-align-baseline - %span.gl-button-text - = _("attach a new file") - = _(".") + %span.attaching-file-message + -# Populated by app/assets/javascripts/dropzone_input.js + %span.uploading-progress 0% + = loading_icon(css_class: 'align-text-bottom gl-mr-2') - %button.btn.gl-button.btn-link.button-attach-file.markdown-selector.button-attach-file.gl-vertical-align-text-bottom - = sprite_icon('media') - %span.gl-button-text - = _("Attach a file") + %span.uploading-error-container.hide + %span.uploading-error-icon + = sprite_icon('media', css_class: 'gl-icon gl-vertical-align-text-bottom') + %span.uploading-error-message + -# Populated by app/assets/javascripts/dropzone_input.js + %button.btn.gl-button.btn-link.gl-vertical-align-baseline.retry-uploading-link + %span.gl-button-text + = _("Try again") + = _("or") + %button.btn.gl-button.btn-link.attach-new-file.markdown-selector.gl-vertical-align-baseline + %span.gl-button-text + = _("attach a new file") + = _(".") - %button.btn.gl-button.btn-link.button-cancel-uploading-files.gl-vertical-align-baseline.hide - %span.gl-button-text - = _("Cancel") + %button.btn.gl-button.btn-link.button-attach-file.markdown-selector.button-attach-file.gl-vertical-align-text-bottom + = sprite_icon('media') + %span.gl-button-text + = _("Attach a file") + + %button.btn.gl-button.btn-link.button-cancel-uploading-files.gl-vertical-align-baseline.hide + %span.gl-button-text + = _("Cancel") diff --git a/app/views/shared/notes/_notes_with_form.html.haml b/app/views/shared/notes/_notes_with_form.html.haml index f7f5c02370d..e34f412baa4 100644 --- a/app/views/shared/notes/_notes_with_form.html.haml +++ b/app/views/shared/notes/_notes_with_form.html.haml @@ -25,4 +25,5 @@ = sprite_icon('lock', css_class: 'icon') %span = html_escape(_("This %{issuable} is locked. Only %{strong_open}project members%{strong_close} can comment.")) % { issuable: issuable.class.to_s.titleize.downcase, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe } +-# haml-lint:disable InlineJavaScript %script.js-notes-data{ type: "application/json" }= initial_notes_data(autocomplete).to_json.html_safe diff --git a/app/views/shared/topics/_search_form.html.haml b/app/views/shared/topics/_search_form.html.haml new file mode 100644 index 00000000000..97343983b3c --- /dev/null +++ b/app/views/shared/topics/_search_form.html.haml @@ -0,0 +1,7 @@ += form_tag page_filter_path, method: :get, class: "topic-filter-form js-topic-filter-form", id: 'topic-filter-form' do |f| + = search_field_tag :search, params[:search], + placeholder: s_('Filter by name'), + class: 'topic-filter-form-field form-control input-short', + spellcheck: false, + id: 'topic-filter-form-field', + autofocus: local_assigns[:autofocus] diff --git a/app/views/shared/web_hooks/_hook.html.haml b/app/views/shared/web_hooks/_hook.html.haml index abe23d0be78..fd124c2967d 100644 --- a/app/views/shared/web_hooks/_hook.html.haml +++ b/app/views/shared/web_hooks/_hook.html.haml @@ -5,12 +5,12 @@ %div - hook.class.triggers.each_value do |trigger| - if hook.public_send(trigger) - %span.gl-badge.gl-bg-gray-10.gl-mt-2.rounded.deploy-project-label= trigger.to_s.titleize - %span.gl-badge.gl-bg-gray-10.gl-mt-2.rounded + %span.gl-badge.badge-muted.badge-pill.sm.gl-mt-2.deploy-project-label= trigger.to_s.titleize + %span.gl-badge.badge-muted.badge-pill.sm.gl-mt-2 = _('SSL Verification:') = hook.enable_ssl_verification ? _('enabled') : _('disabled') .col-md-4.col-lg-5.text-right-md.gl-mt-2 %span>= render 'shared/web_hooks/test_button', hook: hook, button_class: 'btn-sm btn-default gl-mr-3' %span>= link_to _('Edit'), edit_hook_path(hook), class: 'btn gl-button btn-default btn-sm gl-mr-3' - = link_to _('Delete'), destroy_hook_path(hook), data: { confirm: _('Are you sure?') }, method: :delete, class: 'btn gl-button btn-default btn-sm' + = link_to _('Delete'), destroy_hook_path(hook), data: { confirm: _('Are you sure?') }, method: :delete, class: 'btn gl-button btn-secondary btn-danger-secondary btn-sm' diff --git a/app/views/shared/wikis/edit.html.haml b/app/views/shared/wikis/edit.html.haml index 15710f0df49..e0860bc473d 100644 --- a/app/views/shared/wikis/edit.html.haml +++ b/app/views/shared/wikis/edit.html.haml @@ -4,7 +4,7 @@ - if @error #js-wiki-error{ data: { error: @error, wiki_page_path: wiki_page_path(@wiki, @page) } } -.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row +.js-wiki-edit-page.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row = wiki_sidebar_toggle_button %h3.page-title.gl-flex-grow-1 diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index ca52a1f8f46..f1093a3b730 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -12,7 +12,7 @@ - content_for :prefetch_asset_tags do - webpack_preload_asset_tag('monaco', prefetch: true) -#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id, 'report-abuse-path': snippet_report_abuse_path(@snippet) } } +#js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id, 'report-abuse-path': snippet_report_abuse_path(@snippet), 'can-report-spam': @snippet.submittable_as_spam_by?(current_user).to_s } } .row-content-block.top-block.content-component-block = render 'award_emoji/awards_block', awardable: @snippet, inline: true diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 20cbe08225e..522f0f771cd 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -84,10 +84,12 @@ = sprite_icon('location', css_class: 'fgray') %span{ itemprop: 'addressLocality' } = @user.location - = render 'middle_dot_divider', stacking: true do - = sprite_icon('clock', css_class: 'fgray') - %span - = local_time(@user.timezone) + - user_local_time = local_time(@user.timezone) + - unless user_local_time.nil? + = render 'middle_dot_divider', stacking: true, data: { testid: 'user-local-time' } do + = sprite_icon('clock', css_class: 'fgray') + %span + = user_local_time - unless work_information(@user).blank? = render 'middle_dot_divider', stacking: true do = sprite_icon('work', css_class: 'fgray') |