diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-28 18:10:08 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-28 18:10:08 +0300 |
commit | f7f0c0502763777f48964774a87b0a34dfb1d9ab (patch) | |
tree | 777821671f0eba38eadd5f60da96a1e54870350a | |
parent | 10cb807543dca60b59a380100d1b70730d0e8b29 (diff) |
Add latest changes from gitlab-org/gitlab@master
51 files changed, 399 insertions, 356 deletions
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index fda144d68f5..ac373477962 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -18,23 +18,6 @@ Lint/EmptyFile: - 'db/seeds.rb' - 'ee/db/geo/seeds.rb' -# Offense count: 13 -Lint/MixedRegexpCaptureTypes: - Exclude: - - 'app/models/alert_management/alert.rb' - - 'app/models/integrations/ewm.rb' - - 'app/uploaders/file_uploader.rb' - - 'ee/lib/gitlab/code_owners/reference_extractor.rb' - - 'lib/gitlab/ci/pipeline/expression/lexeme/string.rb' - - 'lib/gitlab/dependency_linker/gemfile_linker.rb' - - 'lib/gitlab/diff/suggestions_parser.rb' - - 'lib/gitlab/github_import/representation/note.rb' - - 'lib/gitlab/metrics/system.rb' - - 'lib/gitlab/request_profiler/profile.rb' - - 'lib/gitlab/slash_commands/issue_move.rb' - - 'lib/gitlab/slash_commands/issue_new.rb' - - 'lib/gitlab/slash_commands/run.rb' - # Offense count: 200 # Cop supports --auto-correct. Lint/RedundantCopDisableDirective: diff --git a/.rubocop_todo/lint/mixed_regexp_capture_types.yml b/.rubocop_todo/lint/mixed_regexp_capture_types.yml new file mode 100644 index 00000000000..f9872fdbd7f --- /dev/null +++ b/.rubocop_todo/lint/mixed_regexp_capture_types.yml @@ -0,0 +1,16 @@ +--- +Lint/MixedRegexpCaptureTypes: + Exclude: + - 'app/models/alert_management/alert.rb' + - 'app/models/integrations/ewm.rb' + - 'app/uploaders/file_uploader.rb' + - 'ee/lib/gitlab/code_owners/reference_extractor.rb' + - 'lib/gitlab/ci/pipeline/expression/lexeme/string.rb' + - 'lib/gitlab/dependency_linker/gemfile_linker.rb' + - 'lib/gitlab/diff/suggestions_parser.rb' + - 'lib/gitlab/github_import/representation/note.rb' + - 'lib/gitlab/metrics/system.rb' + - 'lib/gitlab/request_profiler/profile.rb' + - 'lib/gitlab/slash_commands/issue_move.rb' + - 'lib/gitlab/slash_commands/issue_new.rb' + - 'lib/gitlab/slash_commands/run.rb' diff --git a/app/assets/javascripts/boards/components/project_select.vue b/app/assets/javascripts/boards/components/project_select.vue index 1412411c275..f1cc7ae7d75 100644 --- a/app/assets/javascripts/boards/components/project_select.vue +++ b/app/assets/javascripts/boards/components/project_select.vue @@ -91,6 +91,9 @@ export default { loadMoreProjects() { this.fetchGroupProjects({ search: this.searchTerm, fetchNext: true }); }, + setFocus() { + this.$refs.search.focusInput(); + }, }, }; </script> @@ -107,8 +110,10 @@ export default { block menu-class="gl-w-full!" :loading="initialLoading" + @shown="setFocus" > <gl-search-box-by-type + ref="search" v-model.trim="searchTerm" debounce="250" :placeholder="$options.i18n.searchPlaceholder" diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js index 0e0c1475eda..ac32cf951f8 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js +++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js @@ -8,6 +8,7 @@ import createDefaultClient from '~/lib/graphql'; import initSourcegraph from '~/sourcegraph'; import ZenMode from '~/zen_mode'; import initAwardsApp from '~/emoji/awards_app'; +import MrWidgetHowToMergeModal from '~/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue'; import getStateQuery from './queries/get_state.query.graphql'; export default function initMergeRequestShow() { @@ -39,4 +40,24 @@ export default function initMergeRequestShow() { }); }, }); + + const modalEl = document.getElementById('js-check-out-modal'); + + // eslint-disable-next-line no-new + new Vue({ + el: modalEl, + render(h) { + return h(MrWidgetHowToMergeModal, { + props: { + canMerge: modalEl.dataset.canMerge === 'true', + isFork: modalEl.dataset.isFork === 'true', + sourceBranch: modalEl.dataset.sourceBranch, + sourceProjectPath: modalEl.dataset.sourceProjectPath, + targetBranch: modalEl.dataset.targetBranch, + sourceProjectDefaultUrl: modalEl.dataset.sourceProjectDefaultUrl, + reviewingDocsPath: modalEl.dataset.reviewingDocsPath, + }, + }); + }, + }); } diff --git a/app/assets/javascripts/security_configuration/components/app.vue b/app/assets/javascripts/security_configuration/components/app.vue index 8184658716f..ff0e0ed0ab2 100644 --- a/app/assets/javascripts/security_configuration/components/app.vue +++ b/app/assets/javascripts/security_configuration/components/app.vue @@ -3,12 +3,12 @@ import { GlTab, GlTabs, GlSprintf, GlLink, GlAlert } from '@gitlab/ui'; import { __, s__ } from '~/locale'; import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue'; +import SectionLayout from '~/vue_shared/security_configuration/components/section_layout.vue'; import AutoDevOpsAlert from './auto_dev_ops_alert.vue'; import AutoDevOpsEnabledAlert from './auto_dev_ops_enabled_alert.vue'; import { AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY } from './constants'; import FeatureCard from './feature_card.vue'; import TrainingProviderList from './training_provider_list.vue'; -import SectionLayout from './section_layout.vue'; import UpgradeBanner from './upgrade_banner.vue'; export const i18n = { @@ -173,7 +173,7 @@ export default { @dismiss="dismissAutoDevopsEnabledAlert" /> - <section-layout :heading="$options.i18n.securityTesting"> + <section-layout class="gl-border-b-0" :heading="$options.i18n.securityTesting"> <template #description> <p> <span data-testid="latest-pipeline-info-security"> diff --git a/app/assets/javascripts/security_configuration/components/section_layout.vue b/app/assets/javascripts/security_configuration/components/section_layout.vue deleted file mode 100644 index 1fe8dd862a0..00000000000 --- a/app/assets/javascripts/security_configuration/components/section_layout.vue +++ /dev/null @@ -1,23 +0,0 @@ -<script> -export default { - name: 'SectionLayout', - props: { - heading: { - type: String, - required: true, - }, - }, -}; -</script> - -<template> - <div class="row gl-line-height-20 gl-pt-6"> - <div class="col-lg-4"> - <h2 class="gl-font-size-h2 gl-mt-0">{{ heading }}</h2> - <slot name="description"></slot> - </div> - <div class="col-lg-8"> - <slot name="features"></slot> - </div> - </div> -</template> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue index 8cdaa3316ee..e1d88099580 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue @@ -1,9 +1,5 @@ <script> import { - GlButton, - GlDropdown, - GlDropdownSectionHeader, - GlDropdownItem, GlLink, GlTooltipDirective, GlModalDirective, @@ -14,8 +10,6 @@ import { constructWebIDEPath } from '~/lib/utils/url_utility'; import { s__ } from '~/locale'; import clipboardButton from '~/vue_shared/components/clipboard_button.vue'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; -import WebIdeLink from '~/vue_shared/components/web_ide_link.vue'; -import MrWidgetHowToMergeModal from './mr_widget_how_to_merge_modal.vue'; import MrWidgetIcon from './mr_widget_icon.vue'; export default { @@ -24,14 +18,8 @@ export default { clipboardButton, TooltipOnTruncate, MrWidgetIcon, - MrWidgetHowToMergeModal, - GlButton, - GlDropdown, - GlDropdownSectionHeader, - GlDropdownItem, GlLink, GlSprintf, - WebIdeLink, }, directives: { GlTooltip: GlTooltipDirective, @@ -107,71 +95,6 @@ export default { </gl-sprintf> </div> </div> - - <div class="branch-actions d-flex"> - <template v-if="mr.isOpen"> - <web-ide-link - v-if="!mr.sourceBranchRemoved" - :show-edit-button="false" - :show-web-ide-button="true" - :web-ide-url="webIdePath" - :web-ide-text="$options.i18n.webIdeText" - :show-gitpod-button="mr.showGitpodButton" - :gitpod-url="mr.gitpodUrl" - :gitpod-enabled="mr.gitpodEnabled" - :user-preferences-gitpod-path="mr.userPreferencesGitpodPath" - :user-profile-enable-gitpod-path="mr.userProfileEnableGitpodPath" - :gitpod-text="$options.i18n.gitpodText" - class="gl-display-none gl-md-display-inline-block gl-mr-3" - data-placement="bottom" - tabindex="0" - data-qa-selector="open_in_web_ide_button" - /> - <gl-button - v-gl-modal-directive="'modal-merge-info'" - :disabled="mr.sourceBranchRemoved" - class="js-check-out-branch gl-mr-3" - > - {{ s__('mrWidget|Check out branch') }} - </gl-button> - <mr-widget-how-to-merge-modal - :is-fork="isFork" - :can-merge="mr.canMerge" - :source-branch="mr.sourceBranch" - :source-project="mr.sourceProject" - :source-project-path="mr.sourceProjectFullPath" - :target-branch="mr.targetBranch" - :source-project-default-url="mr.sourceProjectDefaultUrl" - :reviewing-docs-path="mr.reviewingDocsPath" - /> - </template> - <gl-dropdown - v-gl-tooltip - :title="__('Download as')" - :aria-label="__('Download as')" - icon="download" - right - data-qa-selector="download_dropdown" - > - <gl-dropdown-section-header>{{ __('Download as') }}</gl-dropdown-section-header> - <gl-dropdown-item - :href="mr.emailPatchesPath" - class="js-download-email-patches" - download - data-qa-selector="download_email_patches_menu_item" - > - {{ s__('mrWidget|Email patches') }} - </gl-dropdown-item> - <gl-dropdown-item - :href="mr.plainDiffPath" - class="js-download-plain-diff" - download - data-qa-selector="download_plain_diff_menu_item" - > - {{ s__('mrWidget|Plain diff') }} - </gl-dropdown-item> - </gl-dropdown> - </div> </div> </div> </template> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue index e906b8c3b59..729782cd7a1 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue @@ -112,11 +112,17 @@ export default { return escapeShellString(this.sourceBranch); }, }, + mounted() { + document.querySelector('.js-check-out-modal-trigger')?.addEventListener('click', () => { + this.$refs.modal.show(); + }); + }, }; </script> <template> <gl-modal + ref="modal" modal-id="modal-merge-info" :no-enforce-focus="true" :title="$options.i18n.title" diff --git a/app/assets/javascripts/vue_shared/security_configuration/components/section_layout.vue b/app/assets/javascripts/vue_shared/security_configuration/components/section_layout.vue new file mode 100644 index 00000000000..6045d75ac11 --- /dev/null +++ b/app/assets/javascripts/vue_shared/security_configuration/components/section_layout.vue @@ -0,0 +1,34 @@ +<script> +import SectionLoader from './section_loader.vue'; + +export default { + name: 'SectionLayout', + components: { + SectionLoader, + }, + props: { + heading: { + type: String, + required: true, + }, + isLoading: { + type: Boolean, + required: false, + default: false, + }, + }, +}; +</script> + +<template> + <div class="row gl-m-0 gl-border-b gl-line-height-20 gl-py-6"> + <div class="col-lg-4 gl-pl-0 gl-pr-9"> + <h2 class="gl-font-size-h2 gl-mt-0">{{ heading }}</h2> + <slot name="description"></slot> + </div> + <div class="col-lg-8 gl-pr-0 gl-pl-0"> + <section-loader v-if="isLoading" /> + <slot v-else name="features"></slot> + </div> + </div> +</template> diff --git a/app/assets/javascripts/vue_shared/security_configuration/components/section_loader.vue b/app/assets/javascripts/vue_shared/security_configuration/components/section_loader.vue new file mode 100644 index 00000000000..b15e25b0943 --- /dev/null +++ b/app/assets/javascripts/vue_shared/security_configuration/components/section_loader.vue @@ -0,0 +1,35 @@ +<script> +import { GlCard, GlSkeletonLoader } from '@gitlab/ui'; + +export default { + name: 'SectionLoader', + components: { + GlCard, + GlSkeletonLoader, + }, +}; +</script> + +<template> + <div> + <gl-skeleton-loader :width="1248" :height="180"> + <rect x="0" y="0" width="100" height="15" rx="4" /> + <rect x="0" y="24" width="460" height="32" rx="4" /> + <rect x="0" y="71" width="100" height="15" rx="4" /> + <rect x="0" y="95" width="460" height="72" rx="4" /> + </gl-skeleton-loader> + <gl-card v-for="i in 2" :key="i" class="gl-mb-5"> + <template #header> + <gl-skeleton-loader :width="1248" :height="15"> + <rect x="0" y="0" width="300" height="15" rx="4" /> + </gl-skeleton-loader> + </template> + <gl-skeleton-loader :width="1248" :height="15"> + <rect x="0" y="0" width="600" height="15" rx="4" /> + </gl-skeleton-loader> + <gl-skeleton-loader :width="1248" :height="15"> + <rect x="0" y="0" width="300" height="15" rx="4" /> + </gl-skeleton-loader> + </gl-card> + </div> +</template> diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 9cebd4f49a4..d349bf7a1d3 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -261,7 +261,7 @@ .btn-block { width: 100%; margin: 0; - margin-bottom: 15px; + @include gl-mb-5; &.btn { padding: 6px 0; diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index 4a3ec5992a5..7f0bdadd2bc 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -45,7 +45,6 @@ .omniauth-container { box-shadow: 0 0 0 1px $border-color; border-radius: $border-radius; - padding: 15px; .login-heading h3 { font-weight: $gl-font-weight-normal; diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss index 0683123c778..87921051f1d 100644 --- a/app/assets/stylesheets/startup/startup-dark.scss +++ b/app/assets/stylesheets/startup/startup-dark.scss @@ -1865,6 +1865,7 @@ body.gl-dark } body.gl-dark .header-search { background-color: rgba(250, 250, 250, 0.2) !important; + border-radius: 4px; } body.gl-dark .header-search svg.gl-search-box-by-type-search-icon { color: rgba(250, 250, 250, 0.8); diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss index de6b8e6e672..fe840f50f1e 100644 --- a/app/assets/stylesheets/startup/startup-signin.scss +++ b/app/assets/stylesheets/startup/startup-signin.scss @@ -138,9 +138,8 @@ hr { margin-right: -15px; margin-left: -15px; } +.col-md-6, .col-sm-12, -.col-sm-7, -.col-sm-5, .col { position: relative; width: 100%; @@ -159,14 +158,6 @@ hr { order: 12; } @media (min-width: 576px) { - .col-sm-5 { - flex: 0 0 41.6666666667%; - max-width: 41.6666666667%; - } - .col-sm-7 { - flex: 0 0 58.3333333333%; - max-width: 58.3333333333%; - } .col-sm-12 { flex: 0 0 100%; max-width: 100%; @@ -178,6 +169,12 @@ hr { order: 12; } } +@media (min-width: 768px) { + .col-md-6 { + flex: 0 0 50%; + max-width: 50%; + } +} .form-control { display: block; width: 100%; @@ -578,7 +575,6 @@ svg { .login-page .omniauth-container { box-shadow: 0 0 0 1px #dbdbdb; border-radius: 0.25rem; - padding: 15px; } .login-page .login-box .login-heading h3, .login-page .omniauth-container .login-heading h3 { diff --git a/app/assets/stylesheets/themes/theme_helper.scss b/app/assets/stylesheets/themes/theme_helper.scss index 07194e2b532..234010074aa 100644 --- a/app/assets/stylesheets/themes/theme_helper.scss +++ b/app/assets/stylesheets/themes/theme_helper.scss @@ -150,6 +150,7 @@ .header-search { background-color: rgba($search-and-nav-links, 0.2) !important; + border-radius: $border-radius-default; &:hover { background-color: rgba($search-and-nav-links, 0.3) !important; diff --git a/app/assets/stylesheets/themes/theme_light.scss b/app/assets/stylesheets/themes/theme_light.scss index 10e03fb885c..66b2b3c3437 100644 --- a/app/assets/stylesheets/themes/theme_light.scss +++ b/app/assets/stylesheets/themes/theme_light.scss @@ -48,6 +48,7 @@ body { .header-search { background-color: $white !important; box-shadow: inset 0 0 0 1px $border-color !important; + border-radius: $border-radius-default; &:hover { background-color: $white !important; diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index cc18ab86251..0e4592259d8 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -15,7 +15,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController skip_cross_project_access_check :index, :starred feature_category :projects - urgency :low, [:starred] + urgency :low, [:starred, :index] def index respond_to do |format| diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb index f678e19d05d..90e13a7ec1a 100644 --- a/app/controllers/projects/autocomplete_sources_controller.rb +++ b/app/controllers/projects/autocomplete_sources_controller.rb @@ -9,7 +9,7 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController feature_category :users, [:members] feature_category :snippets, [:snippets] - urgency :low, [:merge_requests] + urgency :low, [:merge_requests, :members] def members render json: ::Projects::ParticipantsService.new(@project, current_user).execute(target) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 61eb7f52a8d..e57bacbd903 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -59,7 +59,8 @@ class ProjectsController < Projects::ApplicationController urgency :low, [:export, :remove_export, :generate_new_export, :download_export] # TODO: Set high urgency for #show https://gitlab.com/gitlab-org/gitlab/-/issues/334444 - urgency :low, [:refs, :show, :toggle_star, :transfer, :archive, :destroy, :update] + urgency :low, [:refs, :show, :toggle_star, :transfer, :archive, :destroy, :update, :activity, + :edit, :new, :export, :remove_export, :generate_new_export, :download_export] urgency :high, [:unfoldered_environment_names] def index diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e5091a23268..4b239ed9a56 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -34,7 +34,8 @@ class UsersController < ApplicationController feature_category :snippets, [:snippets] # TODO: Set higher urgency after resolving https://gitlab.com/gitlab-org/gitlab/-/issues/357914 - urgency :low, [:show, :calendar_activities] + urgency :low, [:show, :calendar_activities, :activity, :projects, :groups] + urgency :medium, [:calendar] urgency :high, [:exists] def show diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 2d93813d5ee..8c63b9eb930 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -206,6 +206,18 @@ module MergeRequestsHelper api_v4_projects_merge_requests_award_emoji_path(id: merge_request.project.id, merge_request_iid: merge_request.iid) end + def how_merge_modal_data(merge_request) + { + is_fork: merge_request.for_fork?, + can_merge: merge_request.can_be_merged_by?(current_user), + source_branch: merge_request.source_branch, + source_project: merge_request.source_project, + source_project_full_path: merge_request.source_project&.full_path, + target_branch: merge_request.target_branch, + reviewing_docs_path: help_page_path('user/project/merge_requests/reviews/index.md', anchor: "checkout-merge-requests-locally-through-the-head-ref") + } + end + private def review_requested_merge_requests_count diff --git a/app/services/concerns/ci/downstream_pipeline_helpers.rb b/app/services/concerns/ci/downstream_pipeline_helpers.rb index b738a332085..39c0adb6e4e 100644 --- a/app/services/concerns/ci/downstream_pipeline_helpers.rb +++ b/app/services/concerns/ci/downstream_pipeline_helpers.rb @@ -3,7 +3,6 @@ module Ci module DownstreamPipelineHelpers def log_downstream_pipeline_creation(downstream_pipeline) - return unless Feature.enabled?(:ci_log_downstream_pipeline_creation, project, default_enabled: :yaml) return unless downstream_pipeline&.persisted? hierarchy_size = downstream_pipeline.all_pipelines_in_hierarchy.count diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index 83e3fd85511..1280341ba66 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -1,12 +1,12 @@ = gitlab_ui_form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: 'new_user gl-show-field-errors js-sign-in-form', aria: { live: 'assertive' }, data: { testid: 'sign-in-form' }}) do |f| - .form-group + .form-group.gl-px-5.gl-pt-5 = f.label _('Username or email'), for: 'user_login', class: 'label-bold' = f.text_field :login, value: @invite_email, class: 'form-control gl-form-input top js-username-field', autofocus: 'autofocus', autocapitalize: 'off', autocorrect: 'off', required: true, title: _('This field is required.'), data: { qa_selector: 'login_field', testid: 'username-field' } - .form-group + .form-group.gl-px-5 = f.label :password, class: 'label-bold' = f.password_field :password, class: 'form-control gl-form-input bottom', autocomplete: 'current-password', required: true, title: _('This field is required.'), data: { qa_selector: 'password_field' } - if devise_mapping.rememberable? - %div + .gl-px-5 .gl-display-inline-block = f.gitlab_ui_checkbox_component :remember_me, _('Remember me') .gl-float-right @@ -18,7 +18,8 @@ - if Feature.enabled?(:arkose_labs_login_challenge) = render_if_exists 'devise/sessions/arkose_labs' - elsif captcha_enabled? || captcha_on_login_required? - = recaptcha_tags nonce: content_security_policy_nonce + .gl-px-5 + = recaptcha_tags nonce: content_security_policy_nonce - .submit-container.move-submit-down + .submit-container.move-submit-down.gl-px-5 = f.button _('Sign in'), type: :submit, class: "gl-button btn btn-block btn-confirm js-sign-in-button#{' js-no-auto-disable' if Feature.enabled?(:arkose_labs_login_challenge)}", data: { qa_selector: 'sign_in_button', testid: 'sign-in-button' } diff --git a/app/views/devise/sessions/_new_crowd.html.haml b/app/views/devise/sessions/_new_crowd.html.haml index fb4c011dd49..bdf357c5f74 100644 --- a/app/views/devise/sessions/_new_crowd.html.haml +++ b/app/views/devise/sessions/_new_crowd.html.haml @@ -1,13 +1,13 @@ = form_tag(omniauth_authorize_path(:user, :crowd), id: 'new_crowd_user', class: 'gl-show-field-errors') do - .form-group + .form-group.gl-px-5.gl-pt-5 = label_tag :username, _('Username or email') = text_field_tag :username, nil, { class: "form-control top", title: _("This field is required."), autofocus: "autofocus", required: true } - .form-group + .form-group.gl-px-5 = label_tag :password = password_field_tag :password, nil, { autocomplete: 'current-password', class: "form-control bottom", title: _("This field is required."), required: true } - if devise_mapping.rememberable? - .remember-me + .remember-me.gl-px-5 %label{ for: "remember_me" } = check_box_tag :remember_me, '1', false, id: 'remember_me' %span= _('Remember me') - = submit_tag _("Sign in"), class: "gl-button btn-confirm btn" + = submit_tag _("Sign in"), class: "gl-button btn-confirm btn gl-px-5" diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml index fea58779c17..4cde24f4afa 100644 --- a/app/views/devise/sessions/_new_ldap.html.haml +++ b/app/views/devise/sessions/_new_ldap.html.haml @@ -3,17 +3,17 @@ - submit_message = local_assigns.fetch(:submit_message, _('Sign in')) = form_tag(omniauth_callback_path(:user, server['provider_name']), id: 'new_ldap_user', class: "gl-show-field-errors") do - .form-group + .form-group.gl-px-5.gl-pt-5 = label_tag :username, "#{server['label']} Username" = text_field_tag :username, nil, { class: "form-control gl-form-input top", title: _("This field is required."), autofocus: "autofocus", data: { qa_selector: 'username_field' }, required: true } - .form-group + .form-group.gl-px-5 = label_tag :password = password_field_tag :password, nil, { autocomplete: 'current-password', class: "form-control gl-form-input bottom", title: _("This field is required."), data: { qa_selector: 'password_field' }, required: true } - if !hide_remember_me && devise_mapping.rememberable? - .remember-me + .remember-me.gl-px-5 %label{ for: "remember_me" } = check_box_tag :remember_me, '1', false, id: 'remember_me' %span= _('Remember me') - .submit-container.move-submit-down + .submit-container.move-submit-down.gl-px-5 = submit_tag submit_message, class: "gl-button btn btn-confirm", data: { qa_selector: 'sign_in_button' } diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml index 29bcb3c158b..77a2fda021f 100644 --- a/app/views/devise/sessions/two_factor.html.haml +++ b/app/views/devise/sessions/two_factor.html.haml @@ -1,6 +1,6 @@ %div = render 'devise/shared/tab_single', tab_title: _('Two-Factor Authentication') - .login-box + .login-box.gl-p-5 .login-body - if @user.two_factor_otp_enabled? = form_for(resource, as: resource_name, url: session_path(resource_name), method: :post, html: { class: "edit_user gl-show-field-errors js-2fa-form #{'hidden' if @user.two_factor_webauthn_u2f_enabled?}" }) do |f| diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml index bd7fe41ae8d..32b4a15517e 100644 --- a/app/views/devise/shared/_omniauth_box.html.haml +++ b/app/views/devise/shared/_omniauth_box.html.haml @@ -1,6 +1,6 @@ - hide_remember_me = local_assigns.fetch(:hide_remember_me, false) -.omniauth-container.gl-mt-5 +.omniauth-container.gl-mt-5.gl-p-5 %label.gl-font-weight-bold = _('Sign in with') - providers = enabled_button_based_providers diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml index 5c9c6a06ac1..cee5c1b6b69 100644 --- a/app/views/layouts/devise.html.haml +++ b/app/views/layouts/devise.html.haml @@ -16,7 +16,7 @@ %h1.mb-3.font-weight-normal = current_appearance&.title.presence || _('GitLab') .row.mb-3 - .col-sm-7.order-12.order-sm-1.brand-holder + .col-md-6.order-12.order-sm-1.brand-holder - unless recently_confirmed_com? = brand_image - if current_appearance&.description? @@ -36,7 +36,7 @@ = render_if_exists 'layouts/devise_help_text' - .col-sm-5.order-1.new-session-forms-container{ class: recently_confirmed_com? ? 'order-sm-first' : 'order-sm-12' } + .col-md-6.order-1.new-session-forms-container{ class: recently_confirmed_com? ? 'order-sm-first' : 'order-sm-12' } = yield = render 'devise/shared/footer', footer_message: footer_message diff --git a/app/views/notify/merged_merge_request_email.html.haml b/app/views/notify/merged_merge_request_email.html.haml index 0622e2f6ffb..8ffe3edd969 100644 --- a/app/views/notify/merged_merge_request_email.html.haml +++ b/app/views/notify/merged_merge_request_email.html.haml @@ -1,2 +1,16 @@ %p = sprintf(s_('Notify|Merge request %{merge_request} was merged'), { merge_request: merge_request_reference_link(@merge_request) }).html_safe + +%p + = merge_path_description(@merge_request, 'to') + +%p + = sprintf(s_('Notify|Author: %{author_name}'), { author_name: sanitize_name(@merge_request.author_name) }) + +- if @merge_request.assignees.any? + %p + = assignees_label(@merge_request) + +- if @merge_request.reviewers.any? + %p + = reviewers_label(@merge_request) diff --git a/app/views/notify/merged_merge_request_email.text.haml b/app/views/notify/merged_merge_request_email.text.haml index d6ec916641d..9b9eb566903 100644 --- a/app/views/notify/merged_merge_request_email.text.haml +++ b/app/views/notify/merged_merge_request_email.text.haml @@ -5,5 +5,9 @@ = merge_path_description(@merge_request, 'to') = sprintf(s_('Notify|Author: %{author_name}'), { author_name: sanitize_name(@merge_request.author_name) }) -= assignees_label(@merge_request) -= reviewers_label(@merge_request) + +- if @merge_request.assignees.any? + = assignees_label(@merge_request) + +- if @merge_request.reviewers.any? + = reviewers_label(@merge_request) diff --git a/app/views/projects/merge_requests/_code_dropdown.html.haml b/app/views/projects/merge_requests/_code_dropdown.html.haml new file mode 100644 index 00000000000..ab5716d5485 --- /dev/null +++ b/app/views/projects/merge_requests/_code_dropdown.html.haml @@ -0,0 +1,39 @@ +.float-left.gl-md-ml-3.dropdown.gl-new-dropdown{ class: "gl-display-none! gl-md-display-flex!" } + #js-check-out-modal{ data: how_merge_modal_data(@merge_request) } + = button_tag type: 'button', class: "btn dropdown-toggle btn-confirm gl-button gl-dropdown-toggle", data: { toggle: 'dropdown', qa_selector: 'mr_code_drodpown' } do + %span.gl-new-dropdown-button-text= _('Code') + = sprite_icon "chevron-down", size: 16, css_class: "dropdown-icon gl-icon gl-ml-2 gl-mr-0!" + .dropdown-menu.dropdown-menu-right + .gl-new-dropdown-inner + .gl-new-dropdown-contents + %ul + %li.gl-new-dropdown-section-header + %header.dropdown-header + = _('Review changes') + %li.gl-new-dropdown-item + %button.dropdown-item.js-check-out-modal-trigger{ type: 'button' } + .gl-new-dropdown-item-text-wrapper + = _('Check out branch') + - if current_user + %li.gl-new-dropdown-item + = link_to ide_merge_request_path(@merge_request), class: 'dropdown-item', data: { qa_selector: 'open_in_web_ide_button' } do + .gl-new-dropdown-item-text-wrapper + = _('Open in Web IDE') + - if Gitlab::CurrentSettings.gitpod_enabled && current_user&.gitpod_enabled + %li.gl-new-dropdown-item + = link_to "#{Gitlab::CurrentSettings.gitpod_url}##{merge_request_url(@merge_request)}", class: 'dropdown-item' do + .gl-new-dropdown-item-text-wrapper + = _('Open in Gitpod') + %li.gl-new-dropdown-divider + %hr.dropdown-divider + %li.gl-new-dropdown-section-header + %header.dropdown-header + = _('Download') + %li.gl-new-dropdown-item{ data: { qa_selector: 'download_email_patches_menu_item' } } + = link_to merge_request_path(@merge_request, format: :patch), class: 'dropdown-item', download: '' do + .gl-new-dropdown-item-text-wrapper + = _('Email patches') + %li.gl-new-dropdown-item{ data: { qa_selector: 'download_plain_diff_menu_item' } } + = link_to merge_request_path(@merge_request, format: :diff), class: 'dropdown-item' do + .gl-new-dropdown-item-text-wrapper + = _('Plain diff') diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml index ae44143f2ee..b40fef0e892 100644 --- a/app/views/projects/merge_requests/_mr_title.html.haml +++ b/app/views/projects/merge_requests/_mr_title.html.haml @@ -24,6 +24,9 @@ = sprite_icon('chevron-double-lg-left') .detail-page-header-actions.js-issuable-actions + - if @merge_request.source_project + = render 'projects/merge_requests/code_dropdown' + - if can_update_merge_request = link_to _('Edit'), edit_project_merge_request_path(@project, @merge_request), class: "gl-display-none gl-md-display-block btn gl-button btn-default btn-grouped js-issuable-edit", data: { qa_selector: "edit_button" } diff --git a/config/feature_flags/development/ci_log_downstream_pipeline_creation.yml b/config/feature_flags/development/ci_log_downstream_pipeline_creation.yml deleted file mode 100644 index 340055afd8c..00000000000 --- a/config/feature_flags/development/ci_log_downstream_pipeline_creation.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: ci_log_downstream_pipeline_creation -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84760 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/358425 -milestone: '15.0' -type: development -group: group::pipeline execution -default_enabled: false diff --git a/doc/api/members.md b/doc/api/members.md index 77a91436e6c..21ed6db7245 100644 --- a/doc/api/members.md +++ b/doc/api/members.md @@ -367,6 +367,7 @@ Example response: "web_url": "http://192.168.1.8:3000/root", "last_activity_on": "2021-01-27", "membership_type": "group_member", + "membership_state": "active", "removable": true, "created_at": "2021-01-03T12:16:02.000Z" }, @@ -380,6 +381,7 @@ Example response: "email": "john@example.com", "last_activity_on": "2021-01-25", "membership_type": "group_member", + "membership_state": "active", "removable": true, "created_at": "2021-01-04T18:46:42.000Z" }, @@ -392,6 +394,7 @@ Example response: "web_url": "http://192.168.1.8:3000/root", "last_activity_on": "2021-01-20", "membership_type": "group_invite", + "membership_state": "awaiting", "removable": false, "created_at": "2021-01-09T07:12:31.000Z" } diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md index a6e9968d1e0..c0a0ab2b7ef 100644 --- a/doc/user/shortcuts.md +++ b/doc/user/shortcuts.md @@ -136,9 +136,49 @@ These shortcuts are available when browsing the files in a project (go to These shortcuts are available when editing a file with the [Web IDE](project/web_ide/index.md): -| macOS shortcut | Windows shortcut | Description | -|---------------------------------------|---------------------|-------------| -| <kbd>Command</kbd> + <kbd>p</kbd> | <kbd>Control</kbd> + <kbd>p</kbd> | Search for, and then open another file for editing. | +| macOS shortcut | Windows shortcut | Description | +|---------------------------------|---------------------|-------------| +| <kbd>Option</kbd> + <kbd>Command</kbd> + <kbd>↑</kbd> | | Add cursor above | +| <kbd>Option</kbd> + <kbd>Command</kbd> + <kbd>↓</kbd> | | Add cursor below | +| <kbd>Shift</kbd> + <kbd>Option</kbd> + <kbd>I</kbd> | | Add cursors to line ends | +| <kbd>Command</kbd> + <kbd>K</kbd>, <kbd>Command</kbd> + <kbd>C</kbd> | <kbd>Control</kbd> + <kbd>K</kbd>, <kbd>Control</kbd> + <kbd>C</kbd> _or_ <kbd>Control</kbd> + <kbd>/</kbd> | Add line comment | +| <kbd>Command</kbd> + <kbd>D</kbd> | | Add selection to next find match | +| <kbd>Command</kbd> + <kbd>F2</kbd> | | Change all occurrences | +| <kbd>F1</kbd> | | Command palette | +| <kbd>Shift</kbd> + <kbd>Option</kbd> + <kbd>↓</kbd> | | Copy line down | +| <kbd>Shift</kbd> + <kbd>Option</kbd> + <kbd>↑</kbd> | | Copy line up | +| <kbd>Command</kbd> + <kbd>U</kbd> | | Cursor undo | +| <kbd>Command</kbd> + <kbd>Backspace<kbd> | | Delete all left | +| <kbd>Control</kbd> + <kbd>K</kbd> | | Delete all right | +| <kbd>Shift</kbd> + <kbd>Command</kbd> <kbd>K</kbd> | | Delete line | +| <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>Command</kbd> + <kbd>→</kbd> | | Expand selection | +| <kbd>Command</kbd> + <kbd>P</kbd> | | File finder | +| <kbd>Command</kbd> + <kbd>F</kbd> | | Find | +| <kbd>Enter</kbd> | | Find next | +| <kbd>Command</kbd> + <kbd>F3</kbd> | | Find next selection | +| <kbd>Shift</kbd> + <kbd>Enter</kbd> + <kbd>F3</kbd> | | Find previous | +| <kbd>Shift</kbd> + <kbd>Command</kbd> + <kbd>F3</kbd> | | Find previous selection | +| <kbd>Command</kbd> + <kbd>E</kbd> | | Find with selection | +| <kbd>Option</kbd> + <kbd>Command</kbd> + <kbd>[</kbd> | | Fold | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>O</kbd> | | Fold all | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>/</kbd> | | Fold all block comments | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>8</kbd> | | Fold all regions | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>-</kbd> | | Fold all regions except selected | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>1</kbd> | | Fold level 1 | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>2</kbd> | | Fold level 2 | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>3</kbd> | | Fold level 3 | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>4</kbd> | | Fold level 4 | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>5</kbd> | | Fold level 5 | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>6</kbd> | | Fold level 6 | +| <kbd>Command</kbd> + <kbd>K</kbd> , <kbd>Command</kbd> + <kbd>7</kbd> | | Fold level 7 | +| <kbd>Command</kbd> + <kbd>K</kbd> + <kbd>Command</kbd> + <kbd>[</kbd> | | Fold recursively | +| <kbd>Shift</kbd> + <kbd>Command</kbd> + <kbd>\ </kbd> | | Go to bracket | +| <kbd>Control</kbd> + <kbd>G</kbd> | | Go to line or column | +| <kbd>Option</kbd> + <kbd>F8</kbd> | | Go to next problem (error, warning, info) | +| <kbd>F8</kbd> | | Go to next problem in files (error, warning, info) | +| <kbd>Shift</kbd> + <kbd>Option</kbd> + <kbd>F8</kbd> | | Go to previous problem (error, warning, info) | +| <kbd>Shift</kbd> + <kbd>F8</kbd> | | Go to previous problem in files (error, warning, info) | +| <kbd>Command</kbd> + <kbd>p</kbd> | <kbd>Control</kbd> + <kbd>p</kbd> | Search for, and then open another file for editing. | | <kbd>Command</kbd> + <kbd>Enter</kbd> | <kbd>Control</kbd> + <kbd>Enter</kbd> | Commit (when editing the commit message). | ### Repository graph diff --git a/lib/api/avatar.rb b/lib/api/avatar.rb index a42d89ddf83..bd9fb37e18b 100644 --- a/lib/api/avatar.rb +++ b/lib/api/avatar.rb @@ -3,6 +3,7 @@ module API class Avatar < ::API::Base feature_category :users + urgency :high resource :avatar do desc 'Return avatar url for a user' do diff --git a/lib/api/error_tracking/client_keys.rb b/lib/api/error_tracking/client_keys.rb index e97df03b6f0..d92cf220433 100644 --- a/lib/api/error_tracking/client_keys.rb +++ b/lib/api/error_tracking/client_keys.rb @@ -43,6 +43,8 @@ module API delete '/client_keys/:key_id' do key = user_project.error_tracking_client_keys.find(params[:key_id]) key.destroy! + + present key, with: Entities::ErrorTracking::ClientKey end end end diff --git a/lib/api/events.rb b/lib/api/events.rb index db5ed7b7e6e..0a0141484ef 100644 --- a/lib/api/events.rb +++ b/lib/api/events.rb @@ -9,6 +9,7 @@ module API allow_access_with_scope :read_user, if: -> (request) { request.get? || request.head? } feature_category :users + urgency :low resource :events do desc "List currently authenticated user's events" do diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 0d0de29150e..d6f679d0255 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -361,7 +361,7 @@ module API use :group_list_params use :with_custom_attributes end - get ":id/descendant_groups", feature_category: :subgroups do + get ":id/descendant_groups", feature_category: :subgroups, urgency: :low do finder_params = declared_params(include_missing: false).merge(include_parent_descendants: true) groups = find_groups(finder_params, params[:id]) present_groups params, groups diff --git a/lib/api/namespaces.rb b/lib/api/namespaces.rb index 50c099359e6..b94c495c1f0 100644 --- a/lib/api/namespaces.rb +++ b/lib/api/namespaces.rb @@ -65,7 +65,7 @@ module API requires :namespace, type: String, desc: "Namespace's path" optional :parent_id, type: Integer, desc: "The ID of the parent namespace. If no ID is specified, only top-level namespaces are considered." end - get ':namespace/exists', requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS, feature_category: :subgroups do + get ':namespace/exists', requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS, feature_category: :subgroups, urgency: :low do namespace_path = params[:namespace] exists = Namespace.without_project_namespaces.by_parent(params[:parent_id]).filter_by_path(namespace_path).exists? diff --git a/lib/gitlab/ci/templates/dotNET-Core.gitlab-ci.yml b/lib/gitlab/ci/templates/dotNET-Core.gitlab-ci.yml index 09fce67db2d..b8d284532bd 100644 --- a/lib/gitlab/ci/templates/dotNET-Core.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/dotNET-Core.gitlab-ci.yml @@ -1,7 +1,7 @@ # To contribute improvements to CI/CD templates, please follow the Development guide at: # https://docs.gitlab.com/ee/development/cicd/templates.html # This specific template is located at: -# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/dotNET-Core.yml +# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/dotNET-Core.gitlab-ci.yml # This is a simple example illustrating how to build and test .NET Core project # with GitLab Continuous Integration / Continuous Delivery. diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 11d5dcd14e1..941ff5ab6c2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6609,6 +6609,9 @@ msgstr "" msgid "CI/CD configuration file" msgstr "" +msgid "CI/CD minutes" +msgstr "" + msgid "CI/CD|No projects have been added to the scope" msgstr "" @@ -6624,6 +6627,9 @@ msgstr "" msgid "CICDAnalytics|Lead time" msgstr "" +msgid "CICDAnalytics|No shared runner minute usage data available" +msgstr "" + msgid "CICDAnalytics|Projects with releases" msgstr "" @@ -7202,6 +7208,9 @@ msgstr "" msgid "Check feature availability on namespace plan" msgstr "" +msgid "Check out branch" +msgstr "" + msgid "Check out, review, and merge locally" msgstr "" @@ -13464,9 +13473,6 @@ msgstr "" msgid "Download artifacts" msgstr "" -msgid "Download as" -msgstr "" - msgid "Download codes" msgstr "" @@ -13560,6 +13566,9 @@ msgstr "" msgid "Duration" msgstr "" +msgid "Duration (min)" +msgstr "" + msgid "Duration|%s days" msgstr "" @@ -13839,6 +13848,9 @@ msgstr "" msgid "Email patch" msgstr "" +msgid "Email patches" +msgstr "" + msgid "Email sent" msgstr "" @@ -26266,9 +26278,18 @@ msgstr "" msgid "OnDemandScans|%{learnMoreLinkStart}Learn more about on-demand scans%{learnMoreLinkEnd}." msgstr "" +msgid "OnDemandScans|Add a schedule to run this scan at a specified date and time or on a recurring basis. Scheduled scans are automatically saved to scan library." +msgstr "" + +msgid "OnDemandScans|Analyze a deployed version of your web application for known vulnerabilities by examining it from the outside in. DAST works by simulating external attacks on your application while it is running." +msgstr "" + msgid "OnDemandScans|Are you sure you want to delete this scan?" msgstr "" +msgid "OnDemandScans|Cancel" +msgstr "" + msgid "OnDemandScans|Could not delete saved scan. Please refresh the page, or try again later." msgstr "" @@ -26290,22 +26311,37 @@ msgstr "" msgid "OnDemandScans|Create new site profile" msgstr "" +msgid "OnDemandScans|DAST configuration" +msgstr "" + +msgid "OnDemandScans|DAST scans for vulnerabilities in your project's running application, website, or API. For details of all configuration options, see the %{linkStart}GitLab DAST documentation%{linkEnd}." +msgstr "" + +msgid "OnDemandScans|Define the fundamental configuration options for your on-demand scan." +msgstr "" + msgid "OnDemandScans|Delete profile" msgstr "" msgid "OnDemandScans|Description (optional)" msgstr "" +msgid "OnDemandScans|Dynamic Application Security Testing (DAST)" +msgstr "" + msgid "OnDemandScans|Edit on-demand DAST scan" msgstr "" +msgid "OnDemandScans|Edit on-demand scan" +msgstr "" + msgid "OnDemandScans|Edit profile" msgstr "" -msgid "OnDemandScans|For example: Tests the login page for SQL injections" +msgid "OnDemandScans|Enable scan schedule" msgstr "" -msgid "OnDemandScans|Manage DAST scans" +msgid "OnDemandScans|For example: Tests the login page for SQL injections" msgstr "" msgid "OnDemandScans|Manage scanner profiles" @@ -26320,6 +26356,9 @@ msgstr "" msgid "OnDemandScans|New on-demand DAST scan" msgstr "" +msgid "OnDemandScans|New on-demand scan" +msgstr "" + msgid "OnDemandScans|New scan" msgstr "" @@ -26353,19 +26392,25 @@ msgstr "" msgid "OnDemandScans|Save scan" msgstr "" +msgid "OnDemandScans|Scan configuration" +msgstr "" + msgid "OnDemandScans|Scan library" msgstr "" msgid "OnDemandScans|Scan name" msgstr "" -msgid "OnDemandScans|Scan type" +msgid "OnDemandScans|Scan results will be associated with the selected branch." msgstr "" -msgid "OnDemandScans|Scanner profile" +msgid "OnDemandScans|Scan schedule" msgstr "" -msgid "OnDemandScans|Schedule scan" +msgid "OnDemandScans|Scan type" +msgstr "" + +msgid "OnDemandScans|Scanner profile" msgstr "" msgid "OnDemandScans|Select one of the existing profiles" @@ -26398,6 +26443,9 @@ msgstr "" msgid "OnDemandScans|There are no scheduled scans." msgstr "" +msgid "OnDemandScans|Timezone" +msgstr "" + msgid "OnDemandScans|Use existing scanner profile" msgstr "" @@ -26410,6 +26458,9 @@ msgstr "" msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan." msgstr "" +msgid "OnDemandScans|at" +msgstr "" + msgid "Once imported, repositories can be mirrored over SSH. Read more %{link_start}here%{link_end}." msgstr "" @@ -31614,9 +31665,6 @@ msgstr "" msgid "Reopens this %{quick_action_target}." msgstr "" -msgid "Repeats" -msgstr "" - msgid "Replace" msgstr "" @@ -40631,6 +40679,12 @@ msgstr "" msgid "UsageQuota|CI minutes usage by project" msgstr "" +msgid "UsageQuota|CI/CD minutes usage" +msgstr "" + +msgid "UsageQuota|CI/CD minutes usage since %{timeElapsed}" +msgstr "" + msgid "UsageQuota|Code packages and container images." msgstr "" @@ -40691,6 +40745,9 @@ msgstr "" msgid "UsageQuota|Shared bits of code and text." msgstr "" +msgid "UsageQuota|Shared runner usage" +msgstr "" + msgid "UsageQuota|Snippets" msgstr "" @@ -40739,6 +40796,12 @@ msgstr "" msgid "UsageQuota|Usage breakdown" msgstr "" +msgid "UsageQuota|Usage by month" +msgstr "" + +msgid "UsageQuota|Usage by project" +msgstr "" + msgid "UsageQuota|Usage of group resources across the projects in the %{strong_start}%{group_name}%{strong_end} group" msgstr "" @@ -40751,9 +40814,6 @@ msgstr "" msgid "UsageQuota|Usage quotas help link" msgstr "" -msgid "UsageQuota|Usage since" -msgstr "" - msgid "UsageQuota|When you purchase additional storage, we automatically unlock projects that were locked when you reached the %{actualRepositorySizeLimit} limit." msgstr "" @@ -45026,9 +45086,6 @@ msgstr "" msgid "mrWidget|Cancel auto-merge" msgstr "" -msgid "mrWidget|Check out branch" -msgstr "" - msgid "mrWidget|Checking if merge request can be merged…" msgstr "" @@ -45070,9 +45127,6 @@ msgstr "" msgid "mrWidget|Does not delete the source branch" msgstr "" -msgid "mrWidget|Email patches" -msgstr "" - msgid "mrWidget|Failed to load deployment statistics" msgstr "" @@ -45183,9 +45237,6 @@ msgstr "" msgid "mrWidget|Open in Web IDE" msgstr "" -msgid "mrWidget|Plain diff" -msgstr "" - msgid "mrWidget|Please restore it or use a different %{type} branch." msgstr "" diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index 689b3dba286..6aa2d4b407a 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -49,10 +49,9 @@ module QA element :comment_now_button end - view 'app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue' do - element :download_dropdown + view 'app/views/projects/merge_requests/_code_dropdown.html.haml' do + element :mr_code_drodpown element :download_email_patches_menu_item - element :download_plain_diff_menu_item element :open_in_web_ide_button end @@ -343,12 +342,12 @@ module QA end def view_email_patches - click_element(:download_dropdown) + click_element(:mr_code_drodpown) visit_link_in_element(:download_email_patches_menu_item) end def view_plain_diff - click_element(:download_dropdown) + click_element(:mr_code_drodpown) visit_link_in_element(:download_plain_diff_menu_item) end @@ -359,6 +358,7 @@ module QA end def click_open_in_web_ide + click_element(:mr_code_dropdown) click_element(:open_in_web_ide_button) wait_for_requests end diff --git a/spec/features/ide/user_opens_merge_request_spec.rb b/spec/features/ide/user_opens_merge_request_spec.rb index 72fe6eb6ca8..8f4668d49ee 100644 --- a/spec/features/ide/user_opens_merge_request_spec.rb +++ b/spec/features/ide/user_opens_merge_request_spec.rb @@ -14,6 +14,7 @@ RSpec.describe 'IDE merge request', :js do end it 'user opens merge request' do + click_button 'Code' click_link 'Open in Web IDE' wait_for_requests diff --git a/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb b/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb index 38546fd629d..5827266d4b7 100644 --- a/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb +++ b/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb @@ -11,6 +11,8 @@ RSpec.describe 'Merge request > User sees check out branch modal', :js do sign_in(user) visit project_merge_request_path(project, merge_request) wait_for_requests + + click_button 'Code' click_button('Check out branch') end diff --git a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb index d2bde320c54..bcc6abd4f65 100644 --- a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb +++ b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb @@ -62,6 +62,7 @@ RSpec.describe 'Merge request > User selects branches for new MR', :js do fill_in "merge_request_title", with: "Orphaned MR test" click_button "Create merge request" + click_button 'Code' click_button "Check out branch" expect(page).to have_content 'git checkout -b \'orphaned-branch\' \'origin/orphaned-branch\'' diff --git a/spec/frontend/boards/project_select_spec.js b/spec/frontend/boards/project_select_spec.js index 05dc7d28eaa..7206fb83212 100644 --- a/spec/frontend/boards/project_select_spec.js +++ b/spec/frontend/boards/project_select_spec.js @@ -1,4 +1,10 @@ -import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui'; +import { + GlDropdown, + GlDropdownItem, + GlSearchBoxByType, + GlLoadingIcon, + GlFormInput, +} from '@gitlab/ui'; import { mount } from '@vue/test-utils'; import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; @@ -23,6 +29,8 @@ describe('ProjectSelect component', () => { const findInMenuLoadingIcon = () => wrapper.find("[data-testid='dropdown-text-loading-icon']"); const findEmptySearchMessage = () => wrapper.find("[data-testid='empty-result-message']"); + const waitRAF = () => new Promise((resolve) => requestAnimationFrame(resolve)); + const createStore = ({ state, activeGroupProjects }) => { Vue.use(Vuex); @@ -61,6 +69,7 @@ describe('ProjectSelect component', () => { provide: { groupId: 1, }, + attachTo: document.body, }); }; @@ -120,6 +129,17 @@ describe('ProjectSelect component', () => { it('does not render empty search result message', () => { expect(findEmptySearchMessage().exists()).toBe(false); }); + + it('focuses on the search input', async () => { + const dropdownToggle = findGlDropdown().find('.dropdown-toggle'); + + await dropdownToggle.trigger('click'); + await waitRAF(); + await nextTick(); + + const searchInput = findGlDropdown().findComponent(GlFormInput).element; + expect(document.activeElement).toEqual(searchInput); + }); }); describe('when no projects are being returned', () => { diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js index 5a1f17573d4..ed6dc598845 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js @@ -1,7 +1,5 @@ import { shallowMount, mount } from '@vue/test-utils'; -import { nextTick } from 'vue'; import Header from '~/vue_merge_request_widget/components/mr_widget_header.vue'; -import WebIdeLink from '~/vue_shared/components/web_ide_link.vue'; describe('MRWidgetHeader', () => { let wrapper; @@ -17,16 +15,6 @@ describe('MRWidgetHeader', () => { gon.relative_url_root = ''; }); - const expectDownloadDropdownItems = () => { - const downloadEmailPatchesEl = wrapper.find('.js-download-email-patches'); - const downloadPlainDiffEl = wrapper.find('.js-download-plain-diff'); - - expect(downloadEmailPatchesEl.text().trim()).toBe('Email patches'); - expect(downloadEmailPatchesEl.attributes('href')).toBe('/mr/email-patches'); - expect(downloadPlainDiffEl.text().trim()).toBe('Plain diff'); - expect(downloadPlainDiffEl.attributes('href')).toBe('/mr/plainDiffPath'); - }; - const commonMrProps = { divergedCommitsCount: 1, sourceBranch: 'mr-widget-refactor', @@ -36,8 +24,6 @@ describe('MRWidgetHeader', () => { statusPath: 'abc', }; - const findWebIdeButton = () => wrapper.findComponent(WebIdeLink); - describe('computed', () => { describe('shouldShowCommitsBehindText', () => { it('return true when there are divergedCommitsCount', () => { @@ -133,136 +119,6 @@ describe('MRWidgetHeader', () => { }); }); - describe('with an open merge request', () => { - const mrDefaultOptions = { - iid: 1, - divergedCommitsCount: 12, - sourceBranch: 'mr-widget-refactor', - sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>', - sourceBranchRemoved: false, - targetBranchPath: 'foo/bar/commits-path', - targetBranchTreePath: 'foo/bar/tree/path', - targetBranch: 'main', - isOpen: true, - canPushToSourceBranch: true, - emailPatchesPath: '/mr/email-patches', - plainDiffPath: '/mr/plainDiffPath', - statusPath: 'abc', - sourceProjectFullPath: 'root/gitlab-ce', - targetProjectFullPath: 'gitlab-org/gitlab-ce', - gitpodEnabled: true, - showGitpodButton: true, - gitpodUrl: 'http://gitpod.localhost', - userPreferencesGitpodPath: '/-/profile/preferences#user_gitpod_enabled', - userProfileEnableGitpodPath: '/-/profile?user%5Bgitpod_enabled%5D=true', - }; - - it('renders checkout branch button with modal trigger', () => { - createComponent({ - mr: { ...mrDefaultOptions }, - }); - - const button = wrapper.find('.js-check-out-branch'); - - expect(button.text().trim()).toBe('Check out branch'); - }); - - it.each([ - [ - 'renders web ide button', - { - mrProps: {}, - relativeUrl: '', - webIdeUrl: - '/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=gitlab-org%2Fgitlab-ce', - }, - ], - [ - 'renders web ide button with blank target_project, when mr has same target project', - { - mrProps: { targetProjectFullPath: 'root/gitlab-ce' }, - relativeUrl: '', - webIdeUrl: '/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=', - }, - ], - [ - 'renders web ide button with relative url', - { - mrProps: { iid: 2 }, - relativeUrl: '/gitlab', - webIdeUrl: - '/gitlab/-/ide/project/root/gitlab-ce/merge_requests/2?target_project=gitlab-org%2Fgitlab-ce', - }, - ], - ])('%s', async (_, { mrProps, relativeUrl, webIdeUrl }) => { - gon.relative_url_root = relativeUrl; - createComponent({ - mr: { ...mrDefaultOptions, ...mrProps }, - }); - - await nextTick(); - - expect(findWebIdeButton().props()).toMatchObject({ - showEditButton: false, - showWebIdeButton: true, - webIdeText: 'Open in Web IDE', - gitpodText: 'Open in Gitpod', - gitpodEnabled: true, - showGitpodButton: true, - gitpodUrl: 'http://gitpod.localhost', - userPreferencesGitpodPath: mrDefaultOptions.userPreferencesGitpodPath, - userProfileEnableGitpodPath: mrDefaultOptions.userProfileEnableGitpodPath, - webIdeUrl, - }); - }); - - it('does not render web ide button if source branch is removed', async () => { - createComponent({ mr: { ...mrDefaultOptions, sourceBranchRemoved: true } }); - - await nextTick(); - - expect(findWebIdeButton().exists()).toBe(false); - }); - - it('renders download dropdown with links', () => { - createComponent({ - mr: { ...mrDefaultOptions }, - }); - - expectDownloadDropdownItems(); - }); - }); - - describe('with a closed merge request', () => { - beforeEach(() => { - createComponent({ - mr: { - divergedCommitsCount: 12, - sourceBranch: 'mr-widget-refactor', - sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">mr-widget-refactor</a>', - sourceBranchRemoved: false, - targetBranchPath: 'foo/bar/commits-path', - targetBranchTreePath: 'foo/bar/tree/path', - targetBranch: 'main', - isOpen: false, - emailPatchesPath: '/mr/email-patches', - plainDiffPath: '/mr/plainDiffPath', - statusPath: 'abc', - }, - }); - }); - - it('does not render checkout branch button with modal trigger', () => { - const button = wrapper.find('.js-check-out-branch'); - - expect(button.exists()).toBe(false); - }); - - it('renders download dropdown with links', () => { - expectDownloadDropdownItems(); - }); - }); - describe('without diverged commits', () => { beforeEach(() => { createComponent({ diff --git a/spec/frontend/security_configuration/components/section_layout_spec.js b/spec/frontend/vue_shared/security_configuration/components/section_layout_spec.js index 75da380bbb8..136fe74b0d6 100644 --- a/spec/frontend/security_configuration/components/section_layout_spec.js +++ b/spec/frontend/vue_shared/security_configuration/components/section_layout_spec.js @@ -1,6 +1,7 @@ import { mount } from '@vue/test-utils'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import SectionLayout from '~/security_configuration/components/section_layout.vue'; +import SectionLayout from '~/vue_shared/security_configuration/components/section_layout.vue'; +import SectionLoader from '~/vue_shared/security_configuration/components/section_loader.vue'; describe('Section Layout component', () => { let wrapper; @@ -18,6 +19,7 @@ describe('Section Layout component', () => { }; const findHeading = () => wrapper.find('h2'); + const findLoader = () => wrapper.findComponent(SectionLoader); afterEach(() => { wrapper.destroy(); @@ -46,4 +48,11 @@ describe('Section Layout component', () => { }); }); }); + + describe('loading state', () => { + it('should show loaders when loading', () => { + createComponent({ heading: 'testheading', isLoading: true }); + expect(findLoader().exists()).toBe(true); + }); + }); }); diff --git a/spec/requests/api/error_tracking/client_keys_spec.rb b/spec/requests/api/error_tracking/client_keys_spec.rb index 00c1e8799e6..ba4d713dff2 100644 --- a/spec/requests/api/error_tracking/client_keys_spec.rb +++ b/spec/requests/api/error_tracking/client_keys_spec.rb @@ -81,6 +81,10 @@ RSpec.describe API::ErrorTracking::ClientKeys do it 'returns a correct status' do expect(response).to have_gitlab_http_status(:ok) end + + it 'returns specific fields using the entity' do + expect(json_response.keys).to match_array(%w[id active public_key sentry_dsn]) + end end end end diff --git a/spec/support/shared_examples/ci/log_downstream_pipeline_shared_examples.rb b/spec/support/shared_examples/ci/log_downstream_pipeline_shared_examples.rb index 1ccd41c31fe..db724dcfe99 100644 --- a/spec/support/shared_examples/ci/log_downstream_pipeline_shared_examples.rb +++ b/spec/support/shared_examples/ci/log_downstream_pipeline_shared_examples.rb @@ -31,16 +31,4 @@ RSpec.shared_examples 'logs downstream pipeline creation' do root_pipeline_namespace_path: expected_root_pipeline.project.namespace.full_path, root_pipeline_project_path: expected_root_pipeline.project.full_path) end - - context 'when feature flag ci_log_downstream_pipeline_creation is disabled' do - before do - stub_feature_flags(ci_log_downstream_pipeline_creation: false) - end - - it 'does not log the creation' do - log_entry = record_downstream_pipeline_logs { subject } - - expect(log_entry).to be_nil - end - end end |