Commit 2ea6c056 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'ph/324162/updatedReadyToMergeState' into 'master'

Updates ready to merge state to always be visible

See merge request gitlab-org/gitlab!71721
parents ed14a065 4da6b88b
<script>
import { GlSprintf } from '@gitlab/ui';
import { escape } from 'lodash';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { n__, s__ } from '~/locale';
const mergeCommitCount = s__('mrWidgetCommitsAdded|1 merge commit');
export default {
components: {
GlSprintf,
},
mixins: [glFeatureFlagMixin()],
props: {
isSquashEnabled: {
type: Boolean,
required: false,
default: false,
},
isFastForwardEnabled: {
type: Boolean,
required: true,
},
commitsCount: {
type: Number,
required: false,
default: 0,
},
targetBranch: {
type: String,
required: true,
},
},
computed: {
targetBranchEscaped() {
return escape(this.targetBranch);
},
commitsCountMessage() {
return n__('%d commit', '%d commits', this.isSquashEnabled ? 1 : this.commitsCount);
},
message() {
return this.isFastForwardEnabled
? s__('mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}.')
: s__(
'mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}%{squashedCommits}.',
);
},
textDecorativeComponent() {
return this.glFeatures.restructuredMrWidget ? 'span' : 'strong';
},
},
mergeCommitCount,
};
</script>
<template>
<span>
<gl-sprintf :message="message">
<template #commitCount>
<component :is="textDecorativeComponent" class="commits-count-message">{{
commitsCountMessage
}}</component>
</template>
<template #mergeCommitCount>
<component :is="textDecorativeComponent">{{ $options.mergeCommitCount }}</component>
</template>
<template #targetBranch>
<span class="label-branch">{{ targetBranchEscaped }}</span>
</template>
<template v-if="glFeatures.restructuredMrWidget" #squashedCommits>
<template v-if="isSquashEnabled">
{{ __('(commits will be squashed)') }}</template
></template
>
</gl-sprintf>
</span>
</template>
<script> <script>
import { s__, n__ } from '~/locale'; import { s__, n__ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default { export default {
name: 'MRWidgetRelatedLinks', name: 'MRWidgetRelatedLinks',
mixins: [glFeatureFlagMixin()],
props: { props: {
relatedLinks: { relatedLinks: {
type: Object, type: Object,
...@@ -14,6 +16,11 @@ export default { ...@@ -14,6 +16,11 @@ export default {
required: false, required: false,
default: '', default: '',
}, },
showAssignToMe: {
type: Boolean,
required: false,
default: true,
},
}, },
computed: { computed: {
closesText() { closesText() {
...@@ -30,16 +37,25 @@ export default { ...@@ -30,16 +37,25 @@ export default {
}; };
</script> </script>
<template> <template>
<section class="mr-info-list gl-ml-7 gl-pb-5"> <section>
<p v-if="relatedLinks.closing"> <p
v-if="relatedLinks.closing"
:class="{ 'gl-display-line gl-m-0': glFeatures.restructuredMrWidget }"
>
{{ closesText }} {{ closesText }}
<span v-html="relatedLinks.closing /* eslint-disable-line vue/no-v-html */"></span> <span v-html="relatedLinks.closing /* eslint-disable-line vue/no-v-html */"></span>
</p> </p>
<p v-if="relatedLinks.mentioned"> <p
v-if="relatedLinks.mentioned"
:class="{ 'gl-display-line gl-m-0': glFeatures.restructuredMrWidget }"
>
{{ n__('mrWidget|Mentions issue', 'mrWidget|Mentions issues', relatedLinks.mentionedCount) }} {{ n__('mrWidget|Mentions issue', 'mrWidget|Mentions issues', relatedLinks.mentionedCount) }}
<span v-html="relatedLinks.mentioned /* eslint-disable-line vue/no-v-html */"></span> <span v-html="relatedLinks.mentioned /* eslint-disable-line vue/no-v-html */"></span>
</p> </p>
<p v-if="relatedLinks.assignToMe"> <p
v-if="relatedLinks.assignToMe && showAssignToMe"
:class="{ 'gl-display-line gl-m-0': glFeatures.restructuredMrWidget }"
>
<span v-html="relatedLinks.assignToMe /* eslint-disable-line vue/no-v-html */"></span> <span v-html="relatedLinks.assignToMe /* eslint-disable-line vue/no-v-html */"></span>
</p> </p>
</section> </section>
......
<script> <script>
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default { export default {
mixins: [glFeatureFlagMixin()],
props: { props: {
value: { value: {
type: String, type: String,
...@@ -20,7 +23,10 @@ export default { ...@@ -20,7 +23,10 @@ export default {
<template> <template>
<li> <li>
<div class="commit-message-editor"> <div class="commit-message-editor">
<div class="d-flex flex-wrap align-items-center justify-content-between"> <div
:class="{ 'gl-mb-3': glFeatures.restructuredMrWidget }"
class="d-flex flex-wrap align-items-center justify-content-between"
>
<label class="col-form-label" :for="inputId"> <label class="col-form-label" :for="inputId">
<strong>{{ label }}</strong> <strong>{{ label }}</strong>
</label> </label>
......
<script> <script>
import { GlButton, GlSprintf } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { escape } from 'lodash'; import { __ } from '~/locale';
import { __, n__, s__ } from '~/locale'; import AddedCommitMessage from '../added_commit_message.vue';
const mergeCommitCount = s__('mrWidgetCommitsAdded|1 merge commit');
export default { export default {
mergeCommitCount,
components: { components: {
GlButton, GlButton,
GlSprintf, AddedCommitMessage,
}, },
props: { props: {
isSquashEnabled: { isSquashEnabled: {
...@@ -39,9 +36,6 @@ export default { ...@@ -39,9 +36,6 @@ export default {
collapseIcon() { collapseIcon() {
return this.expanded ? 'chevron-down' : 'chevron-right'; return this.expanded ? 'chevron-down' : 'chevron-right';
}, },
commitsCountMessage() {
return n__('%d commit', '%d commits', this.isSquashEnabled ? 1 : this.commitsCount);
},
modifyLinkMessage() { modifyLinkMessage() {
if (this.isFastForwardEnabled) return __('Modify commit message'); if (this.isFastForwardEnabled) return __('Modify commit message');
else if (this.isSquashEnabled) return __('Modify commit messages'); else if (this.isSquashEnabled) return __('Modify commit messages');
...@@ -50,16 +44,6 @@ export default { ...@@ -50,16 +44,6 @@ export default {
ariaLabel() { ariaLabel() {
return this.expanded ? __('Collapse') : __('Expand'); return this.expanded ? __('Collapse') : __('Expand');
}, },
targetBranchEscaped() {
return escape(this.targetBranch);
},
message() {
return this.isFastForwardEnabled
? s__('mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}.')
: s__(
'mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}.',
);
},
}, },
methods: { methods: {
toggle() { toggle() {
...@@ -86,17 +70,12 @@ export default { ...@@ -86,17 +70,12 @@ export default {
<span v-if="expanded">{{ __('Collapse') }}</span> <span v-if="expanded">{{ __('Collapse') }}</span>
<span v-else> <span v-else>
<span class="vertical-align-middle"> <span class="vertical-align-middle">
<gl-sprintf :message="message"> <added-commit-message
<template #commitCount> :is-squash-enabled="isSquashEnabled"
<strong class="commits-count-message">{{ commitsCountMessage }}</strong> :is-fast-forward-enabled="isFastForwardEnabled"
</template> :commits-count="commitsCount"
<template #mergeCommitCount> :target-branch="targetBranch"
<strong>{{ $options.mergeCommitCount }}</strong> />
</template>
<template #targetBranch>
<span class="label-branch">{{ targetBranchEscaped }}</span>
</template>
</gl-sprintf>
</span> </span>
<gl-button variant="link" class="modify-message-button"> <gl-button variant="link" class="modify-message-button">
{{ modifyLinkMessage }} {{ modifyLinkMessage }}
......
<script> <script>
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import statusIcon from '../mr_widget_status_icon.vue'; import statusIcon from '../mr_widget_status_icon.vue';
export default { export default {
...@@ -6,11 +7,12 @@ export default { ...@@ -6,11 +7,12 @@ export default {
components: { components: {
statusIcon, statusIcon,
}, },
mixins: [glFeatureFlagMixin()],
}; };
</script> </script>
<template> <template>
<div class="mr-widget-body media"> <div class="mr-widget-body media">
<status-icon :show-disabled-button="true" status="loading" /> <status-icon :show-disabled-button="!glFeatures.restructuredMrWidget" status="loading" />
<div class="media-body space-children"> <div class="media-body space-children">
<span class="bold"> {{ s__('mrWidget|Checking if merge request can be merged…') }} </span> <span class="bold"> {{ s__('mrWidget|Checking if merge request can be merged…') }} </span>
</div> </div>
......
...@@ -37,7 +37,7 @@ export default { ...@@ -37,7 +37,7 @@ export default {
<template> <template>
<div class="mr-widget-body media"> <div class="mr-widget-body media">
<status-icon status="success" /> <status-icon status="success" />
<p class="media-body gl-m-0! gl-font-weight-bold"> <p class="media-body gl-m-0! gl-font-weight-bold gl-text-gray-900!">
<template v-if="canMerge"> <template v-if="canMerge">
{{ __('Ready to merge!') }} {{ __('Ready to merge!') }}
</template> </template>
......
<script> <script>
import { GlIcon, GlTooltipDirective, GlFormCheckbox } from '@gitlab/ui'; import { GlIcon, GlTooltipDirective, GlFormCheckbox, GlLink } from '@gitlab/ui';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { SQUASH_BEFORE_MERGE } from '../../i18n'; import { SQUASH_BEFORE_MERGE } from '../../i18n';
export default { export default {
components: { components: {
GlIcon, GlIcon,
GlFormCheckbox, GlFormCheckbox,
GlLink,
}, },
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
}, },
mixins: [glFeatureFlagsMixin()],
i18n: { i18n: {
...SQUASH_BEFORE_MERGE, ...SQUASH_BEFORE_MERGE,
}, },
...@@ -33,6 +36,9 @@ export default { ...@@ -33,6 +36,9 @@ export default {
tooltipTitle() { tooltipTitle() {
return this.isDisabled ? this.$options.i18n.tooltipTitle : null; return this.isDisabled ? this.$options.i18n.tooltipTitle : null;
}, },
helpIconName() {
return this.glFeatures.restructuredMrWidget ? 'question-o' : 'question';
},
}, },
}; };
</script> </script>
...@@ -51,18 +57,18 @@ export default { ...@@ -51,18 +57,18 @@ export default {
> >
{{ $options.i18n.checkboxLabel }} {{ $options.i18n.checkboxLabel }}
</gl-form-checkbox> </gl-form-checkbox>
<a <gl-link
v-if="helpPath" v-if="helpPath"
v-gl-tooltip v-gl-tooltip
:href="helpPath" :href="helpPath"
:title="$options.i18n.helpLabel" :title="$options.i18n.helpLabel"
:class="{ 'gl-text-blue-600': glFeatures.restructuredMrWidget }"
target="_blank" target="_blank"
rel="noopener noreferrer nofollow"
> >
<gl-icon name="question" /> <gl-icon :name="helpIconName" />
<span class="sr-only"> <span class="sr-only">
{{ $options.i18n.helpLabel }} {{ $options.i18n.helpLabel }}
</span> </span>
</a> </gl-link>
</div> </div>
</template> </template>
...@@ -91,6 +91,7 @@ export default { ...@@ -91,6 +91,7 @@ export default {
MrWidgetApprovals, MrWidgetApprovals,
SecurityReportsApp: () => import('~/vue_shared/security_reports/security_reports_app.vue'), SecurityReportsApp: () => import('~/vue_shared/security_reports/security_reports_app.vue'),
MergeChecksFailed: () => import('./components/states/merge_checks_failed.vue'), MergeChecksFailed: () => import('./components/states/merge_checks_failed.vue'),
ReadyToMerge: ReadyToMergeState,
}, },
apollo: { apollo: {
state: { state: {
...@@ -213,6 +214,9 @@ export default { ...@@ -213,6 +214,9 @@ export default {
window.gon?.features?.refactorMrWidgetsExtensionsUser window.gon?.features?.refactorMrWidgetsExtensionsUser
); );
}, },
isRestructuredMrWidgetEnabled() {
return window.gon?.features?.restructuredMrWidget;
},
}, },
watch: { watch: {
'mr.machineValue': { 'mr.machineValue': {
...@@ -547,12 +551,17 @@ export default { ...@@ -547,12 +551,17 @@ export default {
<div class="mr-widget-section"> <div class="mr-widget-section">
<component :is="componentName" :mr="mr" :service="service" /> <component :is="componentName" :mr="mr" :service="service" />
<ready-to-merge
<div class="mr-widget-info"> v-if="isRestructuredMrWidgetEnabled && mr.commitsCount"
:mr="mr"
:service="service"
/>
<div v-else class="mr-widget-info">
<mr-widget-related-links <mr-widget-related-links
v-if="shouldRenderRelatedLinks" v-if="shouldRenderRelatedLinks"
:state="mr.state" :state="mr.state"
:related-links="mr.relatedLinks" :related-links="mr.relatedLinks"
class="mr-info-list gl-ml-7 gl-pb-5"
/> />
<source-branch-removal-status v-if="shouldRenderSourceBranchRemovalStatus" /> <source-branch-removal-status v-if="shouldRenderSourceBranchRemovalStatus" />
......
...@@ -18,7 +18,9 @@ fragment ReadyToMerge on Project { ...@@ -18,7 +18,9 @@ fragment ReadyToMerge on Project {
commitCount commitCount
diffHeadSha diffHeadSha
userPermissions { userPermissions {
canMerge
removeSourceBranch removeSourceBranch
updateMergeRequest
} }
targetBranch targetBranch
mergeError mergeError
......
import { stateKey } from './state_maps'; import { stateKey } from './state_maps';
export default function deviseState() { export default function deviseState() {
if (this.hasMergeChecksFailed) { if (!this.commitsCount) {
return stateKey.nothingToMerge;
} else if (this.hasMergeChecksFailed && !this.autoMergeEnabled) {
return stateKey.mergeChecksFailed; return stateKey.mergeChecksFailed;
} else if (this.projectArchived) { } else if (this.projectArchived) {
return stateKey.archived; return stateKey.archived;
} else if (this.branchMissing) { } else if (this.branchMissing) {
return stateKey.missingBranch; return stateKey.missingBranch;
} else if (!this.commitsCount) {
return stateKey.nothingToMerge;
} else if (this.mergeStatus === 'unchecked' || this.mergeStatus === 'checking') { } else if (this.mergeStatus === 'unchecked' || this.mergeStatus === 'checking') {
return stateKey.checking; return stateKey.checking;
} else if (this.hasConflicts) { } else if (this.hasConflicts) {
......
...@@ -269,7 +269,9 @@ $tabs-holder-z-index: 250; ...@@ -269,7 +269,9 @@ $tabs-holder-z-index: 250;
} }
.mr-widget-body { .mr-widget-body {
line-height: 28px; &:not(.mr-widget-body-line-height-1) {
line-height: 28px;
}
@include clearfix; @include clearfix;
......
...@@ -469,11 +469,17 @@ export default { ...@@ -469,11 +469,17 @@ export default {
<div class="mr-widget-section"> <div class="mr-widget-section">
<component :is="componentName" :mr="mr" :service="service" /> <component :is="componentName" :mr="mr" :service="service" />
<div class="mr-widget-info"> <ready-to-merge
v-if="isRestructuredMrWidgetEnabled && mr.commitsCount"
:mr="mr"
:service="service"
/>
<div v-else class="mr-widget-info">
<mr-widget-related-links <mr-widget-related-links
v-if="shouldRenderRelatedLinks" v-if="shouldRenderRelatedLinks"
:state="mr.state" :state="mr.state"
:related-links="mr.relatedLinks" :related-links="mr.relatedLinks"
class="mr-info-list gl-ml-7 gl-pb-5"
/> />
<source-branch-removal-status v-if="shouldRenderSourceBranchRemovalStatus" /> <source-branch-removal-status v-if="shouldRenderSourceBranchRemovalStatus" />
......
...@@ -92,7 +92,7 @@ export default class MergeRequestStore extends CEMergeRequestStore { ...@@ -92,7 +92,7 @@ export default class MergeRequestStore extends CEMergeRequestStore {
get hasMergeChecksFailed() { get hasMergeChecksFailed() {
if (!window.gon?.features?.restructuredMrWidget) return false; if (!window.gon?.features?.restructuredMrWidget) return false;
if (this.hasApprovalsAvailable) return !this.isApproved; if (this.hasApprovalsAvailable && this.approvals && this.approvalsLeft) return !this.isApproved;
return super.hasMergeChecksFailed; return super.hasMergeChecksFailed;
} }
......
...@@ -1110,6 +1110,9 @@ msgstr "" ...@@ -1110,6 +1110,9 @@ msgstr ""
msgid "(check progress)" msgid "(check progress)"
msgstr "" msgstr ""
msgid "(commits will be squashed)"
msgstr ""
msgid "(deleted)" msgid "(deleted)"
msgstr "" msgstr ""
...@@ -12424,6 +12427,9 @@ msgstr "" ...@@ -12424,6 +12427,9 @@ msgstr ""
msgid "Edit comment" msgid "Edit comment"
msgstr "" msgstr ""
msgid "Edit commit message"
msgstr ""
msgid "Edit deploy freeze" msgid "Edit deploy freeze"
msgstr "" msgstr ""
...@@ -21588,6 +21594,9 @@ msgstr "" ...@@ -21588,6 +21594,9 @@ msgstr ""
msgid "Merge commit message" msgid "Merge commit message"
msgstr "" msgstr ""
msgid "Merge details"
msgstr ""
msgid "Merge events" msgid "Merge events"
msgstr "" msgstr ""
...@@ -32449,6 +32458,12 @@ msgstr "" ...@@ -32449,6 +32458,12 @@ msgstr ""
msgid "Source branch" msgid "Source branch"
msgstr "" msgstr ""
msgid "Source branch will be deleted."
msgstr ""
msgid "Source branch will not be deleted."
msgstr ""
msgid "Source branch: %{source_branch_open}%{source_branch}%{source_branch_close}" msgid "Source branch: %{source_branch_open}%{source_branch}%{source_branch_close}"
msgstr "" msgstr ""
...@@ -40956,7 +40971,7 @@ msgstr "" ...@@ -40956,7 +40971,7 @@ msgstr ""
msgid "most recent deployment" msgid "most recent deployment"
msgstr "" msgstr ""
msgid "mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}." msgid "mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}%{squashedCommits}."
msgstr "" msgstr ""
msgid "mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}." msgid "mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}."
......
...@@ -9,7 +9,7 @@ exports[`New ready to merge state component renders permission text if canMerge ...@@ -9,7 +9,7 @@ exports[`New ready to merge state component renders permission text if canMerge
/> />
<p <p
class="media-body gl-m-0! gl-font-weight-bold" class="media-body gl-m-0! gl-font-weight-bold gl-text-gray-900!"
> >
Ready to merge by members who can write to the target branch. Ready to merge by members who can write to the target branch.
...@@ -27,7 +27,7 @@ exports[`New ready to merge state component renders permission text if canMerge ...@@ -27,7 +27,7 @@ exports[`New ready to merge state component renders permission text if canMerge
/> />
<p <p
class="media-body gl-m-0! gl-font-weight-bold" class="media-body gl-m-0! gl-font-weight-bold gl-text-gray-900!"
> >
Ready to merge! Ready to merge!
......
import { shallowMount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { GlSprintf } from '@gitlab/ui'; import { GlSprintf } from '@gitlab/ui';
import CommitsHeader from '~/vue_merge_request_widget/components/states/commits_header.vue'; import CommitsHeader from '~/vue_merge_request_widget/components/states/commits_header.vue';
...@@ -6,7 +6,7 @@ describe('Commits header component', () => { ...@@ -6,7 +6,7 @@ describe('Commits header component', () => {
let wrapper; let wrapper;
const createComponent = (props) => { const createComponent = (props) => {
wrapper = shallowMount(CommitsHeader, { wrapper = mount(CommitsHeader, {
stubs: { stubs: {
GlSprintf, GlSprintf,
}, },
......
import { GlFormCheckbox } from '@gitlab/ui'; import { GlFormCheckbox, GlLink } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue'; import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue';
import { SQUASH_BEFORE_MERGE } from '~/vue_merge_request_widget/i18n'; import { SQUASH_BEFORE_MERGE } from '~/vue_merge_request_widget/i18n';
...@@ -77,7 +77,7 @@ describe('Squash before merge component', () => { ...@@ -77,7 +77,7 @@ describe('Squash before merge component', () => {
value: false, value: false,
}); });
const aboutLink = wrapper.find('a'); const aboutLink = wrapper.findComponent(GlLink);
expect(aboutLink.exists()).toBe(false); expect(aboutLink.exists()).toBe(false);
}); });
...@@ -88,7 +88,7 @@ describe('Squash before merge component', () => { ...@@ -88,7 +88,7 @@ describe('Squash before merge component', () => {
helpPath: 'test-path', helpPath: 'test-path',
}); });
const aboutLink = wrapper.find('a'); const aboutLink = wrapper.findComponent(GlLink);
expect(aboutLink.exists()).toBe(true); expect(aboutLink.exists()).toBe(true);
}); });
...@@ -99,7 +99,7 @@ describe('Squash before merge component', () => { ...@@ -99,7 +99,7 @@ describe('Squash before merge component', () => {
helpPath: 'test-path', helpPath: 'test-path',
}); });
const aboutLink = wrapper.find('a'); const aboutLink = wrapper.findComponent(GlLink);
expect(aboutLink.attributes('href')).toEqual('test-path'); expect(aboutLink.attributes('href')).toEqual('test-path');
}); });
......
...@@ -74,6 +74,7 @@ describe('getStateKey', () => { ...@@ -74,6 +74,7 @@ describe('getStateKey', () => {
expect(bound()).toEqual('nothingToMerge'); expect(bound()).toEqual('nothingToMerge');
context.commitsCount = 1;
context.branchMissing = true; context.branchMissing = true;
expect(bound()).toEqual('missingBranch'); expect(bound()).toEqual('missingBranch');
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment