diff options
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget/components/states')
19 files changed, 392 insertions, 651 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_edit.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_edit.vue index 18761d04c2e..515a7cf51a1 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_edit.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_edit.vue @@ -1,8 +1,5 @@ <script> -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; - export default { - mixins: [glFeatureFlagMixin()], props: { value: { type: String, @@ -23,10 +20,7 @@ export default { <template> <li> <div class="commit-message-editor"> - <div - :class="{ 'gl-mb-3': glFeatures.restructuredMrWidget }" - class="d-flex flex-wrap align-items-center justify-content-between" - > + <div class="d-flex flex-wrap align-items-center justify-content-between gl-mb-3"> <label class="col-form-label" :for="inputId"> <strong>{{ label }}</strong> </label> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue index 071920856a8..f74826f95d3 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.vue @@ -1,5 +1,4 @@ <script> -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import statusIcon from '../mr_widget_status_icon.vue'; export default { @@ -7,7 +6,6 @@ export default { components: { statusIcon, }, - mixins: [glFeatureFlagMixin()], }; </script> <template> @@ -16,7 +14,7 @@ export default { <status-icon status="warning" show-disabled-button /> </div> <div class="media-body"> - <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold"> + <span class="gl-ml-0! gl-text-body! bold"> {{ s__('mrWidget|Merge unavailable: merge requests are read-only on archived projects.') }} </span> </div> 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 aabbeac564a..690acc9a6dc 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,15 +1,15 @@ <script> -import { GlSkeletonLoader, GlIcon, GlButton, GlSprintf } from '@gitlab/ui'; +import { GlSkeletonLoader, GlIcon, GlSprintf } 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 createFlash from '~/flash'; -import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { __ } from '~/locale'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { AUTO_MERGE_STRATEGIES } from '../../constants'; import eventHub from '../../event_hub'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; import MrWidgetAuthor from '../mr_widget_author.vue'; +import StateContainer from '../state_container.vue'; export default { name: 'MRWidgetAutoMergeEnabled', @@ -29,8 +29,8 @@ export default { MrWidgetAuthor, GlSkeletonLoader, GlIcon, - GlButton, GlSprintf, + StateContainer, }, mixins: [autoMergeMixin, glFeatureFlagMixin(), mergeRequestQueryVariablesMixin], props: { @@ -78,18 +78,25 @@ export default { autoMergeStrategy() { return (this.glFeatures.mergeRequestWidgetGraphql ? this.state : this.mr).autoMergeStrategy; }, - canRemoveSourceBranch() { - const { currentUserId } = this.mr; - const mergeUserId = this.glFeatures.mergeRequestWidgetGraphql - ? getIdFromGraphQLId(this.state.mergeUser?.id) - : this.mr.mergeUserId; - const canRemoveSourceBranch = this.glFeatures.mergeRequestWidgetGraphql - ? this.state.userPermissions.removeSourceBranch - : this.mr.canRemoveSourceBranch; + actions() { + const actions = []; - return ( - !this.shouldRemoveSourceBranch && canRemoveSourceBranch && mergeUserId === currentUserId - ); + if (this.loading) { + return actions; + } + + if (this.mr.canCancelAutomaticMerge) { + actions.push({ + text: this.cancelButtonText, + loading: this.isCancellingAutoMerge, + dataQaSelector: 'cancel_auto_merge_button', + class: 'js-cancel-auto-merge', + testId: 'cancelAutomaticMergeButton', + onClick: () => this.cancelAutomaticMerge(), + }); + } + + return actions; }, }, methods: { @@ -144,56 +151,25 @@ export default { }; </script> <template> - <div class="mr-widget-body media"> - <div v-if="loading" class="gl-w-full mr-conflict-loader"> + <state-container status="scheduled" :is-loading="loading" :actions="actions"> + <template #loading> <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> + </template> + <template v-if="!loading"> + <h4 class="gl-mr-3" data-testid="statusText"> + <gl-sprintf :message="statusText" data-testid="statusText"> + <template #merge_author> + <mr-widget-author :author="mergeUser" /> + </template> + </gl-sprintf> + </h4> + </template> + <template v-if="!loading" #icon> <gl-icon name="status_scheduled" :size="24" class="gl-text-blue-500 gl-mr-3 gl-mt-1" /> - <div class="media-body"> - <h4 class="gl-display-flex"> - <span class="gl-mr-3"> - <gl-sprintf :message="statusText" data-testid="statusText"> - <template #merge_author> - <mr-widget-author :author="mergeUser" /> - </template> - </gl-sprintf> - </span> - <gl-button - v-if="mr.canCancelAutomaticMerge" - :loading="isCancellingAutoMerge" - size="small" - class="js-cancel-auto-merge" - data-qa-selector="cancel_auto_merge_button" - data-testid="cancelAutomaticMergeButton" - @click="cancelAutomaticMerge" - > - {{ cancelButtonText }} - </gl-button> - </h4> - <section v-if="!glFeatures.restructuredMrWidget" class="mr-info-list"> - <p v-if="shouldRemoveSourceBranch"> - {{ s__('mrWidget|Deletes the source branch') }} - </p> - <p v-else class="gl-display-flex"> - <span class="gl-mr-3">{{ s__('mrWidget|Does not delete the source branch') }}</span> - <gl-button - v-if="canRemoveSourceBranch" - :loading="isRemovingSourceBranch" - size="small" - class="js-remove-source-branch" - data-testid="removeSourceBranchButton" - @click="removeSourceBranch" - > - {{ s__('mrWidget|Delete source branch') }} - </gl-button> - </p> - </section> - </div> </template> - </div> + </state-container> </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 1a764d3d091..b0cda85f361 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,17 +1,15 @@ <script> -import { GlLoadingIcon, GlButton } from '@gitlab/ui'; +import { s__ } from '~/locale'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import eventHub from '../../event_hub'; 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'; +import StateContainer from '../state_container.vue'; export default { name: 'MRWidgetAutoMergeFailed', components: { - statusIcon, - GlLoadingIcon, - GlButton, + StateContainer, }, mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin], apollo: { @@ -38,6 +36,17 @@ export default { isRefreshing: false, }; }, + computed: { + actions() { + return [ + { + text: s__('mrWidget|Refresh'), + loading: this.isRefreshing, + onClick: () => this.refreshWidget(), + }, + ]; + }, + }, methods: { refreshWidget() { this.isRefreshing = true; @@ -49,23 +58,10 @@ export default { }; </script> <template> - <div class="mr-widget-body media"> - <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="mergeError">{{ mergeError }}</template> - {{ s__('mrWidget|This merge request failed to be merged automatically') }} - </span> - <gl-button - :disabled="isRefreshing" - category="secondary" - variant="default" - size="small" - @click="refreshWidget" - > - <gl-loading-icon v-if="isRefreshing" size="sm" :inline="true" /> - {{ s__('mrWidget|Refresh') }} - </gl-button> - </div> - </div> + <state-container status="warning" :actions="actions"> + <span class="bold gl-ml-0!"> + <template v-if="mergeError">{{ mergeError }}</template> + {{ s__('mrWidget|This merge request failed to be merged automatically') }} + </span> + </state-container> </template> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue index fd42fa0421f..e2d87d8d536 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.vue @@ -1,5 +1,4 @@ <script> -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import statusIcon from '../mr_widget_status_icon.vue'; export default { @@ -7,14 +6,13 @@ export default { components: { statusIcon, }, - mixins: [glFeatureFlagMixin()], }; </script> <template> <div class="mr-widget-body media"> <status-icon :show-disabled-button="true" status="loading" /> <div class="media-body space-children"> - <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold"> + <span class="gl-ml-0! gl-text-body! bold"> {{ s__('mrWidget|Checking if merge request can be merged…') }} </span> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue index d50e52f5ac1..61f7d26f51e 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.vue @@ -1,5 +1,4 @@ <script> -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import MrWidgetAuthorTime from '../mr_widget_author_time.vue'; import statusIcon from '../mr_widget_status_icon.vue'; @@ -9,7 +8,6 @@ export default { MrWidgetAuthorTime, statusIcon, }, - mixins: [glFeatureFlagMixin()], props: { /* TODO: This is providing all store and service down when it only needs metrics and targetBranch */ @@ -30,13 +28,6 @@ export default { :date-title="mr.metrics.closedAt" :date-readable="mr.metrics.readableClosedAt" /> - - <section v-if="!glFeatures.restructuredMrWidget" class="mr-info-list"> - <p> - {{ s__('mrWidget|The changes were not merged into') }} - <a :href="mr.targetBranchPath" class="label-branch"> {{ mr.targetBranch }} </a> - </p> - </section> </div> </div> </template> 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 def30dacf8a..8abd915b93e 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 @@ -4,14 +4,14 @@ import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; import userPermissionsQuery from '../../queries/permissions.query.graphql'; import conflictsStateQuery from '../../queries/states/conflicts.query.graphql'; -import StatusIcon from '../mr_widget_status_icon.vue'; +import StateContainer from '../state_container.vue'; export default { name: 'MRWidgetConflicts', components: { GlSkeletonLoader, - StatusIcon, GlButton, + StateContainer, }, mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin], apollo: { @@ -86,29 +86,23 @@ export default { }; </script> <template> - <div class="mr-widget-body media"> - <status-icon :show-disabled-button="true" status="warning" /> - - <div v-if="isLoading" class="gl-ml-4 gl-w-full mr-conflict-loader"> + <state-container status="warning" :is-loading="isLoading"> + <template #loading> <gl-skeleton-loader :width="334" :height="30"> <rect x="0" y="7" width="150" height="16" rx="4" /> <rect x="158" y="7" width="84" height="16" rx="4" /> <rect x="250" y="7" width="84" height="16" rx="4" /> </gl-skeleton-loader> - </div> - <div v-else class="media-body space-children gl-display-flex gl-align-items-center"> - <span - v-if="shouldBeRebased" - :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" - class="bold" - > + </template> + <template v-if="!isLoading"> + <span v-if="shouldBeRebased" class="bold gl-ml-0! gl-text-body!"> {{ s__(`mrWidget|Merge blocked: fast-forward merge is not possible. To merge this request, first rebase locally.`) }} </span> <template v-else> - <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold"> + <span class="bold gl-ml-0! gl-text-body! gl-flex-grow-1 gl-w-full gl-md-w-auto gl-mr-2"> {{ s__('mrWidget|Merge blocked: merge conflicts must be resolved.') }} <span v-if="!canMerge"> {{ @@ -118,23 +112,30 @@ export default { }} </span> </span> - <gl-button - v-if="showResolveButton" - :href="mr.conflictResolutionPath" - :size="glFeatures.restructuredMrWidget ? 'small' : 'medium'" - data-testid="resolve-conflicts-button" - > - {{ s__('mrWidget|Resolve conflicts') }} - </gl-button> - <gl-button - v-if="canMerge" - :size="glFeatures.restructuredMrWidget ? 'small' : 'medium'" - data-testid="merge-locally-button" - class="js-check-out-modal-trigger" - > - {{ s__('mrWidget|Resolve locally') }} - </gl-button> </template> - </div> - </div> + </template> + <template v-if="!isLoading && !shouldBeRebased" #actions> + <gl-button + v-if="canMerge" + size="small" + variant="confirm" + category="secondary" + data-testid="merge-locally-button" + class="js-check-out-modal-trigger gl-align-self-start" + :class="{ 'gl-mr-2': showResolveButton }" + > + {{ s__('mrWidget|Resolve locally') }} + </gl-button> + <gl-button + v-if="showResolveButton" + :href="mr.conflictResolutionPath" + size="small" + variant="confirm" + class="gl-mb-2 gl-md-mb-0 gl-align-self-start" + data-testid="resolve-conflicts-button" + > + {{ s__('mrWidget|Resolve conflicts') }} + </gl-button> + </template> + </state-container> </template> 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 42e9261b82c..18103ac4a0e 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 @@ -30,7 +30,7 @@ export default { computed: { mergeError() { - const mergeError = this.mr.mergeError ? stripHtml(this.mr.mergeError, ' ').trim() : ''; + const mergeError = this.prepareMergeError(this.mr.mergeError); return sprintf( s__('mrWidget|%{mergeError}.'), @@ -76,6 +76,13 @@ export default { this.refresh(); } }, + prepareMergeError(mergeError) { + return mergeError + ? stripHtml(mergeError, ' ') + .replace(/(\.$|\s+)/g, ' ') + .trim() + : ''; + }, }, }; </script> @@ -89,7 +96,9 @@ export default { <status-icon :show-disabled-button="true" status="warning" /> <div class="media-body space-children"> <span class="bold"> - <span v-if="mr.mergeError" class="has-error-message"> {{ mergeError }} </span> + <span v-if="mr.mergeError" class="has-error-message" data-testid="merge-error"> + {{ mergeError }} + </span> <span v-else> {{ s__('mrWidget|Merge failed.') }} </span> <span :class="{ 'has-custom-error': mr.mergeError }"> {{ timerText }} </span> </span> 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 bf036f562ed..4416123cd51 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,15 +1,13 @@ <script> -/* eslint-disable @gitlab/vue-require-i18n-strings */ -import { GlLoadingIcon, GlButton, GlTooltipDirective, GlIcon } from '@gitlab/ui'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import { GlTooltipDirective, GlIcon } from '@gitlab/ui'; import api from '~/api'; import createFlash 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 StateContainer from '../state_container.vue'; export default { name: 'MRWidgetMerged', @@ -19,11 +17,8 @@ export default { components: { MrWidgetAuthorTime, GlIcon, - ClipboardButton, - GlLoadingIcon, - GlButton, + StateContainer, }, - mixins: [glFeatureFlagMixin()], props: { mr: { type: Object, @@ -78,6 +73,53 @@ export default { cherryPickLabel() { return s__('mrWidget|Cherry-pick'); }, + actions() { + const actions = []; + + if (this.mr.canRevertInCurrentMR) { + actions.push({ + text: this.revertLabel, + tooltipText: this.revertTitle, + dataQaSelector: 'revert_button', + onClick: () => this.openRevertModal(), + }); + } else if (this.mr.revertInForkPath) { + actions.push({ + text: this.revertLabel, + tooltipText: this.revertTitle, + href: this.mr.revertInForkPath, + dataQaSelector: 'revert_button', + dataMethod: 'post', + }); + } + + if (this.mr.canCherryPickInCurrentMR) { + actions.push({ + text: this.cherryPickLabel, + tooltipText: this.cherryPickTitle, + dataQaSelector: 'cherry_pick_button', + onClick: () => this.openCherryPickModal(), + }); + } else if (this.mr.cherryPickInForkPath) { + actions.push({ + text: this.cherryPickLabel, + tooltipText: this.cherryPickTitle, + href: this.mr.cherryPickInForkPath, + dataQaSelector: 'cherry_pick_button', + dataMethod: 'post', + }); + } + + if (this.shouldShowRemoveSourceBranch) { + actions.push({ + text: s__('mrWidget|Delete source branch'), + class: 'js-remove-branch-button', + onClick: () => this.removeSourceBranch(), + }); + } + + return actions; + }, }, mounted() { document.dispatchEvent(new CustomEvent('merged:UpdateActions')); @@ -121,103 +163,15 @@ export default { }; </script> <template> - <div class="mr-widget-body media"> - <gl-icon name="merge" :size="24" class="gl-text-blue-500 gl-mr-3 gl-mt-1" /> - <div class="media-body"> - <div class="space-children"> - <mr-widget-author-time - :action-text="s__('mrWidget|Merged by')" - :author="mr.metrics.mergedBy" - :date-title="mr.metrics.mergedAt" - :date-readable="mr.metrics.readableMergedAt" - /> - <gl-button - v-if="mr.canRevertInCurrentMR" - v-gl-tooltip.hover - :title="revertTitle" - size="small" - category="secondary" - data-qa-selector="revert_button" - @click="openRevertModal" - > - {{ revertLabel }} - </gl-button> - <gl-button - v-else-if="mr.revertInForkPath" - v-gl-tooltip.hover - :href="mr.revertInForkPath" - :title="revertTitle" - size="small" - category="secondary" - data-method="post" - > - {{ revertLabel }} - </gl-button> - <gl-button - v-if="mr.canCherryPickInCurrentMR" - v-gl-tooltip.hover - :title="cherryPickTitle" - size="small" - data-qa-selector="cherry_pick_button" - @click="openCherryPickModal" - > - {{ cherryPickLabel }} - </gl-button> - <gl-button - v-else-if="mr.cherryPickInForkPath" - v-gl-tooltip.hover - :href="mr.cherryPickInForkPath" - :title="cherryPickTitle" - size="small" - data-method="post" - > - {{ cherryPickLabel }} - </gl-button> - <gl-button - v-if="shouldShowRemoveSourceBranch" - :disabled="isMakingRequest" - size="small" - class="js-remove-branch-button" - @click="removeSourceBranch" - > - {{ s__('mrWidget|Delete source branch') }} - </gl-button> - </div> - <section - v-if="!glFeatures.restructuredMrWidget" - class="mr-info-list" - data-qa-selector="merged_status_content" - > - <p> - {{ s__('mrWidget|The changes were merged into') }} - <span class="label-branch"> - <a :href="mr.targetBranchPath">{{ mr.targetBranch }}</a> - </span> - <template v-if="mr.mergeCommitSha"> - with - <a - :href="mr.mergeCommitPath" - class="commit-sha js-mr-merged-commit-sha" - v-text="mr.shortMergeCommitSha" - > - </a> - <clipboard-button - :title="__('Copy commit SHA')" - :text="mr.mergeCommitSha" - css-class="js-mr-merged-copy-sha" - category="tertiary" - size="small" - /> - </template> - </p> - <p v-if="mr.sourceBranchRemoved"> - {{ s__('mrWidget|The source branch has been deleted') }} - </p> - <p v-if="shouldShowSourceBranchRemoving"> - <gl-loading-icon size="sm" :inline="true" /> - <span> {{ s__('mrWidget|The source branch is being deleted') }} </span> - </p> - </section> - </div> - </div> + <state-container :actions="actions"> + <template #icon> + <gl-icon name="merge" :size="24" class="gl-text-blue-500 gl-mr-3 gl-mt-1" /> + </template> + <mr-widget-author-time + :action-text="s__('mrWidget|Merged by')" + :author="mr.metrics.mergedBy" + :date-title="mr.metrics.mergedAt" + :date-readable="mr.metrics.readableMergedAt" + /> + </state-container> </template> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue index b86ab69af3f..c7574a41bb8 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue @@ -1,6 +1,5 @@ <script> import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import simplePoll from '~/lib/utils/simple_poll'; import MergeRequest from '~/merge_request'; import eventHub from '../../event_hub'; @@ -15,7 +14,6 @@ export default { components: { statusIcon, }, - mixins: [glFeatureFlagMixin()], props: { mr: { type: Object, @@ -90,14 +88,6 @@ export default { {{ mergeStatus.message }} <gl-emoji :data-name="mergeStatus.emoji" /> </h4> - <section v-if="!glFeatures.restructuredMrWidget" class="mr-info-list"> - <p> - {{ s__('mrWidget|Merges changes into') }} - <span class="label-branch"> - <a :href="mr.targetBranchPath">{{ mr.targetBranch }}</a> - </span> - </p> - </section> </div> </div> </template> 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 cadbd9c28a9..659d12d1160 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 @@ -74,13 +74,7 @@ export default { <status-icon :show-disabled-button="true" status="warning" /> <div class="media-body space-children"> - <span - :class="{ - 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget, - }" - class="bold js-branch-text" - data-testid="widget-content" - > + <span class="gl-ml-0! gl-text-body! bold js-branch-text" data-testid="widget-content"> <gl-sprintf :message="warning"> <template #code="{ content }"> <code>{{ content }}</code> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue index 34c5a2ff2c8..e99ee59b877 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.vue @@ -14,7 +14,7 @@ export default { <div class="mr-widget-body media"> <status-icon :show-disabled-button="true" status="warning" /> <div class="media-body space-children"> - <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold"> + <span class="gl-ml-0! gl-text-body! bold"> {{ s__( `mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue.`, 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 59767eb2e6e..6c5fc916799 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 @@ -8,7 +8,7 @@ import simplePoll from '~/lib/utils/simple_poll'; import eventHub from '../../event_hub'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; import rebaseQuery from '../../queries/states/rebase.query.graphql'; -import statusIcon from '../mr_widget_status_icon.vue'; +import StateContainer from '../state_container.vue'; export default { name: 'MRWidgetRebase', @@ -25,9 +25,9 @@ export default { }, }, components: { - statusIcon, GlSkeletonLoader, GlButton, + StateContainer, }, mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin], props: { @@ -51,9 +51,6 @@ export default { isLoading() { return this.glFeatures.mergeRequestWidgetGraphql && this.$apollo.queries.state.loading; }, - showRebaseWithoutCi() { - return this.glFeatures?.rebaseWithoutCiUi; - }, rebaseInProgress() { if (this.glFeatures.mergeRequestWidgetGraphql) { return this.state.rebaseInProgress; @@ -76,6 +73,10 @@ export default { return this.mr.targetBranch; }, status() { + if (this.isLoading) { + return undefined; + } + if (this.rebaseInProgress || this.isMakingRequest) { return 'loading'; } @@ -148,92 +149,70 @@ export default { }; </script> <template> - <div class="mr-widget-body media"> - <div v-if="isLoading" class="gl-w-full mr-conflict-loader"> + <state-container :status="status" :is-loading="isLoading"> + <template #loading> <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> + <template v-if="!isLoading"> + <span + v-if="rebaseInProgress || isMakingRequest" + class="gl-ml-0! gl-text-body! gl-font-weight-bold" + data-testid="rebase-message" + >{{ __('Rebase in progress') }}</span + > + <span + v-if="!rebaseInProgress && !canPushToSourceBranch" + class="gl-text-body! gl-font-weight-bold gl-ml-0!" + data-testid="rebase-message" + >{{ fastForwardMergeText }}</span + > + <div + v-if="!rebaseInProgress && canPushToSourceBranch && !isMakingRequest" + class="accept-merge-holder clearfix js-toggle-container media gl-md-display-flex gl-flex-wrap gl-flex-grow-1" + > <span - v-if="rebaseInProgress || isMakingRequest" - :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" - class="gl-font-weight-bold" + v-if="!rebasingError" + class="gl-font-weight-bold gl-w-100 gl-md-w-auto gl-flex-grow-1 gl-ml-0! gl-text-body! gl-md-mr-3" data-testid="rebase-message" - >{{ __('Rebase in progress') }}</span + data-qa-selector="no_fast_forward_message_content" + >{{ + __('Merge blocked: the source branch must be rebased onto the target branch.') + }}</span > <span - v-if="!rebaseInProgress && !canPushToSourceBranch" - :class="{ 'gl-text-body!': glFeatures.restructuredMrWidget }" - class="gl-font-weight-bold gl-ml-0!" + v-else + class="gl-font-weight-bold danger gl-w-100 gl-md-w-auto gl-flex-grow-1 gl-md-mr-3" data-testid="rebase-message" - >{{ fastForwardMergeText }}</span - > - <div - v-if="!rebaseInProgress && canPushToSourceBranch && !isMakingRequest" - class="accept-merge-holder clearfix js-toggle-container accept-action media space-children gl-align-items-center" + >{{ rebasingError }}</span > - <gl-button - v-if="!glFeatures.restructuredMrWidget" - :loading="isMakingRequest" - variant="confirm" - data-qa-selector="mr_rebase_button" - data-testid="standard-rebase-button" - @click="rebase" - > - {{ __('Rebase') }} - </gl-button> - <gl-button - v-if="!glFeatures.restructuredMrWidget && showRebaseWithoutCi" - :loading="isMakingRequest" - variant="confirm" - category="secondary" - data-testid="rebase-without-ci-button" - @click="rebaseWithoutCi" - > - {{ __('Rebase without pipeline') }} - </gl-button> - <span - v-if="!rebasingError" - :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" - class="gl-font-weight-bold" - data-testid="rebase-message" - data-qa-selector="no_fast_forward_message_content" - >{{ - __('Merge blocked: the source branch must be rebased onto the target branch.') - }}</span - > - <span v-else class="gl-font-weight-bold danger" data-testid="rebase-message">{{ - rebasingError - }}</span> - <gl-button - v-if="glFeatures.restructuredMrWidget" - :loading="isMakingRequest" - variant="confirm" - size="small" - data-qa-selector="mr_rebase_button" - class="gl-ml-3!" - @click="rebase" - > - {{ __('Rebase') }} - </gl-button> - <gl-button - v-if="glFeatures.restructuredMrWidget && showRebaseWithoutCi" - :loading="isMakingRequest" - variant="confirm" - size="small" - category="secondary" - data-testid="rebase-without-ci-button" - @click="rebaseWithoutCi" - > - {{ __('Rebase without pipeline') }} - </gl-button> - </div> </div> </template> - </div> + <template v-if="!isLoading" #actions> + <gl-button + :loading="isMakingRequest" + variant="confirm" + size="small" + category="secondary" + data-testid="rebase-without-ci-button" + class="gl-align-self-start gl-mr-2" + @click="rebaseWithoutCi" + > + {{ __('Rebase without pipeline') }} + </gl-button> + <gl-button + :loading="isMakingRequest" + variant="confirm" + size="small" + data-qa-selector="mr_rebase_button" + data-testid="standard-rebase-button" + class="gl-mb-2 gl-md-mb-0 gl-align-self-start" + @click="rebase" + > + {{ __('Rebase') }} + </gl-button> + </template> + </state-container> </template> 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 d204befef58..d507e5f232b 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,7 +1,6 @@ <script> import { GlLink, GlSprintf } from '@gitlab/ui'; import { helpPagePath } from '~/helpers/help_page_helper'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { s__ } from '~/locale'; import statusIcon from '../mr_widget_status_icon.vue'; @@ -12,7 +11,6 @@ export default { GlSprintf, statusIcon, }, - mixins: [glFeatureFlagMixin()], computed: { troubleshootingDocsPath() { return helpPagePath('ci/troubleshooting', { anchor: 'merge-request-status-messages' }); @@ -30,7 +28,7 @@ export default { <div class="mr-widget-body media"> <status-icon :show-disabled-button="true" status="warning" /> <div class="media-body space-children"> - <span :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" class="bold"> + <span class="gl-ml-0! gl-text-body! bold"> <gl-sprintf :message="$options.i18n.failedMessage"> <template #link="{ content }"> <gl-link :href="troubleshootingDocsPath" target="_blank"> 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 cf482410bef..d2c85b14999 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 @@ -31,12 +31,10 @@ import { 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 AddedCommitMessage from '../added_commit_message.vue'; import RelatedLinks from '../mr_widget_related_links.vue'; import CommitEdit from './commit_edit.vue'; import CommitMessageDropdown from './commit_message_dropdown.vue'; -import CommitsHeader from './commits_header.vue'; import SquashBeforeMerge from './squash_before_merge.vue'; import MergeFailedPipelineConfirmationDialog from './merge_failed_pipeline_confirmation_dialog.vue'; @@ -96,9 +94,7 @@ export default { }, }, components: { - statusIcon, SquashBeforeMerge, - CommitsHeader, CommitEdit, CommitMessageDropdown, GlIcon, @@ -320,34 +316,27 @@ export default { showDangerMessageForMergeTrain() { return this.preferredAutoMergeStrategy === MT_MERGE_STRATEGY && this.isPipelineFailed; }, - restructuredWidgetShowMergeButtons() { - if (this.glFeatures.restructuredMrWidget) { - return ( - (this.isMergeAllowed || this.isAutoMergeAvailable) && - this.state.userPermissions.canMerge && - !this.mr.mergeOngoing && - !this.mr.autoMergeEnabled - ); - } - - return true; + shouldShowMergeControls() { + return ( + (this.isMergeAllowed || this.isAutoMergeAvailable) && + (this.stateData.userPermissions?.canMerge || this.mr.canMerge) && + !this.mr.mergeOngoing && + !this.mr.autoMergeEnabled + ); }, sourceBranchDeletedText() { - if (this.glFeatures.restructuredMrWidget) { - if (this.removeSourceBranch) { - return this.mr.state === 'merged' - ? __('Deleted the source branch.') - : __('Source branch will be deleted.'); - } - + if (this.removeSourceBranch) { return this.mr.state === 'merged' - ? __('Did not delete the source branch.') - : __('Source branch will not be deleted.'); + ? __('Deleted the source branch.') + : __('Source branch will be deleted.'); } - return this.removeSourceBranch - ? __('Deletes the source branch.') - : __('Does not delete the source branch.'); + return this.mr.state === 'merged' + ? __('Did not delete the source branch.') + : __('Source branch will not be deleted.'); + }, + showMergeDetailsHeader() { + return ['readyToMerge'].indexOf(this.mr.state) >= 0; }, }, mounted() { @@ -525,10 +514,7 @@ export default { <template> <div data-testid="ready_to_merge_state" - :class="{ - 'gl-border-t-1 gl-border-t-solid gl-border-gray-100 gl-bg-gray-10 gl-pl-7 gl-rounded-bottom-left-base gl-rounded-bottom-right-base': - glFeatures.restructuredMrWidget, - }" + class="gl-border-t-1 gl-border-t-solid gl-border-gray-100 gl-bg-gray-10 gl-pl-7 gl-rounded-bottom-left-base gl-rounded-bottom-right-base" > <div v-if="loading" class="mr-widget-body"> <div class="gl-w-full mr-ready-to-merge-loader"> @@ -541,16 +527,10 @@ export default { </div> </div> <template v-else> - <div - class="mr-widget-body media" - :class="{ - 'mr-widget-body-line-height-1': glFeatures.restructuredMrWidget, - }" - > - <status-icon v-if="!glFeatures.restructuredMrWidget" :status="iconClass" /> + <div class="mr-widget-body mr-widget-body-ready-merge media mr-widget-body-line-height-1"> <div class="media-body"> <div class="mr-widget-body-controls gl-display-flex gl-align-items-center gl-flex-wrap"> - <gl-button-group v-if="restructuredWidgetShowMergeButtons" class="gl-align-self-start"> + <gl-button-group v-if="shouldShowMergeControls" class="gl-align-self-start"> <gl-button size="medium" category="primary" @@ -603,19 +583,14 @@ export default { <merge-train-helper-icon v-if="shouldRenderMergeTrainHelperIcon" class="gl-mx-3" /> <div v-if="shouldShowMergeControls" - :class="{ 'gl-w-full gl-order-n1 gl-mb-5': glFeatures.restructuredMrWidget }" - class="gl-display-flex gl-align-items-center gl-flex-wrap" + class="gl-display-flex gl-align-items-center gl-flex-wrap gl-w-full gl-order-n1 gl-mb-5" > <gl-form-checkbox v-if="canRemoveSourceBranch" id="remove-source-branch-input" v-model="removeSourceBranch" :disabled="isRemoveSourceBranchButtonDisabled" - :class="{ - 'gl-mx-3': !glFeatures.restructuredMrWidget, - 'gl-mr-5': glFeatures.restructuredMrWidget, - }" - class="js-remove-source-branch-checkbox gl-display-flex gl-align-items-center" + class="js-remove-source-branch-checkbox gl-display-flex gl-align-items-center gl-mr-5" > {{ __('Delete source branch') }} </gl-form-checkbox> @@ -626,16 +601,11 @@ export default { v-model="squashBeforeMerge" :help-path="mr.squashBeforeMergeHelpPath" :is-disabled="isSquashReadOnly" - :class="{ - 'gl-mx-3': !glFeatures.restructuredMrWidget, - 'gl-mr-5': glFeatures.restructuredMrWidget, - }" + class="gl-mr-5" /> <gl-form-checkbox - v-if=" - glFeatures.restructuredMrWidget && (shouldShowSquashEdit || shouldShowMergeEdit) - " + v-if="shouldShowSquashEdit || shouldShowMergeEdit" v-model="editCommitMessage" data-testid="widget_edit_commit_message" class="gl-display-flex gl-align-items-center" @@ -644,198 +614,113 @@ export default { </gl-form-checkbox> </div> <div - v-else-if="!glFeatures.restructuredMrWidget" - class="bold js-resolve-mr-widget-items-message gl-ml-3" + v-if="editCommitMessage" + class="gl-w-full gl-order-n1" + data-testid="edit_commit_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" + <ul class="border-top commits-list flex-list gl-list-style-none gl-p-0 gl-pt-4"> + <commit-edit + v-if="shouldShowSquashEdit" + :value="squashCommitMessage" + :label="__('Squash commit message')" + input-id="squash-message-edit" + class="gl-m-0! gl-p-0!" + @input="setSquashCommitMessage" > - <gl-icon name="question" /> - </gl-link> - </div> - <gl-sprintf v-else :message="mergeDisabledText" /> + <template #header> + <commit-message-dropdown :commits="commits" @input="setSquashCommitMessage" /> + </template> + </commit-edit> + <commit-edit + v-if="shouldShowMergeEdit" + :value="commitMessage" + :label="__('Merge commit message')" + input-id="merge-message-edit" + class="gl-m-0! gl-p-0!" + @input="setCommitMessage" + /> + <li class="gl-m-0! gl-p-0!"> + <p class="form-text text-muted"> + <gl-sprintf :message="commitTemplateHintText"> + <template #link="{ content }"> + <gl-link :href="commitTemplateHelpPage" class="inline-link" target="_blank"> + {{ content }} + </gl-link> + </template> + </gl-sprintf> + </p> + </li> + </ul> </div> - <template v-if="glFeatures.restructuredMrWidget"> - <div - v-if="editCommitMessage" - class="gl-w-full gl-order-n1" - data-testid="edit_commit_message" - > - <ul - :class="{ - 'content-list': !glFeatures.restructuredMrWidget, - 'gl-list-style-none gl-p-0 gl-pt-4': glFeatures.restructuredMrWidget, - }" - class="border-top commits-list flex-list" - > - <commit-edit - v-if="shouldShowSquashEdit" - :value="squashCommitMessage" - :label="__('Squash commit message')" - input-id="squash-message-edit" - class="gl-m-0! gl-p-0!" - @input="setSquashCommitMessage" + <div + v-if="!shouldShowMergeControls" + class="gl-w-full gl-order-n1 mr-widget-merge-details" + data-qa-selector="merged_status_content" + > + <p v-if="showMergeDetailsHeader" class="gl-mb-3 gl-text-gray-900"> + {{ __('Merge details') }} + </p> + <ul class="gl-pl-4 gl-mb-0 gl-ml-3 gl-text-gray-600"> + <li v-if="mr.divergedCommitsCount > 0" class="gl-line-height-normal"> + <gl-sprintf + :message="s__('mrWidget|The source branch is %{link} the target branch')" > - <template #header> - <commit-message-dropdown :commits="commits" @input="setSquashCommitMessage" /> + <template #link> + <gl-link :href="mr.targetBranchPath">{{ + n__('%d commit behind', '%d commits behind', mr.divergedCommitsCount) + }}</gl-link> </template> - </commit-edit> - <commit-edit - v-if="shouldShowMergeEdit" - :value="commitMessage" - :label="__('Merge commit message')" - input-id="merge-message-edit" - class="gl-m-0! gl-p-0!" - @input="setCommitMessage" + </gl-sprintf> + </li> + <li class="gl-line-height-normal"> + <added-commit-message + :state="mr.state" + :merge-commit-sha="mr.shortMergeCommitSha" + :is-squash-enabled="squashBeforeMerge" + :is-fast-forward-enabled="!shouldShowMergeEdit" + :commits-count="commitsCount" + :target-branch="stateData.targetBranch" /> - <li class="gl-m-0! gl-p-0!"> - <p class="form-text text-muted"> - <gl-sprintf :message="commitTemplateHintText"> - <template #link="{ content }"> - <gl-link - :href="commitTemplateHelpPage" - class="inline-link" - target="_blank" - > - {{ content }} - </gl-link> - </template> - </gl-sprintf> - </p> - </li> - </ul> - </div> - <div - v-if="!restructuredWidgetShowMergeButtons" - class="gl-w-full gl-order-n1 gl-text-gray-500" - data-qa-selector="merged_status_content" - > - <strong v-if="mr.state !== 'closed'"> - {{ __('Merge details') }} - </strong> - <ul class="gl-pl-4 gl-m-0"> - <li v-if="mr.divergedCommitsCount > 0" class="gl-line-height-normal"> - <gl-sprintf - :message="s__('mrWidget|The source branch is %{link} the target branch')" - > - <template #link> - <gl-link :href="mr.targetBranchPath">{{ - n__('%d commit behind', '%d commits behind', mr.divergedCommitsCount) - }}</gl-link> - </template> - </gl-sprintf> - </li> - <li class="gl-line-height-normal"> - <added-commit-message - :state="mr.state" - :merge-commit-sha="mr.shortMergeCommitSha" - :is-squash-enabled="squashBeforeMerge" - :is-fast-forward-enabled="!shouldShowMergeEdit" - :commits-count="commitsCount" - :target-branch="stateData.targetBranch" - /> - </li> - <li v-if="mr.state !== 'closed'" class="gl-line-height-normal"> - {{ sourceBranchDeletedText }} - </li> - <li v-if="mr.relatedLinks" class="gl-line-height-normal"> - <related-links - :state="mr.state" - :related-links="mr.relatedLinks" - :show-assign-to-me="false" - class="mr-ready-merge-related-links gl-display-inline" - /> - </li> - </ul> - </div> - <div - v-else - :class="{ 'gl-mb-5': restructuredWidgetShowMergeButtons }" - class="gl-w-full gl-order-n1 gl-text-gray-500" - > - <added-commit-message - :is-squash-enabled="squashBeforeMerge" - :is-fast-forward-enabled="!shouldShowMergeEdit" - :commits-count="commitsCount" - :target-branch="stateData.targetBranch" - /> - <template v-if="mr.relatedLinks"> - · + </li> + <li v-if="mr.state !== 'closed'" class="gl-line-height-normal"> + {{ sourceBranchDeletedText }} + </li> + <li v-if="mr.relatedLinks" class="gl-line-height-normal"> <related-links :state="mr.state" :related-links="mr.relatedLinks" :show-assign-to-me="false" - :diverged-commits-count="mr.divergedCommitsCount" - :target-branch-path="mr.targetBranchPath" class="mr-ready-merge-related-links gl-display-inline" /> - </template> - </div> - </template> - </div> - <div - v-if="showDangerMessageForMergeTrain && !glFeatures.restructuredMrWidget" - class="gl-mt-5 gl-text-gray-500" - data-testid="failed-pipeline-merge-train-text" - > - {{ __('The latest pipeline for this merge request did not complete successfully.') }} + </li> + </ul> + </div> + <div + v-else + :class="{ 'gl-mb-5': shouldShowMergeControls }" + class="gl-w-full gl-order-n1 gl-text-gray-500" + > + <added-commit-message + :is-squash-enabled="squashBeforeMerge" + :is-fast-forward-enabled="!shouldShowMergeEdit" + :commits-count="commitsCount" + :target-branch="stateData.targetBranch" + /> + <template v-if="mr.relatedLinks"> + · + <related-links + :state="mr.state" + :related-links="mr.relatedLinks" + :show-assign-to-me="false" + :diverged-commits-count="mr.divergedCommitsCount" + :target-branch-path="mr.targetBranchPath" + class="mr-ready-merge-related-links gl-display-inline" + /> + </template> + </div> </div> </div> </div> - <template v-if="shouldShowMergeControls && !glFeatures.restructuredMrWidget"> - <div v-if="!shouldShowMergeEdit" class="mr-fast-forward-message"> - {{ __('Fast-forward merge without a merge commit') }} - </div> - <commits-header - v-if="!glFeatures.restructuredMrWidget && (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" - :value="squashCommitMessage" - :label="__('Squash commit message')" - input-id="squash-message-edit" - squash - @input="setSquashCommitMessage" - > - <template #header> - <commit-message-dropdown :commits="commits" @input="setSquashCommitMessage" /> - </template> - </commit-edit> - <commit-edit - v-if="shouldShowMergeEdit" - :value="commitMessage" - :label="__('Merge commit message')" - input-id="merge-message-edit" - @input="setCommitMessage" - /> - <li> - <p class="form-text text-muted"> - <gl-sprintf :message="commitTemplateHintText"> - <template #link="{ content }"> - <gl-link :href="commitTemplateHelpPage" class="inline-link" target="_blank"> - {{ content }} - </gl-link> - </template> - </gl-sprintf> - </p> - </li> - </ul> - </commits-header> - </template> </template> </div> </template> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue index b1fbe150fcf..d149f5208fc 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue @@ -1,19 +1,17 @@ <script> import { GlButton } from '@gitlab/ui'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { I18N_SHA_MISMATCH } from '../../i18n'; -import statusIcon from '../mr_widget_status_icon.vue'; +import StateContainer from '../state_container.vue'; export default { name: 'ShaMismatch', components: { - statusIcon, GlButton, + StateContainer, }, i18n: { I18N_SHA_MISMATCH, }, - mixins: [glFeatureFlagMixin()], props: { mr: { type: Object, @@ -24,25 +22,24 @@ export default { </script> <template> - <div class="mr-widget-body media"> - <status-icon :show-disabled-button="false" status="warning" /> - <div class="media-body"> - <span - :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" - class="gl-font-weight-bold" - data-qa-selector="head_mismatch_content" - > - {{ $options.i18n.I18N_SHA_MISMATCH.warningMessage }} - </span> + <state-container status="warning"> + <span + class="gl-font-weight-bold gl-md-mr-3 gl-flex-grow-1 gl-ml-0! gl-text-body!" + data-qa-selector="head_mismatch_content" + > + {{ $options.i18n.I18N_SHA_MISMATCH.warningMessage }} + </span> + <template #actions> <gl-button - class="gl-ml-3" data-testid="action-button" size="small" category="primary" variant="confirm" + class="gl-align-self-start" :href="mr.mergeRequestDiffsPath" - >{{ $options.i18n.I18N_SHA_MISMATCH.actionButtonLabel }}</gl-button > - </div> - </div> + {{ $options.i18n.I18N_SHA_MISMATCH.actionButtonLabel }} + </gl-button> + </template> + </state-container> </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 c6227c4394d..1413a46b4b9 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 @@ -1,6 +1,5 @@ <script> import { GlIcon, GlTooltipDirective, GlFormCheckbox, GlLink } from '@gitlab/ui'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { SQUASH_BEFORE_MERGE } from '../../i18n'; export default { @@ -12,7 +11,6 @@ export default { directives: { GlTooltip: GlTooltipDirective, }, - mixins: [glFeatureFlagsMixin()], i18n: { ...SQUASH_BEFORE_MERGE, }, @@ -36,9 +34,6 @@ export default { tooltipTitle() { return this.isDisabled ? this.$options.i18n.tooltipTitle : null; }, - helpIconName() { - return this.glFeatures.restructuredMrWidget ? 'question-o' : 'question'; - }, }, }; </script> @@ -62,10 +57,10 @@ export default { v-gl-tooltip :href="helpPath" :title="$options.i18n.helpLabel" - :class="{ 'gl-text-blue-600': glFeatures.restructuredMrWidget }" + class="gl-text-blue-600" target="_blank" > - <gl-icon :name="helpIconName" /> + <gl-icon name="question-o" /> <span class="sr-only"> {{ $options.i18n.helpLabel }} </span> 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 25ba4bf12af..035d62eaa59 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,16 +1,14 @@ <script> import { GlButton } from '@gitlab/ui'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import notesEventHub from '~/notes/event_hub'; -import statusIcon from '../mr_widget_status_icon.vue'; +import StateContainer from '../state_container.vue'; export default { name: 'UnresolvedDiscussions', components: { - statusIcon, GlButton, + StateContainer, }, - mixins: [glFeatureFlagMixin()], props: { mr: { type: Object, @@ -26,38 +24,33 @@ export default { </script> <template> - <div class="mr-widget-body media gl-flex-wrap"> - <status-icon show-disabled-button status="warning" /> - <div class="media-body"> - <span - :class="{ - 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget, - 'gl-display-block': !glFeatures.restructuredMrWidget, - }" - class="gl-ml-3 gl-font-weight-bold gl-w-100" - > - {{ s__('mrWidget|Merge blocked: all threads must be resolved.') }} - </span> + <state-container status="warning"> + <span + class="gl-ml-3 gl-font-weight-bold gl-w-100 gl-flex-grow-1 gl-md-mr-3 gl-ml-0! gl-text-body!" + > + {{ s__('mrWidget|Merge blocked: all threads must be resolved.') }} + </span> + <template #actions> <gl-button - data-testid="jump-to-first" - class="gl-ml-3" + v-if="mr.createIssueToResolveDiscussionsPath" + :href="mr.createIssueToResolveDiscussionsPath" + class="js-create-issue gl-align-self-start gl-vertical-align-top gl-mr-2" size="small" - :icon="glFeatures.restructuredMrWidget ? undefined : 'comment-next'" - :variant="glFeatures.restructuredMrWidget ? 'confirm' : 'default'" - :category="glFeatures.restructuredMrWidget ? 'secondary' : 'primary'" - @click="jumpToFirstUnresolvedDiscussion" + variant="confirm" + category="secondary" > - {{ s__('mrWidget|Jump to first unresolved thread') }} + {{ s__('mrWidget|Create issue to resolve all threads') }} </gl-button> <gl-button - v-if="mr.createIssueToResolveDiscussionsPath" - :href="mr.createIssueToResolveDiscussionsPath" - class="js-create-issue gl-ml-3" + data-testid="jump-to-first" + class="gl-mb-2 gl-md-mb-0 gl-align-self-start gl-vertical-align-top" size="small" - :icon="glFeatures.restructuredMrWidget ? undefined : 'issue-new'" + variant="confirm" + category="primary" + @click="jumpToFirstUnresolvedDiscussion" > - {{ s__('mrWidget|Create issue to resolve all threads') }} + {{ s__('mrWidget|Jump to first unresolved thread') }} </gl-button> - </div> - </div> + </template> + </state-container> </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 5bd7745d704..cf7f83c014a 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 @@ -12,13 +12,13 @@ import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_va import getStateQuery from '../../queries/get_state.query.graphql'; import draftQuery from '../../queries/states/draft.query.graphql'; import removeDraftMutation from '../../queries/toggle_draft.mutation.graphql'; -import StatusIcon from '../mr_widget_status_icon.vue'; +import StateContainer from '../state_container.vue'; export default { name: 'WorkInProgress', components: { - StatusIcon, GlButton, + StateContainer, }, mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin], apollo: { @@ -163,29 +163,22 @@ export default { </script> <template> - <div class="mr-widget-body media"> - <status-icon :show-disabled-button="canUpdate" status="warning" /> - <div class="media-body"> - <div class="float-left"> - <span - :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" - class="gl-font-weight-bold" - > - {{ - __("Merge blocked: merge request must be marked as ready. It's still marked as draft.") - }} - </span> - </div> + <state-container status="warning"> + <span class="gl-font-weight-bold gl-ml-0! gl-text-body! gl-flex-grow-1"> + {{ __("Merge blocked: merge request must be marked as ready. It's still marked as draft.") }} + </span> + <template #actions> <gl-button v-if="canUpdate" size="small" :disabled="isMakingRequest" :loading="isMakingRequest" - class="js-remove-draft gl-ml-3" + variant="confirm" + class="js-remove-draft gl-md-ml-3 gl-align-self-start" @click="handleRemoveDraft" > {{ s__('mrWidget|Mark as ready') }} </gl-button> - </div> - </div> + </template> + </state-container> </template> |