Commit e1a3922b authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '349873-Split-rebase-action-buttons-into-two-separate-buttons' into 'master'

Split rebase action buttons into two separate buttons

See merge request gitlab-org/gitlab!81335
parents af5e7e67 5c07dd16
...@@ -3,13 +3,11 @@ import { GlButton, GlSkeletonLoader } from '@gitlab/ui'; ...@@ -3,13 +3,11 @@ import { GlButton, GlSkeletonLoader } from '@gitlab/ui';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { __ } from '~/locale'; import { __ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import ActionsButton from '~/vue_shared/components/actions_button.vue';
import simplePoll from '../../../lib/utils/simple_poll'; import simplePoll from '../../../lib/utils/simple_poll';
import eventHub from '../../event_hub'; import eventHub from '../../event_hub';
import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables';
import rebaseQuery from '../../queries/states/rebase.query.graphql'; import rebaseQuery from '../../queries/states/rebase.query.graphql';
import statusIcon from '../mr_widget_status_icon.vue'; import statusIcon from '../mr_widget_status_icon.vue';
import { REBASE_BUTTON_KEY, REBASE_WITHOUT_CI_BUTTON_KEY } from '../../constants';
export default { export default {
name: 'MRWidgetRebase', name: 'MRWidgetRebase',
...@@ -28,7 +26,6 @@ export default { ...@@ -28,7 +26,6 @@ export default {
components: { components: {
statusIcon, statusIcon,
GlSkeletonLoader, GlSkeletonLoader,
ActionsButton,
GlButton, GlButton,
}, },
mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin], mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
...@@ -47,7 +44,6 @@ export default { ...@@ -47,7 +44,6 @@ export default {
state: {}, state: {},
isMakingRequest: false, isMakingRequest: false,
rebasingError: null, rebasingError: null,
selectedRebaseAction: REBASE_BUTTON_KEY,
}; };
}, },
computed: { computed: {
...@@ -93,28 +89,6 @@ export default { ...@@ -93,28 +89,6 @@ export default {
fastForwardMergeText() { fastForwardMergeText() {
return __('Merge blocked: the source branch must be rebased onto the target branch.'); return __('Merge blocked: the source branch must be rebased onto the target branch.');
}, },
actions() {
return [this.rebaseAction, this.rebaseWithoutCiAction].filter((action) => action);
},
rebaseAction() {
return {
key: REBASE_BUTTON_KEY,
text: __('Rebase'),
secondaryText: __('Rebases and triggers a pipeline'),
attrs: {
'data-qa-selector': 'mr_rebase_button',
},
handle: () => this.rebase(),
};
},
rebaseWithoutCiAction() {
return {
key: REBASE_WITHOUT_CI_BUTTON_KEY,
text: __('Rebase without CI'),
secondaryText: __('Performs a rebase but skips triggering a new pipeline'),
handle: () => this.rebase({ skipCi: true }),
};
},
}, },
methods: { methods: {
rebase({ skipCi = false } = {}) { rebase({ skipCi = false } = {}) {
...@@ -138,8 +112,8 @@ export default { ...@@ -138,8 +112,8 @@ export default {
} }
}); });
}, },
selectRebaseAction(key) { rebaseWithoutCi() {
this.selectedRebaseAction = key; return this.rebase({ skipCi: true });
}, },
checkRebaseStatus(continuePolling, stopPolling) { checkRebaseStatus(continuePolling, stopPolling) {
this.service this.service
...@@ -198,10 +172,10 @@ export default { ...@@ -198,10 +172,10 @@ export default {
> >
<div <div
v-if="!rebaseInProgress && canPushToSourceBranch && !isMakingRequest" v-if="!rebaseInProgress && canPushToSourceBranch && !isMakingRequest"
class="accept-merge-holder clearfix js-toggle-container accept-action media space-children" class="accept-merge-holder clearfix js-toggle-container accept-action media space-children gl-align-items-center"
> >
<gl-button <gl-button
v-if="!glFeatures.restructuredMrWidget && !showRebaseWithoutCi" v-if="!glFeatures.restructuredMrWidget"
:loading="isMakingRequest" :loading="isMakingRequest"
variant="confirm" variant="confirm"
data-qa-selector="mr_rebase_button" data-qa-selector="mr_rebase_button"
...@@ -210,14 +184,16 @@ export default { ...@@ -210,14 +184,16 @@ export default {
> >
{{ __('Rebase') }} {{ __('Rebase') }}
</gl-button> </gl-button>
<actions-button <gl-button
v-if="!glFeatures.restructuredMrWidget && showRebaseWithoutCi" v-if="!glFeatures.restructuredMrWidget && showRebaseWithoutCi"
:actions="actions" :loading="isMakingRequest"
:selected-key="selectedRebaseAction"
variant="confirm" variant="confirm"
category="primary" category="secondary"
@select="selectRebaseAction" data-testid="rebase-without-ci-button"
/> @click="rebaseWithoutCi"
>
{{ __('Rebase without pipeline') }}
</gl-button>
<span <span
v-if="!rebasingError" v-if="!rebasingError"
:class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }" :class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
......
...@@ -166,6 +166,3 @@ export const EXTENSION_SUMMARY_FAILED_CLASS = 'gl-text-red-500'; ...@@ -166,6 +166,3 @@ export const EXTENSION_SUMMARY_FAILED_CLASS = 'gl-text-red-500';
export const EXTENSION_SUMMARY_NEUTRAL_CLASS = 'gl-text-gray-700'; export const EXTENSION_SUMMARY_NEUTRAL_CLASS = 'gl-text-gray-700';
export { STATE_MACHINE }; export { STATE_MACHINE };
export const REBASE_BUTTON_KEY = 'rebase';
export const REBASE_WITHOUT_CI_BUTTON_KEY = 'rebaseWithoutCi';
...@@ -43,7 +43,7 @@ You can also rebase without running a CI/CD pipeline. ...@@ -43,7 +43,7 @@ You can also rebase without running a CI/CD pipeline.
The rebase action is also available as a [quick action command: `/rebase`](../../../topics/git/git_rebase.md#rebase-from-the-gitlab-ui). The rebase action is also available as a [quick action command: `/rebase`](../../../topics/git/git_rebase.md#rebase-from-the-gitlab-ui).
![Fast forward merge request](img/ff_merge_rebase_v14_7.png) ![Fast forward merge request](img/ff_merge_rebase_v14_9.png)
If the target branch is ahead of the source branch and a conflict free rebase is If the target branch is ahead of the source branch and a conflict free rebase is
not possible, you need to rebase the not possible, you need to rebase the
......
...@@ -26531,9 +26531,6 @@ msgstr "" ...@@ -26531,9 +26531,6 @@ msgstr ""
msgid "PerformanceBar|wall" msgid "PerformanceBar|wall"
msgstr "" msgstr ""
msgid "Performs a rebase but skips triggering a new pipeline"
msgstr ""
msgid "Period in seconds" msgid "Period in seconds"
msgstr "" msgstr ""
...@@ -30041,10 +30038,7 @@ msgstr "" ...@@ -30041,10 +30038,7 @@ msgstr ""
msgid "Rebase source branch on the target branch." msgid "Rebase source branch on the target branch."
msgstr "" msgstr ""
msgid "Rebase without CI" msgid "Rebase without pipeline"
msgstr ""
msgid "Rebases and triggers a pipeline"
msgstr "" msgstr ""
msgid "Recaptcha verified?" msgid "Recaptcha verified?"
......
...@@ -2,11 +2,6 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -2,11 +2,6 @@ import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import WidgetRebase from '~/vue_merge_request_widget/components/states/mr_widget_rebase.vue'; import WidgetRebase from '~/vue_merge_request_widget/components/states/mr_widget_rebase.vue';
import eventHub from '~/vue_merge_request_widget/event_hub'; import eventHub from '~/vue_merge_request_widget/event_hub';
import ActionsButton from '~/vue_shared/components/actions_button.vue';
import {
REBASE_BUTTON_KEY,
REBASE_WITHOUT_CI_BUTTON_KEY,
} from '~/vue_merge_request_widget/constants';
let wrapper; let wrapper;
...@@ -38,8 +33,8 @@ function createWrapper(propsData, mergeRequestWidgetGraphql, rebaseWithoutCiUi) ...@@ -38,8 +33,8 @@ function createWrapper(propsData, mergeRequestWidgetGraphql, rebaseWithoutCiUi)
describe('Merge request widget rebase component', () => { describe('Merge request widget rebase component', () => {
const findRebaseMessage = () => wrapper.find('[data-testid="rebase-message"]'); const findRebaseMessage = () => wrapper.find('[data-testid="rebase-message"]');
const findRebaseMessageText = () => findRebaseMessage().text(); const findRebaseMessageText = () => findRebaseMessage().text();
const findRebaseButtonActions = () => wrapper.find(ActionsButton);
const findStandardRebaseButton = () => wrapper.find('[data-testid="standard-rebase-button"]'); const findStandardRebaseButton = () => wrapper.find('[data-testid="standard-rebase-button"]');
const findRebaseWithoutCiButton = () => wrapper.find('[data-testid="rebase-without-ci-button"]');
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
...@@ -112,7 +107,7 @@ describe('Merge request widget rebase component', () => { ...@@ -112,7 +107,7 @@ describe('Merge request widget rebase component', () => {
expect(findRebaseMessageText()).toContain('Something went wrong!'); expect(findRebaseMessageText()).toContain('Something went wrong!');
}); });
describe('Rebase button with flag rebaseWithoutCiUi', () => { describe('Rebase buttons with flag rebaseWithoutCiUi', () => {
beforeEach(() => { beforeEach(() => {
createWrapper( createWrapper(
{ {
...@@ -130,30 +125,13 @@ describe('Merge request widget rebase component', () => { ...@@ -130,30 +125,13 @@ describe('Merge request widget rebase component', () => {
); );
}); });
it('rebase button with actions is rendered', () => { it('renders both buttons', () => {
expect(findRebaseButtonActions().exists()).toBe(true); expect(findRebaseWithoutCiButton().exists()).toBe(true);
expect(findStandardRebaseButton().exists()).toBe(false); expect(findStandardRebaseButton().exists()).toBe(true);
});
it('has rebase and rebase without CI actions', () => {
const actionNames = findRebaseButtonActions()
.props('actions')
.map((action) => action.key);
expect(actionNames).toStrictEqual([REBASE_BUTTON_KEY, REBASE_WITHOUT_CI_BUTTON_KEY]);
});
it('defaults to rebase action', () => {
expect(findRebaseButtonActions().props('selectedKey')).toStrictEqual(REBASE_BUTTON_KEY);
}); });
it('starts the rebase when clicking', async () => { it('starts the rebase when clicking', async () => {
// ActionButtons use the actions props instead of emitting findStandardRebaseButton().vm.$emit('click');
// a click event, therefore simulating the behavior here:
findRebaseButtonActions()
.props('actions')
.find((x) => x.key === REBASE_BUTTON_KEY)
.handle();
await nextTick(); await nextTick();
...@@ -161,12 +139,7 @@ describe('Merge request widget rebase component', () => { ...@@ -161,12 +139,7 @@ describe('Merge request widget rebase component', () => {
}); });
it('starts the CI-skipping rebase when clicking on "Rebase without CI"', async () => { it('starts the CI-skipping rebase when clicking on "Rebase without CI"', async () => {
// ActionButtons use the actions props instead of emitting findRebaseWithoutCiButton().vm.$emit('click');
// a click event, therefore simulating the behavior here:
findRebaseButtonActions()
.props('actions')
.find((x) => x.key === REBASE_WITHOUT_CI_BUTTON_KEY)
.handle();
await nextTick(); await nextTick();
...@@ -193,7 +166,7 @@ describe('Merge request widget rebase component', () => { ...@@ -193,7 +166,7 @@ describe('Merge request widget rebase component', () => {
it('standard rebase button is rendered', () => { it('standard rebase button is rendered', () => {
expect(findStandardRebaseButton().exists()).toBe(true); expect(findStandardRebaseButton().exists()).toBe(true);
expect(findRebaseButtonActions().exists()).toBe(false); expect(findRebaseWithoutCiButton().exists()).toBe(false);
}); });
it('calls rebase method with skip_ci false', () => { it('calls rebase method with skip_ci false', () => {
...@@ -240,7 +213,7 @@ describe('Merge request widget rebase component', () => { ...@@ -240,7 +213,7 @@ describe('Merge request widget rebase component', () => {
}); });
}); });
it('does not render the rebase actions button with rebaseWithoutCiUI flag enabled', () => { it('does not render the "Rebase without pipeline" button with rebaseWithoutCiUI flag enabled', () => {
createWrapper( createWrapper(
{ {
mr: { mr: {
...@@ -254,7 +227,7 @@ describe('Merge request widget rebase component', () => { ...@@ -254,7 +227,7 @@ describe('Merge request widget rebase component', () => {
{ rebaseWithoutCiUi: true }, { rebaseWithoutCiUi: true },
); );
expect(findRebaseButtonActions().exists()).toBe(false); expect(findRebaseWithoutCiButton().exists()).toBe(false);
}); });
it('does not render the standard rebase button with rebaseWithoutCiUI flag disabled', () => { it('does not render the standard rebase button with rebaseWithoutCiUI flag disabled', () => {
......
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