summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_merge_request_widget
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment/memory_usage.vue8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_alert_message.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_merge_help.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue13
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue164
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue19
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue110
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue457
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue24
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/issues.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/index.js6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mixins/approvals.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue31
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.fragment.graphql15
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_failed.query.graphql7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql41
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/rebase.query.graphql11
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/getters.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/index.js15
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js7
40 files changed, 707 insertions, 310 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 7297f8f8677..9b822657184 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
@@ -74,7 +74,7 @@ export default {
return this.mr.approvals || {};
},
approvedBy() {
- return this.approvals.approved_by ? this.approvals.approved_by.map(x => x.user) : [];
+ return this.approvals.approved_by ? this.approvals.approved_by.map((x) => x.user) : [];
},
userHasApproved() {
return Boolean(this.approvals.user_has_approved);
@@ -136,7 +136,7 @@ export default {
approveWithAuth(data) {
this.updateApproval(
() => this.service.approveMergeRequestWithAuth(data),
- error => {
+ (error) => {
if (error && error.response && error.response.status === 401) {
this.hasApprovalAuthError = true;
return;
@@ -155,7 +155,7 @@ export default {
this.isApproving = true;
this.clearError();
return serviceFn()
- .then(data => {
+ .then((data) => {
this.mr.setApprovals(data);
eventHub.$emit('MRWidgetUpdateRequested');
this.$emit('updated');
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 b90cbfd1a1a..215df8acece 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
@@ -121,7 +121,7 @@ export default {
this.actionInProgress = actionName;
MRWidgetService.executeInlineAction(endpoint)
- .then(resp => {
+ .then((resp) => {
const redirectUrl = resp?.data?.redirect_url;
if (redirectUrl) {
visitUrl(redirectUrl);
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue
index e3c0b7935d7..abc831c8abe 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_view_button.vue
@@ -57,7 +57,7 @@ export default {
return this.deployment.changes && this.deployment.changes.length > 1;
},
filteredChanges() {
- return this.deployment?.changes?.filter(change => change.path.includes(this.searchTerm));
+ return this.deployment?.changes?.filter((change) => change.path.includes(this.searchTerm));
},
},
};
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 9b2cd41092e..2f27216f2e9 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
@@ -102,7 +102,7 @@ export default {
loadMetrics() {
backOff((next, stop) => {
MRWidgetService.fetchMetrics(this.metricsUrl)
- .then(res => {
+ .then((res) => {
if (res.status === statusCodes.NO_CONTENT) {
this.backOffRequestCounter += 1;
/* eslint-disable no-unused-expressions */
@@ -113,14 +113,14 @@ export default {
})
.catch(stop);
})
- .then(res => {
+ .then((res) => {
if (res.status === statusCodes.NO_CONTENT) {
return res;
}
return res.data;
})
- .then(data => {
+ .then((data) => {
this.computeGraphData(data.metrics, data.deployment_time);
return data;
})
@@ -145,7 +145,7 @@ export default {
<template #metricsLink="{ content }">
<gl-link :href="metricsMonitoringUrl">{{ content }}</gl-link>
</template>
- <template #emphasis="{content}">
+ <template #emphasis="{ content }">
<strong>{{ content }}</strong>
</template>
<template #memoryFrom>{{ memoryFrom }}</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
index eff26729fa7..33809b953ee 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
@@ -67,11 +67,11 @@ export default {
},
mounted() {
this.fetchCollapsedData(this.$props)
- .then(data => {
+ .then((data) => {
this.collapsedData = data;
this.loadingState = null;
})
- .catch(e => {
+ .catch((e) => {
this.loadingState = LOADING_STATES.collapsedError;
throw e;
});
@@ -86,11 +86,11 @@ export default {
this.loadingState = LOADING_STATES.expandedLoading;
this.fetchFullData(this.$props)
- .then(data => {
+ .then((data) => {
this.loadingState = null;
this.fullData = data;
})
- .catch(e => {
+ .catch((e) => {
this.loadingState = null;
throw e;
});
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js b/app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js
index 5014c12dc30..529160de6a7 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/container.js
@@ -11,7 +11,7 @@ export default {
return h(
'div',
{},
- extensions.map(extension =>
+ extensions.map((extension) =>
h(extension, {
props: extensions[0].props.reduce(
(acc, key) => ({
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js b/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js
index 2bfaec8a1c9..9796bb44939 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/index.js
@@ -3,7 +3,7 @@ import ExtensionBase from './base.vue';
// Holds all the currently registered extensions
export const extensions = [];
-export const registerExtension = extension => {
+export const registerExtension = (extension) => {
// Pushes into the extenions array a dynamically created Vue component
// that gets exteneded from `base.vue`
extensions.push({
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_alert_message.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_alert_message.vue
index a2636ce52ad..560a68031ef 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_alert_message.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_alert_message.vue
@@ -13,7 +13,7 @@ export default {
type: String,
required: false,
default: DANGER,
- validator: value => [WARNING, DANGER].includes(value),
+ validator: (value) => [WARNING, DANGER].includes(value),
},
helpPath: {
type: String,
@@ -36,7 +36,7 @@ export default {
</script>
<template>
- <div class="m-3 ml-7" :class="messageClass">
+ <div class="gl-m-3 gl-ml-7" :class="messageClass">
<slot></slot>
<gl-link v-if="helpPath" :href="helpPath" target="_blank">
<gl-icon :size="16" name="question-o" class="align-middle" />
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_merge_help.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_merge_help.vue
index 1727383ea2c..3cd003461b3 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_merge_help.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_merge_help.vue
@@ -30,7 +30,7 @@ export default {
};
</script>
<template>
- <section class="mr-widget-help font-italic">
+ <section class="gl-py-3 gl-pr-3 gl-pl-5 gl-ml-7 mr-widget-help gl-font-style-italic">
<template v-if="missingBranch">
{{ missingBranchInfo }}
</template>
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 5066a88b52b..4c130945487 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
@@ -11,6 +11,7 @@ import {
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 CiIcon from '~/vue_shared/components/ci_icon.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
@@ -23,6 +24,7 @@ export default {
GlIcon,
GlSprintf,
GlTooltip,
+ PipelineArtifacts,
PipelineStage,
TooltipOnTruncate,
LinkedPipelinesMiniList: () =>
@@ -97,6 +99,9 @@ export default {
hasCommitInfo() {
return this.pipeline.commit && Object.keys(this.pipeline.commit).length > 0;
},
+ hasArtifacts() {
+ return this.pipeline?.details?.artifacts?.length > 0;
+ },
isMergeRequestPipeline() {
return Boolean(this.pipeline.flags && this.pipeline.flags.merge_request_pipeline);
},
@@ -142,7 +147,7 @@ export default {
data-testid="ci-error-message"
>
<gl-sprintf :message="$options.errorText">
- <template #link="{content}">
+ <template #link="{ content }">
<gl-link :href="mrTroubleshootingDocsPath">{{ content }}</gl-link>
</template>
</gl-sprintf>
@@ -218,7 +223,6 @@ export default {
data-testid="pipeline-coverage-delta"
>({{ pipelineCoverageDelta }}%)</span
>
-
{{ pipelineCoverageJobNumberText }}
<span ref="pipelineCoverageQuestion">
<gl-icon name="question" :size="12" />
@@ -258,6 +262,11 @@ export default {
</template>
</span>
<linked-pipelines-mini-list v-if="triggered.length" :triggered="triggered" />
+ <pipeline-artifacts
+ v-if="hasArtifacts"
+ :artifacts="pipeline.details.artifacts"
+ class="gl-ml-3"
+ />
</span>
</div>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
index 56a50b55f9d..43317130b08 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
@@ -30,7 +30,7 @@ export default {
};
</script>
<template>
- <section class="mr-info-list mr-links">
+ <section class="mr-info-list gl-ml-7 gl-pb-5">
<p v-if="relatedLinks.closing">{{ closesText }} <span v-html="relatedLinks.closing"></span></p>
<p v-if="relatedLinks.mentioned">
{{ s__('mrWidget|Mentions') }} <span v-html="relatedLinks.mentioned"></span>
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 a9d148505e1..7acdd695cc2 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
@@ -86,12 +86,12 @@ export default {
to create one.`)
"
>
- <template #prefixToLink="{content}">
+ <template #prefixToLink="{ content }">
<strong>
{{ content }}
</strong>
</template>
- <template #addPipelineLink="{content}">
+ <template #addPipelineLink="{ content }">
<gl-link
:href="pipelinePath"
class="gl-ml-1"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue b/app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue
index c917b69953f..d50d97e3570 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue
@@ -18,7 +18,7 @@ export default {
</script>
<template>
- <p v-once class="mr-info-list mr-links gl-mb-0">
+ <p v-once class="mr-info-list gl-ml-7 gl-pb-5 gl-mb-0">
<span class="status-text">
<gl-sprintf :message="$options.i18n.removesBranchText">
<template #strong="{ content }">
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue
index b6722de5277..73d75352cb5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue
@@ -25,12 +25,13 @@ export default {
class="mr-commit-dropdown"
>
<gl-dropdown-item
- v-for="commit in commits"
- :key="commit.short_id"
+ v-for="(commit, index) in commits"
+ :key="index"
class="text-nowrap text-truncate"
@click="$emit('input', commit.message)"
>
- <span class="monospace mr-2">{{ commit.short_id }}</span> {{ commit.title }}
+ <span class="monospace mr-2">{{ commit.shortId || commit.short_id }}</span>
+ {{ commit.title }}
</gl-dropdown-item>
</gl-dropdown>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue
index bdcea9871ea..d331f1690f5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue
@@ -83,6 +83,7 @@ export default {
:aria-label="ariaLabel"
category="tertiary"
class="commit-edit-toggle gl-mr-3"
+ size="small"
:icon="collapseIcon"
@click.stop="toggle()"
/>
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 750014c599a..20ac8f5a467 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
@@ -1,21 +1,37 @@
<script>
-import { GlLoadingIcon } from '@gitlab/ui';
+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 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 mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables';
export default {
name: 'MRWidgetAutoMergeEnabled',
+ apollo: {
+ state: {
+ query: autoMergeEnabledQuery,
+ skip() {
+ return !this.glFeatures.mergeRequestWidgetGraphql;
+ },
+ variables() {
+ return this.mergeRequestQueryVariables;
+ },
+ update: (data) => data.project?.mergeRequest,
+ },
+ },
components: {
MrWidgetAuthor,
statusIcon,
GlLoadingIcon,
+ GlSkeletonLoader,
},
- mixins: [autoMergeMixin],
+ mixins: [autoMergeMixin, glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
props: {
mr: {
type: Object,
@@ -30,20 +46,47 @@ export default {
},
data() {
return {
+ state: {},
isCancellingAutoMerge: false,
isRemovingSourceBranch: false,
};
},
computed: {
+ loading() {
+ return this.glFeatures.mergeRequestWidgetGraphql && this.$apollo.queries.state.loading;
+ },
+ mergeUser() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.mergeUser;
+ }
+
+ return this.mr.setToAutoMergeBy;
+ },
+ targetBranch() {
+ return (this.glFeatures.mergeRequestWidgetGraphql ? this.state : this.mr).targetBranch;
+ },
+ shouldRemoveSourceBranch() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.shouldRemoveSourceBranch || this.state.forceRemoveSourceBranch;
+ }
+
+ return this.mr.shouldRemoveSourceBranch;
+ },
+ autoMergeStrategy() {
+ return (this.glFeatures.mergeRequestWidgetGraphql ? this.state : this.mr).autoMergeStrategy;
+ },
canRemoveSourceBranch() {
- const {
- shouldRemoveSourceBranch,
- canRemoveSourceBranch,
- mergeUserId,
- currentUserId,
- } = this.mr;
+ const { currentUserId } = this.mr;
+ const mergeUserId = this.glFeatures.mergeRequestWidgetGraphql
+ ? this.state.mergeUser?.id
+ : this.mr.mergeUserId;
+ const canRemoveSourceBranch = this.glFeatures.mergeRequestWidgetGraphql
+ ? this.state.userPermissions.removeSourceBranch
+ : this.mr.canRemoveSourceBranch;
- return !shouldRemoveSourceBranch && canRemoveSourceBranch && mergeUserId === currentUserId;
+ return (
+ !this.shouldRemoveSourceBranch && canRemoveSourceBranch && mergeUserId === currentUserId
+ );
},
},
methods: {
@@ -51,8 +94,8 @@ export default {
this.isCancellingAutoMerge = true;
this.service
.cancelAutomaticMerge()
- .then(res => res.data)
- .then(data => {
+ .then((res) => res.data)
+ .then((data) => {
eventHub.$emit('UpdateWidgetData', data);
})
.catch(() => {
@@ -63,15 +106,15 @@ export default {
removeSourceBranch() {
const options = {
sha: this.mr.sha,
- auto_merge_strategy: this.mr.autoMergeStrategy,
+ auto_merge_strategy: this.autoMergeStrategy,
should_remove_source_branch: true,
};
this.isRemovingSourceBranch = true;
this.service
.merge(options)
- .then(res => res.data)
- .then(data => {
+ .then((res) => res.data)
+ .then((data) => {
if (AUTO_MERGE_STRATEGIES.includes(data.status)) {
eventHub.$emit('MRWidgetUpdateRequested');
}
@@ -86,49 +129,64 @@ export default {
</script>
<template>
<div class="mr-widget-body media">
- <status-icon status="success" />
- <div class="media-body">
- <h4 class="d-flex align-items-start">
- <span class="gl-mr-3">
- <span class="js-status-text-before-author">{{ statusTextBeforeAuthor }}</span>
- <mr-widget-author :author="mr.setToAutoMergeBy" />
- <span class="js-status-text-after-author">{{ statusTextAfterAuthor }}</span>
- </span>
- <a
- v-if="mr.canCancelAutomaticMerge"
- :disabled="isCancellingAutoMerge"
- role="button"
- href="#"
- class="btn btn-sm btn-default js-cancel-auto-merge"
- @click.prevent="cancelAutomaticMerge"
- >
- <gl-loading-icon v-if="isCancellingAutoMerge" inline class="gl-mr-1" />
- {{ cancelButtonText }}
- </a>
- </h4>
- <section class="mr-info-list">
- <p>
- {{ s__('mrWidget|The changes will be merged into') }}
- <a :href="mr.targetBranchPath" class="label-branch">{{ mr.targetBranch }}</a>
- </p>
- <p v-if="mr.shouldRemoveSourceBranch">
- {{ s__('mrWidget|The source branch will be deleted') }}
- </p>
- <p v-else class="d-flex align-items-start">
- <span class="gl-mr-3">{{ s__('mrWidget|The source branch will not be deleted') }}</span>
+ <div v-if="loading" class="gl-w-full mr-conflict-loader">
+ <gl-skeleton-loader :width="334" :height="30">
+ <rect x="0" y="3" width="24" height="24" rx="4" />
+ <rect x="32" y="7" width="150" height="16" rx="4" />
+ <rect x="190" y="7" width="144" height="16" rx="4" />
+ </gl-skeleton-loader>
+ </div>
+ <template v-else>
+ <status-icon status="success" />
+ <div class="media-body">
+ <h4 class="gl-display-flex">
+ <span class="gl-mr-3">
+ <span class="js-status-text-before-author" data-testid="beforeStatusText">{{
+ statusTextBeforeAuthor
+ }}</span>
+ <mr-widget-author :author="mergeUser" />
+ <span class="js-status-text-after-author" data-testid="afterStatusText">{{
+ statusTextAfterAuthor
+ }}</span>
+ </span>
<a
- v-if="canRemoveSourceBranch"
- :disabled="isRemovingSourceBranch"
+ v-if="mr.canCancelAutomaticMerge"
+ :disabled="isCancellingAutoMerge"
role="button"
- class="btn btn-sm btn-default js-remove-source-branch"
href="#"
- @click.prevent="removeSourceBranch"
+ class="btn btn-sm btn-default js-cancel-auto-merge"
+ data-testid="cancelAutomaticMergeButton"
+ @click.prevent="cancelAutomaticMerge"
>
- <gl-loading-icon v-if="isRemovingSourceBranch" inline class="gl-mr-1" />
- {{ s__('mrWidget|Delete source branch') }}
+ <gl-loading-icon v-if="isCancellingAutoMerge" inline class="gl-mr-1" />
+ {{ cancelButtonText }}
</a>
- </p>
- </section>
- </div>
+ </h4>
+ <section class="mr-info-list">
+ <p>
+ {{ s__('mrWidget|The changes will be merged into') }}
+ <a :href="mr.targetBranchPath" class="label-branch">{{ targetBranch }}</a>
+ </p>
+ <p v-if="shouldRemoveSourceBranch">
+ {{ s__('mrWidget|The source branch will be deleted') }}
+ </p>
+ <p v-else class="gl-display-flex">
+ <span class="gl-mr-3">{{ s__('mrWidget|The source branch will not be deleted') }}</span>
+ <a
+ v-if="canRemoveSourceBranch"
+ :disabled="isRemovingSourceBranch"
+ role="button"
+ class="btn btn-sm btn-default js-remove-source-branch"
+ href="#"
+ data-testid="removeSourceBranchButton"
+ @click.prevent="removeSourceBranch"
+ >
+ <gl-loading-icon v-if="isRemovingSourceBranch" inline class="gl-mr-1" />
+ {{ s__('mrWidget|Delete source branch') }}
+ </a>
+ </p>
+ </section>
+ </div>
+ </template>
</div>
</template>
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 30da9947859..a2771bc4bfb 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
@@ -1,7 +1,10 @@
<script>
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';
export default {
name: 'MRWidgetAutoMergeFailed',
@@ -10,6 +13,19 @@ export default {
GlLoadingIcon,
GlButton,
},
+ mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
+ apollo: {
+ mergeError: {
+ query: autoMergeFailedQuery,
+ skip() {
+ return !this.glFeatures.mergeRequestWidgetGraphql;
+ },
+ variables() {
+ return this.mergeRequestQueryVariables;
+ },
+ update: (data) => data.project?.mergeRequest?.mergeError,
+ },
+ },
props: {
mr: {
type: Object,
@@ -18,6 +34,7 @@ export default {
},
data() {
return {
+ mergeError: this.glFeatures.mergeRequestWidgetGraphql ? null : this.mr.mergeError,
isRefreshing: false,
};
},
@@ -36,7 +53,7 @@ export default {
<status-icon status="warning" />
<div class="media-body space-children gl-display-flex gl-flex-wrap gl-align-items-center">
<span class="bold">
- <template v-if="mr.mergeError">{{ mr.mergeError }}</template>
+ <template v-if="mergeError">{{ mergeError }}</template>
{{ s__('mrWidget|This merge request failed to be merged automatically') }}
</span>
<gl-button
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 87c59e5ece9..3d5daa4979b 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
@@ -30,7 +30,7 @@ export default {
variables() {
return this.mergeRequestQueryVariables;
},
- update: data => data.project.mergeRequest.userPermissions,
+ update: (data) => data.project.mergeRequest.userPermissions,
},
stateData: {
query: conflictsStateQuery,
@@ -40,7 +40,7 @@ export default {
variables() {
return this.mergeRequestQueryVariables;
},
- update: data => data.project.mergeRequest,
+ update: (data) => data.project.mergeRequest,
},
},
props: {
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 17cd740ddd9..9d646dbfb3e 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
@@ -83,8 +83,8 @@ export default {
this.service
.removeSourceBranch()
- .then(res => res.data)
- .then(data => {
+ .then((res) => res.data)
+ .then((data) => {
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26
// eslint-disable-next-line @gitlab/require-i18n-strings
if (data.message === 'Branch was deleted') {
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 8511797286d..3f68979bc0e 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
@@ -25,7 +25,7 @@ export default {
variables() {
return this.mergeRequestQueryVariables;
},
- update: data => data.project.mergeRequest,
+ update: (data) => data.project.mergeRequest,
},
},
props: {
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 14c2e9fa828..bf86e0d8b07 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
@@ -1,19 +1,36 @@
<script>
/* eslint-disable vue/no-v-html */
-import { GlButton } from '@gitlab/ui';
+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 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 { __, sprintf } from '~/locale';
export default {
name: 'MRWidgetRebase',
+ apollo: {
+ state: {
+ query: rebaseQuery,
+ skip() {
+ return !this.glFeatures.mergeRequestWidgetGraphql;
+ },
+ variables() {
+ return this.mergeRequestQueryVariables;
+ },
+ update: (data) => data.project.mergeRequest,
+ },
+ },
components: {
statusIcon,
GlButton,
+ GlSkeletonLoader,
},
+ mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
props: {
mr: {
type: Object,
@@ -26,16 +43,41 @@ export default {
},
data() {
return {
+ state: {},
isMakingRequest: false,
rebasingError: null,
};
},
computed: {
+ isLoading() {
+ return this.glFeatures.mergeRequestWidgetGraphql && this.$apollo.queries.state.loading;
+ },
+ rebaseInProgress() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.rebaseInProgress;
+ }
+
+ return this.mr.rebaseInProgress;
+ },
+ canPushToSourceBranch() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.userPermissions.pushToSourceBranch;
+ }
+
+ return this.mr.canPushToSourceBranch;
+ },
+ targetBranch() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.targetBranch;
+ }
+
+ return this.mr.targetBranch;
+ },
status() {
- if (this.mr.rebaseInProgress || this.isMakingRequest) {
+ if (this.rebaseInProgress || this.isMakingRequest) {
return 'loading';
}
- if (!this.mr.canPushToSourceBranch && !this.mr.rebaseInProgress) {
+ if (!this.canPushToSourceBranch && !this.rebaseInProgress) {
return 'warning';
}
return 'success';
@@ -49,7 +91,7 @@ export default {
'Fast-forward merge is not possible. Rebase the source branch onto %{targetBranch} to allow this merge request to be merged.',
),
{
- targetBranch: `<span class="label-branch">${escape(this.mr.targetBranch)}</span>`,
+ targetBranch: `<span class="label-branch">${escape(this.targetBranch)}</span>`,
},
false,
);
@@ -65,7 +107,7 @@ export default {
.then(() => {
simplePoll(this.checkRebaseStatus);
})
- .catch(error => {
+ .catch((error) => {
this.isMakingRequest = false;
if (error.response && error.response.data && error.response.data.merge_error) {
@@ -78,8 +120,8 @@ export default {
checkRebaseStatus(continuePolling, stopPolling) {
this.service
.poll()
- .then(res => res.data)
- .then(res => {
+ .then((res) => res.data)
+ .then((res) => {
if (res.rebase_in_progress) {
continuePolling();
} else {
@@ -105,17 +147,30 @@ export default {
</script>
<template>
<div class="mr-widget-body media">
- <status-icon :status="status" :show-disabled-button="showDisabledButton" />
+ <div v-if="isLoading" class="gl-w-full mr-conflict-loader">
+ <gl-skeleton-loader :width="334" :height="30">
+ <rect x="0" y="3" width="24" height="24" rx="4" />
+ <rect x="32" y="5" width="302" height="20" rx="4" />
+ </gl-skeleton-loader>
+ </div>
+ <template v-else>
+ <status-icon :status="status" :show-disabled-button="showDisabledButton" />
- <div class="rebase-state-find-class-convention media media-body space-children">
- <template v-if="mr.rebaseInProgress || isMakingRequest">
- <span class="bold" data-testid="rebase-message">{{ __('Rebase in progress') }}</span>
- </template>
- <template v-if="!mr.rebaseInProgress && !mr.canPushToSourceBranch">
- <span class="bold" data-testid="rebase-message" v-html="fastForwardMergeText"></span>
- </template>
- <template v-if="!mr.rebaseInProgress && mr.canPushToSourceBranch && !isMakingRequest">
+ <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!"
+ data-testid="rebase-message"
+ >{{ __('Rebase in progress') }}</span
+ >
+ <span
+ v-if="!rebaseInProgress && !canPushToSourceBranch"
+ class="gl-font-weight-bold gl-ml-0!"
+ data-testid="rebase-message"
+ v-html="fastForwardMergeText"
+ ></span>
<div
+ v-if="!rebaseInProgress && canPushToSourceBranch && !isMakingRequest"
class="accept-merge-holder clearfix js-toggle-container accept-action media space-children"
>
<gl-button
@@ -126,14 +181,21 @@ export default {
>
{{ __('Rebase') }}
</gl-button>
- <span v-if="!rebasingError" class="bold" data-testid="rebase-message">{{
- __(
- 'Fast-forward merge is not possible. Rebase the source branch onto the target branch.',
- )
+ <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">{{
+ rebasingError
}}</span>
- <span v-else class="bold danger" data-testid="rebase-message">{{ rebasingError }}</span>
</div>
- </template>
- </div>
+ </div>
+ </template>
</div>
</template>
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 2c1f2285dda..a890b176df0 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
@@ -9,13 +9,18 @@ import {
GlSprintf,
GlLink,
GlTooltipDirective,
+ GlSkeletonLoader,
} from '@gitlab/ui';
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 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 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';
@@ -35,6 +40,31 @@ const MERGE_HOOK_VALIDATION_ERROR_STATUS = 'hook_validation_error';
export default {
name: 'ReadyToMerge',
+ apollo: {
+ state: {
+ query: readyToMergeQuery,
+ skip() {
+ return !this.glFeatures.mergeRequestWidgetGraphql;
+ },
+ variables() {
+ return this.mergeRequestQueryVariables;
+ },
+ manual: true,
+ result({ data }) {
+ this.state = {
+ ...data.project.mergeRequest,
+ mergeRequestsFfOnlyEnabled: data.mergeRequestsFfOnlyEnabled,
+ onlyAllowMergeIfPipelineSucceeds: data.onlyAllowMergeIfPipelineSucceeds,
+ };
+ this.removeSourceBranch = data.project.mergeRequest.shouldRemoveSourceBranch;
+ this.commitMessage = data.project.mergeRequest.defaultMergeCommitMessage;
+ this.squashBeforeMerge = data.project.mergeRequest.squashOnMerge;
+ this.isSquashReadOnly = data.project.squashReadOnly;
+ this.squashCommitMessage = data.project.mergeRequest.defaultSquashCommitMessage;
+ this.loading = false;
+ },
+ },
+ },
components: {
statusIcon,
SquashBeforeMerge,
@@ -48,6 +78,7 @@ export default {
GlButtonGroup,
GlDropdown,
GlDropdownItem,
+ GlSkeletonLoader,
MergeTrainHelperText: () =>
import('ee_component/vue_merge_request_widget/components/merge_train_helper_text.vue'),
MergeImmediatelyConfirmationDialog: () =>
@@ -58,13 +89,15 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
- mixins: [readyToMergeMixin],
+ mixins: [readyToMergeMixin, glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
props: {
mr: { type: Object, required: true },
service: { type: Object, required: true },
},
data() {
return {
+ loading: this.glFeatures.mergeRequestWidgetGraphql,
+ state: {},
removeSourceBranch: this.mr.shouldRemoveSourceBranch,
isMakingRequest: false,
isMergingImmediately: false,
@@ -75,13 +108,93 @@ export default {
};
},
computed: {
+ stateData() {
+ return this.glFeatures.mergeRequestWidgetGraphql ? this.state : this.mr;
+ },
+ hasCI() {
+ return this.stateData.hasCI || this.stateData.hasCi;
+ },
isAutoMergeAvailable() {
- return !isEmpty(this.mr.availableAutoMergeStrategies);
+ return !isEmpty(this.stateData.availableAutoMergeStrategies);
+ },
+ pipeline() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.pipelines?.nodes?.[0];
+ }
+
+ return this.mr.pipeline;
+ },
+ isPipelineFailed() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return ['FAILED', 'CANCELED'].indexOf(this.pipeline?.status) !== -1;
+ }
+
+ return this.mr.isPipelineFailed;
+ },
+ isMergeAllowed() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.mergeable || false;
+ }
+
+ return this.mr.isMergeAllowed;
+ },
+ canRemoveSourceBranch() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.userPermissions.removeSourceBranch;
+ }
+
+ return this.mr.canRemoveSourceBranch;
+ },
+ commits() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.commitsWithoutMergeCommits.nodes;
+ }
+
+ return this.mr.commits;
+ },
+ commitsCount() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.state.commitCount || 0;
+ }
+
+ return this.mr.commitsCount;
+ },
+ preferredAutoMergeStrategy() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return MergeRequestStore.getPreferredAutoMergeStrategy(
+ this.state.availableAutoMergeStrategies,
+ );
+ }
+
+ return this.mr.preferredAutoMergeStrategy;
+ },
+ isSHAMismatch() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.mr.sha !== this.state.diffHeadSha;
+ }
+
+ return this.mr.isSHAMismatch;
+ },
+ squashIsSelected() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.squashReadOnly ? this.state.squashOnMerge : this.state.squash;
+ }
+
+ return this.mr.squashIsSelected;
+ },
+ isPipelineActive() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.pipeline?.active || false;
+ }
+
+ return this.mr.isPipelineActive;
},
status() {
- const { pipeline, isPipelineFailed, hasCI, ciStatus } = this.mr;
+ const ciStatus = this.glFeatures.mergeRequestWidgetGraphql
+ ? this.pipeline?.status.toLowerCase()
+ : this.mr.ciStatus;
- if ((hasCI && !ciStatus) || this.hasPipelineMustSucceedConflict) {
+ if ((this.hasCI && !ciStatus) || this.hasPipelineMustSucceedConflict) {
return PIPELINE_FAILED_STATE;
}
@@ -89,7 +202,7 @@ export default {
return PIPELINE_PENDING_STATE;
}
- if (pipeline && isPipelineFailed) {
+ if (this.pipeline && this.isPipelineFailed) {
return PIPELINE_FAILED_STATE;
}
@@ -114,7 +227,7 @@ export default {
if (
this.status === PIPELINE_FAILED_STATE ||
!this.commitMessage.length ||
- !this.mr.isMergeAllowed ||
+ !this.isMergeAllowed ||
this.mr.preventMerge
) {
return WARNING;
@@ -133,27 +246,31 @@ export default {
return __('Merge');
},
hasPipelineMustSucceedConflict() {
- return !this.mr.hasCI && this.mr.onlyAllowMergeIfPipelineSucceeds;
+ return !this.hasCI && this.stateData.onlyAllowMergeIfPipelineSucceeds;
},
isRemoveSourceBranchButtonDisabled() {
return this.isMergeButtonDisabled;
},
shouldShowSquashBeforeMerge() {
- const { commitsCount, enableSquashBeforeMerge, squashIsReadonly, squashIsSelected } = this.mr;
+ const { enableSquashBeforeMerge } = this.mr;
- if (squashIsReadonly && !squashIsSelected) {
+ if (this.isSquashReadOnly && !this.squashIsSelected) {
return false;
}
- return enableSquashBeforeMerge && commitsCount > 1;
+ return enableSquashBeforeMerge && this.commitsCount > 1;
},
shouldShowMergeControls() {
- return this.mr.isMergeAllowed || this.isAutoMergeAvailable;
+ return this.isMergeAllowed || this.isAutoMergeAvailable;
},
shouldShowSquashEdit() {
return this.squashBeforeMerge && this.shouldShowSquashBeforeMerge;
},
shouldShowMergeEdit() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return !this.state.mergeRequestsFfOnlyEnabled;
+ }
+
return !this.mr.ffOnlyEnabled;
},
shaMismatchLink() {
@@ -162,18 +279,26 @@ export default {
},
methods: {
updateMergeCommitMessage(includeDescription) {
- const { commitMessageWithDescription, commitMessage } = this.mr;
+ const commitMessage = this.glFeatures.mergeRequestWidgetGraphql
+ ? this.state.defaultMergeCommitMessage
+ : this.mr.commitMessage;
+ const commitMessageWithDescription = this.glFeatures.mergeRequestWidgetGraphql
+ ? this.state.defaultMergeCommitMessageWithDescription
+ : this.mr.commitMessageWithDescription;
this.commitMessage = includeDescription ? commitMessageWithDescription : commitMessage;
},
handleMergeButtonClick(useAutoMerge, mergeImmediately = false) {
if (mergeImmediately) {
this.isMergingImmediately = true;
}
+ const latestSha = this.glFeatures.mergeRequestWidgetGraphql
+ ? this.state.diffHeadSha
+ : this.mr.latestSHA;
const options = {
- sha: this.mr.latestSHA || this.mr.sha,
+ sha: latestSha || this.mr.sha,
commit_message: this.commitMessage,
- auto_merge_strategy: useAutoMerge ? this.mr.preferredAutoMergeStrategy : undefined,
+ auto_merge_strategy: useAutoMerge ? this.preferredAutoMergeStrategy : undefined,
should_remove_source_branch: this.removeSourceBranch === true,
squash: this.squashBeforeMerge,
};
@@ -188,8 +313,8 @@ export default {
this.isMakingRequest = true;
this.service
.merge(options)
- .then(res => res.data)
- .then(data => {
+ .then((res) => res.data)
+ .then((data) => {
const hasError =
data.status === MERGE_FAILED_STATUS ||
data.status === MERGE_HOOK_VALIDATION_ERROR_STATUS;
@@ -228,8 +353,8 @@ export default {
handleMergePolling(continuePolling, stopPolling) {
this.service
.poll()
- .then(res => res.data)
- .then(data => {
+ .then((res) => res.data)
+ .then((data) => {
if (data.state === 'merged') {
// If state is merged we should update the widget and stop the polling
eventHub.$emit('MRWidgetUpdateRequested');
@@ -270,8 +395,8 @@ export default {
handleRemoveBranchPolling(continuePolling, stopPolling) {
this.service
.poll()
- .then(res => res.data)
- .then(data => {
+ .then((res) => res.data)
+ .then((data) => {
// If source branch exists then we should continue polling
// because removing a source branch is a background task and takes time
if (data.source_branch_exists) {
@@ -294,156 +419,168 @@ export default {
<template>
<div>
- <div class="mr-widget-body media" :class="{ 'gl-pb-3': shouldRenderMergeTrainHelperText }">
- <status-icon :status="iconClass" />
- <div class="media-body">
- <div class="mr-widget-body-controls media space-children">
- <gl-button-group>
- <gl-button
- size="medium"
- category="primary"
- class="qa-merge-button accept-merge-request"
- :variant="mergeButtonVariant"
- :disabled="isMergeButtonDisabled"
- :loading="isMakingRequest"
- @click="handleMergeButtonClick(isAutoMergeAvailable)"
- >{{ mergeButtonText }}</gl-button
- >
- <gl-dropdown
- v-if="shouldShowMergeImmediatelyDropdown"
- v-gl-tooltip.hover.focus="__('Select merge moment')"
- :disabled="isMergeButtonDisabled"
- variant="info"
- data-qa-selector="merge_moment_dropdown"
- toggle-class="btn-icon js-merge-moment"
- >
- <template #button-content>
- <gl-icon name="chevron-down" class="mr-0" />
- <span class="sr-only">{{ __('Select merge moment') }}</span>
- </template>
- <gl-dropdown-item
- icon-name="warning"
- button-class="accept-merge-request js-merge-immediately-button"
- data-qa-selector="merge_immediately_option"
- @click="handleMergeImmediatelyButtonClick"
+ <div v-if="loading" class="mr-widget-body">
+ <div class="gl-w-full mr-ready-to-merge-loader">
+ <gl-skeleton-loader :width="418" :height="30">
+ <rect x="0" y="3" width="24" height="24" rx="4" />
+ <rect x="32" y="0" width="70" height="30" rx="4" />
+ <rect x="110" y="7" width="150" height="16" rx="4" />
+ <rect x="268" y="7" width="150" height="16" rx="4" />
+ </gl-skeleton-loader>
+ </div>
+ </div>
+ <template v-else>
+ <div class="mr-widget-body media" :class="{ 'gl-pb-3': shouldRenderMergeTrainHelperText }">
+ <status-icon :status="iconClass" />
+ <div class="media-body">
+ <div class="mr-widget-body-controls media space-children">
+ <gl-button-group>
+ <gl-button
+ size="medium"
+ category="primary"
+ class="qa-merge-button accept-merge-request"
+ :variant="mergeButtonVariant"
+ :disabled="isMergeButtonDisabled"
+ :loading="isMakingRequest"
+ @click="handleMergeButtonClick(isAutoMergeAvailable)"
+ >{{ mergeButtonText }}</gl-button
>
- {{ __('Merge immediately') }}
- </gl-dropdown-item>
- <merge-immediately-confirmation-dialog
- ref="confirmationDialog"
- :docs-url="mr.mergeImmediatelyDocsPath"
- @mergeImmediately="onMergeImmediatelyConfirmation"
- />
- </gl-dropdown>
- </gl-button-group>
- <div class="media-body-wrap space-children">
- <template v-if="shouldShowMergeControls">
- <label v-if="mr.canRemoveSourceBranch">
- <input
- id="remove-source-branch-input"
- v-model="removeSourceBranch"
- :disabled="isRemoveSourceBranchButtonDisabled"
- class="js-remove-source-branch-checkbox"
- type="checkbox"
+ <gl-dropdown
+ v-if="shouldShowMergeImmediatelyDropdown"
+ v-gl-tooltip.hover.focus="__('Select merge moment')"
+ :disabled="isMergeButtonDisabled"
+ variant="info"
+ data-qa-selector="merge_moment_dropdown"
+ toggle-class="btn-icon js-merge-moment"
+ >
+ <template #button-content>
+ <gl-icon name="chevron-down" class="mr-0" />
+ <span class="sr-only">{{ __('Select merge moment') }}</span>
+ </template>
+ <gl-dropdown-item
+ icon-name="warning"
+ button-class="accept-merge-request js-merge-immediately-button"
+ data-qa-selector="merge_immediately_option"
+ @click="handleMergeImmediatelyButtonClick"
+ >
+ {{ __('Merge immediately') }}
+ </gl-dropdown-item>
+ <merge-immediately-confirmation-dialog
+ ref="confirmationDialog"
+ :docs-url="mr.mergeImmediatelyDocsPath"
+ @mergeImmediately="onMergeImmediatelyConfirmation"
/>
- {{ __('Delete source branch') }}
- </label>
+ </gl-dropdown>
+ </gl-button-group>
+ <div class="media-body-wrap space-children">
+ <template v-if="shouldShowMergeControls">
+ <label v-if="canRemoveSourceBranch">
+ <input
+ id="remove-source-branch-input"
+ v-model="removeSourceBranch"
+ :disabled="isRemoveSourceBranchButtonDisabled"
+ class="js-remove-source-branch-checkbox"
+ type="checkbox"
+ />
+ {{ __('Delete source branch') }}
+ </label>
- <!-- Placeholder for EE extension of this component -->
- <squash-before-merge
- v-if="shouldShowSquashBeforeMerge"
- v-model="squashBeforeMerge"
- :help-path="mr.squashBeforeMergeHelpPath"
- :is-disabled="isSquashReadOnly"
- />
- </template>
- <template v-else>
- <div class="bold js-resolve-mr-widget-items-message">
- <div
- v-if="hasPipelineMustSucceedConflict"
- class="gl-display-flex gl-align-items-center"
- data-testid="pipeline-succeed-conflict"
- >
- <gl-sprintf :message="pipelineMustSucceedConflictText" />
- <gl-link
- :href="mr.pipelineMustSucceedDocsPath"
- target="_blank"
- class="gl-display-flex gl-ml-2"
+ <!-- Placeholder for EE extension of this component -->
+ <squash-before-merge
+ v-if="shouldShowSquashBeforeMerge"
+ v-model="squashBeforeMerge"
+ :help-path="mr.squashBeforeMergeHelpPath"
+ :is-disabled="isSquashReadOnly"
+ />
+ </template>
+ <template v-else>
+ <div class="bold js-resolve-mr-widget-items-message">
+ <div
+ v-if="hasPipelineMustSucceedConflict"
+ class="gl-display-flex gl-align-items-center"
+ data-testid="pipeline-succeed-conflict"
>
- <gl-icon name="question" />
- </gl-link>
+ <gl-sprintf :message="pipelineMustSucceedConflictText" />
+ <gl-link
+ :href="mr.pipelineMustSucceedDocsPath"
+ target="_blank"
+ class="gl-display-flex gl-ml-2"
+ >
+ <gl-icon name="question" />
+ </gl-link>
+ </div>
+ <gl-sprintf v-else :message="mergeDisabledText" />
</div>
- <gl-sprintf v-else :message="mergeDisabledText" />
- </div>
- </template>
- </div>
- </div>
- <div v-if="mr.isSHAMismatch" class="d-flex align-items-center mt-2 js-sha-mismatch">
- <gl-icon name="warning-solid" class="text-warning mr-1" />
- <span class="text-warning">
- <gl-sprintf
- :message="
- __('New changes were added. %{linkStart}Reload the page to review them%{linkEnd}')
- "
- >
- <template #link="{ content }">
- <gl-link :href="mr.mergeRequestDiffsPath">{{ content }}</gl-link>
</template>
- </gl-sprintf>
- </span>
+ </div>
+ </div>
+ <div v-if="isSHAMismatch" class="d-flex align-items-center mt-2 js-sha-mismatch">
+ <gl-icon name="warning-solid" class="text-warning mr-1" />
+ <span class="text-warning">
+ <gl-sprintf
+ :message="
+ __('New changes were added. %{linkStart}Reload the page to review them%{linkEnd}')
+ "
+ >
+ <template #link="{ content }">
+ <gl-link :href="mr.mergeRequestDiffsPath">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
+ </div>
</div>
</div>
- </div>
- <merge-train-helper-text
- v-if="shouldRenderMergeTrainHelperText"
- :pipeline-id="mr.pipeline.id"
- :pipeline-link="mr.pipeline.path"
- :merge-train-length="mr.mergeTrainsCount"
- :merge-train-when-pipeline-succeeds-docs-path="mr.mergeTrainWhenPipelineSucceedsDocsPath"
- />
- <template v-if="shouldShowMergeControls">
- <div v-if="mr.ffOnlyEnabled" class="mr-fast-forward-message">
- {{ __('Fast-forward merge without a merge commit') }}
- </div>
- <commits-header
- v-if="shouldShowSquashEdit || shouldShowMergeEdit"
- :is-squash-enabled="squashBeforeMerge"
- :commits-count="mr.commitsCount"
- :target-branch="mr.targetBranch"
- :is-fast-forward-enabled="mr.ffOnlyEnabled"
- :class="{ 'border-bottom': mr.mergeError }"
- >
- <ul class="border-top content-list commits-list flex-list">
- <commit-edit
- v-if="shouldShowSquashEdit"
- v-model="squashCommitMessage"
- :label="__('Squash commit message')"
- input-id="squash-message-edit"
- squash
- >
- <commit-message-dropdown
- slot="header"
+ <merge-train-helper-text
+ v-if="shouldRenderMergeTrainHelperText"
+ :pipeline-id="pipeline.id"
+ :pipeline-link="pipeline.path"
+ :merge-train-length="stateData.mergeTrainsCount"
+ :merge-train-when-pipeline-succeeds-docs-path="mr.mergeTrainWhenPipelineSucceedsDocsPath"
+ />
+ <template v-if="shouldShowMergeControls">
+ <div v-if="!shouldShowMergeEdit" class="mr-fast-forward-message">
+ {{ __('Fast-forward merge without a merge commit') }}
+ </div>
+ <commits-header
+ v-if="shouldShowSquashEdit || shouldShowMergeEdit"
+ :is-squash-enabled="squashBeforeMerge"
+ :commits-count="commitsCount"
+ :target-branch="stateData.targetBranch"
+ :is-fast-forward-enabled="!shouldShowMergeEdit"
+ :class="{ 'border-bottom': stateData.mergeError }"
+ >
+ <ul class="border-top content-list commits-list flex-list">
+ <commit-edit
+ v-if="shouldShowSquashEdit"
v-model="squashCommitMessage"
- :commits="mr.commits"
- />
- </commit-edit>
- <commit-edit
- v-if="shouldShowMergeEdit"
- v-model="commitMessage"
- :label="__('Merge commit message')"
- input-id="merge-message-edit"
- >
- <label slot="checkbox">
- <input
- id="include-description"
- type="checkbox"
- @change="updateMergeCommitMessage($event.target.checked)"
+ :label="__('Squash commit message')"
+ input-id="squash-message-edit"
+ squash
+ >
+ <commit-message-dropdown
+ slot="header"
+ v-model="squashCommitMessage"
+ :commits="commits"
/>
- {{ __('Include merge request description') }}
- </label>
- </commit-edit>
- </ul>
- </commits-header>
+ </commit-edit>
+ <commit-edit
+ v-if="shouldShowMergeEdit"
+ v-model="commitMessage"
+ :label="__('Merge commit message')"
+ input-id="merge-message-edit"
+ >
+ <label slot="checkbox">
+ <input
+ id="include-description"
+ type="checkbox"
+ @change="updateMergeCommitMessage($event.target.checked)"
+ />
+ {{ __('Include merge request description') }}
+ </label>
+ </commit-edit>
+ </ul>
+ </commits-header>
+ </template>
</template>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
index 1c9909e7178..12fdfe601a4 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
@@ -46,7 +46,7 @@ export default {
name="squash"
class="qa-squash-checkbox js-squash-checkbox gl-mb-0 gl-mr-2"
:title="tooltipTitle"
- @change="checked => $emit('input', checked)"
+ @change="(checked) => $emit('input', checked)"
>
{{ $options.i18n.checkboxLabel }}
</gl-form-checkbox>
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 1d591168a17..3f1db815f95 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
@@ -29,7 +29,7 @@ export default {
variables() {
return this.mergeRequestQueryVariables;
},
- update: data => data.project.mergeRequest.userPermissions,
+ update: (data) => data.project.mergeRequest.userPermissions,
},
},
props: {
@@ -86,7 +86,7 @@ export default {
variables: mergeRequestQueryVariables,
});
- const data = produce(sourceData, draftState => {
+ const data = produce(sourceData, (draftState) => {
// eslint-disable-next-line no-param-reassign
draftState.project.mergeRequest.workInProgress = workInProgress;
// eslint-disable-next-line no-param-reassign
@@ -113,10 +113,18 @@ export default {
},
},
})
- .then(({ data: { mergeRequestSetWip: { mergeRequest: { title } } } }) => {
- createFlash(__('The merge request can now be merged.'), 'notice');
- $('.merge-request .detail-page-description .title').text(title);
- })
+ .then(
+ ({
+ data: {
+ mergeRequestSetWip: {
+ mergeRequest: { title },
+ },
+ },
+ }) => {
+ createFlash(__('The merge request can now be merged.'), 'notice');
+ $('.merge-request .detail-page-description .title').text(title);
+ },
+ )
.catch(() => createFlash(__('Something went wrong. Please try again.')))
.finally(() => {
this.isMakingRequest = false;
@@ -129,8 +137,8 @@ export default {
this.isMakingRequest = true;
this.service
.removeWIP()
- .then(res => res.data)
- .then(data => {
+ .then((res) => res.data)
+ .then((data) => {
eventHub.$emit('UpdateWidgetData', data);
MergeRequest.toggleDraftStatus(this.mr.title, true);
})
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 4de41dd5887..180db7828a8 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
@@ -40,7 +40,7 @@ export default {
);
},
numberOfInvalidPlans() {
- return Object.values(this.plansObject).filter(plan => plan.tf_report_error).length;
+ return Object.values(this.plansObject).filter((plan) => plan.tf_report_error).length;
},
numberOfPlans() {
return Object.keys(this.plansObject).length;
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js b/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
index 2d21ced1b28..6c6f5e7fc73 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
@@ -38,7 +38,7 @@ export default {
.query({ query: issuesQuery, variables: { projectPath: targetProjectFullPath } })
.then(({ data }) => {
// Return some transformed data to be rendered in the expanded state
- return data.project.issues.nodes.map(issue => ({
+ return data.project.issues.nodes.map((issue) => ({
id: issue.id, // Required: The ID of the object
text: issue.title, // Required: The text to get used on each row
// Icon to get rendered on the side of each row
diff --git a/app/assets/javascripts/vue_merge_request_widget/index.js b/app/assets/javascripts/vue_merge_request_widget/index.js
index 8f2cca3309a..d512877a20d 100644
--- a/app/assets/javascripts/vue_merge_request_widget/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/index.js
@@ -26,7 +26,11 @@ export default () => {
registerExtension(issueExtension);
- const vm = new Vue({ ...MrWidgetOptions, apolloProvider });
+ const vm = new Vue({
+ el: '#js-vue-mr-widget',
+ ...MrWidgetOptions,
+ apolloProvider,
+ });
window.gl.mrWidget = {
checkStatus: vm.checkStatus,
diff --git a/app/assets/javascripts/vue_merge_request_widget/mixins/approvals.js b/app/assets/javascripts/vue_merge_request_widget/mixins/approvals.js
index e50555ca875..943011949fd 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mixins/approvals.js
+++ b/app/assets/javascripts/vue_merge_request_widget/mixins/approvals.js
@@ -11,7 +11,7 @@ export default {
}
},
refreshApprovals() {
- return this.service.fetchApprovals().then(data => {
+ return this.service.fetchApprovals().then((data) => {
this.mr.setApprovals(data);
});
},
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 dc8a6b56d58..fe512d68ea2 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
@@ -27,7 +27,7 @@ export default {
return __('Merge when pipeline succeeds');
},
shouldShowMergeImmediatelyDropdown() {
- return this.mr.isPipelineActive && !this.mr.onlyAllowMergeIfPipelineSucceeds;
+ return this.isPipelineActive && !this.stateData.onlyAllowMergeIfPipelineSucceeds;
},
isMergeImmediatelyDangerous() {
return false;
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 3f1f2144d8e..519576d9fe6 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
@@ -43,12 +43,11 @@ import SourceBranchRemovalStatus from './components/source_branch_removal_status
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/common_utils';
+import { setFaviconOverlay } from '../lib/utils/favicon';
import GroupedAccessibilityReportsApp from '../reports/accessibility_report/grouped_accessibility_reports_app.vue';
import getStateQuery from './queries/get_state.query.graphql';
export default {
- el: '#js-vue-mr-widget',
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
// eslint-disable-next-line @gitlab/require-i18n-strings
name: 'MRWidget',
@@ -166,7 +165,8 @@ export default {
return (
!this.mr.canRemoveSourceBranch &&
this.mr.shouldRemoveSourceBranch &&
- (!this.mr.isNothingToMergeState && !this.mr.isMergedState)
+ !this.mr.isNothingToMergeState &&
+ !this.mr.isMergedState
);
},
shouldRenderCollaborationStatus() {
@@ -190,9 +190,13 @@ export default {
mergeError = mergeError.slice(0, -1);
}
- return sprintf(s__('mrWidget|Merge failed: %{mergeError}. Please try again.'), {
- mergeError,
- });
+ return sprintf(
+ s__('mrWidget|Merge failed: %{mergeError}. Please try again.'),
+ {
+ mergeError,
+ },
+ false,
+ );
},
shouldShowAccessibilityReport() {
return this.mr.accessibilityReportPath;
@@ -306,8 +310,7 @@ export default {
callback: this.checkStatus,
startingInterval: this.startingPollInterval,
maxInterval: this.startingPollInterval + secondsToMilliseconds(4 * 60),
- hiddenInterval:
- window.gon?.features?.widgetVisibilityPolling && secondsToMilliseconds(6 * 60),
+ hiddenInterval: secondsToMilliseconds(6 * 60),
incrementByFactorOf: 2,
});
},
@@ -357,7 +360,7 @@ export default {
fetchActionsContent() {
this.service
.fetchMergeActionsContent()
- .then(res => {
+ .then((res) => {
if (res.data) {
const el = document.createElement('div');
el.innerHTML = res.data;
@@ -387,26 +390,26 @@ export default {
this.pollingInterval.stopTimer();
},
bindEventHubListeners() {
- eventHub.$on('MRWidgetUpdateRequested', cb => {
+ eventHub.$on('MRWidgetUpdateRequested', (cb) => {
this.checkStatus(cb);
});
- eventHub.$on('MRWidgetRebaseSuccess', cb => {
+ eventHub.$on('MRWidgetRebaseSuccess', (cb) => {
this.checkStatus(cb, true);
});
// `params` should be an Array contains a Boolean, like `[true]`
// Passing parameter as Boolean didn't work.
- eventHub.$on('SetBranchRemoveFlag', params => {
+ eventHub.$on('SetBranchRemoveFlag', (params) => {
[this.mr.isRemovingSourceBranch] = params;
});
- eventHub.$on('FailedToMerge', mergeError => {
+ eventHub.$on('FailedToMerge', (mergeError) => {
this.mr.state = 'failedToMerge';
this.mr.mergeError = mergeError;
});
- eventHub.$on('UpdateWidgetData', data => {
+ eventHub.$on('UpdateWidgetData', (data) => {
this.mr.setData(data);
});
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
new file mode 100644
index 00000000000..64cd70fcf42
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.fragment.graphql
@@ -0,0 +1,15 @@
+fragment autoMergeEnabled on MergeRequest {
+ autoMergeStrategy
+ mergeUser {
+ name
+ username
+ webUrl
+ avatarUrl
+ }
+ targetBranch
+ shouldRemoveSourceBranch
+ forceRemoveSourceBranch
+ userPermissions {
+ removeSourceBranch
+ }
+}
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
new file mode 100644
index 00000000000..bdcb7a8206b
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql
@@ -0,0 +1,10 @@
+#import "./auto_merge_enabled.fragment.graphql"
+
+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/auto_merge_failed.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_failed.query.graphql
new file mode 100644
index 00000000000..2fe0d174b67
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_failed.query.graphql
@@ -0,0 +1,7 @@
+query autoMergeFailedQuery($projectPath: ID!, $iid: String!) {
+ project(fullPath: $projectPath) {
+ mergeRequest(iid: $iid) {
+ mergeError
+ }
+ }
+}
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
new file mode 100644
index 00000000000..9479ef3cf79
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql
@@ -0,0 +1,41 @@
+fragment ReadyToMerge on Project {
+ onlyAllowMergeIfPipelineSucceeds
+ mergeRequestsFfOnlyEnabled
+ squashReadOnly
+ mergeRequest(iid: $iid) {
+ autoMergeEnabled
+ shouldRemoveSourceBranch
+ defaultMergeCommitMessage
+ defaultMergeCommitMessageWithDescription
+ defaultSquashCommitMessage
+ squash
+ squashOnMerge
+ availableAutoMergeStrategies
+ hasCi
+ mergeable
+ mergeWhenPipelineSucceeds
+ commitCount
+ diffHeadSha
+ userPermissions {
+ removeSourceBranch
+ }
+ targetBranch
+ mergeError
+ commitsWithoutMergeCommits {
+ nodes {
+ sha
+ shortId
+ title
+ message
+ }
+ }
+ pipelines(first: 1) {
+ nodes {
+ id
+ status
+ path
+ active
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql
new file mode 100644
index 00000000000..78259e1f553
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql
@@ -0,0 +1,7 @@
+#import "./ready_to_merge.fragment.graphql"
+
+query readyToMergeQuery($projectPath: ID!, $iid: String!) {
+ project(fullPath: $projectPath) {
+ ...ReadyToMerge
+ }
+}
diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/rebase.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/rebase.query.graphql
new file mode 100644
index 00000000000..a8c7d2610bf
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/rebase.query.graphql
@@ -0,0 +1,11 @@
+query rebaseQuery($projectPath: ID!, $iid: String!) {
+ project(fullPath: $projectPath) {
+ mergeRequest(iid: $iid) {
+ rebaseInProgress
+ targetBranch
+ userPermissions {
+ pushToSourceBranch
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js b/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
index 2ad15f231bb..7dcb4881e7f 100644
--- a/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
+++ b/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
@@ -60,15 +60,15 @@ export default class MRWidgetService {
}
fetchApprovals() {
- return axios.get(this.apiApprovalsPath).then(res => res.data);
+ return axios.get(this.apiApprovalsPath).then((res) => res.data);
}
approveMergeRequest() {
- return axios.post(this.apiApprovePath).then(res => res.data);
+ return axios.post(this.apiApprovePath).then((res) => res.data);
}
unapproveMergeRequest() {
- return axios.post(this.apiUnapprovePath).then(res => res.data);
+ return axios.post(this.apiUnapprovePath).then((res) => res.data);
}
static executeInlineAction(url) {
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/getters.js b/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/getters.js
index 15d67ea18ea..7740147c8e4 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/getters.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/artifacts_list/getters.js
@@ -1,6 +1,6 @@
import { s__, n__ } from '~/locale';
-export const title = state => {
+export const title = (state) => {
if (state.isLoading) {
return s__('BuildArtifacts|Loading artifacts');
}
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 f8abbc99f0f..e6cb5ead089 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
@@ -7,10 +7,11 @@ import state from './state';
Vue.use(Vuex);
-export default () =>
- new Vuex.Store({
- actions,
- mutations,
- getters,
- state: state(),
- });
+export const getStoreConfig = () => ({
+ actions,
+ mutations,
+ getters,
+ state: state(),
+});
+
+export default () => new Vuex.Store(getStoreConfig());
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 f50b6caf0f5..a6bbab47a06 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,5 +1,6 @@
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';
@@ -154,6 +155,10 @@ export default class MergeRequestStore {
this.canRevertInCurrentMR = currentUser.can_revert_on_current_merge_request || false;
this.setState();
+
+ mrEventHub.$emit('mr.state.updated', {
+ state: this.mergeRequestState,
+ });
}
setGraphqlData(project) {
@@ -167,7 +172,7 @@ export default class MergeRequestStore {
this.canBeMerged = mergeRequest.mergeStatus === 'can_be_merged';
this.canMerge = mergeRequest.userPermissions.canMerge;
this.ciStatus = pipeline?.status.toLowerCase();
- this.commitsCount = mergeRequest.commitCount;
+ this.commitsCount = mergeRequest.commitCount || 10;
this.branchMissing = !mergeRequest.sourceBranchExists || !mergeRequest.targetBranchExists;
this.hasConflicts = mergeRequest.conflicts;
this.hasMergeableDiscussionsState = mergeRequest.mergeableDiscussionsState === false;