Commit 17e5f87c authored by Himanshu Kapoor's avatar Himanshu Kapoor

Use GlModal for Create Branch Modal in the Web IDE

Migrate the create branch modal in Web IDE to use GlModal. The modal
appears when the branch you're trying to commit on is behind its remote
counterpart.
parent 5cddf3a9
<script>
import { mapState, mapActions, mapGetters } from 'vuex';
import { n__, __ } from '~/locale';
import { GlModal } from '@gitlab/ui';
import LoadingButton from '~/vue_shared/components/loading_button.vue';
import CommitMessageField from './message_field.vue';
import Actions from './actions.vue';
import SuccessMessage from './success_message.vue';
import { leftSidebarViews, MAX_WINDOW_HEIGHT_COMPACT } from '../../constants';
import consts from '../../stores/modules/commit/constants';
export default {
components: {
......@@ -13,6 +15,7 @@ export default {
LoadingButton,
CommitMessageField,
SuccessMessage,
GlModal,
},
data() {
return {
......@@ -54,7 +57,20 @@ export default {
},
methods: {
...mapActions(['updateActivityBarView']),
...mapActions('commit', ['updateCommitMessage', 'discardDraft', 'commitChanges']),
...mapActions('commit', [
'updateCommitMessage',
'discardDraft',
'commitChanges',
'updateCommitAction',
]),
commit() {
return this.commitChanges().catch(() => {
this.$refs.createBranchModal.show();
});
},
forceCreateNewBranch() {
return this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH).then(() => this.commit());
},
toggleIsCompact() {
if (this.currentViewIsCommitView) {
this.isCompact = !this.isCompact;
......@@ -119,13 +135,13 @@ export default {
</button>
<p class="text-center bold">{{ overviewText }}</p>
</div>
<form v-if="!isCompact" ref="formEl" @submit.prevent.stop="commitChanges">
<form v-if="!isCompact" ref="formEl" @submit.prevent.stop="commit">
<transition name="fade"> <success-message v-show="lastCommitMsg" /> </transition>
<commit-message-field
:text="commitMessage"
:placeholder="preBuiltCommitMessage"
@input="updateCommitMessage"
@submit="commitChanges"
@submit="commit"
/>
<div class="clearfix prepend-top-15">
<actions />
......@@ -133,7 +149,7 @@ export default {
:loading="submitCommitLoading"
:label="commitButtonText"
container-class="btn btn-success btn-sm float-left qa-commit-button"
@click="commitChanges"
@click="commit"
/>
<button
v-if="!discardDraftButtonDisabled"
......@@ -152,6 +168,19 @@ export default {
{{ __('Collapse') }}
</button>
</div>
<gl-modal
ref="createBranchModal"
modal-id="ide-create-branch-modal"
:ok-title="__('Create new branch')"
:title="__('Branch has changed')"
ok-variant="success"
@ok="forceCreateNewBranch"
>
{{
__(`This branch has changed since you started editing.
Would you like to create a new branch?`)
}}
</gl-modal>
</form>
</transition>
</div>
......
<script>
import { mapState, mapActions, mapGetters } from 'vuex';
import tooltip from '~/vue_shared/directives/tooltip';
import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue';
import CommitFilesList from './commit_sidebar/list.vue';
import EmptyState from './commit_sidebar/empty_state.vue';
import consts from '../stores/modules/commit/constants';
import { leftSidebarViews, stageKeys } from '../constants';
export default {
components: {
DeprecatedModal,
CommitFilesList,
EmptyState,
},
......@@ -53,10 +50,6 @@ export default {
},
methods: {
...mapActions(['openPendingTab', 'updateViewer', 'updateActivityBarView']),
...mapActions('commit', ['commitChanges', 'updateCommitAction']),
forceCreateNewBranch() {
return this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH).then(() => this.commitChanges());
},
},
stageKeys,
};
......@@ -64,20 +57,6 @@ export default {
<template>
<div class="multi-file-commit-panel-section">
<deprecated-modal
id="ide-create-branch-modal"
:primary-button-label="__('Create new branch')"
:title="__('Branch has changed')"
kind="success"
@submit="forceCreateNewBranch"
>
<template slot="body">
{{
__(`This branch has changed since you started editing.
Would you like to create a new branch?`)
}}
</template>
</deprecated-modal>
<template v-if="showStageUnstageArea">
<commit-files-list
:key-prefix="$options.stageKeys.staged"
......
import $ from 'jquery';
import { sprintf, __ } from '~/locale';
import flash from '~/flash';
import httpStatusCodes from '~/lib/utils/http_status';
import * as rootTypes from '../../mutation_types';
import { createCommitPayload, createNewMergeRequestUrl } from '../../utils';
import router from '../../../ide_router';
......@@ -215,25 +215,23 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
);
})
.catch(err => {
if (err.response.status === 400) {
$('#ide-create-branch-modal').modal('show');
} else {
dispatch(
'setErrorMessage',
{
text: __('An error occurred while committing your changes.'),
action: () =>
dispatch('commitChanges').then(() =>
dispatch('setErrorMessage', null, { root: true }),
),
actionText: __('Please try again'),
},
{ root: true },
);
window.dispatchEvent(new Event('resize'));
}
commit(types.UPDATE_LOADING, false);
// don't catch bad request errors, let the view handle them
if (err.response.status === httpStatusCodes.BAD_REQUEST) throw err;
dispatch(
'setErrorMessage',
{
text: __('An error occurred while committing your changes.'),
action: () =>
dispatch('commitChanges').then(() => dispatch('setErrorMessage', null, { root: true })),
actionText: __('Please try again'),
},
{ root: true },
);
window.dispatchEvent(new Event('resize'));
});
};
......
import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { projectData } from 'jest/ide/mock_data';
import store from '~/ide/stores';
import CommitForm from '~/ide/components/commit_sidebar/form.vue';
......@@ -31,10 +30,10 @@ describe('IDE commit form', () => {
});
describe('compact', () => {
beforeEach(done => {
beforeEach(() => {
vm.isCompact = true;
vm.$nextTick(done);
return vm.$nextTick();
});
it('renders commit button in compact mode', () => {
......@@ -46,95 +45,84 @@ describe('IDE commit form', () => {
expect(vm.$el.querySelector('form')).toBeNull();
});
it('renders overview text', done => {
it('renders overview text', () => {
vm.$store.state.stagedFiles.push('test');
vm.$nextTick(() => {
return vm.$nextTick(() => {
expect(vm.$el.querySelector('p').textContent).toContain('1 changed file');
done();
});
});
it('shows form when clicking commit button', done => {
it('shows form when clicking commit button', () => {
vm.$el.querySelector('.btn-primary').click();
vm.$nextTick(() => {
return vm.$nextTick(() => {
expect(vm.$el.querySelector('form')).not.toBeNull();
done();
});
});
it('toggles activity bar view when clicking commit button', done => {
it('toggles activity bar view when clicking commit button', () => {
vm.$el.querySelector('.btn-primary').click();
vm.$nextTick(() => {
return vm.$nextTick(() => {
expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name);
done();
});
});
it('collapses if lastCommitMsg is set to empty and current view is not commit view', done => {
it('collapses if lastCommitMsg is set to empty and current view is not commit view', () => {
store.state.lastCommitMsg = 'abc';
store.state.currentActivityView = leftSidebarViews.edit.name;
vm.$nextTick(() => {
// if commit message is set, form is uncollapsed
expect(vm.isCompact).toBe(false);
return vm
.$nextTick()
.then(() => {
// if commit message is set, form is uncollapsed
expect(vm.isCompact).toBe(false);
store.state.lastCommitMsg = '';
store.state.lastCommitMsg = '';
vm.$nextTick(() => {
return vm.$nextTick();
})
.then(() => {
// collapsed when set to empty
expect(vm.isCompact).toBe(true);
done();
});
});
});
});
describe('full', () => {
beforeEach(done => {
beforeEach(() => {
vm.isCompact = false;
vm.$nextTick(done);
return vm.$nextTick();
});
it('updates commitMessage in store on input', done => {
it('updates commitMessage in store on input', () => {
const textarea = vm.$el.querySelector('textarea');
textarea.value = 'testing commit message';
textarea.dispatchEvent(new Event('input'));
waitForPromises()
.then(() => {
expect(vm.$store.state.commit.commitMessage).toBe('testing commit message');
})
.then(done)
.catch(done.fail);
return vm.$nextTick().then(() => {
expect(vm.$store.state.commit.commitMessage).toBe('testing commit message');
});
});
it('updating currentActivityView not to commit view sets compact mode', done => {
it('updating currentActivityView not to commit view sets compact mode', () => {
store.state.currentActivityView = 'a';
vm.$nextTick(() => {
return vm.$nextTick(() => {
expect(vm.isCompact).toBe(true);
done();
});
});
it('always opens itself in full view current activity view is not commit view when clicking commit button', done => {
it('always opens itself in full view current activity view is not commit view when clicking commit button', () => {
vm.$el.querySelector('.btn-primary').click();
vm.$nextTick(() => {
return vm.$nextTick(() => {
expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name);
expect(vm.isCompact).toBe(false);
done();
});
});
......@@ -143,41 +131,54 @@ describe('IDE commit form', () => {
expect(vm.$el.querySelector('.btn-default').textContent).toContain('Collapse');
});
it('resets commitMessage when clicking discard button', done => {
it('resets commitMessage when clicking discard button', () => {
vm.$store.state.commit.commitMessage = 'testing commit message';
waitForPromises()
return vm
.$nextTick()
.then(() => {
vm.$el.querySelector('.btn-default').click();
})
.then(Vue.nextTick)
.then(() => vm.$nextTick())
.then(() => {
expect(vm.$store.state.commit.commitMessage).not.toBe('testing commit message');
})
.then(done)
.catch(done.fail);
});
});
});
describe('when submitting', () => {
beforeEach(() => {
jest.spyOn(vm, 'commitChanges').mockImplementation(() => {});
jest.spyOn(vm, 'commitChanges');
vm.$store.state.stagedFiles.push('test');
vm.$store.state.commit.commitMessage = 'testing commit message';
});
it('calls commitChanges', done => {
vm.$store.state.commit.commitMessage = 'testing commit message';
it('calls commitChanges', () => {
vm.commitChanges.mockResolvedValue({ success: true });
return vm.$nextTick().then(() => {
vm.$el.querySelector('.btn-success').click();
expect(vm.commitChanges).toHaveBeenCalled();
});
});
it('opens new branch modal if commitChanges throws an error', () => {
vm.commitChanges.mockRejectedValue({ success: false });
waitForPromises()
jest.spyOn(vm.$refs.createBranchModal, 'show').mockImplementation();
return vm
.$nextTick()
.then(() => {
vm.$el.querySelector('.btn-success').click();
return vm.$nextTick();
})
.then(Vue.nextTick)
.then(() => {
expect(vm.commitChanges).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
expect(vm.$refs.createBranchModal.show).toHaveBeenCalled();
});
});
});
});
......
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