diff options
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget')
37 files changed, 272 insertions, 170 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue index 9b822657184..a5b83167283 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue @@ -1,6 +1,7 @@ <script> import { GlButton } from '@gitlab/ui'; import { deprecatedCreateFlash as createFlash } from '~/flash'; +import { BV_SHOW_MODAL } from '~/lib/utils/constants'; import { s__ } from '~/locale'; import eventHub from '../../event_hub'; import approvalsMixin from '../../mixins/approvals'; @@ -124,7 +125,7 @@ export default { methods: { approve() { if (this.requirePasswordToApprove) { - this.$root.$emit('bv::show::modal', this.modalId); + this.$root.$emit(BV_SHOW_MODAL, this.modalId); return; } @@ -158,6 +159,7 @@ export default { .then((data) => { this.mr.setApprovals(data); eventHub.$emit('MRWidgetUpdateRequested'); + eventHub.$emit('ApprovalUpdated'); this.$emit('updated'); }) .catch(errFn) diff --git a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals_summary.vue b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals_summary.vue index fb342a5d340..ea73ab416de 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals_summary.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals_summary.vue @@ -1,8 +1,8 @@ <script> -import { n__, sprintf } from '~/locale'; import { toNounSeriesText } from '~/lib/utils/grammar'; -import UserAvatarList from '~/vue_shared/components/user_avatar/user_avatar_list.vue'; +import { n__, sprintf } from '~/locale'; import { APPROVED_MESSAGE } from '~/vue_merge_request_widget/components/approvals/messages'; +import UserAvatarList from '~/vue_shared/components/user_avatar/user_avatar_list.vue'; export default { components: { diff --git a/app/assets/javascripts/vue_merge_request_widget/components/artifacts_list_app.vue b/app/assets/javascripts/vue_merge_request_widget/components/artifacts_list_app.vue index 730e67761be..ebf42fa0be0 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/artifacts_list_app.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/artifacts_list_app.vue @@ -1,8 +1,8 @@ <script> import { mapActions, mapState, mapGetters } from 'vuex'; +import createStore from '../stores/artifacts_list'; import ArtifactsList from './artifacts_list.vue'; import MrCollapsibleExtension from './mr_collapsible_extension.vue'; -import createStore from '../stores/artifacts_list'; export default { store: createStore(), diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment.vue index f497936e299..d79da9d3b90 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment.vue @@ -1,7 +1,7 @@ <script> +import { MANUAL_DEPLOY, WILL_DEPLOY, CREATED } from './constants'; import DeploymentActions from './deployment_actions.vue'; import DeploymentInfo from './deployment_info.vue'; -import { MANUAL_DEPLOY, WILL_DEPLOY, CREATED } from './constants'; export default { // name: 'Deployment' is a false positive: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26#possible-false-positives diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue index 215df8acece..513d88ecab6 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue @@ -1,11 +1,9 @@ <script> -import { __, s__ } from '~/locale'; import { deprecatedCreateFlash as createFlash } from '~/flash'; import { visitUrl } from '~/lib/utils/url_utility'; +import { __, s__ } from '~/locale'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import MRWidgetService from '../../services/mr_widget_service'; -import DeploymentActionButton from './deployment_action_button.vue'; -import DeploymentViewButton from './deployment_view_button.vue'; import { MANUAL_DEPLOY, FAILED, @@ -15,6 +13,8 @@ import { REDEPLOYING, ACT_BUTTON_ICONS, } from './constants'; +import DeploymentActionButton from './deployment_action_button.vue'; +import DeploymentViewButton from './deployment_view_button.vue'; export default { name: 'DeploymentActions', diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_info.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_info.vue index 390469dec24..cbace1ad57c 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_info.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_info.vue @@ -3,7 +3,6 @@ import { GlLink, GlTooltipDirective } from '@gitlab/ui'; import { __ } from '~/locale'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; import timeagoMixin from '~/vue_shared/mixins/timeago'; -import MemoryUsage from './memory_usage.vue'; import { MANUAL_DEPLOY, WILL_DEPLOY, @@ -13,6 +12,7 @@ import { CANCELED, SKIPPED, } from './constants'; +import MemoryUsage from './memory_usage.vue'; export default { name: 'DeploymentInfo', diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/memory_usage.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/memory_usage.vue index 2f27216f2e9..410d2740e1d 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/memory_usage.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/memory_usage.vue @@ -1,9 +1,9 @@ <script> import { GlLoadingIcon, GlSprintf, GlLink } from '@gitlab/ui'; -import { s__ } from '~/locale'; +import { backOff } from '~/lib/utils/common_utils'; import statusCodes from '~/lib/utils/http_status'; import { bytesToMiB } from '~/lib/utils/number_utils'; -import { backOff } from '~/lib/utils/common_utils'; +import { s__ } from '~/locale'; import MemoryGraph from '~/vue_shared/components/memory_graph.vue'; import MRWidgetService from '../../services/mr_widget_service'; 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 6628ab7be83..71ff0fe6fbd 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,6 +1,5 @@ <script> /* eslint-disable vue/no-v-html */ -import { escape } from 'lodash'; import { GlButton, GlDropdown, @@ -9,12 +8,13 @@ import { GlTooltipDirective, GlModalDirective, } from '@gitlab/ui'; -import { n__, s__, sprintf } from '~/locale'; +import { escape } from 'lodash'; import { mergeUrlParams, webIDEUrl } from '~/lib/utils/url_utility'; +import { n__, s__, sprintf } from '~/locale'; import clipboardButton from '~/vue_shared/components/clipboard_button.vue'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; -import MrWidgetIcon from './mr_widget_icon.vue'; import MrWidgetHowToMergeModal from './mr_widget_how_to_merge_modal.vue'; +import MrWidgetIcon from './mr_widget_icon.vue'; export default { name: 'MRWidgetHeader', @@ -133,14 +133,12 @@ export default { v-gl-tooltip :title="ideButtonTitle" class="gl-display-none d-md-inline-block gl-mr-3" - :tabindex="!mr.canPushToSourceBranch ? 0 : null" + :tabindex="ideButtonTitle ? 0 : null" > <gl-button :href="webIdePath" :disabled="!mr.canPushToSourceBranch" class="js-web-ide" - tabindex="0" - role="button" data-qa-selector="open_in_web_ide_button" > {{ s__('mrWidget|Open in Web IDE') }} 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 785e8ef8e8f..7c50df5f104 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 @@ -1,8 +1,8 @@ <script> /* eslint-disable @gitlab/require-i18n-strings */ import { GlModal, GlLink, GlSprintf } from '@gitlab/ui'; -import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import { __ } from '~/locale'; +import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; export default { i18n: { diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue index 4c130945487..d022579ef54 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue @@ -1,5 +1,5 @@ <script> -/* eslint-disable vue/require-default-prop, vue/no-v-html */ +/* eslint-disable vue/require-default-prop */ import { GlIcon, GlLink, @@ -7,11 +7,12 @@ import { GlSprintf, GlTooltip, GlTooltipDirective, + GlSafeHtmlDirective, } from '@gitlab/ui'; import mrWidgetPipelineMixin from 'ee_else_ce/vue_merge_request_widget/mixins/mr_widget_pipeline'; import { s__, n__ } from '~/locale'; -import PipelineStage from '~/pipelines/components/pipelines_list/stage.vue'; import PipelineArtifacts from '~/pipelines/components/pipelines_list/pipelines_artifacts.vue'; +import PipelineStage from '~/pipelines/components/pipelines_list/stage.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; @@ -32,6 +33,7 @@ export default { }, directives: { GlTooltip: GlTooltipDirective, + SafeHtml: GlSafeHtmlDirective, }, mixins: [mrWidgetPipelineMixin], props: { @@ -139,45 +141,38 @@ export default { <div class="ci-widget media"> <template v-if="hasCIError"> <gl-icon name="status_failed" class="gl-text-red-500" :size="24" /> - <div - class="gl-flex-fill-1 gl-ml-5" - tabindex="0" - role="text" - :aria-label="$options.errorText" - data-testid="ci-error-message" - > + <p class="gl-flex-fill-1 gl-ml-5 gl-mb-0" data-testid="ci-error-message"> <gl-sprintf :message="$options.errorText"> <template #link="{ content }"> <gl-link :href="mrTroubleshootingDocsPath">{{ content }}</gl-link> </template> </gl-sprintf> - </div> + </p> </template> <template v-else-if="!hasPipeline"> <gl-loading-icon size="md" /> - <div class="gl-flex-fill-1 gl-display-flex gl-ml-5" data-testid="monitoring-pipeline-message"> - <span tabindex="0" role="text" :aria-label="$options.monitoringPipelineText"> - <gl-sprintf :message="$options.monitoringPipelineText" /> - </span> + <p + class="gl-flex-fill-1 gl-display-flex gl-ml-5 gl-mb-0" + data-testid="monitoring-pipeline-message" + > + {{ $options.monitoringPipelineText }} <gl-link + v-gl-tooltip :href="ciTroubleshootingDocsPath" target="_blank" + :title="__('About this feature')" class="gl-display-flex gl-align-items-center gl-ml-2" - tabindex="0" > <gl-icon name="question" - :size="12" - tabindex="0" - role="text" :aria-label="__('Link to go to GitLab pipeline documentation')" /> </gl-link> - </div> + </p> </template> <template v-else-if="hasPipeline"> <a :href="status.details_path" class="align-self-start gl-mr-3"> - <ci-icon :status="status" :size="24" :borderless="true" class="add-border" /> + <ci-icon :status="status" :size="24" /> </a> <div class="ci-widget-container d-flex"> <div class="ci-widget-content"> @@ -208,10 +203,10 @@ export default { <template v-if="showSourceBranch"> {{ s__('Pipeline|on') }} <tooltip-on-truncate + v-safe-html="sourceBranchLink" :title="sourceBranch" truncate-target="child" class="label-branch label-truncate gl-font-weight-normal" - v-html="sourceBranchLink" /> </template> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue index 99b55c0f9ee..2bf86c1863a 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue @@ -1,10 +1,10 @@ <script> import { isNumber } from 'lodash'; import { sanitize } from '~/lib/dompurify'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import ArtifactsApp from './artifacts_list_app.vue'; import MrWidgetContainer from './mr_widget_container.vue'; import MrWidgetPipeline from './mr_widget_pipeline.vue'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; /** * Renders the pipeline and related deployments from the store. diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue index bc23ca6b1fc..677c50ed930 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue @@ -43,10 +43,9 @@ export default { <gl-button v-if="showDisabledButton" - type="button" category="primary" variant="success" - class="js-disabled-merge-button" + data-testid="disabled-merge-button" :disabled="true" > {{ s__('mrWidget|Merge') }} diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue index 7acdd695cc2..d2581f57837 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue @@ -1,6 +1,5 @@ <script> import { GlLink, GlSprintf, GlButton } from '@gitlab/ui'; -import MrWidgetIcon from './mr_widget_icon.vue'; import Tracking from '~/tracking'; import DismissibleContainer from '~/vue_shared/components/dismissible_container.vue'; import { @@ -13,6 +12,7 @@ import { SP_HELP_URL, SP_ICON_NAME, } from '../constants'; +import MrWidgetIcon from './mr_widget_icon.vue'; const trackingMixin = Tracking.mixin(); diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue index 20ac8f5a467..428641a1109 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue @@ -2,14 +2,15 @@ import { GlLoadingIcon, GlSkeletonLoader } from '@gitlab/ui'; import autoMergeMixin from 'ee_else_ce/vue_merge_request_widget/mixins/auto_merge'; import autoMergeEnabledQuery from 'ee_else_ce/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql'; +import { getIdFromGraphQLId } from '~/graphql_shared/utils'; +import { __ } from '~/locale'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { deprecatedCreateFlash as Flash } from '../../../flash'; -import statusIcon from '../mr_widget_status_icon.vue'; -import MrWidgetAuthor from '../mr_widget_author.vue'; -import eventHub from '../../event_hub'; import { AUTO_MERGE_STRATEGIES } from '../../constants'; -import { __ } from '~/locale'; +import eventHub from '../../event_hub'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; +import MrWidgetAuthor from '../mr_widget_author.vue'; +import statusIcon from '../mr_widget_status_icon.vue'; export default { name: 'MRWidgetAutoMergeEnabled', @@ -53,7 +54,11 @@ export default { }, computed: { loading() { - return this.glFeatures.mergeRequestWidgetGraphql && this.$apollo.queries.state.loading; + return ( + this.glFeatures.mergeRequestWidgetGraphql && + this.$apollo.queries.state.loading && + Object.keys(this.state).length === 0 + ); }, mergeUser() { if (this.glFeatures.mergeRequestWidgetGraphql) { @@ -78,7 +83,7 @@ export default { canRemoveSourceBranch() { const { currentUserId } = this.mr; const mergeUserId = this.glFeatures.mergeRequestWidgetGraphql - ? this.state.mergeUser?.id + ? getIdFromGraphQLId(this.state.mergeUser?.id) : this.mr.mergeUserId; const canRemoveSourceBranch = this.glFeatures.mergeRequestWidgetGraphql ? this.state.userPermissions.removeSourceBranch @@ -96,7 +101,11 @@ export default { .cancelAutomaticMerge() .then((res) => res.data) .then((data) => { - eventHub.$emit('UpdateWidgetData', data); + if (this.glFeatures.mergeRequestWidgetGraphql) { + eventHub.$emit('MRWidgetUpdateRequested'); + } else { + eventHub.$emit('UpdateWidgetData', data); + } }) .catch(() => { this.isCancellingAutoMerge = false; @@ -119,6 +128,11 @@ export default { eventHub.$emit('MRWidgetUpdateRequested'); } }) + .then(() => { + if (this.glFeatures.mergeRequestWidgetGraphql) { + this.$apollo.queries.state.refetch(); + } + }) .catch(() => { this.isRemovingSourceBranch = false; Flash(__('Something went wrong. Please try again.')); diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue index a2771bc4bfb..5f8630bf7b3 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue @@ -2,9 +2,9 @@ import { GlLoadingIcon, GlButton } from '@gitlab/ui'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import eventHub from '../../event_hub'; -import statusIcon from '../mr_widget_status_icon.vue'; -import autoMergeFailedQuery from '../../queries/states/auto_merge_failed.query.graphql'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; +import autoMergeFailedQuery from '../../queries/states/auto_merge_failed.query.graphql'; +import statusIcon from '../mr_widget_status_icon.vue'; export default { name: 'MRWidgetAutoMergeFailed', diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue index 3d5daa4979b..2335e2984e4 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue @@ -1,14 +1,14 @@ <script> +import { GlButton, GlModalDirective, GlSkeletonLoader } from '@gitlab/ui'; import $ from 'jquery'; import { escape } from 'lodash'; -import { GlButton, GlModalDirective, GlSkeletonLoader } from '@gitlab/ui'; import { s__, sprintf } from '~/locale'; import { mouseenter, debouncedMouseleave, togglePopover } from '~/shared/popover'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; -import StatusIcon from '../mr_widget_status_icon.vue'; import userPermissionsQuery from '../../queries/permissions.query.graphql'; import conflictsStateQuery from '../../queries/states/conflicts.query.graphql'; +import StatusIcon from '../mr_widget_status_icon.vue'; export default { name: 'MRWidgetConflicts', diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue index a5ec095b8ec..e973a2350a3 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue @@ -1,9 +1,9 @@ <script> import { GlButton } from '@gitlab/ui'; -import { n__ } from '~/locale'; import { stripHtml } from '~/lib/utils/text_utility'; -import statusIcon from '../mr_widget_status_icon.vue'; +import { sprintf, s__, n__ } from '~/locale'; import eventHub from '../../event_hub'; +import statusIcon from '../mr_widget_status_icon.vue'; export default { name: 'MRWidgetFailedToMerge', @@ -31,7 +31,15 @@ export default { computed: { mergeError() { - return this.mr.mergeError ? stripHtml(this.mr.mergeError, ' ').trim() : ''; + const mergeError = this.mr.mergeError ? stripHtml(this.mr.mergeError, ' ').trim() : ''; + + return sprintf( + s__('mrWidget|%{mergeError}.'), + { + mergeError, + }, + false, + ); }, timerText() { return n__( diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue index 9d646dbfb3e..043d14e32a2 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue @@ -3,10 +3,12 @@ import { GlLoadingIcon, GlButton, GlTooltipDirective } from '@gitlab/ui'; import { deprecatedCreateFlash as Flash } from '~/flash'; import { s__, __ } from '~/locale'; +import { OPEN_REVERT_MODAL, OPEN_CHERRY_PICK_MODAL } from '~/projects/commit/constants'; +import modalEventHub from '~/projects/commit/event_hub'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; +import eventHub from '../../event_hub'; import MrWidgetAuthorTime from '../mr_widget_author_time.vue'; import statusIcon from '../mr_widget_status_icon.vue'; -import eventHub from '../../event_hub'; export default { name: 'MRWidgetMerged', @@ -77,6 +79,9 @@ export default { return s__('mrWidget|Cherry-pick'); }, }, + mounted() { + document.dispatchEvent(new CustomEvent('merged:UpdateActions')); + }, methods: { removeSourceBranch() { this.isMakingRequest = true; @@ -98,6 +103,12 @@ export default { Flash(__('Something went wrong. Please try again.')); }); }, + openRevertModal() { + modalEventHub.$emit(OPEN_REVERT_MODAL); + }, + openCherryPickModal() { + modalEventHub.$emit(OPEN_CHERRY_PICK_MODAL); + }, }, }; </script> @@ -119,9 +130,7 @@ export default { size="small" category="secondary" variant="warning" - href="#modal-revert-commit" - data-toggle="modal" - data-container="body" + @click="openRevertModal" > {{ revertLabel }} </gl-button> @@ -142,9 +151,7 @@ export default { v-gl-tooltip.hover :title="cherryPickTitle" size="small" - href="#modal-cherry-pick-commit" - data-toggle="modal" - data-container="body" + @click="openCherryPickModal" > {{ cherryPickLabel }} </gl-button> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue index 3f68979bc0e..f91350d4a82 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue @@ -1,10 +1,10 @@ <script> import { GlIcon, GlTooltipDirective } from '@gitlab/ui'; import { sprintf, s__ } from '~/locale'; -import statusIcon from '../mr_widget_status_icon.vue'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; import missingBranchQuery from '../../queries/states/missing_branch.query.graphql'; +import statusIcon from '../mr_widget_status_icon.vue'; export default { name: 'MRWidgetMissingBranch', diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue index bf86e0d8b07..d15794c71b1 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue @@ -4,12 +4,12 @@ import { GlButton, GlSkeletonLoader } from '@gitlab/ui'; import { escape } from 'lodash'; import { __, sprintf } from '~/locale'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import { deprecatedCreateFlash as Flash } from '../../../flash'; import simplePoll from '../../../lib/utils/simple_poll'; import eventHub from '../../event_hub'; -import statusIcon from '../mr_widget_status_icon.vue'; -import rebaseQuery from '../../queries/states/ready_to_merge.query.graphql'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; -import { deprecatedCreateFlash as Flash } from '../../../flash'; +import rebaseQuery from '../../queries/states/rebase.query.graphql'; +import statusIcon from '../mr_widget_status_icon.vue'; export default { name: 'MRWidgetRebase', @@ -159,7 +159,7 @@ export default { <div class="rebase-state-find-class-convention media media-body space-children"> <span v-if="rebaseInProgress || isMakingRequest" - class="gl-font-weight-bold gl-ml-0!" + class="gl-font-weight-bold" data-testid="rebase-message" >{{ __('Rebase in progress') }}</span > @@ -181,17 +181,12 @@ export default { > {{ __('Rebase') }} </gl-button> - <span - v-if="!rebasingError" - class="gl-font-weight-bold gl-ml-0!" - data-testid="rebase-message" - >{{ - __( - 'Fast-forward merge is not possible. Rebase the source branch onto the target branch.', - ) - }}</span - > - <span v-else class="gl-font-weight-bold danger gl-ml-0!" data-testid="rebase-message">{{ + <span v-if="!rebasingError" class="gl-font-weight-bold" data-testid="rebase-message">{{ + __( + 'Fast-forward merge is not possible. Rebase the source branch onto the target branch.', + ) + }}</span> + <span v-else class="gl-font-weight-bold danger" data-testid="rebase-message">{{ rebasingError }}</span> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue index 14a29483d3c..f0259a975db 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue @@ -1,9 +1,13 @@ <script> /* eslint-disable vue/no-v-html */ +import { GlButton } from '@gitlab/ui'; import emptyStateSVG from 'icons/_mr_widget_empty_state.svg'; export default { name: 'MRWidgetNothingToMerge', + components: { + GlButton, + }, props: { mr: { type: Object, @@ -25,11 +29,13 @@ export default { <span v-html="emptyStateSVG"></span> </div> <div class="text col-md-7 order-md-first col-12"> - <span>{{ - s__( - 'mrWidgetNothingToMerge|Merge requests are a place to propose changes you have made to a project and discuss those changes with others.', - ) - }}</span> + <p class="highlight"> + {{ + s__( + 'mrWidgetNothingToMerge|Merge requests are a place to propose changes you have made to a project and discuss those changes with others.', + ) + }} + </p> <p> {{ s__( @@ -45,9 +51,14 @@ export default { }} </p> <div> - <a v-if="mr.newBlobPath" :href="mr.newBlobPath" class="btn btn-inverted btn-success">{{ - __('Create file') - }}</a> + <gl-button + v-if="mr.newBlobPath" + :href="mr.newBlobPath" + category="secondary" + variant="success" + > + {{ __('Create file') }} + </gl-button> </div> </div> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue index 5f56157cb89..b5d2f91c637 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/pipeline_failed.vue @@ -1,11 +1,26 @@ <script> +import { GlLink, GlSprintf } from '@gitlab/ui'; +import { helpPagePath } from '~/helpers/help_page_helper'; +import { s__ } from '~/locale'; import statusIcon from '../mr_widget_status_icon.vue'; export default { name: 'PipelineFailed', components: { + GlLink, + GlSprintf, statusIcon, }, + computed: { + troubleshootingDocsPath() { + return helpPagePath('ci/troubleshooting', { anchor: 'merge-request-status-messages' }); + }, + }, + i18n: { + failedMessage: s__( + `mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions.`, + ), + }, }; </script> @@ -14,10 +29,13 @@ export default { <status-icon :show-disabled-button="true" status="warning" /> <div class="media-body space-children"> <span class="bold"> - {{ - s__(`mrWidget|The pipeline for this merge request failed. -Please retry the job or push a new commit to fix the failure`) - }} + <gl-sprintf :message="$options.i18n.failedMessage"> + <template #link="{ content }"> + <gl-link :href="troubleshootingDocsPath" target="_blank"> + {{ content }} + </gl-link> + </template> + </gl-sprintf> </span> </div> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index a890b176df0..690b6e9c462 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -1,5 +1,4 @@ <script> -import { isEmpty } from 'lodash'; import { GlIcon, GlButton, @@ -11,23 +10,24 @@ import { GlTooltipDirective, GlSkeletonLoader, } from '@gitlab/ui'; +import { isEmpty } from 'lodash'; import readyToMergeMixin from 'ee_else_ce/vue_merge_request_widget/mixins/ready_to_merge'; import readyToMergeQuery from 'ee_else_ce/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql'; +import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests'; import simplePoll from '~/lib/utils/simple_poll'; import { __ } from '~/locale'; -import MergeRequest from '../../../merge_request'; -import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; import { deprecatedCreateFlash as Flash } from '../../../flash'; +import MergeRequest from '../../../merge_request'; +import { AUTO_MERGE_STRATEGIES, DANGER, INFO, WARNING } from '../../constants'; +import eventHub from '../../event_hub'; +import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; import MergeRequestStore from '../../stores/mr_widget_store'; import statusIcon from '../mr_widget_status_icon.vue'; -import eventHub from '../../event_hub'; -import SquashBeforeMerge from './squash_before_merge.vue'; -import CommitsHeader from './commits_header.vue'; import CommitEdit from './commit_edit.vue'; import CommitMessageDropdown from './commit_message_dropdown.vue'; -import { AUTO_MERGE_STRATEGIES, DANGER, INFO, WARNING } from '../../constants'; +import CommitsHeader from './commits_header.vue'; +import SquashBeforeMerge from './squash_before_merge.vue'; const PIPELINE_RUNNING_STATE = 'running'; const PIPELINE_FAILED_STATE = 'failed'; @@ -53,10 +53,13 @@ export default { result({ data }) { this.state = { ...data.project.mergeRequest, - mergeRequestsFfOnlyEnabled: data.mergeRequestsFfOnlyEnabled, - onlyAllowMergeIfPipelineSucceeds: data.onlyAllowMergeIfPipelineSucceeds, + mergeRequestsFfOnlyEnabled: data.project.mergeRequestsFfOnlyEnabled, + onlyAllowMergeIfPipelineSucceeds: data.project.onlyAllowMergeIfPipelineSucceeds, }; - this.removeSourceBranch = data.project.mergeRequest.shouldRemoveSourceBranch; + this.removeSourceBranch = + data.project.mergeRequest.shouldRemoveSourceBranch || + data.project.mergeRequest.forceRemoveSourceBranch || + false; this.commitMessage = data.project.mergeRequest.defaultMergeCommitMessage; this.squashBeforeMerge = data.project.mergeRequest.squashOnMerge; this.isSquashReadOnly = data.project.squashReadOnly; @@ -277,7 +280,20 @@ export default { return this.mr.mergeRequestDiffsPath; }, }, + mounted() { + if (this.glFeatures.mergeRequestWidgetGraphql) { + eventHub.$on('ApprovalUpdated', this.updateGraphqlState); + } + }, + beforeDestroy() { + if (this.glFeatures.mergeRequestWidgetGraphql) { + eventHub.$off('ApprovalUpdated', this.updateGraphqlState); + } + }, methods: { + updateGraphqlState() { + return this.$apollo.queries.state.refetch(); + }, updateMergeCommitMessage(includeDescription) { const commitMessage = this.glFeatures.mergeRequestWidgetGraphql ? this.state.defaultMergeCommitMessage @@ -326,6 +342,10 @@ export default { } else if (hasError) { eventHub.$emit('FailedToMerge', data.merge_error); } + + if (this.glFeatures.mergeRequestWidgetGraphql) { + this.updateGraphqlState(); + } }) .catch(() => { this.isMakingRequest = false; @@ -442,6 +462,7 @@ export default { :variant="mergeButtonVariant" :disabled="isMergeButtonDisabled" :loading="isMakingRequest" + data-qa-selector="merge_button" @click="handleMergeButtonClick(isAutoMergeAvailable)" >{{ mergeButtonText }}</gl-button > @@ -532,7 +553,7 @@ export default { </div> <merge-train-helper-text v-if="shouldRenderMergeTrainHelperText" - :pipeline-id="pipeline.id" + :pipeline-id="pipelineId" :pipeline-link="pipeline.path" :merge-train-length="stateData.mergeTrainsCount" :merge-train-when-pipeline-succeeds-docs-path="mr.mergeTrainWhenPipelineSucceedsDocsPath" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue index 78e69b9ff9b..329964d009a 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue @@ -1,7 +1,7 @@ <script> import { GlButton } from '@gitlab/ui'; -import statusIcon from '../mr_widget_status_icon.vue'; import notesEventHub from '~/notes/event_hub'; +import statusIcon from '../mr_widget_status_icon.vue'; export default { name: 'UnresolvedDiscussions', diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue index 3f1db815f95..af305815381 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue @@ -1,17 +1,17 @@ <script> -import $ from 'jquery'; import { GlButton } from '@gitlab/ui'; import { produce } from 'immer'; -import { __ } from '~/locale'; +import $ from 'jquery'; import { deprecatedCreateFlash as createFlash } from '~/flash'; +import { __ } from '~/locale'; import MergeRequest from '~/merge_request'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import eventHub from '../../event_hub'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; import getStateQuery from '../../queries/get_state.query.graphql'; import workInProgressQuery from '../../queries/states/work_in_progress.query.graphql'; import removeWipMutation from '../../queries/toggle_wip.mutation.graphql'; import StatusIcon from '../mr_widget_status_icon.vue'; -import eventHub from '../../event_hub'; export default { name: 'WorkInProgress', diff --git a/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue b/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue index 180db7828a8..25f339b362f 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue @@ -1,9 +1,9 @@ <script> import { GlDeprecatedSkeletonLoading as GlSkeletonLoading, GlSprintf } from '@gitlab/ui'; -import { n__ } from '~/locale'; import axios from '~/lib/utils/axios_utils'; -import MrWidgetExpanableSection from '../mr_widget_expandable_section.vue'; import Poll from '~/lib/utils/poll'; +import { n__ } from '~/locale'; +import MrWidgetExpanableSection from '../mr_widget_expandable_section.vue'; import TerraformPlan from './terraform_plan.vue'; export default { @@ -128,12 +128,9 @@ export default { </template> <template #content> - <terraform-plan - v-for="(plan, key) in plansObject" - :key="key" - :plan="plan" - class="mr-widget-body" - /> + <div class="mr-widget-body gl-pb-1"> + <terraform-plan v-for="(plan, key) in plansObject" :key="key" :plan="plan" /> + </div> </template> </mr-widget-expanable-section> </section> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue b/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue index b74e036d9d9..25e3dae92e8 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/terraform/terraform_plan.vue @@ -15,6 +15,16 @@ export default { type: Object, }, }, + i18n: { + changes: s__( + 'Terraform|Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete', + ), + generationErrored: s__('Terraform|Generating the report caused an error.'), + namedReportFailed: s__('Terraform|The report %{name} failed to generate.'), + namedReportGenerated: s__('Terraform|The report %{name} was generated in your pipelines.'), + reportFailed: s__('Terraform|A report failed to generate.'), + reportGenerated: s__('Terraform|A report was generated in your pipelines.'), + }, computed: { addNum() { return Number(this.plan.create); @@ -30,23 +40,21 @@ export default { }, reportChangeText() { if (this.validPlanValues) { - return s__( - 'Terraform|Reported Resource Changes: %{addNum} to add, %{changeNum} to change, %{deleteNum} to delete', - ); + return this.$options.i18n.changes; } - return s__('Terraform|Generating the report caused an error.'); + return this.$options.i18n.generationErrored; }, reportHeaderText() { if (this.validPlanValues) { return this.plan.job_name - ? s__('Terraform|The Terraform report %{name} was generated in your pipelines.') - : s__('Terraform|A Terraform report was generated in your pipelines.'); + ? this.$options.i18n.namedReportGenerated + : this.$options.i18n.reportGenerated; } return this.plan.job_name - ? s__('Terraform|The Terraform report %{name} failed to generate.') - : s__('Terraform|A Terraform report failed to generate.'); + ? this.$options.i18n.namedReportFailed + : this.$options.i18n.reportFailed; }, validPlanValues() { return this.addNum + this.changeNum + this.deleteNum >= 0; @@ -56,16 +64,16 @@ export default { </script> <template> - <div class="gl-display-flex"> + <div class="gl-display-flex gl-pb-3"> <span - class="gl-display-flex gl-align-items-center gl-justify-content-center gl-mr-3 gl-align-self-start gl-mt-1" + class="gl-display-flex gl-align-items-center gl-justify-content-center gl-align-self-start gl-px-2" > - <gl-icon :name="iconType" :size="18" data-testid="change-type-icon" /> + <gl-icon :name="iconType" :size="16" data-testid="change-type-icon" /> </span> - <div class="gl-display-flex gl-flex-fill-1 gl-flex-direction-column flex-md-row"> - <div class="gl-flex-fill-1 gl-display-flex gl-flex-direction-column"> - <p class="gl-m-0 gl-pr-1"> + <div class="gl-display-flex gl-flex-fill-1 gl-flex-direction-column flex-md-row gl-pl-3"> + <div class="gl-flex-fill-1 gl-display-flex gl-flex-direction-column gl-pr-3"> + <p class="gl-mb-3 gl-line-height-normal"> <gl-sprintf :message="reportHeaderText"> <template #name> <strong>{{ plan.job_name }}</strong> @@ -73,7 +81,7 @@ export default { </gl-sprintf> </p> - <p class="gl-m-0"> + <p class="gl-mb-3 gl-line-height-normal"> <gl-sprintf :message="reportChangeText"> <template #addNum> <strong>{{ addNum }}</strong> diff --git a/app/assets/javascripts/vue_merge_request_widget/index.js b/app/assets/javascripts/vue_merge_request_widget/index.js index d512877a20d..c1c491f6fe0 100644 --- a/app/assets/javascripts/vue_merge_request_widget/index.js +++ b/app/assets/javascripts/vue_merge_request_widget/index.js @@ -1,8 +1,12 @@ +// This is a false violation of @gitlab/no-runtime-template-compiler, since it +// creates a new Vue instance by spreading a _valid_ Vue component definition +// into the Vue constructor. +/* eslint-disable @gitlab/no-runtime-template-compiler */ import Vue from 'vue'; -import MrWidgetOptions from 'ee_else_ce/vue_merge_request_widget/mr_widget_options.vue'; import VueApollo from 'vue-apollo'; -import Translate from '../vue_shared/translate'; +import MrWidgetOptions from 'ee_else_ce/vue_merge_request_widget/mr_widget_options.vue'; import createDefaultClient from '~/lib/graphql'; +import Translate from '../vue_shared/translate'; import { registerExtension } from './components/extensions'; import issueExtension from './extensions/issues'; diff --git a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js index fe512d68ea2..23215982e6e 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js +++ b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js @@ -35,5 +35,8 @@ export default { shouldRenderMergeTrainHelperText() { return false; }, + pipelineId() { + return this.pipeline.id; + }, }, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue index 519576d9fe6..2a53eb8b241 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue @@ -1,50 +1,50 @@ <script> +import { GlSafeHtmlDirective } from '@gitlab/ui'; import { isEmpty } from 'lodash'; -import MRWidgetStore from 'ee_else_ce/vue_merge_request_widget/stores/mr_widget_store'; -import MRWidgetService from 'ee_else_ce/vue_merge_request_widget/services/mr_widget_service'; import MrWidgetApprovals from 'ee_else_ce/vue_merge_request_widget/components/approvals/approvals.vue'; +import MRWidgetService from 'ee_else_ce/vue_merge_request_widget/services/mr_widget_service'; +import MRWidgetStore from 'ee_else_ce/vue_merge_request_widget/stores/mr_widget_store'; import stateMaps from 'ee_else_ce/vue_merge_request_widget/stores/state_maps'; -import { GlSafeHtmlDirective } from '@gitlab/ui'; +import { secondsToMilliseconds } from '~/lib/utils/datetime_utility'; +import notify from '~/lib/utils/notify'; import { sprintf, s__, __ } from '~/locale'; import Project from '~/pages/projects/project'; import SmartInterval from '~/smart_interval'; -import { secondsToMilliseconds } from '~/lib/utils/datetime_utility'; import { deprecatedCreateFlash as createFlash } from '../flash'; -import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variables'; +import { setFaviconOverlay } from '../lib/utils/favicon'; +import GroupedAccessibilityReportsApp from '../reports/accessibility_report/grouped_accessibility_reports_app.vue'; +import GroupedCodequalityReportsApp from '../reports/codequality_report/grouped_codequality_reports_app.vue'; +import GroupedTestReportsApp from '../reports/components/grouped_test_reports_app.vue'; import Loading from './components/loading.vue'; +import MrWidgetAlertMessage from './components/mr_widget_alert_message.vue'; import WidgetHeader from './components/mr_widget_header.vue'; -import WidgetSuggestPipeline from './components/mr_widget_suggest_pipeline.vue'; import WidgetMergeHelp from './components/mr_widget_merge_help.vue'; import MrWidgetPipelineContainer from './components/mr_widget_pipeline_container.vue'; import WidgetRelatedLinks from './components/mr_widget_related_links.vue'; -import MrWidgetAlertMessage from './components/mr_widget_alert_message.vue'; -import MergedState from './components/states/mr_widget_merged.vue'; -import ClosedState from './components/states/mr_widget_closed.vue'; -import MergingState from './components/states/mr_widget_merging.vue'; -import RebaseState from './components/states/mr_widget_rebase.vue'; -import WorkInProgressState from './components/states/work_in_progress.vue'; +import WidgetSuggestPipeline from './components/mr_widget_suggest_pipeline.vue'; +import SourceBranchRemovalStatus from './components/source_branch_removal_status.vue'; import ArchivedState from './components/states/mr_widget_archived.vue'; +import MrWidgetAutoMergeEnabled from './components/states/mr_widget_auto_merge_enabled.vue'; +import AutoMergeFailed from './components/states/mr_widget_auto_merge_failed.vue'; +import CheckingState from './components/states/mr_widget_checking.vue'; +import ClosedState from './components/states/mr_widget_closed.vue'; import ConflictsState from './components/states/mr_widget_conflicts.vue'; -import NothingToMergeState from './components/states/nothing_to_merge.vue'; +import FailedToMerge from './components/states/mr_widget_failed_to_merge.vue'; +import MergedState from './components/states/mr_widget_merged.vue'; +import MergingState from './components/states/mr_widget_merging.vue'; import MissingBranchState from './components/states/mr_widget_missing_branch.vue'; import NotAllowedState from './components/states/mr_widget_not_allowed.vue'; -import ReadyToMergeState from './components/states/ready_to_merge.vue'; -import UnresolvedDiscussionsState from './components/states/unresolved_discussions.vue'; import PipelineBlockedState from './components/states/mr_widget_pipeline_blocked.vue'; +import RebaseState from './components/states/mr_widget_rebase.vue'; +import NothingToMergeState from './components/states/nothing_to_merge.vue'; import PipelineFailedState from './components/states/pipeline_failed.vue'; -import FailedToMerge from './components/states/mr_widget_failed_to_merge.vue'; -import MrWidgetAutoMergeEnabled from './components/states/mr_widget_auto_merge_enabled.vue'; -import AutoMergeFailed from './components/states/mr_widget_auto_merge_failed.vue'; -import CheckingState from './components/states/mr_widget_checking.vue'; +import ReadyToMergeState from './components/states/ready_to_merge.vue'; +import UnresolvedDiscussionsState from './components/states/unresolved_discussions.vue'; +import WorkInProgressState from './components/states/work_in_progress.vue'; // import ExtensionsContainer from './components/extensions/container'; -import eventHub from './event_hub'; -import notify from '~/lib/utils/notify'; -import SourceBranchRemovalStatus from './components/source_branch_removal_status.vue'; import TerraformPlan from './components/terraform/mr_widget_terraform_container.vue'; -import GroupedCodequalityReportsApp from '../reports/codequality_report/grouped_codequality_reports_app.vue'; -import GroupedTestReportsApp from '../reports/components/grouped_test_reports_app.vue'; -import { setFaviconOverlay } from '../lib/utils/favicon'; -import GroupedAccessibilityReportsApp from '../reports/accessibility_report/grouped_accessibility_reports_app.vue'; +import eventHub from './event_hub'; +import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variables'; import getStateQuery from './queries/get_state.query.graphql'; export default { @@ -94,7 +94,6 @@ export default { state: { query: getStateQuery, manual: true, - pollInterval: 10 * 1000, skip() { return !this.mr || !window.gon?.features?.mergeRequestWidgetGraphql; }, @@ -181,7 +180,7 @@ export default { ); }, shouldRenderSecurityReport() { - return Boolean(window.gon?.features?.coreSecurityMrWidget && this.mr.pipeline.id); + return Boolean(this.mr.pipeline.id); }, mergeError() { let { mergeError } = this.mr; @@ -191,7 +190,7 @@ export default { } return sprintf( - s__('mrWidget|Merge failed: %{mergeError}. Please try again.'), + s__('mrWidget|%{mergeError}. Try again.'), { mergeError, }, @@ -286,6 +285,10 @@ export default { return new MRWidgetService(this.getServiceEndpoints(store)); }, checkStatus(cb, isRebased) { + if (window.gon?.features?.mergeRequestWidgetGraphql) { + this.$apollo.queries.state.refetch(); + } + return this.service .checkStatus() .then(({ data }) => { @@ -365,6 +368,7 @@ export default { const el = document.createElement('div'); el.innerHTML = res.data; document.body.appendChild(el); + document.dispatchEvent(new CustomEvent('merged:UpdateActions')); Project.initRefSwitcher(); } }) @@ -464,6 +468,7 @@ export default { :head-path="mr.codeclimate.head_path" :head-blob-path="mr.headBlobPath" :base-blob-path="mr.baseBlobPath" + :codequality-reports-path="mr.codequalityReportsPath" :codequality-help-path="mr.codequalityHelpPath" /> diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql index 44fc1cc7f23..13ea07884b1 100644 --- a/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql +++ b/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql @@ -14,10 +14,12 @@ query getState($projectPath: ID!, $iid: String!) { pipelines(first: 1) { nodes { status + warnings } } shouldBeRebased sourceBranchExists + state targetBranchExists userPermissions { canMerge diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.fragment.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.fragment.graphql index 64cd70fcf42..ad715599eb1 100644 --- a/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.fragment.graphql +++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.fragment.graphql @@ -1,6 +1,7 @@ fragment autoMergeEnabled on MergeRequest { autoMergeStrategy mergeUser { + id name username webUrl diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql index bdcb7a8206b..daf21e75b3b 100644 --- a/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql +++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql @@ -4,7 +4,6 @@ query autoMergeEnabledQuery($projectPath: ID!, $iid: String!) { project(fullPath: $projectPath) { mergeRequest(iid: $iid) { ...autoMergeEnabled - mergeTrainsCount } } } diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql index 9479ef3cf79..8ee45b05431 100644 --- a/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql +++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql @@ -5,6 +5,7 @@ fragment ReadyToMerge on Project { mergeRequest(iid: $iid) { autoMergeEnabled shouldRemoveSourceBranch + forceRemoveSourceBranch defaultMergeCommitMessage defaultMergeCommitMessageWithDescription defaultSquashCommitMessage diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/actions.js b/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/actions.js index 419793977f0..5fd5950859b 100644 --- a/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/actions.js +++ b/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/actions.js @@ -1,7 +1,7 @@ import Visibility from 'visibilityjs'; import axios from '~/lib/utils/axios_utils'; -import Poll from '~/lib/utils/poll'; import httpStatusCodes from '~/lib/utils/http_status'; +import Poll from '~/lib/utils/poll'; import * as types from './mutation_types'; diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/index.js b/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/index.js index e6cb5ead089..a2edfa94a48 100644 --- a/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/index.js +++ b/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/index.js @@ -1,8 +1,8 @@ import Vue from 'vue'; import Vuex from 'vuex'; import * as actions from './actions'; -import mutations from './mutations'; import * as getters from './getters'; +import mutations from './mutations'; import state from './state'; Vue.use(Vuex); diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js index a6bbab47a06..a0f14f558d2 100644 --- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js +++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js @@ -1,9 +1,9 @@ import { format } from 'timeago.js'; import getStateKey from 'ee_else_ce/vue_merge_request_widget/stores/get_state_key'; import mrEventHub from '~/merge_request/eventhub'; -import { stateKey } from './state_maps'; import { formatDate } from '../../lib/utils/datetime_utility'; import { MTWPS_MERGE_STRATEGY, MT_MERGE_STRATEGY, MWPS_MERGE_STRATEGY } from '../constants'; +import { stateKey } from './state_maps'; export default class MergeRequestStore { constructor(data) { @@ -156,9 +156,9 @@ export default class MergeRequestStore { this.setState(); - mrEventHub.$emit('mr.state.updated', { - state: this.mergeRequestState, - }); + if (!window.gon?.features?.mergeRequestWidgetGraphql) { + this.emitUpdatedState(); + } } setGraphqlData(project) { @@ -172,6 +172,11 @@ export default class MergeRequestStore { this.canBeMerged = mergeRequest.mergeStatus === 'can_be_merged'; this.canMerge = mergeRequest.userPermissions.canMerge; this.ciStatus = pipeline?.status.toLowerCase(); + + if (pipeline?.warnings && this.ciStatus === 'success') { + this.ciStatus = `${this.ciStatus}-with-warnings`; + } + this.commitsCount = mergeRequest.commitCount || 10; this.branchMissing = !mergeRequest.sourceBranchExists || !mergeRequest.targetBranchExists; this.hasConflicts = mergeRequest.conflicts; @@ -182,7 +187,9 @@ export default class MergeRequestStore { this.isSHAMismatch = this.sha !== mergeRequest.diffHeadSha; this.shouldBeRebased = mergeRequest.shouldBeRebased; this.workInProgress = mergeRequest.workInProgress; + this.mergeRequestState = mergeRequest.state; + this.emitUpdatedState(); this.setState(); } @@ -208,6 +215,12 @@ export default class MergeRequestStore { } } + emitUpdatedState() { + mrEventHub.$emit('mr.state.updated', { + state: this.mergeRequestState, + }); + } + setPaths(data) { // Paths are set on the first load of the page and not auto-refreshed this.squashBeforeMergeHelpPath = data.squash_before_merge_help_path; @@ -241,10 +254,11 @@ export default class MergeRequestStore { this.isDismissedSuggestPipeline = data.is_dismissed_suggest_pipeline; this.securityReportsDocsPath = data.security_reports_docs_path; - // codeclimate + // code quality const blobPath = data.blob_path || {}; this.headBlobPath = blobPath.head_path || ''; this.baseBlobPath = blobPath.base_path || ''; + this.codequalityReportsPath = data.codequality_reports_path; this.codequalityHelpPath = data.codequality_help_path; this.codeclimate = data.codeclimate; |