summaryrefslogtreecommitdiff
path: root/app/views/admin
diff options
context:
space:
mode:
Diffstat (limited to 'app/views/admin')
-rw-r--r--app/views/admin/appearances/_form.html.haml34
-rw-r--r--app/views/admin/appearances/preview_sign_in.html.haml8
-rw-r--r--app/views/admin/application_settings/_abuse.html.haml6
-rw-r--r--app/views/admin/application_settings/_floc.html.haml22
-rw-r--r--app/views/admin/application_settings/_gitaly.html.haml8
-rw-r--r--app/views/admin/application_settings/_initial_branch_name.html.haml4
-rw-r--r--app/views/admin/application_settings/_package_registry.html.haml3
-rw-r--r--app/views/admin/application_settings/_package_registry_limits.html.haml37
-rw-r--r--app/views/admin/application_settings/_plantuml.html.haml2
-rw-r--r--app/views/admin/application_settings/_prometheus.html.haml22
-rw-r--r--app/views/admin/application_settings/_repository_check.html.haml2
-rw-r--r--app/views/admin/application_settings/_signin.html.haml22
-rw-r--r--app/views/admin/application_settings/_spam.html.haml32
-rw-r--r--app/views/admin/application_settings/_terminal.html.haml7
-rw-r--r--app/views/admin/application_settings/_usage.html.haml11
-rw-r--r--app/views/admin/application_settings/_whats_new.html.haml13
-rw-r--r--app/views/admin/application_settings/general.html.haml1
-rw-r--r--app/views/admin/application_settings/network.html.haml11
-rw-r--r--app/views/admin/application_settings/preferences.html.haml11
-rw-r--r--app/views/admin/application_settings/repository.html.haml21
-rw-r--r--app/views/admin/background_jobs/show.html.haml7
-rw-r--r--app/views/admin/broadcast_messages/_form.html.haml10
-rw-r--r--app/views/admin/dashboard/index.html.haml2
-rw-r--r--app/views/admin/deploy_keys/new.html.haml2
-rw-r--r--app/views/admin/dev_ops_report/_card.html.haml25
-rw-r--r--app/views/admin/dev_ops_report/_no_data.html.haml7
-rw-r--r--app/views/admin/dev_ops_report/_report.html.haml26
-rw-r--r--app/views/admin/groups/_group.html.haml2
-rw-r--r--app/views/admin/health_check/show.html.haml6
-rw-r--r--app/views/admin/hook_logs/_index.html.haml2
-rw-r--r--app/views/admin/labels/_label.html.haml2
-rw-r--r--app/views/admin/labels/destroy.js.haml3
-rw-r--r--app/views/admin/projects/_projects.html.haml2
-rw-r--r--app/views/admin/requests_profiles/index.html.haml6
-rw-r--r--app/views/admin/runners/index.html.haml2
-rw-r--r--app/views/admin/runners/show.html.haml15
-rw-r--r--app/views/admin/spam_logs/index.html.haml22
-rw-r--r--app/views/admin/users/_ban_user.html.haml9
-rw-r--r--app/views/admin/users/_cohorts.html.haml5
-rw-r--r--app/views/admin/users/_form.html.haml26
-rw-r--r--app/views/admin/users/_head.html.haml3
-rw-r--r--app/views/admin/users/_profile.html.haml16
-rw-r--r--app/views/admin/users/_projects.html.haml4
-rw-r--r--app/views/admin/users/_tabs.html.haml7
-rw-r--r--app/views/admin/users/_user.html.haml8
-rw-r--r--app/views/admin/users/_users.html.haml27
-rw-r--r--app/views/admin/users/cohorts.html.haml7
-rw-r--r--app/views/admin/users/edit.html.haml2
-rw-r--r--app/views/admin/users/index.html.haml14
-rw-r--r--app/views/admin/users/projects.html.haml10
-rw-r--r--app/views/admin/users/show.html.haml115
51 files changed, 369 insertions, 302 deletions
diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml
index 1aaea1999e5..872a6bef18b 100644
--- a/app/views/admin/appearances/_form.html.haml
+++ b/app/views/admin/appearances/_form.html.haml
@@ -1,4 +1,4 @@
-- parsed_with_gfm = "Content parsed with #{link_to('GitLab Flavored Markdown', help_page_path('user/markdown'), target: '_blank')}.".html_safe
+- parsed_with_gfm = (_("Content parsed with %{link}.") % { link: link_to('GitLab Flavored Markdown', help_page_path('user/markdown'), target: '_blank') }).html_safe
= form_for @appearance, url: admin_appearances_path, html: { class: 'gl-mt-3' } do |f|
= form_errors(@appearance)
@@ -6,22 +6,22 @@
.row
.col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0 Navigation bar
+ %h4.gl-mt-0= _('Navigation bar')
.col-lg-8
.form-group
- = f.label :header_logo, 'Header logo', class: 'col-form-label label-bold pt-0'
+ = f.label :header_logo, _('Header logo'), class: 'col-form-label label-bold pt-0'
%p
- if @appearance.header_logo?
= image_tag @appearance.header_logo_path, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
- = link_to 'Remove header logo', header_logos_admin_appearances_path, data: { confirm: "Header logo will be removed. Are you sure?"}, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
+ = link_to _('Remove header logo'), header_logos_admin_appearances_path, data: { confirm: _("Header logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
%hr
= f.hidden_field :header_logo_cache
= f.file_field :header_logo, class: "", accept: 'image/*'
.hint
- Maximum file size is 1MB. Pages are optimized for a 28px tall header logo
+ = _('Maximum file size is 1MB. Pages are optimized for a 28px tall header logo')
%hr
.row
.col-lg-4.profile-settings-sidebar
@@ -29,27 +29,27 @@
.col-lg-8
.form-group
- = f.label :favicon, 'Favicon', class: 'col-form-label label-bold pt-0'
+ = f.label :favicon, _('Favicon'), class: 'col-form-label label-bold pt-0'
%p
- if @appearance.favicon?
= image_tag @appearance.favicon_path, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
- = link_to 'Remove favicon', favicon_admin_appearances_path, data: { confirm: "Favicon will be removed. Are you sure?"}, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
+ = link_to _('Remove favicon'), favicon_admin_appearances_path, data: { confirm: _("Favicon will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
%hr
= f.hidden_field :favicon_cache
= f.file_field :favicon, class: '', accept: 'image/*'
.hint
- Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are #{favicon_extension_whitelist}.
+ = _("Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are %{favicon_extension_whitelist}.") % { favicon_extension_whitelist: favicon_extension_whitelist }
%br
- Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.
+ = _("Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior.")
= render partial: 'admin/appearances/system_header_footer_form', locals: { form: f }
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0 Sign in/Sign up pages
+ %h4.gl-mt-0= _('Sign in/Sign up pages')
.col-lg-8
.form-group
@@ -67,17 +67,17 @@
= image_tag @appearance.logo_path, class: 'appearance-logo-preview'
- if @appearance.persisted?
%br
- = link_to 'Remove logo', logo_admin_appearances_path, data: { confirm: "Logo will be removed. Are you sure?"}, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm remove-logo"
+ = link_to _('Remove logo'), logo_admin_appearances_path, data: { confirm: _("Logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm remove-logo"
%hr
= f.hidden_field :logo_cache
= f.file_field :logo, class: "", accept: 'image/*'
.hint
- Maximum file size is 1MB. Pages are optimized for a 640x360 px logo.
+ = _('Maximum file size is 1MB. Pages are optimized for a 640x360 px logo.')
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0 New project pages
+ %h4.gl-mt-0= _('New project pages')
.col-lg-8
.form-group
@@ -90,7 +90,7 @@
%hr
.row
.col-lg-4.profile-settings-sidebar
- %h4.gl-mt-0 Profile image guideline
+ %h4.gl-mt-0= _('Profile image guideline')
.col-lg-8
.form-group
@@ -101,13 +101,13 @@
= parsed_with_gfm
.gl-mt-3.gl-mb-3
- = f.submit 'Update appearance settings', class: 'btn gl-button btn-confirm'
+ = f.submit _('Update appearance settings'), class: 'btn gl-button btn-confirm'
- if @appearance.persisted? || @appearance.updated_at
.mt-4
- if @appearance.persisted?
Preview last save:
- = link_to 'Sign-in page', preview_sign_in_admin_appearances_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
- = link_to 'New project page', new_project_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Sign-in page'), preview_sign_in_admin_appearances_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('New project page'), new_project_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
- if @appearance.updated_at
%span.float-right
diff --git a/app/views/admin/appearances/preview_sign_in.html.haml b/app/views/admin/appearances/preview_sign_in.html.haml
index f972b3b5cbf..a317611862c 100644
--- a/app/views/admin/appearances/preview_sign_in.html.haml
+++ b/app/views/admin/appearances/preview_sign_in.html.haml
@@ -1,12 +1,12 @@
-= render 'devise/shared/tab_single', tab_title: 'Sign in preview'
+= render 'devise/shared/tab_single', tab_title: _('Sign in preview')
.login-box
%form.gl-show-field-errors
.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, class: "form-control gl-form-input top", title: _('Please provide your username or email address.')
.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, class: "form-control gl-form-input bottom", title: _('This field is required.')
.form-group
- = button_tag "Sign in", class: "btn gl-button btn-confirm"
+ = button_tag _("Sign in"), class: "btn gl-button btn-confirm"
diff --git a/app/views/admin/application_settings/_abuse.html.haml b/app/views/admin/application_settings/_abuse.html.haml
index f050c0816b1..fab3ce584f0 100644
--- a/app/views/admin/application_settings/_abuse.html.haml
+++ b/app/views/admin/application_settings/_abuse.html.haml
@@ -3,9 +3,9 @@
%fieldset
.form-group
- = f.label :abuse_notification_email, 'Abuse reports notification email', class: 'label-bold'
+ = 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.
+ = _('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"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_floc.html.haml b/app/views/admin/application_settings/_floc.html.haml
new file mode 100644
index 00000000000..398064f9730
--- /dev/null
+++ b/app/views/admin/application_settings/_floc.html.haml
@@ -0,0 +1,22 @@
+- expanded = integration_expanded?('floc_')
+
+%section.settings.no-animate#js-floc-settings{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4
+ = s_('FloC|Federated Learning of Cohorts')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = s_('FloC|Configure whether you want to participate in FloC.').html_safe
+ = link_to sprite_icon('question-o'), 'https://github.com/WICG/floc', target: '_blank', class: 'has-tooltip', title: _('More information')
+
+ .settings-content
+ = form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-floc-settings'), html: { class: 'fieldset-form', id: 'floc-settings' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ .form-check
+ = f.check_box :floc_enabled, class: 'form-check-input'
+ = f.label :floc_enabled, s_('FloC|Enable FloC (Federated Learning of Cohorts)'), class: 'form-check-label'
+ = f.submit s_('Save changes'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/admin/application_settings/_gitaly.html.haml b/app/views/admin/application_settings/_gitaly.html.haml
index 72e7cb0b437..b28a53d8bf6 100644
--- a/app/views/admin/application_settings/_gitaly.html.haml
+++ b/app/views/admin/application_settings/_gitaly.html.haml
@@ -3,7 +3,7 @@
%fieldset
.form-group
- = f.label :gitaly_timeout_default, 'Default Timeout Period', class: 'label-bold'
+ = f.label :gitaly_timeout_default, _('Default Timeout Period'), class: 'label-bold'
= f.number_field :gitaly_timeout_default, class: 'form-control gl-form-input'
.form-text.text-muted
Timeout for Gitaly calls from the GitLab application (in seconds). This timeout is not enforced
@@ -12,16 +12,16 @@
worker timeout, the remaining time from the worker timeout would be used to avoid having to terminate
the worker.
.form-group
- = f.label :gitaly_timeout_fast, 'Fast Timeout Period', class: 'label-bold'
+ = f.label :gitaly_timeout_fast, _('Fast Timeout Period'), class: 'label-bold'
= f.number_field :gitaly_timeout_fast, class: 'form-control gl-form-input'
.form-text.text-muted
Fast operation timeout (in seconds). Some Gitaly operations are expected to be fast.
If they exceed this threshold, there may be a problem with a storage shard and 'failing fast'
can help maintain the stability of the GitLab instance.
.form-group
- = f.label :gitaly_timeout_medium, 'Medium Timeout Period', class: 'label-bold'
+ = f.label :gitaly_timeout_medium, _('Medium Timeout Period'), class: 'label-bold'
= f.number_field :gitaly_timeout_medium, class: 'form-control gl-form-input'
.form-text.text-muted
Medium operation timeout (in seconds). This should be a value between the Fast and the Default timeout.
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_initial_branch_name.html.haml b/app/views/admin/application_settings/_initial_branch_name.html.haml
index b5c178641df..f881808e51f 100644
--- a/app/views/admin/application_settings/_initial_branch_name.html.haml
+++ b/app/views/admin/application_settings/_initial_branch_name.html.haml
@@ -1,12 +1,12 @@
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting)
- - fallback_branch_name = '<code>master</code>'
+ - fallback_branch_name = "<code>#{Gitlab::DefaultBranch.value}</code>"
%fieldset
.form-group
= f.label :default_branch_name, _('Default initial branch name'), class: 'label-light'
- = f.text_field :default_branch_name, placeholder: 'master', class: 'form-control gl-form-input'
+ = f.text_field :default_branch_name, placeholder: Gitlab::DefaultBranch.value, class: 'form-control gl-form-input'
%span.form-text.text-muted
= (_("Changes affect new repositories only. If not specified, Git's default name %{branch_name_default} will be used.") % { branch_name_default: fallback_branch_name } ).html_safe
diff --git a/app/views/admin/application_settings/_package_registry.html.haml b/app/views/admin/application_settings/_package_registry.html.haml
index 0ca8493c596..8de65f267d2 100644
--- a/app/views/admin/application_settings/_package_registry.html.haml
+++ b/app/views/admin/application_settings/_package_registry.html.haml
@@ -45,6 +45,9 @@
= f.label :pypi_max_file_size, _('Maximum PyPI package file size in bytes'), class: 'label-bold'
= f.number_field :pypi_max_file_size, class: 'form-control gl-form-input'
.form-group
+ = f.label :terraform_module_max_file_size, _('Maximum Terraform Module package file size in bytes'), class: 'label-bold'
+ = f.number_field :terraform_module_max_file_size, class: 'form-control gl-form-input'
+ .form-group
= f.label :generic_packages_max_file_size, _('Generic package file size in bytes'), class: 'label-bold'
= f.number_field :generic_packages_max_file_size, class: 'form-control gl-form-input'
= f.submit _('Save %{name} size limits').html_safe % { name: plan.name.capitalize }, class: 'btn gl-button btn-confirm'
diff --git a/app/views/admin/application_settings/_package_registry_limits.html.haml b/app/views/admin/application_settings/_package_registry_limits.html.haml
new file mode 100644
index 00000000000..b1dfd04c55e
--- /dev/null
+++ b/app/views/admin/application_settings/_package_registry_limits.html.haml
@@ -0,0 +1,37 @@
+= 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
+ %h5
+ = _('Unauthenticated API request rate limit')
+ .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')
+ %span.form-text.text-muted
+ = _('Helps reduce request volume (e.g. from crawlers or abusive bots)')
+ .form-group
+ = f.label :throttle_unauthenticated_packages_api_requests_per_period, 'Max unauthenticated API requests per 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
+ %h5
+ = _('Authenticated API request rate limit')
+ .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')
+ %span.form-text.text-muted
+ = _('Helps reduce request volume (e.g. from crawlers or abusive bots)')
+ .form-group
+ = f.label :throttle_authenticated_packages_api_requests_per_period, 'Max authenticated API requests per 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/_plantuml.html.haml b/app/views/admin/application_settings/_plantuml.html.haml
index d57ae94b084..632aeec6ce3 100644
--- a/app/views/admin/application_settings/_plantuml.html.haml
+++ b/app/views/admin/application_settings/_plantuml.html.haml
@@ -17,7 +17,7 @@
= f.check_box :plantuml_enabled, class: 'form-check-input'
= f.label :plantuml_enabled, _('Enable PlantUML'), class: 'form-check-label'
.form-group
- = f.label :plantuml_url, 'PlantUML URL', class: 'label-bold'
+ = f.label :plantuml_url, _('PlantUML URL'), class: 'label-bold'
= f.text_field :plantuml_url, class: 'form-control gl-form-input', placeholder: 'http://your-plantuml-instance:8080'
.form-text.text-muted
Allow rendering of
diff --git a/app/views/admin/application_settings/_prometheus.html.haml b/app/views/admin/application_settings/_prometheus.html.haml
index 468c1786d6f..f102b3d580b 100644
--- a/app/views/admin/application_settings/_prometheus.html.haml
+++ b/app/views/admin/application_settings/_prometheus.html.haml
@@ -3,31 +3,25 @@
%fieldset
%p
- Enable a Prometheus metrics endpoint at
- %code= metrics_path
- to expose a variety of statistics on the health and performance of GitLab. Additional information on authenticating and connecting to the metrics endpoint is available
- = link_to 'here', admin_health_check_path
- \. This setting requires a
- = link_to 'restart', help_page_path('administration/restart_gitlab')
- to take effect.
+ - link_to_restart = link_to(_('restart'), help_page_path('administration/restart_gitlab'))
+ = _('Enable a Prometheus metrics endpoint at %{metrics_path} to expose a variety of statistics on the health and performance of GitLab. Additional information on authenticating and connecting to the metrics endpoint is available %{link}.').html_safe % { metrics_path: "<code>#{metrics_path}</code>".html_safe, link: link_to(_('here'), admin_health_check_path) }
+ = _('This setting requires a %{link_to_restart} to take effect.').html_safe % { link_to_restart: link_to_restart }
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/index')
.form-group
.form-check
= f.check_box :prometheus_metrics_enabled, class: 'form-check-input'
= f.label :prometheus_metrics_enabled, class: 'form-check-label' do
- Enable Prometheus Metrics
+ = _("Enable Prometheus Metrics")
- unless Gitlab::Metrics.metrics_folder_present?
.form-text.text-muted
- %strong.cred WARNING:
- Environment variable
- %code prometheus_multiproc_dir
- does not exist or is not pointing to a valid directory.
+ %strong.cred= _("WARNING:")
+ = _("Environment variable %{code_start}%{environment_variable}%{code_end} does not exist or is not pointing to a valid directory.").html_safe % { environment_variable: prometheus_multiproc_dir, code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/gitlab_metrics', anchor: 'metrics-shared-directory')
.form-group
- = f.label :metrics_method_call_threshold, 'Method Call Threshold (ms)', class: 'label-bold'
+ = f.label :metrics_method_call_threshold, _('Method Call Threshold (ms)'), class: 'label-bold'
= f.number_field :metrics_method_call_threshold, class: 'form-control gl-form-input'
.form-text.text-muted
A method call is only tracked when it takes longer to complete than
the given amount of milliseconds.
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_repository_check.html.haml b/app/views/admin/application_settings/_repository_check.html.haml
index edf6853a1aa..31576d54a04 100644
--- a/app/views/admin/application_settings/_repository_check.html.haml
+++ b/app/views/admin/application_settings/_repository_check.html.haml
@@ -17,7 +17,7 @@
= _("If you got a lot of false alarms from repository checks you can choose to clear all repository check information from the database.")
- clear_repository_checks_link = _('Clear all repository checks')
- clear_repository_checks_message = _('This will clear repository check states for ALL projects in the database. This cannot be undone. Are you sure?')
- = link_to clear_repository_checks_link, clear_repository_check_states_admin_application_settings_path, data: { confirm: clear_repository_checks_message }, method: :put, class: "gl-button btn btn-sm btn-danger"
+ = link_to clear_repository_checks_link, clear_repository_check_states_admin_application_settings_path, data: { confirm: clear_repository_checks_message }, method: :put, class: "gl-button btn btn-sm btn-danger gl-mt-3"
.sub-section
%h4= _("Housekeeping")
diff --git a/app/views/admin/application_settings/_signin.html.haml b/app/views/admin/application_settings/_signin.html.haml
index 62d6c973efe..12a9f949750 100644
--- a/app/views/admin/application_settings/_signin.html.haml
+++ b/app/views/admin/application_settings/_signin.html.haml
@@ -6,14 +6,14 @@
.form-check
= f.check_box :password_authentication_enabled_for_web, class: 'form-check-input'
= f.label :password_authentication_enabled_for_web, class: 'form-check-label' do
- Password authentication enabled for web interface
+ = _('Password authentication enabled for web interface')
.form-text.text-muted
- When disabled, an external authentication provider must be used.
+ = _('When disabled, an external authentication provider must be used.')
.form-group
.form-check
= f.check_box :password_authentication_enabled_for_git, class: 'form-check-input'
= f.label :password_authentication_enabled_for_git, class: 'form-check-label' do
- Password authentication enabled for Git over HTTP(S)
+ = _('Password authentication enabled for Git over HTTP(S)')
.form-text.text-muted
When disabled, a Personal Access Token
- if Gitlab::Auth::Ldap::Config.enabled?
@@ -26,11 +26,11 @@
- oauth_providers_checkboxes.each do |source|
= source
.form-group
- = f.label :two_factor_authentication, 'Two-factor authentication', class: 'label-bold'
+ = f.label :two_factor_authentication, _('Two-factor authentication'), class: 'label-bold'
.form-check
= f.check_box :require_two_factor_authentication, class: 'form-check-input'
= f.label :require_two_factor_authentication, class: 'form-check-label' do
- Require all users to set up Two-factor authentication
+ = _('Require all users to set up two-factor authentication')
.form-group
= f.label :admin_mode, _('Admin Mode'), class: 'label-bold'
= sprite_icon('lock', css_class: 'gl-icon')
@@ -50,19 +50,19 @@
'https://docs.gitlab.com/ee/user/profile/unknown_sign_in_notification.html',
target: '_blank'
.form-group
- = f.label :two_factor_authentication, 'Two-factor grace period (hours)', class: 'label-bold'
+ = f.label :two_factor_authentication, _('Two-factor grace period (hours)'), class: 'label-bold'
= f.number_field :two_factor_grace_period, min: 0, class: 'form-control gl-form-input', placeholder: '0'
- .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= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication')
.form-group
- = f.label :home_page_url, 'Home page URL', class: 'label-bold'
+ = f.label :home_page_url, _('Home page URL'), class: 'label-bold'
= f.text_field :home_page_url, class: 'form-control gl-form-input', placeholder: 'http://company.example.com', :'aria-describedby' => 'home_help_block'
- %span.form-text.text-muted#home_help_block We will redirect non-logged in users to this page
+ %span.form-text.text-muted#home_help_block= _("We will redirect non-logged in users to this page")
.form-group
= f.label :after_sign_out_path, _('After sign-out path'), class: 'label-bold'
= f.text_field :after_sign_out_path, class: 'form-control gl-form-input', placeholder: 'http://company.example.com', :'aria-describedby' => 'after_sign_out_path_help_block'
- %span.form-text.text-muted#after_sign_out_path_help_block We will redirect users to this page after they sign out
+ %span.form-text.text-muted#after_sign_out_path_help_block= _("We will redirect users to this page after they sign out")
.form-group
= f.label :sign_in_text, _('Sign-in text'), class: 'label-bold'
= f.text_area :sign_in_text, class: 'form-control gl-form-input', rows: 4
.form-text.text-muted Markdown enabled
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_spam.html.haml b/app/views/admin/application_settings/_spam.html.haml
index 2086fbc9d32..011bce3ca99 100644
--- a/app/views/admin/application_settings/_spam.html.haml
+++ b/app/views/admin/application_settings/_spam.html.haml
@@ -6,25 +6,25 @@
.form-check
= f.check_box :recaptcha_enabled, class: 'form-check-input'
= f.label :recaptcha_enabled, class: 'form-check-label' do
- Enable reCAPTCHA
+ = _("Enable reCAPTCHA")
%span.form-text.text-muted#recaptcha_help_block
= _('Helps prevent bots from creating accounts.')
.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
+ = _("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'
+ = f.label :recaptcha_private_key, _('reCAPTCHA Private Key'), class: 'label-bold'
.form-group
= f.text_field :recaptcha_private_key, class: 'form-control gl-form-input'
@@ -41,10 +41,10 @@
= 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'
+ = f.label :akismet_api_key, _('Akismet API Key'), class: 'label-bold'
= f.text_field :akismet_api_key, class: 'form-control gl-form-input'
.form-text.text-muted
Generate API key at
@@ -54,21 +54,21 @@
.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 ips")
%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, _('IPs 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 IPs 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 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 will be counted towards the limit")
.form-group
.form-check
@@ -78,5 +78,9 @@
.form-group
= 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.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')
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = 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 482466c4b3b..d6e31a24cf6 100644
--- a/app/views/admin/application_settings/_terminal.html.haml
+++ b/app/views/admin/application_settings/_terminal.html.haml
@@ -3,9 +3,8 @@
%fieldset
.form-group
- = f.label :terminal_max_session_time, 'Max session time', class: 'label-bold'
+ = 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.
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = _('Maximum time for web terminal websocket connection (in seconds). 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 a2d61bd010f..64e8751bf31 100644
--- a/app/views/admin/application_settings/_usage.html.haml
+++ b/app/views/admin/application_settings/_usage.html.haml
@@ -8,11 +8,10 @@
.form-check
= f.check_box :version_check_enabled, class: 'form-check-input'
= f.label :version_check_enabled, class: 'form-check-label' do
- Enable version check
+ = _("Enable version check")
.form-text.text-muted
- GitLab will inform you if a new version is available.
- = link_to 'Learn more', help_page_path('user/admin_area/settings/usage_statistics', anchor: 'version-check')
- about what information is shared with GitLab Inc.
+ = _("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 }
.form-group
- can_be_configured = @application_setting.usage_ping_can_be_configured?
.form-check
@@ -28,7 +27,7 @@
%p.mb-2= s_('%{usage_ping_link_start}Learn more%{usage_ping_link_end} about what information is shared with GitLab Inc.').html_safe % { usage_ping_link_start: usage_ping_link_start, usage_ping_link_end: '</a>'.html_safe }
%button.gl-button.btn.btn-default.js-payload-preview-trigger{ type: 'button', data: { payload_selector: ".#{payload_class}" } }
- .spinner.js-spinner.d-none
+ .gl-spinner.js-spinner.gl-display-none.gl-mr-2
.js-text.d-inline= _('Preview payload')
%pre.usage-data.js-syntax-highlight.code.highlight.mt-2.d-none{ class: payload_class, data: { endpoint: usage_data_admin_application_settings_path(format: :html) } }
- else
@@ -37,4 +36,4 @@
- deactivating_usage_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: deactivating_usage_ping_path }
= s_('For more information, see the documentation on %{deactivating_usage_ping_link_start}deactivating the usage ping%{deactivating_usage_ping_link_end}.').html_safe % { deactivating_usage_ping_link_start: deactivating_usage_ping_link_start, deactivating_usage_ping_link_end: '</a>'.html_safe }
- = f.submit 'Save changes', class: "gl-button btn btn-confirm"
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_whats_new.html.haml b/app/views/admin/application_settings/_whats_new.html.haml
new file mode 100644
index 00000000000..70ba994d21e
--- /dev/null
+++ b/app/views/admin/application_settings/_whats_new.html.haml
@@ -0,0 +1,13 @@
+= form_for @application_setting, url: preferences_admin_application_settings_path(anchor: 'js-whats-new-settings'), html: { class: 'fieldset-form whats-new-settings' } do |f|
+ = form_errors(@application_setting)
+
+ - whats_new_variants.keys.each do |variant|
+ .form-check.gl-mb-4
+ = f.radio_button :whats_new_variant, variant, class: 'form-check-input'
+ = f.label :whats_new_variant, value: variant, class: 'form-check-label' do
+ .font-weight-bold
+ = whats_new_variants_label(variant)
+ .option-description
+ = whats_new_variants_description(variant)
+
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml
index 86226a9de2f..217225e6186 100644
--- a/app/views/admin/application_settings/general.html.haml
+++ b/app/views/admin/application_settings/general.html.haml
@@ -112,3 +112,4 @@
= render 'admin/application_settings/third_party_offers'
= render 'admin/application_settings/snowplow'
= render 'admin/application_settings/eks'
+= render 'admin/application_settings/floc'
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 72716e76013..72a27e4523f 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -24,6 +24,17 @@
.settings-content
= render 'ip_limits'
+%section.settings.as-packages-limits.no-animate#js-packages-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'packages_limits_content' } }
+ .settings-header
+ %h4
+ = _('Package Registry Rate Limits')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure specific limits for Packages API requests that supersede the general user and IP rate limits.')
+ .settings-content
+ = render 'package_registry_limits'
+
%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'outbound_requests_content' } }
.settings-header
%h4
diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml
index fd5ce890648..17bf9ba84a2 100644
--- a/app/views/admin/application_settings/preferences.html.haml
+++ b/app/views/admin/application_settings/preferences.html.haml
@@ -13,6 +13,17 @@
.settings-content
= render 'email'
+%section.settings.as-whats-new-page.no-animate#js-whats-new-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _("What's new")
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _("Configure What's new drawer and content.")
+ .settings-content
+ = render 'whats_new'
+
%section.settings.as-help-page.no-animate#js-help-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml
index 4365d8937bd..111cc9c5d7c 100644
--- a/app/views/admin/application_settings/repository.html.haml
+++ b/app/views/admin/application_settings/repository.html.haml
@@ -2,17 +2,16 @@
- page_title _("Repository")
- @content_class = "limit-container-width" unless fluid_layout
-- if Feature.enabled?(:global_default_branch_name, default_enabled: true)
- %section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) }
- .settings-header
- %h4
- = _('Default initial branch name')
- %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
- = expanded_by_default? ? _('Collapse') : _('Expand')
- %p
- = _('Set the default name of the initial branch when creating new repositories through the user interface.')
- .settings-content
- = render 'initial_branch_name'
+%section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Default initial branch name')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Set the default name of the initial branch when creating new repositories through the user interface.')
+ .settings-content
+ = render 'initial_branch_name'
%section.settings.as-mirror.no-animate#js-mirror-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
diff --git a/app/views/admin/background_jobs/show.html.haml b/app/views/admin/background_jobs/show.html.haml
index 9ba72caa88e..bab9fa02928 100644
--- a/app/views/admin/background_jobs/show.html.haml
+++ b/app/views/admin/background_jobs/show.html.haml
@@ -1,7 +1,10 @@
- page_title _("Background Jobs")
-%h3.page-title Background Jobs
-%p.light GitLab uses #{link_to "sidekiq", "http://sidekiq.org/"} library for async job processing
+%h3.page-title= _('Background Jobs')
+%p.light
+ - sidekiq_link_url = 'http://sidekiq.org/'
+ - sidekiq_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: sidekiq_link_url }
+ = html_escape(_('GitLab uses %{linkStart}Sidekiq%{linkEnd} to process background jobs')) % { linkStart: sidekiq_link_start, linkEnd: '</a>'.html_safe }
%hr
.card.gl-rounded-0
diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml
index 9a4bb9b0a48..fe5759ecdbf 100644
--- a/app/views/admin/broadcast_messages/_form.html.haml
+++ b/app/views/admin/broadcast_messages/_form.html.haml
@@ -4,7 +4,7 @@
- if @broadcast_message.message.present?
= render_broadcast_message(@broadcast_message)
- else
- Your message here
+ = _('Your message here')
.d-flex.justify-content-center
.broadcast-message.broadcast-notification-message.preview.js-broadcast-notification-message-preview.mt-2{ class: ('hidden' unless @broadcast_message.notification? ) }
= sprite_icon('bullhorn', css_class: 'vertical-align-text-top')
@@ -12,7 +12,7 @@
- if @broadcast_message.message.present?
= render_broadcast_message(@broadcast_message)
- else
- Your message here
+ = _('Your message here')
= form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form js-quick-submit js-requires-input'} do |f|
= form_errors(@broadcast_message)
@@ -55,7 +55,7 @@
= _('Allow users to dismiss the broadcast message')
.form-group.row.js-toggle-colors-container.toggle-colors.hide
.col-sm-2.col-form-label
- = f.label :font, "Font Color"
+ = f.label :font, _("Font Color")
.col-sm-10
= f.color_field :font, class: "form-control gl-form-input text-font-color"
.form-group.row
@@ -77,6 +77,6 @@
= f.datetime_select :ends_at, {}, class: 'form-control form-control-inline'
.form-actions
- if @broadcast_message.persisted?
- = f.submit "Update broadcast message", class: "btn gl-button btn-confirm"
+ = f.submit _("Update broadcast message"), class: "btn gl-button btn-confirm"
- else
- = f.submit "Add broadcast message", class: "btn gl-button btn-confirm"
+ = f.submit _("Add broadcast message"), class: "btn gl-button btn-confirm"
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index e34808665bb..2dbb804d537 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -44,7 +44,7 @@
trigger: "focus",
content: s_("AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}.").html_safe % { billable_users_link_start: billable_users_link_start, billable_users_link_end: '</a>'.html_safe },
} }
- = sprite_icon('question', size: 16, css_class: 'gl-text-gray-700')
+ = sprite_icon('question-o', size: 16, css_class: 'gl-text-blue-600')
.gl-mt-3.text-uppercase
= s_('AdminArea|Users')
= link_to(s_('AdminArea|Users statistics'), admin_dashboard_stats_path, class: "text-capitalize gl-ml-2")
diff --git a/app/views/admin/deploy_keys/new.html.haml b/app/views/admin/deploy_keys/new.html.haml
index 0eaf7b60b25..b0b12a01aed 100644
--- a/app/views/admin/deploy_keys/new.html.haml
+++ b/app/views/admin/deploy_keys/new.html.haml
@@ -6,5 +6,5 @@
= form_for [:admin, @deploy_key], html: { class: 'deploy-key-form' } do |f|
= render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key }
.form-actions
- = f.submit 'Create', class: 'btn gl-button btn-confirm'
+ = f.submit 'Create', class: 'btn gl-button btn-confirm', data: { qa_selector: "add_deploy_key_button" }
= link_to 'Cancel', admin_deploy_keys_path, class: 'btn gl-button btn-default btn-cancel'
diff --git a/app/views/admin/dev_ops_report/_card.html.haml b/app/views/admin/dev_ops_report/_card.html.haml
deleted file mode 100644
index dd6e5c0f108..00000000000
--- a/app/views/admin/dev_ops_report/_card.html.haml
+++ /dev/null
@@ -1,25 +0,0 @@
-.devops-card-wrapper
- .devops-card{ class: "devops-card-#{score_level(card.percentage_score)}" }
- .devops-card-title
- %h3
- = card.title
- .light-text
- = card.description
- .board-card-scores
- .board-card-score
- .board-card-score-value
- = format_score(card.instance_score)
- .board-card-score-name= _('You')
- .board-card-score
- .board-card-score-value
- = format_score(card.leader_score)
- .board-card-score-name= _('Lead')
- .board-card-score-big
- = number_to_percentage(card.percentage_score, precision: 1)
- .board-card-buttons
- - if card.blog
- %a.btn-svg{ href: card.blog }
- = sprite_icon('information-o')
- - if card.docs
- %a.btn-svg{ href: card.docs }
- = sprite_icon('question-o')
diff --git a/app/views/admin/dev_ops_report/_no_data.html.haml b/app/views/admin/dev_ops_report/_no_data.html.haml
deleted file mode 100644
index e540a4e2bce..00000000000
--- a/app/views/admin/dev_ops_report/_no_data.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-.container.devops-empty
- .col-sm-12.justify-content-center.text-center
- = custom_icon('dev_ops_report_no_data')
- %h4= _('Data is still calculating...')
- %p
- = _('It may be several days before you see feature usage data.')
- = link_to _('Our documentation includes an example DevOps Score report.'), help_page_path('user/admin_area/analytics/dev_ops_report'), target: '_blank'
diff --git a/app/views/admin/dev_ops_report/_report.html.haml b/app/views/admin/dev_ops_report/_report.html.haml
index 95ef1298d03..dbd0020e382 100644
--- a/app/views/admin/dev_ops_report/_report.html.haml
+++ b/app/views/admin/dev_ops_report/_report.html.haml
@@ -4,29 +4,7 @@
= render 'callout'
- if !usage_ping_enabled
- #js-devops-empty-state{ data: { is_admin: current_user&.admin.to_s, empty_state_svg_path: image_path('illustrations/convdev/convdev_no_index.svg'), enable_usage_ping_link: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), docs_link: help_page_path('development/usage_ping/index.md') } }
-- elsif @metric.blank?
- = render 'no_data'
+ #js-devops-usage-ping-disabled{ data: { is_admin: current_user&.admin.to_s, empty_state_svg_path: image_path('illustrations/convdev/convdev_no_index.svg'), enable_usage_ping_link: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), docs_link: help_page_path('development/usage_ping/index.md') } }
- else
- .devops
- .gl-my-3.gl-text-gray-400{ data: { testid: 'devops-score-note-text' } }
- = s_('DevopsReport|DevOps score metrics are based on usage over the last 30 days. Last updated: %{timestamp}.').html_safe % { timestamp: @metric.created_at.strftime('%Y-%m-%d %H:%M') }
- .devops-header
- %h2.devops-header-title{ class: "devops-#{score_level(@metric.average_percentage_score)}-score" }
- = number_to_percentage(@metric.average_percentage_score, precision: 1)
- .devops-header-subtitle
- = s_('DevopsReport|DevOps')
- %br
- = s_('DevopsReport|Score')
- = link_to sprite_icon('question-o', css_class: 'devops-header-icon'), help_page_path('user/admin_area/analytics/dev_ops_report')
+ #js-devops-score{ data: { devops_score_metrics: devops_score_metrics(@metric).to_json, devops_report_docs_path: help_page_path('user/admin_area/analytics/dev_ops_report'), no_data_image_path: image_path('dev_ops_report_no_data.svg') } }
- .devops-cards.board-card-container
- - @metric.cards.each do |card|
- = render 'card', card: card
-
- .devops-steps.d-none.d-lg-block
- - @metric.idea_to_production_steps.each_with_index do |step, index|
- .devops-step{ class: "devops-#{score_level(step.percentage_score)}-score" }
- = custom_icon("i2p_step_#{index + 1}")
- %h4.devops-step-title
- = step.title
diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml
index df7af86e089..bbc65850794 100644
--- a/app/views/admin/groups/_group.html.haml
+++ b/app/views/admin/groups/_group.html.haml
@@ -15,7 +15,7 @@
= markdown_field(group, :description)
.stats.gl-text-gray-500.gl-flex-shrink-0.gl-display-none.gl-sm-display-flex
- %span.badge.badge-pill
+ %span.badge.badge-muted.badge-pill.gl-badge.sm
= storage_counter(group.storage_size)
= render_if_exists 'admin/namespace_plan_badge', namespace: group, css_class: 'gl-ml-5 gl-mr-0'
diff --git a/app/views/admin/health_check/show.html.haml b/app/views/admin/health_check/show.html.haml
index 78f0fd325fb..a289cea0d5a 100644
--- a/app/views/admin/health_check/show.html.haml
+++ b/app/views/admin/health_check/show.html.haml
@@ -23,8 +23,8 @@
%code= metrics_url(token: Gitlab::CurrentSettings.health_check_access_token)
= render_if_exists 'admin/health_check/health_check_url'
%hr
-.card
- .card-header
+.gl-card
+ .gl-card-header
Current Status:
- if no_errors
= sprite_icon('check', css_class: 'cgreen')
@@ -32,7 +32,7 @@
- else
= sprite_icon('warning-solid', css_class: 'cred')
#{ s_('HealthCheck|Unhealthy') }
- .card-body
+ .gl-card-body
- if no_errors
#{ s_('HealthCheck|No Health Problems Detected') }
- else
diff --git a/app/views/admin/hook_logs/_index.html.haml b/app/views/admin/hook_logs/_index.html.haml
index 61af7535c1e..a7f947f96ea 100644
--- a/app/views/admin/hook_logs/_index.html.haml
+++ b/app/views/admin/hook_logs/_index.html.haml
@@ -4,7 +4,7 @@
= _('Recent Deliveries')
%p= _('When an event in GitLab triggers a webhook, you can use the request details to figure out if something went wrong.')
.col-lg-9
- - if hook_logs.any?
+ - if hook_logs.present?
%table.table
%thead
%tr
diff --git a/app/views/admin/labels/_label.html.haml b/app/views/admin/labels/_label.html.haml
index a357c3d9d34..16661efce04 100644
--- a/app/views/admin/labels/_label.html.haml
+++ b/app/views/admin/labels/_label.html.haml
@@ -3,5 +3,5 @@
.label-actions-list
= link_to edit_admin_label_path(label), class: 'btn btn-default gl-button btn-default-tertiary label-action has-tooltip', title: _('Edit'), data: { placement: 'bottom' }, aria_label: _('Edit') do
= sprite_icon('pencil')
- = link_to admin_label_path(label), class: 'btn btn-default gl-button btn-default-tertiary hover-red js-remove-row label-action has-tooltip', title: _('Delete'), data: { placement: 'bottom', confirm: "Delete this label? Are you sure?" }, aria_label: _('Delete'), method: :delete, remote: true do
+ = link_to admin_label_path(label), class: 'btn btn-default gl-button btn-default-tertiary hover-red js-remove-label label-action has-tooltip', title: _('Delete'), data: { placement: 'bottom', confirm: "Delete this label? Are you sure?" }, aria_label: _('Delete'), method: :delete, remote: true do
= sprite_icon('remove')
diff --git a/app/views/admin/labels/destroy.js.haml b/app/views/admin/labels/destroy.js.haml
deleted file mode 100644
index 5ee53088230..00000000000
--- a/app/views/admin/labels/destroy.js.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-- if @labels.size == 0
- var emptyState = document.querySelector('.labels .nothing-here-block.hidden');
- if (emptyState) emptyState.classList.remove('hidden');
diff --git a/app/views/admin/projects/_projects.html.haml b/app/views/admin/projects/_projects.html.haml
index 7e505729213..6f7cea85ed1 100644
--- a/app/views/admin/projects/_projects.html.haml
+++ b/app/views/admin/projects/_projects.html.haml
@@ -1,7 +1,7 @@
.js-projects-list-holder
- if @projects.any?
%ul.projects-list.content-list.admin-projects
- - @projects.each_with_index do |project|
+ - @projects.each do |project|
%li.project-row{ class: ('no-description' if project.description.blank?) }
.controls
= link_to _('Edit'), edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn gl-button btn-default"
diff --git a/app/views/admin/requests_profiles/index.html.haml b/app/views/admin/requests_profiles/index.html.haml
index 6c75dfe9733..9d42a2bfa93 100644
--- a/app/views/admin/requests_profiles/index.html.haml
+++ b/app/views/admin/requests_profiles/index.html.haml
@@ -4,9 +4,7 @@
= page_title
.bs-callout.clearfix
- Pass the header
- %code X-Profile-Token: #{@profile_token}
- to profile the request
+ = html_escape(_('Pass the header %{codeOpen} X-Profile-Token: %{profile_token} %{codeClose} to profile the request')) % { profile_token: @profile_token, codeOpen: '<code>'.html_safe, codeClose: '</code>'.html_safe }
- if @profiles.present?
.gl-mt-3
@@ -21,4 +19,4 @@
admin_requests_profile_path(profile)
- else
%p
- No profiles found
+ = _('No profiles found')
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index a38615d9b1b..359e5b411b1 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -5,7 +5,7 @@
.col-sm-6
.bs-callout
%p
- = (_"Runners are processes that pick up and execute CI/CD jobs for GitLab.")
+ = _("Runners are processes that pick up and execute CI/CD jobs for GitLab.")
%br
= _('You can register runners as separate users, on separate servers, and on your local machine. Register as many runners as you want.')
%br
diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml
index 705716c09b7..d911f35d946 100644
--- a/app/views/admin/runners/show.html.haml
+++ b/app/views/admin/runners/show.html.haml
@@ -1,11 +1,11 @@
- add_page_specific_style 'page_bundles/ci_status'
-- page_title @runner.short_sha
+- breadcrumb_title @runner.short_sha
+- page_title "##{@runner.id} (#{@runner.short_sha})"
- add_to_breadcrumbs _('Runners'), admin_runners_path
-- breadcrumb_title page_title
- if Feature.enabled?(:runner_detailed_view_vue_ui, current_user, default_enabled: :yaml)
- #js-runner-detail{ data: {runner_id: @runner.id} }
+ #js-runner-details{ data: {runner_id: @runner.id} }
- else
%h2.page-title
= s_('Runners|Runner #%{runner_id}' % { runner_id: @runner.id })
@@ -46,9 +46,10 @@
%tr
%td
= form_tag admin_runner_path(@runner), id: 'runner-projects-search', class: 'form-inline', method: :get do
- .form-group
- = search_field_tag :search, params[:search], class: 'form-control', spellcheck: false
- = submit_tag 'Search', class: 'btn'
+ .input-group
+ = search_field_tag :search, params[:search], class: 'form-control gl-form-input', spellcheck: false
+ .input-group-append
+ = submit_tag _('Search'), class: 'gl-button btn btn-default'
%td
- @projects.each do |project|
@@ -59,7 +60,7 @@
.float-right
= form_for project.runner_projects.new, url: admin_namespace_project_runner_projects_path(project.namespace, project), method: :post do |f|
= f.hidden_field :runner_id, value: @runner.id
- = f.submit 'Enable', class: 'gl-button btn btn-sm'
+ = f.submit _('Enable'), class: 'gl-button btn btn-sm'
= paginate_without_count @projects
.col-md-6
diff --git a/app/views/admin/spam_logs/index.html.haml b/app/views/admin/spam_logs/index.html.haml
index 40fbc559d72..2a36c991ed2 100644
--- a/app/views/admin/spam_logs/index.html.haml
+++ b/app/views/admin/spam_logs/index.html.haml
@@ -1,22 +1,22 @@
- page_title _("Spam Logs")
-%h3.page-title Spam Logs
+%h3.page-title= _('Spam Logs')
%hr
- if @spam_logs.present?
.table-holder
%table.table
%thead
%tr
- %th Date
- %th User
- %th Source IP
- %th API?
- %th Recaptcha verified?
- %th Type
- %th Title
- %th Description
- %th Primary Action
+ %th= _('Date')
+ %th= _('User')
+ %th= _('Source IP')
+ %th= _('API?')
+ %th= _('Recaptcha verified?')
+ %th= _('Type')
+ %th= _('Title')
+ %th= _('Description')
+ %th= _('Primary Action')
%th
= render @spam_logs
= paginate @spam_logs, theme: 'gitlab'
- else
- %h4 There are no Spam Logs
+ %h4= _('There are no Spam Logs')
diff --git a/app/views/admin/users/_ban_user.html.haml b/app/views/admin/users/_ban_user.html.haml
new file mode 100644
index 00000000000..229c88adb7f
--- /dev/null
+++ b/app/views/admin/users/_ban_user.html.haml
@@ -0,0 +1,9 @@
+- if ban_feature_available?
+ .card.border-warning
+ .card-header.bg-warning.gl-text-white
+ = s_('AdminUsers|Ban user')
+ .card-body
+ = user_ban_effects
+ %br
+ %button.btn.gl-button.btn-warning.js-confirm-modal-button{ data: user_ban_data(user) }
+ = s_('AdminUsers|Ban user')
diff --git a/app/views/admin/users/_cohorts.html.haml b/app/views/admin/users/_cohorts.html.haml
index 013c6072165..25b30adc5be 100644
--- a/app/views/admin/users/_cohorts.html.haml
+++ b/app/views/admin/users/_cohorts.html.haml
@@ -1,4 +1 @@
-- if @cohorts
- = render 'cohorts_table'
-- else
- #js-cohorts-empty-state{ data: { empty_state_svg_path: image_path('illustrations/convdev/convdev_no_index.svg'), enable_usage_ping_link: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), docs_link: help_page_path('user/admin_area/analytics/user_cohorts') } }
+= render 'cohorts_table'
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index b3ed8369263..9d62c19e2fc 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -3,40 +3,38 @@
= form_errors(@user)
%fieldset
- %legend Account
+ %legend= _('Account')
.form-group.row
.col-sm-2.col-form-label
= f.label :name
.col-sm-10
= f.text_field :name, required: true, autocomplete: 'off', class: 'form-control gl-form-input'
- %span.help-inline * required
+ %span.help-inline * #{_('required')}
.form-group.row
.col-sm-2.col-form-label
= f.label :username
.col-sm-10
= f.text_field :username, required: true, autocomplete: 'off', autocorrect: 'off', autocapitalize: 'off', spellcheck: false, class: 'form-control gl-form-input'
- %span.help-inline * required
+ %span.help-inline * #{_('required')}
.form-group.row
.col-sm-2.col-form-label
= f.label :email
.col-sm-10
= f.text_field :email, required: true, autocomplete: 'off', class: 'form-control gl-form-input'
- %span.help-inline * required
+ %span.help-inline * #{_('required')}
- if @user.new_record?
%fieldset
- %legend Password
+ %legend= _('Password')
.form-group.row
.col-sm-2.col-form-label
= f.label :password
.col-sm-10
%strong
- Reset link will be generated and sent to the user.
- %br
- User will be forced to set the password on first sign in.
+ = _('Reset link will be generated and sent to the user. %{break} User will be forced to set the password on first sign in.').html_safe % { break: '<br />'.html_safe }
- else
%fieldset
- %legend Password
+ %legend= _('Password')
.form-group.row
.col-sm-2.col-form-label
= f.label :password
@@ -55,7 +53,7 @@
= render_if_exists 'admin/users/limits', f: f
%fieldset
- %legend Profile
+ %legend= _('Profile')
.form-group.row
.col-sm-2.col-form-label
= f.label :avatar
@@ -87,8 +85,8 @@
.form-actions
- if @user.new_record?
- = f.submit 'Create user', class: "btn gl-button btn-confirm"
- = link_to 'Cancel', admin_users_path, class: "gl-button btn btn-default btn-cancel"
+ = f.submit _('Create user'), class: "btn gl-button btn-confirm"
+ = link_to _('Cancel'), admin_users_path, class: "gl-button btn btn-default btn-cancel"
- else
- = f.submit 'Save changes', class: "btn gl-button btn-confirm"
- = link_to 'Cancel', admin_user_path(@user), class: "gl-button btn btn-default btn-cancel"
+ = f.submit _('Save changes'), class: "btn gl-button btn-confirm"
+ = link_to _('Cancel'), admin_user_path(@user), class: "gl-button btn btn-default btn-cancel"
diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml
index ade3581e5b9..be04e87f8b9 100644
--- a/app/views/admin/users/_head.html.haml
+++ b/app/views/admin/users/_head.html.haml
@@ -3,6 +3,9 @@
- if @user.blocked_pending_approval?
%span.cred
= s_('AdminUsers|(Pending approval)')
+ - elsif @user.banned?
+ %span.cred
+ = s_('AdminUsers|(Banned)')
- elsif @user.blocked?
%span.cred
= s_('AdminUsers|(Blocked)')
diff --git a/app/views/admin/users/_profile.html.haml b/app/views/admin/users/_profile.html.haml
index 4fcb9aad343..e90dab68b39 100644
--- a/app/views/admin/users/_profile.html.haml
+++ b/app/views/admin/users/_profile.html.haml
@@ -1,31 +1,31 @@
.card
.card-header
- Profile
+ = _('Profile')
%ul.content-list
%li
- %span.light Member since
+ %span.light= _('Member since')
%strong= user.created_at.to_s(:medium)
- unless user.public_email.blank?
%li
- %span.light E-mail:
+ %span.light= _('E-mail:')
%strong= link_to user.public_email, "mailto:#{user.public_email}"
- unless user.skype.blank?
%li
- %span.light Skype:
+ %span.light= _('Skype:')
%strong= link_to user.skype, "skype:#{user.skype}"
- unless user.linkedin.blank?
%li
- %span.light LinkedIn:
+ %span.light= _('LinkedIn:')
%strong= link_to user.linkedin, "https://www.linkedin.com/in/#{user.linkedin}"
- unless user.twitter.blank?
%li
- %span.light Twitter:
+ %span.light= _('Twitter:')
%strong= link_to user.twitter, "https://twitter.com/#{user.twitter}"
- unless user.website_url.blank?
%li
- %span.light Website:
+ %span.light= _('Website:')
%strong= link_to user.short_website_url, user.full_website_url
- unless user.location.blank?
%li
- %span.light Location:
+ %span.light= _('Location:')
%strong= user.location
diff --git a/app/views/admin/users/_projects.html.haml b/app/views/admin/users/_projects.html.haml
index 81cfb71af16..a9f5c560b41 100644
--- a/app/views/admin/users/_projects.html.haml
+++ b/app/views/admin/users/_projects.html.haml
@@ -1,13 +1,13 @@
- if local_assigns.has_key?(:contributed_projects) && contributed_projects.present?
.card.contributed-projects
- .card-header Projects contributed to
+ .card-header= _('Projects contributed to')
= render 'shared/projects/list',
projects: contributed_projects.sort_by(&:star_count).reverse,
projects_limit: 5, stars: true, avatar: false
- if local_assigns.has_key?(:projects) && projects.present?
.card
- .card-header Personal projects
+ .card-header= _('Personal projects')
= render 'shared/projects/list',
projects: projects.sort_by(&:star_count).reverse,
projects_limit: 10, stars: true, avatar: false
diff --git a/app/views/admin/users/_tabs.html.haml b/app/views/admin/users/_tabs.html.haml
new file mode 100644
index 00000000000..1a3239897eb
--- /dev/null
+++ b/app/views/admin/users/_tabs.html.haml
@@ -0,0 +1,7 @@
+%ul.nav-links.nav-tabs.nav.js-users-tabs{ role: 'tablist' }
+ %li.nav-item{ role: 'presentation' }
+ %a.nav-link{ href: admin_users_path, class: active_when(current_page?(admin_users_path)), role: 'tab' }
+ = s_('AdminUsers|Users')
+ %li.nav-item{ role: 'presentation' }
+ %a.nav-link{ href: cohorts_admin_users_path, class: active_when(current_page?(cohorts_admin_users_path)), role: 'tab' }
+ = s_('AdminUsers|Cohorts')
diff --git a/app/views/admin/users/_user.html.haml b/app/views/admin/users/_user.html.haml
index f2920579057..2816a1061b9 100644
--- a/app/views/admin/users/_user.html.haml
+++ b/app/views/admin/users/_user.html.haml
@@ -21,13 +21,13 @@
= user.last_activity_on.nil? ? _('Never') : l(user.last_activity_on, format: :admin)
- unless user.internal?
.table-section.section-20.table-button-footer
- .table-action-buttons
- = link_to _('Edit'), edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn gl-button btn-default'
+ .table-action-buttons{ data: { testid: "user-actions-#{user.id}" } }
+ = link_to _('Edit'), edit_admin_user_path(user), class: 'btn gl-button btn-default'
- unless user == current_user
- %button.dropdown-new.btn.gl-button.btn-default{ type: 'button', data: { testid: "user-action-button-#{user.id}", toggle: 'dropdown' } }
+ %button.dropdown-new.btn.gl-button.btn-default{ type: 'button', data: { testid: "dropdown-toggle", toggle: 'dropdown' } }
= sprite_icon('settings')
= sprite_icon('chevron-down')
- %ul.dropdown-menu.dropdown-menu-right{ data: { testid: "user-action-dropdown-#{user.id}" } }
+ %ul.dropdown-menu.dropdown-menu-right
%li.dropdown-header
= _('Settings')
%li
diff --git a/app/views/admin/users/_users.html.haml b/app/views/admin/users/_users.html.haml
index c79b2e978f2..e4438f38a47 100644
--- a/app/views/admin/users/_users.html.haml
+++ b/app/views/admin/users/_users.html.haml
@@ -7,39 +7,44 @@
= nav_link(html_options: { class: active_when(params[:filter].nil?) }) do
= link_to admin_users_path do
= s_('AdminUsers|Active')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.active_without_ghosts)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.active_without_ghosts)
= nav_link(html_options: { class: active_when(params[:filter] == 'admins') }) do
= link_to admin_users_path(filter: "admins") do
= s_('AdminUsers|Admins')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.admins)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.admins)
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'two_factor_enabled')} filter-two-factor-enabled" }) do
= link_to admin_users_path(filter: 'two_factor_enabled') do
= s_('AdminUsers|2FA Enabled')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.with_two_factor)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.with_two_factor)
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'two_factor_disabled')} filter-two-factor-disabled" }) do
= link_to admin_users_path(filter: 'two_factor_disabled') do
= s_('AdminUsers|2FA Disabled')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.without_two_factor)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.without_two_factor)
= nav_link(html_options: { class: active_when(params[:filter] == 'external') }) do
= link_to admin_users_path(filter: 'external') do
= s_('AdminUsers|External')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.external)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.external)
= nav_link(html_options: { class: active_when(params[:filter] == 'blocked') }) do
= link_to admin_users_path(filter: "blocked") do
= s_('AdminUsers|Blocked')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.blocked)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.blocked)
+ - if ban_feature_available?
+ = nav_link(html_options: { class: active_when(params[:filter] == 'banned') }) do
+ = link_to admin_users_path(filter: "banned") do
+ = s_('AdminUsers|Banned')
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.banned)
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do
= link_to admin_users_path(filter: "blocked_pending_approval"), data: { qa_selector: 'pending_approval_tab' } do
= s_('AdminUsers|Pending approval')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.blocked_pending_approval)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.blocked_pending_approval)
= nav_link(html_options: { class: active_when(params[:filter] == 'deactivated') }) do
= link_to admin_users_path(filter: "deactivated") do
= s_('AdminUsers|Deactivated')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.deactivated)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.deactivated)
= nav_link(html_options: { class: active_when(params[:filter] == 'wop') }) do
= link_to admin_users_path(filter: "wop") do
= s_('AdminUsers|Without projects')
- %small.badge.badge-pill= limited_counter_with_delimiter(User.without_projects)
+ %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.without_projects)
.nav-controls
= render_if_exists 'admin/users/admin_email_users'
= render_if_exists 'admin/users/admin_export_user_permissions'
@@ -68,7 +73,7 @@
= link_to admin_users_path(sort: value, filter: params[:filter], search_query: params[:search_query]) do
= title
-- if Feature.enabled?(:vue_admin_users)
+- if Feature.enabled?(:vue_admin_users, default_enabled: :yaml)
#js-admin-users-app{ data: admin_users_data_attributes(@users) }
.gl-spinner-container.gl-my-7
%span.gl-vertical-align-bottom.gl-spinner.gl-spinner-dark.gl-spinner-lg{ aria: { label: _('Loading') } }
@@ -83,6 +88,6 @@
= render partial: 'admin/users/user', collection: @users
-= paginate @users, theme: "gitlab"
+= paginate_collection @users
= render partial: 'admin/users/modals'
diff --git a/app/views/admin/users/cohorts.html.haml b/app/views/admin/users/cohorts.html.haml
new file mode 100644
index 00000000000..3f3d22fa410
--- /dev/null
+++ b/app/views/admin/users/cohorts.html.haml
@@ -0,0 +1,7 @@
+- page_title _("Users")
+
+= render 'tabs'
+
+.tab-content
+ .tab-pane.active
+ = render 'cohorts'
diff --git a/app/views/admin/users/edit.html.haml b/app/views/admin/users/edit.html.haml
index 7d10e839cd6..e3ebb691ba9 100644
--- a/app/views/admin/users/edit.html.haml
+++ b/app/views/admin/users/edit.html.haml
@@ -1,5 +1,5 @@
- page_title _("Edit"), @user.name, _("Users")
%h3.page-title
- Edit user: #{@user.name}
+ = _("Edit user: %{user_name}") % { user_name: @user.name }
%hr
= render 'form'
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index f9b631ed6cf..86b777d8458 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -1,17 +1,7 @@
- page_title _("Users")
-%ul.nav-links.nav-tabs.nav.js-users-tabs{ role: 'tablist' }
- %li.nav-item.js-users-tab-item{ role: 'presentation' }
- %a.nav-link{ href: '#users', class: active_when(params[:tab] != 'cohorts'), data: { toggle: 'tab' }, role: 'tab' }
- = s_('AdminUsers|Users')
- %li.nav-item.js-users-tab-item{ role: 'presentation' }
- %a.nav-link{ href: '#cohorts', class: active_when(params[:tab] == 'cohorts'), data: { toggle: 'tab' }, role: 'tab' }
- = s_('AdminUsers|Cohorts')
+= render 'tabs'
.tab-content
- .tab-pane{ id: 'users', class: ('active' if params[:tab] != 'cohorts') }
+ .tab-pane.active
= render 'users'
- .tab-pane{ id: 'cohorts', class: ('active' if params[:tab] == 'cohorts') }
- = render 'cohorts'
-
-
diff --git a/app/views/admin/users/projects.html.haml b/app/views/admin/users/projects.html.haml
index 70a497f14ff..3ff726e1945 100644
--- a/app/views/admin/users/projects.html.haml
+++ b/app/views/admin/users/projects.html.haml
@@ -5,7 +5,7 @@
- if @user.groups.any?
.card
- .card-header Group projects
+ .card-header= _('Group projects')
%ul.hover-list
- @user.group_members.includes(:source).each do |group_member| # rubocop: disable CodeReuse/ActiveRecord
- group = group_member.group
@@ -24,12 +24,12 @@
- if @personal_projects.present?
= render 'admin/users/projects', projects: @personal_projects
- else
- .nothing-here-block This user has no personal projects.
+ .nothing-here-block= _('This user has no personal projects.')
.col-md-6
.card
- .card-header Joined projects (#{@joined_projects.count})
+ .card-header= _('Joined projects (%{projects_count})') % { projects_count: @joined_projects.count }
%ul.hover-list
- @joined_projects.sort_by(&:full_name).each do |project|
- member = project.team.find_member(@user.id)
@@ -41,10 +41,10 @@
- if member
.float-right
- if member.owner?
- %span.light Owner
+ %span.light= _('Owner')
- else
%span.light.vertical-align-middle= member.human_access
- if member.respond_to? :project
- = link_to project_project_member_path(project, member), data: { confirm: remove_member_message(member) }, remote: true, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon gl-ml-3", title: 'Remove user from project' do
+ = link_to project_project_member_path(project, member), data: { confirm: remove_member_message(member) }, remote: true, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon gl-ml-3", title: _('Remove user from project') do
= sprite_icon('close', size: 16, css_class: 'gl-icon')
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index c7ec3ab66d7..19cc29668f5 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -12,7 +12,7 @@
%li
= image_tag avatar_icon_for_user(@user, 60), class: "avatar s60"
%li
- %span.light Profile page:
+ %span.light= _('Profile page:')
%strong
= link_to user_path(@user) do
= @user.username
@@ -20,25 +20,25 @@
.card
.card-header
- Account:
+ = _('Account:')
%ul.content-list
%li
- %span.light Name:
+ %span.light= _('Name:')
%strong= @user.name
%li
- %span.light Username:
+ %span.light= _('Username:')
%strong
= @user.username
%li
- %span.light Email:
+ %span.light= _('Email:')
%strong
= render partial: 'shared/email_with_badge', locals: { email: mail_to(@user.email), verified: @user.confirmed? }
- @user.emails.each do |email|
%li
- %span.light Secondary email:
+ %span.light= _('Secondary email:')
%strong
= render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? }
- = link_to remove_email_admin_user_path(@user, email), data: { confirm: "Are you sure you want to remove #{email.email}?" }, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon float-right", title: 'Remove secondary email', id: "remove_email_#{email.id}" do
+ = link_to remove_email_admin_user_path(@user, email), data: { confirm: _("Are you sure you want to remove %{email}?") % { email: email.email } }, method: :delete, class: "btn btn-sm btn-danger gl-button btn-icon float-right", title: _('Remove secondary email'), id: "remove_email_#{email.id}" do
= sprite_icon('close', size: 16, css_class: 'gl-icon')
%li
%span.light ID:
@@ -50,65 +50,68 @@
= @user.namespace_id
%li.two-factor-status
- %span.light Two-factor Authentication:
+ %span.light= _('Two-factor Authentication:')
%strong{ class: @user.two_factor_enabled? ? 'cgreen' : 'cred' }
- if @user.two_factor_enabled?
- Enabled
- = link_to 'Disable', disable_two_factor_admin_user_path(@user), data: {confirm: 'Are you sure?'}, method: :patch, class: 'btn gl-button btn-sm btn-danger float-right', title: 'Disable Two-factor Authentication'
+ = _('Enabled')
+ = link_to _('Disable'), disable_two_factor_admin_user_path(@user), data: { confirm: _('Are you sure?') }, method: :patch, class: 'btn gl-button btn-sm btn-danger float-right', title: _('Disable Two-factor Authentication')
- else
- Disabled
+ = _('Disabled')
= render_if_exists 'admin/namespace_plan_info', namespace: @user.namespace
%li
- %span.light External User:
+ %span.light= _('External User:')
%strong
- = @user.external? ? "Yes" : "No"
+ = @user.external? ? _('Yes') : _('No')
+
+ = render_if_exists 'admin/users/provisioned_by', user: @user
+
%li
- %span.light Can create groups:
+ %span.light= _('Can create groups:')
%strong
- = @user.can_create_group ? "Yes" : "No"
+ = @user.can_create_group ? _('Yes') : _('No')
%li
- %span.light Personal projects limit:
+ %span.light= _('Personal projects limit:')
%strong
= @user.projects_limit
%li
- %span.light Member since:
+ %span.light= _('Member since:')
%strong
= @user.created_at.to_s(:medium)
- if @user.confirmed_at
%li
- %span.light Confirmed at:
+ %span.light= _('Confirmed at:')
%strong
= @user.confirmed_at.to_s(:medium)
- else
%li
- %span.light Confirmed:
+ %span.ligh= _('Confirmed:')
%strong.cred
- No
+ = _('No')
%li
- %span.light Current sign-in IP:
+ %span.light= _('Current sign-in IP:')
%strong
= @user.current_sign_in_ip || _('never')
%li
- %span.light Current sign-in at:
+ %span.light= _('Current sign-in at:')
%strong
= @user.current_sign_in_at&.to_s(:medium) || _('never')
%li
- %span.light Last sign-in IP:
+ %span.light= _('Last sign-in IP:')
%strong
= @user.last_sign_in_ip || _('never')
%li
- %span.light Last sign-in at:
+ %span.light= _('Last sign-in at:')
%strong
= @user.last_sign_in_at&.to_s(:medium) || _('never')
%li
- %span.light Sign-in count:
+ %span.light= _('Sign-in count:')
%strong
= @user.sign_in_count
@@ -121,13 +124,13 @@
- if @user.ldap_user?
%li
- %span.light LDAP uid:
+ %span.light= _('LDAP uid:')
%strong
= @user.ldap_identity.extern_uid
- if @user.created_by
%li
- %span.light Created by:
+ %span.light= _('Created by:')
%strong
= link_to @user.created_by.name, [:admin, @user.created_by]
@@ -140,13 +143,13 @@
- if can_force_email_confirmation?(@user)
.gl-card.border-info.gl-mb-5
.gl-card-header.bg-info.text-white
- Confirm user
+ = _('Confirm user')
.gl-card-body
- if @user.unconfirmed_email.present?
- email = " (#{@user.unconfirmed_email})"
- %p This user has an unconfirmed email address#{email}. You may force a confirmation.
+ %p= _('This user has an unconfirmed email address %{email}. You may force a confirmation.') % { email: email }
%br
- = link_to 'Confirm user', confirm_admin_user_path(@user), method: :put, class: "btn gl-button btn-info", data: { confirm: 'Are you sure?', qa_selector: 'confirm_user_button' }
+ = link_to _('Confirm user'), confirm_admin_user_path(@user), method: :put, class: "btn gl-button btn-info", data: { confirm: _('Are you sure?'), qa_selector: 'confirm_user_button' }
= render 'admin/users/user_detail_note'
@@ -154,7 +157,7 @@
- if @user.deactivated?
.gl-card.border-info.gl-mb-5
.gl-card-header.bg-info.text-white
- Reactivate this user
+ = _('Reactivate this user')
.gl-card-body
= render partial: 'admin/users/user_activation_effects'
%br
@@ -163,7 +166,7 @@
- elsif @user.can_be_deactivated?
.gl-card.border-warning.gl-mb-5
.gl-card-header.bg-warning.text-white
- Deactivate this user
+ = _('Deactivate this user')
.gl-card-body
= user_deactivation_effects
%br
@@ -173,36 +176,51 @@
- if @user.blocked_pending_approval?
= render 'admin/users/approve_user', user: @user
= render 'admin/users/reject_pending_user', user: @user
+ - elsif @user.banned?
+ .gl-card.border-info.gl-mb-5
+ .gl-card-header.gl-bg-blue-500.gl-text-white
+ = _('This user is banned')
+ .gl-card-body
+ %p= _('A banned user cannot:')
+ %ul
+ %li= _('Log in')
+ %li= _('Access Git repositories')
+ - link_start = '<a href="%{url}" target="_blank">'.html_safe % { url: help_page_path("user/admin_area/moderate_users", anchor: "ban-a-user") }
+ = s_('AdminUsers|Learn more about %{link_start}banned users.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ %p
+ %button.btn.gl-button.btn-info.js-confirm-modal-button{ data: user_unban_data(@user) }
+ = s_('AdminUsers|Unban user')
- else
.gl-card.border-info.gl-mb-5
.gl-card-header.gl-bg-blue-500.gl-text-white
- This user is blocked
+ = _('This user is blocked')
.gl-card-body
- %p A blocked user cannot:
+ %p= _('A blocked user cannot:')
%ul
- %li Log in
- %li Access Git repositories
+ %li= _('Log in')
+ %li= _('Access Git repositories')
%br
%button.btn.gl-button.btn-info.js-confirm-modal-button{ data: user_unblock_data(@user) }
= s_('AdminUsers|Unblock user')
- elsif !@user.internal?
= render 'admin/users/block_user', user: @user
+ = render 'admin/users/ban_user', user: @user
- if @user.access_locked?
.card.border-info.gl-mb-5
.card-header.bg-info.text-white
- This account has been locked
+ = _('This account has been locked')
.card-body
- %p This user has been temporarily locked due to excessive number of failed logins. You may manually unlock the account.
+ %p= _('This user has been temporarily locked due to excessive number of failed logins. You may manually unlock the account.')
%br
- = link_to 'Unlock user', unlock_admin_user_path(@user), method: :put, class: "btn gl-button btn-info", data: { confirm: 'Are you sure?' }
+ = link_to _('Unlock user'), unlock_admin_user_path(@user), method: :put, class: "btn gl-button btn-info", data: { confirm: _('Are you sure?') }
- if !@user.blocked_pending_approval?
.gl-card.border-danger.gl-mb-5
.gl-card-header.bg-danger.text-white
= s_('AdminUsers|Delete user')
.gl-card-body
- if @user.can_be_removed? && can?(current_user, :destroy_user, @user)
- %p Deleting a user has the following effects:
+ %p= _('Deleting a user has the following effects:')
= render 'users/deletion_guidance', user: @user
%br
%button.js-delete-user-modal-button.btn.gl-button.btn-danger{ data: { 'gl-modal-action': 'delete',
@@ -213,13 +231,13 @@
- else
- if @user.solo_owned_groups.present?
%p
- This user is currently an owner in these groups:
+ = _('This user is currently an owner in these groups:')
%strong= @user.solo_owned_groups.map(&:name).join(', ')
%p
- You must transfer ownership or delete these groups before you can delete this user.
+ = _('You must transfer ownership or delete these groups before you can delete this user.')
- else
%p
- You don't have access to delete this user.
+ = _("You don't have access to delete this user.")
.gl-card.border-danger
.gl-card-header.bg-danger.text-white
@@ -227,13 +245,8 @@
.gl-card-body
- if can?(current_user, :destroy_user, @user)
%p
- This option deletes the user and any contributions that
- would usually be moved to the
- = succeed "." do
- = link_to "system ghost user", help_page_path("user/profile/account/delete_account")
- As well as the user's personal projects, groups owned solely by
- the user, and projects in them, will also be removed. Commits
- to other projects are unaffected.
+ - link_to_ghost_user = link_to(_("system ghost user"), help_page_path("user/profile/account/delete_account"))
+ = _("This option deletes the user and any contributions that would usually be moved to the %{link_to_ghost_user}. As well as the user's personal projects, groups owned solely by the user, and projects in them, will also be removed. Commits to other projects are unaffected.").html_safe % { link_to_ghost_user: link_to_ghost_user }
%br
%button.js-delete-user-modal-button.btn.gl-button.btn-danger{ data: { 'gl-modal-action': 'delete-with-contributions',
delete_user_url: admin_user_path(@user, hard_delete: true),
@@ -242,6 +255,6 @@
= s_('AdminUsers|Delete user and contributions')
- else
%p
- You don't have access to delete this user.
+ = _("You don't have access to delete this user.")
= render partial: 'admin/users/modals'