diff options
Diffstat (limited to 'app/views')
180 files changed, 1082 insertions, 819 deletions
diff --git a/app/views/admin/application_settings/_help_page.html.haml b/app/views/admin/application_settings/_help_page.html.haml index a869f1bd4df..5e5ab1e4269 100644 --- a/app/views/admin/application_settings/_help_page.html.haml +++ b/app/views/admin/application_settings/_help_page.html.haml @@ -16,6 +16,6 @@ .form-group = f.label :help_page_support_url, _('Support page URL'), class: 'label-bold' = f.text_field :help_page_support_url, class: 'form-control', placeholder: 'http://company.example.com/getting-help', :'aria-describedby' => 'support_help_block' - %span.form-text.text-muted#support_help_block= _('Alternate support URL for help page') + %span.form-text.text-muted#support_help_block= _('Alternate support URL for help page and help dropdown') = f.submit _('Save changes'), class: "btn btn-success" diff --git a/app/views/admin/application_settings/_outbound.html.haml b/app/views/admin/application_settings/_outbound.html.haml index d16304ed338..ad26f52aea7 100644 --- a/app/views/admin/application_settings/_outbound.html.haml +++ b/app/views/admin/application_settings/_outbound.html.haml @@ -4,9 +4,20 @@ %fieldset .form-group .form-check - = f.check_box :allow_local_requests_from_hooks_and_services, class: 'form-check-input' - = f.label :allow_local_requests_from_hooks_and_services, class: 'form-check-label' do - Allow requests to the local network from hooks and services + = f.check_box :allow_local_requests_from_web_hooks_and_services, class: 'form-check-input' + = f.label :allow_local_requests_from_web_hooks_and_services, class: 'form-check-label' do + = _('Allow requests to the local network from web hooks and services') + .form-check + = f.check_box :allow_local_requests_from_system_hooks, class: 'form-check-input' + = f.label :allow_local_requests_from_system_hooks, class: 'form-check-label' do + = _('Allow requests to the local network from system hooks') + + .form-group + = f.label :outbound_local_requests_whitelist_raw, class: 'label-bold' do + = _('Whitelist to allow requests to the local network from hooks and services') + = f.text_area :outbound_local_requests_whitelist_raw, placeholder: "example.com, 192.168.1.1", class: 'form-control', rows: 8 + %span.form-text.text-muted + = _('Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 or 127.0.0.0/28 are supported. Domain wildcards are not supported currently. Use comma, semicolon, or newline to separate multiple entries. The whitelist can hold a maximum of 1000 entries. Domains should use IDNA encoding. Ex: example.com, 192.168.1.1, 127.0.0.0/28, xn--itlab-j1a.com.') .form-group .form-check diff --git a/app/views/admin/application_settings/_pages.html.haml b/app/views/admin/application_settings/_pages.html.haml index d7d709ffd62..1282a032f52 100644 --- a/app/views/admin/application_settings/_pages.html.haml +++ b/app/views/admin/application_settings/_pages.html.haml @@ -14,23 +14,22 @@ = _("Require users to prove ownership of custom domains") .form-text.text-muted = _("Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled") - = link_to icon('question-circle'), help_page_path('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') - - if Feature.enabled?(:pages_auto_ssl) - %h5 - = _("Configure Let's Encrypt") - %p - - lets_encrypt_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: "https://letsencrypt.org/" } - = _("%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA), that give digital certificates in order to enable HTTPS (SSL/TLS) for websites.").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: '</a>'.html_safe } - .form-group - = f.label :lets_encrypt_notification_email, _("Email"), class: 'label-bold' - = f.text_field :lets_encrypt_notification_email, class: 'form-control' - .form-text.text-muted - = _("A Let's Encrypt account will be configured for this GitLab installation using your email address. You will receive emails to warn of expiring certificates.") - .form-group - .form-check - = f.check_box :lets_encrypt_terms_of_service_accepted, class: 'form-check-input' - = f.label :lets_encrypt_terms_of_service_accepted, class: 'form-check-label' do - - terms_of_service_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: lets_encrypt_terms_of_service_admin_application_settings_path } - = _("I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end}").html_safe % { link_start: terms_of_service_link_start, link_end: '</a>'.html_safe } + = link_to icon('question-circle'), help_page_path('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: '4-verify-the-domains-ownership') + %h5 + = _("Configure Let's Encrypt") + %p + - lets_encrypt_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: "https://letsencrypt.org/" } + = _("%{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end} is a free, automated, and open certificate authority (CA), that give digital certificates in order to enable HTTPS (SSL/TLS) for websites.").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: '</a>'.html_safe } + .form-group + = f.label :lets_encrypt_notification_email, _("Email"), class: 'label-bold' + = f.text_field :lets_encrypt_notification_email, class: 'form-control' + .form-text.text-muted + = _("A Let's Encrypt account will be configured for this GitLab installation using your email address. You will receive emails to warn of expiring certificates.") + .form-group + .form-check + = f.check_box :lets_encrypt_terms_of_service_accepted, class: 'form-check-input' + = f.label :lets_encrypt_terms_of_service_accepted, class: 'form-check-label' do + - terms_of_service_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: lets_encrypt_terms_of_service_admin_application_settings_path } + = _("I have read and agree to the Let's Encrypt %{link_start}Terms of Service%{link_end}").html_safe % { link_start: terms_of_service_link_start, link_end: '</a>'.html_safe } = f.submit _('Save changes'), class: "btn btn-success" diff --git a/app/views/admin/application_settings/_performance.html.haml b/app/views/admin/application_settings/_performance.html.haml index 7821a83530f..b52171afc69 100644 --- a/app/views/admin/application_settings/_performance.html.haml +++ b/app/views/admin/application_settings/_performance.html.haml @@ -15,4 +15,10 @@ AuthorizedKeysCommand. Click on the help icon for more details. = link_to icon('question-circle'), help_page_path('administration/operations/fast_ssh_key_lookup') + .form-group + = f.label :raw_blob_request_limit, _('Raw blob request rate limit per minute'), class: 'label-bold' + = f.number_field :raw_blob_request_limit, class: 'form-control' + .form-text.text-muted + = _('Highest number of requests per minute for each raw path, default to 300. To disable throttling set to 0.') + = f.submit 'Save changes', class: "btn btn-success" diff --git a/app/views/admin/application_settings/_snowplow.html.haml b/app/views/admin/application_settings/_snowplow.html.haml new file mode 100644 index 00000000000..b60b5d55a1b --- /dev/null +++ b/app/views/admin/application_settings/_snowplow.html.haml @@ -0,0 +1,30 @@ +- expanded = true if !@application_setting.valid? && @application_setting.errors.any? { |k| k.to_s.start_with?('snowplow_') } +%section.settings.as-snowplow.no-animate#js-snowplow-settings{ class: ('expanded' if expanded) } + .settings-header + %h4 + = _('Snowplow') + %button.btn.btn-default.js-settings-toggle{ type: 'button' } + = expanded ? _('Collapse') : _('Expand') + %p + = _('Configure the %{link} integration.').html_safe % { link: link_to('Snowplow', 'https://snowplowanalytics.com/', target: '_blank') } + .settings-content + + = form_for @application_setting, url: integrations_admin_application_settings_path, html: { class: 'fieldset-form' } do |f| + = form_errors(@application_setting) + + %fieldset + .form-group + .form-check + = f.check_box :snowplow_enabled, class: 'form-check-input' + = f.label :snowplow_enabled, _('Enable snowplow tracking'), class: 'form-check-label' + .form-group + = f.label :snowplow_collector_hostname, _('Collector hostname'), class: 'label-light' + = f.text_field :snowplow_collector_hostname, class: 'form-control', placeholder: 'snowplow.example.com' + .form-group + = f.label :snowplow_site_id, _('Site ID'), class: 'label-light' + = f.text_field :snowplow_site_id, class: 'form-control' + .form-group + = f.label :snowplow_cookie_domain, _('Cookie domain'), class: 'label-light' + = f.text_field :snowplow_cookie_domain, class: 'form-control' + + = f.submit _('Save changes'), class: 'btn btn-success' diff --git a/app/views/admin/applications/_delete_form.html.haml b/app/views/admin/applications/_delete_form.html.haml index 82781f6716d..86f09bf1cb0 100644 --- a/app/views/admin/applications/_delete_form.html.haml +++ b/app/views/admin/applications/_delete_form.html.haml @@ -1,4 +1,4 @@ - submit_btn_css ||= 'btn btn-link btn-remove btn-sm' = form_tag admin_application_path(application) do %input{ :name => "_method", :type => "hidden", :value => "delete" }/ - = submit_tag 'Destroy', onclick: "return confirm('Are you sure?')", class: submit_btn_css + = submit_tag 'Destroy', class: submit_btn_css, data: { confirm: _('Are you sure?') } diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml index c8ee87c6212..962234d3aea 100644 --- a/app/views/admin/broadcast_messages/_form.html.haml +++ b/app/views/admin/broadcast_messages/_form.html.haml @@ -17,19 +17,27 @@ required: true, dir: 'auto', data: { preview_path: preview_admin_broadcast_messages_path } - .form-group.row.js-toggle-colors-container - .col-sm-10.offset-sm-2 - = link_to 'Customize colors', '#', class: 'js-toggle-colors-link' - .form-group.row.js-toggle-colors-container.toggle-colors.hide + .form-group.row .col-sm-2.col-form-label - = f.label :color, "Background Color" + = f.label :color, _("Background color") .col-sm-10 - = f.color_field :color, class: "form-control" + .input-group + .input-group-prepend + .input-group-text.label-color-preview{ :style => 'background-color: ' + @broadcast_message.color + '; color: ' + @broadcast_message.font } + = ' '.html_safe + = f.text_field :color, class: "form-control" + .form-text.text-muted + = _('Choose any color.') + %br + = _("Or you can choose one of the suggested colors below") + + = render_suggested_colors + .form-group.row.js-toggle-colors-container.toggle-colors.hide .col-sm-2.col-form-label = f.label :font, "Font Color" .col-sm-10 - = f.color_field :font, class: "form-control" + = f.color_field :font, class: "form-control text-font-color" .form-group.row .col-sm-2.col-form-label = f.label :starts_at, _("Starts at (UTC)") diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 581f6ae0714..c29ecb43fe6 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -76,51 +76,17 @@ .info-well .well-segment.admin-well.admin-well-features %h4 Features - - sign_up = "Sign up" - %p{ "aria-label" => "#{sign_up}: status " + (allow_signup? ? "on" : "off") } - = sign_up - %span.light.float-right - = boolean_to_icon allow_signup? - - ldap = "LDAP" - %p{ "aria-label" => "#{ldap}: status " + (Gitlab.config.ldap.enabled ? "on" : "off") } - = ldap - %span.light.float-right - = boolean_to_icon Gitlab.config.ldap.enabled - - gravatar = "Gravatar" - %p{ "aria-label" => "#{gravatar}: status " + (gravatar_enabled? ? "on" : "off") } - = gravatar - %span.light.float-right - = boolean_to_icon gravatar_enabled? - - omniauth = "OmniAuth" - %p{ "aria-label" => "#{omniauth}: status " + (Gitlab::Auth.omniauth_enabled? ? "on" : "off") } - = omniauth - %span.light.float-right - = boolean_to_icon Gitlab::Auth.omniauth_enabled? - - reply_email = "Reply by email" - %p{ "aria-label" => "#{reply_email}: status " + (Gitlab::IncomingEmail.enabled? ? "on" : "off") } - = reply_email - %span.light.float-right - = boolean_to_icon Gitlab::IncomingEmail.enabled? + = feature_entry(_('Sign up'), href: admin_application_settings_path(anchor: 'js-signup-settings')) + = feature_entry(_('LDAP'), enabled: Gitlab.config.ldap.enabled) + = feature_entry(_('Gravatar'), href: admin_application_settings_path(anchor: 'js-account-settings'), enabled: gravatar_enabled?) + = feature_entry(_('OmniAuth'), href: admin_application_settings_path(anchor: 'js-signin-settings'), enabled: Gitlab::Auth.omniauth_enabled?) + = feature_entry(_('Reply by email'), enabled: Gitlab::IncomingEmail.enabled?) = render_if_exists 'admin/dashboard/elastic_and_geo' - - container_reg = "Container Registry" - %p{ "aria-label" => "#{container_reg}: status " + (Gitlab.config.registry.enabled ? "on" : "off") } - = container_reg - %span.light.float-right - = boolean_to_icon Gitlab.config.registry.enabled - - gitlab_pages = 'GitLab Pages' - - gitlab_pages_enabled = Gitlab.config.pages.enabled - %p{ "aria-label" => "#{gitlab_pages}: status " + (gitlab_pages_enabled ? "on" : "off") } - = gitlab_pages - %span.light.float-right - = boolean_to_icon gitlab_pages_enabled - - gitlab_shared_runners = 'Shared Runners' - - gitlab_shared_runners_enabled = Gitlab.config.gitlab_ci.shared_runners_enabled - %p{ "aria-label" => "#{gitlab_shared_runners}: status " + (gitlab_shared_runners_enabled ? "on" : "off") } - = gitlab_shared_runners - %span.light.float-right - = boolean_to_icon gitlab_shared_runners_enabled + = feature_entry(_('Container Registry'), href: ci_cd_admin_application_settings_path(anchor: 'js-registry-settings'), enabled: Gitlab.config.registry.enabled) + = feature_entry(_('Gitlab Pages'), href: help_instance_configuration_url, enabled: Gitlab.config.pages.enabled) + = feature_entry(_('Shared Runners'), href: admin_runners_path, enabled: Gitlab.config.gitlab_ci.shared_runners_enabled) .col-md-4 .info-well .well-segment.admin-well @@ -130,7 +96,8 @@ .float-right = version_status_badge %p - GitLab + %a{ href: admin_application_settings_path } + GitLab %span.float-right = Gitlab::VERSION = "(#{Gitlab.revision})" diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 98230684d56..f9cc118a252 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -40,6 +40,11 @@ %strong = @group.created_at.to_s(:medium) + %li + %span.light= _('ID:') + %strong + = @group.id + = render_if_exists 'admin/namespace_plan_info', namespace: @group %li diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 0fae8060b32..3eff0a221d7 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -55,6 +55,11 @@ = @project.created_at.to_s(:medium) %li + %span.light ID: + %strong + = @project.id + + %li %span.light http: %strong = link_to @project.http_url_to_repo, project_path(@project) diff --git a/app/views/admin/requests_profiles/index.html.haml b/app/views/admin/requests_profiles/index.html.haml index adfc67d66d0..86bfeef580c 100644 --- a/app/views/admin/requests_profiles/index.html.haml +++ b/app/views/admin/requests_profiles/index.html.haml @@ -19,7 +19,8 @@ %ul.content-list - profiles.each do |profile| %li - = link_to profile.time.to_s(:long), admin_requests_profile_path(profile) + = link_to profile.time.to_s(:long) + ' ' + profile.profile_mode.capitalize, + admin_requests_profile_path(profile) - else %p No profiles found diff --git a/app/views/admin/services/_form.html.haml b/app/views/admin/services/_form.html.haml index ab08d5c4906..495ee6a04ea 100644 --- a/app/views/admin/services/_form.html.haml +++ b/app/views/admin/services/_form.html.haml @@ -6,6 +6,5 @@ = form_for :service, url: admin_application_settings_service_path, method: :put, html: { class: 'fieldset-form' } do |form| = render 'shared/service_settings', form: form, subject: @service - - unless @service.is_a?(KubernetesService) - .footer-block.row-content-block - = form.submit 'Save', class: 'btn btn-success' + .footer-block.row-content-block + = form.submit 'Save', class: 'btn btn-success' diff --git a/app/views/admin/users/_access_levels.html.haml b/app/views/admin/users/_access_levels.html.haml index 77729636f9d..bb1e22cc610 100644 --- a/app/views/admin/users/_access_levels.html.haml +++ b/app/views/admin/users/_access_levels.html.haml @@ -19,7 +19,7 @@ - editing_current_user = (current_user == @user) = f.radio_button :access_level, :regular, disabled: editing_current_user - = label_tag :regular, class: 'font-weight-bold' do + = f.label :access_level_regular, class: 'font-weight-bold' do Regular %p.light Regular users have access to their groups and projects @@ -27,7 +27,7 @@ = render_if_exists 'admin/users/auditor_access_level_radio', f: f, disabled: editing_current_user = f.radio_button :access_level, :admin, disabled: editing_current_user - = label_tag :admin, class: 'font-weight-bold' do + = f.label :access_level_admin, class: 'font-weight-bold' do Admin %p.light Administrators have access to all groups, projects and users and can manage all features in this installation diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index c3d5ce0fe70..6fc7ec1bb6f 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -52,7 +52,7 @@ = icon("search", class: "search-icon") = button_tag s_('AdminUsers|Search users') if Rails.env.test? .dropdown.user-sort-dropdown - - toggle_text = if @sort.present? then users_sort_options_hash[@sort] else sort_title_name end + - toggle_text = @sort.present? ? users_sort_options_hash[@sort] : sort_title_name = dropdown_toggle(toggle_text, { toggle: 'dropdown' }) %ul.dropdown-menu.dropdown-menu-right %li.dropdown-header diff --git a/app/views/ci/status/_icon.html.haml b/app/views/ci/status/_icon.html.haml index f38bdb2e5ed..fdaacb732c7 100644 --- a/app/views/ci/status/_icon.html.haml +++ b/app/views/ci/status/_icon.html.haml @@ -1,12 +1,10 @@ -- status = local_assigns.fetch(:status) -- size = local_assigns.fetch(:size, 16) -- type = local_assigns.fetch(:type, 'pipeline') -- tooltip_placement = local_assigns.fetch(:tooltip_placement, "left") -- path = local_assigns.fetch(:path, status.has_details? ? status.details_path : nil) -- css_classes = "ci-status-link ci-status-icon ci-status-icon-#{status.group} has-tooltip" +- status = local_assigns.fetch(:status) +- size = local_assigns.fetch(:size, 16) +- tooltip_placement = local_assigns.fetch(:tooltip_placement, "left") +- path = local_assigns.fetch(:path, status.has_details? ? status.details_path : nil) +- option_css_classes = local_assigns.fetch(:option_css_classes, '') +- css_classes = "ci-status-link ci-status-icon ci-status-icon-#{status.group} has-tooltip #{option_css_classes}" - title = s_("PipelineStatusTooltip|Pipeline: %{ci_status}") % {ci_status: status.label} -- if type == 'commit' - - title = s_("PipelineStatusTooltip|Commit: %{ci_status}") % {ci_status: status.label} - if path = link_to path, class: css_classes, title: title, data: { placement: tooltip_placement } do diff --git a/app/views/ci/variables/_environment_scope.html.haml b/app/views/ci/variables/_environment_scope.html.haml new file mode 100644 index 00000000000..15e61d85881 --- /dev/null +++ b/app/views/ci/variables/_environment_scope.html.haml @@ -0,0 +1,21 @@ +- form_field = local_assigns.fetch(:form_field, nil) +- variable = local_assigns.fetch(:variable, nil) + +- if @project + - environment_scope = variable&.environment_scope || '*' + - environment_scope_label = environment_scope == '*' ? s_('CiVariable|All environments') : environment_scope + + %input{ type: "hidden", name: "#{form_field}[variables_attributes][][environment_scope]", value: environment_scope } + = dropdown_tag(environment_scope_label, + options: { wrapper_class: 'ci-variable-body-item js-variable-environment-dropdown-wrapper', + toggle_class: 'js-variable-environment-toggle wide', + filter: true, + dropdown_class: "dropdown-menu-selectable", + placeholder: s_('CiVariable|Search environments'), + footer_content: true, + data: { selected: environment_scope } }) do + %ul.dropdown-footer-list + %li + %button{ class: "dropdown-create-new-item-button js-dropdown-create-new-item", title: s_('CiVariable|New environment') } + = s_('CiVariable|Create wildcard') + %code diff --git a/app/views/ci/variables/_environment_scope_header.html.haml b/app/views/ci/variables/_environment_scope_header.html.haml new file mode 100644 index 00000000000..4ba4ceec16c --- /dev/null +++ b/app/views/ci/variables/_environment_scope_header.html.haml @@ -0,0 +1,2 @@ +.bold.table-section.section-15.append-right-10 + = s_('CiVariables|Scope') diff --git a/app/views/clusters/clusters/_banner.html.haml b/app/views/clusters/clusters/_banner.html.haml index a5de67be96b..4b4278075a6 100644 --- a/app/views/clusters/clusters/_banner.html.haml +++ b/app/views/clusters/clusters/_banner.html.haml @@ -3,7 +3,8 @@ %p.js-error-reason .hidden.js-cluster-creating.bs-callout.bs-callout-info{ role: 'alert' } - = s_('ClusterIntegration|Kubernetes cluster is being created on Google Kubernetes Engine...') + %span.spinner.spinner-dark.spinner-sm{ 'aria-label': 'Loading' } + %span.prepend-left-4= s_('ClusterIntegration|Kubernetes cluster is being created on Google Kubernetes Engine...') .hidden.row.js-cluster-api-unreachable.bs-callout.bs-callout-warning{ role: 'alert' } .col-11 @@ -18,4 +19,4 @@ %button.js-close-banner.close.cluster-application-banner-close.h-100.m-0= "Ć" .hidden.js-cluster-success.bs-callout.bs-callout-success{ role: 'alert' } - = s_("ClusterIntegration|Kubernetes cluster was successfully created on Google Kubernetes Engine. Refresh the page to see Kubernetes cluster's details") + = s_("ClusterIntegration|Kubernetes cluster was successfully created on Google Kubernetes Engine.") diff --git a/app/views/clusters/clusters/_namespace.html.haml b/app/views/clusters/clusters/_namespace.html.haml new file mode 100644 index 00000000000..0c64819ad62 --- /dev/null +++ b/app/views/clusters/clusters/_namespace.html.haml @@ -0,0 +1,14 @@ +- managed_namespace_help_text = s_('ClusterIntegration|Choose a prefix to be used for your namespaces. Defaults to your project path.') +- non_managed_namespace_help_text = s_('ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, pod logs, and Web terminals.') +- managed_namespace_help_link = link_to _('More information'), help_page_path('user/project/clusters/index.md', + anchor: 'gitlab-managed-clusters'), target: '_blank' + +.js-namespace-prefixed + = platform_field.text_field :namespace, + label: s_('ClusterIntegration|Project namespace prefix (optional, unique)'), label_class: 'label-bold', + help: '%{help_text} %{help_link}'.html_safe % { help_text: managed_namespace_help_text, help_link: managed_namespace_help_link } +.js-namespace.hidden + = platform_field.text_field :namespace, + label: s_('ClusterIntegration|Project namespace (optional, unique)'), label_class: 'label-bold', + help: '%{help_text}'.html_safe % { help_text: non_managed_namespace_help_text }, + disabled: true diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml index 4dfbb310142..913d4caa0bc 100644 --- a/app/views/clusters/clusters/show.html.haml +++ b/app/views/clusters/clusters/show.html.haml @@ -33,26 +33,29 @@ %section#cluster-integration %h4= @cluster.name = render 'banner' - = render 'form' - - = render_if_exists 'projects/clusters/prometheus_graphs' - - .cluster-applications-table#js-cluster-applications - - %section.settings#js-cluster-details{ class: ('expanded' if expanded) } - .settings-header - %h4= s_('ClusterIntegration|Kubernetes cluster details') - %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p= s_('ClusterIntegration|See and edit the details for your Kubernetes cluster') - .settings-content - = render 'clusters/platforms/kubernetes/form', cluster: @cluster, platform: @cluster.platform_kubernetes, update_cluster_url_path: clusterable.cluster_path(@cluster) - - %section.settings.no-animate#js-cluster-advanced-settings{ class: ('expanded' if expanded) } - .settings-header - %h4= _('Advanced settings') - %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? _('Collapse') : _('Expand') - %p= s_("ClusterIntegration|Advanced options on this Kubernetes cluster's integration") - .settings-content#advanced-settings-section - = render 'advanced_settings' + + - unless @cluster.status_name.in? %i/scheduled creating/ + = render 'form' + + - unless @cluster.status_name.in? %i/scheduled creating/ + = render_if_exists 'projects/clusters/prometheus_graphs' + + .cluster-applications-table#js-cluster-applications + + %section.settings#js-cluster-details{ class: ('expanded' if expanded) } + .settings-header + %h4= s_('ClusterIntegration|Kubernetes cluster details') + %button.btn.js-settings-toggle{ type: 'button' } + = expanded ? _('Collapse') : _('Expand') + %p= s_('ClusterIntegration|See and edit the details for your Kubernetes cluster') + .settings-content + = render 'clusters/platforms/kubernetes/form', cluster: @cluster, platform: @cluster.platform_kubernetes, update_cluster_url_path: clusterable.cluster_path(@cluster) + + %section.settings.no-animate#js-cluster-advanced-settings{ class: ('expanded' if expanded) } + .settings-header + %h4= _('Advanced settings') + %button.btn.js-settings-toggle{ type: 'button' } + = expanded ? _('Collapse') : _('Expand') + %p= s_("ClusterIntegration|Advanced options on this Kubernetes cluster's integration") + .settings-content#advanced-settings-section + = render 'advanced_settings' diff --git a/app/views/clusters/clusters/user/_form.html.haml b/app/views/clusters/clusters/user/_form.html.haml index f2fc5ac93fb..1d212553c3b 100644 --- a/app/views/clusters/clusters/user/_form.html.haml +++ b/app/views/clusters/clusters/user/_form.html.haml @@ -34,10 +34,6 @@ autocomplete: 'off', label_class: 'label-bold', help: '%{help_text} %{help_link}'.html_safe % { help_text: token_help_text, help_link: more_info_link } - - if @user_cluster.allow_user_defined_namespace? - = platform_kubernetes_field.text_field :namespace, - label: s_('ClusterIntegration|Project namespace (optional, unique)'), label_class: 'label-bold' - = platform_kubernetes_field.form_group :authorization_type, { help: '%{help_text} %{help_link}'.html_safe % { help_text: rbac_help_text, help_link: rbac_help_link } } do = platform_kubernetes_field.check_box :authorization_type, @@ -46,10 +42,15 @@ .form-group = field.check_box :managed, { label: s_('ClusterIntegration|GitLab-managed cluster'), + class: 'js-gl-managed', label_class: 'label-bold' } .form-text.text-muted = s_('ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster.') = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank' + = field.fields_for :platform_kubernetes, @user_cluster.platform_kubernetes do |platform_kubernetes_field| + - if @user_cluster.allow_user_defined_namespace? + = render('clusters/clusters/namespace', platform_field: platform_kubernetes_field) + .form-group = field.submit s_('ClusterIntegration|Add Kubernetes cluster'), class: 'btn btn-success' diff --git a/app/views/clusters/platforms/kubernetes/_form.html.haml b/app/views/clusters/platforms/kubernetes/_form.html.haml index f2e44462226..e50c573bd90 100644 --- a/app/views/clusters/platforms/kubernetes/_form.html.haml +++ b/app/views/clusters/platforms/kubernetes/_form.html.haml @@ -36,10 +36,6 @@ label: s_('ClusterIntegration|Service Token'), label_class: 'label-bold', input_group_class: 'gl-field-error-anchor', append: show_token_btn + copy_token_btn - - if cluster.allow_user_defined_namespace? - = platform_field.text_field :namespace, label: s_('ClusterIntegration|Project namespace (optional, unique)'), - label_class: 'label-bold' - = platform_field.form_group :authorization_type do = platform_field.check_box :authorization_type, { disabled: true, label: s_('ClusterIntegration|RBAC-enabled cluster'), label_class: 'label-bold', inline: true }, 'rbac', 'abac' @@ -49,10 +45,14 @@ .form-group = field.check_box :managed, { label: s_('ClusterIntegration|GitLab-managed cluster'), + class: 'js-gl-managed', label_class: 'label-bold' } .form-text.text-muted = s_('ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster.') = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank' + - if cluster.allow_user_defined_namespace? + = render('clusters/clusters/namespace', platform_field: platform_field) + .form-group = field.submit s_('ClusterIntegration|Save changes'), class: 'btn btn-success' diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml index 09ea7716a47..fee87c6324c 100644 --- a/app/views/devise/passwords/edit.html.haml +++ b/app/views/devise/passwords/edit.html.haml @@ -7,12 +7,12 @@ = f.hidden_field :reset_password_token .form-group = f.label 'New password', for: "user_password" - = f.password_field :password, class: "form-control top qa-password-field", required: true, title: 'This field is required' + = f.password_field :password, class: "form-control top", required: true, title: 'This field is required', data: { qa_selector: 'password_field'} .form-group = f.label 'Confirm new password', for: "user_password_confirmation" - = f.password_field :password_confirmation, class: "form-control bottom qa-password-confirmation", title: 'This field is required', required: true + = f.password_field :password_confirmation, class: "form-control bottom", title: 'This field is required', data: { qa_selector: 'password_confirmation_field' }, required: true .clearfix - = f.submit "Change your password", class: "btn btn-primary qa-change-password-button" + = f.submit "Change your password", class: "btn btn-primary", data: { qa_selector: 'change_password_button' } .clearfix.prepend-top-20 %p diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index 7dacd0b1d72..0b1d3d1ddb3 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -1,20 +1,23 @@ = form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: 'new_user gl-show-field-errors', 'aria-live' => 'assertive'}) do |f| .form-group - = f.label "Username or email", for: "user_login", class: 'label-bold' - = f.text_field :login, class: "form-control top qa-login-field", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off", required: true, title: "This field is required." + = f.label _('Username or email'), for: 'user_login', class: 'label-bold' + = f.text_field :login, class: 'form-control top', autofocus: 'autofocus', autocapitalize: 'off', autocorrect: 'off', required: true, title: _('This field is required.'), data: { qa_selector: 'login_field' } .form-group = f.label :password, class: 'label-bold' - = f.password_field :password, class: "form-control bottom qa-password-field", required: true, title: "This field is required." + = f.password_field :password, class: 'form-control bottom', required: true, title: _('This field is required.'), data: { qa_selector: 'password_field' } - if devise_mapping.rememberable? .remember-me - %label{ for: "user_remember_me" } + %label{ for: 'user_remember_me' } = f.check_box :remember_me, class: 'remember-me-checkbox' %span Remember me - .float-right.forgot-password - = link_to "Forgot your password?", new_password_path(:user) + .float-right + - if unconfirmed_email? + = link_to _('Resend confirmation email'), new_user_confirmation_path + - else + = link_to _('Forgot your password?'), new_password_path(:user) %div - if captcha_enabled? = recaptcha_tags .submit-container.move-submit-down - = f.submit "Sign in", class: "btn btn-success qa-sign-in-button" + = f.submit _('Sign in'), class: 'btn btn-success', data: { qa_selector: 'sign_in_button' } diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml index f856773526d..31c4bb0e33e 100644 --- a/app/views/devise/sessions/_new_ldap.html.haml +++ b/app/views/devise/sessions/_new_ldap.html.haml @@ -3,13 +3,13 @@ = form_tag(omniauth_callback_path(:user, server['provider_name']), id: 'new_ldap_user', class: "gl-show-field-errors") do .form-group = label_tag :username, "#{server['label']} Username" - = text_field_tag :username, nil, { class: "form-control top qa-username-field", title: "This field is required.", autofocus: "autofocus", required: true } + = text_field_tag :username, nil, { class: "form-control top", title: "This field is required.", autofocus: "autofocus", data: { qa_selector: 'username_field' }, required: true } .form-group = label_tag :password - = password_field_tag :password, nil, { class: "form-control bottom qa-password-field", title: "This field is required.", required: true } + = password_field_tag :password, nil, { class: "form-control bottom", title: "This field is required.", data: { qa_selector: 'password_field' }, required: true } - if devise_mapping.rememberable? .remember-me %label{ for: "remember_me" } = check_box_tag :remember_me, '1', false, id: 'remember_me' %span Remember me - = submit_tag "Sign in", class: "btn-success btn qa-sign-in-button" + = submit_tag "Sign in", class: "btn-success btn", data: { qa_selector: 'sign_in_button' } diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml index 034273558bb..2cd77af6877 100644 --- a/app/views/devise/shared/_signup_box.html.haml +++ b/app/views/devise/shared/_signup_box.html.haml @@ -5,28 +5,30 @@ = form_for(resource, as: "new_#{resource_name}", url: registration_path(resource_name), html: { class: "new_new_user gl-show-field-errors", "aria-live" => "assertive" }) do |f| .devise-errors = render "devise/shared/error_messages", resource: resource + - if Feature.enabled?(:invisible_captcha) + = invisible_captcha .name.form-group = f.label :name, _('Full name'), class: 'label-bold' - = f.text_field :name, class: "form-control top qa-new-user-name js-block-emoji js-validate-length", :data => { :max_length => max_name_length, :max_length_message => s_("SignUp|Name is too long (maximum is %{max_length} characters).") % { max_length: max_name_length } }, required: true, title: _("This field is required.") + = f.text_field :name, class: "form-control top js-block-emoji js-validate-length", :data => { :max_length => max_name_length, :max_length_message => s_("SignUp|Name is too long (maximum is %{max_length} characters).") % { max_length: max_name_length }, :qa_selector => 'new_user_name_field' }, required: true, title: _("This field is required.") .username.form-group = f.label :username, class: 'label-bold' - = f.text_field :username, class: "form-control middle qa-new-user-username js-block-emoji js-validate-length js-validate-username", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length } }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.") + = f.text_field :username, class: "form-control middle js-block-emoji js-validate-length js-validate-username", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length }, :qa_selector => 'new_user_username_field' }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.") %p.validation-error.gl-field-error-ignore.field-validation.hide= _('Username is already taken.') %p.validation-success.gl-field-error-ignore.field-validation.hide= _('Username is available.') %p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking username availability...') .form-group = f.label :email, class: 'label-bold' - = f.email_field :email, class: "form-control middle qa-new-user-email", required: true, title: _("Please provide a valid email address.") + = f.email_field :email, class: "form-control middle", data: { qa_selector: 'new_user_email_field' }, required: true, title: _("Please provide a valid email address.") .form-group = f.label :email_confirmation, class: 'label-bold' - = f.email_field :email_confirmation, class: "form-control middle qa-new-user-email-confirmation", required: true, title: _("Please retype the email address.") + = f.email_field :email_confirmation, class: "form-control middle", data: { qa_selector: 'new_user_email_confirmation_field' }, required: true, title: _("Please retype the email address.") .form-group.append-bottom-20#password-strength = f.label :password, class: 'label-bold' - = f.password_field :password, class: "form-control bottom qa-new-user-password", required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length } + = f.password_field :password, class: "form-control bottom", data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: _("Minimum length is %{minimum_password_length} characters.") % { minimum_password_length: @minimum_password_length } %p.gl-field-hint.text-secondary= _('Minimum length is %{minimum_password_length} characters') % { minimum_password_length: @minimum_password_length } - if Gitlab::CurrentSettings.current_application_settings.enforce_terms? .form-group - = check_box_tag :terms_opt_in, '1', false, required: true, class: 'qa-new-user-accept-terms' + = check_box_tag :terms_opt_in, '1', false, required: true, data: { qa_selector: 'new_user_accept_terms_checkbox' } = label_tag :terms_opt_in do - terms_link = link_to s_("I accept the|Terms of Service and Privacy Policy"), terms_path, target: "_blank" - accept_terms_label = _("I accept the %{terms_link}") % { terms_link: terms_link } @@ -36,4 +38,4 @@ - if show_recaptcha_sign_up? = recaptcha_tags .submit-container - = f.submit _("Register"), class: "btn-register btn qa-new-user-register-button" + = f.submit _("Register"), class: "btn-register btn", data: { qa_selector: 'new_user_register_button' } diff --git a/app/views/devise/shared/_tabs_ldap.html.haml b/app/views/devise/shared/_tabs_ldap.html.haml index b1a9470cf1c..db54c166a53 100644 --- a/app/views/devise/shared/_tabs_ldap.html.haml +++ b/app/views/devise/shared/_tabs_ldap.html.haml @@ -5,13 +5,13 @@ = render_if_exists "devise/shared/kerberos_tab" - @ldap_servers.each_with_index do |server, i| %li.nav-item - = link_to server['label'], "##{server['provider_name']}", class: "nav-link #{active_when(i.zero? && form_based_auth_provider_has_active_class?(:ldapmain))} qa-ldap-tab", 'data-toggle' => 'tab' + = link_to server['label'], "##{server['provider_name']}", class: "nav-link #{active_when(i.zero? && form_based_auth_provider_has_active_class?(:ldapmain))}", data: { toggle: 'tab', qa_selector: 'ldap_tab' } = render_if_exists 'devise/shared/tab_smartcard' - if password_authentication_enabled_for_web? %li.nav-item - = link_to 'Standard', '#login-pane', class: 'nav-link qa-standard-tab', 'data-toggle' => 'tab' + = link_to 'Standard', '#login-pane', class: 'nav-link', data: { toggle: 'tab', qa_selector: 'standard_tab' } - if allow_signup? %li.nav-item - = link_to 'Register', '#register-pane', class: 'nav-link qa-register-tab', 'data-toggle' => 'tab' + = link_to 'Register', '#register-pane', class: 'nav-link', data: { toggle: 'tab', qa_selector: 'register_tab' } diff --git a/app/views/devise/shared/_tabs_normal.html.haml b/app/views/devise/shared/_tabs_normal.html.haml index 4cd03be572f..b6a1b8805ee 100644 --- a/app/views/devise/shared/_tabs_normal.html.haml +++ b/app/views/devise/shared/_tabs_normal.html.haml @@ -1,6 +1,6 @@ %ul.nav-links.new-session-tabs.nav-tabs.nav{ role: 'tablist' } %li.nav-item{ role: 'presentation' } - %a.nav-link.qa-sign-in-tab.active{ href: '#login-pane', data: { toggle: 'tab' }, role: 'tab' } Sign in + %a.nav-link.active{ href: '#login-pane', data: { toggle: 'tab', qa_selector: 'sign_in_tab' }, role: 'tab' } Sign in - if allow_signup? %li.nav-item{ role: 'presentation' } - %a.nav-link.qa-register-tab{ href: '#register-pane', data: { track_label: 'sign_in_register', track_property: 'sign_in', track_event: 'click_button', track_value: 'register', toggle: 'tab' }, role: 'tab' } Register + %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 diff --git a/app/views/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml index dae9a7acf6b..5d57337a568 100644 --- a/app/views/doorkeeper/authorizations/new.html.haml +++ b/app/views/doorkeeper/authorizations/new.html.haml @@ -46,4 +46,4 @@ = hidden_field_tag :response_type, @pre_auth.response_type = hidden_field_tag :scope, @pre_auth.scope = hidden_field_tag :nonce, @pre_auth.nonce - = submit_tag _("Authorize"), class: "btn btn-success prepend-left-10" + = submit_tag _("Authorize"), class: "btn btn-success prepend-left-10", data: { qa_selector: 'authorization_button' } diff --git a/app/views/doorkeeper/authorized_applications/_delete_form.html.haml b/app/views/doorkeeper/authorized_applications/_delete_form.html.haml index 69cc510e9c1..9bc5e2ee42f 100644 --- a/app/views/doorkeeper/authorized_applications/_delete_form.html.haml +++ b/app/views/doorkeeper/authorized_applications/_delete_form.html.haml @@ -5,4 +5,4 @@ = form_tag path do %input{ :name => "_method", :type => "hidden", :value => "delete" }/ - = submit_tag _('Revoke'), onclick: "return confirm('#{_('Are you sure?')}')", class: 'btn btn-remove btn-sm' + = submit_tag _('Revoke'), class: 'btn btn-remove btn-sm', data: { confirm: _('Are you sure?') } diff --git a/app/views/errors/access_denied.html.haml b/app/views/errors/access_denied.html.haml index 46931b5932d..1ed7b56db1d 100644 --- a/app/views/errors/access_denied.html.haml +++ b/app/views/errors/access_denied.html.haml @@ -10,7 +10,7 @@ = message %p = s_('403|Please contact your GitLab administrator to get permission.') - .action-container.js-go-back{ style: 'display: none' } - %a{ href: 'javascript:history.back()', class: 'btn btn-success' } + .action-container.js-go-back{ hidden: true } + %button{ type: 'button', class: 'btn btn-success' } = s_('Go Back') = render "errors/footer" diff --git a/app/views/explore/projects/_projects.html.haml b/app/views/explore/projects/_projects.html.haml index 67f2f897137..35b32662b8a 100644 --- a/app/views/explore/projects/_projects.html.haml +++ b/app/views/explore/projects/_projects.html.haml @@ -1 +1,2 @@ -= render 'shared/projects/list', projects: projects, user: current_user +- is_explore_page = defined?(explore_page) && explore_page += render 'shared/projects/list', projects: projects, user: current_user, explore_page: is_explore_page diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml index ed508fa2506..153c90e534e 100644 --- a/app/views/explore/projects/trending.html.haml +++ b/app/views/explore/projects/trending.html.haml @@ -10,4 +10,4 @@ = render 'explore/head' = render 'explore/projects/nav' unless Feature.enabled?(:project_list_filter_bar) && current_user -= render 'projects', projects: @projects += render 'projects', projects: @projects, explore_page: true diff --git a/app/views/groups/_group_admin_settings.html.haml b/app/views/groups/_group_admin_settings.html.haml index b8f632d11d3..733cb36cc3d 100644 --- a/app/views/groups/_group_admin_settings.html.haml +++ b/app/views/groups/_group_admin_settings.html.haml @@ -17,6 +17,12 @@ = f.select :project_creation_level, options_for_select(::Gitlab::Access.project_creation_options, @group.project_creation_level), {}, class: 'form-control' .form-group.row + .col-sm-2.col-form-label + = f.label s_('SubgroupCreationlevel|Allowed to create subgroups') + .col-sm-10 + = f.select :subgroup_creation_level, options_for_select(::Gitlab::Access.subgroup_creation_options, @group.subgroup_creation_level), {}, class: 'form-control' + +.form-group.row .col-sm-2.col-form-label.pt-0 = f.label :require_two_factor_authentication, 'Two-factor authentication' .col-sm-10 diff --git a/app/views/groups/_home_panel.html.haml b/app/views/groups/_home_panel.html.haml index 4daf3683eaf..e50d2b8e994 100644 --- a/app/views/groups/_home_panel.html.haml +++ b/app/views/groups/_home_panel.html.haml @@ -1,4 +1,5 @@ - can_create_subgroups = can?(current_user, :create_subgroup, @group) +- emails_disabled = @group.emails_disabled? .group-home-panel .row.mb-3 @@ -21,7 +22,7 @@ .home-panel-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end - if current_user .group-buttons - = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn' + = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn', emails_disabled: emails_disabled - if can? current_user, :create_projects, @group - new_project_label = _("New project") - new_subgroup_label = _("New subgroup") diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml index 021c0b6c429..882fcc79421 100644 --- a/app/views/groups/group_members/index.html.haml +++ b/app/views/groups/group_members/index.html.haml @@ -1,39 +1,67 @@ -- page_title "Members" +- page_title _("Members") - can_manage_members = can?(current_user, :admin_group_member, @group) +- show_invited_members = can_manage_members && @invited_members.exists? +- pending_active = params[:search_invited].present? .project-members-page.prepend-top-default %h4 - Members + = _("Members") %hr - if can_manage_members .project-members-new.append-bottom-default %p.clearfix - Add new member to - %strong= @group.name + = _("Add new member to %{strong_start}%{group_name}%{strong_end}").html_safe % { group_name: @group.name, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe } = render "new_group_member" = render 'shared/members/requests', membership_source: @group, requesters: @requesters = render_if_exists 'groups/group_members/ldap_sync' - .clearfix - %h5.member.existing-title - Existing members - .card - .card-header.flex-project-members-panel - %span.flex-project-title - Members with access to - %strong= @group.name - %span.badge.badge-pill= @members.total_count - = form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form flex-project-members-form' do - .form-group - .position-relative.append-right-8 - = search_field_tag :search, params[:search], { placeholder: 'Find existing members by name', class: 'form-control', spellcheck: false } - %button.member-search-btn{ type: "submit", "aria-label" => "Submit search" } - = icon("search") - - if can_manage_members - = render 'shared/members/filter_2fa_dropdown' - = render 'shared/members/sort_dropdown' - %ul.content-list.members-list - = render partial: 'shared/members/member', collection: @members, as: :member - = paginate @members, theme: 'gitlab' + %ul.nav-links.mobile-separator.nav.nav-tabs.clearfix + %li.nav-item + = link_to "#existing_members", class: ["nav-link", ("active" unless pending_active)] , 'data-toggle' => 'tab' do + %span + = _("Existing") + %span.badge.badge-pill= @members.total_count + - if show_invited_members + %li.nav-item + = link_to "#invited_members", class: ["nav-link", ("active" if pending_active)], 'data-toggle' => 'tab' do + %span + = _("Pending") + %span.badge.badge-pill= @invited_members.total_count + + .tab-content + #existing_members.tab-pane{ :class => ("active" unless pending_active) } + .card.card-without-border + .d-flex.flex-column.flex-md-row.row-content-block.second-block + %span.flex-grow-1.align-self-md-center.col-form-label + = _("Members with access to %{strong_start}%{group_name}%{strong_end}").html_safe % { group_name: @group.name, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe } + = form_tag group_group_members_path(@group), method: :get, class: 'form-inline user-search-form' do + .form-group.flex-grow + .position-relative.mr-md-2 + = search_field_tag :search, params[:search], { placeholder: _('Search'), class: 'form-control', spellcheck: false } + %button.user-search-btn.border-left{ type: "submit", "aria-label" => _("Submit search") } + = icon("search") + - if can_manage_members + = label_tag '2fa', '2FA', class: 'col-form-label label-bold pr-md-2' + = render 'shared/members/filter_2fa_dropdown' + = render 'shared/members/sort_dropdown' + %ul.content-list.members-list + = render partial: 'shared/members/member', collection: @members, as: :member + = paginate @members, theme: 'gitlab' + + - if show_invited_members + #invited_members.tab-pane{ :class => ("active" if pending_active) } + .card.card-without-border + .d-flex.flex-column.flex-md-row.row-content-block.second-block + %span.flex-grow-1 + = _("Members with pending access to %{strong_start}%{group_name}%{strong_end}").html_safe % { group_name: @group.name, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe } + = form_tag group_group_members_path(@group), method: :get, class: 'form-inline user-search-form' do + .form-group + .position-relative.mr-md-2 + = search_field_tag :search_invited, params[:search_invited], { placeholder: _('Search'), class: 'form-control', spellcheck: false } + %button.user-search-btn.border-left{ type: "submit", "aria-label" => _("Submit search") } + = icon("search") + %ul.content-list.members-list + = render partial: 'shared/members/member', collection: @invited_members, as: :member + = paginate @invited_members, param_name: 'invited_members_page', theme: 'gitlab' diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index f05e269553a..bf077eb09d2 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -1,4 +1,4 @@ -- @can_bulk_update = can?(current_user, :admin_issue, @group) +- @can_bulk_update = can?(current_user, :admin_issue, @group) && @group.feature_available?(:group_bulk_edit) - page_title "Issues" = content_for :meta_tags do @@ -13,7 +13,7 @@ = render 'shared/issuable/feed_buttons' - if @can_bulk_update - = render_if_exists 'shared/issuable/bulk_update_button' + = 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 diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index 808bb1309b1..0780fab513b 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -1,3 +1,5 @@ +- @can_bulk_update = can?(current_user, :admin_merge_request, @group) && @group.feature_available?(:group_bulk_edit) + - page_title "Merge Requests" - if group_merge_requests_count(state: 'all').zero? @@ -7,8 +9,14 @@ = render 'shared/issuable/nav', type: :merge_requests - if current_user .nav-controls + - if @can_bulk_update + = render_if_exists 'shared/issuable/bulk_update_button', type: :merge_requests + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", type: :merge_requests, with_feature_enabled: 'merge_requests', with_shared: false, include_projects_in_subgroups: true = render 'shared/issuable/search_bar', type: :merge_requests + - if @can_bulk_update + = render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :merge_requests + = render 'shared/merge_requests' diff --git a/app/views/groups/settings/_advanced.html.haml b/app/views/groups/settings/_advanced.html.haml index 5d211d0e186..d1eb6478997 100644 --- a/app/views/groups/settings/_advanced.html.haml +++ b/app/views/groups/settings/_advanced.html.haml @@ -23,20 +23,19 @@ = f.submit 'Change group path', class: 'btn btn-warning' -- if supports_nested_groups? - .sub-section - %h4.warning-title Transfer group - = form_for @group, url: transfer_group_path(@group), method: :put do |f| - .form-group - = dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', data: { data: parent_group_options(@group) } }) - = hidden_field_tag 'new_parent_group_id' +.sub-section + %h4.warning-title Transfer group + = form_for @group, url: transfer_group_path(@group), method: :put do |f| + .form-group + = dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', data: { data: parent_group_options(@group) } }) + = hidden_field_tag 'new_parent_group_id' - %ul - %li Be careful. Changing a group's parent can have unintended #{link_to 'side effects', 'https://docs.gitlab.com/ce/user/project/index.html#redirects-when-changing-repository-paths', target: 'blank'}. - %li You can only transfer the group to a group you manage. - %li You will need to update your local repositories to point to the new location. - %li If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility. - = f.submit 'Transfer group', class: 'btn btn-warning' + %ul + %li Be careful. Changing a group's parent can have unintended #{link_to 'side effects', 'https://docs.gitlab.com/ce/user/project/index.html#redirects-when-changing-repository-paths', target: 'blank'}. + %li You can only transfer the group to a group you manage. + %li You will need to update your local repositories to point to the new location. + %li If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility. + = f.submit 'Transfer group', class: 'btn btn-warning' .sub-section %h4.danger-title= _('Remove group') diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml index 0da1f1ba7f5..94a938021f9 100644 --- a/app/views/groups/settings/_permissions.html.haml +++ b/app/views/groups/settings/_permissions.html.haml @@ -11,15 +11,23 @@ .form-check = f.check_box :share_with_group_lock, disabled: !can_change_share_with_group_lock?(@group), class: 'form-check-input' = f.label :share_with_group_lock, class: 'form-check-label' do - %span + %span.d-block - group_link = link_to @group.name, group_path(@group) = s_('GroupSettings|Prevent sharing a project within %{group} with other groups').html_safe % { group: group_link } - %br %span.descr.text-muted= share_with_group_lock_help_text(@group) + .form-group.append-bottom-default + .form-check + = f.check_box :emails_disabled, checked: @group.emails_disabled?, disabled: !can_disable_group_emails?(@group), class: 'form-check-input' + = f.label :emails_disabled, class: 'form-check-label' do + %span.d-block= s_('GroupSettings|Disable email notifications') + %span.text-muted= s_('GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects.') + = render_if_exists 'groups/settings/ip_restriction', f: f, group: @group + = render_if_exists 'groups/settings/allowed_email_domain', f: f, group: @group = render 'groups/settings/lfs', f: f = render 'groups/settings/project_creation_level', f: f, group: @group + = render 'groups/settings/subgroup_creation_level', f: f, group: @group = render 'groups/settings/two_factor_auth', f: f = render_if_exists 'groups/member_lock_setting', f: f, group: @group diff --git a/app/views/groups/settings/_subgroup_creation_level.html.haml b/app/views/groups/settings/_subgroup_creation_level.html.haml new file mode 100644 index 00000000000..f36ad192bad --- /dev/null +++ b/app/views/groups/settings/_subgroup_creation_level.html.haml @@ -0,0 +1,3 @@ +.form-group + = f.label s_('SubgroupCreationLevel|Allowed to create subgroups'), class: 'label-bold' + = f.select :subgroup_creation_level, options_for_select(::Gitlab::Access.subgroup_creation_options, group.subgroup_creation_level), {}, class: 'form-control' diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml index efb3815b257..a996c86a256 100644 --- a/app/views/help/_shortcuts.html.haml +++ b/app/views/help/_shortcuts.html.haml @@ -3,9 +3,9 @@ .modal-content .modal-header %h4.modal-title - Keyboard Shortcuts + = _('Keyboard Shortcuts') %small - = link_to '(Show all)', '#', class: 'js-more-help-button' + = link_to _('(Show all)'), '#', class: 'js-more-help-button' %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } %span{ "aria-hidden": true } × .modal-body @@ -15,281 +15,281 @@ %tbody %tr %th - %th Global Shortcuts + %th= _('Global Shortcuts') %tr %td.shortcut %kbd s - %td Focus Search + %td= _('Focus Search') %tr %td.shortcut %kbd f - %td Focus Filter - - if performance_bar_enabled? - %tr - %td.shortcut - %kbd p b - %td Show/hide the Performance Bar + %td= _('Focus Filter') + %tr + %td.shortcut + %kbd p + %kbd b + %td= _('Toggle the Performance Bar') %tr %td.shortcut %kbd ? - %td Show/hide this dialog + %td= _('Show/hide this dialog') %tr %td.shortcut - if browser.platform.mac? %kbd ⌘ shift p - else %kbd ctrl shift p - %td Toggle Markdown preview + %td= _('Toggle Markdown preview') %tr %td.shortcut %kbd %i.fa.fa-arrow-up - %td Edit last comment (when focused on an empty textarea) + %td= _('Edit last comment (when focused on an empty textarea)') %tr %td.shortcut %kbd shift t %td - Go to todos + = _('Go to todos') %tr %td.shortcut %kbd shift a %td - Go to the activity feed + = _('Go to the activity feed') %tr %td.shortcut %kbd shift p %td - Go to projects + = _('Go to projects') %tr %td.shortcut %kbd shift i %td - Go to issues + = _('Go to issues') %tr %td.shortcut %kbd shift m %td - Go to merge requests + = _('Go to merge requests') %tr %td.shortcut %kbd shift g %td - Go to groups + = _('Go to groups') %tr %td.shortcut %kbd shift l %td - Go to milestones + = _('Go to milestones') %tr %td.shortcut %kbd shift s %td - Go to snippets + = _('Go to snippets') %tbody %tr %th - %th Finding Project File + %th= _('Finding Project File') %tr %td.shortcut %kbd %i.fa.fa-arrow-up - %td Move selection up + %td= _('Move selection up') %tr %td.shortcut %kbd %i.fa.fa-arrow-down - %td Move selection down + %td= _('Move selection down') %tr %td.shortcut %kbd enter - %td Open Selection + %td= _('Open Selection') %tr %td.shortcut %kbd esc - %td Go back + %td= _('Go back') .col-lg-4 %table.shortcut-mappings %tbody %tr %th - %th Project + %th= _('Project') %tr %td.shortcut %kbd g %kbd p %td - Go to the project's overview page + = _('Go to the project\'s overview page') %tr %td.shortcut %kbd g %kbd v %td - Go to the project's activity feed + = _('Go to the project\'s activity feed') %tr %td.shortcut %kbd g %kbd f %td - Go to files + = _('Go to files') %tr %td.shortcut %kbd g %kbd c %td - Go to commits + = _('Go to commits') %tr %td.shortcut %kbd g %kbd j %td - Go to jobs + = _('Go to jobs') %tr %td.shortcut %kbd g %kbd n %td - Go to network graph + = _('Go to network graph') %tr %td.shortcut %kbd g %kbd d %td - Go to repository charts + = _('Go to repository charts') %tr %td.shortcut %kbd g %kbd i %td - Go to issues + = _('Go to issues') %tr %td.shortcut %kbd g %kbd b %td - Go to issue boards + = _('Go to issue boards') %tr %td.shortcut %kbd g %kbd m %td - Go to merge requests + = _('Go to merge requests') %tr %td.shortcut %kbd g %kbd e %td - Go to environments + = _('Go to environments') %tr %td.shortcut %kbd g %kbd l %td - Go to metrics + = _('Go to metrics') %tr %td.shortcut %kbd g %kbd k %td - Go to kubernetes + = _('Go to kubernetes') %tr %td.shortcut %kbd g %kbd s %td - Go to snippets + = _('Go to snippets') %tr %td.shortcut %kbd g %kbd w %td - Go to wiki + = _('Go to wiki') %tr %td.shortcut %kbd t - %td Go to finding file + %td= _('Go to finding file') %tr %td.shortcut %kbd i - %td New issue + %td= _('New issue') %tbody %tr %th - %th Project Files browsing + %th= _('Project Files browsing') %tr %td.shortcut %kbd %i.fa.fa-arrow-up - %td Move selection up + %td= _('Move selection up') %tr %td.shortcut %kbd %i.fa.fa-arrow-down - %td Move selection down + %td= _('Move selection down') %tr %td.shortcut %kbd enter - %td Open Selection + %td= _('Open Selection') %tbody %tr %th - %th Project File + %th= _('Project File') %tr %td.shortcut %kbd y - %td Go to file permalink + %td= _('Go to file permalink') %tbody %tr %th - %th Web IDE + %th= _('Web IDE') %tr %td.shortcut - if browser.platform.mac? %kbd ⌘ p - else %kbd ctrl p - %td Go to file + %td= _('Go to file') %tr %td.shortcut - if browser.platform.mac? %kbd ⌘ enter - else %kbd ctrl enter - %td Commit (when editing commit message) + %td= _('Commit (when editing commit message)') .col-lg-4 %table.shortcut-mappings - %tbody.hidden-shortcut{ style: 'display:none' } + %tbody.hidden-shortcut.network{ style: 'display:none' } %tr %th - %th Network Graph + %th= _('Network Graph') %tr %td.shortcut %kbd %i.fa.fa-arrow-left \/ %kbd h - %td Scroll left + %td= _('Scroll left') %tr %td.shortcut %kbd %i.fa.fa-arrow-right \/ %kbd l - %td Scroll right + %td= _('Scroll right') %tr %td.shortcut %kbd %i.fa.fa-arrow-up \/ %kbd k - %td Scroll up + %td= _('Scroll up') %tr %td.shortcut %kbd %i.fa.fa-arrow-down \/ %kbd j - %td Scroll down + %td= _('Scroll down') %tr %td.shortcut %kbd @@ -298,7 +298,7 @@ \/ %kbd shift k - %td Scroll to top + %td= _('Scroll to top') %tr %td.shortcut %kbd @@ -307,72 +307,80 @@ \/ %kbd shift j - %td Scroll to bottom - %tbody.hidden-shortcut{ style: 'display:none' } + %td= _('Scroll to bottom') + %tbody.hidden-shortcut.issues{ style: 'display:none' } %tr %th - %th Issues + %th= _('Issues') %tr %td.shortcut %kbd a - %td Change assignee + %td= _('Change assignee') %tr %td.shortcut %kbd m - %td Change milestone + %td= _('Change milestone') %tr %td.shortcut %kbd r - %td Reply (quoting selected text) + %td= _('Reply (quoting selected text)') %tr %td.shortcut %kbd e - %td Edit issue + %td= _('Edit issue') %tr %td.shortcut %kbd l - %td Change Label - %tbody.hidden-shortcut{ style: 'display:none' } + %td= _('Change Label') + %tbody.hidden-shortcut.merge_requests{ style: 'display:none' } %tr %th - %th Merge Requests + %th= _('Merge Requests') %tr %td.shortcut %kbd a - %td Change assignee + %td= _('Change assignee') %tr %td.shortcut %kbd m - %td Change milestone + %td= _('Change milestone') %tr %td.shortcut %kbd r - %td Reply (quoting selected text) + %td= _('Reply (quoting selected text)') %tr %td.shortcut %kbd e - %td Edit merge request + %td= _('Edit merge request') %tr %td.shortcut %kbd l - %td Change Label + %td= _('Change Label') %tr %td.shortcut %kbd ] \/ %kbd j - %td Move to next file + %td= _('Move to next file') %tr %td.shortcut %kbd [ \/ %kbd k - %td Move to previous file - %tbody.hidden-shortcut{ style: 'display:none' } + %td= _('Move to previous file') + %tr + %td.shortcut + %kbd n + %td= _('Move to next unresolved discussion') + %tr + %td.shortcut + %kbd p + %td= _('Move to previous unresolved discussion') + %tbody.hidden-shortcut.wiki{ style: 'display:none' } %tr %th - %th Wiki pages + %th= _('Wiki pages') %tr %td.shortcut %kbd e - %td Edit wiki page + %td= _('Edit wiki page') diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml index 50933c7d434..ed904c48ddb 100644 --- a/app/views/help/index.html.haml +++ b/app/views/help/index.html.haml @@ -33,7 +33,7 @@ .documentation-index.md = markdown(@help_index) .col-md-4 - .card + .card.links-card .card-header Quick help %ul.content-list diff --git a/app/views/import/bitbucket_server/status.html.haml b/app/views/import/bitbucket_server/status.html.haml index 40609fddbde..aac09801d91 100644 --- a/app/views/import/bitbucket_server/status.html.haml +++ b/app/views/import/bitbucket_server/status.html.haml @@ -17,8 +17,13 @@ = button_tag class: 'btn btn-import btn-success js-import-all' do = _('Import all projects') = icon('spinner spin', class: 'loading-icon') - .btn-group - = link_to('Reconfigure', configure_import_bitbucket_server_path, class: 'btn btn-primary', method: :post) + +.btn-group + = link_to('Reconfigure', configure_import_bitbucket_server_path, class: 'btn btn-primary', method: :post) + +.input-btn-group.float-right + = form_tag status_import_bitbucket_server_path, :method => 'get' do + = text_field_tag :filter, sanitize(params[:filter]), class: 'form-control append-bottom-10', placeholder: _('Filter your projects by name'), size: 40, autoFocus: true .table-responsive.prepend-top-10 %table.table.import-jobs @@ -62,7 +67,7 @@ = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true %span.input-group-prepend .input-group-text / - = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true + = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, required: true %td.import-actions.job-status = button_tag class: 'btn btn-import js-add-to-import' do Import diff --git a/app/views/import/github/new.html.haml b/app/views/import/github/new.html.haml index 72e5934574a..518c44cc687 100644 --- a/app/views/import/github/new.html.haml +++ b/app/views/import/github/new.html.haml @@ -1,30 +1,32 @@ -- title = has_ci_cd_only_params? ? _('Connect repositories from GitHub') : _('GitHub import') +- title = _('Authenticate with GitHub') - page_title title - breadcrumb_title title - header_title _("Projects"), root_path -%h3.page-title - = icon 'github', text: _('Import repositories from GitHub') +%h2.page-title + = title -- if github_import_configured? - %p - = import_github_authorize_message +%p + = import_github_authorize_message - = link_to _('List your GitHub repositories'), status_import_github_path(ci_cd_only: params[:ci_cd_only]), class: 'btn btn-success' +- if github_import_configured? && !has_ci_cd_only_params? + = link_to icon('github', text: title), status_import_github_path, class: 'btn btn-success' %hr -%p - = import_github_personal_access_token_message +- unless github_import_configured? || has_ci_cd_only_params? + .bs-callout.bs-callout-info + = import_configure_github_admin_message -= form_tag personal_access_token_import_github_path, method: :post, class: 'form-inline' do += form_tag personal_access_token_import_github_path, method: :post do .form-group - = text_field_tag :personal_access_token, '', class: 'form-control append-right-8', placeholder: _('Personal Access Token'), size: 40 - = submit_tag _('List your GitHub repositories'), class: 'btn btn-success' + %label.label-bold= _('Personal Access Token') + = text_field_tag :personal_access_token, '', class: 'form-control', placeholder: _('e.g. %{token}') % { token: '8d3f016698e...' } + %span.form-text.text-muted + = import_github_personal_access_token_message = render_if_exists 'import/github/ci_cd_only' -- unless github_import_configured? - %hr - %p - = import_configure_github_admin_message + .form-actions.d-flex.justify-content-end + = link_to _('Cancel'), new_project_path, class: 'btn' + = submit_tag _('Authenticate'), class: 'btn btn-success ml-2' diff --git a/app/views/layouts/_google_analytics.html.haml b/app/views/layouts/_google_analytics.html.haml index 98ea96b0b77..e8a5359e791 100644 --- a/app/views/layouts/_google_analytics.html.haml +++ b/app/views/layouts/_google_analytics.html.haml @@ -1,11 +1,11 @@ --# haml-lint:disable InlineJavaScript -:javascript - var _gaq = _gaq || []; - _gaq.push(['_setAccount', '#{extra_config.google_analytics_id}']); - _gaq.push(['_trackPageview']); += javascript_tag nonce: true do + :plain + var _gaq = _gaq || []; + _gaq.push(['_setAccount', '#{extra_config.google_analytics_id}']); + _gaq.push(['_trackPageview']); - (function() { - var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; - var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); - })(); + (function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); + })(); diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 20b844f9fd8..271b73326fa 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -40,7 +40,7 @@ = stylesheet_link_tag "highlight/themes/#{user_color_scheme}", media: "all" - = Gon::Base.render_data + = Gon::Base.render_data(nonce: content_security_policy_nonce) - if content_for?(:library_javascripts) = yield :library_javascripts @@ -56,6 +56,7 @@ = yield :project_javascripts = csrf_meta_tags + = csp_meta_tag - unless browser.safari? %meta{ name: 'referrer', content: 'origin-when-cross-origin' } @@ -78,4 +79,3 @@ = render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id') = render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id') = render_if_exists 'layouts/snowplow' - = render_if_exists 'layouts/pendo' if Feature.enabled?(:pendo_tracking) && !Rails.env.test? diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml index 240e03a5d53..82ec92988eb 100644 --- a/app/views/layouts/_init_auto_complete.html.haml +++ b/app/views/layouts/_init_auto_complete.html.haml @@ -4,8 +4,8 @@ - datasources = autocomplete_data_sources(object, noteable_type) - if object - -# haml-lint:disable InlineJavaScript - :javascript - gl = window.gl || {}; - gl.GfmAutoComplete = gl.GfmAutoComplete || {}; - gl.GfmAutoComplete.dataSources = #{datasources.to_json}; + = javascript_tag nonce: true do + :plain + gl = window.gl || {}; + gl.GfmAutoComplete = gl.GfmAutoComplete || {}; + gl.GfmAutoComplete.dataSources = #{datasources.to_json}; diff --git a/app/views/layouts/_init_client_detection_flags.html.haml b/app/views/layouts/_init_client_detection_flags.html.haml index c729f8aa696..6537b86085f 100644 --- a/app/views/layouts/_init_client_detection_flags.html.haml +++ b/app/views/layouts/_init_client_detection_flags.html.haml @@ -1,7 +1,7 @@ - client = client_js_flags - if client - -# haml-lint:disable InlineJavaScript - :javascript - gl = window.gl || {}; - gl.client = #{client.to_json}; + = javascript_tag nonce: true do + :plain + gl = window.gl || {}; + gl.client = #{client.to_json}; diff --git a/app/views/layouts/_piwik.html.haml b/app/views/layouts/_piwik.html.haml index 473b14ce626..361a7b03180 100644 --- a/app/views/layouts/_piwik.html.haml +++ b/app/views/layouts/_piwik.html.haml @@ -1,15 +1,15 @@ <!-- Piwik --> --# haml-lint:disable InlineJavaScript -:javascript - var _paq = _paq || []; - _paq.push(['trackPageView']); - _paq.push(['enableLinkTracking']); - (function() { - var u="//#{extra_config.piwik_url}/"; - _paq.push(['setTrackerUrl', u+'piwik.php']); - _paq.push(['setSiteId', "#{extra_config.piwik_site_id}"]); - var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; - g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); - })(); += javascript_tag nonce: true do + :plain + var _paq = _paq || []; + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + (function() { + var u="//#{extra_config.piwik_url}/"; + _paq.push(['setTrackerUrl', u+'piwik.php']); + _paq.push(['setSiteId', "#{extra_config.piwik_site_id}"]); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); + })(); <noscript><p><img src="//#{extra_config.piwik_url}/piwik.php?idsite=#{extra_config.piwik_site_id}" style="border:0;" alt="" /></p></noscript> <!-- End Piwik Code --> diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index a5f57f5893c..e6a235e39da 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -2,7 +2,7 @@ - group_data_attrs = { group_path: j(@group.path), name: j(@group.name), issues_path: issues_group_path(@group), mr_path: merge_requests_group_path(@group) } - if @project && @project.persisted? - project_data_attrs = { project_path: j(@project.path), name: j(@project.name), issues_path: project_issues_path(@project), mr_path: project_merge_requests_path(@project), issues_disabled: !@project.issues_enabled? } -.search.search-form{ data: { track_label: "navbar_search", track_event: "activate_form_input" } } +.search.search-form{ data: { track_label: "navbar_search", track_event: "activate_form_input", track_value: "" } } = form_tag search_path, method: :get, class: 'form-inline' do |f| .search-input-container .search-input-wrap @@ -13,7 +13,8 @@ tabindex: '1', autocomplete: 'off', data: { issues_path: issues_dashboard_path, - mr_path: merge_requests_dashboard_path }, + mr_path: merge_requests_dashboard_path, + qa_selector: 'search_term_field' }, aria: { label: _('Search or jump toā¦') } %button.hidden.js-dropdown-search-toggle{ type: 'button', data: { toggle: 'dropdown' } } .dropdown-menu.dropdown-select.js-dashboard-search-options @@ -45,5 +46,7 @@ - if @snippet || @snippets = hidden_field_tag :snippets, true = hidden_field_tag :repository_ref, @ref + = hidden_field_tag :nav_source, 'navbar' + -# workaround for non-JS feature specs, for JS you need to use find('#search').send_keys(:enter) = button_tag 'Go' if ENV['RAILS_ENV'] == 'test' .search-autocomplete-opts.hide{ :'data-autocomplete-path' => search_autocomplete_path, :'data-autocomplete-project-id' => @project.try(:id), :'data-autocomplete-project-ref' => @ref } diff --git a/app/views/layouts/_snowplow.html.haml b/app/views/layouts/_snowplow.html.haml new file mode 100644 index 00000000000..5f5c5e984c5 --- /dev/null +++ b/app/views/layouts/_snowplow.html.haml @@ -0,0 +1,29 @@ +- return unless Gitlab::CurrentSettings.snowplow_enabled? + += javascript_tag nonce: true do + :plain + ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[]; + p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments) + };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.snowplow('newTracker', '#{Gitlab::SnowplowTracker::NAMESPACE}', '#{Gitlab::CurrentSettings.snowplow_collector_hostname}', { + appId: '#{Gitlab::CurrentSettings.snowplow_site_id}', + cookieDomain: '#{Gitlab::CurrentSettings.snowplow_cookie_domain}', + userFingerprint: false, + respectDoNotTrack: true, + forceSecureTracker: true, + post: true, + contexts: { webPage: true }, + stateStorageStrategy: "localStorage" + }); + + window.snowplow('enableActivityTracking', 30, 30); + window.snowplow('trackPageView'); + +- return unless Feature.enabled?(:additional_snowplow_tracking, @group) + += javascript_tag nonce: true do + :plain + window.snowplow('enableFormTracking'); + window.snowplow('enableLinkClickTracking'); diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml index ff3410f6268..e9a4a068599 100644 --- a/app/views/layouts/devise.html.haml +++ b/app/views/layouts/devise.html.haml @@ -1,7 +1,7 @@ !!! 5 %html.devise-layout-html{ class: system_message_class } = render "layouts/head" - %body.ui-indigo.login-page.application.navless.qa-login-page{ data: { page: body_data_page } } + %body.ui-indigo.login-page.application.navless{ data: { page: body_data_page, qa_selector: 'login_page' } } = header_message .page-wrap = render "layouts/header/empty" diff --git a/app/views/layouts/errors.html.haml b/app/views/layouts/errors.html.haml index 06069a72951..dc924a0e25d 100644 --- a/app/views/layouts/errors.html.haml +++ b/app/views/layouts/errors.html.haml @@ -8,12 +8,16 @@ %body .page-container = yield - -# haml-lint:disable InlineJavaScript - :javascript - (function(){ - var goBackElement = document.querySelector('.js-go-back'); + = javascript_tag nonce: true do + :plain + (function(){ + var goBackElement = document.querySelector('.js-go-back'); - if (goBackElement && history.length > 1) { - goBackElement.style.display = 'block'; - } - }()); + if (goBackElement && history.length > 1) { + goBackElement.removeAttribute('hidden'); + + goBackElement.querySelector('button').addEventListener('click', function() { + history.back(); + }); + } + }()); diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml index 1d40b78fa83..49de821f1c2 100644 --- a/app/views/layouts/group.html.haml +++ b/app/views/layouts/group.html.haml @@ -6,8 +6,8 @@ - content_for :page_specific_javascripts do - if current_user - -# haml-lint:disable InlineJavaScript - :javascript - window.uploads_path = "#{group_uploads_path(@group)}"; + = javascript_tag nonce: true do + :plain + window.uploads_path = "#{group_uploads_path(@group)}"; = render template: "layouts/application" diff --git a/app/views/layouts/header/_current_user_dropdown.html.haml b/app/views/layouts/header/_current_user_dropdown.html.haml index 4f3e4031fe3..808290afcad 100644 --- a/app/views/layouts/header/_current_user_dropdown.html.haml +++ b/app/views/layouts/header/_current_user_dropdown.html.haml @@ -20,8 +20,8 @@ = link_to s_("CurrentUser|Profile"), current_user, class: 'profile-link', data: { user: current_user.username } - if current_user_menu?(:settings) %li - = link_to s_("CurrentUser|Settings"), profile_path + = link_to s_("CurrentUser|Settings"), profile_path, data: { qa_selector: 'settings_link' } - if current_user_menu?(:sign_out) %li.divider %li - = link_to _("Sign out"), destroy_user_session_path, class: "sign-out-link" + = link_to _("Sign out"), destroy_user_session_path, class: "sign-out-link", data: { qa_selector: 'sign_out_link' } diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index f9ee6f42e23..14c7b2428b2 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -4,8 +4,9 @@ - search_path_url = search_path(group_id: group.id) - else - search_path_url = search_path +- has_impersonation_link = header_link?(:admin_impersonation) -%header.navbar.navbar-gitlab.qa-navbar.navbar-expand-sm.js-navbar +%header.navbar.navbar-gitlab.navbar-expand-sm.js-navbar{ data: { qa_selector: 'navbar' } } %a.sr-only.gl-accessibility{ href: "#content-body", tabindex: "1" } Skip to content .container-fluid .header-content @@ -64,14 +65,14 @@ .dropdown-menu.dropdown-menu-right = render 'layouts/header/help_dropdown' - if header_link?(:user_dropdown) - %li.nav-item.header-user.dropdown{ data: { track_label: "profile_dropdown", track_event: "click_dropdown" } } + %li.nav-item.header-user.dropdown{ data: { track_label: "profile_dropdown", track_event: "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" = sprite_icon('angle-down', css_class: 'caret-down') .dropdown-menu.dropdown-menu-right = render 'layouts/header/current_user_dropdown' - - if header_link?(:admin_impersonation) - %li.nav-item.impersonation + - if has_impersonation_link + %li.nav-item.impersonation.ml-0 = link_to admin_impersonation_path, class: 'nav-link impersonation-btn', method: :delete, title: _('Stop impersonation'), aria: { label: _('Stop impersonation') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = icon('user-secret') - if header_link?(:sign_in) diff --git a/app/views/layouts/header/_help_dropdown.html.haml b/app/views/layouts/header/_help_dropdown.html.haml index 5643a508ddc..41d7aa3741a 100644 --- a/app/views/layouts/header/_help_dropdown.html.haml +++ b/app/views/layouts/header/_help_dropdown.html.haml @@ -2,6 +2,8 @@ - if current_user_menu?(:help) %li = link_to _("Help"), help_path + %li + = link_to _("Support"), support_url = render_if_exists "shared/learn_gitlab_menu_item" %li.divider %li diff --git a/app/views/layouts/header/_new_dropdown.haml b/app/views/layouts/header/_new_dropdown.haml index 1d7a501e5c2..e28efb09be5 100644 --- a/app/views/layouts/header/_new_dropdown.haml +++ b/app/views/layouts/header/_new_dropdown.haml @@ -1,4 +1,4 @@ -%li.header-new.dropdown{ data: { track_label: "new_dropdown", track_event: "click_dropdown" } } +%li.header-new.dropdown{ data: { track_label: "new_dropdown", track_event: "click_dropdown", track_value: "" } } = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", id: "js-onboarding-new-project-link", title: _("New..."), ref: 'tooltip', aria: { label: _("New...") }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do = sprite_icon('plus-square', size: 16) = sprite_icon('angle-down', css_class: 'caret-down') diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index 54028dc8554..ff0c5b241b2 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -2,7 +2,7 @@ -# https://gitlab.com/gitlab-org/gitlab-ce/issues/49713 for more information. %ul.list-unstyled.navbar-sub-nav - if dashboard_nav_link?(:projects) - = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown", data: { track_label: "projects_dropdown", track_event: "click_dropdown" } }) do + = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown", data: { track_label: "projects_dropdown", track_event: "click_dropdown", track_value: "" } }) do %button.btn{ type: 'button', data: { toggle: "dropdown" } } = _('Projects') = sprite_icon('angle-down', css_class: 'caret-down') @@ -10,7 +10,7 @@ = render "layouts/nav/projects_dropdown/show" - if dashboard_nav_link?(:groups) - = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "home dropdown header-groups qa-groups-dropdown", data: { track_label: "groups_dropdown", track_event: "click_dropdown" } }) do + = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "home dropdown header-groups qa-groups-dropdown", data: { track_label: "groups_dropdown", track_event: "click_dropdown", track_value: "" } }) do %button.btn{ type: 'button', data: { toggle: "dropdown" } } = _('Groups') = sprite_icon('angle-down', css_class: 'caret-down') @@ -32,6 +32,8 @@ = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets qa-snippets-link' do = _('Snippets') + = render_if_exists 'layouts/nav/sidebar/analytics_link' + - if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets]) %li.header-more.dropdown.d-xl-none{ class: ('d-lg-none' unless has_extra_nav_icons?) } %a{ href: "#", data: { toggle: "dropdown" } } @@ -53,6 +55,9 @@ = nav_link(controller: 'dashboard/snippets') do = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets' do = _('Snippets') + + = render_if_exists 'layouts/nav/sidebar/analytics_more_link' + %li.dropdown.d-lg-none = render_if_exists 'dashboard/operations/nav_link_list' - if can?(current_user, :read_instance_statistics) diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml index 87133c7ba22..cb39c830170 100644 --- a/app/views/layouts/nav/sidebar/_admin.html.haml +++ b/app/views/layouts/nav/sidebar/_admin.html.haml @@ -236,7 +236,7 @@ %span = _('General') = nav_link(path: 'application_settings#integrations') do - = link_to integrations_admin_application_settings_path, title: _('Integrations') do + = link_to integrations_admin_application_settings_path, title: _('Integrations'), data: { qa_selector: 'integration_settings_link' } do %span = _('Integrations') = nav_link(path: 'application_settings#repository') do diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index 4b5ccc33716..48c9f19f89f 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -36,8 +36,6 @@ %span = _('Activity') - = render_if_exists 'groups/sidebar/security_dashboard' # EE-specific - - if group_sidebar_link?(:contribution_analytics) = nav_link(path: 'analytics#show') do = link_to group_analytics_path(@group), title: _('Contribution Analytics'), data: { placement: 'right' } do @@ -105,6 +103,8 @@ = _('Merge Requests') %span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge= number_with_delimiter(merge_requests_count) + = render_if_exists "layouts/nav/ee/security_link" # EE-specific + - if group_sidebar_link?(:kubernetes) = nav_link(controller: [:clusters]) do = link_to group_clusters_path(@group) do diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml index a9af5ba5008..48fea2bbecf 100644 --- a/app/views/layouts/nav/sidebar/_project.html.haml +++ b/app/views/layouts/nav/sidebar/_project.html.haml @@ -9,7 +9,7 @@ = @project.name %ul.sidebar-top-level-items = nav_link(path: sidebar_projects_paths, html_options: { class: 'home' }) do - = link_to project_path(@project), class: 'shortcuts-project qa-link-project' do + = link_to project_path(@project), class: 'shortcuts-project rspec-project-link', data: { qa_selector: 'project_link' } do .nav-icon-container = sprite_icon('home') %span.nav-item-name @@ -26,7 +26,7 @@ %span= _('Details') = nav_link(path: 'projects#activity') do - = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity qa-activity-link' do + = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity', data: { qa_selector: 'activity_link' } do %span= _('Activity') - if project_nav_tab?(:releases) @@ -34,10 +34,6 @@ = link_to project_releases_path(@project), title: _('Releases'), class: 'shortcuts-project-releases' do %span= _('Releases') - = render_if_exists 'projects/sidebar/security_dashboard' - - = render_if_exists 'projects/sidebar/dependencies' - - if can?(current_user, :read_cycle_analytics, @project) = nav_link(path: 'cycle_analytics#show') do = link_to project_cycle_analytics_path(@project), title: _('Cycle Analytics'), class: 'shortcuts-project-cycle-analytics' do @@ -119,7 +115,7 @@ = _('List') = nav_link(controller: :boards) do - = link_to project_boards_path(@project), title: boards_link_text do + = link_to project_boards_path(@project), title: boards_link_text, data: { qa_selector: "issue_boards_link" } do %span = boards_link_text @@ -150,7 +146,7 @@ - if project_nav_tab? :merge_requests = nav_link(controller: @project.issues_enabled? ? :merge_requests : [:merge_requests, :labels, :milestones]) do - = link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests qa-merge-requests-link' do + = link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests', data: { qa_selector: 'merge_requests_link' } do .nav-icon-container = sprite_icon('git-merge') %span.nav-item-name#js-onboarding-mr-link @@ -167,7 +163,7 @@ - if project_nav_tab? :pipelines = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts]) do - = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines' do + = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines' do .nav-icon-container = sprite_icon('rocket') %span.nav-item-name#js-onboarding-pipelines-link @@ -203,6 +199,8 @@ %span = _('Charts') + = render_if_exists 'layouts/nav/sidebar/project_security_link' # EE-specific + - if project_nav_tab? :operations = nav_link(controller: sidebar_operations_paths) do = link_to sidebar_operations_link_path, class: 'shortcuts-operations qa-link-operations' do @@ -274,25 +272,12 @@ = render_if_exists 'layouts/nav/sidebar/project_feature_flags_link' - - if project_nav_tab? :container_registry - = nav_link(controller: %w[projects/registry/repositories]) do - = link_to project_container_registry_index_path(@project), class: 'shortcuts-container-registry' do - .nav-icon-container - = sprite_icon('disk') - %span.nav-item-name - = _('Registry') - %ul.sidebar-sub-level-items.is-fly-out-only - = nav_link(controller: %w[projects/registry/repositories], html_options: { class: "fly-out-top-item" } ) do - = link_to project_container_registry_index_path(@project) do - %strong.fly-out-top-item-name - = _('Registry') - = render_if_exists 'layouts/nav/sidebar/project_packages_link' - if project_nav_tab? :wiki - wiki_url = project_wiki_path(@project, :home) = nav_link(controller: :wikis) do - = link_to wiki_url, class: 'shortcuts-wiki qa-wiki-link' do + = link_to wiki_url, class: 'shortcuts-wiki', data: { qa_selector: 'wiki_link' } do .nav-icon-container = sprite_icon('book') %span.nav-item-name diff --git a/app/views/layouts/nav/sidebar/_project_packages_link.html.haml b/app/views/layouts/nav/sidebar/_project_packages_link.html.haml new file mode 100644 index 00000000000..0fdfc6cd2ab --- /dev/null +++ b/app/views/layouts/nav/sidebar/_project_packages_link.html.haml @@ -0,0 +1,16 @@ +- if project_nav_tab? :container_registry + = nav_link controller: :repositories do + = link_to project_container_registry_index_path(@project) do + .nav-icon-container + = sprite_icon('package') + %span.nav-item-name + = _('Packages') + %ul.sidebar-sub-level-items + = nav_link(controller: :repositories, html_options: { class: "fly-out-top-item" } ) do + = link_to project_container_registry_index_path(@project) do + %strong.fly-out-top-item-name + = _('Packages') + %li.divider.fly-out-top-item + = nav_link controller: :repositories do + = link_to project_container_registry_index_path(@project), class: 'shortcuts-container-registry', title: _('Container Registry') do + %span= _('Container Registry') diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml index 6b51483810e..b8ef38272fc 100644 --- a/app/views/layouts/project.html.haml +++ b/app/views/layouts/project.html.haml @@ -7,8 +7,8 @@ - content_for :project_javascripts do - project = @target_project || @project - if current_user - -# haml-lint:disable InlineJavaScript - :javascript - window.uploads_path = "#{project_uploads_path(project)}"; + = javascript_tag nonce: true do + :plain + window.uploads_path = "#{project_uploads_path(project)}"; = render template: "layouts/application" diff --git a/app/views/layouts/snippets.html.haml b/app/views/layouts/snippets.html.haml index 841b2a5e79c..cde2b467392 100644 --- a/app/views/layouts/snippets.html.haml +++ b/app/views/layouts/snippets.html.haml @@ -3,8 +3,8 @@ - content_for :page_specific_javascripts do - if snippets_upload_path - -# haml-lint:disable InlineJavaScript - :javascript - window.uploads_path = "#{snippets_upload_path}"; + = javascript_tag nonce: true do + :plain + window.uploads_path = "#{snippets_upload_path}"; = render template: "layouts/application" diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml index 2ddea0b9f16..8fecdc6e8a6 100644 --- a/app/views/notify/new_merge_request_email.html.haml +++ b/app/views/notify/new_merge_request_email.html.haml @@ -5,7 +5,7 @@ .branch = merge_path_description(@merge_request, 'to') .author - Author #{@merge_request.author_name} + Author: #{@merge_request.author_name} .assignee = assignees_label(@merge_request) .approvers diff --git a/app/views/notify/pages_domain_disabled_email.html.haml b/app/views/notify/pages_domain_disabled_email.html.haml index 224b79bfde8..44f85df97b9 100644 --- a/app/views/notify/pages_domain_disabled_email.html.haml +++ b/app/views/notify/pages_domain_disabled_email.html.haml @@ -8,6 +8,6 @@ Domain: #{link_to @domain.domain, project_pages_domain_url(@project, @domain)} %p If this domain has been disabled in error, please follow - = link_to 'these instructions', help_page_url('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') + = link_to 'these instructions', help_page_url('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: '4-verify-the-domains-ownership') to verify and re-enable your domain. = render 'removal_notification' diff --git a/app/views/notify/pages_domain_disabled_email.text.haml b/app/views/notify/pages_domain_disabled_email.text.haml index 4e81b054b1f..5a0fcab72d4 100644 --- a/app/views/notify/pages_domain_disabled_email.text.haml +++ b/app/views/notify/pages_domain_disabled_email.text.haml @@ -7,7 +7,7 @@ Domain: #{@domain.domain} (#{project_pages_domain_url(@project, @domain)}) If this domain has been disabled in error, please follow these instructions to verify and re-enable your domain: -= help_page_url('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') += help_page_url('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: 'steps') If you no longer wish to use this domain with GitLab Pages, please remove it from your GitLab project and delete any related DNS records. diff --git a/app/views/notify/pages_domain_enabled_email.html.haml b/app/views/notify/pages_domain_enabled_email.html.haml index db09e503f65..103b17a87df 100644 --- a/app/views/notify/pages_domain_enabled_email.html.haml +++ b/app/views/notify/pages_domain_enabled_email.html.haml @@ -7,5 +7,5 @@ Domain: #{link_to @domain.domain, project_pages_domain_url(@project, @domain)} %p Please visit - = link_to 'these instructions', help_page_url('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') + = link_to 'these instructions', help_page_url('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: 'steps') for more information about custom domain verification. diff --git a/app/views/notify/pages_domain_enabled_email.text.haml b/app/views/notify/pages_domain_enabled_email.text.haml index 1ed1dbb8315..bf8d2ac767a 100644 --- a/app/views/notify/pages_domain_enabled_email.text.haml +++ b/app/views/notify/pages_domain_enabled_email.text.haml @@ -5,5 +5,5 @@ Project: #{@project.human_name} (#{project_url(@project)}) Domain: #{@domain.domain} (#{project_pages_domain_url(@project, @domain)}) Please visit -= help_page_url('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') += help_page_url('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: 'steps') for more information about custom domain verification. diff --git a/app/views/notify/pages_domain_verification_failed_email.html.haml b/app/views/notify/pages_domain_verification_failed_email.html.haml index 03b298f8e7c..a819b66f18e 100644 --- a/app/views/notify/pages_domain_verification_failed_email.html.haml +++ b/app/views/notify/pages_domain_verification_failed_email.html.haml @@ -10,6 +10,6 @@ Until then, you can view your content at #{link_to @domain.url, @domain.url} %p Please visit - = link_to 'these instructions', help_page_url('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') + = link_to 'these instructions', help_page_url('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: 'steps') for more information about custom domain verification. = render 'removal_notification' diff --git a/app/views/notify/pages_domain_verification_failed_email.text.haml b/app/views/notify/pages_domain_verification_failed_email.text.haml index c14e0e0c24d..85aa2d7a503 100644 --- a/app/views/notify/pages_domain_verification_failed_email.text.haml +++ b/app/views/notify/pages_domain_verification_failed_email.text.haml @@ -7,7 +7,7 @@ Unless you take action, it will be disabled on *#{@domain.enabled_until.strftime Until then, you can view your content at #{@domain.url} Please visit -= help_page_url('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') += help_page_url('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: 'steps') for more information about custom domain verification. If you no longer wish to use this domain with GitLab Pages, please remove it diff --git a/app/views/notify/pages_domain_verification_succeeded_email.html.haml b/app/views/notify/pages_domain_verification_succeeded_email.html.haml index 2ead3187b10..808b12948f9 100644 --- a/app/views/notify/pages_domain_verification_succeeded_email.html.haml +++ b/app/views/notify/pages_domain_verification_succeeded_email.html.haml @@ -9,5 +9,5 @@ content at #{link_to @domain.url, @domain.url} %p Please visit - = link_to 'these instructions', help_page_url('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') + = link_to 'these instructions', help_page_url('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: 'steps') for more information about custom domain verification. diff --git a/app/views/notify/pages_domain_verification_succeeded_email.text.haml b/app/views/notify/pages_domain_verification_succeeded_email.text.haml index e7cdbdee420..8d0694ef613 100644 --- a/app/views/notify/pages_domain_verification_succeeded_email.text.haml +++ b/app/views/notify/pages_domain_verification_succeeded_email.text.haml @@ -6,5 +6,5 @@ Domain: #{@domain.domain} (#{project_pages_domain_url(@project, @domain)}) No action is required on your part. You can view your content at #{@domain.url} Please visit -= help_page_url('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record') += help_page_url('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: 'steps') for more information about custom domain verification. diff --git a/app/views/peek/_bar.html.haml b/app/views/peek/_bar.html.haml index 89d3b931f88..5228930293c 100644 --- a/app/views/peek/_bar.html.haml +++ b/app/views/peek/_bar.html.haml @@ -2,6 +2,5 @@ #js-peek{ data: { env: Peek.env, request_id: Peek.request_id, - peek_url: "#{peek_routes_path}/results", - profile_url: url_for(safe_params.merge(lineprofiler: 'true')) }, + peek_url: "#{peek_routes_path}/results" }, class: Peek.env } diff --git a/app/views/peek/views/_gc.html.haml b/app/views/peek/views/_gc.html.haml deleted file mode 100644 index 2a586261ce1..00000000000 --- a/app/views/peek/views/_gc.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- local_assigns.fetch(:view) - -%span.bold - %span{ title: _('Invoke Time'), data: { defer_to: "#{view.defer_key}-gc_time" } }... - \/ - %span{ title: _('Invoke Count'), data: { defer_to: "#{view.defer_key}-invokes" } }... -gc diff --git a/app/views/peek/views/_redis.html.haml b/app/views/peek/views/_redis.html.haml deleted file mode 100644 index f7fba6c95fc..00000000000 --- a/app/views/peek/views/_redis.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- local_assigns.fetch(:view) - -%span.bold - %span{ data: { defer_to: "#{view.defer_key}-duration" } }... - \/ - %span{ data: { defer_to: "#{view.defer_key}-calls" } }... -redis diff --git a/app/views/peek/views/_sidekiq.html.haml b/app/views/peek/views/_sidekiq.html.haml deleted file mode 100644 index 7efbc05890d..00000000000 --- a/app/views/peek/views/_sidekiq.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- local_assigns.fetch(:view) - -%span.bold - %span{ data: { defer_to: "#{view.defer_key}-duration" } }... - \/ - %span{ data: { defer_to: "#{view.defer_key}-calls" } }... -sidekiq diff --git a/app/views/profiles/notifications/_group_settings.html.haml b/app/views/profiles/notifications/_group_settings.html.haml index cf17ee44145..1776d260e19 100644 --- a/app/views/profiles/notifications/_group_settings.html.haml +++ b/app/views/profiles/notifications/_group_settings.html.haml @@ -1,16 +1,15 @@ +- emails_disabled = group.emails_disabled? + .gl-responsive-table-row.notification-list-item .table-section.section-40 %span.notification.fa.fa-holder.append-right-5 - - if setting.global? - = notification_icon(current_user.global_notification_setting.level) - - else - = notification_icon(setting.level) + = notification_icon(notification_icon_level(setting, emails_disabled)) %span.str-truncated = link_to group.name, group_path(group) .table-section.section-30.text-right - = render 'shared/notifications/button', notification_setting: setting + = render 'shared/notifications/button', notification_setting: setting, emails_disabled: emails_disabled .table-section.section-30 = form_for @user.notification_settings.find { |ns| ns.source == group }, url: profile_notifications_group_path(group), method: :put, html: { class: 'update-notifications' } do |f| diff --git a/app/views/profiles/notifications/_project_settings.html.haml b/app/views/profiles/notifications/_project_settings.html.haml index 823fec3fab4..63a77b335b6 100644 --- a/app/views/profiles/notifications/_project_settings.html.haml +++ b/app/views/profiles/notifications/_project_settings.html.haml @@ -1,12 +1,11 @@ +- emails_disabled = project.emails_disabled? + %li.notification-list-item %span.notification.fa.fa-holder.append-right-5 - - if setting.global? - = notification_icon(current_user.global_notification_setting.level) - - else - = notification_icon(setting.level) + = notification_icon(notification_icon_level(setting, emails_disabled)) %span.str-truncated = link_to_project(project) .float-right - = render 'shared/notifications/button', notification_setting: setting + = render 'shared/notifications/button', notification_setting: setting, emails_disabled: emails_disabled diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 65ef9690062..08a39fc4f58 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -31,7 +31,7 @@ = s_('AccessTokens|It cannot be used to access any other data.') .col-lg-8.feed-token-reset = label_tag :feed_token, s_('AccessTokens|Feed token'), class: "label-bold" - = text_field_tag :feed_token, current_user.feed_token, class: 'form-control', readonly: true, onclick: 'this.select()' + = text_field_tag :feed_token, current_user.feed_token, class: 'form-control js-select-on-focus', readonly: true %p.form-text.text-muted - reset_link = link_to s_('AccessTokens|reset it'), [:reset, :feed_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working.') } - reset_message = s_('AccessTokens|Keep this token secret. Anyone who gets ahold of it can read activity and issue RSS feeds or your calendar feed as if they were you. You should %{link_reset_it} if that ever happens.') % { link_reset_it: reset_link } @@ -49,7 +49,7 @@ = s_('AccessTokens|It cannot be used to access any other data.') .col-lg-8.incoming-email-token-reset = label_tag :incoming_email_token, s_('AccessTokens|Incoming email token'), class: "label-bold" - = text_field_tag :incoming_email_token, current_user.incoming_email_token, class: 'form-control', readonly: true, onclick: 'this.select()' + = text_field_tag :incoming_email_token, current_user.incoming_email_token, class: 'form-control js-select-on-focus', readonly: true %p.form-text.text-muted - reset_link = link_to s_('AccessTokens|reset it'), [:reset, :incoming_email_token, :profile], method: :put, data: { confirm: s_('AccessTokens|Are you sure? Any issue email addresses currently in use will stop working.') } - reset_message = s_('AccessTokens|Keep this token secret. Anyone who gets ahold of it can create issues as if they were you. You should %{link_reset_it} if that ever happens.') % { link_reset_it: reset_link } diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index d16e2dddbe0..0887e8e64da 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -45,20 +45,20 @@ .form-group = f.label :layout, class: 'label-bold' do = s_('Preferences|Layout width') - = f.select :layout, layout_choices, {}, class: 'form-control' + = f.select :layout, layout_choices, {}, class: 'select2' .form-text.text-muted - = s_('Preferences|Choose between fixed (max. 1280px) and fluid (100%%) application layout.') + = s_('Preferences|Choose between fixed (max. 1280px) and fluid (%{percentage}) application layout.').html_safe % { percentage: '100%' } .form-group = f.label :dashboard, class: 'label-bold' do = s_('Preferences|Default dashboard') - = f.select :dashboard, dashboard_choices, {}, class: 'form-control' + = f.select :dashboard, dashboard_choices, {}, class: 'select2' = render_if_exists 'profiles/preferences/group_overview_selector', f: f # EE-specific .form-group = f.label :project_view, class: 'label-bold' do = s_('Preferences|Project overview content') - = f.select :project_view, project_view_choices, {}, class: 'form-control' + = f.select :project_view, project_view_choices, {}, class: 'select2' .form-text.text-muted = s_('Preferences|Choose what content you want to see on a projectās overview page.') @@ -82,7 +82,7 @@ .form-group = f.label :first_day_of_week, class: 'label-bold' do = _('First day of the week') - = f.select :first_day_of_week, first_day_of_week_choices_with_default, {}, class: 'form-control' + = f.select :first_day_of_week, first_day_of_week_choices_with_default, {}, class: 'select2' - if Feature.enabled?(:user_time_settings) .col-sm-12 %hr diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index e36d5192a29..ffb90bbd354 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -89,10 +89,10 @@ .col-lg-8 .row - if @user.read_only_attribute?(:name) - = f.text_field :name, required: true, readonly: true, wrapper: { class: 'col-md-9 qa-full-name' }, + = f.text_field :name, required: true, readonly: true, wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Your name was automatically set based on your %{provider_label} account, so people you know can recognize you") % { provider_label: attribute_provider_label(:name) } - else - = f.text_field :name, label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you") + = f.text_field :name, label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you") = f.text_field :id, readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' } = render_if_exists 'profiles/email_settings', form: f diff --git a/app/views/projects/_export.html.haml b/app/views/projects/_export.html.haml index 1056977886a..e42772c2dd9 100644 --- a/app/views/projects/_export.html.haml +++ b/app/views/projects/_export.html.haml @@ -15,6 +15,7 @@ %li= _('Project configuration, including services') %li= _('Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities') %li= _('LFS objects') + %li= _('Issue Boards') %p= _('The following items will NOT be exported:') %ul %li= _('Job traces and artifacts') diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml index 6763513f9ae..95fdad125a7 100644 --- a/app/views/projects/_files.html.haml +++ b/app/views/projects/_files.html.haml @@ -20,6 +20,9 @@ - if vue_file_list_enabled? #js-tree-list{ data: { project_path: @project.full_path, project_short_path: @project.path, ref: ref, full_name: @project.name_with_namespace } } + - if can_edit_tree? + = render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: project_create_blob_path(@project, @id), method: :post + = render 'projects/blob/new_dir' - if @tree.readme = render "projects/tree/readme", readme: @tree.readme - else diff --git a/app/views/projects/_flash_messages.html.haml b/app/views/projects/_flash_messages.html.haml index d95045c9cce..f9222387e97 100644 --- a/app/views/projects/_flash_messages.html.haml +++ b/app/views/projects/_flash_messages.html.haml @@ -5,7 +5,7 @@ - if current_user && can?(current_user, :download_code, project) = render 'shared/no_ssh' = render 'shared/no_password' - = render_if_exists 'shared/shared_runners_minutes_limit', project: project - unless project.empty_repo? = render 'shared/auto_devops_implicitly_enabled_banner', project: project = render_if_exists 'projects/above_size_limit_warning', project: project + = render_if_exists 'shared/shared_runners_minutes_limit', project: project, classes: [container_class, ("limit-container-width" unless fluid_layout)] diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 824fe3c791d..4783b10cf6d 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -1,6 +1,8 @@ - empty_repo = @project.empty_repo? - show_auto_devops_callout = show_auto_devops_callout?(@project) - max_project_topic_length = 15 +- emails_disabled = @project.emails_disabled? + .project-home-panel{ class: [("empty-project" if empty_repo), ("js-keep-hidden-on-navigation" if vue_file_list_enabled?)] } .row.append-bottom-8 .home-panel-title-row.col-md-12.col-lg-6.d-flex @@ -41,7 +43,7 @@ .project-repo-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end - if current_user .d-inline-flex - = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn-xs' + = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn-xs', emails_disabled: emails_disabled .count-buttons.d-inline-flex = render 'projects/buttons/star' diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml index 7541737f79c..5d88be0925e 100644 --- a/app/views/projects/_new_project_fields.html.haml +++ b/app/views/projects/_new_project_fields.html.haml @@ -54,7 +54,7 @@ .form-group.row.initialize-with-readme-setting %div{ :class => "col-sm-12" } .form-check - = check_box_tag 'project[initialize_with_readme]', '1', false, class: 'form-check-input qa-initialize-with-readme-checkbox', data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "init_with_readme" } + = check_box_tag 'project[initialize_with_readme]', '1', false, class: 'form-check-input qa-initialize-with-readme-checkbox', data: { track_label: "#{track_label}", track_event: "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') @@ -62,4 +62,4 @@ = 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 btn-success project-submit", data: { track_label: "#{track_label}", track_event: "click_button", track_property: "create_project", track_value: "" } -= link_to _('Cancel'), dashboard_projects_path, class: 'btn btn-cancel', data: { track_label: "#{track_label}", track_event: "click_button", track_property: "cancel" } += link_to _('Cancel'), dashboard_projects_path, class: 'btn btn-cancel', data: { track_label: "#{track_label}", track_event: "click_button", track_property: "cancel", track_value: "" } diff --git a/app/views/projects/buttons/_star.html.haml b/app/views/projects/buttons/_star.html.haml index 090d1549aa7..02e5297528b 100644 --- a/app/views/projects/buttons/_star.html.haml +++ b/app/views/projects/buttons/_star.html.haml @@ -8,7 +8,8 @@ = sprite_icon('star-o', { css_class: 'icon' }) %span= s_('ProjectOverview|Star') %span.star-count.count-badge-count.d-flex.align-items-center - = @project.star_count + = link_to project_starrers_path(@project), title: n_(s_('ProjectOverview|Starrer'), s_('ProjectOverview|Starrers'), @project.star_count), class: 'count' do + = @project.star_count - else .count-badge.d-inline-flex.align-item-stretch.append-right-8 @@ -16,4 +17,5 @@ = sprite_icon('star-o', { css_class: 'icon' }) %span= s_('ProjectOverview|Star') %span.star-count.count-badge-count.d-flex.align-items-center - = @project.star_count + = link_to project_starrers_path(@project), title: n_(s_('ProjectOverview|Starrer'), s_('ProjectOverview|Starrers'), @project.star_count), class: 'count' do + = @project.star_count diff --git a/app/views/projects/commit/_ajax_signature.html.haml b/app/views/projects/commit/_ajax_signature.html.haml index ae9aef5a9b0..e1bf0940f59 100644 --- a/app/views/projects/commit/_ajax_signature.html.haml +++ b/app/views/projects/commit/_ajax_signature.html.haml @@ -1,2 +1,2 @@ - if commit.has_signature? - %a{ href: 'javascript:void(0)', tabindex: 0, class: commit_signature_badge_classes('js-loading-gpg-badge'), data: { toggle: 'tooltip', placement: 'top', title: _('GPG signature (loading...)'), 'commit-sha' => commit.sha } } + %button{ tabindex: 0, class: commit_signature_badge_classes('js-loading-gpg-badge'), data: { toggle: 'tooltip', placement: 'top', title: _('GPG signature (loading...)'), 'commit-sha' => commit.sha } } diff --git a/app/views/projects/commit/_signature_badge.html.haml b/app/views/projects/commit/_signature_badge.html.haml index 1331fa179fc..cbd998c60ef 100644 --- a/app/views/projects/commit/_signature_badge.html.haml +++ b/app/views/projects/commit/_signature_badge.html.haml @@ -24,5 +24,5 @@ = link_to(_('Learn more about signing commits'), help_page_path('user/project/repository/gpg_signed_commits/index.md'), class: 'gpg-popover-help-link') -%a{ href: 'javascript:void(0)', tabindex: 0, class: css_classes, data: { toggle: 'popover', html: 'true', placement: 'top', title: title, content: content } } +%button{ tabindex: 0, class: css_classes, data: { toggle: 'popover', html: 'true', placement: 'top', title: title, content: content } } = label diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml index 59f0afd59e6..2b594c125f4 100644 --- a/app/views/projects/cycle_analytics/show.html.haml +++ b/app/views/projects/cycle_analytics/show.html.haml @@ -34,40 +34,29 @@ {{ n__('Last %d day', 'Last %d days', 90) }} .stage-panel-container .card.stage-panel - .card-header + .card-header.border-bottom-0 %nav.col-headers %ul - %li.stage-header - %span.stage-name + %li.stage-header.pl-5 + %span.stage-name.font-weight-bold {{ s__('ProjectLifecycle|Stage') }} %i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The phase of the development lifecycle."), "aria-hidden" => "true" } %li.median-header - %span.stage-name + %span.stage-name.font-weight-bold {{ __('Median') }} %i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."), "aria-hidden" => "true" } - %li.event-header - %span.stage-name + %li.event-header.pl-3 + %span.stage-name.font-weight-bold {{ currentStage ? __(currentStage.legend) : __('Related Issues') }} %i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The collection of events added to the data gathered for that stage."), "aria-hidden" => "true" } - %li.total-time-header - %span.stage-name + %li.total-time-header.pr-5.text-right + %span.stage-name.font-weight-bold {{ __('Total Time') }} %i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The time taken by each data entry gathered by that stage."), "aria-hidden" => "true" } .stage-panel-body %nav.stage-nav %ul - %li.stage-nav-item{ ':class' => '{ active: stage.active }', '@click' => 'selectStage(stage)', "v-for" => "stage in state.stages" } - .stage-nav-item-cell.stage-name - {{ stage.title }} - .stage-nav-item-cell.stage-median - %template{ "v-if" => "stage.isUserAllowed" } - %span{ "v-if" => "stage.value" } - {{ stage.value }} - %span.stage-empty{ "v-else" => true } - {{ __('Not enough data') }} - %template{ "v-else" => true } - %span.not-available - {{ __('Not available') }} + %stage-nav-item{ "v-for" => "stage in state.stages", ":key" => '`ca-stage-title-${stage.title}`', '@select' => 'selectStage(stage)', ":title" => "stage.title", ":is-user-allowed" => "stage.isUserAllowed", ":value" => "stage.value", ":is-active" => "stage.active" } .section.stage-events %template{ "v-if" => "isLoadingStage" } = icon("spinner spin") diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml index a11e23b6daa..752be02443c 100644 --- a/app/views/projects/deployments/_deployment.html.haml +++ b/app/views/projects/deployments/_deployment.html.haml @@ -15,10 +15,10 @@ .flex-truncate-child = link_to [@project.namespace.becomes(Namespace), @project, deployment.deployable], class: 'build-link' do #{deployment.deployable.name} (##{deployment.deployable.id}) - - if deployment.user + - if deployment.deployed_by %div by - = user_avatar(user: deployment.user, size: 20, css_class: "mr-0 float-none") + = user_avatar(user: deployment.deployed_by, size: 20, css_class: "mr-0 float-none") .table-section.section-15{ role: 'gridcell' } .table-mobile-header{ role: 'rowheader' }= _("Created") diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 3403564992e..763cc764144 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -23,7 +23,7 @@ .js-project-permissions-form = f.submit _('Save changes'), class: "btn btn-success" -%section.qa-merge-request-settings.settings.merge-requests-feature.no-animate#js-merge-request-settings{ class: [('expanded' if expanded), ('hidden' if @project.project_feature.send(:merge_requests_access_level) == 0)] } +%section.qa-merge-request-settings.rspec-merge-request-settings.settings.merge-requests-feature.no-animate#js-merge-request-settings{ class: [('expanded' if expanded), ('hidden' if @project.project_feature.send(:merge_requests_access_level) == 0)] } .settings-header %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Merge requests') %button.btn.btn-default.js-settings-toggle{ type: 'button' }= expanded ? _('Collapse') : _('Expand') @@ -35,7 +35,7 @@ = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "merge-request-settings-form js-mr-settings-form" }, authenticity_token: true do |f| %input{ name: 'update_section', type: 'hidden', value: 'js-merge-request-settings' } = render 'projects/merge_request_settings', form: f - = f.submit _('Save changes'), class: "btn btn-success qa-save-merge-request-changes" + = f.submit _('Save changes'), class: "btn btn-success qa-save-merge-request-changes rspec-save-merge-request-changes" = render_if_exists 'projects/merge_request_approvals_settings', expanded: expanded diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml index c13a47b0b09..6100fd3ad37 100644 --- a/app/views/projects/environments/show.html.haml +++ b/app/views/projects/environments/show.html.haml @@ -3,6 +3,9 @@ - breadcrumb_title @environment.name - page_title _("Environments") +- content_for :page_specific_javascripts do + = stylesheet_link_tag 'page_bundles/xterm' + %div{ class: container_class } - if can?(current_user, :stop_environment, @environment) #stop-environment-modal.modal.fade{ tabindex: -1 } diff --git a/app/views/projects/forks/_fork_button.html.haml b/app/views/projects/forks/_fork_button.html.haml index 3f0798a898d..c7ed6a5094d 100644 --- a/app/views/projects/forks/_fork_button.html.haml +++ b/app/views/projects/forks/_fork_button.html.haml @@ -5,9 +5,9 @@ .bordered-box.fork-thumbnail.text-center.prepend-left-default.append-right-default.prepend-top-default.append-bottom-default.forked = link_to project_path(forked_project) do - if /no_((\w*)_)*avatar/.match(avatar) - = group_icon(namespace, class: "avatar rect-avatar s100 identicon") + = group_icon(namespace, class: "avatar rect-avatar s100 identicon mx-auto") - else - .avatar-container.s100 + .avatar-container.s100.mx-auto = image_tag(avatar, class: "avatar s100") %h5.prepend-top-default = namespace.human_name @@ -18,9 +18,9 @@ class: ("disabled has-tooltip" unless can_create_project), title: (_('You have reached your project limit') unless can_create_project) do - if /no_((\w*)_)*avatar/.match(avatar) - = group_icon(namespace, class: "avatar rect-avatar s100 identicon") + = group_icon(namespace, class: "avatar rect-avatar s100 identicon mx-auto") - else - .avatar-container.s100 + .avatar-container.s100.mx-auto = image_tag(avatar, class: "avatar s100") %h5.prepend-top-default = namespace.human_name diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 4759991449e..de0c21e7cf6 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -45,7 +45,7 @@ %ul.controls - if issue.closed? %li.issuable-status - CLOSED + = _('CLOSED') - if issue.assignees.any? %li = render 'shared/issuable/assignees', project: @project, issuable: issue @@ -53,4 +53,5 @@ = render 'shared/issuable_meta_data', issuable: issue .float-right.issuable-updated-at.d-none.d-sm-inline-block - %span updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')} + %span + = _('updated %{time_ago}').html_safe % { time_ago: time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago') } diff --git a/app/views/projects/issues/import_csv/_modal.html.haml b/app/views/projects/issues/import_csv/_modal.html.haml index 86bc54786ad..fe4a4236896 100644 --- a/app/views/projects/issues/import_csv/_modal.html.haml +++ b/app/views/projects/issues/import_csv/_modal.html.haml @@ -20,5 +20,5 @@ = _('It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected.') = _('The maximum file size allowed is %{size}.') % { size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes) } .modal-footer - %button{ type: 'submit', class: 'btn btn-success', title: _('Import issues'), data: { track_label: "export_issues_csv", track_event: "click_button"} } + %button{ type: 'submit', class: 'btn btn-success', title: _('Import issues'), data: { track_label: "export_issues_csv", track_event: "click_button", track_value: ""} } = _('Import issues') diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml index 81a53f22f67..a3688c17041 100644 --- a/app/views/projects/jobs/show.html.haml +++ b/app/views/projects/jobs/show.html.haml @@ -7,8 +7,10 @@ = stylesheet_link_tag 'page_bundles/xterm' %div{ class: container_class } - #js-job-vue-app{ data: { endpoint: project_job_path(@project, @build, format: :json), + #js-job-vue-app{ data: { endpoint: project_job_path(@project, @build, format: :json), project_path: @project.full_path, deployment_help_url: help_page_path('user/project/clusters/index.html', anchor: 'troubleshooting-failed-deployment-jobs'), runner_help_url: help_page_path('ci/runners/README.html', anchor: 'setting-maximum-job-timeout-for-a-runner'), runner_settings_url: project_runners_path(@build.project, anchor: 'js-runners-settings'), + variables_settings_url: project_variables_path(@build.project, anchor: 'js-cicd-variables-settings'), + page_path: project_job_path(@project, @build), build_status: @build.status, build_stage: @build.stage, log_state: '', build_options: javascript_build_options } } diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index eb516684e52..36f19ee6175 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -38,27 +38,28 @@ = link_to_label(label, type: :merge_request, css_class: 'label-link') .issuable-meta - %ul.controls + %ul.controls.d-flex.align-items-end - if merge_request.merged? %li.issuable-status.d-none.d-sm-inline-block - MERGED + = _('MERGED') - elsif merge_request.closed? %li.issuable-status.d-none.d-sm-inline-block = icon('ban') - CLOSED + = _('CLOSED') - if can?(current_user, :read_pipeline, merge_request.head_pipeline) - %li.issuable-pipeline-status.d-none.d-sm-inline-block - = render 'ci/status/icon', status: merge_request.head_pipeline.detailed_status(current_user) + %li.issuable-pipeline-status.d-none.d-sm-flex + = render 'ci/status/icon', status: merge_request.head_pipeline.detailed_status(current_user), option_css_classes: 'd-flex' - if merge_request.open? && merge_request.broken? - %li.issuable-pipeline-broken.d-none.d-sm-inline-block + %li.issuable-pipeline-broken.d-none.d-sm-flex = link_to merge_request_path(merge_request), class: "has-tooltip", title: _('Cannot be merged automatically') do = icon('exclamation-triangle') - if merge_request.assignees.any? - %li + %li.d-flex = render 'shared/issuable/assignees', project: merge_request.project, issuable: merge_request = render_if_exists 'projects/merge_requests/approvals_count', merge_request: merge_request = render 'shared/issuable_meta_data', issuable: merge_request .float-right.issuable-updated-at.d-none.d-sm-inline-block - %span updated #{time_ago_with_tooltip(merge_request.updated_at, placement: 'bottom', html_class: 'merge_request_updated_ago')} + %span + = _('updated %{time_ago}').html_safe % { time_ago: time_ago_with_tooltip(merge_request.updated_at, placement: 'bottom', html_class: 'merge_request_updated_ago') } 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 11272a67f93..be01905dd35 100644 --- a/app/views/projects/merge_requests/creations/_new_compare.html.haml +++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml @@ -2,6 +2,8 @@ New Merge Request = form_for [@project.namespace.becomes(Namespace), @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? + = hidden_field_tag(:nav_source, params[:nav_source]) .hide.alert.alert-danger.mr-compare-errors .js-merge-request-new-compare.row{ 'data-source-branch-url': project_new_merge_request_branch_from_path(@source_project), 'data-target-branch-url': project_new_merge_request_branch_to_path(@source_project) } .col-lg-6 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 464f8fa65e9..543441b9479 100644 --- a/app/views/projects/merge_requests/creations/_new_submit.html.haml +++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml @@ -17,6 +17,9 @@ = f.hidden_field :target_project_id = f.hidden_field :target_branch, id: '' + - if params[:nav_source].present? + = hidden_field_tag(:nav_source, params[:nav_source]) + .mr-compare.merge-request.js-merge-request-new-submit{ 'data-mr-submit-action': "#{j params[:tab].presence || 'new'}" } - if @commits.empty? .commits-empty diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml index 2084ca6f905..af3bd8dcd69 100644 --- a/app/views/projects/merge_requests/show.html.haml +++ b/app/views/projects/merge_requests/show.html.haml @@ -16,13 +16,13 @@ - if @merge_request.source_branch_exists? = render "projects/merge_requests/how_to_merge" - -# haml-lint:disable InlineJavaScript - :javascript - window.gl = window.gl || {}; - window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)} + = javascript_tag nonce: true do + :plain + window.gl = window.gl || {}; + window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)} - window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}'; - window.gl.mrWidgetData.troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/index.md', anchor: 'troubleshooting')}'; + window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}'; + window.gl.mrWidgetData.troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/index.md', anchor: 'troubleshooting')}'; #js-vue-mr-widget.mr-widget @@ -32,7 +32,7 @@ .merge-request-tabs-holder{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') } .merge-request-tabs-container %ul.merge-request-tabs.nav-tabs.nav.nav-links - %li.notes-tab.qa-notes-tab + %li.notes-tab{ data: { qa_selector: 'notes_tab'} } = tab_link_for @merge_request, :show, force_link: @commit.present? do = _("Discussion") %span.badge.badge-pill= @merge_request.related_notes.user.count diff --git a/app/views/projects/mirrors/_disabled_mirror_badge.html.haml b/app/views/projects/mirrors/_disabled_mirror_badge.html.haml index 356cb43f07f..9c11b650f75 100644 --- a/app/views/projects/mirrors/_disabled_mirror_badge.html.haml +++ b/app/views/projects/mirrors/_disabled_mirror_badge.html.haml @@ -1 +1 @@ -.badge.badge-warning.qa-disabled-mirror-badge{ data: { toggle: 'tooltip', html: 'true' }, title: _('Disabled mirrors can only be enabled by instance owners. It is recommended that you delete them.') }= _('Disabled') +.badge.badge-warning.qa-disabled-mirror-badge.rspec-disabled-mirror-badge{ data: { toggle: 'tooltip', html: 'true' }, title: _('Disabled mirrors can only be enabled by instance owners. It is recommended that you delete them.') }= _('Disabled') diff --git a/app/views/projects/mirrors/_instructions.html.haml b/app/views/projects/mirrors/_instructions.html.haml index 33e5a6e67c3..1a163cc4a54 100644 --- a/app/views/projects/mirrors/_instructions.html.haml +++ b/app/views/projects/mirrors/_instructions.html.haml @@ -2,7 +2,7 @@ %ul %li = _('The repository must be accessible over <code>http://</code>, - <code>https://</code>, <code>ssh://</code> and <code>git://</code>.').html_safe + <code>https://</code>, <code>ssh://</code> or <code>git://</code>.').html_safe %li= _('Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>.').html_safe %li - minutes = Gitlab.config.gitlab_shell.git_timeout / 60 diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml index e68fa5d08c7..6f8a93fbcf5 100644 --- a/app/views/projects/mirrors/_mirror_repos.html.haml +++ b/app/views/projects/mirrors/_mirror_repos.html.haml @@ -13,8 +13,6 @@ .settings-content = form_for @project, url: project_mirror_path(@project), html: { class: 'gl-show-field-errors js-mirror-form', autocomplete: 'new-password', data: mirrors_form_data_attributes } do |f| .panel.panel-default - .panel-heading - %h3.panel-title= _('Mirror a repository') .panel-body %div= form_errors(@project) @@ -43,16 +41,19 @@ = _('Mirrored repositories') = render_if_exists 'projects/mirrors/mirrored_repositories_count' %th= _('Direction') - %th= _('Last update') + %th= _('Last update attempt') + %th= _('Last successful update') %th %th %tbody.js-mirrors-table-body = render_if_exists 'projects/mirrors/table_pull_row' - @project.remote_mirrors.each_with_index do |mirror, index| - next if mirror.new_record? - %tr.qa-mirrored-repository-row{ class: ('bg-secondary' if mirror.disabled?) } + %tr.qa-mirrored-repository-row.rspec-mirrored-repository-row{ class: ('bg-secondary' if mirror.disabled?) } %td.qa-mirror-repository-url= mirror.safe_url %td= _('Push') + %td + = mirror.last_update_started_at.present? ? time_ago_with_tooltip(mirror.last_update_started_at) : _('Never') %td.qa-mirror-last-update-at= mirror.last_update_at.present? ? time_ago_with_tooltip(mirror.last_update_at) : _('Never') %td - if mirror.disabled? @@ -64,4 +65,4 @@ - if mirror.ssh_key_auth? = clipboard_button(text: mirror.ssh_public_key, class: 'btn btn-default', title: _('Copy SSH public key')) = render 'shared/remote_mirror_update_button', remote_mirror: mirror - %button.js-delete-mirror.qa-delete-mirror.btn.btn-danger{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= icon('trash-o') + %button.js-delete-mirror.qa-delete-mirror.rspec-delete-mirror.btn.btn-danger{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= icon('trash-o') diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 33de0aa153b..fabe636b05c 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -32,15 +32,15 @@ .col-lg-9.js-toggle-container %ul.nav.nav-tabs.nav-links.gitlab-tabs{ role: 'tablist' } %li.nav-item{ role: 'presentation' } - %a.nav-link.active{ href: '#blank-project-pane', id: 'blank-project-tab', data: { toggle: 'tab', track_label: 'blank_project', track_event: "click_tab" }, role: 'tab' } + %a.nav-link.active{ href: '#blank-project-pane', id: 'blank-project-tab', data: { toggle: 'tab', track_label: 'blank_project', track_event: "click_tab", track_value: "" }, role: 'tab' } %span.d-none.d-sm-block= s_('ProjectsNew|Blank project') %span.d-block.d-sm-none= s_('ProjectsNew|Blank') %li.nav-item{ role: 'presentation' } - %a.nav-link{ href: '#create-from-template-pane', id: 'create-from-template-tab', data: { toggle: 'tab', track_label: 'create_from_template', track_event: "click_tab" }, role: 'tab' } + %a.nav-link{ href: '#create-from-template-pane', id: 'create-from-template-tab', data: { toggle: 'tab', track_label: 'create_from_template', track_event: "click_tab", track_value: "" }, role: 'tab' } %span.d-none.d-sm-block.qa-project-create-from-template-tab= s_('ProjectsNew|Create from template') %span.d-block.d-sm-none= s_('ProjectsNew|Template') %li.nav-item{ role: 'presentation' } - %a.nav-link{ href: '#import-project-pane', id: 'import-project-tab', data: { toggle: 'tab', track_label: 'import_project', track_event: "click_tab" }, role: 'tab' } + %a.nav-link{ href: '#import-project-pane', id: 'import-project-tab', data: { toggle: 'tab', track_label: 'import_project', track_event: "click_tab", track_value: "" }, role: 'tab' } %span.d-none.d-sm-block= s_('ProjectsNew|Import project') %span.d-block.d-sm-none= s_('ProjectsNew|Import') = render_if_exists 'projects/new_ci_cd_only_project_tab', active_tab: active_tab @@ -51,7 +51,7 @@ = render 'new_project_fields', f: f, project_name_id: "blank-project-name" #create-from-template-pane.tab-pane.js-toggle-container.px-0.pb-0{ class: active_when(active_tab == 'template'), role: 'tabpanel' } - .card-slim.m-4.p-4 + .card.card-slim.m-4.p-4 %div - contributing_templates_url = 'https://gitlab.com/gitlab-org/project-templates/contributing' - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: contributing_templates_url } diff --git a/app/views/projects/pages_domains/_certificate.html.haml b/app/views/projects/pages_domains/_certificate.html.haml new file mode 100644 index 00000000000..42631fca5e8 --- /dev/null +++ b/app/views/projects/pages_domains/_certificate.html.haml @@ -0,0 +1,18 @@ +- if @domain.auto_ssl_enabled? + - if @domain.enabled? + - if @domain.certificate_text + %pre + = @domain.certificate_text + - else + .bs-callout.bs-callout-info + = _("GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later.") + - else + .bs-callout.bs-callout-warning + = _("A Let's Encrypt SSL certificate can not be obtained until your domain is verified.") +- else + - if @domain.certificate_text + %pre + = @domain.certificate_text + - else + .light + = _("missing") diff --git a/app/views/projects/pages_domains/_form.html.haml b/app/views/projects/pages_domains/_form.html.haml index 5b657966909..4aa1e574d93 100644 --- a/app/views/projects/pages_domains/_form.html.haml +++ b/app/views/projects/pages_domains/_form.html.haml @@ -11,7 +11,7 @@ - if Gitlab.config.pages.external_https - - auto_ssl_available = ::Gitlab::LetsEncrypt.enabled?(@domain) + - auto_ssl_available = ::Gitlab::LetsEncrypt.enabled? - auto_ssl_enabled = @domain.auto_ssl_enabled? - auto_ssl_available_and_enabled = auto_ssl_available && auto_ssl_enabled @@ -33,7 +33,7 @@ = sprite_icon("status_success_borderless", size: 16, css_class: "toggle-icon-svg toggle-status-checked") = sprite_icon("status_failed_borderless", size: 16, css_class: "toggle-icon-svg toggle-status-unchecked") %p.text-secondary.mt-3 - - docs_link_url = help_page_path("user/project/pages/lets_encrypt_for_gitlab_pages.md", anchor: "lets-encrypt-for-gitlab-pages") + - docs_link_url = help_page_path("user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md") - docs_link_start = "<a href=\"%{docs_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { docs_link_url: docs_link_url } - docs_link_end = "</a>".html_safe = _("Let's Encrypt is a free, automated, and open certificate authority (CA) that gives digital certificates in order to enable HTTPS (SSL/TLS) for websites. Learn more about Let's Encrypt configuration by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}.").html_safe % { docs_link_url: docs_link_url, docs_link_start: docs_link_start, docs_link_end: docs_link_end } diff --git a/app/views/projects/pages_domains/_helper_text.html.haml b/app/views/projects/pages_domains/_helper_text.html.haml index 5a79fefabfc..f29cb0609e6 100644 --- a/app/views/projects/pages_domains/_helper_text.html.haml +++ b/app/views/projects/pages_domains/_helper_text.html.haml @@ -1,9 +1,5 @@ -- docs_link_url = help_page_path("user/project/pages/getting_started_part_three.md", anchor: "adding-certificates-to-your-project") +- docs_link_url = help_page_path("user/project/pages/custom_domains_ssl_tls_certification/index.md", anchor: "adding-an-ssltls-certificate-to-pages") - docs_link_start = "<a href=\"%{docs_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { docs_link_url: docs_link_url } - docs_link_end = "</a>".html_safe --# Hiding behind a feature flag to avoid any changes to this feature's implemention --# when the :pages_auto_ssl feature flag is disabled. This check should be removed --# once the :pages_auto_ssl feature flag is removed. -- if Feature.enabled?(:pages_auto_ssl) - %p= _("Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}.").html_safe % { docs_link_url: docs_link_url, docs_link_start: docs_link_start, docs_link_end: docs_link_end } +%p= _("Learn more about adding certificates to your project by following the %{docs_link_start}documentation on GitLab Pages%{docs_link_end}.").html_safe % { docs_link_url: docs_link_url, docs_link_start: docs_link_start, docs_link_end: docs_link_end } diff --git a/app/views/projects/pages_domains/show.html.haml b/app/views/projects/pages_domains/show.html.haml index 82147568981..d0b54946f7e 100644 --- a/app/views/projects/pages_domains/show.html.haml +++ b/app/views/projects/pages_domains/show.html.haml @@ -53,16 +53,11 @@ .input-group-append = clipboard_button(target: '#domain_verification', class: 'btn-default d-none d-sm-block') %p.form-text.text-muted - - link_to_help = link_to(_('verify ownership'), help_page_path('user/project/pages/getting_started_part_three.md', anchor: 'dns-txt-record')) + - link_to_help = link_to(_('verify ownership'), help_page_path('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: '4-verify-the-domains-ownership')) = _("To %{link_to_help} of your domain, add the above key to a TXT record within to your DNS configuration.").html_safe % { link_to_help: link_to_help } %tr %td = _("Certificate") %td - - if @domain.certificate_text - %pre - = @domain.certificate_text - - else - .light - = _("missing") + = render 'certificate' diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 5d307d6a70d..53bb3c7487d 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -21,7 +21,7 @@ .icon-container = sprite_icon('flag') - if @pipeline.latest? - %span.js-pipeline-url-latest.badge.badge-success.has-tooltip{ title: _("Latest pipeline for this branch") } + %span.js-pipeline-url-latest.badge.badge-success.has-tooltip{ title: _("Latest pipeline for the most recent commit on this branch") } latest - if @pipeline.has_yaml_errors? %span.js-pipeline-url-yaml.badge.badge-danger.has-tooltip{ title: @pipeline.yaml_errors } @@ -43,7 +43,7 @@ } } Auto DevOps - if @pipeline.detached_merge_request_pipeline? - %span.js-pipeline-url-mergerequest.badge.badge-info.has-tooltip{ title: "This pipeline is run on the source branch" } + %span.js-pipeline-url-mergerequest.badge.badge-info.has-tooltip{ title: _('Pipelines for merge requests are configured. A detached pipeline runs in the context of the merge request, and not against the merged result. Learn more on the documentation for Pipelines for Merged Results.') } detached - if @pipeline.stuck? %span.js-pipeline-url-stuck.badge.badge-warning diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml index c04f076a3ab..56995ffbcee 100644 --- a/app/views/projects/pipelines/_with_tabs.html.haml +++ b/app/views/projects/pipelines/_with_tabs.html.haml @@ -1,7 +1,7 @@ .tabs-holder %ul.pipelines-tabs.nav-links.no-top.no-bottom.mobile-separator.nav.nav-tabs %li.js-pipeline-tab-link - = link_to project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-pipeline', action: 'pipelines', toggle: 'tab' }, class: 'pipeline-tab' do + = link_to @pipeline_path, data: { target: '#js-tab-pipeline', action: 'pipelines', toggle: 'tab' }, class: 'pipeline-tab' do = _('Pipeline') %li.js-builds-tab-link = link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml index 4d1d078661d..6b4110e07d2 100644 --- a/app/views/projects/pipelines/charts.html.haml +++ b/app/views/projects/pipelines/charts.html.haml @@ -2,12 +2,9 @@ - page_title _('CI / CD Charts') %div{ class: container_class } + #charts.ci-charts - .row - .col-md-6 - = render 'projects/pipelines/charts/overall' - .col-md-6 - = render 'projects/pipelines/charts/pipeline_times' + = render 'projects/pipelines/charts/overall' %hr = render 'projects/pipelines/charts/pipelines' diff --git a/app/views/projects/pipelines/charts/_overall.haml b/app/views/projects/pipelines/charts/_overall.haml index 66786c7ff59..651f9217455 100644 --- a/app/views/projects/pipelines/charts/_overall.haml +++ b/app/views/projects/pipelines/charts/_overall.haml @@ -1,15 +1,6 @@ -%h4= s_("PipelineCharts|Overall statistics") -%ul - %li - = s_("PipelineCharts|Total:") - %strong= n_("1 pipeline", "%d pipelines", @counts[:total]) % @counts[:total] - %li - = s_("PipelineCharts|Successful:") - %strong= n_("1 pipeline", "%d pipelines", @counts[:success]) % @counts[:success] - %li - = s_("PipelineCharts|Failed:") - %strong= n_("1 pipeline", "%d pipelines", @counts[:failed]) % @counts[:failed] - %li - = s_("PipelineCharts|Success ratio:") - %strong - #{success_ratio(@counts)}% +%h4.mt-4.mb-4= s_("PipelineCharts|Overall statistics") +.row + .col-md-6 + = render 'projects/pipelines/charts/pipeline_statistics' + .col-md-6 + = render 'projects/pipelines/charts/pipeline_times' diff --git a/app/views/projects/pipelines/charts/_pipeline_statistics.haml b/app/views/projects/pipelines/charts/_pipeline_statistics.haml new file mode 100644 index 00000000000..b323e290ed4 --- /dev/null +++ b/app/views/projects/pipelines/charts/_pipeline_statistics.haml @@ -0,0 +1,14 @@ +%ul + %li + = s_("PipelineCharts|Total:") + %strong= n_("1 pipeline", "%d pipelines", @counts[:total]) % @counts[:total] + %li + = s_("PipelineCharts|Successful:") + %strong= n_("1 pipeline", "%d pipelines", @counts[:success]) % @counts[:success] + %li + = s_("PipelineCharts|Failed:") + %strong= n_("1 pipeline", "%d pipelines", @counts[:failed]) % @counts[:failed] + %li + = s_("PipelineCharts|Success ratio:") + %strong + #{success_ratio(@counts)}% diff --git a/app/views/projects/pipelines/charts/_pipelines.haml b/app/views/projects/pipelines/charts/_pipelines.haml index 47f1f074210..afff9e82e45 100644 --- a/app/views/projects/pipelines/charts/_pipelines.haml +++ b/app/views/projects/pipelines/charts/_pipelines.haml @@ -1,4 +1,4 @@ -%h4= _("Pipelines charts") +%h4.mt-4.mb-4= _("Pipelines charts") %p %span.legend-success diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml index efabb7f7b19..149b0d6cddd 100644 --- a/app/views/projects/project_members/_new_project_member.html.haml +++ b/app/views/projects/project_members/_new_project_member.html.haml @@ -2,7 +2,7 @@ .col-sm-12 = form_for @project_member, as: :project_member, url: project_project_members_path(@project), html: { class: 'users-project-form' } do |f| .form-group - = label_tag :user_ids, _("Select members to invite"), class: "label-bold" + = label_tag :user_ids, _("GitLab member or Email address"), class: "label-bold" = users_select_tag(:user_ids, multiple: true, class: "input-clamp qa-member-select-input", scope: :all, email_user: true, placeholder: "Search for members to update or invite") .form-group = label_tag :access_level, _("Choose a role permission"), class: "label-bold" diff --git a/app/views/projects/project_members/_team.html.haml b/app/views/projects/project_members/_team.html.haml index f220299ec30..5310c1fad01 100644 --- a/app/views/projects/project_members/_team.html.haml +++ b/app/views/projects/project_members/_team.html.haml @@ -6,11 +6,11 @@ %span.flex-project-title = _("Members of <strong>%{project_name}</strong>").html_safe % { project_name: sanitize(project.name, tags: []) } %span.badge.badge-pill= members.total_count - = form_tag project_project_members_path(project), method: :get, class: 'form-inline member-search-form flex-project-members-form' do + = form_tag project_project_members_path(project), method: :get, class: 'form-inline user-search-form flex-users-form' do .form-group .position-relative = search_field_tag :search, params[:search], { placeholder: _('Find existing members by name'), class: 'form-control', spellcheck: false } - %button.member-search-btn{ type: "submit", "aria-label" => _("Submit search") } + %button.user-search-btn{ type: "submit", "aria-label" => _("Submit search") } = icon("search") = render 'shared/members/sort_dropdown' %ul.content-list.members-list.qa-members-list diff --git a/app/views/projects/project_templates/_built_in_templates.html.haml b/app/views/projects/project_templates/_built_in_templates.html.haml index 6159f1c3542..d1c09e83fd3 100644 --- a/app/views/projects/project_templates/_built_in_templates.html.haml +++ b/app/views/projects/project_templates/_built_in_templates.html.haml @@ -9,9 +9,9 @@ .text-muted = template.description .controls.d-flex.align-items-center - %a.btn.btn-default.append-right-10{ href: template.preview, rel: 'noopener noreferrer', target: '_blank', data: { track_label: "create_from_template", track_property: "template_preview", track_event: "click_button", track_value: template.name } } + %a.btn.btn-default.append-right-10{ href: template.preview, rel: 'noopener noreferrer', target: '_blank', data: { track_label: "template_preview", track_property: template.name, track_event: "click_button", track_value: "" } } = _("Preview") %label.btn.btn-success.template-button.choose-template.append-bottom-0{ for: template.name } - %input{ type: "radio", autocomplete: "off", name: "project[template_name]", id: template.name, value: template.name, data: { track_label: "create_from_template", track_property: "template_use", track_event: "click_button" } } + %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: "" } } %span = _("Use template") diff --git a/app/views/projects/protected_branches/_create_protected_branch.html.haml b/app/views/projects/protected_branches/_create_protected_branch.html.haml index 24b53555cdc..ee359a01e74 100644 --- a/app/views/projects/protected_branches/_create_protected_branch.html.haml +++ b/app/views/projects/protected_branches/_create_protected_branch.html.haml @@ -2,13 +2,13 @@ .merge_access_levels-container = dropdown_tag('Select', options: { toggle_class: 'js-allowed-to-merge qa-allowed-to-merge-select wide', - dropdown_class: 'dropdown-menu-selectable qa-allowed-to-merge-dropdown capitalize-header', + dropdown_class: 'dropdown-menu-selectable qa-allowed-to-merge-dropdown rspec-allowed-to-merge-dropdown capitalize-header', data: { field_name: 'protected_branch[merge_access_levels_attributes][0][access_level]', input_id: 'merge_access_levels_attributes' }}) - content_for :push_access_levels do .push_access_levels-container = dropdown_tag('Select', options: { toggle_class: 'js-allowed-to-push qa-allowed-to-push-select wide', - dropdown_class: 'dropdown-menu-selectable qa-allowed-to-push-dropdown capitalize-header', + dropdown_class: 'dropdown-menu-selectable qa-allowed-to-push-dropdown rspec-allowed-to-push-dropdown capitalize-header', data: { field_name: 'protected_branch[push_access_levels_attributes][0][access_level]', input_id: 'push_access_levels_attributes' }}) = render 'projects/protected_branches/shared/create_protected_branch' diff --git a/app/views/projects/serverless/functions/index.html.haml b/app/views/projects/serverless/functions/index.html.haml index 9c69aedfbfc..bac6c76684b 100644 --- a/app/views/projects/serverless/functions/index.html.haml +++ b/app/views/projects/serverless/functions/index.html.haml @@ -14,5 +14,5 @@ .js-serverless-functions-notice .flash-container - .top-area.adjust + .top-area.adjust.d-flex.justify-content-center .serverless-functions-table#js-serverless-functions diff --git a/app/views/projects/services/prometheus/_metrics.html.haml b/app/views/projects/services/prometheus/_metrics.html.haml index a1d74b91002..7685dee08fc 100644 --- a/app/views/projects/services/prometheus/_metrics.html.haml +++ b/app/views/projects/services/prometheus/_metrics.html.haml @@ -1,28 +1,35 @@ - project = local_assigns.fetch(:project) -.card.js-panel-monitored-metrics{ data: { active_metrics: active_common_project_prometheus_metrics_path(project, :json), metrics_help_path: help_page_path('user/project/integrations/prometheus_library/index') } } - .card-header - = s_('PrometheusService|Common metrics') - %span.badge.badge-pill.js-monitored-count 0 - .card-body - .loading-metrics.js-loading-metrics - %p.prepend-top-10.prepend-left-10 - = icon('spinner spin', class: 'metrics-load-spinner') - = s_('PrometheusService|Finding and configuring metrics...') - .empty-metrics.hidden.js-empty-metrics - %p.text-tertiary.prepend-top-10.prepend-left-10 - = s_('PrometheusService|Waiting for your first deployment to an environment to find common metrics') - %ul.list-unstyled.metrics-list.hidden.js-metrics-list +.col-lg-3 + %p + = s_('PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters.') + = link_to s_('PrometheusService|More information'), help_page_path('user/project/integrations/prometheus_library/index'), target: '_blank', rel: "noopener noreferrer" -.card.hidden.js-panel-missing-env-vars - .card-header - = icon('caret-right lg fw', class: 'panel-toggle js-panel-toggle', 'aria-label' => 'Toggle panel') - = s_('PrometheusService|Missing environment variable') - %span.badge.badge-pill.js-env-var-count 0 - .card-body.hidden - .flash-container - .flash-notice - .flash-text - = s_("PrometheusService|To set up automatic monitoring, add the environment variable %{variable} to exporter's queries." % { variable: "<code>$CI_ENVIRONMENT_SLUG</code>" }).html_safe - = link_to s_('PrometheusService|More information'), help_page_path('user/project/integrations/prometheus', anchor: 'metrics-and-labels') - %ul.list-unstyled.metrics-list.js-missing-var-metrics-list +.col-lg-9 + .card.js-panel-monitored-metrics{ data: { active_metrics: active_common_project_prometheus_metrics_path(project, :json), metrics_help_path: help_page_path('user/project/integrations/prometheus_library/index') } } + .card-header + %strong + = s_('PrometheusService|Common metrics') + %span.badge.badge-pill.js-monitored-count 0 + .card-body + .loading-metrics.js-loading-metrics + %p.m-3 + = icon('spinner spin', class: 'metrics-load-spinner') + = s_('PrometheusService|Finding and configuring metrics...') + .empty-metrics.hidden.js-empty-metrics + %p.text-tertiary.m-3 + = s_('PrometheusService|Waiting for your first deployment to an environment to find common metrics') + %ul.list-unstyled.metrics-list.hidden.js-metrics-list + + .card.hidden.js-panel-missing-env-vars + .card-header + = icon('caret-right lg fw', class: 'panel-toggle js-panel-toggle', 'aria-label' => 'Toggle panel') + = s_('PrometheusService|Missing environment variable') + %span.badge.badge-pill.js-env-var-count 0 + .card-body.hidden + .flash-container + .flash-notice + .flash-text + = s_("PrometheusService|To set up automatic monitoring, add the environment variable %{variable} to exporter's queries." % { variable: "<code>$CI_ENVIRONMENT_SLUG</code>" }).html_safe + = link_to s_('PrometheusService|More information'), help_page_path('user/project/integrations/prometheus', anchor: 'metrics-and-labels') + %ul.list-unstyled.metrics-list.js-missing-var-metrics-list diff --git a/app/views/projects/services/prometheus/_show.html.haml b/app/views/projects/services/prometheus/_show.html.haml index 6aafa85e99a..c719661d8e8 100644 --- a/app/views/projects/services/prometheus/_show.html.haml +++ b/app/views/projects/services/prometheus/_show.html.haml @@ -1,12 +1,9 @@ -.row.prepend-top-default.append-bottom-default.prometheus-metrics-monitoring.js-prometheus-metrics-monitoring +.row .col-lg-3 %h4.prepend-top-0 = s_('PrometheusService|Metrics') - %p - = s_('PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters.') - = link_to s_('PrometheusService|More information'), help_page_path('user/project/integrations/prometheus_library/index'), target: '_blank', rel: "noopener noreferrer" - .col-lg-9 - = render 'projects/services/prometheus/metrics', project: @project +.row.append-bottom-default.prometheus-metrics-monitoring.js-prometheus-metrics-monitoring + = render 'projects/services/prometheus/metrics', project: @project = render_if_exists 'projects/services/prometheus/external_alerts', project: @project diff --git a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml index fe74dc122c3..04b77fb987a 100644 --- a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml +++ b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml @@ -8,7 +8,7 @@ .card.auto-devops-card .card-body .form-check - = form.check_box :enabled, class: 'form-check-input js-toggle-extra-settings', checked: auto_devops_enabled + = form.check_box :enabled, class: 'form-check-input js-toggle-extra-settings', checked: auto_devops_enabled, data: { qa_selector: 'enable_autodevops_checkbox' } = form.label :enabled, class: 'form-check-label' do %strong= s_('CICD|Default to Auto DevOps pipeline') - if auto_devops_enabled @@ -42,4 +42,4 @@ = s_('CICD|Automatic deployment to staging, manual deployment to production') = link_to icon('question-circle'), help_page_path('topics/autodevops/index.md', anchor: 'incremental-rollout-to-production'), target: '_blank' - = f.submit _('Save changes'), class: "btn btn-success prepend-top-15" + = f.submit _('Save changes'), class: "btn btn-success prepend-top-15", data: { qa_selector: 'save_changes_button' } diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml index 2d108a1cba5..498a9744783 100644 --- a/app/views/projects/settings/ci_cd/_form.html.haml +++ b/app/views/projects/settings/ci_cd/_form.html.haml @@ -99,7 +99,7 @@ %code \(\d+.\d+\%\) covered %li pytest-cov (Python) - - %code ^TOTAL\s+\d+\s+\d+\s+(\d+\%)$ + %code ^TOTAL.+?(\d+\%)$ %li phpunit --coverage-text --colors=never (PHP) - %code ^\s*Lines:\s*\d+.\d+\% diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml index 5e3e1076c2c..87000e8270b 100644 --- a/app/views/projects/settings/ci_cd/show.html.haml +++ b/app/views/projects/settings/ci_cd/show.html.haml @@ -16,7 +16,7 @@ .settings-content = render 'form' -%section.qa-autodevops-settings.settings#autodevops-settings.no-animate{ class: ('expanded' if expanded) } +%section.settings#autodevops-settings.no-animate{ class: ('expanded' if expanded), data: { qa_selector: 'autodevops_settings_content' } } .settings-header %h4 = s_('CICD|Auto DevOps') @@ -30,7 +30,7 @@ = render_if_exists 'projects/settings/ci_cd/protected_environments', expanded: expanded -%section.qa-runners-settings.settings.no-animate#js-runners-settings{ class: ('expanded' if expanded) } +%section.settings.no-animate#js-runners-settings{ class: ('expanded' if expanded), data: { qa_selector: 'runners_settings_content' } } .settings-header %h4 = _("Runners") @@ -41,7 +41,7 @@ .settings-content = render 'projects/runners/index' -%section.qa-variables-settings.settings.no-animate{ class: ('expanded' if expanded) } +%section.qa-variables-settings.settings.no-animate#js-cicd-variables-settings{ class: ('expanded' if expanded), data: { qa_selector: 'variables_settings_content' } } .settings-header = render 'ci/variables/header', expanded: expanded .settings-content diff --git a/app/views/projects/settings/operations/_external_dashboard.html.haml b/app/views/projects/settings/operations/_external_dashboard.html.haml index a124283921d..08d50a336fd 100644 --- a/app/views/projects/settings/operations/_external_dashboard.html.haml +++ b/app/views/projects/settings/operations/_external_dashboard.html.haml @@ -1,3 +1,3 @@ .js-operation-settings{ data: { operations_settings_endpoint: project_settings_operations_path(@project), external_dashboard: { url: metrics_external_dashboard_url, - help_page_path: help_page_path('user/project/operations/link_to_external_dashboard') } } } + help_page_path: help_page_path('user/project/operations/linking_to_an_external_dashboard') } } } diff --git a/app/views/projects/starrers/_starrer.html.haml b/app/views/projects/starrers/_starrer.html.haml new file mode 100644 index 00000000000..377d62f8abd --- /dev/null +++ b/app/views/projects/starrers/_starrer.html.haml @@ -0,0 +1,19 @@ +- starrer = local_assigns.fetch(:starrer) + +.col-lg-3.col-md-4.col-sm-12 + .card + .card-body + = image_tag avatar_icon_for_user(starrer.user, 40), class: "avatar s40", alt: '' + + .user-info + .block-truncated + = link_to starrer.user.name, user_path(starrer.user), class: 'user js-user-link', data: { user_id: starrer.user.id } + + .block-truncated + %span.cgray= starrer.user.to_reference + + - if starrer.user == current_user + %span.badge.badge-success.prepend-left-5= _("It's you") + + .block-truncated + = time_ago_with_tooltip(starrer.starred_since) diff --git a/app/views/projects/starrers/index.html.haml b/app/views/projects/starrers/index.html.haml new file mode 100644 index 00000000000..e55ed99f643 --- /dev/null +++ b/app/views/projects/starrers/index.html.haml @@ -0,0 +1,32 @@ +- page_title _("Starrers") + +.top-area.adjust + .nav-text + - full_count_title = "#{@public_count} public and #{@private_count} private" + #{pluralize(@total_count, 'starrer')}: #{full_count_title} + - if @starrers.size > 0 || params[:search].present? + .nav-controls + = form_tag request.original_url, method: :get, class: 'form-inline user-search-form flex-users-form' do + .form-group + .position-relative + = search_field_tag :search, params[:search], { placeholder: _('Search'), class: 'form-control', spellcheck: false } + %button.user-search-btn{ type: "submit", "aria-label" => _("Submit search") } + = icon("search") + .dropdown.inline.user-sort-dropdown + = dropdown_toggle(starrers_sort_options_hash[@sort], { toggle: 'dropdown' }) + %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable + %li.dropdown-header + = _("Sort by") + - starrers_sort_options_hash.each do |value, title| + %li + = link_to filter_starrer_path(sort: value), class: ("is-active" if @sort == value) do + = title +- if @starrers.size > 0 + .row.prepend-top-10 + = render partial: 'starrer', collection: @starrers, as: :starrer + = paginate @starrers, theme: 'gitlab' +- else + - if params[:search].present? + .nothing-here-block= _('No starrers matched your search') + - else + .nothing-here-block= _('Nobody has starred this repository yet') diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml index 02f6ef02843..78cce58938e 100644 --- a/app/views/projects/tags/show.html.haml +++ b/app/views/projects/tags/show.html.haml @@ -4,7 +4,7 @@ - page_title @tag.name, s_('TagsPage|Tags') %div{ class: container_class } - .top-area.multi-line + .top-area.multi-line.flex-wrap .nav-text .title %span.item-title.ref-name diff --git a/app/views/projects/tree/_tree_content.html.haml b/app/views/projects/tree/_tree_content.html.haml index 889a13339fd..cb459b031fc 100644 --- a/app/views/projects/tree/_tree_content.html.haml +++ b/app/views/projects/tree/_tree_content.html.haml @@ -1,4 +1,4 @@ -.tree-content-holder.js-tree-content{ 'data-logs-path': @logs_path } +.tree-content-holder.js-tree-content{ data: tree_content_data(@logs_path, @project, @path) } .table-holder.bordered-box %table.table#tree-slider{ class: "table_#{@hex_path} tree-table qa-file-tree" } %thead diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml index 1d0bc588c9c..41cd044a5b0 100644 --- a/app/views/projects/tree/_tree_header.html.haml +++ b/app/views/projects/tree/_tree_header.html.haml @@ -11,7 +11,7 @@ - addtotree_toggle_attributes = { title: _("You can only add files when you are on a branch"), data: { container: 'body' }, class: 'disabled has-tooltip' } - if vue_file_list_enabled? - #js-repo-breadcrumb + #js-repo-breadcrumb{ data: breadcrumb_data_attributes } - else %ul.breadcrumb.repo-breadcrumb %li.breadcrumb-item diff --git a/app/views/projects/triggers/_content.html.haml b/app/views/projects/triggers/_content.html.haml index 96a41aa066c..e686068657c 100644 --- a/app/views/projects/triggers/_content.html.haml +++ b/app/views/projects/triggers/_content.html.haml @@ -1,8 +1,9 @@ -%p.append-bottom-default - Triggers with the - %span.badge.badge-primary legacy - label do not have an associated user and only have access to the current project. - %br - = succeed '.' do - Learn more in the - = link_to 'triggers documentation', help_page_path('ci/triggers/README'), target: '_blank' +- if Feature.enabled?(:use_legacy_pipeline_triggers, @project) + %p.append-bottom-default + Triggers with the + %span.badge.badge-primary legacy + label do not have an associated user and only have access to the current project. + %br + = succeed '.' do + Learn more in the + = link_to 'triggers documentation', help_page_path('ci/triggers/README'), target: '_blank' diff --git a/app/views/projects/triggers/_trigger.html.haml b/app/views/projects/triggers/_trigger.html.haml index 6f6f1e5e0c5..9899cf9c6de 100644 --- a/app/views/projects/triggers/_trigger.html.haml +++ b/app/views/projects/triggers/_trigger.html.haml @@ -8,8 +8,11 @@ .label-container - if trigger.legacy? - %span.badge.badge-primary.has-tooltip{ title: "Trigger makes use of deprecated functionality" } legacy - - if !trigger.can_access_project? + - if trigger.supports_legacy_tokens? + %span.badge.badge-primary.has-tooltip{ title: "Trigger makes use of deprecated functionality" } legacy + - else + %span.badge.badge-danger.has-tooltip{ title: "Trigger is invalid due to being a legacy trigger. We recommend replacing it with a new trigger" } invalid + - elsif !trigger.can_access_project? %span.badge.badge-danger.has-tooltip{ title: "Trigger user has insufficient permissions to project" } invalid %td @@ -30,10 +33,7 @@ Never %td.text-right.trigger-actions - - take_ownership_confirmation = "By taking ownership you will bind this trigger to your user account. With this the trigger will have access to all your projects as if it was you. Are you sure?" - revoke_trigger_confirmation = "By revoking a trigger you will break any processes making use of it. Are you sure?" - - if trigger.owner != current_user && can?(current_user, :manage_trigger, trigger) - = link_to 'Take ownership', take_ownership_project_trigger_path(@project, trigger), data: { confirm: take_ownership_confirmation }, method: :post, class: "btn btn-default btn-sm btn-trigger-take-ownership" - if can?(current_user, :admin_trigger, trigger) = link_to edit_project_trigger_path(@project, trigger), method: :get, title: "Edit", class: "btn btn-default btn-sm" do %i.fa.fa-pencil diff --git a/app/views/projects/update.js.haml b/app/views/projects/update.js.haml index 70f1bf8ef46..c5eecc900b2 100644 --- a/app/views/projects/update.js.haml +++ b/app/views/projects/update.js.haml @@ -4,7 +4,7 @@ location.reload(); - else :plain - $(".project-edit-errors").html("#{escape_javascript(render('errors'))}"); + $(".flash-container").html("#{escape_javascript(render('errors'))}"); $('.save-project-loader').hide(); $('.project-edit-container').show(); $('.edit-project .js-btn-success-general-project-settings').enable(); diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml index 5bb69563b51..a153f527ee0 100644 --- a/app/views/projects/wikis/_form.html.haml +++ b/app/views/projects/wikis/_form.html.haml @@ -1,8 +1,8 @@ -- commit_message = @page.persisted? ? s_("WikiPageEdit|Update %{page_title}") : s_("WikiPageCreate|Create %{page_title}") -- commit_message = commit_message % { page_title: @page.title } +- form_classes = 'wiki-form common-note-form prepend-top-default js-quick-submit' +- form_classes += ' js-new-wiki-page' unless @page.persisted? = form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post, - html: { class: 'wiki-form common-note-form prepend-top-default js-quick-submit' }, + html: { class: form_classes }, data: { uploads_path: uploads_path } do |f| = form_errors(@page) @@ -12,12 +12,14 @@ .form-group.row .col-sm-12= f.label :title, class: 'control-label-full-width' .col-sm-12 - = f.text_field :title, class: 'form-control qa-wiki-title-textbox', value: @page.title - - if @page.persisted? - %span.edit-wiki-page-slug-tip - = icon('lightbulb-o') + = f.text_field :title, class: 'form-control qa-wiki-title-textbox', value: @page.title, required: true, autofocus: !@page.persisted?, placeholder: _('Wiki|Page title') + %span.d-inline-block.mw-100.prepend-top-5 + = icon('lightbulb-o') + - if @page.persisted? = s_("WikiEditPageTip|Tip: You can move this page by adding the path to the beginning of the title.") = link_to icon('question-circle'), help_page_path('user/project/wiki/index', anchor: 'moving-a-wiki-page'), target: '_blank' + - else + = s_("WikiNewPageTip|Tip: You can specify the full path for the new file. We will automatically create any missing directories.") .form-group.row .col-sm-12= f.label :format, class: 'control-label-full-width' .col-sm-12 @@ -43,7 +45,7 @@ .form-group.row .col-sm-12= f.label :commit_message, class: 'control-label-full-width' - .col-sm-12= f.text_field :message, class: 'form-control qa-wiki-message-textbox', rows: 18, value: commit_message + .col-sm-12= f.text_field :message, class: 'form-control qa-wiki-message-textbox', rows: 18, value: nil .form-actions - if @page && @page.persisted? @@ -51,6 +53,6 @@ .float-right = link_to _("Cancel"), project_wiki_path(@project, @page), class: 'btn btn-cancel btn-grouped' - else - = f.submit s_("Wiki|Create page"), class: 'btn-success btn qa-create-page-button' + = f.submit s_("Wiki|Create page"), class: 'btn-success btn qa-create-page-button rspec-create-page-button' .float-right = link_to _("Cancel"), project_wiki_path(@project, :home), class: 'btn btn-cancel' diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml index 643b51e01d1..2e1e176c42a 100644 --- a/app/views/projects/wikis/_main_links.html.haml +++ b/app/views/projects/wikis/_main_links.html.haml @@ -1,9 +1,9 @@ - if (@page && @page.persisted?) - if can?(current_user, :create_wiki, @project) - = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-success", "data-toggle" => "modal" do + = link_to project_wikis_new_path(@project), class: "add-new-wiki btn btn-success", role: "button" do = s_("Wiki|New page") - = link_to project_wiki_history_path(@project, @page), class: "btn" do + = link_to project_wiki_history_path(@project, @page), class: "btn", role: "button" do = s_("Wiki|Page history") - if can?(current_user, :create_wiki, @project) && @page.latest? && @valid_encoding - = link_to project_wiki_edit_path(@project, @page), class: "btn js-wiki-edit" do + = link_to project_wiki_edit_path(@project, @page), class: "btn js-wiki-edit", role: "button" do = _("Edit") diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml deleted file mode 100644 index dc12e368b35..00000000000 --- a/app/views/projects/wikis/_new.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -#modal-new-wiki.modal - .modal-dialog - .modal-content - .modal-header - %h3.page-title= s_("WikiNewPageTitle|New Wiki Page") - %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') } - %span{ "aria-hidden": true } × - .modal-body - %form.new-wiki-page - .form-group - = label_tag :new_wiki_path do - %span= s_("WikiPage|Page slug") - = text_field_tag :new_wiki_path, nil, placeholder: s_("WikiNewPagePlaceholder|how-to-setup"), class: 'form-control', required: true, :'data-wikis-path' => project_wikis_path(@project), autofocus: true - %span.new-wiki-page-slug-tip - = icon('lightbulb-o') - = s_("WikiNewPageTip|Tip: You can specify the full path for the new file. We will automatically create any missing directories.") - .form-actions - = button_tag s_("Wiki|Create page"), class: "build-new-wiki btn btn-success" diff --git a/app/views/projects/wikis/_sidebar.html.haml b/app/views/projects/wikis/_sidebar.html.haml index 28353927135..83d145444d8 100644 --- a/app/views/projects/wikis/_sidebar.html.haml +++ b/app/views/projects/wikis/_sidebar.html.haml @@ -1,6 +1,6 @@ %aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" } } .sidebar-container - .block.wiki-sidebar-header.append-bottom-default + .block.wiki-sidebar-header.append-bottom-default.w-100 %a.gutter-toggle.float-right.d-block.d-sm-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" } = icon('angle-double-right') @@ -10,14 +10,12 @@ %span= _("Clone repository") .blocks-container - .block.block-first + .block.block-first.w-100 - if @sidebar_page = render_wiki_content(@sidebar_page) - else %ul.wiki-pages = render @sidebar_wiki_entries, context: 'sidebar' - .block + .block.w-100 = link_to project_wikis_pages_path(@project), class: 'btn btn-block' do = s_("Wiki|More Pages") - -= render 'projects/wikis/new' diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index 1277ea6c743..9ccf5acfefc 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -5,7 +5,7 @@ = wiki_page_errors(@error) -.wiki-page-header.has-sidebar-toggle +.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } = icon('angle-double-left') @@ -13,16 +13,13 @@ %h2.wiki-page-title - if @page.persisted? = link_to @page.human_title, project_wiki_path(@project, @page) - - else - = @page.human_title - %span.light - · - - if @page.persisted? + %span.light + · = s_("Wiki|Edit Page") - - else - = s_("Wiki|Create Page") + - else + = s_("Wiki|Create New Page") - .nav-controls + .nav-controls.pb-md-3.pb-lg-0 - if @page.persisted? = link_to project_wiki_history_path(@project, @page), class: "btn" do = s_("Wiki|Page history") diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml index 8c2cbd495a0..6972eda9bb7 100644 --- a/app/views/projects/wikis/git_access.html.haml +++ b/app/views/projects/wikis/git_access.html.haml @@ -1,15 +1,17 @@ - @content_class = "limit-container-width" unless fluid_layout - page_title s_("WikiClone|Git Access"), _("Wiki") -.wiki-page-header.has-sidebar-toggle +.wiki-page-header.top-area.has-sidebar-toggle.py-3.flex-column.flex-lg-row %button.btn.btn-default.d-block.d-sm-block.d-md-none.float-right.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } = icon('angle-double-left') - .git-access-header - = _("Clone repository") - %strong= @project_wiki.full_path + .git-access-header.w-100.d-flex.flex-column.justify-content-center + %span + = _("Clone repository") + %strong= @project_wiki.full_path - = render "shared/clone_panel", project: @project_wiki + .pt-3.pt-lg-0.w-100 + = render "shared/clone_panel", project: @project_wiki .wiki-git-access %h3= s_("WikiClone|Install Gollum") diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml index c5fbeeafa54..d3a55c53649 100644 --- a/app/views/projects/wikis/history.html.haml +++ b/app/views/projects/wikis/history.html.haml @@ -1,6 +1,6 @@ - page_title _("History"), @page.human_title, _("Wiki") -.wiki-page-header.has-sidebar-toggle +.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } = icon('angle-double-left') diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index 2191e5ab287..275dc5dbd23 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -5,13 +5,13 @@ - sort_title = wiki_sort_title(params[:sort]) %div{ class: container_class } - .wiki-page-header + .wiki-page-header.top-area.flex-column.flex-lg-row .nav-text.flex-fill %h2.wiki-page-title = s_("Wiki|Wiki Pages") - .nav-controls + .nav-controls.pb-md-3.pb-lg-0 = link_to project_wikis_git_access_path(@project), class: 'btn' do = icon('cloud-download') = _("Clone repository") diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 95cd3356ec8..c6197fe576e 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -4,7 +4,7 @@ - page_title @page.human_title, _("Wiki") - add_to_breadcrumbs _("Wiki"), project_wiki_path(@project, :home) -.wiki-page-header.has-sidebar-toggle +.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } = icon('angle-double-left') @@ -15,7 +15,7 @@ = (_("Last edited by %{name}") % { name: "<strong>#{@page.last_version.author_name}</strong>" }).html_safe #{time_ago_with_tooltip(@page.last_version.authored_date)} - .nav-controls + .nav-controls.pb-md-3.pb-lg-0 = render 'main_links' - if @page.historical? diff --git a/app/views/search/_category.html.haml b/app/views/search/_category.html.haml index ee7d89a9bd8..eae2a491ceb 100644 --- a/app/views/search/_category.html.haml +++ b/app/views/search/_category.html.haml @@ -1,10 +1,6 @@ - users = capture_haml do - if search_tabs?(:members) - %li{ class: active_when(@scope == 'users') } - = link_to search_filter_path(scope: 'users') do - Users - %span.badge.badge-pill - = limited_count(@search_results.limited_users_count) + = search_filter_link 'users', _("Users") .scrolling-tabs-container.inner-page-scroll-tabs.is-smaller .fade-left= icon('angle-left') @@ -12,80 +8,28 @@ %ul.nav-links.search-filter.scrolling-tabs.nav.nav-tabs - if @project - if project_search_tabs?(:blobs) - %li{ class: active_when(@scope == 'blobs') } - = link_to search_filter_path(scope: 'blobs') do - = _("Code") - %span.badge.badge-pill - = @search_results.blobs_count + = search_filter_link 'blobs', _("Code"), data: { qa_selector: 'code_tab' } - if project_search_tabs?(:issues) - %li{ class: active_when(@scope == 'issues') } - = link_to search_filter_path(scope: 'issues') do - = _("Issues") - %span.badge.badge-pill - = limited_count(@search_results.limited_issues_count) + = search_filter_link 'issues', _("Issues") - if project_search_tabs?(:merge_requests) - %li{ class: active_when(@scope == 'merge_requests') } - = link_to search_filter_path(scope: 'merge_requests') do - = _("Merge requests") - %span.badge.badge-pill - = limited_count(@search_results.limited_merge_requests_count) + = search_filter_link 'merge_requests', _("Merge requests") - if project_search_tabs?(:milestones) - %li{ class: active_when(@scope == 'milestones') } - = link_to search_filter_path(scope: 'milestones') do - = _("Milestones") - %span.badge.badge-pill - = limited_count(@search_results.limited_milestones_count) + = search_filter_link 'milestones', _("Milestones") - if project_search_tabs?(:notes) - %li{ class: active_when(@scope == 'notes') } - = link_to search_filter_path(scope: 'notes') do - = _("Comments") - %span.badge.badge-pill - = limited_count(@search_results.limited_notes_count) + = search_filter_link 'notes', _("Comments") - if project_search_tabs?(:wiki) - %li{ class: active_when(@scope == 'wiki_blobs') } - = link_to search_filter_path(scope: 'wiki_blobs') do - = _("Wiki") - %span.badge.badge-pill - = @search_results.wiki_blobs_count + = search_filter_link 'wiki_blobs', _("Wiki") - if project_search_tabs?(:commits) - %li{ class: active_when(@scope == 'commits') } - = link_to search_filter_path(scope: 'commits') do - = _("Commits") - %span.badge.badge-pill - = @search_results.commits_count + = search_filter_link 'commits', _("Commits") = users - elsif @show_snippets - %li{ class: active_when(@scope == 'snippet_blobs') } - = link_to search_filter_path(scope: 'snippet_blobs', snippets: true, group_id: nil, project_id: nil) do - = _("Snippet Contents") - %span.badge.badge-pill - = @search_results.snippet_blobs_count - %li{ class: active_when(@scope == 'snippet_titles') } - = link_to search_filter_path(scope: 'snippet_titles', snippets: true, group_id: nil, project_id: nil) do - = _("Titles and Filenames") - %span.badge.badge-pill - = @search_results.snippet_titles_count + = search_filter_link 'snippet_blobs', _("Snippet Contents"), search: { snippets: true, group_id: nil, project_id: nil } + = search_filter_link 'snippet_titles', _("Titles and Filenames"), search: { snippets: true, group_id: nil, project_id: nil } - else - %li{ class: active_when(@scope == 'projects') } - = link_to search_filter_path(scope: 'projects') do - = _("Projects") - %span.badge.badge-pill - = limited_count(@search_results.limited_projects_count) - %li{ class: active_when(@scope == 'issues') } - = link_to search_filter_path(scope: 'issues') do - = _("Issues") - %span.badge.badge-pill - = limited_count(@search_results.limited_issues_count) - %li{ class: active_when(@scope == 'merge_requests') } - = link_to search_filter_path(scope: 'merge_requests') do - = _("Merge requests") - %span.badge.badge-pill - = limited_count(@search_results.limited_merge_requests_count) - %li{ class: active_when(@scope == 'milestones') } - = link_to search_filter_path(scope: 'milestones') do - = _("Milestones") - %span.badge.badge-pill - = limited_count(@search_results.limited_milestones_count) + = search_filter_link 'projects', _("Projects") + = search_filter_link 'issues', _("Issues") + = search_filter_link 'merge_requests', _("Merge requests") + = search_filter_link 'milestones', _("Milestones") = render_if_exists 'search/category_elasticsearch' = users diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index c8b6a3258ab..bee4aff605f 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -2,10 +2,11 @@ = hidden_field_tag :group_id, params[:group_id] - if params[:project_id].present? = hidden_field_tag :project_id, params[:project_id] -.dropdown - %button.dropdown-menu-toggle.js-search-group-dropdown{ type: "button", data: { toggle: "dropdown", default_label: _('Group:'), group_id: params[:group_id] } } +.dropdown.form-group.mb-lg-0.mx-lg-1 + %label.d-block{ for: "dashboard_search_group" } + = _("Group") + %button.dropdown-menu-toggle.js-search-group-dropdown.mt-0{ type: "button", id: "dashboard_search_group", data: { toggle: "dropdown", group_id: params[:group_id] } } %span.dropdown-toggle-text - = _("Group:") - if @group.present? = @group.name - else @@ -17,10 +18,11 @@ = dropdown_content = dropdown_loading -.dropdown.project-filter - %button.dropdown-menu-toggle.js-search-project-dropdown{ type: "button", data: { toggle: "dropdown", default_label: _('Project:') } } +.dropdown.project-filter.form-group.mb-lg-0.mx-lg-1 + %label.d-block{ for: "dashboard_search_project" } + = _("Project") + %button.dropdown-menu-toggle.js-search-project-dropdown.mt-0{ type: "button", id: "dashboard_search_project", data: { toggle: "dropdown"} } %span.dropdown-toggle-text - = _("Project:") - if @project.present? = @project.full_name - else diff --git a/app/views/search/_form.html.haml b/app/views/search/_form.html.haml index db0dcc8adfb..464db94b7f4 100644 --- a/app/views/search/_form.html.haml +++ b/app/views/search/_form.html.haml @@ -1,16 +1,21 @@ -= form_tag search_path, method: :get, class: 'js-search-form' do |f| += form_tag search_path, method: :get, class: 'search-page-form js-search-form' do |f| = hidden_field_tag :snippets, params[:snippets] = hidden_field_tag :scope, params[:scope] + = hidden_field_tag :repository_ref, params[:repository_ref] - .search-holder - .search-field-holder - = search_field_tag :search, params[:search], placeholder: _("Search for projects, issues, etc."), class: "form-control search-text-input js-search-input", id: "dashboard_search", autofocus: true, spellcheck: false - = icon("search", class: "search-icon") - %button.search-clear.js-search-clear{ class: ("hidden" if !params[:search].present?), type: "button", tabindex: "-1" } - = icon("times-circle") - %span.sr-only - = _("Clear search") + .d-lg-flex.align-items-end + .search-field-holder.form-group.mr-lg-1.mb-lg-0 + %label{ for: "dashboard_search" } + = _("What are you searching for?") + .position-relative + = search_field_tag :search, params[:search], placeholder: _("Search for projects, issues, etc."), class: "form-control search-text-input js-search-input", id: "dashboard_search", autofocus: true, spellcheck: false + = icon("search", class: "search-icon") + %button.search-clear.js-search-clear{ class: ("hidden" if !params[:search].present?), type: "button", tabindex: "-1" } + = icon("times-circle") + %span.sr-only + = _("Clear search") - unless params[:snippets].eql? 'true' = render 'filter' - = button_tag _("Search"), class: "btn btn-success btn-search" - = render_if_exists 'search/form_elasticsearch' + .d-flex-center.flex-column.flex-lg-row + = button_tag _("Search"), class: "btn btn-success btn-search form-control mt-lg-0 ml-lg-1 align-self-end" + = render_if_exists 'search/form_elasticsearch' diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index cb8a8a24be8..de9947528cf 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -2,17 +2,25 @@ = render partial: "search/results/empty" = render_if_exists 'shared/promotions/promote_advanced_search' - else - .row-content-block + .row-content-block.d-md-flex.text-left.align-items-center - unless @search_objects.is_a?(Kaminari::PaginatableWithoutCount) = search_entries_info(@search_objects, @scope, @search_term) - unless @show_snippets - if @project - - link_to_project = link_to(@project.full_name, [@project.namespace.becomes(Namespace), @project]) - = _("in project %{link_to_project}").html_safe % { link_to_project: link_to_project } + - link_to_project = link_to(@project.full_name, [@project.namespace.becomes(Namespace), @project], class: 'ml-md-1') + - if @scope == 'blobs' + - repository_ref = params[:repository_ref].to_s.presence || @project.default_branch + = s_("SearchCodeResults|in") + .mx-md-1 + = render partial: "shared/ref_switcher", locals: { ref: repository_ref, form_path: request.fullpath, field_name: 'repository_ref' } + = s_('SearchCodeResults|of %{link_to_project}').html_safe % { link_to_project: link_to_project } + - else + = _("in project %{link_to_project}").html_safe % { link_to_project: link_to_project } - elsif @group - - link_to_group = link_to(@group.name, @group) + - link_to_group = link_to(@group.name, @group, class: 'ml-md-1') = _("in group %{link_to_group}").html_safe % { link_to_group: link_to_group } = render_if_exists 'shared/promotions/promote_advanced_search' + .results.prepend-top-10 - if @scope == 'commits' %ul.content-list.commit-list diff --git a/app/views/search/results/_blob_data.html.haml b/app/views/search/results/_blob_data.html.haml index 143e9f91ca3..36b6ea7bd37 100644 --- a/app/views/search/results/_blob_data.html.haml +++ b/app/views/search/results/_blob_data.html.haml @@ -1,10 +1,10 @@ -.blob-result +.blob-result{ data: { qa_selector: 'result_item_content' } } .file-holder - .js-file-title.file-title + .js-file-title.file-title{ data: { qa_selector: 'file_title_content' } } = link_to blob_link do %i.fa.fa-file %strong = search_blob_title(project, file_name) - if blob.data - .file-content.code.term + .file-content.code.term{ data: { qa_selector: 'file_text_content' } } = render 'shared/file_highlight', blob: blob, first_line_number: blob.startline diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml index 3260d05f509..9235678bc1d 100644 --- a/app/views/search/show.html.haml +++ b/app/views/search/show.html.haml @@ -1,6 +1,10 @@ - @hide_top_links = true -- breadcrumb_title _("Search") - page_title @search_term +- @hide_breadcrumbs = true + +.page-title-holder.d-flex.align-items-center + %h1.page-title< + = _('Search') .prepend-top-default = render 'search/form' diff --git a/app/views/shared/_issuable_meta_data.html.haml b/app/views/shared/_issuable_meta_data.html.haml index 71b13a5d741..7807371285c 100644 --- a/app/views/shared/_issuable_meta_data.html.haml +++ b/app/views/shared/_issuable_meta_data.html.haml @@ -1,7 +1,7 @@ - note_count = @issuable_meta_data[issuable.id].user_notes_count - issue_votes = @issuable_meta_data[issuable.id] - upvotes, downvotes = issue_votes.upvotes, issue_votes.downvotes -- issuable_url = @collection_type == "Issue" ? issue_path(issuable, anchor: 'notes') : merge_request_path(issuable, anchor: 'notes') +- issuable_path = issuable_path(issuable, anchor: 'notes') - issuable_mr = @issuable_meta_data[issuable.id].merge_requests_count(current_user) - if issuable_mr > 0 @@ -20,6 +20,6 @@ = downvotes %li.issuable-comments.d-none.d-sm-block - = link_to issuable_url, class: ['has-tooltip', ('no-comments' if note_count.zero?)], title: _('Comments') do + = link_to issuable_path, class: ['has-tooltip', ('no-comments' if note_count.zero?)], title: _('Comments') do = icon('comments') = note_count diff --git a/app/views/shared/_label_row.html.haml b/app/views/shared/_label_row.html.haml index af11ce94ec5..b05d903fabe 100644 --- a/app/views/shared/_label_row.html.haml +++ b/app/views/shared/_label_row.html.haml @@ -1,7 +1,7 @@ - force_priority = local_assigns.fetch(:force_priority, false) - subject_or_group_defined = defined?(@project) || defined?(@group) -- show_label_issues_link = subject_or_group_defined && show_label_issuables_link?(label, :issues, project: @project) -- show_label_merge_requests_link = subject_or_group_defined && show_label_issuables_link?(label, :merge_requests, project: @project) +- show_label_issues_link = subject_or_group_defined && show_label_issuables_link?(label, :issues) +- show_label_merge_requests_link = subject_or_group_defined && show_label_issuables_link?(label, :merge_requests) .label-name = render_label(label, tooltip: false) diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml index 7cbc5810c10..74e0a088656 100644 --- a/app/views/shared/_ref_switcher.html.haml +++ b/app/views/shared/_ref_switcher.html.haml @@ -1,12 +1,19 @@ -- dropdown_toggle_text = @ref || @project.default_branch -= form_tag switch_project_refs_path(@project), method: :get, class: "project-refs-form" do - = hidden_field_tag :destination, destination +- return unless @project + +- ref = local_assigns.fetch(:ref, @ref) +- form_path = local_assigns.fetch(:form_path, switch_project_refs_path(@project)) +- dropdown_toggle_text = ref || @project.default_branch +- field_name = local_assigns.fetch(:field_name, 'ref') + += form_tag form_path, method: :get, class: "project-refs-form" do + - if defined?(destination) + = hidden_field_tag :destination, destination - if defined?(path) = hidden_field_tag :path, path - @options && @options.each do |key, value| = hidden_field_tag key, value, id: nil .dropdown - = dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_project_path(@project, sort: 'updated_desc'), field_name: 'ref', submit_form_on_click: true, visit: true }, { toggle_class: "js-project-refs-dropdown qa-branches-select" } + = dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: ref, refs_url: refs_project_path(@project, sort: 'updated_desc'), field_name: field_name, submit_form_on_click: true, visit: true }, { toggle_class: "js-project-refs-dropdown qa-branches-select" } .dropdown-menu.dropdown-menu-selectable.git-revision-dropdown.dropdown-menu-paging.qa-branches-dropdown{ class: ("dropdown-menu-right" if local_assigns[:align_right]) } .dropdown-page-one = dropdown_title _("Switch branch/tag") diff --git a/app/views/shared/_remote_mirror_update_button.html.haml b/app/views/shared/_remote_mirror_update_button.html.haml index 8da2ae5111a..4b39c8b06e9 100644 --- a/app/views/shared/_remote_mirror_update_button.html.haml +++ b/app/views/shared/_remote_mirror_update_button.html.haml @@ -2,5 +2,5 @@ %button.btn.disabled{ type: 'button', data: { toggle: 'tooltip', container: 'body' }, title: _('Updating') } = icon("refresh spin") - elsif remote_mirror.enabled? - = link_to update_now_project_mirror_path(@project, sync_remote: true), method: :post, class: "btn qa-update-now-button", data: { toggle: 'tooltip', container: 'body' }, title: _('Update now') do + = link_to update_now_project_mirror_path(@project, sync_remote: true), method: :post, class: "btn qa-update-now-button rspec-update-now-button", data: { toggle: 'tooltip', container: 'body' }, title: _('Update now') do = icon("refresh") diff --git a/app/views/shared/_sidebar_toggle_button.html.haml b/app/views/shared/_sidebar_toggle_button.html.haml index d499bc0a253..c7546073e5c 100644 --- a/app/views/shared/_sidebar_toggle_button.html.haml +++ b/app/views/shared/_sidebar_toggle_button.html.haml @@ -1,4 +1,4 @@ -%a.toggle-sidebar-button.js-toggle-sidebar.qa-toggle-sidebar{ role: "button", type: "button", title: "Toggle sidebar" } +%a.toggle-sidebar-button.js-toggle-sidebar.qa-toggle-sidebar.rspec-toggle-sidebar{ role: "button", type: "button", title: "Toggle sidebar" } = sprite_icon('angle-double-left', css_class: 'icon-angle-double-left') = sprite_icon('angle-double-right', css_class: 'icon-angle-double-right') %span.collapse-text= _("Collapse sidebar") diff --git a/app/views/shared/_visibility_radios.html.haml b/app/views/shared/_visibility_radios.html.haml index 9fc46afe177..82ffdc9cd13 100644 --- a/app/views/shared/_visibility_radios.html.haml +++ b/app/views/shared/_visibility_radios.html.haml @@ -1,17 +1,19 @@ - Gitlab::VisibilityLevel.values.each do |level| - disallowed = disallowed_visibility_level?(form_model, level) - restricted = restricted_visibility_levels.include?(level) - - disabled = disallowed || restricted - .form-check{ class: [('disabled' if disabled), ('restricted' if restricted)] } - = form.radio_button model_method, level, checked: (selected_level == level), disabled: disabled, class: 'form-check-input', data: { track_label: "blank_project", track_event: "activate_form_input", track_property: "#{model_method}", track_value: "#{level}" } + - next if disallowed || restricted + + .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: "" } = form.label "#{model_method}_#{level}", class: 'form-check-label' do = visibility_level_icon(level) .option-title = visibility_level_label(level) .option-description = visibility_level_description(level, form_model) - .option-disabled-reason - - if restricted - = restricted_visibility_level_description(level) - - elsif disallowed - = disallowed_visibility_level_description(level, form_model) + +.text-muted + - if all_visibility_levels_restricted? + = _('Visibility settings have been disabled by the administrator.') + - elsif multiple_visibility_levels_restricted? + = _('Other visibility settings have been disabled by the administrator.') diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml index 813fccd217b..4f0be117035 100644 --- a/app/views/shared/boards/_show.html.haml +++ b/app/views/shared/boards/_show.html.haml @@ -14,10 +14,9 @@ %script#js-board-promotion{ type: "text/x-template" }= render_if_exists "shared/promotions/promote_issue_board" #board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" } - .d-none.d-sm-none.d-md-block - = render 'shared/issuable/search_bar', type: :boards, board: board + = render 'shared/issuable/search_bar', type: :boards, board: board - .boards-list.w-100.py-3.px-2.text-nowrap + .boards-list.w-100.py-3.px-2.text-nowrap{ data: { qa_selector: "boards_list" } } .boards-app-loading.w-100.text-center{ "v-if" => "loading" } = icon("spinner spin 2x") %board{ "v-cloak" => "true", diff --git a/app/views/shared/boards/_switcher.html.haml b/app/views/shared/boards/_switcher.html.haml new file mode 100644 index 00000000000..79118630762 --- /dev/null +++ b/app/views/shared/boards/_switcher.html.haml @@ -0,0 +1,16 @@ +- parent = board.parent +- milestone_filter_opts = { format: :json } +- milestone_filter_opts = milestone_filter_opts.merge(only_group_milestones: true) if board.group_board? +- weights = Gitlab.ee? ? ([Issue::WEIGHT_ANY] + Issue.weight_options) : [] + +#js-multiple-boards-switcher.inline.boards-switcher{ data: { current_board: current_board_json.to_json, + milestone_path: milestones_filter_path(milestone_filter_opts), + board_base_url: board_base_url, + has_missing_boards: (!multiple_boards_available? && current_board_parent.boards.size > 1).to_s, + can_admin_board: can?(current_user, :admin_board, parent).to_s, + multiple_issue_boards_available: parent.multiple_issue_boards_available?.to_s, + labels_path: labels_filter_path_with_defaults(only_group_labels: true, include_descendant_groups: true), + project_id: @project&.id, + group_id: @group&.id, + scoped_issue_board_feature_enabled: Gitlab.ee? && parent.feature_available?(:scoped_issue_board) ? 'true' : 'false', + weights: weights.to_json } } diff --git a/app/views/shared/boards/components/_board.html.haml b/app/views/shared/boards/components/_board.html.haml index 6c0613605eb..ffa24d1c041 100644 --- a/app/views/shared/boards/components/_board.html.haml +++ b/app/views/shared/boards/components/_board.html.haml @@ -1,7 +1,7 @@ -.board.d-inline-block.h-100.px-2.align-top.ws-normal{ ":class" => '{ "is-draggable": !list.preset, "is-expandable": list.isExpandable, "is-collapsed": !list.isExpanded, "board-type-assignee": list.type === "assignee" }', - ":data-id" => "list.id" } +.board.h-100.px-2.align-top.ws-normal{ ":class" => '{ "is-draggable": !list.preset, "is-expandable": list.isExpandable, "is-collapsed": !list.isExpanded, "board-type-assignee": list.type === "assignee" }', + ":data-id" => "list.id", data: { qa_selector: "board_list" } } .board-inner.d-flex.flex-column.position-relative.h-100.rounded - %header.board-header{ ":class" => '{ "has-border": list.label && list.label.color, "position-relative": list.isExpanded, "position-absolute position-top-0 position-left-0 w-100 h-100": !list.isExpanded }', ":style" => "{ borderTopColor: (list.label && list.label.color ? list.label.color : null) }" } + %header.board-header{ ":class" => '{ "has-border": list.label && list.label.color, "position-relative": list.isExpanded, "position-absolute position-top-0 position-left-0 w-100 h-100": !list.isExpanded }', ":style" => "{ borderTopColor: (list.label && list.label.color ? list.label.color : null) }", data: { qa_selector: "board_list_header" } } %h3.board-title.m-0.d-flex.js-board-handle{ ":class" => '{ "user-can-drag": (!disabled && !list.preset), "border-bottom-0": !list.isExpanded }' } .board-title-caret.no-drag{ "v-if": "list.isExpandable", diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml index b11cb8a3076..be78fd0ccfb 100644 --- a/app/views/shared/form_elements/_description.html.haml +++ b/app/views/shared/form_elements/_description.html.haml @@ -15,7 +15,7 @@ = render layout: 'projects/md_preview', locals: { url: preview_url, referenced_users: true } do = render 'projects/zen', f: form, attr: :description, - classes: 'note-textarea qa-issuable-form-description', + classes: 'note-textarea qa-issuable-form-description rspec-issuable-form-description', placeholder: "Write a comment or drag your files hereā¦", supports_quick_actions: supports_quick_actions = render 'shared/notes/hints', supports_quick_actions: supports_quick_actions diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml index 483652852b6..bca5db16bd3 100644 --- a/app/views/shared/issuable/_label_dropdown.html.haml +++ b/app/views/shared/issuable/_label_dropdown.html.haml @@ -1,4 +1,5 @@ - project = @target_project || @project +- edit_context = local_assigns.fetch(:edit_context, nil) || project - show_create = local_assigns.fetch(:show_create, true) - extra_options = local_assigns.fetch(:extra_options, true) - filter_submit = local_assigns.fetch(:filter_submit, true) @@ -8,7 +9,7 @@ - classes = local_assigns.fetch(:classes, []) - selected = local_assigns.fetch(:selected, nil) - dropdown_title = local_assigns.fetch(:dropdown_title, "Filter by label") -- dropdown_data = label_dropdown_data(@project, labels: labels_filter_path_with_defaults, default_label: "Labels") +- dropdown_data = label_dropdown_data(edit_context, labels: labels_filter_path_with_defaults(only_group_labels: edit_context.is_a?(Group)), default_label: "Labels") - dropdown_data.merge!(data_options) - label_name = local_assigns.fetch(:label_name, "Labels") - no_default_styles = local_assigns.fetch(:no_default_styles, false) diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index 3d6c5d29d44..c9458475aa5 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -1,19 +1,20 @@ - type = local_assigns.fetch(:type) - board = local_assigns.fetch(:board, nil) -- block_css_class = type != :boards_modal ? 'row-content-block second-block' : '' +- is_not_boards_modal_or_productivity_analytics = type != :boards_modal && type != :productivity_analytics +- block_css_class = is_not_boards_modal_or_productivity_analytics ? 'row-content-block second-block' : '' - user_can_admin_list = board && can?(current_user, :admin_list, board.parent) .issues-filters{ class: ("w-100" if type == :boards_modal) } - .issues-details-filters.filtered-search-block.d-flex{ class: block_css_class, "v-pre" => type == :boards_modal } + .issues-details-filters.filtered-search-block.d-flex.flex-column.flex-md-row{ class: block_css_class, "v-pre" => type == :boards_modal } - if type == :boards - = render_if_exists "shared/boards/switcher", board: board + = render "shared/boards/switcher", board: board = form_tag page_filter_path, method: :get, class: 'filter-form js-filter-form w-100' do - if params[:search].present? = hidden_field_tag :search, params[:search] - if @can_bulk_update .check-all-holder.d-none.d-sm-block.hidden = check_box_tag "check-all-issues", nil, false, class: "check-all-issues left" - .issues-other-filters.filtered-search-wrapper + .issues-other-filters.filtered-search-wrapper.d-flex.flex-column.flex-md-row .filtered-search-box - if type != :boards_modal && type != :boards = dropdown_tag(custom_icon('icon_history'), @@ -147,7 +148,7 @@ %button.clear-search.hidden{ type: 'button' } = icon('times') - .filter-dropdown-container + .filter-dropdown-container.d-flex.flex-column.flex-md-row - if type == :boards .js-board-config{ data: { can_admin_list: user_can_admin_list, has_scope: board.scoped? } } - if user_can_admin_list @@ -155,5 +156,5 @@ - if @project #js-add-issues-btn.prepend-left-10{ data: { can_admin_list: can?(current_user, :admin_list, @project) } } #js-toggle-focus-btn - - elsif type != :boards_modal + - elsif is_not_boards_modal_or_productivity_analytics = render 'shared/issuable/sort_dropdown' diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index b4f8377c008..837707707a9 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -38,7 +38,7 @@ = _('Milestone') = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') - if can_edit_issuable - = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right' + = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "milestone", track_event: "click_edit_button", track_value: "" } .value.hide-collapsed - if milestone.present? = link_to milestone[:title], milestone[:web_url], class: "bold has-tooltip", title: sidebar_milestone_remaining_days(milestone), data: { container: "body", html: 'true', boundary: 'viewport' } @@ -66,7 +66,7 @@ = _('Due date') = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') - if can_edit_issuable - = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right' + = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link float-right', data: { track_label: "right_sidebar", track_property: "due_date", track_event: "click_edit_button", track_value: "" } .value.hide-collapsed %span.value-content - if issuable_sidebar[:due_date] @@ -102,7 +102,7 @@ = _('Labels') = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') - if can_edit_issuable - = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link qa-edit-link-labels float-right' + = link_to _('Edit'), '#', class: 'js-sidebar-dropdown-toggle edit-link qa-edit-link-labels float-right', data: { track_label: "right_sidebar", track_property: "labels", track_event: "click_edit_button", track_value: "" } .value.issuable-show-labels.dont-hide.hide-collapsed.qa-labels-block{ class: ("has-labels" if selected_labels.any?) } - if selected_labels.any? - selected_labels.each do |label_hash| @@ -137,7 +137,13 @@ .js-sidebar-participants-entry-point - if signed_in - .js-sidebar-subscriptions-entry-point + - if issuable_sidebar[:project_emails_disabled] + .block.js-emails-disabled + .sidebar-collapsed-icon.has-tooltip{ title: notification_description(:owner_disabled), data: { placement: "left", container: "body", boundary: 'viewport' } } + = notification_setting_icon + .hide-collapsed= notification_description(:owner_disabled) + - else + .js-sidebar-subscriptions-entry-point - project_ref = issuable_sidebar[:reference] .block.project-reference @@ -156,7 +162,7 @@ = custom_icon('icon_arrow_right') .dropdown.sidebar-move-issue-dropdown.hide-collapsed %button.btn.btn-default.btn-block.js-sidebar-dropdown-toggle.js-move-issue{ type: 'button', - data: { toggle: 'dropdown', display: 'static' } } + data: { toggle: 'dropdown', display: 'static', track_label: "right_sidebar", track_property: "move_issue", track_event: "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_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml index ab01094ed6e..1dc538826dc 100644 --- a/app/views/shared/issuable/_sidebar_assignees.html.haml +++ b/app/views/shared/issuable/_sidebar_assignees.html.haml @@ -20,6 +20,8 @@ placeholder: _('Search users'), data: { first_user: issuable_sidebar.dig(:current_user, :username), current_user: true, + iid: issuable_sidebar[:iid], + issuable_type: issuable_type, project_id: issuable_sidebar[:project_id], author_id: issuable_sidebar[:author_id], field_name: "#{issuable_type}[assignee_ids][]", diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml index 403e001bfe8..8260915c2ab 100644 --- a/app/views/shared/issuable/_sort_dropdown.html.haml +++ b/app/views/shared/issuable/_sort_dropdown.html.haml @@ -1,7 +1,7 @@ - sort_value = @sort - sort_title = issuable_sort_option_title(sort_value) - viewing_issues = controller.controller_name == 'issues' || controller.action_name == 'issues' -- manual_sorting = viewing_issues && controller.controller_name != 'dashboard' && Feature.enabled?(:manual_sorting) +- manual_sorting = viewing_issues && controller.controller_name != 'dashboard' .dropdown.inline.prepend-left-10.issue-sort-dropdown .btn-group{ role: 'group' } diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml index 1e03440a5dc..90a6a98235d 100644 --- a/app/views/shared/issuable/form/_metadata.html.haml +++ b/app/views/shared/issuable/form/_metadata.html.haml @@ -23,6 +23,7 @@ = 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/weight", issuable: issuable, form: form + = render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form - if has_due_date .col-lg-6 diff --git a/app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml b/app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml index 5336159e762..60dc893d9f9 100644 --- a/app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml +++ b/app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml @@ -1,4 +1,4 @@ -= form.label :assignee_id, "Assignee", class: "col-form-label #{has_due_date ? "col-lg-4" : "col-sm-2"}" += form.label :assignee_id, "Assignee", 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.selectbox - issuable.assignees.each do |assignee| diff --git a/app/views/shared/members/_filter_2fa_dropdown.html.haml b/app/views/shared/members/_filter_2fa_dropdown.html.haml index 3e98587aeaa..44ea844028e 100644 --- a/app/views/shared/members/_filter_2fa_dropdown.html.haml +++ b/app/views/shared/members/_filter_2fa_dropdown.html.haml @@ -1,7 +1,7 @@ - filter = params[:two_factor] || 'everyone' - filter_options = { 'everyone' => _('Everyone'), 'enabled' => _('Enabled'), 'disabled' => _('Disabled') } -.dropdown.inline.member-filter-2fa-dropdown - = dropdown_toggle('2FA: ' + filter_options[filter], { toggle: 'dropdown' }) +.dropdown.inline.member-filter-2fa-dropdown.pr-md-2 + = dropdown_toggle(filter_options[filter], { toggle: 'dropdown' }) %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-selectable %li.dropdown-header = _("Filter by two-factor authentication") diff --git a/app/views/shared/members/_group.html.haml b/app/views/shared/members/_group.html.haml index e83ca5eaab8..42a823e3a8d 100644 --- a/app/views/shared/members/_group.html.haml +++ b/app/views/shared/members/_group.html.haml @@ -32,7 +32,7 @@ %ul - Gitlab::Access.options.each do |role, role_id| %li - = link_to role, "javascript:void(0)", + = link_to role, '#', class: ("is-active" if group_link.group_access == role_id), data: { id: role_id, el_id: dom_id } .clearable-input.member-form-control.d-sm-inline-block diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml index 331283f7eec..6762f211a80 100644 --- a/app/views/shared/members/_member.html.haml +++ b/app/views/shared/members/_member.html.haml @@ -82,7 +82,7 @@ %ul - member.valid_level_roles.each do |role, role_id| %li - = link_to role, "javascript:void(0)", + = link_to role, '#', class: ("is-active" if member.access_level == role_id), data: { id: role_id, el_id: dom_id(member) } = render_if_exists 'shared/members/ee/revert_ldap_group_sync_option', diff --git a/app/views/shared/members/_sort_dropdown.html.haml b/app/views/shared/members/_sort_dropdown.html.haml index 59bdfb73e6e..feca109dade 100644 --- a/app/views/shared/members/_sort_dropdown.html.haml +++ b/app/views/shared/members/_sort_dropdown.html.haml @@ -1,4 +1,5 @@ -.dropdown.inline.member-sort-dropdown += label_tag :sort_by, 'Sort by', class: 'col-form-label label-bold pr-2' +.dropdown.inline.qa-user-sort-dropdown = dropdown_toggle(member_sort_options_hash[@sort], { toggle: 'dropdown' }) %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable %li.dropdown-header diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml index 43503e1d08a..fd3317341f6 100644 --- a/app/views/shared/milestones/_top.html.haml +++ b/app/views/shared/milestones/_top.html.haml @@ -53,7 +53,7 @@ - close_msg = group ? 'You may close the milestone now.' : 'Navigate to the project to close the milestone.' %span All issues for this milestone are closed. #{close_msg} -= render_if_exists 'shared/milestones/burndown', milestone: @milestone, project: @project += render_if_exists 'shared/milestones/burndown', milestone: milestone, project: @project - if is_dynamic_milestone .table-holder diff --git a/app/views/shared/notifications/_button.html.haml b/app/views/shared/notifications/_button.html.haml index 749aa258af6..b4266937a4e 100644 --- a/app/views/shared/notifications/_button.html.haml +++ b/app/views/shared/notifications/_button.html.haml @@ -1,6 +1,15 @@ -- btn_class = local_assigns.fetch(:btn_class, nil) +- btn_class = local_assigns.fetch(:btn_class, '') +- emails_disabled = local_assigns.fetch(:emails_disabled, false) - if notification_setting + - if emails_disabled + - button_title = notification_description(:owner_disabled) + - aria_label = button_title + - btn_class << " disabled" + - else + - button_title = _("Notification setting") + - aria_label = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) } + .js-notification-dropdown.notification-dropdown.mr-md-2.home-panel-action-button.dropdown.inline = form_for notification_setting, remote: true, html: { class: "inline notification-form" } do |f| = hidden_setting_source_input(notification_setting) @@ -8,14 +17,14 @@ .js-notification-toggle-btns %div{ class: ("btn-group" if notification_setting.custom?) } - if notification_setting.custom? - %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn.text-left#notifications-button{ type: "button", title: _("Notification setting"), class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } } + %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn.text-left#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } } = icon("bell", class: "js-notification-loading") = notification_title(notification_setting.level) %button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } } = icon('caret-down') .sr-only Toggle dropdown - else - %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: _("Notification setting"), class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } } + %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } } .float-left = icon("bell", class: "js-notification-loading") = notification_title(notification_setting.level) diff --git a/app/views/shared/notifications/_new_button.html.haml b/app/views/shared/notifications/_new_button.html.haml index 052e6da5bae..3c8cc023848 100644 --- a/app/views/shared/notifications/_new_button.html.haml +++ b/app/views/shared/notifications/_new_button.html.haml @@ -1,6 +1,13 @@ -- btn_class = local_assigns.fetch(:btn_class, nil) +- btn_class = local_assigns.fetch(:btn_class, '') +- emails_disabled = local_assigns.fetch(:emails_disabled, false) - if notification_setting + - if emails_disabled + - button_title = notification_description(:owner_disabled) + - btn_class << " disabled" + - else + - button_title = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) } + .js-notification-dropdown.notification-dropdown.home-panel-action-button.prepend-top-default.append-right-8.dropdown.inline = form_for notification_setting, remote: true, html: { class: "inline notification-form no-label" } do |f| = hidden_setting_source_input(notification_setting) @@ -9,14 +16,14 @@ .js-notification-toggle-btns %div{ class: ("btn-group" if notification_setting.custom?) } - if notification_setting.custom? - %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", placement: 'top', toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } } + %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => button_title, data: { container: "body", placement: 'top', toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } } = notification_setting_icon(notification_setting) %span.js-notification-loading.fa.hidden %button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" }, class: "#{btn_class}" } = sprite_icon("arrow-down", css_class: "icon mr-0") .sr-only Toggle dropdown - else - %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", placement: 'top', toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } } + %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => button_title, data: { container: "body", placement: 'top', toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } } = notification_setting_icon(notification_setting) %span.js-notification-loading.fa.hidden = sprite_icon("arrow-down", css_class: "icon") diff --git a/app/views/shared/projects/_list.html.haml b/app/views/shared/projects/_list.html.haml index 576ec3e1782..bb05658c719 100644 --- a/app/views/shared/projects/_list.html.haml +++ b/app/views/shared/projects/_list.html.haml @@ -17,14 +17,20 @@ - contributed_projects_illustration_path = 'illustrations/profile-page/contributed-projects.svg' - contributed_projects_current_user_empty_message_header = s_('UserProfile|Explore public groups to find projects to contribute to.') - contributed_projects_visitor_empty_message = s_('UserProfile|This user hasn\'t contributed to any projects') +- starred_projects_illustration_path = 'illustrations/starred_empty.svg' +- starred_projects_current_user_empty_message_header = s_('UserProfile|Star projects to track their progress and show your appreciation.') +- starred_projects_visitor_empty_message = s_('UserProfile|This user hasn\'t starred any projects') - own_projects_illustration_path = 'illustrations/profile-page/personal-project.svg' - own_projects_current_user_empty_message_header = s_('UserProfile|You haven\'t created any personal projects.') - own_projects_current_user_empty_message_description = s_('UserProfile|Your projects can be available publicly, internally, or privately, at your choice.') - own_projects_visitor_empty_message = s_('UserProfile|This user doesn\'t have any personal projects') -- primary_button_label = _('New project') -- primary_button_link = new_project_path -- secondary_button_label = _('Explore groups') -- secondary_button_link = explore_groups_path +- explore_page_empty_message = s_('UserProfile|Explore public groups to find projects to contribute to.') +- new_project_button_label = _('New project') +- new_project_button_link = new_project_path +- explore_projects_button_label = _('Explore projects') +- explore_projects_button_link = explore_projects_path +- explore_groups_button_label = _('Explore groups') +- explore_groups_button_link = explore_groups_path .js-projects-list-holder - if any_projects?(projects) @@ -47,15 +53,21 @@ - if @contributed_projects = render partial: 'shared/empty_states/profile_tabs', locals: { illustration_path: contributed_projects_illustration_path, current_user_empty_message_header: contributed_projects_current_user_empty_message_header, - primary_button_label: primary_button_label, - primary_button_link: primary_button_link, - secondary_button_label: secondary_button_label, - secondary_button_link: secondary_button_link, + primary_button_label: new_project_button_label, + primary_button_link: new_project_button_link, + secondary_button_label: explore_groups_button_label, + secondary_button_link: explore_groups_button_link, visitor_empty_message: contributed_projects_visitor_empty_message } + - elsif @starred_projects + = render partial: 'shared/empty_states/profile_tabs', locals: { illustration_path: starred_projects_illustration_path, + current_user_empty_message_header: starred_projects_current_user_empty_message_header, + primary_button_label: explore_projects_button_label, + primary_button_link: explore_projects_button_link, + visitor_empty_message: starred_projects_visitor_empty_message } - else = render partial: 'shared/empty_states/profile_tabs', locals: { illustration_path: own_projects_illustration_path, current_user_empty_message_header: own_projects_current_user_empty_message_header, current_user_empty_message_description: own_projects_current_user_empty_message_description, - primary_button_label: primary_button_label, - primary_button_link: primary_button_link, - visitor_empty_message: own_projects_visitor_empty_message } + primary_button_label: new_project_button_label, + primary_button_link: new_project_button_link, + visitor_empty_message: defined?(explore_page) && explore_page ? explore_page_empty_message : own_projects_visitor_empty_message } diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index 90fb067e75d..573ed36d7f4 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -37,7 +37,7 @@ %span.project-name< = project.name - %span.metadata-info.visibility-icon.append-right-10.prepend-top-8.has-tooltip{ data: { container: 'body', placement: 'top' }, title: visibility_icon_description(project) } + %span.metadata-info.visibility-icon.append-right-10.prepend-top-8.text-secondary.has-tooltip{ data: { container: 'body', placement: 'top' }, title: visibility_icon_description(project) } = visibility_level_icon(project.visibility_level, fw: true) - if explore_projects_tab? && project.repository.license @@ -58,12 +58,14 @@ .description.d-none.d-sm-block.append-right-default = markdown_field(project, :description) - .controls.d-flex.flex-sm-column.align-items-center.align-items-sm-end.flex-wrap.flex-shrink-0{ class: css_controls_class } + .controls.d-flex.flex-sm-column.align-items-center.align-items-sm-end.flex-wrap.flex-shrink-0.text-secondary{ class: css_controls_class } .icon-container.d-flex.align-items-center - if project.archived %span.d-flex.icon-wrapper.badge.badge-warning archived - if stars - %span.d-flex.align-items-center.icon-wrapper.stars.has-tooltip{ data: { container: 'body', placement: 'top' }, title: _('Stars') } + = link_to project_starrers_path(project), + class: "d-flex align-items-center icon-wrapper stars has-tooltip", + title: _('Stars'), data: { container: 'body', placement: 'top' } do = sprite_icon('star', size: 14, css_class: 'append-right-4') = number_with_delimiter(project.star_count) - if forks @@ -87,6 +89,8 @@ - if pipeline_status && can?(current_user, :read_cross_project) && project.pipeline_status.has_status? && can?(current_user, :read_build, project) - pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref) %span.icon-wrapper.pipeline-status - = render 'ci/status/icon', status: project.commit.last_pipeline.detailed_status(current_user), type: 'commit', tooltip_placement: 'top', path: pipeline_path + = render 'ci/status/icon', status: project.commit.last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path .updated-note - %span Updated #{updated_tooltip} + %span + = _('Updated') + = updated_tooltip diff --git a/app/views/u2f/_register.html.haml b/app/views/u2f/_register.html.haml index f6724f72307..ef3835332a7 100644 --- a/app/views/u2f/_register.html.haml +++ b/app/views/u2f/_register.html.haml @@ -16,7 +16,7 @@ .col-md-4 %button#js-setup-u2f-device.btn.btn-info.btn-block{ disabled: true }= _("Set up new U2F device") .col-md-8 - %p.text-warning= _("You need to register a two-factor authentication app before you can set up a U2F device.") + %p= _("You need to register a two-factor authentication app before you can set up a U2F device.") %script#js-register-u2f-in-progress{ type: "text/template" } %p= _("Trying to communicate with your device. Plug it in (if you haven't already) and press the button on the device now.") diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index b3a73030859..73bee7c2586 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -111,6 +111,10 @@ %li.js-projects-tab = link_to user_projects_path, data: { target: 'div#projects', action: 'projects', toggle: 'tab', endpoint: user_projects_path(format: :json) } do = s_('UserProfile|Personal projects') + - if profile_tab?(:starred) + %li.js-starred-tab + = link_to user_starred_projects_path, data: { target: 'div#starred', action: 'starred', toggle: 'tab', endpoint: user_starred_projects_path(format: :json) } do + = s_('UserProfile|Starred projects') - if profile_tab?(:snippets) %li.js-snippets-tab = link_to user_snippets_path, data: { target: 'div#snippets', action: 'snippets', toggle: 'tab', endpoint: user_snippets_path(format: :json) } do @@ -142,6 +146,10 @@ #projects.tab-pane -# This tab is always loaded via AJAX + - if profile_tab?(:starred) + #starred.tab-pane + -# This tab is always loaded via AJAX + - if profile_tab?(:snippets) #snippets.tab-pane -# This tab is always loaded via AJAX |