diff options
Diffstat (limited to 'app/views')
163 files changed, 713 insertions, 677 deletions
diff --git a/app/views/admin/application_settings/_ci_cd.html.haml b/app/views/admin/application_settings/_ci_cd.html.haml index ee97a678aaa..fea116bd419 100644 --- a/app/views/admin/application_settings/_ci_cd.html.haml +++ b/app/views/admin/application_settings/_ci_cd.html.haml @@ -41,7 +41,7 @@ = f.label :default_artifacts_expire_in, _('Default artifacts expiration'), class: 'label-bold' = f.text_field :default_artifacts_expire_in, class: 'form-control gl-form-input' .form-text.text-muted - = html_escape(_("The default expiration time for job artifacts. 0 for unlimited. The default unit is in seconds, but you can use other units, for example %{code_open}4 mins 2 sec%{code_close}, %{code_open}2h42min%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe } + = html_escape(_("Set the default expiration time for job artifacts in all projects. Set to %{code_open}0%{code_close} to never expire artifacts by default. If no unit is written, it defaults to seconds. For example, these are all equivalent: %{code_open}3600%{code_close}, %{code_open}60 minutes%{code_close}, or %{code_open}one hour%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe } = link_to _('Learn more.'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'default-artifacts-expiration') .form-group .form-check diff --git a/app/views/admin/application_settings/_eks.html.haml b/app/views/admin/application_settings/_eks.html.haml index c44bad132bd..c83e28d7f0b 100644 --- a/app/views/admin/application_settings/_eks.html.haml +++ b/app/views/admin/application_settings/_eks.html.haml @@ -17,20 +17,20 @@ .form-check = f.check_box :eks_integration_enabled, class: 'form-check-input' = f.label :eks_integration_enabled, class: 'form-check-label' do - Enable Amazon EKS integration + = _('Enable Amazon EKS integration') .form-group - = f.label :eks_account_id, 'Account ID', class: 'label-bold' + = f.label :eks_account_id, _('Account ID'), class: 'label-bold' = f.text_field :eks_account_id, class: 'form-control gl-form-input' .form-group - = f.label :eks_access_key_id, 'Access key ID', class: 'label-bold' + = f.label :eks_access_key_id, _('Access key ID'), class: 'label-bold' = f.text_field :eks_access_key_id, class: 'form-control gl-form-input' .form-text.text-muted = _('AWS Access Key. Only required if not using role instance credentials') .form-group - = f.label :eks_secret_access_key, 'Secret access key', class: 'label-bold' + = f.label :eks_secret_access_key, _('Secret access key'), class: 'label-bold' = f.password_field :eks_secret_access_key, autocomplete: 'off', class: 'form-control gl-form-input' .form-text.text-muted = _('AWS Secret Access Key. Only required if not using role instance credentials') - = 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/_email.html.haml b/app/views/admin/application_settings/_email.html.haml index 1c35250644d..073c0bf619d 100644 --- a/app/views/admin/application_settings/_email.html.haml +++ b/app/views/admin/application_settings/_email.html.haml @@ -33,4 +33,12 @@ .form-text.text-muted = _('Send emails to help guide new users through the onboarding process.') + .form-group + .form-check + = f.check_box :user_deactivation_emails_enabled, class: 'form-check-input' + = f.label :user_deactivation_emails_enabled, class: 'form-check-label' do + = _('Enable user deactivation emails') + .form-text.text-muted + = _('Send emails to users upon account deactivation.') + = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/admin/application_settings/_external_authorization_service_form.html.haml b/app/views/admin/application_settings/_external_authorization_service_form.html.haml index abd182027b1..23484eaec32 100644 --- a/app/views/admin/application_settings/_external_authorization_service_form.html.haml +++ b/app/views/admin/application_settings/_external_authorization_service_form.html.haml @@ -47,4 +47,4 @@ .form-group = f.label :external_authorization_service_default_label, _('Default classification label'), class: 'label-bold' = f.text_field :external_authorization_service_default_label, class: 'form-control gl-form-input' - = 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/_files_limits.html.haml b/app/views/admin/application_settings/_files_limits.html.haml new file mode 100644 index 00000000000..9cd12fa1caa --- /dev/null +++ b/app/views/admin/application_settings/_files_limits.html.haml @@ -0,0 +1,34 @@ += 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/_floc.html.haml b/app/views/admin/application_settings/_floc.html.haml index 398064f9730..52833b5cfc2 100644 --- a/app/views/admin/application_settings/_floc.html.haml +++ b/app/views/admin/application_settings/_floc.html.haml @@ -19,4 +19,4 @@ .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' + = f.submit _('Save changes'), class: 'gl-button btn btn-confirm' diff --git a/app/views/admin/application_settings/_git_lfs_limits.html.haml b/app/views/admin/application_settings/_git_lfs_limits.html.haml new file mode 100644 index 00000000000..de5a2ceaa3d --- /dev/null +++ b/app/views/admin/application_settings/_git_lfs_limits.html.haml @@ -0,0 +1,21 @@ += form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-git-lfs-limits-settings'), html: { class: 'fieldset-form' } do |f| + = form_errors(@application_setting) + + %fieldset + %h5 + = _('Authenticated Git LFS request rate limit') + .form-group + .form-check + = f.check_box :throttle_authenticated_git_lfs_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_git_lfs_checkbox' } + = f.label :throttle_authenticated_git_lfs_enabled, class: 'form-check-label gl-font-weight-bold' do + = _('Enable authenticated Git LFS request rate limit') + %span.form-text.gl-text-gray-600 + = _('Helps reduce request volume (for example, from crawlers or abusive bots)') + .form-group + = f.label :throttle_authenticated_git_lfs_requests_per_period, _('Max authenticated Git LFS requests per period per user'), class: 'gl-font-weight-bold' + = f.number_field :throttle_authenticated_git_lfs_requests_per_period, class: 'form-control gl-form-input' + .form-group + = f.label :throttle_authenticated_git_lfs_period_in_seconds, _('Authenticated Git LFS rate limit period in seconds'), class: 'gl-font-weight-bold' + = f.number_field :throttle_authenticated_git_lfs_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/_gitpod.html.haml b/app/views/admin/application_settings/_gitpod.html.haml index c08b41e8c55..8f99a07b87c 100644 --- a/app/views/admin/application_settings/_gitpod.html.haml +++ b/app/views/admin/application_settings/_gitpod.html.haml @@ -27,4 +27,4 @@ = s_('Gitpod|The URL to your Gitpod instance configured to read your GitLab projects, such as https://gitpod.example.com.') - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('integration/gitpod', anchor: 'enable-gitpod-in-your-user-settings') } = s_('Gitpod|To use the integration, each user must also enable Gitpod on their GitLab account. %{link_start}How do I enable it?%{link_end} ').html_safe % { link_start: link_start, link_end: '</a>'.html_safe } - = f.submit s_('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/_import_export_limits.html.haml b/app/views/admin/application_settings/_import_export_limits.html.haml index 820c11279d5..bc4a1577f90 100644 --- a/app/views/admin/application_settings/_import_export_limits.html.haml +++ b/app/views/admin/application_settings/_import_export_limits.html.haml @@ -2,33 +2,37 @@ = form_errors(@application_setting) %fieldset + = html_escape(_("Set any rate limit to %{code_open}0%{code_close} to disable the limit.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe } + + + %fieldset .form-group - = f.label :project_import_limit, _('Max Project Import requests per minute per user'), class: 'label-bold' + = f.label :project_import_limit, _('Maximum project import requests per minute'), class: 'label-bold' = f.number_field :project_import_limit, class: 'form-control gl-form-input' %fieldset .form-group - = f.label :project_export_limit, _('Max Project Export requests per minute per user'), class: 'label-bold' + = f.label :project_export_limit, _('Maximum project export requests per minute'), class: 'label-bold' = f.number_field :project_export_limit, class: 'form-control gl-form-input' %fieldset .form-group - = f.label :project_download_export_limit, _('Max Project Export Download requests per minute per user'), class: 'label-bold' + = f.label :project_download_export_limit, _('Maximum project export download requests per minute'), class: 'label-bold' = f.number_field :project_download_export_limit, class: 'form-control gl-form-input' %fieldset .form-group - = f.label :group_import_limit, _('Max Group Import requests per minute per user'), class: 'label-bold' + = f.label :group_import_limit, _('Maximum group import requests per minute'), class: 'label-bold' = f.number_field :group_import_limit, class: 'form-control gl-form-input' %fieldset .form-group - = f.label :group_export_limit, _('Max Group Export requests per minute per user'), class: 'label-bold' + = f.label :group_export_limit, _('Maximum group export requests per minute'), class: 'label-bold' = f.number_field :group_export_limit, class: 'form-control gl-form-input' %fieldset .form-group - = f.label :group_download_export_limit, _('Max Group Export Download requests per minute per user'), class: 'label-bold' + = f.label :group_download_export_limit, _('Maximum group export download requests per minute'), class: 'label-bold' = f.number_field :group_download_export_limit, class: 'form-control gl-form-input' - = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } + = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } 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 34c40892467..8832bc02056 100644 --- a/app/views/admin/application_settings/_initial_branch_name.html.haml +++ b/app/views/admin/application_settings/_initial_branch_name.html.haml @@ -1,4 +1,4 @@ -= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f| += form_for @application_setting, url: repository_admin_application_settings_path(anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f| = form_errors(@application_setting) - fallback_branch_name = "<code>#{Gitlab::DefaultBranch.value}</code>" diff --git a/app/views/admin/application_settings/_ip_limits.html.haml b/app/views/admin/application_settings/_ip_limits.html.haml index e584aaf9880..4362ae9cb9b 100644 --- a/app/views/admin/application_settings/_ip_limits.html.haml +++ b/app/views/admin/application_settings/_ip_limits.html.haml @@ -1,60 +1,69 @@ -= form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-ip-limits-settings'), html: { class: 'fieldset-form' } do |f| += gitlab_ui_form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-ip-limits-settings'), html: { class: 'fieldset-form' } do |f| = form_errors(@application_setting) %fieldset - %h5 - = _('Unauthenticated request rate limit') + = _("Rate limits can help reduce request volume (like from crawlers or abusive bots).") + + %fieldset + .form-group + = f.gitlab_ui_checkbox_component :throttle_unauthenticated_api_enabled, + _("Enable unauthenticated API request rate limit"), + checkbox_options: { data: { qa_selector: 'throttle_unauthenticated_api_checkbox' } }, + label_options: { class: 'label-bold' } .form-group - .form-check - = f.check_box :throttle_unauthenticated_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_unauthenticated_checkbox' } - = f.label :throttle_unauthenticated_enabled, class: 'form-check-label label-bold' do - = _("Enable unauthenticated request rate limit") - %span.form-text.text-muted - = _("Helps reduce request volume (e.g. from crawlers or abusive bots)") + = f.label :throttle_unauthenticated_api_requests_per_period, _('Maximum unauthenticated API requests per rate limit period per IP'), class: 'label-bold' + = f.number_field :throttle_unauthenticated_api_requests_per_period, class: 'form-control gl-form-input' .form-group - = f.label :throttle_unauthenticated_requests_per_period, _('Max unauthenticated requests per period per IP'), class: 'label-bold' + = f.label :throttle_unauthenticated_api_period_in_seconds, _('Unauthenticated API rate limit period in seconds'), class: 'label-bold' + = f.number_field :throttle_unauthenticated_api_period_in_seconds, class: 'form-control gl-form-input' + + %fieldset + .form-group + = f.gitlab_ui_checkbox_component :throttle_unauthenticated_enabled, + _("Enable unauthenticated web request rate limit"), + checkbox_options: { data: { qa_selector: 'throttle_unauthenticated_web_checkbox' } }, + label_options: { class: 'label-bold' } + .form-group + = f.label :throttle_unauthenticated_requests_per_period, _('Maximum unauthenticated web requests per rate limit period per IP'), class: 'label-bold' = f.number_field :throttle_unauthenticated_requests_per_period, class: 'form-control gl-form-input' .form-group - = f.label :throttle_unauthenticated_period_in_seconds, _('Unauthenticated rate limit period in seconds'), class: 'label-bold' + = f.label :throttle_unauthenticated_period_in_seconds, _('Unauthenticated web rate limit period in seconds'), class: 'label-bold' = f.number_field :throttle_unauthenticated_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_api_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_api_checkbox' } - = f.label :throttle_authenticated_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_api_requests_per_period, _('Max authenticated API requests per period per user'), class: 'label-bold' + + %fieldset + .form-group + = f.gitlab_ui_checkbox_component :throttle_authenticated_api_enabled, + _("Enable authenticated API request rate limit"), + checkbox_options: { data: { qa_selector: 'throttle_authenticated_api_checkbox' }}, + label_options: { class: 'label-bold' } + .form-group + = f.label :throttle_authenticated_api_requests_per_period, _('Maximum authenticated API requests per rate limit period per user'), class: 'label-bold' = f.number_field :throttle_authenticated_api_requests_per_period, class: 'form-control gl-form-input' .form-group = f.label :throttle_authenticated_api_period_in_seconds, _('Authenticated API rate limit period in seconds'), class: 'label-bold' = f.number_field :throttle_authenticated_api_period_in_seconds, class: 'form-control gl-form-input' - %hr - %h5 - = _('Authenticated web request rate limit') - .form-group - .form-check - = f.check_box :throttle_authenticated_web_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_web_checkbox' } - = f.label :throttle_authenticated_web_enabled, class: 'form-check-label label-bold' do - Enable authenticated web 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_web_requests_per_period, _('Max authenticated web requests per period per user'), class: 'label-bold' + + %fieldset + .form-group + = f.gitlab_ui_checkbox_component :throttle_authenticated_web_enabled, + _("Enable authenticated web request rate limit"), + checkbox_options: { data: { qa_selector: 'throttle_authenticated_web_checkbox' } }, + label_options: { class: 'label-bold' } + .form-group + = f.label :throttle_authenticated_web_requests_per_period, _('Maximum authenticated web requests per rate limit period per user'), class: 'label-bold' = f.number_field :throttle_authenticated_web_requests_per_period, class: 'form-control gl-form-input' .form-group = f.label :throttle_authenticated_web_period_in_seconds, _('Authenticated web rate limit period in seconds'), class: 'label-bold' = f.number_field :throttle_authenticated_web_period_in_seconds, class: 'form-control gl-form-input' - %hr - %h5 + + %fieldset + %legend.h5.gl-border-none = _('Response text') .form-group = f.label :rate_limiting_response_text, class: 'label-bold' do - = _('A plain-text response to show to clients that hit the rate limit.') + = _('Plain-text response to send to clients that hit a rate limit') = f.text_area :rate_limiting_response_text, placeholder: ::Gitlab::Throttle::DEFAULT_RATE_LIMITING_RESPONSE_TEXT, class: 'form-control gl-form-input', rows: 5 + .form-text.text-muted + = html_escape(_("If blank, defaults to %{code_open}Retry later%{code_close}.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe } = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/admin/application_settings/_issue_limits.html.haml b/app/views/admin/application_settings/_issue_limits.html.haml index 0e1ba8c9c88..663e1485749 100644 --- a/app/views/admin/application_settings/_issue_limits.html.haml +++ b/app/views/admin/application_settings/_issue_limits.html.haml @@ -6,4 +6,4 @@ = f.label :issues_create_limit, 'Max requests per minute per user', class: 'label-bold' = f.number_field :issues_create_limit, class: 'form-control gl-form-input' - = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } + = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/admin/application_settings/_mailgun.html.haml b/app/views/admin/application_settings/_mailgun.html.haml index 6204f7df5dc..40b4d5cac6d 100644 --- a/app/views/admin/application_settings/_mailgun.html.haml +++ b/app/views/admin/application_settings/_mailgun.html.haml @@ -1,5 +1,3 @@ -- return unless Feature.enabled?(:mailgun_events_receiver) - - expanded = integration_expanded?('mailgun_') %section.settings.as-mailgun.no-animate#js-mailgun-settings{ class: ('expanded' if expanded) } .settings-header diff --git a/app/views/admin/application_settings/_note_limits.html.haml b/app/views/admin/application_settings/_note_limits.html.haml index d50b3395d8f..eb6122f244a 100644 --- a/app/views/admin/application_settings/_note_limits.html.haml +++ b/app/views/admin/application_settings/_note_limits.html.haml @@ -3,10 +3,13 @@ %fieldset .form-group - = f.label :notes_create_limit, _('Max requests per minute per user'), class: 'label-bold' + = f.label :notes_create_limit, _('Maximum requests per minute'), class: 'label-bold' = f.number_field :notes_create_limit, class: 'form-control gl-form-input' .form-group - = f.label :notes_create_limit_allowlist, _('List of users to be excluded from the limit'), class: 'label-bold' + = f.label :notes_create_limit_allowlist, _('Users to exclude from the rate limit'), class: 'label-bold' = f.text_area :notes_create_limit_allowlist_raw, placeholder: 'username1, username2', class: 'form-control gl-form-input', rows: 5 + .form-text.text-muted + = _('Comma-separated list of users allowed to exceed the rate limit.') + = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/admin/application_settings/_outbound.html.haml b/app/views/admin/application_settings/_outbound.html.haml index d8d105293a1..142a3fbfbd0 100644 --- a/app/views/admin/application_settings/_outbound.html.haml +++ b/app/views/admin/application_settings/_outbound.html.haml @@ -27,4 +27,4 @@ %span.form-text.text-muted = _('Resolves IP addresses once and uses them to submit requests') - = f.submit 'Save changes', class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } + = 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 index b1dfd04c55e..8769171c9e0 100644 --- a/app/views/admin/application_settings/_package_registry_limits.html.haml +++ b/app/views/admin/application_settings/_package_registry_limits.html.haml @@ -2,36 +2,31 @@ = form_errors(@application_setting) %fieldset - %h5 - = _('Unauthenticated API request rate limit') + = _("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') - %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.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.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.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.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' } + = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/admin/application_settings/_protected_paths.html.haml b/app/views/admin/application_settings/_protected_paths.html.haml index faa675f211d..04b42f42014 100644 --- a/app/views/admin/application_settings/_protected_paths.html.haml +++ b/app/views/admin/application_settings/_protected_paths.html.haml @@ -28,4 +28,4 @@ = _('All paths are relative to the GitLab URL. Do not include %{relative_url_link_start}relative URL%{relative_url_link_end}.').html_safe % { relative_url_link_start: relative_url_link_start, relative_url_link_end: '</a>'.html_safe } = f.text_area :protected_paths_raw, placeholder: '/users/sign_in,/users/password', class: 'form-control gl-form-input', rows: 10 - = 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/_sidekiq_job_limits.html.haml b/app/views/admin/application_settings/_sidekiq_job_limits.html.haml new file mode 100644 index 00000000000..eaf4bbf4702 --- /dev/null +++ b/app/views/admin/application_settings/_sidekiq_job_limits.html.haml @@ -0,0 +1,21 @@ += form_for @application_setting, url: preferences_admin_application_settings_path(anchor: 'js-sidekiq-job-limits-settings'), html: { class: 'fieldset-form' } do |f| + = form_errors(@application_setting) + + %fieldset + .form-group + = f.label :sidekiq_job_limiter_mode, _('Limiting mode'), class: 'label-bold' + = f.select :sidekiq_job_limiter_mode, sidekiq_job_limiter_modes_for_select, {}, class: 'form-control' + .form-text.text-muted + = sidekiq_job_limiter_mode_help_text + .form-group + = f.label :sidekiq_job_limiter_compression_threshold_bytes, _('Sidekiq job compression threshold (bytes)'), class: 'label-bold' + = f.number_field :sidekiq_job_limiter_compression_threshold_bytes, class: 'form-control gl-form-input' + .form-text.text-muted + = _('Threshold in bytes at which to compress Sidekiq job arguments.') + .form-group + = f.label :sidekiq_job_limiter_limit_bytes, _('Sidekiq job size limit (bytes)'), class: 'label-bold' + = f.number_field :sidekiq_job_limiter_limit_bytes, class: 'form-control gl-form-input' + .form-text.text-muted + = _("Threshold in bytes at which to reject Sidekiq jobs. Set this to 0 to if you don't want to limit Sidekiq jobs.") + + = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml index 0e9dcb23dcb..8dff2bc36cb 100644 --- a/app/views/admin/application_settings/network.html.haml +++ b/app/views/admin/application_settings/network.html.haml @@ -16,24 +16,49 @@ %section.settings.as-ip-limits.no-animate#js-ip-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'ip_limits_content' } } .settings-header %h4 - = _('User and IP Rate Limits') + = _('User and IP rate limits') %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Configure limits for web and API requests.') + = _('Set limits for web and API requests.') + = link_to _('Learn more.'), help_page_path('user/admin_area/settings/user_and_ip_rate_limits.md'), target: '_blank', rel: 'noopener noreferrer' .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') + = _('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.') + = _('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' +- 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' } } + .settings-header + %h4 + = _('Files API Rate Limits') + %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Configure specific limits for Files API requests that supersede the general user and IP rate limits.') + .settings-content + = render 'files_limits' + +%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 + %h4 + = _('Git LFS Rate Limits') + %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Configure specific limits for Git LFS requests that supersede the general user and IP rate limits.') + = link_to _('Learn more.'), help_page_path('user/admin_area/settings/git_lfs_rate_limits.md'), target: '_blank', rel: 'noopener noreferrer' + .settings-content + = render 'git_lfs_limits' %section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'outbound_requests_content' } } .settings-header @@ -76,22 +101,24 @@ %section.settings.as-note-limits.no-animate#js-note-limits-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 - = _('Notes Rate Limits') + = _('Notes rate limit') %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Configure limit for notes created per minute by web and API requests.') + = _('Set the per-user rate limit for notes created by web or API requests.') + = link_to _('Learn more.'), help_page_path('user/admin_area/settings/rate_limit_on_notes_creation.md'), target: '_blank', rel: 'noopener noreferrer' .settings-content = render 'note_limits' %section.settings.as-import-export-limits.no-animate#js-import-export-limits-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 - = _('Import/Export Rate Limits') + = _('Import and export rate limits') %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Configure limits for Project/Group Import/Export.') + = _('Set per-user rate limits for imports and exports of projects and groups.') + = link_to _('Learn more.'), help_page_path('user/admin_area/settings/import_export_rate_limits.md'), target: '_blank', rel: 'noopener noreferrer' .settings-content = render 'import_export_limits' diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml index 9711c335802..af4bfd28a01 100644 --- a/app/views/admin/application_settings/preferences.html.haml +++ b/app/views/admin/application_settings/preferences.html.haml @@ -82,3 +82,17 @@ = _('Configure the default first day of the week and time tracking units.') .settings-content = render 'localization' + +%section.settings.as-sidekiq-job-limits.no-animate#js-sidekiq-job-limits-settings{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Sidekiq job size limits') + %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Limit the size of Sidekiq jobs stored in Redis.') + %span + = link_to _('Learn more.'), help_page_path('user/admin_area/settings/sidekiq_job_limits.md'), target: '_blank', rel: 'noopener noreferrer' + + .settings-content + = render 'sidekiq_job_limits' diff --git a/app/views/admin/applications/_form.html.haml b/app/views/admin/applications/_form.html.haml index 74eda21d5bd..a1990ad5750 100644 --- a/app/views/admin/applications/_form.html.haml +++ b/app/views/admin/applications/_form.html.haml @@ -33,6 +33,14 @@ %span.form-text.text-muted = _('The application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.') + = content_tag :div, class: 'form-group row' do + .col-sm-2.col-form-label.pt-0 + = f.label :expire_access_tokens + .col-sm-10 + = f.check_box :expire_access_tokens + %span.form-text.text-muted + = _('Access tokens expire after 2 hours. A refresh token may be used at any time to generate a new access token. Non-expiring access tokens are deprecated. Clear this setting to enable backward compatibility.') + .form-group.row .col-sm-2.col-form-label.pt-0 = f.label :scopes diff --git a/app/views/admin/applications/edit.html.haml b/app/views/admin/applications/edit.html.haml index 4f737a14e12..42f7f6c3d66 100644 --- a/app/views/admin/applications/edit.html.haml +++ b/app/views/admin/applications/edit.html.haml @@ -2,6 +2,7 @@ - breadcrumb_title @application.name - page_title _("Edit"), @application.name, _("Applications") -%h3.page-title Edit application +%h3.page-title + = _('Edit application') - @url = admin_application_path(@application) = render 'form', application: @application diff --git a/app/views/admin/background_migrations/_migration.html.haml b/app/views/admin/background_migrations/_migration.html.haml index ddb2eb27705..4a7c0083bc7 100644 --- a/app/views/admin/background_migrations/_migration.html.haml +++ b/app/views/admin/background_migrations/_migration.html.haml @@ -17,3 +17,7 @@ = button_to resume_admin_background_migration_path(migration), class: 'gl-button btn btn-icon has-tooltip', title: _('Resume'), 'aria-label' => _('Resume') do = sprite_icon('play', css_class: 'gl-button-icon gl-icon') + - elsif migration.failed? + = button_to retry_admin_background_migration_path(migration), + class: 'gl-button btn btn-icon has-tooltip', title: _('Retry'), 'aria-label' => _('Retry') do + = sprite_icon('retry', css_class: 'gl-button-icon gl-icon') diff --git a/app/views/admin/deploy_keys/new.html.haml b/app/views/admin/deploy_keys/new.html.haml index b0b12a01aed..fe2bc8530f7 100644 --- a/app/views/admin/deploy_keys/new.html.haml +++ b/app/views/admin/deploy_keys/new.html.haml @@ -7,4 +7,4 @@ = render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key } .form-actions = 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' + = link_to _('Cancel'), admin_deploy_keys_path, class: 'btn gl-button btn-default btn-cancel' diff --git a/app/views/admin/identities/edit.html.haml b/app/views/admin/identities/edit.html.haml index fa09138c502..0fd1f2f547f 100644 --- a/app/views/admin/identities/edit.html.haml +++ b/app/views/admin/identities/edit.html.haml @@ -1,6 +1,6 @@ -- add_to_breadcrumbs "Users", admin_users_path +- add_to_breadcrumbs _('Users'), admin_users_path - add_to_breadcrumbs @user.name, admin_user_identities_path(@user) -- breadcrumb_title "Edit Identity" +- breadcrumb_title _('Edit Identity') - page_title _("Edit"), @identity.provider, _("Identities"), @user.name, _("Users") %h3.page-title = _('Edit identity for %{user_name}') % { user_name: @user.name } diff --git a/app/views/admin/identities/index.html.haml b/app/views/admin/identities/index.html.haml index d85ab476693..3b3042b5506 100644 --- a/app/views/admin/identities/index.html.haml +++ b/app/views/admin/identities/index.html.haml @@ -1,4 +1,4 @@ -- add_to_breadcrumbs "Users", admin_users_path +- add_to_breadcrumbs _('Users'), admin_users_path - breadcrumb_title @user.name - page_title _("Identities"), @user.name, _("Users") = render 'admin/users/head' diff --git a/app/views/admin/identities/new.html.haml b/app/views/admin/identities/new.html.haml index c28d22625b5..b4f37057c51 100644 --- a/app/views/admin/identities/new.html.haml +++ b/app/views/admin/identities/new.html.haml @@ -1,7 +1,7 @@ -- add_to_breadcrumbs "Users", admin_users_path +- add_to_breadcrumbs _('Users'), admin_users_path - add_to_breadcrumbs @user.name, admin_user_identities_path(@user) -- breadcrumb_title "New Identity" -- page_title _("New Identity") +- breadcrumb_title _('New Identity') +- page_title _('New Identity') %h3.page-title= _('New identity') %hr = render 'form' diff --git a/app/views/admin/impersonation_tokens/index.html.haml b/app/views/admin/impersonation_tokens/index.html.haml index 1609687fc8d..26fbba83a32 100644 --- a/app/views/admin/impersonation_tokens/index.html.haml +++ b/app/views/admin/impersonation_tokens/index.html.haml @@ -1,4 +1,4 @@ -- add_to_breadcrumbs 'Users', admin_users_path +- add_to_breadcrumbs _('Users'), admin_users_path - breadcrumb_title @user.name - page_title _('Impersonation Tokens'), @user.name, _('Users') - type = _('impersonation token') diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index 79d77790b02..5ebfd296e2b 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -1,18 +1,17 @@ - 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-links.nav.nav-tabs - - opts = params[:visibility_level].present? ? {} : { page: admin_projects_path } - = nav_link(opts) do - = link_to _('All'), admin_projects_path - - = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::PRIVATE.to_s) }) do - = link_to _('Private'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PRIVATE) - = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::INTERNAL.to_s) }) do - = link_to _('Internal'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - = nav_link(html_options: { class: active_when(params[:visibility_level] == Gitlab::VisibilityLevel::PUBLIC.to_s) }) do - = link_to _('Public'), admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + %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}" .nav-controls .search-holder diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml index 6f3c16f7abf..59523ed3a0c 100644 --- a/app/views/admin/runners/show.html.haml +++ b/app/views/admin/runners/show.html.haml @@ -4,15 +4,7 @@ - page_title "##{@runner.id} (#{@runner.short_sha})" - add_to_breadcrumbs _('Runners'), admin_runners_path -- if Feature.enabled?(:runner_detailed_view_vue_ui, current_user, default_enabled: :yaml) - #js-runner-details{ data: {runner_id: @runner.id} } -- else - %h2.page-title - = s_('Runners|Runner #%{runner_id}' % { runner_id: @runner.id }) - = render 'shared/runners/runner_type_badge', runner: @runner - = render 'shared/runners/runner_type_alert', runner: @runner - .gl-mb-6 - = render 'shared/runners/form', runner: @runner, runner_form_url: admin_runner_path(@runner), in_gitlab_com_admin_context: Gitlab.com? +#js-runner-details{ data: {runner_id: @runner.id} } .row .col-md-6 @@ -35,7 +27,7 @@ %strong = project.full_name .gl-alert-actions - = link_to s_('Disable'), admin_namespace_project_runner_project_path(project.namespace, project, runner_project), method: :delete, class: 'btn gl-alert-action btn-confirm btn-md gl-button' + = link_to _('Disable'), admin_namespace_project_runner_project_path(project.namespace, project, runner_project), method: :delete, class: 'btn gl-alert-action btn-confirm btn-md gl-button' %table.table{ data: { testid: 'unassigned-projects' } } %thead @@ -60,7 +52,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', data: { confirm: (s_('Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?') if @runner.instance_type?) } = paginate_without_count @projects .col-md-6 diff --git a/app/views/ci/group_variables/_variable_header.html.haml b/app/views/ci/group_variables/_variable_header.html.haml index 75a432e7f7c..5ef9dc96691 100644 --- a/app/views/ci/group_variables/_variable_header.html.haml +++ b/app/views/ci/group_variables/_variable_header.html.haml @@ -1,7 +1,7 @@ %tr %th - = s_('Key') + = _('Key') %th - = s_('Environments') + = _('Environments') %th - = s_('Group') + = _('Group') diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml index cdfc174ebf1..f289e6a3386 100644 --- a/app/views/ci/variables/_index.html.haml +++ b/app/views/ci/variables/_index.html.haml @@ -16,7 +16,7 @@ aws_tip_deploy_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'deploy-your-application-to-the-aws-elastic-container-service-ecs'), aws_tip_commands_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'run-aws-commands-from-gitlab-cicd'), aws_tip_learn_link: help_page_path('ci/cloud_deployment/index.md', anchor: 'aws'), - contains_variable_reference_link: help_page_path('ci/variables/index', anchor: 'use-variables-or-in-other-variables'), + contains_variable_reference_link: help_page_path('ci/variables/index', anchor: 'use-variables-in-other-variables'), protected_environment_variables_link: help_page_path('ci/variables/index', anchor: 'protect-a-cicd-variable'), masked_environment_variables_link: help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'), } } diff --git a/app/views/devise/mailer/unlock_instructions.html.haml b/app/views/devise/mailer/unlock_instructions.html.haml index 0c05ee4a6cd..a8f1d89f21e 100644 --- a/app/views/devise/mailer/unlock_instructions.html.haml +++ b/app/views/devise/mailer/unlock_instructions.html.haml @@ -1,6 +1,8 @@ #content = email_default_heading(_("Hello, %{name}!") % { name: @resource.name }) %p - = _("Your GitLab account has been locked due to an excessive amount of unsuccessful sign in attempts. Your account will automatically unlock in %{duration} or you may click the link below to unlock now.") % { duration: distance_of_time_in_words(Devise.unlock_in) } + = _("Your GitLab account has been locked due to an excessive number of unsuccessful sign in attempts. You can wait for your account to automatically unlock in %{duration} or you can click the link below to unlock now.") % { duration: distance_of_time_in_words(Devise.unlock_in) } #cta = link_to(_('Unlock account'), unlock_url(@resource, unlock_token: @token)) + %p + = _('If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account.') diff --git a/app/views/devise/mailer/unlock_instructions.text.erb b/app/views/devise/mailer/unlock_instructions.text.erb index 9b1e2166cee..d58bb8facc3 100644 --- a/app/views/devise/mailer/unlock_instructions.text.erb +++ b/app/views/devise/mailer/unlock_instructions.text.erb @@ -1,5 +1,7 @@ <%= _('Hello, %{name}!') % { name: @resource.name } %> -<%= _("Your GitLab account has been locked due to an excessive amount of unsuccessful sign in attempts. Your account will automatically unlock in %{duration} or you may click the link below to unlock now.") % { duration: distance_of_time_in_words(Devise.unlock_in) } %> +<%= _("Your GitLab account has been locked due to an excessive number of unsuccessful sign in attempts. You can wait for your account to automatically unlock in %{duration} or you can click the link below to unlock now.") % { duration: distance_of_time_in_words(Devise.unlock_in) } %> <%= unlock_url(@resource, unlock_token: @token) %> + +<%= _('If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account.') %> diff --git a/app/views/devise/shared/_footer.html.haml b/app/views/devise/shared/_footer.html.haml index ca1adb48543..5803107a8f7 100644 --- a/app/views/devise/shared/_footer.html.haml +++ b/app/views/devise/shared/_footer.html.haml @@ -4,5 +4,5 @@ - unless public_visibility_restricted? = link_to _("Explore"), explore_root_path = link_to _("Help"), help_path - = link_to _("About GitLab"), "https://about.gitlab.com/" + = link_to _("About GitLab"), "https://#{ApplicationHelper.promo_host}" = footer_message diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml index 8b54b735205..1752a43b032 100644 --- a/app/views/devise/shared/_omniauth_box.html.haml +++ b/app/views/devise/shared/_omniauth_box.html.haml @@ -7,10 +7,10 @@ .d-flex.justify-content-between.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)}" do + = 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 - if has_icon = provider_image_tag(provider) - %span + %span.gl-button-text = label_for_provider(provider) - unless hide_remember_me %fieldset.remember-me diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml index a313ad7d23c..f9649875538 100644 --- a/app/views/devise/shared/_signup_box.html.haml +++ b/app/views/devise/shared/_signup_box.html.haml @@ -57,6 +57,7 @@ pattern: ".{#{@minimum_password_length},}", title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length } %p.gl-field-hint.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length } + = render_if_exists 'devise/shared/phone_verification', form: f %div - if show_recaptcha_sign_up? = recaptcha_tags nonce: content_security_policy_nonce diff --git a/app/views/devise/shared/_tabs_normal.html.haml b/app/views/devise/shared/_tabs_normal.html.haml index a2d5a8be625..01dd3748887 100644 --- a/app/views/devise/shared/_tabs_normal.html.haml +++ b/app/views/devise/shared/_tabs_normal.html.haml @@ -6,4 +6,4 @@ %a.nav-link.active{ href: '#login-pane', data: { toggle: 'tab', qa_selector: 'sign_in_tab' }, role: 'tab' }= tab_title - if render_signup_link && allow_signup? %li.nav-item{ role: 'presentation' } - %a.nav-link{ href: '#register-pane', data: { track_label: 'sign_in_register', track_property: '', track_event: 'click_button', track_value: '', toggle: 'tab', qa_selector: 'register_tab' }, role: 'tab' } Register + %a.nav-link{ href: '#register-pane', data: { track_label: 'sign_in_register', track_property: '', track_action: 'click_button', track_value: '', toggle: 'tab', qa_selector: 'register_tab' }, role: 'tab' } Register diff --git a/app/views/errors/access_denied.html.haml b/app/views/errors/access_denied.html.haml index ce921060cab..e368ee1a75a 100644 --- a/app/views/errors/access_denied.html.haml +++ b/app/views/errors/access_denied.html.haml @@ -12,5 +12,5 @@ = s_('403|Please contact your GitLab administrator to get permission.') .action-container.js-go-back{ hidden: true } %button{ type: 'button', class: 'gl-button btn btn-success' } - = s_('Go Back') + = _('Go Back') = render "errors/footer" diff --git a/app/views/groups/_group_admin_settings.html.haml b/app/views/groups/_group_admin_settings.html.haml index 0c3eff85f16..ea191449fe3 100644 --- a/app/views/groups/_group_admin_settings.html.haml +++ b/app/views/groups/_group_admin_settings.html.haml @@ -30,8 +30,8 @@ = f.check_box :require_two_factor_authentication, class: 'form-check-input' = f.label :require_two_factor_authentication, class: 'form-check-label' do %strong - = _("Require all users in this group to setup Two-factor authentication") - = link_to sprite_icon('question-o'), help_page_path('security/two_factor_authentication', anchor: 'enforcing-2fa-for-all-users-in-a-group') + = _("Require all users in this group to set up two-factor authentication") + = link_to sprite_icon('question-o'), help_page_path('security/two_factor_authentication', anchor: 'enforce-2fa-for-all-users-in-a-group') .form-group.row .offset-sm-2.col-sm-10 .form-check diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml index b7c2b4d86b2..0352f366f5d 100644 --- a/app/views/groups/_home_panel.html.haml +++ b/app/views/groups/_home_panel.html.haml @@ -13,18 +13,18 @@ = @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.d-flex.align-items-center.text-secondary + .home-panel-metadata.text-secondary %span = _("Group ID: %{group_id}") % { group_id: @group.id } - if current_user - %span.access-request-links.gl-ml-3 + %span.gl-ml-3 = render 'shared/members/access_request_links', source: @group .home-panel-buttons.col-md-12.col-lg-6 - if current_user .gl-display-flex.gl-flex-wrap.gl-lg-justify-content-end.gl-mx-n2{ data: { testid: 'group-buttons' } } - if current_user.admin? - = link_to [:admin, @group], class: 'btn btn-default gl-button btn-icon gl-mt-3 gl-mr-2', title: s_('View group in admin area'), + = link_to [:admin, @group], class: 'btn btn-default gl-button btn-icon gl-mt-3 gl-mr-2', title: _('View group in admin area'), data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon('admin') - if @notification_setting diff --git a/app/views/groups/_new_group_fields.html.haml b/app/views/groups/_new_group_fields.html.haml index 49c8c2700ce..8ee7c91a938 100644 --- a/app/views/groups/_new_group_fields.html.haml +++ b/app/views/groups/_new_group_fields.html.haml @@ -13,7 +13,10 @@ - if Gitlab.config.mattermost.enabled .row = render 'create_chat_team', f: f -.row + += render 'personalize', f: f + +.row.js-invite-members-section .col-sm-4 = render_if_exists 'shared/groups/invite_members' diff --git a/app/views/groups/_personalize.html.haml b/app/views/groups/_personalize.html.haml new file mode 100644 index 00000000000..5ecb0017cd8 --- /dev/null +++ b/app/views/groups/_personalize.html.haml @@ -0,0 +1,27 @@ +.row + .form-group.col-sm-12.gl-mb-0 + %label.label-bold + = _('Now, personalize your GitLab experience') + %p + = _("We'll use this to help surface the right features and information to you.") + +.row + .form-group.col-sm-4 + = label :user, :role, _('Role') + = select :user, :role, ::User.roles.keys.map { |role| [role.titleize, role] }, { selected: @current_user.role }, class: 'form-control' + +.row + .form-group.col-sm-4 + = f.label :setup_for_company, _('Who will be using this group?') + .gl-display-flex.gl-flex-direction-column.gl-lg-flex-direction-row + .gl-flex-grow-1.gl-display-flex.gl-align-items-center + = f.radio_button :setup_for_company, true, checked: true + = f.label :setup_for_company, _('My company or team'), class: 'gl-font-weight-normal gl-mb-0 gl-ml-2', value: 'true' + .gl-flex-grow-1.gl-display-flex.gl-align-items-center + = f.radio_button :setup_for_company, false + = f.label :setup_for_company, _('Just me'), class: 'gl-font-weight-normal gl-mb-0 gl-ml-2', value: 'false' + +.row + .form-group.col-sm-4 + = f.label :jobs_to_be_done, _("What will you use this group for?") + = f.select :jobs_to_be_done, ::NamespaceSetting.jobs_to_be_dones.keys.map { |job_to_be_done| [localized_jobs_to_be_done_choices[job_to_be_done], job_to_be_done] }, { include_blank: true }, class: 'form-control' diff --git a/app/views/groups/dependency_proxies/_url.html.haml b/app/views/groups/dependency_proxies/_url.html.haml index a8034c50ed8..9a76da63a72 100644 --- a/app/views/groups/dependency_proxies/_url.html.haml +++ b/app/views/groups/dependency_proxies/_url.html.haml @@ -1,4 +1,4 @@ -- proxy_url = group_dependency_proxy_image_prefix(@group) +- proxy_url = @group.dependency_proxy_image_prefix %h5.prepend-top-20= _('Dependency proxy image prefix') diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index fdd6962eb21..1f746484b7d 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -5,29 +5,34 @@ = content_for :meta_tags do = auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@group.name} issues") -.top-area - = render 'shared/issuable/nav', type: :issues - .nav-controls - = render 'shared/issuable/feed_buttons' +- if Feature.enabled?(:vue_issues_list, @group, default_enabled: :yaml) + .js-issues-list{ data: group_issues_list_data(@group, current_user, @issues) } + - if @can_bulk_update + = render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :issues +- else + .top-area + = render 'shared/issuable/nav', type: :issues + .nav-controls + = render 'shared/issuable/feed_buttons' - - if @can_bulk_update - = render_if_exists 'shared/issuable/bulk_update_button', type: :issues + - if @can_bulk_update + = render_if_exists 'shared/issuable/bulk_update_button', type: :issues - = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues, with_feature_enabled: 'issues', with_shared: false, include_projects_in_subgroups: true + = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues, with_feature_enabled: 'issues', with_shared: false, include_projects_in_subgroups: true -= render 'shared/issuable/search_bar', type: :issues + = render 'shared/issuable/search_bar', type: :issues -- if @can_bulk_update - = render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :issues + - if @can_bulk_update + = render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :issues -- if Feature.enabled?(:vue_issuables_list, @group) && @issues.to_a.any? - - if use_startup_call? - - add_page_startup_api_call(api_v4_groups_issues_path(id: @group.id, params: startup_call_params)) - .js-issuables-list{ data: { endpoint: expose_url(api_v4_groups_issues_path(id: @group.id)), - 'can-bulk-edit': @can_bulk_update.to_json, - 'empty-state-meta': { svg_path: image_path('illustrations/issues.svg') }, - 'sort-key': @sort, - type: 'issues', - 'scoped-labels-available': scoped_labels_available?(@group).to_json } } -- else - = render 'shared/issues', project_select_button: true + - if Feature.enabled?(:vue_issuables_list, @group) && @issues.to_a.any? + - if use_startup_call? + - add_page_startup_api_call(api_v4_groups_issues_path(id: @group.id, params: startup_call_params)) + .js-issuables-list{ data: { endpoint: expose_url(api_v4_groups_issues_path(id: @group.id)), + 'can-bulk-edit': @can_bulk_update.to_json, + 'empty-state-meta': { svg_path: image_path('illustrations/issues.svg') }, + 'sort-key': @sort, + type: 'issues', + 'scoped-labels-available': scoped_labels_available?(@group).to_json } } + - else + = render 'shared/issues', project_select_button: true diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml index 11927142ea6..0f11ca5fb8f 100644 --- a/app/views/groups/new.html.haml +++ b/app/views/groups/new.html.haml @@ -15,7 +15,7 @@ #import-group-pane.tab-pane - if import_sources_enabled? - - if Feature.enabled?(:bulk_import) + - if Feature.enabled?(:bulk_import, default_enabled: :yaml) = render 'import_group_from_another_instance_panel' .gl-mt-7.gl-border-b-solid.gl-border-gray-100.gl-border-1 = render 'import_group_from_file_panel' diff --git a/app/views/groups/runners/_runner.html.haml b/app/views/groups/runners/_runner.html.haml index 13da2292985..66ffef98553 100644 --- a/app/views/groups/runners/_runner.html.haml +++ b/app/views/groups/runners/_runner.html.haml @@ -1,6 +1,3 @@ --# Note: This file should stay aligned with: --# `app/views/admin/runners/_runner.html.haml` - .gl-responsive-table-row{ id: dom_id(runner) } .table-section.section-10.section-wrap .table-mobile-header{ role: 'rowheader' }= _('Type') diff --git a/app/views/groups/runners/index.html.haml b/app/views/groups/runners/index.html.haml index 4e7bc99b1f0..f904b34d29e 100644 --- a/app/views/groups/runners/index.html.haml +++ b/app/views/groups/runners/index.html.haml @@ -3,4 +3,4 @@ %h2.page-title = s_('Runners|Group Runners') -#js-group-runners{ data: { registration_token: @group.runners_token, group_id: @group.id } } +#js-group-runners{ data: group_runners_data_attributes(@group).merge( { group_runners_limited_count: @group_runners_limited_count } ) } diff --git a/app/views/groups/settings/_membership.html.haml b/app/views/groups/settings/_membership.html.haml new file mode 100644 index 00000000000..b05a294e864 --- /dev/null +++ b/app/views/groups/settings/_membership.html.haml @@ -0,0 +1,6 @@ +%h5= _('Membership') + +.form-group + = render 'shared/allow_request_access', form: f + += render_if_exists 'groups/member_lock_setting', f: f, group: @group diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml index 683e70248b6..8f428909e60 100644 --- a/app/views/groups/settings/_permissions.html.haml +++ b/app/views/groups/settings/_permissions.html.haml @@ -4,9 +4,6 @@ %fieldset %h5= _('Permissions') - .form-group - = render 'shared/allow_request_access', form: f - - if @group.root? .form-group.gl-mb-3 = f.gitlab_ui_checkbox_component :prevent_sharing_groups_outside_hierarchy, @@ -43,5 +40,5 @@ = render_if_exists 'groups/settings/prevent_forking', f: f, group: @group = render 'groups/settings/two_factor_auth', f: f, group: @group = render_if_exists 'groups/personal_access_token_expiration_policy', f: f, group: @group - = render_if_exists 'groups/member_lock_setting', f: f, group: @group + = render 'groups/settings/membership', f: f, group: @group = f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mt-3 js-dirty-submit', data: { qa_selector: 'save_permissions_changes_button' } diff --git a/app/views/groups/settings/_two_factor_auth.html.haml b/app/views/groups/settings/_two_factor_auth.html.haml index 9e5eeee2e2a..8204cafcb44 100644 --- a/app/views/groups/settings/_two_factor_auth.html.haml +++ b/app/views/groups/settings/_two_factor_auth.html.haml @@ -1,5 +1,5 @@ - return unless group.parent_allows_two_factor_authentication? -- docs_link_url = help_page_path('security/two_factor_authentication', anchor: 'enforcing-2fa-for-all-users-in-a-group') +- docs_link_url = help_page_path('security/two_factor_authentication', anchor: 'enforce-2fa-for-all-users-in-a-group') - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url } %h5= _('Two-factor authentication') diff --git a/app/views/groups/settings/ci_cd/show.html.haml b/app/views/groups/settings/ci_cd/show.html.haml index 018dd4c424d..331cb31c626 100644 --- a/app/views/groups/settings/ci_cd/show.html.haml +++ b/app/views/groups/settings/ci_cd/show.html.haml @@ -9,7 +9,7 @@ - if can?(current_user, :update_max_artifacts_size, @group) %section.settings#js-general-pipeline-settings.no-animate{ class: ('expanded' if general_expanded) } .settings-header - %h4 + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only = _("General pipelines") %button.btn.gl-button.js-settings-toggle{ type: 'button' } = expanded ? _('Collapse') : _('Expand') @@ -26,7 +26,7 @@ %section.settings#runners-settings.no-animate{ class: ('expanded' if expanded) } .settings-header - %h4 + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only = _('Runners') %button.btn.gl-button.btn-default.js-settings-toggle{ type: "button" } = expanded ? _('Collapse') : _('Expand') @@ -38,7 +38,7 @@ %section.settings#auto-devops-settings.no-animate{ class: ('expanded' if expanded) } .settings-header - %h4 + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only = _('Auto DevOps') %button.btn.gl-button.btn-default.js-settings-toggle{ type: "button" } = expanded ? _('Collapse') : _('Expand') diff --git a/app/views/groups/settings/repository/_initial_branch_name.html.haml b/app/views/groups/settings/repository/_initial_branch_name.html.haml index 5299c38576d..15a3bacf12d 100644 --- a/app/views/groups/settings/repository/_initial_branch_name.html.haml +++ b/app/views/groups/settings/repository/_initial_branch_name.html.haml @@ -1,6 +1,6 @@ %section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) } .settings-header - %h4 + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only = _('Default initial branch name') %button.gl-button.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 76850f0a884..2e74d983397 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -12,9 +12,11 @@ = content_for :group_invite_members_banner do .container-fluid.container-limited{ class: "gl-pb-2! gl-pt-6! #{@content_class}" } .js-group-invite-members-banner{ data: { svg_path: image_path('illustrations/merge_requests.svg'), - is_dismissed_key: "invite_#{@group.id}_#{current_user.id}", track_label: 'invite_members_banner', - invite_members_path: group_group_members_path(@group) } } + invite_members_path: group_group_members_path(@group), + callouts_path: group_callouts_path, + callouts_feature_id: UserCalloutsHelper::INVITE_MEMBERS_BANNER, + group_id: @group.id } } = render 'groups/invite_members_modal', group: @group = content_for :meta_tags do diff --git a/app/views/help/instance_configuration.html.haml b/app/views/help/instance_configuration.html.haml index 88c531535b4..411a81cb976 100644 --- a/app/views/help/instance_configuration.html.haml +++ b/app/views/help/instance_configuration.html.haml @@ -7,7 +7,7 @@ = render 'help/instance_configuration/ssh_info' = render 'help/instance_configuration/gitlab_pages' - = render 'help/instance_configuration/gitlab_ci' + = render 'help/instance_configuration/size_limits' = render 'help/instance_configuration/package_registry' = render 'help/instance_configuration/rate_limits' %p diff --git a/app/views/help/instance_configuration/_gitlab_ci.html.haml b/app/views/help/instance_configuration/_gitlab_ci.html.haml deleted file mode 100644 index 53fa3f89873..00000000000 --- a/app/views/help/instance_configuration/_gitlab_ci.html.haml +++ /dev/null @@ -1,24 +0,0 @@ -- content_for :table_content do - %li= link_to _('GitLab CI'), '#gitlab-ci' - -- content_for :settings_content do - %h2#gitlab-ci - = _('GitLab CI') - - %p - = _('Below are the current settings regarding') - = succeed('.') { link_to(_('GitLab CI'), 'https://about.gitlab.com/gitlab-ci', target: '_blank') } - - .table-responsive - %table - %thead - %tr - %th= _('Setting') - %th= instance_configuration_host(@instance_configuration.settings[:host]) - %th= _('Default') - %tbody - %tr - - artifacts_size = @instance_configuration.settings[:gitlab_ci][:artifacts_max_size] - %td= _('Artifacts maximum size') - %td= instance_configuration_human_size_cell(artifacts_size[:value]) - %td= instance_configuration_human_size_cell(artifacts_size[:default]) diff --git a/app/views/help/instance_configuration/_gitlab_pages.html.haml b/app/views/help/instance_configuration/_gitlab_pages.html.haml index 55f043214f6..51835c202d6 100644 --- a/app/views/help/instance_configuration/_gitlab_pages.html.haml +++ b/app/views/help/instance_configuration/_gitlab_pages.html.haml @@ -28,8 +28,3 @@ %td= _('Port') %td %code= instance_configuration_cell_html(gitlab_pages[:port]) - %br - - %p - - link_to_gitlab_ci = link_to(_('GitLab CI'), '#gitlab-ci') - = _("The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}.").html_safe % { link_to_gitlab_ci: link_to_gitlab_ci } diff --git a/app/views/help/instance_configuration/_size_limits.html.haml b/app/views/help/instance_configuration/_size_limits.html.haml new file mode 100644 index 00000000000..b592eeed020 --- /dev/null +++ b/app/views/help/instance_configuration/_size_limits.html.haml @@ -0,0 +1,40 @@ +- size_limits = @instance_configuration.settings[:size_limits] +- content_for :table_content do + - if size_limits.present? + %li= link_to _('Size Limits'), '#size-limits' + +- content_for :settings_content do + - if size_limits.present? + %h2#size-limits + = _('Size Limits') + + %p + = _('There are several size limits in place.') + .table-responsive + %table + %thead + %tr + %th= _('Setting') + %th= instance_configuration_host(@instance_configuration.settings[:host]) + %tbody + %tr + %td= _('Maximum attachment size') + %td= instance_configuration_human_size_cell(size_limits[:max_attachment_size]) + %tr + %td= _('Maximum push size') + %td= instance_configuration_human_size_cell(size_limits[:receive_max_input_size]) + %tr + %td= _('Maximum import size') + %td= instance_configuration_human_size_cell(size_limits[:max_import_size]) + %tr + %td= _('Maximum diff patch size') + %td= instance_configuration_human_size_cell(size_limits[:diff_max_patch_bytes]) + %tr + %td= _('Maximum job artifact size') + %td= instance_configuration_human_size_cell(size_limits[:max_artifacts_size]) + %tr + %td= _('Maximum page size') + %td= instance_configuration_human_size_cell(size_limits[:max_pages_size]) + %tr + %td= _('Maximum snippet size') + %td= instance_configuration_human_size_cell(size_limits[:snippet_size_limit]) diff --git a/app/views/issues/_issue.atom.builder b/app/views/issues/_issue.atom.builder index e2ab360a3e4..d14eff22bb6 100644 --- a/app/views/issues/_issue.atom.builder +++ b/app/views/issues/_issue.atom.builder @@ -3,42 +3,7 @@ xml.entry do xml.id project_issue_url(issue.project, issue) xml.link href: project_issue_url(issue.project, issue) - xml.title truncate(issue.title, length: 80) - xml.updated issue.updated_at.xmlschema - xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon_for_user(issue.author)) - - xml.author do - xml.name issue.author_name - xml.email issue.author_public_email - end - - xml.summary issue.title - xml.description issue.description if issue.description - xml.content issue.description if issue.description - xml.milestone issue.milestone.title if issue.milestone + # using the shovel operator (xml <<) would make us lose indentation, so we do this (https://github.com/rails/rails/issues/7036) + render(partial: 'shared/issuable/issuable', object: issue, locals: { builder: xml }) xml.due_date issue.due_date if issue.due_date - - unless issue.labels.empty? - xml.labels do - issue.labels.each do |label| - xml.label label.name - end - end - end - - if issue.assignees.any? - xml.assignees do - issue.assignees.each do |assignee| - xml.assignee do - xml.name assignee.name - xml.email assignee.public_email - end - end - end - - xml.assignee do - xml.name issue.assignees.first.name - xml.email issue.assignees.first.public_email - end - end end diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index ba2d6aa79eb..ec2904245d3 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -14,7 +14,7 @@ = render "layouts/nav/classification_level_banner" = yield :flash_message = render "shared/service_ping_consent" - = render_account_recovery_regular_check + = 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/new_user_signups_cap_reached_alert" diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index 5ce275d4a43..2d186dfbd91 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -1,4 +1,4 @@ -.search.search-form{ data: { track_label: "navbar_search", track_event: "activate_form_input", track_value: "" } } +.search.search-form{ data: { track_label: "navbar_search", track_action: "activate_form_input", track_value: "" } } = form_tag search_path, method: :get, class: 'form-inline form-control' do |_f| .search-input-container .search-input-wrap diff --git a/app/views/layouts/_snowplow.html.haml b/app/views/layouts/_snowplow.html.haml index 9c0384e5faa..fc3b12acc46 100644 --- a/app/views/layouts/_snowplow.html.haml +++ b/app/views/layouts/_snowplow.html.haml @@ -7,7 +7,8 @@ };p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1; n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","#{asset_url('snowplow/sp.js')}","snowplow")); - window.snowplowOptions = #{Gitlab::Tracking.snowplow_options(@group).to_json} + window.snowplowOptions = #{Gitlab::Tracking.options(@group).to_json} gl = window.gl || {}; gl.snowplowStandardContext = #{Gitlab::Tracking::StandardContext.new.to_context.to_json.to_json} + gl.snowplowPseudonymizedPageUrl = #{masked_page_url.to_json}; diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 2f6287bdfb3..3e7155b2c0e 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -15,7 +15,7 @@ %span.logo-text.d-none.d-lg-block.gl-ml-3 = logo_text - if Gitlab.com_and_canary? - = link_to 'https://next.gitlab.com', class: 'canary-badge bg-transparent', target: :_blank, rel: :_noopener do + = link_to 'https://next.gitlab.com', class: 'canary-badge bg-transparent', data: { qa_selector: 'canary_badge_link' }, target: :_blank, rel: :_noopener do %span.gl-badge.gl-bg-green-500.gl-text-white.gl-rounded-pill.gl-font-weight-bold.gl-py-1 = _('Next') @@ -29,7 +29,15 @@ - if top_nav_show_search - search_menu_item = top_nav_search_menu_item_attrs %li.nav-item.d-none.d-lg-block.m-auto - = render 'layouts/search' unless current_controller?(:search) + - unless current_controller?(:search) + - if Feature.enabled?(:new_header_search) + #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 } } + %input{ type: "text", placeholder: _('Search or jump to...'), class: 'form-control gl-form-input' } + - else + = render 'layouts/search' %li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' } = link_to search_menu_item.fetch(:href), title: search_menu_item.fetch(:title), aria: { label: search_menu_item.fetch(:title) }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon(search_menu_item.fetch(:icon)) @@ -38,7 +46,7 @@ = link_to assigned_issues_dashboard_path, title: _('Issues'), class: 'dashboard-shortcuts-issues', aria: { label: _('Issues') }, data: { qa_selector: 'issues_shortcut_button', toggle: 'tooltip', placement: 'bottom', track_label: 'main_navigation', - track_event: 'click_issues_link', + track_action: 'click_issues_link', track_property: 'navigation', container: 'body' } do = sprite_icon('issues') @@ -52,7 +60,7 @@ toggle: "dropdown", placement: 'bottom', track_label: 'main_navigation', - track_event: 'click_merge_link', + track_action: 'click_merge_link', track_property: 'navigation', container: 'body' } do = sprite_icon('git-merge') @@ -78,7 +86,7 @@ = link_to dashboard_todos_path, title: _('To-Do List'), aria: { label: _('To-Do List') }, class: 'shortcuts-todos', data: { qa_selector: 'todos_shortcut_button', toggle: 'tooltip', placement: 'bottom', track_label: 'main_navigation', - track_event: 'click_to_do_link', + track_action: 'click_to_do_link', track_property: 'navigation', container: 'body' } do = sprite_icon('todo-done') @@ -94,7 +102,7 @@ .dropdown-menu.dropdown-menu-right = render 'layouts/header/help_dropdown' - if header_link?(:user_dropdown) - %li.nav-item.header-user.js-nav-user-dropdown.dropdown{ data: { track_label: "profile_dropdown", track_event: "click_dropdown", track_value: "", qa_selector: 'user_menu' }, class: ('mr-0' if has_impersonation_link) } + %li.nav-item.header-user.js-nav-user-dropdown.dropdown{ data: { track_label: "profile_dropdown", track_action: "click_dropdown", track_value: "", qa_selector: 'user_menu' }, class: ('mr-0' if has_impersonation_link) } = link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do = image_tag avatar_icon_for_user(current_user, 23), width: 23, height: 23, class: "header-user-avatar qa-user-avatar", alt: current_user.name = render_if_exists 'layouts/header/user_notification_dot', project: project, namespace: group diff --git a/app/views/layouts/header/_new_dropdown.html.haml b/app/views/layouts/header/_new_dropdown.html.haml index 0be87ad963c..a0b271fdafa 100644 --- a/app/views/layouts/header/_new_dropdown.html.haml +++ b/app/views/layouts/header/_new_dropdown.html.haml @@ -6,7 +6,7 @@ - return if menu_sections.empty? -%li.header-new.dropdown{ class: top_class, data: { track_label: "new_dropdown", track_event: "click_dropdown" } } +%li.header-new.dropdown{ class: top_class, data: { track_label: "new_dropdown", track_action: "click_dropdown" } } = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip", id: "js-onboarding-new-project-link", title: title, ref: 'tooltip', aria: { label: title }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static', qa_selector: 'new_menu_toggle' } do = sprite_icon('plus-square') = sprite_icon('chevron-down', css_class: 'caret-down') diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index 980730bc3be..c2b50bc0e52 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -1,3 +1 @@ --# We're migration the group sidebar to a logical model based structure. If you need to update --# any of the existing menus, you can find them in app/views/layouts/nav/sidebar/_group_menus.html.haml. = render partial: 'shared/nav/sidebar', object: Sidebars::Groups::Panel.new(group_sidebar_context(@group, current_user)) diff --git a/app/views/layouts/nav/sidebar/_group_menus.html.haml b/app/views/layouts/nav/sidebar/_group_menus.html.haml deleted file mode 100644 index 25b6c264d92..00000000000 --- a/app/views/layouts/nav/sidebar/_group_menus.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -= render_if_exists "groups/ee/administration_nav" - -= render 'shared/sidebar_toggle_button' diff --git a/app/views/notify/member_invited_email.html.haml b/app/views/notify/member_invited_email.html.haml index 843a820bd1b..5489a2ac6a1 100644 --- a/app/views/notify/member_invited_email.html.haml +++ b/app/views/notify/member_invited_email.html.haml @@ -5,7 +5,6 @@ br_tag: '<br/>'.html_safe, role: member.human_access.downcase } - join_text = s_('InviteEmail|Join now') -- join_url = invite_url(@token, invite_type: Emails::Members::INITIAL_INVITE, experiment_name: 'invite_email_preview_text') - inviter_name = member.created_by.name if member.created_by - experiment(:invite_email_preview_text, actor: member) do |experiment_instance| @@ -17,7 +16,7 @@ = s_('InviteEmail|Join your team on GitLab! %{inviter} invited you to %{project_or_group_name}') % { inviter: inviter_name, project_or_group_name: placeholders[:project_or_group_name] } - else = s_('InviteEmail|Join your team on GitLab! You are invited to %{project_or_group_name}') % { project_or_group_name: placeholders[:project_or_group_name] } - = gmail_goto_action(join_text, join_url) + = gmail_goto_action(join_text, invited_join_url(@token, member)) %tr %td.text-content{ colspan: 2 } @@ -28,7 +27,7 @@ - else = html_escape(s_("InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}")) % placeholders %p.invite-actions - = link_to join_text, join_url, class: 'invite-btn-join' + = link_to join_text, invited_join_url(@token, member), class: 'invite-btn-join' %tr.border-top %td.text-content.mailer-align-left.half-width %h4 diff --git a/app/views/profiles/_email_settings.html.haml b/app/views/profiles/_email_settings.html.haml index 6691d20c8f7..bc678c2c429 100644 --- a/app/views/profiles/_email_settings.html.haml +++ b/app/views/profiles/_email_settings.html.haml @@ -11,6 +11,6 @@ - commit_email_link_url = help_page_path('user/profile/index', anchor: 'change-the-email-displayed-on-your-commits', target: '_blank') - commit_email_link_start = '<a href="%{url}">'.html_safe % { url: commit_email_link_url } - commit_email_docs_link = s_('Profiles|This email will be used for web based operations, such as edits and merges. %{commit_email_link_start}Learn more%{commit_email_link_end}').html_safe % { commit_email_link_start: commit_email_link_start, commit_email_link_end: '</a>'.html_safe } -= form.select :commit_email, options_for_select(commit_email_select_options(@user), selected: selected_commit_email(@user)), += form.select :commit_email, options_for_select(commit_email_select_options(@user), selected: @user.commit_email), { help: commit_email_docs_link }, control_class: 'select2 input-lg', disabled: email_change_disabled diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml index c14efa99555..35bdfbb1c29 100644 --- a/app/views/profiles/emails/index.html.haml +++ b/app/views/profiles/emails/index.html.haml @@ -38,21 +38,21 @@ = render partial: 'shared/email_with_badge', locals: { email: @primary_email, verified: current_user.confirmed? } %span.float-right %span.badge.badge-muted.badge-pill.gl-badge.badge-success= s_('Profiles|Primary email') - - if @primary_email === current_user.commit_email + - if @primary_email === current_user.commit_email_or_default %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Commit email') - if @primary_email === current_user.public_email %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Public email') - - if @primary_email === current_user.notification_email + - if @primary_email === current_user.notification_email_or_default %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Default notification email') - @emails.each do |email| %li{ data: { qa_selector: 'email_row_content' } } = render partial: 'shared/email_with_badge', locals: { email: email.email, verified: email.confirmed? } %span.float-right - - if email.email === current_user.commit_email + - if email.email === current_user.commit_email_or_default %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Commit email') - if email.email === current_user.public_email %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Public email') - - if email.email === current_user.notification_email + - if email.email === current_user.notification_email_or_default %span.badge.badge-muted.badge-pill.gl-badge.badge-info= s_('Profiles|Notification email') - unless email.confirmed? - confirm_title = "#{email.confirmation_sent_at ? _('Resend confirmation email') : _('Send confirmation email')}" diff --git a/app/views/profiles/keys/show.html.haml b/app/views/profiles/keys/show.html.haml index 360de7a0c11..09c16b0c038 100644 --- a/app/views/profiles/keys/show.html.haml +++ b/app/views/profiles/keys/show.html.haml @@ -1,4 +1,4 @@ -- add_to_breadcrumbs "SSH Keys", profile_keys_path +- add_to_breadcrumbs _('SSH Keys'), profile_keys_path - breadcrumb_title @key.title - page_title @key.title, _('SSH Keys') - @content_class = "limit-container-width" unless fluid_layout diff --git a/app/views/profiles/notifications/_email_settings.html.haml b/app/views/profiles/notifications/_email_settings.html.haml index f452a5b2eb5..f2121199412 100644 --- a/app/views/profiles/notifications/_email_settings.html.haml +++ b/app/views/profiles/notifications/_email_settings.html.haml @@ -1,7 +1,7 @@ - form = local_assigns.fetch(:form) .form-group = form.label :notification_email, class: "label-bold" - = form.select :notification_email, @user.public_verified_emails, { include_blank: false }, class: "select2", disabled: local_assigns.fetch(:email_change_disabled, nil) + = form.select :notification_email, @user.public_verified_emails, { include_blank: _('Use primary email (%{email})') % { email: @user.email }, selected: @user.notification_email }, class: "select2", disabled: local_assigns.fetch(:email_change_disabled, nil) .help-block = local_assigns.fetch(:help_text, nil) .form-group diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 6eba0309a4f..0bb4859dd1e 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -99,11 +99,12 @@ = f.text_field :pronouns, class: 'input-md gl-form-input', help: s_("Profiles|Enter your pronouns to let people know how to refer to you") = f.text_field :pronunciation, class: 'input-md gl-form-input', help: s_("Profiles|Enter how your name is pronounced to help people address you correctly") + = render_if_exists 'profiles/extra_settings', form: f = render_if_exists 'profiles/email_settings', form: f = f.text_field :skype, class: 'input-md gl-form-input', placeholder: s_("Profiles|username") = f.text_field :linkedin, class: 'input-md gl-form-input', help: s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename") = f.text_field :twitter, class: 'input-md gl-form-input', placeholder: s_("Profiles|@username") - = f.text_field :website_url, class: 'input-lg gl-form-input', placeholder: s_("Profiles|website.com") + = f.text_field :website_url, class: 'input-lg gl-form-input', placeholder: s_("Profiles|https://website.com") - if @user.read_only_attribute?(:location) = f.text_field :location, class: 'gl-form-input', readonly: true, help: s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) } - else @@ -112,7 +113,7 @@ = f.text_field :organization, label: s_('Profiles|Organization'), class: 'input-md gl-form-input', help: s_("Profiles|Who you represent or work for") = f.text_area :bio, class: 'gl-form-input', label: s_('Profiles|Bio'), rows: 4, maxlength: 250, help: s_("Profiles|Tell us about yourself in fewer than 250 characters") %hr - %h5= s_("Private profile") + %h5= _('Private profile') .checkbox-icon-inline-wrapper - private_profile_label = capture do = s_("Profiles|Don't display activity-related personal information on your profiles") diff --git a/app/views/projects/_commit_button.html.haml b/app/views/projects/_commit_button.html.haml index 987ec74e4ba..2c18921d874 100644 --- a/app/views/projects/_commit_button.html.haml +++ b/app/views/projects/_commit_button.html.haml @@ -1,7 +1,7 @@ .form-actions.gl-display-flex = button_tag 'Commit changes', id: 'commit-changes', class: 'gl-button btn btn-confirm js-commit-button qa-commit-button' - = link_to 'Cancel', cancel_path, + = link_to _('Cancel'), cancel_path, class: 'gl-button btn btn-default gl-ml-3', data: {confirm: leave_edit_message} = render 'shared/projects/edit_information' diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 8909536a1ec..f2cee618849 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -15,13 +15,13 @@ %span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) } = visibility_level_icon(@project.visibility_level, options: { class: 'icon' }) = render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: @project - .home-panel-metadata.d-flex.flex-wrap.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal + .home-panel-metadata.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal - if can?(current_user, :read_project, @project) - button_class = "btn gl-button btn-sm btn-tertiary btn-default-tertiary home-panel-metadata" - button_text = s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id } = clipboard_button(title: s_('ProjectPage|Copy project ID'), text: @project.id, hide_button_icon: true, button_text: button_text, class: button_class, qa_selector: 'project_id_content', itemprop: 'identifier') - if current_user - %span.access-request-links.gl-ml-3 + %span.gl-display-inline-block.gl-vertical-align-middle.gl-ml-3 = render 'shared/members/access_request_links', source: @project .gl-mt-3.gl-pl-3.gl-w-full @@ -31,7 +31,7 @@ .project-repo-buttons.gl-display-flex.gl-justify-content-md-end.gl-align-items-start.gl-flex-wrap.gl-mt-5 - if current_user - if current_user.admin? - = link_to [:admin, @project], class: 'btn gl-button btn-icon gl-align-self-start gl-py-2! gl-mr-3', title: s_('View project in admin area'), + = link_to [:admin, @project], class: 'btn gl-button btn-icon gl-align-self-start gl-py-2! gl-mr-3', title: _('View project in admin area'), data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon('admin') .gl-display-flex.gl-align-items-start.gl-mr-3 diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml index 2055f1c7f60..815a3cf6966 100644 --- a/app/views/projects/_import_project_pane.html.haml +++ b/app/views/projects/_import_project_pane.html.haml @@ -76,7 +76,7 @@ - if phabricator_import_enabled? %div - = link_to new_import_phabricator_path, class: 'gl-button btn-default btn import_phabricator', data: { track_label: "#{track_label}", track_event: "click_button", track_property: "phabricator" } do + = link_to new_import_phabricator_path, class: 'gl-button btn-default btn import_phabricator', data: { track_label: "#{track_label}", track_action: "click_button", track_property: "phabricator" } do .gl-button-icon = custom_icon('issues') = _("Phabricator Tasks") diff --git a/app/views/projects/_invite_members_empty_project.html.haml b/app/views/projects/_invite_members_empty_project.html.haml index ee2215b0fbb..5bc53339bf0 100644 --- a/app/views/projects/_invite_members_empty_project.html.haml +++ b/app/views/projects/_invite_members_empty_project.html.haml @@ -1,6 +1,6 @@ %h4.gl-mt-0.gl-mb-3{ data: { testid: 'invite-member-section', track_label: 'invite_members_empty_project', - track_event: 'render' } } + track_action: 'render' } } = s_('InviteMember|Invite your team') %p= s_('InviteMember|Add members to this project and start collaborating with your team.') .js-invite-members-trigger{ data: { variant: 'confirm', diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml index 026c7a0d79d..fb7a7ef8985 100644 --- a/app/views/projects/_new_project_fields.html.haml +++ b/app/views/projects/_new_project_fields.html.haml @@ -8,23 +8,25 @@ .form-group.project-name.col-sm-12 = f.label :name, class: 'label-bold' do %span= _("Project name") - = f.text_field :name, placeholder: "My awesome project", class: "form-control gl-form-input input-lg", autofocus: true, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_name", track_value: "" }, required: true, aria: { required: true } + = f.text_field :name, placeholder: "My awesome project", class: "form-control gl-form-input input-lg", data: { track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_name", track_value: "" }, required: true, aria: { required: true } .form-group.project-path.col-sm-6 = f.label :namespace_id, class: 'label-bold' do - %span= s_("Project URL") + %span= _('Project URL') .input-group.gl-flex-nowrap - if current_user.can_select_namespace? - .input-group-prepend.flex-shrink-0.has-tooltip{ title: root_url } - .input-group-text - = root_url - namespace_id = namespace_id_from(params) - = f.select(:namespace_id, - namespaces_options_with_developer_maintainer_access(selected: namespace_id, - display_path: true, - extra_group: namespace_id), - {}, - { class: 'select2 js-select-namespace qa-project-namespace-select block-truncated', data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_path", track_value: "", qa_selector: "select_namespace_dropdown" }}) - + - 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 } } + - else + .input-group-prepend.flex-shrink-0.has-tooltip{ title: root_url } + .input-group-text + = root_url + = f.select(:namespace_id, + namespaces_options_with_developer_maintainer_access(selected: namespace_id, + display_path: true, + extra_group: namespace_id), + {}, + { class: 'select2 js-select-namespace qa-project-namespace-select block-truncated', data: { track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_path", track_value: "", qa_selector: "select_namespace_dropdown" }}) - else .input-group-prepend.static-namespace.flex-shrink-0.has-tooltip{ title: user_url(current_user.username) + '/' } .input-group-text.border-0 @@ -43,7 +45,7 @@ .form-group = f.label :description, class: 'label-bold' do = s_('ProjectsNew|Project description %{tag_start}(optional)%{tag_end}').html_safe % { tag_start: '<span>'.html_safe, tag_end: '</span>'.html_safe } - = f.text_area :description, placeholder: s_('ProjectsNew|Description format'), class: "form-control gl-form-input", rows: 3, maxlength: 250, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_description", track_value: "" } + = f.text_area :description, placeholder: s_('ProjectsNew|Description format'), class: "form-control gl-form-input", rows: 3, maxlength: 250, data: { track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_description", track_value: "" } = f.label :visibility_level, class: 'label-bold' do = s_('ProjectsNew|Visibility Level') @@ -54,12 +56,12 @@ .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_event: "activate_form_input", track_property: "init_with_readme", track_value: "" } + = 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.submit _('Create project'), class: "btn gl-button btn-confirm", data: { track_label: "#{track_label}", track_event: "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_event: "click_button", track_property: "cancel", track_value: "" } += 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/_new_dir.html.haml b/app/views/projects/blob/_new_dir.html.haml index 905dc2a49ec..3cc9fea56e2 100644 --- a/app/views/projects/blob/_new_dir.html.haml +++ b/app/views/projects/blob/_new_dir.html.haml @@ -16,6 +16,6 @@ .form-actions = submit_tag _("Create directory"), class: 'btn gl-button btn-confirm' - = link_to "Cancel", '#', class: "btn gl-button btn-default btn-cancel", "data-dismiss" => "modal" + = link_to _('Cancel'), '#', class: "btn gl-button btn-default btn-cancel", "data-dismiss" => "modal" = render 'shared/projects/edit_information' diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml index 298a36e28ec..1463fcf8052 100644 --- a/app/views/projects/blob/_remove.html.haml +++ b/app/views/projects/blob/_remove.html.haml @@ -13,4 +13,4 @@ .form-group.row .offset-sm-2.col-sm-10 = button_tag 'Delete file', class: 'btn gl-button btn-danger btn-remove-file' - = link_to "Cancel", '#', class: "btn gl-button btn-cancel", "data-dismiss" => "modal" + = link_to _('Cancel'), '#', class: "btn gl-button btn-cancel", "data-dismiss" => "modal" diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml index 1ba38808937..66e9badbafb 100644 --- a/app/views/projects/blob/show.html.haml +++ b/app/views/projects/blob/show.html.haml @@ -1,4 +1,4 @@ -- breadcrumb_title "Repository" +- breadcrumb_title _('Repository') - page_title @blob.path, @ref - signatures_path = namespace_project_signatures_path(namespace_id: @project.namespace.full_path, project_id: @project.path, id: @last_commit, limit: 1) - content_for :prefetch_asset_tags do diff --git a/app/views/projects/blob/viewers/_notebook.html.haml b/app/views/projects/blob/viewers/_notebook.html.haml index eb4ca1b9816..b537a48e087 100644 --- a/app/views/projects/blob/viewers/_notebook.html.haml +++ b/app/views/projects/blob/viewers/_notebook.html.haml @@ -1 +1 @@ -.file-content#js-notebook-viewer{ data: { endpoint: blob_raw_path } } +.file-content#js-notebook-viewer{ data: { endpoint: blob_raw_path, relative_raw_path: parent_dir_raw_path } } diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml index 6de50d48721..27858932e5e 100644 --- a/app/views/projects/branches/new.html.haml +++ b/app/views/projects/branches/new.html.haml @@ -9,7 +9,7 @@ .gl-alert-body = @error %h3.page-title - New Branch + = _('New Branch') %hr = form_tag namespace_project_branches_path, method: :post, id: "new-branch-form", class: "js-create-branch-form js-requires-input" do @@ -30,5 +30,5 @@ .form-text.text-muted Existing branch name, tag, or commit SHA .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' + = link_to _('Cancel'), project_branches_path(@project), class: 'gl-button btn btn-default btn-cancel' %script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml index 1a3813ba99f..437529c3608 100644 --- a/app/views/projects/ci/builds/_build.html.haml +++ b/app/views/projects/ci/builds/_build.html.haml @@ -7,10 +7,14 @@ - pipeline_link = local_assigns.fetch(:pipeline_link, false) - stage = local_assigns.fetch(:stage, false) - allow_retry = local_assigns.fetch(:allow_retry, false) +-# This prevents initializing another Ci::Status object where 'status' is used +- status = job.detailed_status(current_user) %tr.build.commit{ class: ('retried' if retried) } %td.status - = render "ci/status/badge", status: job.detailed_status(current_user), title: job.status_title + -# Sending 'status' prevents calling the user relation inside the presenter, generating N+1, + -# see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68743 + = render "ci/status/badge", status: status, title: job.status_title(status) %td - if can?(current_user, :read_build, job) diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml index 3c9762e200a..f398ac6ede7 100644 --- a/app/views/projects/cycle_analytics/show.html.haml +++ b/app/views/projects/cycle_analytics/show.html.haml @@ -1,6 +1,4 @@ - page_title _("Value Stream Analytics") - add_page_specific_style 'page_bundles/cycle_analytics' -- svgs = { empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_data_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_access_svg_path: image_path("illustrations/analytics/no-access.svg") } -- initial_data = { project_id: @project.id, group_path: @project.group&.path, request_path: project_cycle_analytics_path(@project), full_path: @project.full_path }.merge!(svgs) -#js-cycle-analytics{ data: initial_data } +#js-cycle-analytics{ data: cycle_analytics_initial_data(@project, @group) } diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml index 8edaacf7552..fe9658a440a 100644 --- a/app/views/projects/diffs/_stats.html.haml +++ b/app/views/projects/diffs/_stats.html.haml @@ -1,41 +1 @@ -- sum_added_lines = diff_files.sum(&:added_lines) -- sum_removed_lines = diff_files.sum(&:removed_lines) -.commit-stat-summary.dropdown - Showing - %button.diff-stats-summary-toggler.js-diff-stats-dropdown{ type: "button", data: { toggle: "dropdown", display: "static" } }< - = pluralize(diff_files.size, "changed file") - = sprite_icon("chevron-down", css_class: "gl-ml-2") - %span.diff-stats-additions-deletions-expanded#diff-stats - with - %strong.cgreen= pluralize(sum_added_lines, 'addition') - and - %strong.cred= pluralize(sum_removed_lines, 'deletion') - .diff-stats-additions-deletions-collapsed.float-right.d-none{ "aria-hidden": "true", "aria-describedby": "diff-stats" } - %strong.cgreen< - +#{sum_added_lines} - %strong.cred< - \-#{sum_removed_lines} - .dropdown-menu.diff-file-changes - = dropdown_filter("Search files") - .dropdown-content - %ul - - diff_files.each do |diff_file| - %li - %a.diff-changed-file{ href: "##{hexdigest(diff_file.file_path)}", title: diff_file.new_path } - = sprite_icon(diff_file_changed_icon(diff_file), css_class: "#{diff_file_changed_icon_color(diff_file)} diff-file-changed-icon gl-mr-3") - %span.diff-changed-file-content.gl-mr-3 - - if diff_file.file_path - %strong.diff-changed-file-name - = diff_file.file_path - - else - %strong.diff-changed-blank-file-name - = s_('Diffs|No file name available') - %span.diff-changed-file-path.gl-mt-2= diff_file_path_text(diff_file) - %span.diff-changed-stats - %span.cgreen< - +#{diff_file.added_lines} - %span.cred< - \-#{diff_file.removed_lines} - %li.dropdown-menu-empty-item.hidden - %a - = _("No files found.") +.js-diff-stats-dropdown{ data: { changed: diff_files.size, added: diff_files.sum(&:added_lines), deleted: diff_files.sum(&:removed_lines), files: diff_files_data(diff_files) } } diff --git a/app/views/projects/error_tracking/details.html.haml b/app/views/projects/error_tracking/details.html.haml index 4a14e34cbf1..eb26a299a66 100644 --- a/app/views/projects/error_tracking/details.html.haml +++ b/app/views/projects/error_tracking/details.html.haml @@ -1,5 +1,5 @@ - page_title _('Error Details') -- add_to_breadcrumbs 'Errors', project_error_tracking_index_path(@project) +- add_to_breadcrumbs _('Errors'), project_error_tracking_index_path(@project) - add_page_specific_style 'page_bundles/error_tracking_details' #js-error_details{ data: error_details_data(@project, @issue_id) } diff --git a/app/views/projects/hooks/edit.html.haml b/app/views/projects/hooks/edit.html.haml index 226cd7d89b6..e8ea4ad90dc 100644 --- a/app/views/projects/hooks/edit.html.haml +++ b/app/views/projects/hooks/edit.html.haml @@ -10,7 +10,7 @@ = form_for [@project, @hook], as: :hook, url: project_hook_path(@project, @hook) do |f| = render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook } - = f.submit 'Save changes', class: 'btn gl-button btn-confirm gl-mr-3' + = f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mr-3' = render 'shared/web_hooks/test_button', hook: @hook = link_to _('Delete'), project_hook_path(@project, @hook), method: :delete, class: 'btn gl-button btn-danger float-right', data: { confirm: _('Are you sure?') } diff --git a/app/views/projects/imports/new.html.haml b/app/views/projects/imports/new.html.haml index e2d8791b5d2..77c715aa376 100644 --- a/app/views/projects/imports/new.html.haml +++ b/app/views/projects/imports/new.html.haml @@ -1,6 +1,6 @@ - page_title _("Import repository") %h3.page-title - Import repository + = _('Import repository') %hr diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index ee3aaee6dbb..2de2c2cba6c 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -12,9 +12,7 @@ - if issue.confidential? %span.has-tooltip{ title: _('Confidential') } = confidential_icon(issue) - - if Feature.enabled?(:ban_user_feature_flag) && issue.hidden? - %span.has-tooltip{ title: _('This issue is hidden because its author has been banned') } - = hidden_issue_icon(issue) + = hidden_issue_icon(issue) = link_to issue.title, issue_path(issue) = render_if_exists 'projects/issues/subepic_flag', issue: issue - if issue.tasks? diff --git a/app/views/projects/issues/_nav_btns.html.haml b/app/views/projects/issues/_nav_btns.html.haml index 1289f7aa0c4..0d69f6f69aa 100644 --- a/app/views/projects/issues/_nav_btns.html.haml +++ b/app/views/projects/issues/_nav_btns.html.haml @@ -3,7 +3,7 @@ - show_export_button = local_assigns.fetch(:show_export_button, true) - issuable_type = 'issues' - can_edit = can?(current_user, :admin_project, @project) -- notification_email = @current_user.present? ? @current_user.notification_email : nil +- notification_email = @current_user.present? ? @current_user.notification_email_or_default : nil .nav-controls.issues-nav-controls - if show_feed_buttons diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index ecf10cd4821..53c2052bfab 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -13,8 +13,8 @@ issues_path: project_issues_path(@project), project_path: @project.full_path } } -- if Feature.enabled?(:vue_issues_list, @project) - .js-issues-list{ data: issues_list_data(@project, current_user, finder) } +- if Feature.enabled?(:vue_issues_list, @project&.group, default_enabled: :yaml) + .js-issues-list{ data: project_issues_list_data(@project, current_user, finder) } - if @can_bulk_update = render 'shared/issuable/bulk_update_sidebar', type: :issues - elsif project_issues(@project).exists? diff --git a/app/views/projects/jobs/index.html.haml b/app/views/projects/jobs/index.html.haml index 1da3881c104..c58c6ab8287 100644 --- a/app/views/projects/jobs/index.html.haml +++ b/app/views/projects/jobs/index.html.haml @@ -1,8 +1,9 @@ - page_title _("Jobs") - add_page_specific_style 'page_bundles/ci_status' +- admin = local_assigns.fetch(:admin, false) - if Feature.enabled?(:jobs_table_vue, @project, default_enabled: :yaml) - #js-jobs-table{ data: { full_path: @project.full_path, job_counts: job_counts.to_json, job_statuses: job_statuses.to_json, pipeline_editor_path: project_ci_pipeline_editor_path(@project), empty_state_svg_path: image_path('jobs-empty-state.svg') } } + #js-jobs-table{ data: { admin: admin, full_path: @project.full_path, job_counts: job_counts.to_json, job_statuses: job_statuses.to_json, pipeline_editor_path: project_ci_pipeline_editor_path(@project), empty_state_svg_path: image_path('jobs-empty-state.svg') } } - else .top-area - build_path_proc = ->(scope) { project_jobs_path(@project, scope: scope) } diff --git a/app/views/projects/labels/edit.html.haml b/app/views/projects/labels/edit.html.haml index 343900359b4..8023fb93c64 100644 --- a/app/views/projects/labels/edit.html.haml +++ b/app/views/projects/labels/edit.html.haml @@ -3,6 +3,6 @@ - page_title _("Edit"), @label.name, _("Labels") %h3.page-title - Edit Label + = _('Edit Label') %hr = render 'shared/labels/form', url: project_label_path(@project, @label), back_path: project_labels_path(@project) diff --git a/app/views/projects/labels/new.html.haml b/app/views/projects/labels/new.html.haml index 38bd6102437..1ae87bf93d1 100644 --- a/app/views/projects/labels/new.html.haml +++ b/app/views/projects/labels/new.html.haml @@ -3,6 +3,6 @@ - page_title _("New Label") %h3.page-title - New Label + = _('New Label') %hr = render 'shared/labels/form', url: project_labels_path(@project), back_path: project_labels_path(@project) diff --git a/app/views/projects/mattermosts/_team_selection.html.haml b/app/views/projects/mattermosts/_team_selection.html.haml index 4109fdfc13b..4832880eefc 100644 --- a/app/views/projects/mattermosts/_team_selection.html.haml +++ b/app/views/projects/mattermosts/_team_selection.html.haml @@ -42,5 +42,5 @@ %hr .clearfix .float-right - = link_to 'Cancel', edit_project_service_path(@project, @integration), class: 'gl-button btn btn-lg' + = link_to _('Cancel'), edit_project_service_path(@project, @integration), class: 'gl-button btn btn-lg' = f.submit 'Install', class: 'gl-button btn btn-success btn-lg' diff --git a/app/views/projects/merge_requests/_merge_request.atom.builder b/app/views/projects/merge_requests/_merge_request.atom.builder new file mode 100644 index 00000000000..e27cf93bb97 --- /dev/null +++ b/app/views/projects/merge_requests/_merge_request.atom.builder @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +xml.entry do + xml.id project_merge_request_url(merge_request.project, merge_request) + xml.link href: project_merge_request_url(merge_request.project, merge_request) + # using the shovel operator (xml <<) would make us lose indentation, so we do this (https://github.com/rails/rails/issues/7036) + render(partial: 'shared/issuable/issuable', object: merge_request, locals: { builder: xml }) +end diff --git a/app/views/projects/merge_requests/_merge_requests.html.haml b/app/views/projects/merge_requests/_merge_requests.html.haml index e2123e36e67..0abbf953fc7 100644 --- a/app/views/projects/merge_requests/_merge_requests.html.haml +++ b/app/views/projects/merge_requests/_merge_requests.html.haml @@ -2,7 +2,7 @@ - if @merge_requests.present? = render @merge_requests - else - = render 'shared/empty_states/merge_requests' + = render 'shared/empty_states/merge_requests', button_path: new_merge_request_path - if @merge_requests.present? = paginate_collection @merge_requests, total_pages: @total_pages diff --git a/app/views/projects/merge_requests/_nav_btns.html.haml b/app/views/projects/merge_requests/_nav_btns.html.haml index 511e53b192f..b34cf23634c 100644 --- a/app/views/projects/merge_requests/_nav_btns.html.haml +++ b/app/views/projects/merge_requests/_nav_btns.html.haml @@ -1,6 +1,7 @@ - issuable_type = 'merge-requests' -- notification_email = @current_user.present? ? @current_user.notification_email : nil +- notification_email = @current_user.present? ? @current_user.notification_email_or_default : nil += render 'shared/issuable/feed_buttons', show_calendar_button: false .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 diff --git a/app/views/projects/merge_requests/_widget.html.haml b/app/views/projects/merge_requests/_widget.html.haml index 5f2cb1cfcc4..47a0d05fc65 100644 --- a/app/views/projects/merge_requests/_widget.html.haml +++ b/app/views/projects/merge_requests/_widget.html.haml @@ -18,5 +18,7 @@ window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/merge_request_approvals")}'; 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}'; #js-vue-mr-widget.mr-widget diff --git a/app/views/projects/merge_requests/creations/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml index b99714c1794..ea778517374 100644 --- a/app/views/projects/merge_requests/creations/_new_compare.html.haml +++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml @@ -1,5 +1,5 @@ %h3.page-title - New merge request + = _('New merge request') = form_for [@project, @merge_request], url: project_new_merge_request_path(@project), method: :get, html: { class: "merge-request-form js-requires-input" } do |f| - if params[:nav_source].present? diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml index 4aca13ae74a..eb5d052ec19 100644 --- a/app/views/projects/merge_requests/creations/_new_submit.html.haml +++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml @@ -1,5 +1,5 @@ %h3.page-title - New merge request + = _('New merge request') = form_for [@project, @merge_request], html: { class: 'merge-request-form common-note-form js-requires-input js-quick-submit' } do |f| = render 'shared/issuable/form', f: f, issuable: @merge_request, commits: @commits, presenter: @mr_presenter = f.hidden_field :source_project_id diff --git a/app/views/projects/merge_requests/index.atom.builder b/app/views/projects/merge_requests/index.atom.builder new file mode 100644 index 00000000000..36fe6bf759b --- /dev/null +++ b/app/views/projects/merge_requests/index.atom.builder @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# rubocop: disable CodeReuse/ActiveRecord +xml.title "#{@project.name} merge requests" +xml.link href: url_for(safe_params), rel: "self", type: "application/atom+xml" +xml.link href: project_merge_requests_url(@project), rel: "alternate", type: "text/html" +xml.id project_merge_requests_url(@project) +xml.updated @merge_requests.first.updated_at.xmlschema if @merge_requests.reorder(nil).any? + +xml << render(partial: 'projects/merge_requests/merge_request', collection: @merge_requests) if @merge_requests.reorder(nil).any? +# rubocop: enable CodeReuse/ActiveRecord diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml index 289f88c9705..41c6696789d 100644 --- a/app/views/projects/merge_requests/index.html.haml +++ b/app/views/projects/merge_requests/index.html.haml @@ -6,6 +6,9 @@ - page_title _("Merge requests") - new_merge_request_email = @project.new_issuable_address(current_user, 'merge_request') += content_for :meta_tags do + = auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} merge requests") + = render 'projects/last_push' - if @project.merge_requests.exists? @@ -20,7 +23,7 @@ = render 'shared/issuable/bulk_update_sidebar', type: :merge_requests .merge-requests-holder - = render 'merge_requests' + = render 'merge_requests', new_merge_request_path: new_merge_request_path - if new_merge_request_email .gl-text-center.gl-pt-5.gl-pb-7 .js-issueable-by-email{ data: { initial_email: new_merge_request_email, issuable_type: issuable_type, emails_help_page_path: help_page_path('development/emails', anchor: 'email-namespace'), quick_actions_help_path: help_page_path('user/project/quick_actions'), markdown_help_path: help_page_path('user/markdown'), reset_path: new_issuable_address_project_path(@project, issuable_type: issuable_type) } } diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml index 6d1ba9e693b..7e260a03c5d 100644 --- a/app/views/projects/merge_requests/show.html.haml +++ b/app/views/projects/merge_requests/show.html.haml @@ -6,7 +6,6 @@ - page_description @merge_request.description_html - page_card_attributes @merge_request.card_attributes - suggest_changes_help_path = help_page_path('user/project/merge_requests/reviews/suggestions.md') -- number_of_pipelines = @pipelines.size - mr_action = j(params[:tab].presence || 'show') - add_page_specific_style 'page_bundles/merge_requests' - add_page_specific_style 'page_bundles/pipelines' @@ -32,11 +31,11 @@ = tab_link_for @merge_request, :commits do = _("Commits") %span.badge.badge-pill.gl-badge.badge-muted.sm= @commits_count - - if number_of_pipelines.nonzero? + - if @number_of_pipelines.nonzero? = render "projects/merge_requests/tabs/tab", name: "pipelines", class: "pipelines-tab" do = tab_link_for @merge_request, :pipelines do = _("Pipelines") - %span.badge.badge-pill.gl-badge.badge-muted.sm.js-pipelines-mr-count= number_of_pipelines + %span.badge.badge-pill.gl-badge.badge-muted.sm.js-pipelines-mr-count= @number_of_pipelines = render "projects/merge_requests/tabs/tab", name: "diffs", class: "diffs-tab", id: "diffs-tab", qa_selector: "diffs_tab" do = tab_link_for @merge_request, :diffs do = _("Changes") @@ -76,7 +75,7 @@ = render "projects/merge_requests/tabs/pane", name: "commits", id: "commits", class: "commits" do -# This tab is always loaded via AJAX = render "projects/merge_requests/tabs/pane", name: "pipelines", id: "pipelines", class: "pipelines" do - - if number_of_pipelines.nonzero? + - if @number_of_pipelines.nonzero? = render 'projects/commit/pipelines_list', disable_initialization: true, endpoint: pipelines_project_merge_request_path(@project, @merge_request) - params = request.query_parameters - if Feature.enabled?(:default_merge_ref_for_diffs, @project, default_enabled: :yaml) diff --git a/app/views/projects/packages/packages/show.html.haml b/app/views/projects/packages/packages/show.html.haml index 42c31b3272f..ebdc9e654f6 100644 --- a/app/views/projects/packages/packages/show.html.haml +++ b/app/views/projects/packages/packages/show.html.haml @@ -6,7 +6,4 @@ .row .col-12 - - if Feature.enabled?(:package_details_apollo, default_enabled: :yaml) - #js-vue-packages-detail-new{ data: package_details_data(@project, @package) } - - else - #js-vue-packages-detail{ data: package_details_data(@project, @package, true) } + #js-vue-packages-detail-new{ data: package_details_data(@project, @package) } diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml index 190bf9bf071..f6a0638ccd0 100644 --- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml +++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml @@ -27,7 +27,7 @@ %td .float-right.btn-group - if can?(current_user, :play_pipeline_schedule, pipeline_schedule) - = link_to play_pipeline_schedule_path(pipeline_schedule), method: :post, title: s_('Play'), class: 'btn gl-button btn-default btn-icon' do + = link_to play_pipeline_schedule_path(pipeline_schedule), method: :post, title: _('Play'), class: 'btn gl-button btn-default btn-icon' do = sprite_icon('play') - if can?(current_user, :take_ownership_pipeline_schedule, pipeline_schedule) = link_to take_ownership_pipeline_schedule_path(pipeline_schedule), method: :post, title: s_('PipelineSchedules|Take ownership'), class: 'btn gl-button btn-default' do diff --git a/app/views/projects/pipeline_schedules/new.html.haml b/app/views/projects/pipeline_schedules/new.html.haml index a2652304768..1b50090e445 100644 --- a/app/views/projects/pipeline_schedules/new.html.haml +++ b/app/views/projects/pipeline_schedules/new.html.haml @@ -1,4 +1,4 @@ -- breadcrumb_title "Schedules" +- breadcrumb_title _('Schedules') - @breadcrumb_link = namespace_project_pipeline_schedules_path(@project.namespace, @project) - page_title _("New Pipeline Schedule") - add_page_specific_style 'page_bundles/pipeline_schedules' diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml index c1d48992500..23606e24563 100644 --- a/app/views/projects/pipelines/_with_tabs.html.haml +++ b/app/views/projects/pipelines/_with_tabs.html.haml @@ -34,8 +34,8 @@ %thead %tr %th= _('Status') - %th= _('Job ID') %th= _('Name') + %th= _('Job ID') %th %th= _('Coverage') %th diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml index 30ebe4f20b6..8fd8d3cf540 100644 --- a/app/views/projects/pipelines/show.html.haml +++ b/app/views/projects/pipelines/show.html.haml @@ -28,4 +28,4 @@ = render "projects/pipelines/with_tabs", pipeline: @pipeline, stages: @stages, pipeline_has_errors: pipeline_has_errors -.js-pipeline-details-vue{ data: { endpoint: project_pipeline_path(@project, @pipeline, format: :json), metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: @project.namespace, project_id: @project, format: :json), pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, graphql_resource_etag: graphql_etag_pipeline_path(@pipeline) } } +.js-pipeline-details-vue{ data: { metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: @project.namespace, project_id: @project, format: :json), pipeline_project_path: @project.full_path, pipeline_iid: @pipeline.iid, graphql_resource_etag: graphql_etag_pipeline_path(@pipeline) } } diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml index 0239e408e87..12b2b33e364 100644 --- a/app/views/projects/project_members/index.html.haml +++ b/app/views/projects/project_members/index.html.haml @@ -3,7 +3,7 @@ .row.gl-mt-3 .col-lg-12 - - if can_invite_members_for_project?(@project) || can_invite_group_for_project?(@project) + - if can_invite_members_for_project?(@project) .row .col-md-12.col-lg-6.gl-display-flex .gl-flex-direction-column.gl-flex-wrap.align-items-baseline @@ -18,10 +18,7 @@ .col-md-12.col-lg-6 .gl-display-flex.gl-flex-wrap.gl-justify-content-end - if can_admin_project_member?(@project) - = link_to _("Import a project"), - import_project_project_members_path(@project), - class: "btn btn-default btn-md gl-button gl-mt-3 gl-sm-w-auto gl-w-full", - title: _("Import members from another project") + .js-import-a-project-modal{ data: { project_id: @project.id, project_name: @project.name } } - if @project.allowed_to_share_with_group? .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite a group') } } - if can_admin_project_member?(@project) diff --git a/app/views/projects/project_templates/_template.html.haml b/app/views/projects/project_templates/_template.html.haml index 827ff62f8c3..5e4b1397dd3 100644 --- a/app/views/projects/project_templates/_template.html.haml +++ b/app/views/projects/project_templates/_template.html.haml @@ -8,9 +8,9 @@ .text-muted = template.description .controls.d-flex.align-items-center - %a.btn.gl-button.btn-default.gl-mr-3{ href: template.preview, rel: 'noopener noreferrer', target: '_blank', data: { track_label: "template_preview", track_property: template.name, track_event: "click_button", track_value: "" } } + %a.btn.gl-button.btn-default.gl-mr-3{ href: template.preview, rel: 'noopener noreferrer', target: '_blank', data: { track_label: "template_preview", track_property: template.name, track_action: "click_button", track_value: "" } } = _("Preview") %label.btn.gl-button.btn-confirm.template-button.choose-template.gl-mb-0{ for: template.name } - %input{ type: "radio", autocomplete: "off", name: "project[template_name]", id: template.name, value: template.name, data: { track_label: "template_use", track_property: template.name, track_event: "click_button", track_value: "" } } + %input{ type: "radio", autocomplete: "off", name: "project[template_name]", id: template.name, value: template.name, data: { track_label: "template_use", track_property: template.name, track_action: "click_button", track_value: "" } } %span{ data: { qa_selector: 'use_template_button' } } = _("Use template") diff --git a/app/views/projects/services/slack_slash_commands/_help.html.haml b/app/views/projects/services/slack_slash_commands/_help.html.haml index 9702f9b08f2..fee0ca15808 100644 --- a/app/views/projects/services/slack_slash_commands/_help.html.haml +++ b/app/views/projects/services/slack_slash_commands/_help.html.haml @@ -4,22 +4,21 @@ .info-well .well-segment %p - = s_("SlackService|This service allows users to perform common operations on this project by entering slash commands in Slack.") + = s_("SlackService|Perform common operations in this project by entering slash commands in Slack.") = link_to help_page_path('user/project/integrations/slack_slash_commands.md'), target: '_blank' do - = _("View documentation") + = _("Learn more.") = sprite_icon('external-link') %p.inline - = s_("SlackService|See list of available commands in Slack after setting up this service, by entering") - %kbd.inline /<command> help + = s_("SlackService|After setup, get a list of available Slack slash commands by entering") + %kbd.inline /<command> help - if integration.project_level? - %p= _("To set up this service:") + %p= _("To set up this integration:") %ul.list-unstyled.indent-list %li - 1. - = link_to 'https://my.slack.com/services/new/slash-commands', target: '_blank', rel: 'noreferrer noopener nofollow' do - Add a slash command - = sprite_icon('external-link') - in your Slack team with these options: + - slash_command_link_url = 'https://my.slack.com/services/new/slash-commands' + - slash_command_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: slash_command_link_url } + - slash_command_link_end = ' %{external_link_icon}</a>'.html_safe % { external_link_icon: sprite_icon('external-link') } + = html_escape(s_('SlackService|1. %{slash_command_link_start}Add a slash command%{slash_command_link_end} in your Slack team using this information:')) % { slash_command_link_start: slash_command_link_start, slash_command_link_end: slash_command_link_end } %hr @@ -89,6 +88,6 @@ %ul.list-unstyled.indent-list %li - = html_escape(s_("SlackService|2. Paste the %{strong_open}Token%{strong_close} into the field below")) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe } + = html_escape(s_("SlackService|2. Paste the token from Slack in the %{strong_open}Token%{strong_close} field below.")) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe } %li - = html_escape(s_("SlackService|3. Select the %{strong_open}Active%{strong_close} checkbox, press %{strong_open}Save changes%{strong_close} and start using GitLab inside Slack!")) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe } + = html_escape(s_("SlackService|3. Select the %{strong_open}Active%{strong_close} checkbox, select %{strong_open}Save changes%{strong_close}, and start using slash commands in Slack!")) % { strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe } diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml index 70626636ac0..75bd985560b 100644 --- a/app/views/projects/settings/ci_cd/show.html.haml +++ b/app/views/projects/settings/ci_cd/show.html.haml @@ -105,6 +105,6 @@ = expanded ? _('Collapse') : _('Expand') %p = _("Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API.") - = link_to _('Learn more'), help_page_path('api/index', anchor: 'limit-gitlab-cicd-job-token-access'), target: '_blank', rel: 'noopener noreferrer' + = link_to _('Learn more'), help_page_path('ci/jobs/ci_job_token'), target: '_blank', rel: 'noopener noreferrer' .settings-content = render 'ci/token_access/index' diff --git a/app/views/projects/settings/operations/_error_tracking.html.haml b/app/views/projects/settings/operations/_error_tracking.html.haml index 4ef9e1bd6fb..6b2a1468eec 100644 --- a/app/views/projects/settings/operations/_error_tracking.html.haml +++ b/app/views/projects/settings/operations/_error_tracking.html.haml @@ -17,4 +17,5 @@ project: error_tracking_setting_project_json, api_host: setting.api_host, enabled: setting.enabled.to_json, + integrated: setting.integrated.to_json, token: setting.token.present? ? '*' * 12 : nil } } diff --git a/app/views/projects/tags/releases/edit.html.haml b/app/views/projects/tags/releases/edit.html.haml index 88594209c3b..c99f146ea7a 100644 --- a/app/views/projects/tags/releases/edit.html.haml +++ b/app/views/projects/tags/releases/edit.html.haml @@ -15,5 +15,5 @@ = render 'shared/notes/hints' .error-alert .gl-mt-5.gl-display-flex - = f.submit 'Save changes', class: 'btn gl-button btn-confirm gl-mr-3' - = link_to "Cancel", project_tag_path(@project, @tag.name), class: "btn gl-button btn-default btn-cancel" + = f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mr-3' + = link_to _('Cancel'), project_tag_path(@project, @tag.name), class: "btn gl-button btn-default btn-cancel" diff --git a/app/views/projects/usage_quotas/index.html.haml b/app/views/projects/usage_quotas/index.html.haml new file mode 100644 index 00000000000..dfd46af0499 --- /dev/null +++ b/app/views/projects/usage_quotas/index.html.haml @@ -0,0 +1,19 @@ +- page_title s_("UsageQuota|Usage") + +%h3.page-title + = s_('UsageQuota|Usage Quotas') + +.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') } + = s_('UsageQuota|Learn more about usage quotas') + '.' + +.top-area.scrolling-tabs-container.inner-page-scroll-tabs + %ul.nav.nav-tabs.nav-links.scrolling-tabs.separator.js-usage-quota-tabs{ role: 'tablist' } + %li.nav-item + %a.nav-link#storage-quota{ data: { toggle: "tab", action: '#storage-quota-tab' }, href: '#storage-quota-tab', 'aria-controls': '#storage-quota-tab', 'aria-selected': 'true' } + = s_('UsageQuota|Storage') +.tab-content + .tab-pane#storage-quota-tab + #js-project-storage-count-app{ data: @storage_app_data } diff --git a/app/views/projects/work_items/index.html.haml b/app/views/projects/work_items/index.html.haml new file mode 100644 index 00000000000..052db598571 --- /dev/null +++ b/app/views/projects/work_items/index.html.haml @@ -0,0 +1,3 @@ +- page_title s_('WorkItem|Work Items') + +#js-work-items diff --git a/app/views/registrations/experience_levels/show.html.haml b/app/views/registrations/experience_levels/show.html.haml deleted file mode 100644 index 16e59757147..00000000000 --- a/app/views/registrations/experience_levels/show.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -- page_title _('What’s your experience level?') -- @hide_flash = true - -.gl-display-flex.gl-flex-direction-column.gl-align-items-center - = image_tag 'learn-gitlab-avatar.jpg', width: '90' - - %h2.gl-text-center.gl-mt-3.gl-mb-3= _('Hello there') - %p.gl-text-center.gl-font-lg.gl-mb-6= _('Welcome to the guided GitLab tour') - - %h3.gl-text-center.gl-font-lg.gl-mt-6.gl-mb-0= _('What describes you best?') - - .card-deck.gl-mt-6 - .card - .card-body.gl-display-flex.gl-py-8.gl-pr-5.gl-pl-7 - .gl-align-self-center.gl-pr-6 - = image_tag 'novice.svg', width: '78', height: '78', alt: '' - %div - %p.gl-font-lg.gl-font-weight-bold.gl-mb-2= _('Novice') - %p= _('I’m not familiar with the basics of DevOps.') - = link_to _('Show me the basics'), users_sign_up_experience_level_path(experience_level: :novice, namespace_path: params[:namespace_path]), method: :patch, class: 'stretched-link' - - .card - .card-body.gl-display-flex.gl-py-8.gl-pr-5.gl-pl-7 - .gl-align-self-center.gl-pr-6 - = image_tag 'experienced.svg', width: '78', height: '78', alt: '' - %div - %p.gl-font-lg.gl-font-weight-bold.gl-mb-2= _('Experienced') - %p= _('I’m familiar with the basics of DevOps.') - = link_to _('Show me advanced features'), users_sign_up_experience_level_path(experience_level: :experienced, namespace_path: params[:namespace_path]), method: :patch, class: 'stretched-link' diff --git a/app/views/search/_category.html.haml b/app/views/search/_category.html.haml index 7f8a530deb8..ca6f2369bd8 100644 --- a/app/views/search/_category.html.haml +++ b/app/views/search/_category.html.haml @@ -27,11 +27,11 @@ = search_filter_link 'snippet_titles', _("Titles and Descriptions"), search: { snippets: true, group_id: nil, project_id: nil } - else = search_filter_link 'projects', _("Projects"), data: { qa_selector: 'projects_tab' } - = render_if_exists 'search/category_code' + = render_if_exists 'search/category_code' if feature_flag_tab_enabled?(:global_search_code_tab) = render_if_exists 'search/epics_filter_link' - = search_filter_link 'issues', _("Issues") - = search_filter_link 'merge_requests', _("Merge requests") - = render_if_exists 'search/category_wiki' + = search_filter_link 'issues', _("Issues") if feature_flag_tab_enabled?(:global_search_issues_tab) + = search_filter_link 'merge_requests', _("Merge requests") if feature_flag_tab_enabled?(:global_search_merge_requests_tab) + = render_if_exists 'search/category_wiki' if feature_flag_tab_enabled?(:global_search_wiki_tab) = render_if_exists 'search/category_elasticsearch' = search_filter_link 'milestones', _("Milestones") = users diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml index 2f13d7d96c7..88a2ab4bb42 100644 --- a/app/views/search/results/_blob_data.html.haml +++ b/app/views/search/results/_blob_data.html.haml @@ -1,7 +1,7 @@ -.blob-result.gl-mt-3.gl-mb-5{ data: { qa_selector: 'result_item_content' } } +.js-blob-result.gl-mt-3.gl-mb-5{ data: { qa_selector: 'result_item_content' } } .file-holder.file-holder-top-border .js-file-title.file-title{ data: { qa_selector: 'file_title_content' } } - = link_to blob_link, data: {track_event: 'click_text', track_label: 'blob_path', track_property: 'search_result'} do + = link_to blob_link, data: {track_action: 'click_text', track_label: 'blob_path', track_property: 'search_result'} do = sprite_icon('document') %strong = search_blob_title(project, path) diff --git a/app/views/search/results/_commit.html.haml b/app/views/search/results/_commit.html.haml index 3e5ea785aae..7aeeef5faed 100644 --- a/app/views/search/results/_commit.html.haml +++ b/app/views/search/results/_commit.html.haml @@ -1 +1 @@ -= render 'projects/commits/commit', project: commit.project, commit: commit, ref: nil, show_project_name: @project.nil?, link_data_attrs: {track_event: 'click_text', track_label: 'commit_title', track_property: 'search_result'} += render 'projects/commits/commit', project: commit.project, commit: commit, ref: nil, show_project_name: @project.nil?, link_data_attrs: {track_action: 'click_text', track_label: 'commit_title', track_property: 'search_result'} diff --git a/app/views/search/results/_issuable.html.haml b/app/views/search/results/_issuable.html.haml index 63524bbf00e..5645fbfb238 100644 --- a/app/views/search/results/_issuable.html.haml +++ b/app/views/search/results/_issuable.html.haml @@ -3,7 +3,7 @@ %span.gl-display-flex.gl-align-items-center %span.badge.badge-pill.gl-badge.sm{ class: "badge-#{issuable_state_to_badge_class(issuable)}" }= issuable_state_text(issuable) = sprite_icon('eye-slash', css_class: 'gl-text-gray-500 gl-ml-2') if issuable.respond_to?(:confidential?) && issuable.confidential? - = link_to issuable_path(issuable), data: { track_event: 'click_text', track_label: "#{issuable.class.name.downcase}_title", track_property: 'search_result' }, class: 'gl-w-full' do + = link_to issuable_path(issuable), data: { track_action: 'click_text', track_label: "#{issuable.class.name.downcase}_title", track_property: 'search_result' }, class: 'gl-w-full' do %span.term.str-truncated.gl-font-weight-bold.gl-ml-2= issuable.title .gl-text-gray-500.gl-my-3 = issuable_project_reference(issuable) diff --git a/app/views/search/results/_milestone.html.haml b/app/views/search/results/_milestone.html.haml index 6d4ce88a377..a57c94c19c9 100644 --- a/app/views/search/results/_milestone.html.haml +++ b/app/views/search/results/_milestone.html.haml @@ -1,6 +1,6 @@ .search-result-row %h4 - = link_to project_milestone_path(milestone.project, milestone), data: {track_event: 'click_text', track_label: 'milestone_title', track_property: 'search_result'} do + = link_to project_milestone_path(milestone.project, milestone), data: {track_action: 'click_text', track_label: 'milestone_title', track_property: 'search_result'} do %span.term.str-truncated= milestone.title - if milestone.description.present? diff --git a/app/views/search/results/_note.html.haml b/app/views/search/results/_note.html.haml index 8d5d8670b5c..67f16075649 100644 --- a/app/views/search/results/_note.html.haml +++ b/app/views/search/results/_note.html.haml @@ -18,7 +18,7 @@ - else %span #{note.noteable_type.titleize} ##{noteable_identifier} · - = link_to note.noteable.title, note_url, data: {track_event: 'click_text', track_label: 'noteable_title', track_property: 'search_result'} + = link_to note.noteable.title, note_url, data: {track_action: 'click_text', track_label: 'noteable_title', track_property: 'search_result'} %span.note-headline-light.note-headline-meta %span.system-note-separator diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml index 55161ce333b..b59275c35df 100644 --- a/app/views/search/results/_wiki_blob.html.haml +++ b/app/views/search/results/_wiki_blob.html.haml @@ -3,7 +3,7 @@ %div{ class: 'search-result-row gl-pb-3! gl-mt-5 gl-mb-0!' } %span.gl-display-flex.gl-align-items-center - = link_to wiki_blob_link, data: { track_event: 'click_text', track_label: "wiki_title", track_property: 'search_result' }, class: 'gl-w-full' do + = link_to wiki_blob_link, data: { track_action: 'click_text', track_label: "wiki_title", track_property: 'search_result' }, class: 'gl-w-full' do %span.term.str-truncated.gl-font-weight-bold= ::Gitlab::Git::Wiki::GollumSlug.canonicalize_filename(wiki_blob.path) .description.term.col-sm-10.gl-px-0 = simple_search_highlight_and_truncate(wiki_blob.data, @search_term) diff --git a/app/views/shared/_help_dropdown_forum_link.html.haml b/app/views/shared/_help_dropdown_forum_link.html.haml index 351c875475a..f3c69a7c897 100644 --- a/app/views/shared/_help_dropdown_forum_link.html.haml +++ b/app/views/shared/_help_dropdown_forum_link.html.haml @@ -1,2 +1,2 @@ = link_to _("Community forum"), "https://forum.gitlab.com/", target: '_blank', class: 'text-nowrap', - rel: 'noopener noreferrer', data: { 'track_event': 'click_forum', 'track_property': 'question_menu' } + rel: 'noopener noreferrer', data: { 'track_action': 'click_forum', 'track_property': 'question_menu' } diff --git a/app/views/shared/_check_recovery_settings.html.haml b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml index 2ba0cca9ef6..d4764d1a5d9 100644 --- a/app/views/shared/_check_recovery_settings.html.haml +++ b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml @@ -1,7 +1,7 @@ = render 'shared/global_alert', variant: :warning, alert_class: 'js-recovery-settings-callout', - alert_data: { feature_id: 'account_recovery_regular_check', dismiss_endpoint: user_callouts_path, defer_links: 'true' }, + alert_data: { feature_id: UserCalloutsHelper::TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK, dismiss_endpoint: user_callouts_path, defer_links: 'true' }, close_button_data: { testid: 'close-account-recovery-regular-check-callout' } do .gl-alert-body = s_('Profiles|Ensure you have two-factor authentication recovery codes stored in a safe place.') diff --git a/app/views/shared/_visibility_level.html.haml b/app/views/shared/_visibility_level.html.haml index 84ce40e240c..3e30dcaf35a 100644 --- a/app/views/shared/_visibility_level.html.haml +++ b/app/views/shared/_visibility_level.html.haml @@ -7,7 +7,7 @@ = _('Who can see this group?') - visibility_docs_path = help_page_path('public_access/public_access') - docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: visibility_docs_path } - = s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe } + = _('%{docs_link_start}Learn about visibility levels.%{docs_link_end}').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe } - if can_change_visibility_level = render('shared/visibility_radios', model_method: :visibility_level, form: f, selected_level: visibility_level, form_model: form_model) - else diff --git a/app/views/shared/_visibility_radios.html.haml b/app/views/shared/_visibility_radios.html.haml index 90b12557bc8..f48bfcd0e72 100644 --- a/app/views/shared/_visibility_radios.html.haml +++ b/app/views/shared/_visibility_radios.html.haml @@ -3,7 +3,7 @@ - available_visibility_levels.each do |level| .form-check - = form.radio_button model_method, level, checked: (selected_level == level), class: 'form-check-input', data: { track_label: "blank_project", track_event: "activate_form_input", track_property: "#{model_method}_#{level}", track_value: "", qa_selector: "#{visibility_level_label(level).downcase}_radio" } + = form.radio_button model_method, level, checked: (selected_level == level), class: 'form-check-input', data: { track_label: "blank_project", track_action: "activate_form_input", track_property: "#{model_method}_#{level}", track_value: "", qa_selector: "#{visibility_level_label(level).downcase}_radio" } = form.label "#{model_method}_#{level}", class: 'form-check-label' do = visibility_level_icon(level) .option-title diff --git a/app/views/shared/access_tokens/_table.html.haml b/app/views/shared/access_tokens/_table.html.haml index 33d6b9573d4..c096044e439 100644 --- a/app/views/shared/access_tokens/_table.html.haml +++ b/app/views/shared/access_tokens/_table.html.haml @@ -51,7 +51,7 @@ = _('Expired') - else %span{ class: ('text-warning' if token.expires_soon?) } - = _('In %{time_to_now}') % { time_to_now: distance_of_time_in_words_to_now(token.expires_at) } + = time_ago_with_tooltip(token.expires_at) - else %span.token-never-expires-label= _('Never') - if project diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml index a49c17e9265..98752345074 100644 --- a/app/views/shared/boards/_show.html.haml +++ b/app/views/shared/boards/_show.html.haml @@ -1,5 +1,4 @@ - board = local_assigns.fetch(:board, nil) -- group = local_assigns.fetch(:group, false) - @no_breadcrumb_container = true - @no_container = true - @content_wrapper_class = "#{@content_wrapper_class} gl-relative" @@ -18,8 +17,5 @@ - add_page_specific_style 'page_bundles/boards' = render 'shared/issuable/search_bar', type: :boards, board: board -#board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" } - %board-content{ ":lists" => "state.lists", ":disabled" => "disabled" } - - if !is_epic_board && !Feature.enabled?(:graphql_board_lists, default_enabled: :yaml) - = render "shared/boards/components/sidebar", group: group - %board-settings-sidebar + +#js-issuable-board-app{ data: board_data } diff --git a/app/views/shared/boards/components/_sidebar.html.haml b/app/views/shared/boards/components/_sidebar.html.haml deleted file mode 100644 index 8976e89b3d3..00000000000 --- a/app/views/shared/boards/components/_sidebar.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -%board-sidebar{ "inline-template" => true, ":current-user" => (UserSerializer.new.represent(current_user) || {}).to_json } - %transition{ name: "boards-sidebar-slide" } - %aside.right-sidebar.right-sidebar-expanded.boards-sidebar{ "v-show" => "showSidebar", 'aria-label': s_('Boards|Board'), 'data-testid': 'issue-boards-sidebar' } - .issuable-sidebar - .block.issuable-sidebar-header.position-relative - %span.issuable-header-text.hide-collapsed.float-left - %strong.bold - {{ issue.title }} - %br/ - %span - = render_if_exists "shared/boards/components/sidebar/issue_project_path" - = precede "#" do - {{ issue.iid }} - %a.gutter-toggle.position-absolute.position-top-0.position-right-0{ role: "button", - href: "#", - "@click.prevent" => "closeSidebar", - "aria-label" => "Toggle sidebar" } - = custom_icon("icon_close", size: 15) - .js-issuable-update - = render "shared/boards/components/sidebar/assignee" - = render_if_exists "shared/boards/components/sidebar/epic" - = render "shared/boards/components/sidebar/milestone" - = render "shared/boards/components/sidebar/time_tracker" - = render "shared/boards/components/sidebar/due_date" - = render "shared/boards/components/sidebar/labels" - = render_if_exists "shared/boards/components/sidebar/weight" - = render "shared/boards/components/sidebar/notifications" diff --git a/app/views/shared/boards/components/sidebar/_assignee.html.haml b/app/views/shared/boards/components/sidebar/_assignee.html.haml deleted file mode 100644 index 79817025565..00000000000 --- a/app/views/shared/boards/components/sidebar/_assignee.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -- dropdown_options = assignees_dropdown_options('issue') -- relative_url = Gitlab.config.gitlab.relative_url_root || '/' - -.block.assignee{ ref: "assigneeBlock" } - %template{ "v-if" => "issue.assignees" } - %sidebar-assignees-widget{ ":iid" => "String(issue.iid)", - ":full-path" => "issue.path.split('/-/')[0].substring(1).replace(`#{relative_url}`, '')", - ":initial-assignees" => "issue.assignees", - ":allow-multiple-assignees" => "!Boolean(#{dropdown_options[:data][:"max-select"]})", - "@assignees-updated" => "setAssignees" } diff --git a/app/views/shared/boards/components/sidebar/_due_date.html.haml b/app/views/shared/boards/components/sidebar/_due_date.html.haml deleted file mode 100644 index ab4d22ac03d..00000000000 --- a/app/views/shared/boards/components/sidebar/_due_date.html.haml +++ /dev/null @@ -1,31 +0,0 @@ -.block.due_date - .title.gl-h-5.gl-display-flex.gl-align-items-center - = _("Due date") - - if can_admin_issue? - = loading_icon(css_class: 'gl-ml-2 block-loading') - = link_to _("Edit"), "#", class: "js-sidebar-dropdown-toggle edit-link gl-ml-auto" - .value - .value-content - %span.no-value{ "v-if" => "!issue.dueDate" } - = _("None") - %span.bold{ "v-if" => "issue.dueDate" } - {{ issue.dueDate | due-date }} - - if can_admin_issue? - %span.no-value.js-remove-due-date-holder{ "v-if" => "issue.dueDate" } - \- - %a.js-remove-due-date{ href: "#", role: "button" } - = _('remove due date') - - if can_admin_issue? - .selectbox - %input{ type: "hidden", - name: "issue[due_date]", - ":value" => "issue.dueDate" } - .dropdown - %button.dropdown-menu-toggle.js-due-date-select.js-issue-boards-due-date{ type: 'button', - data: { toggle: 'dropdown', field_name: "issue[due_date]", ability_name: "issue" } } - %span.dropdown-toggle-text= _("Due date") - = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3") - .dropdown-menu.dropdown-menu-due-date - = dropdown_title(_('Due date')) - = dropdown_content do - .js-due-date-calendar diff --git a/app/views/shared/boards/components/sidebar/_labels.html.haml b/app/views/shared/boards/components/sidebar/_labels.html.haml deleted file mode 100644 index 5af52d4de23..00000000000 --- a/app/views/shared/boards/components/sidebar/_labels.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -.block.labels - .title.gl-h-5.gl-display-flex.gl-align-items-center - = _("Labels") - - if can_admin_issue? - = loading_icon(css_class: 'gl-ml-2 block-loading') - = link_to _("Edit"), "#", class: "js-sidebar-dropdown-toggle edit-link gl-ml-auto" - .value.issuable-show-labels.dont-hide - %span.no-value{ "v-if" => "issue.labels && issue.labels.length === 0" } - = _("None") - %span{ "v-for" => "label in issue.labels" } - %gl-label{ ":key" => "label.id", - ":background-color" => "label.color", - ":title" => "label.title", - ":description" => "label.description", - ":scoped" => "showScopedLabels(label)" } - - - if can_admin_issue? - .selectbox - %input{ type: "hidden", - name: "issue[label_names][]", - "v-for" => "label in issue.labels", - ":value" => "label.id" } - .dropdown - %button.dropdown-menu-toggle.js-label-select.js-multiselect.js-issue-board-sidebar{ type: "button", - ":data-selected" => "selectedLabels", - ":data-labels" => "issue.assignableLabelsEndpoint", - data: label_dropdown_data(@project, namespace_path: @namespace_path, field_name: "issue[label_names][]") } - %span.dropdown-toggle-text - {{ labelDropdownTitle }} - = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3") - .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable.dropdown-extended-height - = render partial: "shared/issuable/label_page_default" - - if can?(current_user, :admin_label, current_board_parent) - = render partial: "shared/issuable/label_page_create", locals: { show_add_list: true } diff --git a/app/views/shared/boards/components/sidebar/_milestone.html.haml b/app/views/shared/boards/components/sidebar/_milestone.html.haml deleted file mode 100644 index 6143f1d5afe..00000000000 --- a/app/views/shared/boards/components/sidebar/_milestone.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -.block.milestone - .title.gl-h-5.gl-display-flex.gl-align-items-center - = _("Milestone") - - if can_admin_issue? - = loading_icon(css_class: 'gl-ml-2 block-loading') - = link_to _("Edit"), "#", class: "js-sidebar-dropdown-toggle edit-link gl-ml-auto" - .value - %span.no-value{ "v-if" => "!issue.milestone" } - = _("None") - %span.bold.has-tooltip{ "v-if" => "issue.milestone" } - {{ issue.milestone.title }} - - if can_admin_issue? - .selectbox - %input{ type: "hidden", - ":value" => "issue.milestone.id", - name: "issue[milestone_id]", - "v-if" => "issue.milestone" } - .dropdown - %button.dropdown-menu-toggle.js-milestone-select.js-issue-board-sidebar{ type: "button", data: { toggle: "dropdown", show_no: "true", field_name: "issue[milestone_id]", ability_name: "issue", use_id: "true", default_no: "true" }, - ":data-selected" => "milestoneTitle", - ":data-issuable-id" => "issue.iid", - ":data-project-id" => "issue.project_id" } - = _("Milestone") - = sprite_icon('chevron-down', css_class: "dropdown-menu-toggle-icon gl-top-3") - .dropdown-menu.dropdown-select.dropdown-menu-selectable - = dropdown_title(_("Assign milestone")) - = dropdown_filter(_("Search milestones")) - = dropdown_content - = dropdown_loading diff --git a/app/views/shared/boards/components/sidebar/_notifications.html.haml b/app/views/shared/boards/components/sidebar/_notifications.html.haml deleted file mode 100644 index 333dd1a00b4..00000000000 --- a/app/views/shared/boards/components/sidebar/_notifications.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -- if current_user - .block.subscriptions - %subscriptions{ ":loading" => "issue.isFetching && issue.isFetching.subscriptions", - ":subscribed" => "issue.subscribed", - ":id" => "issue.id" } diff --git a/app/views/shared/boards/components/sidebar/_time_tracker.html.haml b/app/views/shared/boards/components/sidebar/_time_tracker.html.haml deleted file mode 100644 index eea3ec35000..00000000000 --- a/app/views/shared/boards/components/sidebar/_time_tracker.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.block.time-tracking - %time-tracker{ ":limit-to-hours" => "timeTrackingLimitToHours", - ":issuable-id" => "issue.id ? issue.id.toString() : ''", - ":issuable-iid" => "issue.iid ? issue.iid.toString() : ''", - ":full-path" => "issue.project ? issue.project.fullPath : ''", - "root-path" => "#{root_url}" } diff --git a/app/views/shared/deploy_tokens/_form.html.haml b/app/views/shared/deploy_tokens/_form.html.haml index e7bbb351633..652da4b396a 100644 --- a/app/views/shared/deploy_tokens/_form.html.haml +++ b/app/views/shared/deploy_tokens/_form.html.haml @@ -48,7 +48,7 @@ .text-secondary= s_('DeployTokens|Allows read-only access to the package registry.') %fieldset.form-group.form-check - = f.check_box :write_package_registry, class: 'form-check-input' + = f.check_box :write_package_registry, class: 'form-check-input', data: { qa_selector: 'deploy_token_write_package_registry_checkbox' } = f.label :write_package_registry, 'write_package_registry', class: 'label-bold form-check-label' .text-secondary= s_('DeployTokens|Allows read and write access to the package registry.') diff --git a/app/views/shared/deploy_tokens/_table.html.haml b/app/views/shared/deploy_tokens/_table.html.haml index fe32fcf94d0..db9c646b694 100644 --- a/app/views/shared/deploy_tokens/_table.html.haml +++ b/app/views/shared/deploy_tokens/_table.html.haml @@ -20,7 +20,7 @@ %td - if token.expires? %span{ class: ('text-warning' if token.expires_soon?) } - In #{distance_of_time_in_words_to_now(token.expires_at)} + = time_ago_with_tooltip(token.expires_at) - else %span.token-never-expires-label= _('Never') %td= token.scopes.present? ? token.scopes.join(', ') : _('no scopes selected') diff --git a/app/views/shared/doorkeeper/applications/_form.html.haml b/app/views/shared/doorkeeper/applications/_form.html.haml index 91a32b55542..180c658dbdc 100644 --- a/app/views/shared/doorkeeper/applications/_form.html.haml +++ b/app/views/shared/doorkeeper/applications/_form.html.haml @@ -18,6 +18,12 @@ %span.form-text.text-muted = _('The application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.') + .form-group.form-check + = f.check_box :expire_access_tokens, class: 'form-check-input' + = f.label :expire_access_tokens, class: 'label-bold form-check-label' + %span.form-text.text-muted + = _('Access tokens expire after 2 hours. A refresh token may be used at any time to generate a new access token. Non-expiring access tokens are deprecated. Clear this setting to enable backward compatibility.') + .form-group = f.label :scopes, class: 'label-bold' = render 'shared/tokens/scopes_form', prefix: 'doorkeeper_application', token: @application, scopes: @scopes diff --git a/app/views/shared/empty_states/_merge_requests.html.haml b/app/views/shared/empty_states/_merge_requests.html.haml index 879447f16ae..72db4d4c846 100644 --- a/app/views/shared/empty_states/_merge_requests.html.haml +++ b/app/views/shared/empty_states/_merge_requests.html.haml @@ -20,7 +20,7 @@ = _("To widen your search, change or remove filters above") .text-center - if can_create_merge_request - = link_to _("New merge request"), project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request") + = link_to _("New merge request"), button_path || project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request") - elsif is_opened_state && opened_merged_count == 0 && closed_merged_count > 0 %h4.text-center = _("There are no open merge requests") @@ -28,7 +28,7 @@ = _("To keep this project going, create a new merge request") .text-center - if can_create_merge_request - = link_to _("New merge request"), project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request") + = link_to _("New merge request"), button_path || project_new_merge_request_path(@project), class: "gl-button btn btn-confirm", title: _("New merge request") - elsif is_closed_state && opened_merged_count > 0 && closed_merged_count == 0 %h4.text-center = _("There are no closed merge requests") diff --git a/app/views/shared/issuable/_board_create_list_dropdown.html.haml b/app/views/shared/issuable/_board_create_list_dropdown.html.haml deleted file mode 100644 index 74b064648c0..00000000000 --- a/app/views/shared/issuable/_board_create_list_dropdown.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -.dropdown.gl-display-flex.gl-align-items-center.gl-ml-3#js-add-list - %button.gl-button.btn.btn-confirm.js-new-board-list{ type: "button", data: board_list_data } - Add list - .dropdown-menu.dropdown-extended-height.dropdown-menu-paging.dropdown-menu-right.dropdown-menu-issues-board-new.dropdown-menu-selectable.js-tab-container-labels - = render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Add list" } - - if can?(current_user, :admin_label, board.resource_parent) - = render partial: "shared/issuable/label_page_create", locals: { show_add_list: true, add_list: true, add_list_class: 'd-none' } - = dropdown_loading diff --git a/app/views/shared/issuable/_feed_buttons.html.haml b/app/views/shared/issuable/_feed_buttons.html.haml index c3e4c3a15cc..f0e4b915ac8 100644 --- a/app/views/shared/issuable/_feed_buttons.html.haml +++ b/app/views/shared/issuable/_feed_buttons.html.haml @@ -1,4 +1,8 @@ -= link_to safe_params.merge(rss_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body', testid: 'rss-feed-link' }, title: _('Subscribe to RSS feed') do +- show_calendar_button = local_assigns.fetch(:show_calendar_button, true) + += link_to safe_params.merge(rss_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body', testid: 'rss-feed-link' }, title: _('Subscribe to RSS feed') , 'aria-label': _('Subscribe to RSS feed') do = sprite_icon('rss', css_class: 'qa-rss-icon') -= link_to safe_params.merge(calendar_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body' }, title: _('Subscribe to calendar') do - = sprite_icon('calendar') + +- if show_calendar_button + = link_to safe_params.merge(calendar_url_options), class: 'btn gl-button btn-default btn-icon has-tooltip', data: { container: 'body' }, title: _('Subscribe to calendar'), 'aria-label': _('Subscribe to calendar') do + = sprite_icon('calendar') diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index dc93442d6cd..cb03bd4c473 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -66,7 +66,7 @@ - if issuable.new_record? = form.submit "Create #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-confirm gl-mr-2', data: { qa_selector: 'issuable_create_button' } - else - = form.submit 'Save changes', class: 'gl-button btn btn-confirm gl-mr-2' + = form.submit _('Save changes'), class: 'gl-button btn btn-confirm gl-mr-2' - if issuable.new_record? = link_to _('Cancel'), polymorphic_path([@project, issuable.class]), class: 'btn gl-button btn-default' diff --git a/app/views/shared/issuable/_issuable.atom.builder b/app/views/shared/issuable/_issuable.atom.builder new file mode 100644 index 00000000000..931fb74dc00 --- /dev/null +++ b/app/views/shared/issuable/_issuable.atom.builder @@ -0,0 +1,38 @@ +# frozen_string_literal: true +builder.title truncate(issuable.title, length: 80) +builder.updated issuable.updated_at.xmlschema +builder.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon_for_user(issuable.author)) + +builder.author do + builder.name issuable.author_name + builder.email issuable.author_public_email +end + +builder.summary issuable.title +builder.description truncate(issuable.description, length: 240) if issuable.description +builder.content issuable.description if issuable.description +builder.milestone issuable.milestone.title if issuable.milestone + +unless issuable.labels.empty? + builder.labels do + issuable.labels.each do |label| + builder.label label.name + end + end +end + +if issuable.assignees.any? + builder.assignees do + issuable.assignees.each do |assignee| + builder.assignee do + builder.name assignee.name + builder.email assignee.public_email + end + end + end + + builder.assignee do + builder.name issuable.assignees.first.name + builder.email issuable.assignees.first.public_email + end +end diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index 737a0ff8c5b..e6c4b3f4814 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -207,10 +207,7 @@ #js-board-epics-swimlanes-toggle .js-board-config{ data: { can_admin_list: user_can_admin_list.to_s, has_scope: board.scoped?.to_s } } - if user_can_admin_list - - if Feature.enabled?(:board_new_list, board.resource_parent, default_enabled: :yaml) || board.to_type == "EpicBoard" - .js-create-column-trigger{ data: board_list_data } - - else - = render 'shared/issuable/board_create_list_dropdown', board: board + .js-create-column-trigger{ data: board_list_data } #js-toggle-focus-btn - elsif type != :productivity_analytics && show_sorting_dropdown = render 'shared/issuable/sort_dropdown' diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index c76aa176696..1e8724c3448 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -88,7 +88,7 @@ = custom_icon('icon_arrow_right') .dropdown.sidebar-move-issue-dropdown.hide-collapsed %button.gl-button.btn.btn-default.btn-block.js-sidebar-dropdown-toggle.js-move-issue{ type: 'button', - data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_event: "click_button", track_value: "" } } + data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_action: "click_button", track_value: "" } } = _('Move issue') .dropdown-menu.dropdown-menu-selectable.dropdown-extended-height = dropdown_title(_('Move issue')) diff --git a/app/views/shared/issuable/_sidebar_user_dropdown.html.haml b/app/views/shared/issuable/_sidebar_user_dropdown.html.haml index 84d2fc033c8..c058e7ebe3e 100644 --- a/app/views/shared/issuable/_sidebar_user_dropdown.html.haml +++ b/app/views/shared/issuable/_sidebar_user_dropdown.html.haml @@ -6,7 +6,7 @@ - options[:footer_content] = true - options[:wrapper_class] = local_assigns.fetch(:wrapper_class) - options[:toggle_class] += ' js-invite-members-track' - - data['track-event'] = 'show_invite_members' + - data['track-action'] = 'show_invite_members' - data['track-label'] = local_assigns.fetch(:track_label) = dropdown_tag(data['dropdown-title'], options: options) do diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml index f5bf010e4db..5742f22ce05 100644 --- a/app/views/shared/issuable/_sort_dropdown.html.haml +++ b/app/views/shared/issuable/_sort_dropdown.html.haml @@ -21,5 +21,6 @@ = sortable_item(sort_title_merged_date, page_filter_path(sort: sort_value_merged_date), sort_title) if viewing_merge_requests = sortable_item(sort_title_closed_date, page_filter_path(sort: sort_value_closed_date), sort_title) if viewing_merge_requests = sortable_item(sort_title_relative_position, page_filter_path(sort: sort_value_relative_position), sort_title) if viewing_issues + = sortable_item(sort_title_title, page_filter_path(sort: sort_value_title), sort_title) if viewing_issues = render_if_exists('shared/ee/issuable/sort_dropdown', viewing_issues: viewing_issues, sort_title: sort_title) = issuable_sort_direction_button(sort_value) diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml index 1043eb49752..2f05d272ca3 100644 --- a/app/views/shared/issuable/form/_metadata.html.haml +++ b/app/views/shared/issuable/form/_metadata.html.haml @@ -1,13 +1,10 @@ - project = local_assigns.fetch(:project) - issuable = local_assigns.fetch(:issuable) - presenter = local_assigns.fetch(:presenter) - -- return unless can?(current_user, :"set_#{issuable.to_ability_name}_metadata", issuable) - - has_due_date = issuable.has_attribute?(:due_date) - form = local_assigns.fetch(:form) -- if issuable.respond_to?(:confidential) +- if issuable.respond_to?(:confidential) && can?(current_user, :set_confidentiality, issuable) .form-group.row .offset-sm-2.col-sm-10 .form-check @@ -15,39 +12,40 @@ = form.label :confidential, class: 'form-check-label' do This issue is confidential and should only be visible to team members with at least Reporter access. -%hr -.row - %div{ class: (has_due_date ? "col-lg-6" : "col-12") } - .form-group.row.merge-request-assignee - = render "shared/issuable/form/metadata_issuable_assignee", issuable: issuable, form: form, has_due_date: has_due_date - - - if issuable.allows_reviewers? - .form-group.row.merge-request-reviewer - = render "shared/issuable/form/metadata_issuable_reviewer", issuable: issuable, form: form, has_due_date: has_due_date, presenter: presenter +- if can?(current_user, :"set_#{issuable.to_ability_name}_metadata", issuable) + %hr + .row + %div{ class: (has_due_date ? "col-lg-6" : "col-12") } + .form-group.row.merge-request-assignee + = render "shared/issuable/form/metadata_issuable_assignee", issuable: issuable, form: form, has_due_date: has_due_date - = render_if_exists "shared/issuable/form/epic", issuable: issuable, form: form, project: project - - - if issuable.supports_milestone? - .form-group.row.issue-milestone - = form.label :milestone_id, "Milestone", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}" - .col-sm-10{ class: ("col-md-8" if has_due_date) } - .issuable-form-select-holder - = render "shared/issuable/milestone_dropdown", selected: issuable.milestone, name: "#{issuable.class.model_name.param_key}[milestone_id]", show_any: false, show_upcoming: false, show_started: false, extra_class: "qa-issuable-milestone-dropdown js-issuable-form-dropdown js-dropdown-keep-input", dropdown_title: "Select milestone" + - if issuable.allows_reviewers? + .form-group.row.merge-request-reviewer + = render "shared/issuable/form/metadata_issuable_reviewer", issuable: issuable, form: form, has_due_date: has_due_date, presenter: presenter - .form-group.row - = form.label :label_ids, "Labels", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}" - = form.hidden_field :label_ids, multiple: true, value: '' - .col-sm-10{ class: "#{"col-md-8" if has_due_date}" } - .issuable-form-select-holder - = render "shared/issuable/label_dropdown", classes: ["js-issuable-form-dropdown"], selected: issuable.labels, data_options: { field_name: "#{issuable.class.model_name.param_key}[label_ids][]", show_any: false }, dropdown_title: "Select label" + = render_if_exists "shared/issuable/form/epic", issuable: issuable, form: form, project: project - = render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form + - if issuable.supports_milestone? + .form-group.row.issue-milestone + = form.label :milestone_id, "Milestone", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}" + .col-sm-10{ class: ("col-md-8" if has_due_date) } + .issuable-form-select-holder + = render "shared/issuable/milestone_dropdown", selected: issuable.milestone, name: "#{issuable.class.model_name.param_key}[milestone_id]", show_any: false, show_upcoming: false, show_started: false, extra_class: "qa-issuable-milestone-dropdown js-issuable-form-dropdown js-dropdown-keep-input", dropdown_title: "Select milestone" - - if has_due_date - .col-lg-6 - = render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form .form-group.row - = form.label :due_date, "Due date", class: "col-form-label col-md-2 col-lg-4" - .col-8 + = form.label :label_ids, "Labels", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}" + = form.hidden_field :label_ids, multiple: true, value: '' + .col-sm-10{ class: "#{"col-md-8" if has_due_date}" } .issuable-form-select-holder - = form.text_field :due_date, id: "issuable-due-date", class: "datepicker form-control", placeholder: "Select due date", autocomplete: 'off' + = render "shared/issuable/label_dropdown", classes: ["js-issuable-form-dropdown"], selected: issuable.labels, data_options: { field_name: "#{issuable.class.model_name.param_key}[label_ids][]", show_any: false }, dropdown_title: "Select label" + + = render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form + + - if has_due_date + .col-lg-6 + = render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form + .form-group.row + = form.label :due_date, "Due date", class: "col-form-label col-md-2 col-lg-4" + .col-8 + .issuable-form-select-holder + = form.text_field :due_date, id: "issuable-due-date", class: "datepicker form-control", placeholder: "Select due date", autocomplete: 'off' diff --git a/app/views/shared/issuable/form/_type_selector.html.haml b/app/views/shared/issuable/form/_type_selector.html.haml index 3b4ab22ce32..f5f6f32d5ba 100644 --- a/app/views/shared/issuable/form/_type_selector.html.haml +++ b/app/views/shared/issuable/form/_type_selector.html.haml @@ -21,7 +21,7 @@ %li.js-filter-issuable-type = link_to new_project_issue_path(@project), class: ("is-active" if issuable.issue?) do #{sprite_icon(work_item_type_icon(:issue), css_class: 'gl-icon')} #{_("Issue")} - %li.js-filter-issuable-type{ data: { track: { event: "select_issue_type_incident", label: "select_issue_type_incident_dropdown_option" } } } + %li.js-filter-issuable-type{ data: { track: { action: "select_issue_type_incident", label: "select_issue_type_incident_dropdown_option" } } } = link_to new_project_issue_path(@project, { issuable_template: 'incident', issue: { issue_type: 'incident' } }), class: ("is-active" if issuable.incident?) do #{sprite_icon(work_item_type_icon(:incident), css_class: 'gl-icon')} #{_("Incident")} diff --git a/app/views/shared/issue_type/_details_header.html.haml b/app/views/shared/issue_type/_details_header.html.haml index a25e35cdcd4..eca61819cca 100644 --- a/app/views/shared/issue_type/_details_header.html.haml +++ b/app/views/shared/issue_type/_details_header.html.haml @@ -15,7 +15,7 @@ = _('Open') .issuable-meta - #js-issuable-header-warnings + #js-issuable-header-warnings{ data: { hidden: issue_hidden?(issuable).to_s } } = issuable_meta(issuable, @project) %a.btn.gl-button.btn-default.btn-icon.float-right.gl-display-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" } diff --git a/app/views/shared/labels/_form.html.haml b/app/views/shared/labels/_form.html.haml index 604aac9237c..6f65dbe4811 100644 --- a/app/views/shared/labels/_form.html.haml +++ b/app/views/shared/labels/_form.html.haml @@ -28,7 +28,7 @@ = render_suggested_colors .form-actions - if @label.persisted? - = f.submit 'Save changes', class: 'btn gl-button btn-confirm js-save-button' + = f.submit _('Save changes'), class: 'btn gl-button btn-confirm js-save-button' - else = f.submit 'Create label', class: 'btn gl-button btn-confirm js-save-button qa-label-create-button' - = link_to 'Cancel', back_path, class: 'btn gl-button btn-default btn-cancel' + = link_to _('Cancel'), back_path, class: 'btn gl-button btn-default btn-cancel' diff --git a/app/views/shared/members/_access_request_links.html.haml b/app/views/shared/members/_access_request_links.html.haml index a983a736a1e..8600db25e65 100644 --- a/app/views/shared/members/_access_request_links.html.haml +++ b/app/views/shared/members/_access_request_links.html.haml @@ -5,13 +5,11 @@ = link_to link_text, polymorphic_path([:leave, source, :members]), method: :delete, data: { confirm: leave_confirmation_message(source), qa_selector: 'leave_group_link' }, - class: '.gl-pl-3.gl-border-l-1.gl-border-l-solid.gl-border-l-gray-500 js-leave-link' + class: 'js-leave-link' - elsif requester = source.requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord = link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]), method: :delete, - data: { confirm: remove_member_message(requester) }, - class: '.gl-pl-3.gl-border-l-1.gl-border-l-solid.gl-border-l-gray-500' + data: { confirm: remove_member_message(requester) } - elsif source.request_access_enabled && can?(current_user, :request_access, source) = link_to _('Request Access'), polymorphic_path([:request_access, source, :members]), - method: :post, - class: '.gl-pl-3.gl-border-l-1.gl-border-l-solid.gl-border-l-gray-500' + method: :post diff --git a/app/views/shared/runners/_runner_details.html.haml b/app/views/shared/runners/_runner_details.html.haml index 672f0b6a83f..a7b2947057d 100644 --- a/app/views/shared/runners/_runner_details.html.haml +++ b/app/views/shared/runners/_runner_details.html.haml @@ -60,4 +60,4 @@ - if runner.contacted_at = time_ago_with_tooltip runner.contacted_at - else - = s_('Never') + = _('Never') diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml index c1918198594..0a8ca309823 100644 --- a/app/views/shared/wikis/pages.html.haml +++ b/app/views/shared/wikis/pages.html.haml @@ -1,4 +1,4 @@ -- add_to_breadcrumbs "Wiki", wiki_path(@wiki) +- add_to_breadcrumbs _('Wiki'), wiki_path(@wiki) - breadcrumb_title s_("Wiki|Pages") - page_title s_("Wiki|Pages"), _("Wiki") - sort_title = wiki_sort_title(params[:sort]) diff --git a/app/views/sherlock/queries/_backtrace.html.haml b/app/views/sherlock/queries/_backtrace.html.haml index ff5a6b73e47..425113ba325 100644 --- a/app/views/sherlock/queries/_backtrace.html.haml +++ b/app/views/sherlock/queries/_backtrace.html.haml @@ -8,7 +8,7 @@ %li %strong - if defined?(BetterErrors) - = link_to(location.path, BetterErrors.editor[location.path, location.line]) + = link_to(location.path, BetterErrors.editor.url(location.path, location.line)) - else = location.path %small.light diff --git a/app/views/sherlock/queries/_general.html.haml b/app/views/sherlock/queries/_general.html.haml index cd810ae10ad..a16314213c4 100644 --- a/app/views/sherlock/queries/_general.html.haml +++ b/app/views/sherlock/queries/_general.html.haml @@ -16,7 +16,7 @@ #{t('sherlock.origin')}: %strong - if defined?(BetterErrors) - = link_to(frame.path, BetterErrors.editor[frame.path, frame.line]) + = link_to(frame.path, BetterErrors.editor.url(frame.path, frame.line)) - else = frame.path %small.light diff --git a/app/views/users/_middle_dot_divider.html.haml b/app/views/users/_middle_dot_divider.html.haml new file mode 100644 index 00000000000..540a200921f --- /dev/null +++ b/app/views/users/_middle_dot_divider.html.haml @@ -0,0 +1,5 @@ +- stacking = local_assigns.delete(:stacking) +- breakpoint = local_assigns.delete(:breakpoint) + +%div{ class: middle_dot_divider_classes(stacking, breakpoint), **local_assigns } + = yield diff --git a/app/views/users/_profile_basic_info.html.haml b/app/views/users/_profile_basic_info.html.haml index c431a72d0e7..3b0186e84e1 100644 --- a/app/views/users/_profile_basic_info.html.haml +++ b/app/views/users/_profile_basic_info.html.haml @@ -1,6 +1,6 @@ -%p.mb-1.mb-sm-2.mt-2.mt-sm-3 - %span.middle-dot-divider +.gl-text-gray-900.gl-mt-4 + = render 'middle_dot_divider' do @#{@user.username} - if can?(current_user, :read_user_profile, @user) - %span.middle-dot-divider + = render 'middle_dot_divider' do = s_('Member since %{date}') % { date: @user.created_at.to_date.to_s(:long) } diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 363909c54e2..20cbe08225e 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -2,7 +2,7 @@ - @hide_breadcrumbs = true - @no_container = true - page_title user_display_name(@user) -- page_description @user.bio_html +- page_description @user.bio - header_title @user.name, user_path(@user) - page_itemtype 'http://schema.org/Person' - link_classes = "flex-grow-1 mx-1 " @@ -26,6 +26,13 @@ = link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referer), class: link_classes + 'btn gl-button btn-default btn-icon', title: s_('UserProfile|Report abuse'), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = sprite_icon('error') + - verified_gpg_keys = @user.gpg_keys.select(&:verified?) + - if verified_gpg_keys.any? + = link_to user_gpg_keys_path, + class: link_classes + 'btn btn-default btn-md gl-button btn-icon has-tooltip', + title: n_('View public GPG key', 'View public GPG keys', verified_gpg_keys.length), + data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do + = sprite_icon('key', css_class: 'gl-button-icon gl-icon') - if can?(current_user, :read_user_profile, @user) = link_to user_path(@user, rss_url_options), class: link_classes + 'btn gl-button btn-default btn-icon has-tooltip', title: s_('UserProfile|Subscribe'), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do @@ -71,56 +78,56 @@ = emoji_icon(@user.status.emoji, class: 'gl-mr-2') = markdown_field(@user.status, :message) = render "users/profile_basic_info" - .cover-desc.cgray.mb-1.mb-sm-2 + .gl-text-gray-900.mb-1.mb-sm-2 - unless @user.location.blank? - .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0{ itemprop: 'address', itemscope: true, itemtype: 'https://schema.org/PostalAddress' } + = render 'middle_dot_divider', stacking: true, itemprop: 'address', itemscope: true, itemtype: 'https://schema.org/PostalAddress' do = sprite_icon('location', css_class: 'fgray') %span{ itemprop: 'addressLocality' } = @user.location - .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0 + = render 'middle_dot_divider', stacking: true do = sprite_icon('clock', css_class: 'fgray') %span = local_time(@user.timezone) - unless work_information(@user).blank? - .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline + = render 'middle_dot_divider', stacking: true do = sprite_icon('work', css_class: 'fgray') %span = work_information(@user, with_schema_markup: true) - .cover-desc.cgray.mb-1.mb-sm-2 + .gl-text-gray-900 - unless @user.skype.blank? - .profile-link-holder.middle-dot-divider - = link_to "skype:#{@user.skype}", title: "Skype" do + = render 'middle_dot_divider' do + = link_to "skype:#{@user.skype}", class: 'gl-hover-text-decoration-none', title: "Skype" do = sprite_icon('skype') - unless @user.linkedin.blank? - .profile-link-holder.middle-dot-divider - = link_to linkedin_url(@user), title: "LinkedIn", target: '_blank', rel: 'noopener noreferrer nofollow' do + = render 'middle_dot_divider' do + = link_to linkedin_url(@user), class: 'gl-hover-text-decoration-none', title: "LinkedIn", target: '_blank', rel: 'noopener noreferrer nofollow' do = sprite_icon('linkedin') - unless @user.twitter.blank? - .profile-link-holder.middle-dot-divider-sm - = link_to twitter_url(@user), title: "Twitter", target: '_blank', rel: 'noopener noreferrer nofollow' do + = render 'middle_dot_divider', breakpoint: 'sm' do + = link_to twitter_url(@user), class: 'gl-hover-text-decoration-none', title: "Twitter", target: '_blank', rel: 'noopener noreferrer nofollow' do = sprite_icon('twitter') - unless @user.website_url.blank? - .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0 + = render 'middle_dot_divider', stacking: true do - if Feature.enabled?(:security_auto_fix) && @user.bot? = sprite_icon('question', css_class: 'gl-text-blue-600') - = link_to @user.short_website_url, @user.full_website_url, class: 'text-link', target: '_blank', rel: 'me noopener noreferrer nofollow', itemprop: 'url' + = link_to @user.short_website_url, @user.full_website_url, target: '_blank', rel: 'me noopener noreferrer nofollow', itemprop: 'url' - unless @user.public_email.blank? - .profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0 - = link_to @user.public_email, "mailto:#{@user.public_email}", class: 'text-link', itemprop: 'email' - .cover-desc.gl-text-gray-900.gl-mb-2.mb-sm-2 + = render 'middle_dot_divider', stacking: true do + = link_to @user.public_email, "mailto:#{@user.public_email}", itemprop: 'email' + .gl-text-gray-900 = sprite_icon('users', css_class: 'gl-vertical-align-middle gl-text-gray-500') - .profile-link-holder.middle-dot-divider - = link_to user_followers_path, class: 'text-link' do + = render 'middle_dot_divider' do + = link_to user_followers_path do - count = @user.followers.count = n_('1 follower', '%{count} followers', count) % { count: count } - .profile-link-holder.middle-dot-divider - = link_to user_following_path, class: 'text-link', data: { qa_selector: 'following_link' } do + = render 'middle_dot_divider' do + = link_to user_following_path, data: { qa_selector: 'following_link' } do = @user.followees.count = _('following') - if @user.bio.present? - .cover-desc.cgray + .gl-text-gray-900 .profile-user-bio - = markdown(@user.bio_html) + = @user.bio - unless profile_tabs.empty? diff --git a/app/views/users/terms/index.html.haml b/app/views/users/terms/index.html.haml index 73d0f51f9ac..771ee693120 100644 --- a/app/views/users/terms/index.html.haml +++ b/app/views/users/terms/index.html.haml @@ -1,12 +1,14 @@ - redirect_params = { redirect: @redirect } if @redirect +- accept_term_link = accept_term_path(@term, redirect_params) .card-body.rendered-terms{ data: { qa_selector: 'terms_content' } } = markdown_field(@term, :terms) - if current_user + = render_if_exists 'devise/shared/form_phone_verification', accept_term_link: accept_term_link, inline: true .card-footer.footer-block.clearfix - if can?(current_user, :accept_terms, @term) .float-right - = button_to accept_term_path(@term, redirect_params), class: 'gl-button btn btn-confirm gl-ml-3', data: { qa_selector: 'accept_terms_button' } do + = button_to accept_term_link, class: 'gl-button btn btn-confirm gl-ml-3', data: { qa_selector: 'accept_terms_button' } do = _('Accept terms') - else .float-right |