Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /app/assets/javascripts/vue_merge_request_widget/components/states
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget/components/states')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue14
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue73
-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/unresolved_discussions.vue37
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue156
8 files changed, 211 insertions, 77 deletions
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..f17e409d996 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
@@ -1,10 +1,10 @@
<script>
-import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { GlDeprecatedDropdown, GlDeprecatedDropdownItem } from '@gitlab/ui';
export default {
components: {
- GlDropdown,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownItem,
},
props: {
commits: {
@@ -18,20 +18,20 @@ export default {
<template>
<div>
- <gl-dropdown
+ <gl-deprecated-dropdown
right
text="Use an existing commit message"
variant="link"
class="mr-commit-dropdown"
>
- <gl-dropdown-item
+ <gl-deprecated-dropdown-item
v-for="commit in commits"
:key="commit.short_id"
class="text-nowrap text-truncate"
@click="$emit('input', commit.message)"
>
<span class="monospace mr-2">{{ commit.short_id }}</span> {{ commit.title }}
- </gl-dropdown-item>
- </gl-dropdown>
+ </gl-deprecated-dropdown-item>
+ </gl-deprecated-dropdown>
</div>
</template>
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 f02e0ac84da..12f65a4c235 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,6 +1,6 @@
<script>
import autoMergeMixin from 'ee_else_ce/vue_merge_request_widget/mixins/auto_merge';
-import Flash from '../../../flash';
+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';
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 1a6e186a371..166700dbcbf 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
@@ -1,7 +1,7 @@
<script>
/* eslint-disable @gitlab/vue-require-i18n-strings */
import { GlLoadingIcon } from '@gitlab/ui';
-import Flash from '~/flash';
+import { deprecatedCreateFlash as Flash } from '~/flash';
import tooltip from '~/vue_shared/directives/tooltip';
import { s__, __ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
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 c3cc30a1a6f..794c994bffe 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,7 +4,7 @@ import { escape } from 'lodash';
import simplePoll from '../../../lib/utils/simple_poll';
import eventHub from '../../event_hub';
import statusIcon from '../mr_widget_status_icon.vue';
-import Flash from '../../../flash';
+import { deprecatedCreateFlash as Flash } from '../../../flash';
import { __, sprintf } from '~/locale';
export default {
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 cc43135f50a..930a2b68d8e 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
@@ -8,14 +8,23 @@ import simplePoll from '~/lib/utils/simple_poll';
import { __, sprintf } from '~/locale';
import MergeRequest from '../../../merge_request';
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
-import Flash from '../../../flash';
+import { deprecatedCreateFlash as Flash } from '../../../flash';
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 } from '../../constants';
+import { AUTO_MERGE_STRATEGIES, DANGER, INFO, WARNING } from '../../constants';
+
+const PIPELINE_RUNNING_STATE = 'running';
+const PIPELINE_FAILED_STATE = 'failed';
+const PIPELINE_PENDING_STATE = 'pending';
+const PIPELINE_SUCCESS_STATE = 'success';
+
+const MERGE_FAILED_STATUS = 'failed';
+const MERGE_SUCCESS_STATUS = 'success';
+const MERGE_HOOK_VALIDATION_ERROR_STATUS = 'hook_validation_error';
export default {
name: 'ReadyToMerge',
@@ -29,6 +38,8 @@ export default {
GlSprintf,
GlLink,
GlDeprecatedButton,
+ MergeTrainHelperText: () =>
+ import('ee_component/vue_merge_request_widget/components/merge_train_helper_text.vue'),
MergeImmediatelyConfirmationDialog: () =>
import(
'ee_component/vue_merge_request_widget/components/merge_immediately_confirmation_dialog.vue'
@@ -60,35 +71,45 @@ export default {
const { pipeline, isPipelineFailed, hasCI, ciStatus } = this.mr;
if ((hasCI && !ciStatus) || this.hasPipelineMustSucceedConflict) {
- return 'failed';
- } else if (this.isAutoMergeAvailable) {
- return 'pending';
- } else if (!pipeline) {
- return 'success';
- } else if (isPipelineFailed) {
- return 'failed';
+ return PIPELINE_FAILED_STATE;
+ }
+
+ if (this.isAutoMergeAvailable) {
+ return PIPELINE_PENDING_STATE;
+ }
+
+ if (pipeline && isPipelineFailed) {
+ return PIPELINE_FAILED_STATE;
}
- return 'success';
+ return PIPELINE_SUCCESS_STATE;
},
mergeButtonVariant() {
- if (this.status === 'failed') {
- return 'danger';
- } else if (this.status === 'pending') {
- return 'info';
+ if (this.status === PIPELINE_FAILED_STATE) {
+ return DANGER;
}
- return 'success';
+
+ if (this.status === PIPELINE_PENDING_STATE) {
+ return INFO;
+ }
+
+ return PIPELINE_SUCCESS_STATE;
},
iconClass() {
+ if (this.shouldRenderMergeTrainHelperText && !this.mr.preventMerge) {
+ return PIPELINE_RUNNING_STATE;
+ }
+
if (
- this.status === 'failed' ||
+ this.status === PIPELINE_FAILED_STATE ||
!this.commitMessage.length ||
!this.mr.isMergeAllowed ||
this.mr.preventMerge
) {
- return 'warning';
+ return WARNING;
}
- return 'success';
+
+ return PIPELINE_SUCCESS_STATE;
},
mergeButtonText() {
if (this.isMergingImmediately) {
@@ -167,11 +188,13 @@ export default {
.merge(options)
.then(res => res.data)
.then(data => {
- const hasError = data.status === 'failed' || data.status === 'hook_validation_error';
+ const hasError =
+ data.status === MERGE_FAILED_STATUS ||
+ data.status === MERGE_HOOK_VALIDATION_ERROR_STATUS;
if (AUTO_MERGE_STRATEGIES.includes(data.status)) {
eventHub.$emit('MRWidgetUpdateRequested');
- } else if (data.status === 'success') {
+ } else if (data.status === MERGE_SUCCESS_STATUS) {
this.initiateMergePolling();
} else if (hasError) {
eventHub.$emit('FailedToMerge', data.merge_error);
@@ -269,7 +292,7 @@ export default {
<template>
<div>
- <div class="mr-widget-body media">
+ <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">
@@ -358,6 +381,7 @@ export default {
<div
v-if="hasPipelineMustSucceedConflict"
class="gl-display-flex gl-align-items-center"
+ data-testid="pipeline-succeed-conflict"
>
<gl-sprintf :message="pipelineMustSucceedConflictText" />
<gl-link
@@ -379,6 +403,13 @@ export default {
</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') }}
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 efd58341a2d..3cf7dc3c4d1 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
@@ -38,7 +38,7 @@ export default {
<div class="inline">
<label
v-tooltip
- :class="{ 'gl-text-gray-600': isDisabled }"
+ :class="{ 'gl-text-gray-400': isDisabled }"
data-testid="squashLabel"
:data-title="tooltipTitle"
>
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 d4a5fdb4b97..78e69b9ff9b 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,10 +1,13 @@
<script>
+import { GlButton } from '@gitlab/ui';
import statusIcon from '../mr_widget_status_icon.vue';
+import notesEventHub from '~/notes/event_hub';
export default {
name: 'UnresolvedDiscussions',
components: {
statusIcon,
+ GlButton,
},
props: {
mr: {
@@ -12,23 +15,39 @@ export default {
required: true,
},
},
+ methods: {
+ jumpToFirstUnresolvedDiscussion() {
+ notesEventHub.$emit('jumpToFirstUnresolvedDiscussion');
+ },
+ },
};
</script>
<template>
- <div class="mr-widget-body media">
+ <div class="mr-widget-body media gl-flex-wrap">
<status-icon :show-disabled-button="true" status="warning" />
- <div class="media-body space-children">
- <span class="bold">
- {{ s__('mrWidget|There are unresolved threads. Please resolve these threads') }}
- </span>
- <a
+ <div class="media-body">
+ <span class="gl-ml-3 gl-font-weight-bold gl-display-block gl-w-100">{{
+ s__('mrWidget|Before this can be merged, one or more threads must be resolved.')
+ }}</span>
+ <gl-button
+ data-testid="jump-to-first"
+ class="gl-ml-3"
+ size="small"
+ icon="comment-next"
+ @click="jumpToFirstUnresolvedDiscussion"
+ >
+ {{ s__('mrWidget|Jump to first unresolved thread') }}
+ </gl-button>
+ <gl-button
v-if="mr.createIssueToResolveDiscussionsPath"
:href="mr.createIssueToResolveDiscussionsPath"
- class="btn btn-default btn-sm js-create-issue"
+ class="js-create-issue gl-ml-3"
+ size="small"
+ icon="issue-new"
>
- {{ s__('mrWidget|Create an issue to resolve them later') }}
- </a>
+ {{ s__('mrWidget|Resolve all threads in new issue') }}
+ </gl-button>
</div>
</div>
</template>
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 118caac84b9..44668170fe4 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,8 +1,13 @@
<script>
import $ from 'jquery';
-import { GlDeprecatedButton } from '@gitlab/ui';
-import { __, s__ } from '~/locale';
-import createFlash from '~/flash';
+import { GlButton } from '@gitlab/ui';
+import { __ } from '~/locale';
+import { deprecatedCreateFlash as createFlash } from '~/flash';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+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 tooltip from '../../../vue_shared/directives/tooltip';
import eventHub from '../../event_hub';
@@ -11,72 +16,151 @@ export default {
name: 'WorkInProgress',
components: {
StatusIcon,
- GlDeprecatedButton,
+ GlButton,
},
directives: {
tooltip,
},
+ mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
+ apollo: {
+ userPermissions: {
+ query: workInProgressQuery,
+ skip() {
+ return !this.glFeatures.mergeRequestWidgetGraphql;
+ },
+ variables() {
+ return this.mergeRequestQueryVariables;
+ },
+ update: data => data.project.mergeRequest.userPermissions,
+ },
+ },
props: {
mr: { type: Object, required: true },
service: { type: Object, required: true },
},
data() {
return {
+ userPermissions: {},
isMakingRequest: false,
};
},
computed: {
- wipInfoTooltip() {
- return s__(
- 'mrWidget|When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged',
- );
+ canUpdate() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ return this.userPermissions.updateMergeRequest;
+ }
+
+ return Boolean(this.mr.removeWIPPath);
},
},
methods: {
- handleRemoveWIP() {
+ removeWipMutation() {
this.isMakingRequest = true;
- this.service
- .removeWIP()
- .then(res => res.data)
- .then(data => {
- eventHub.$emit('UpdateWidgetData', data);
+
+ this.$apollo
+ .mutate({
+ mutation: removeWipMutation,
+ variables: {
+ ...this.mergeRequestQueryVariables,
+ wip: false,
+ },
+ update(
+ store,
+ {
+ data: {
+ mergeRequestSetWip: {
+ errors,
+ mergeRequest: { workInProgress, title },
+ },
+ },
+ },
+ ) {
+ if (errors?.length) {
+ createFlash(__('Something went wrong. Please try again.'));
+
+ return;
+ }
+
+ const data = store.readQuery({
+ query: getStateQuery,
+ variables: this.mergeRequestQueryVariables,
+ });
+ data.project.mergeRequest.workInProgress = workInProgress;
+ data.project.mergeRequest.title = title;
+ store.writeQuery({
+ query: getStateQuery,
+ data,
+ variables: this.mergeRequestQueryVariables,
+ });
+ },
+ optimisticResponse: {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ __typename: 'Mutation',
+ mergeRequestSetWip: {
+ __typename: 'MergeRequestSetWipPayload',
+ errors: [],
+ mergeRequest: {
+ __typename: 'MergeRequest',
+ title: this.mr.title,
+ workInProgress: false,
+ },
+ },
+ },
+ })
+ .then(({ data: { mergeRequestSetWip: { mergeRequest: { title } } } }) => {
createFlash(__('The merge request can now be merged.'), 'notice');
- $('.merge-request .detail-page-description .title').text(this.mr.title);
+ $('.merge-request .detail-page-description .title').text(title);
})
- .catch(() => {
+ .catch(() => createFlash(__('Something went wrong. Please try again.')))
+ .finally(() => {
this.isMakingRequest = false;
- createFlash(__('Something went wrong. Please try again.'));
});
},
+ handleRemoveWIP() {
+ if (this.glFeatures.mergeRequestWidgetGraphql) {
+ this.removeWipMutation();
+ } else {
+ this.isMakingRequest = true;
+ this.service
+ .removeWIP()
+ .then(res => res.data)
+ .then(data => {
+ eventHub.$emit('UpdateWidgetData', data);
+ createFlash(__('The merge request can now be merged.'), 'notice');
+ $('.merge-request .detail-page-description .title').text(this.mr.title);
+ })
+ .catch(() => {
+ this.isMakingRequest = false;
+ createFlash(__('Something went wrong. Please try again.'));
+ });
+ }
+ },
},
};
</script>
<template>
<div class="mr-widget-body media">
- <status-icon :show-disabled-button="Boolean(mr.removeWIPPath)" status="warning" />
- <div class="media-body space-children">
- <span class="bold">
- {{ __('This is a Work in Progress') }}
- <i
- v-tooltip
- class="fa fa-question-circle"
- :title="wipInfoTooltip"
- :aria-label="wipInfoTooltip"
- >
- </i>
- </span>
- <gl-deprecated-button
- v-if="mr.removeWIPPath"
- size="sm"
- variant="default"
+ <status-icon :show-disabled-button="canUpdate" status="warning" />
+ <div class="media-body">
+ <div class="gl-ml-3 float-left">
+ <span class="gl-font-weight-bold">
+ {{ __('This merge request is still a work in progress.') }}
+ </span>
+ <span class="gl-display-block text-muted">{{
+ __("Draft merge requests can't be merged.")
+ }}</span>
+ </div>
+ <gl-button
+ v-if="canUpdate"
+ size="small"
:disabled="isMakingRequest"
:loading="isMakingRequest"
- class="js-remove-wip"
+ class="js-remove-wip gl-ml-3"
@click="handleRemoveWIP"
>
- {{ s__('mrWidget|Resolve WIP status') }}
- </gl-deprecated-button>
+ {{ s__('mrWidget|Mark as ready') }}
+ </gl-button>
</div>
</div>
</template>