diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-12 09:15:13 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-12 09:15:13 +0000 |
commit | 612dd7d31ab927dd79968a6be7cb36599291bace (patch) | |
tree | 6af6f616794ec0bd40bec2174d5bc58a4231fb21 /app | |
parent | 563d0d3bc956f6d6a9805720dade3b72bd488043 (diff) | |
download | gitlab-ce-612dd7d31ab927dd79968a6be7cb36599291bace.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
24 files changed, 167 insertions, 83 deletions
diff --git a/app/assets/javascripts/admin/users/components/user_actions.vue b/app/assets/javascripts/admin/users/components/user_actions.vue index 567d7151847..f5d21ece138 100644 --- a/app/assets/javascripts/admin/users/components/user_actions.vue +++ b/app/assets/javascripts/admin/users/components/user_actions.vue @@ -109,12 +109,13 @@ export default { <div v-if="hasDropdownActions" class="gl-p-2"> <gl-dropdown data-testid="dropdown-toggle" - right :text="$options.i18n.userAdministration" :text-sr-only="!showButtonLabels" icon="ellipsis_h" data-qa-selector="user_actions_dropdown_toggle" :data-qa-username="user.username" + no-caret + right > <gl-dropdown-section-header>{{ $options.i18n.userAdministration diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue index 563bed6a6b8..dc821cb9f58 100644 --- a/app/assets/javascripts/boards/components/board_card.vue +++ b/app/assets/javascripts/boards/components/board_card.vue @@ -72,7 +72,7 @@ export default { data-qa-selector="board_card" :class="{ 'multi-select': multiSelectVisible, - 'user-can-drag': isDraggable, + 'gl-cursor-grab': isDraggable, 'is-disabled': isDisabled, 'is-active': isActive, 'gl-cursor-not-allowed gl-bg-gray-10': item.isLoading, diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue index 19004518edf..6835d83a66c 100644 --- a/app/assets/javascripts/boards/components/board_list_header.vue +++ b/app/assets/javascripts/boards/components/board_list_header.vue @@ -263,7 +263,7 @@ export default { > <h3 :class="{ - 'user-can-drag': userCanDrag, + 'gl-cursor-grab': userCanDrag, 'gl-py-3 gl-h-full': list.collapsed && !isSwimlanesHeader, 'gl-border-b-0': list.collapsed || isSwimlanesHeader, 'gl-py-2': list.collapsed && isSwimlanesHeader, diff --git a/app/assets/javascripts/cycle_analytics/components/stage_table.vue b/app/assets/javascripts/cycle_analytics/components/stage_table.vue index fc4dfafb809..1139403bcf7 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_table.vue +++ b/app/assets/javascripts/cycle_analytics/components/stage_table.vue @@ -89,6 +89,11 @@ export default { required: false, default: true, }, + includeProjectName: { + type: Boolean, + required: false, + default: false, + }, }, data() { if (this.pagination) { @@ -144,8 +149,13 @@ export default { isMrLink(url = '') { return url.includes('/merge_request'); }, - itemId({ url, iid }) { - return this.isMrLink(url) ? `!${iid}` : `#${iid}`; + itemId({ iid, projectPath }, separator = '#') { + const prefix = this.includeProjectName ? projectPath : ''; + return `${prefix}${separator}${iid}`; + }, + itemDisplayName(item) { + const separator = this.isMrLink(item.url) ? '!' : '#'; + return this.itemId(item, separator); }, itemTitle(item) { return item.title || item.name; @@ -201,8 +211,11 @@ export default { <div data-testid="vsa-stage-event"> <div v-if="item.id" data-testid="vsa-stage-content"> <p class="gl-m-0"> - <gl-link class="gl-text-black-normal pipeline-id" :href="item.url" - >#{{ item.id }}</gl-link + <gl-link + data-testid="vsa-stage-event-link" + class="gl-text-black-normal pipeline-id" + :href="item.url" + >{{ itemId(item.id, '#') }}</gl-link > <gl-icon :size="16" name="fork" /> <gl-link @@ -240,7 +253,12 @@ export default { <gl-link class="gl-text-black-normal" :href="item.url">{{ itemTitle(item) }}</gl-link> </h5> <p class="gl-m-0"> - <gl-link class="gl-text-black-normal" :href="item.url">{{ itemId(item) }}</gl-link> + <gl-link + data-testid="vsa-stage-event-link" + class="gl-text-black-normal" + :href="item.url" + >{{ itemDisplayName(item) }}</gl-link + > <span class="gl-font-lg">·</span> <span data-testid="vsa-stage-event-date"> {{ s__('OpenedNDaysAgo|Opened') }} diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue index 167130cb6f2..ca38c83547b 100644 --- a/app/assets/javascripts/integrations/edit/components/integration_form.vue +++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue @@ -216,62 +216,69 @@ export default { v-bind="propsSource.jiraIssuesProps" @request-jira-issue-types="onRequestJiraIssueTypes" /> - <div v-if="isEditable" class="footer-block row-content-block"> - <template v-if="isInstanceOrGroupLevel"> + + <div + v-if="isEditable" + class="footer-block row-content-block gl-display-flex gl-justify-content-space-between" + > + <div> + <template v-if="isInstanceOrGroupLevel"> + <gl-button + v-gl-modal.confirmSaveIntegration + category="primary" + variant="confirm" + :loading="isSaving" + :disabled="disableButtons" + data-testid="save-button-instance-group" + data-qa-selector="save_changes_button" + > + {{ __('Save changes') }} + </gl-button> + <confirmation-modal @submit="onSaveClick" /> + </template> <gl-button - v-gl-modal.confirmSaveIntegration + v-else category="primary" variant="confirm" + type="submit" :loading="isSaving" :disabled="disableButtons" - data-testid="save-button-instance-group" + data-testid="save-button" data-qa-selector="save_changes_button" + @click.prevent="onSaveClick" > {{ __('Save changes') }} </gl-button> - <confirmation-modal @submit="onSaveClick" /> - </template> - <gl-button - v-else - category="primary" - variant="confirm" - type="submit" - :loading="isSaving" - :disabled="disableButtons" - data-testid="save-button" - data-qa-selector="save_changes_button" - @click.prevent="onSaveClick" - > - {{ __('Save changes') }} - </gl-button> - <gl-button - v-if="showTestButton" - category="secondary" - variant="confirm" - :loading="isTesting" - :disabled="disableButtons" - data-testid="test-button" - @click.prevent="onTestClick" - > - {{ __('Test settings') }} - </gl-button> + <gl-button + v-if="showTestButton" + category="secondary" + variant="confirm" + :loading="isTesting" + :disabled="disableButtons" + data-testid="test-button" + @click.prevent="onTestClick" + > + {{ __('Test settings') }} + </gl-button> + + <gl-button :href="propsSource.cancelPath">{{ __('Cancel') }}</gl-button> + </div> <template v-if="showResetButton"> <gl-button v-gl-modal.confirmResetIntegration - category="secondary" - variant="confirm" + category="tertiary" + variant="danger" :loading="isResetting" :disabled="disableButtons" data-testid="reset-button" > {{ __('Reset') }} </gl-button> + <reset-confirmation-modal @reset="onResetClick" /> </template> - - <gl-button :href="propsSource.cancelPath">{{ __('Cancel') }}</gl-button> </div> </div> </div> diff --git a/app/assets/javascripts/related_issues/components/related_issues_list.vue b/app/assets/javascripts/related_issues/components/related_issues_list.vue index 58138655241..8b39851405e 100644 --- a/app/assets/javascripts/related_issues/components/related_issues_list.vue +++ b/app/assets/javascripts/related_issues/components/related_issues_list.vue @@ -110,7 +110,7 @@ export default { v-for="issue in relatedIssues" :key="issue.id" :class="{ - 'user-can-drag': canReorder, + 'gl-cursor-grab': canReorder, 'sortable-row': canReorder, 'card card-slim': canReorder, }" diff --git a/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue b/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue index 1e9e866d382..82ee41d6def 100644 --- a/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue +++ b/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue @@ -1,6 +1,6 @@ <script> import { GlButton, GlButtonGroup, GlModalDirective, GlTooltipDirective } from '@gitlab/ui'; -import createFlash from '~/flash'; +import { createAlert } from '~/flash'; import { __, s__, sprintf } from '~/locale'; import runnerDeleteMutation from '~/runner/graphql/runner_delete.mutation.graphql'; import runnerActionsUpdateMutation from '~/runner/graphql/runner_actions_update.mutation.graphql'; @@ -139,7 +139,7 @@ export default { onError(error) { const { message } = error; - createFlash({ message }); + createAlert({ message }); this.reportToSentry(error); }, diff --git a/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue b/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue index 3bb15bff8d8..edcbcb2bf69 100644 --- a/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue +++ b/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue @@ -1,6 +1,6 @@ <script> import { GlDropdownItem, GlLoadingIcon } from '@gitlab/ui'; -import createFlash from '~/flash'; +import { createAlert } from '~/flash'; import { TYPE_GROUP, TYPE_PROJECT } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { __, s__ } from '~/locale'; @@ -91,7 +91,7 @@ export default { }, onError(error) { const { message } = error; - createFlash({ message }); + createAlert({ message }); this.reportToSentry(error); }, diff --git a/app/assets/javascripts/runner/components/runner_update_form.vue b/app/assets/javascripts/runner/components/runner_update_form.vue index 9a6fc07f6dd..aeb5869bcce 100644 --- a/app/assets/javascripts/runner/components/runner_update_form.vue +++ b/app/assets/javascripts/runner/components/runner_update_form.vue @@ -11,7 +11,7 @@ import { modelToUpdateMutationVariables, runnerToModel, } from 'ee_else_ce/runner/runner_details/runner_update_form_utils'; -import createFlash, { FLASH_TYPES } from '~/flash'; +import { createAlert, VARIANT_SUCCESS } from '~/flash'; import { __ } from '~/locale'; import { captureException } from '~/runner/sentry_utils'; import { ACCESS_LEVEL_NOT_PROTECTED, ACCESS_LEVEL_REF_PROTECTED, PROJECT_TYPE } from '../constants'; @@ -75,14 +75,14 @@ export default { if (errors?.length) { // Validation errors need not be thrown - createFlash({ message: errors[0] }); + createAlert({ message: errors[0] }); return; } this.onSuccess(); } catch (error) { const { message } = error; - createFlash({ message }); + createAlert({ message }); this.reportToSentry(error); } finally { @@ -90,7 +90,7 @@ export default { } }, onSuccess() { - createFlash({ message: __('Changes saved.'), type: FLASH_TYPES.SUCCESS }); + createAlert({ message: __('Changes saved.'), variant: VARIANT_SUCCESS }); this.model = runnerToModel(this.runner); }, reportToSentry(error) { diff --git a/app/assets/javascripts/runner/components/search_tokens/tag_token.vue b/app/assets/javascripts/runner/components/search_tokens/tag_token.vue index 7461308ab91..59230bb809e 100644 --- a/app/assets/javascripts/runner/components/search_tokens/tag_token.vue +++ b/app/assets/javascripts/runner/components/search_tokens/tag_token.vue @@ -1,6 +1,6 @@ <script> import { GlFilteredSearchSuggestion, GlToken } from '@gitlab/ui'; -import createFlash from '~/flash'; +import { createAlert } from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { s__ } from '~/locale'; @@ -50,7 +50,7 @@ export default { try { this.tags = await this.getTagsOptions(searchTerm); } catch { - createFlash({ + createAlert({ message: s__('Runners|Something went wrong while fetching the tags suggestions'), }); } finally { diff --git a/app/assets/javascripts/runner/group_runners/group_runners_app.vue b/app/assets/javascripts/runner/group_runners/group_runners_app.vue index a58a53a6a0d..f33f28c11e3 100644 --- a/app/assets/javascripts/runner/group_runners/group_runners_app.vue +++ b/app/assets/javascripts/runner/group_runners/group_runners_app.vue @@ -1,6 +1,6 @@ <script> import { GlLink } from '@gitlab/ui'; -import createFlash from '~/flash'; +import { createAlert } from '~/flash'; import { fetchPolicies } from '~/lib/graphql'; import { updateHistory } from '~/lib/utils/url_utility'; import { formatNumber, sprintf, s__ } from '~/locale'; @@ -84,7 +84,7 @@ export default { }; }, error(error) { - createFlash({ message: I18N_FETCH_ERROR }); + createAlert({ message: I18N_FETCH_ERROR }); this.reportToSentry(error); }, diff --git a/app/assets/javascripts/runner/runner_details/runner_details_app.vue b/app/assets/javascripts/runner/runner_details/runner_details_app.vue index 7b5f4a90351..f0a1d781a3a 100644 --- a/app/assets/javascripts/runner/runner_details/runner_details_app.vue +++ b/app/assets/javascripts/runner/runner_details/runner_details_app.vue @@ -1,5 +1,5 @@ <script> -import createFlash from '~/flash'; +import { createAlert } from '~/flash'; import { TYPE_CI_RUNNER } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import RunnerHeader from '../components/runner_header.vue'; @@ -34,7 +34,7 @@ export default { }; }, error(error) { - createFlash({ message: I18N_FETCH_ERROR }); + createAlert({ message: I18N_FETCH_ERROR }); this.reportToSentry(error); }, diff --git a/app/assets/stylesheets/page_bundles/boards.scss b/app/assets/stylesheets/page_bundles/boards.scss index d4c59a6ab0c..f91ca489bdf 100644 --- a/app/assets/stylesheets/page_bundles/boards.scss +++ b/app/assets/stylesheets/page_bundles/boards.scss @@ -1,9 +1,5 @@ @import 'mixins_and_variables_and_functions'; -.user-can-drag { - cursor: grab; -} - .is-ghost { opacity: 0.3; pointer-events: none; diff --git a/app/assets/stylesheets/page_bundles/issues_list.scss b/app/assets/stylesheets/page_bundles/issues_list.scss index 8a958bdf0c5..41515a98e0a 100644 --- a/app/assets/stylesheets/page_bundles/issues_list.scss +++ b/app/assets/stylesheets/page_bundles/issues_list.scss @@ -35,10 +35,6 @@ } } -.user-can-drag { - cursor: grab; -} - .is-ghost { opacity: 0.3; pointer-events: none; diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index b1a5e4068cc..5aa2aca37f3 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -7,7 +7,7 @@ module IssuesHelper classes = ["issue"] classes << "closed" if issue.closed? classes << "today" if issue.new? - classes << "user-can-drag" if @sort == 'relative_position' + classes << "gl-cursor-grab" if @sort == 'relative_position' classes.join(' ') end diff --git a/app/models/deployment.rb b/app/models/deployment.rb index 943abdc7c1c..453c6bce362 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -8,6 +8,7 @@ class Deployment < ApplicationRecord include Importable include Gitlab::Utils::StrongMemoize include FastDestroyAll + include FromUnion StatusUpdateError = Class.new(StandardError) StatusSyncError = Class.new(StandardError) diff --git a/app/models/preloaders/environments/deployment_preloader.rb b/app/models/preloaders/environments/deployment_preloader.rb new file mode 100644 index 00000000000..fcf892698bb --- /dev/null +++ b/app/models/preloaders/environments/deployment_preloader.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Preloaders + module Environments + # This class is to batch-load deployments of multiple environments. + # The deployments to batch-load are fetched using UNION of N selects in a single query instead of default scoping with `IN (environment_id1, environment_id2 ...)`. + # See https://gitlab.com/gitlab-org/gitlab/-/issues/345672#note_761852224 for more details. + class DeploymentPreloader + attr_reader :environments + + def initialize(environments) + @environments = environments + end + + def execute_with_union(association_name, association_attributes) + load_deployment_association(association_name, association_attributes) + end + + private + + def load_deployment_association(association_name, association_attributes) + return unless environments.present? + + union_arg = environments.inject([]) do |result, environment| + result << environment.association(association_name).scope + end + + union_sql = Deployment.from_union(union_arg).to_sql + + deployments = Deployment + .from("(#{union_sql}) #{::Deployment.table_name}") + .preload(association_attributes) + + deployments_by_environment_id = deployments.index_by(&:environment_id) + + environments.each do |environment| + environment.association(association_name).target = deployments_by_environment_id[environment.id] + environment.association(association_name).loaded! + end + end + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 0e0388b52b7..3dacff4a989 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -48,7 +48,7 @@ class User < ApplicationRecord add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) } add_authentication_token_field :feed_token - add_authentication_token_field :static_object_token + add_authentication_token_field :static_object_token, encrypted: :optional default_value_for :admin, false default_value_for(:external) { Gitlab::CurrentSettings.user_default_external } diff --git a/app/serializers/analytics_build_entity.rb b/app/serializers/analytics_build_entity.rb index 99663c8d5eb..5beb945257f 100644 --- a/app/serializers/analytics_build_entity.rb +++ b/app/serializers/analytics_build_entity.rb @@ -9,6 +9,9 @@ class AnalyticsBuildEntity < Grape::Entity expose :ref, as: :branch expose :short_sha expose :author, using: UserEntity + expose :project_path do |build| + build.project.path + end expose :started_at, as: :date do |build| interval_in_words(build[:started_at]) diff --git a/app/serializers/analytics_issue_entity.rb b/app/serializers/analytics_issue_entity.rb index 307ce14a921..b3244740ae1 100644 --- a/app/serializers/analytics_issue_entity.rb +++ b/app/serializers/analytics_issue_entity.rb @@ -6,6 +6,9 @@ class AnalyticsIssueEntity < Grape::Entity expose :title expose :author, using: UserEntity + expose :project_path do |object| + object[:project_path] + end expose :iid do |object| object[:iid].to_s diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb index 2fb1ad52135..11445f93609 100644 --- a/app/serializers/environment_serializer.rb +++ b/app/serializers/environment_serializer.rb @@ -52,7 +52,17 @@ class EnvironmentSerializer < BaseSerializer end def batch_load(resource) - resource = resource.preload(environment_associations) + if ::Feature.enabled?(:custom_preloader_for_deployments, default_enabled: :yaml) + resource = resource.preload(environment_associations.except(:last_deployment, :upcoming_deployment)) + + Preloaders::Environments::DeploymentPreloader.new(resource) + .execute_with_union(:last_deployment, deployment_associations) + + Preloaders::Environments::DeploymentPreloader.new(resource) + .execute_with_union(:upcoming_deployment, deployment_associations) + else + resource = resource.preload(environment_associations) + end resource.all.to_a.tap do |environments| environments.each do |environment| diff --git a/app/services/ci/process_build_service.rb b/app/services/ci/process_build_service.rb index 5271c0fe93d..e6ec65fcc91 100644 --- a/app/services/ci/process_build_service.rb +++ b/app/services/ci/process_build_service.rb @@ -4,14 +4,7 @@ module Ci class ProcessBuildService < BaseService def execute(build, current_status) if valid_statuses_for_build(build).include?(current_status) - if build.schedulable? - build.schedule - elsif build.action? - build.actionize - else - enqueue(build) - end - + process(build) true else build.skip @@ -21,6 +14,16 @@ module Ci private + def process(build) + if build.schedulable? + build.schedule + elsif build.action? + build.actionize + else + enqueue(build) + end + end + def enqueue(build) build.enqueue end diff --git a/app/services/packages/terraform_module/create_package_service.rb b/app/services/packages/terraform_module/create_package_service.rb index 03f749edfa8..d1bc79089a3 100644 --- a/app/services/packages/terraform_module/create_package_service.rb +++ b/app/services/packages/terraform_module/create_package_service.rb @@ -7,7 +7,7 @@ module Packages def execute return error('Version is empty.', 400) if params[:module_version].blank? - return error('Package already exists.', 403) if current_package_exists_elsewhere? + return error('Access Denied', 403) if current_package_exists_elsewhere? return error('Package version already exists.', 403) if current_package_version_exists? return error('File is too large.', 400) if file_size_exceeded? diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml index bafb2085589..ca14d898d79 100644 --- a/app/views/admin/users/_head.html.haml +++ b/app/views/admin/users/_head.html.haml @@ -3,23 +3,26 @@ %h3.page-title.gl-m-0 = @user.name - if @user.blocked_pending_approval? - %span.cred + %span.gl-text-red-500 = s_('AdminUsers|(Pending approval)') - elsif @user.banned? - %span.cred + %span.gl-text-red-500 = s_('AdminUsers|(Banned)') - elsif @user.blocked? - %span.cred + %span.gl-text-red-500 = s_('AdminUsers|(Blocked)') - if @user.internal? - %span.cred + %span.gl-text-red-500 = s_('AdminUsers|(Internal)') - if @user.admin - %span.cred + %span.gl-text-red-500 = s_('AdminUsers|(Admin)') - if @user.deactivated? - %span.cred + %span.gl-text-red-500 = s_('AdminUsers|(Deactivated)') + - if @user.access_locked? + %span.gl-text-red-500 + = s_('AdminUsers|(Locked)') = render_if_exists 'admin/users/auditor_user_badge' = render_if_exists 'admin/users/gma_user_badge' |