Commit 4d69c73d authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Fixes the flash of text after editing

Adds a loading icon when we are editing
a custom stage, the loader will disappear
once the updated stages have been fetched.

Adds set / clear actions for the saving state

Updates related specs
parent f8f9e71d
...@@ -296,7 +296,11 @@ export default { ...@@ -296,7 +296,11 @@ export default {
/> />
</template> </template>
<template v-if="customStageFormActive" #content> <template v-if="customStageFormActive" #content>
<div v-if="isEditingCustomStage && isSavingCustomStage">
<gl-loading-icon class="mt-4" size="md" />
</div>
<custom-stage-form <custom-stage-form
v-else
:events="formEvents" :events="formEvents"
:is-saving-custom-stage="isSavingCustomStage" :is-saving-custom-stage="isSavingCustomStage"
:initial-fields="formInitialData" :initial-fields="formInitialData"
......
...@@ -179,10 +179,10 @@ export const requestUpdateStage = ({ commit }) => commit(types.REQUEST_UPDATE_ST ...@@ -179,10 +179,10 @@ export const requestUpdateStage = ({ commit }) => commit(types.REQUEST_UPDATE_ST
export const receiveUpdateStageSuccess = ({ commit, dispatch }, updatedData) => { export const receiveUpdateStageSuccess = ({ commit, dispatch }, updatedData) => {
commit(types.RECEIVE_UPDATE_STAGE_SUCCESS); commit(types.RECEIVE_UPDATE_STAGE_SUCCESS);
createFlash(__('Stage data updated'), 'notice'); createFlash(__('Stage data updated'), 'notice');
return Promise.all([ return Promise.resolve()
dispatch('fetchGroupStagesAndEvents'), .then(() => dispatch('fetchGroupStagesAndEvents'))
dispatch('customStages/showEditForm', updatedData), .then(() => dispatch('customStages/showEditForm', updatedData))
]).catch(() => { .catch(() => {
createFlash(__('There was a problem refreshing the data, please try again')); createFlash(__('There was a problem refreshing the data, please try again'));
}); });
}; };
...@@ -209,6 +209,7 @@ export const updateStage = ({ dispatch, state }, { id, ...rest }) => { ...@@ -209,6 +209,7 @@ export const updateStage = ({ dispatch, state }, { id, ...rest }) => {
} = state; } = state;
dispatch('requestUpdateStage'); dispatch('requestUpdateStage');
dispatch('customStages/setSavingCustomStage');
return Api.cycleAnalyticsUpdateStage(id, fullPath, { ...rest }) return Api.cycleAnalyticsUpdateStage(id, fullPath, { ...rest })
.then(({ data }) => dispatch('receiveUpdateStageSuccess', data)) .then(({ data }) => dispatch('receiveUpdateStageSuccess', data))
......
...@@ -31,6 +31,7 @@ export const showEditForm = ({ commit, dispatch }, selectedStage = {}) => { ...@@ -31,6 +31,7 @@ export const showEditForm = ({ commit, dispatch }, selectedStage = {}) => {
commit(types.SET_FORM_INITIAL_DATA, selectedStage); commit(types.SET_FORM_INITIAL_DATA, selectedStage);
commit(types.SHOW_EDIT_FORM); commit(types.SHOW_EDIT_FORM);
dispatch('setSelectedStage', selectedStage, { root: true }); dispatch('setSelectedStage', selectedStage, { root: true });
dispatch('clearSavingCustomStage');
removeFlash(); removeFlash();
}; };
...@@ -39,13 +40,16 @@ export const clearFormErrors = ({ commit }) => { ...@@ -39,13 +40,16 @@ export const clearFormErrors = ({ commit }) => {
removeFlash(); removeFlash();
}; };
export const requestCreateStage = ({ commit }) => commit(types.REQUEST_CREATE_STAGE); export const setSavingCustomStage = ({ commit }) => commit(types.SET_SAVING_CUSTOM_STAGE);
export const clearSavingCustomStage = ({ commit }) => commit(types.CLEAR_SAVING_CUSTOM_STAGE);
export const receiveCreateStageSuccess = ({ commit, dispatch }, { data: { title } }) => { export const receiveCreateStageSuccess = ({ commit, dispatch }, { data: { title } }) => {
commit(types.RECEIVE_CREATE_STAGE_SUCCESS); commit(types.RECEIVE_CREATE_STAGE_SUCCESS);
createFlash(sprintf(__(`Your custom stage '%{title}' was created`), { title }), 'notice'); createFlash(sprintf(__(`Your custom stage '%{title}' was created`), { title }), 'notice');
return Promise.resolve() return Promise.resolve()
.then(() => dispatch('fetchGroupStagesAndEvents', null, { root: true })) .then(() => dispatch('fetchGroupStagesAndEvents', null, { root: true }))
.then(() => dispatch('clearSavingCustomStage'))
.catch(() => { .catch(() => {
createFlash(__('There was a problem refreshing the data, please try again')); createFlash(__('There was a problem refreshing the data, please try again'));
}); });
...@@ -71,7 +75,8 @@ export const createStage = ({ dispatch, rootState }, data) => { ...@@ -71,7 +75,8 @@ export const createStage = ({ dispatch, rootState }, data) => {
selectedGroup: { fullPath }, selectedGroup: { fullPath },
} = rootState; } = rootState;
dispatch('requestCreateStage'); dispatch('clearFormErrors');
dispatch('setSavingCustomStage');
return Api.cycleAnalyticsCreateStage(fullPath, data) return Api.cycleAnalyticsCreateStage(fullPath, data)
.then(response => { .then(response => {
...@@ -80,7 +85,6 @@ export const createStage = ({ dispatch, rootState }, data) => { ...@@ -80,7 +85,6 @@ export const createStage = ({ dispatch, rootState }, data) => {
}) })
.catch(({ response } = {}) => { .catch(({ response } = {}) => {
const { data: { message, errors } = null, status = 400 } = response; const { data: { message, errors } = null, status = 400 } = response;
dispatch('receiveCreateStageError', { data, message, errors, status }); dispatch('receiveCreateStageError', { data, message, errors, status });
}); });
}; };
export const SET_STAGE_EVENTS = 'SET_STAGE_EVENTS'; export const SET_STAGE_EVENTS = 'SET_STAGE_EVENTS';
export const SET_STAGE_FORM_ERRORS = 'SET_STAGE_FORM_ERRORS'; export const SET_STAGE_FORM_ERRORS = 'SET_STAGE_FORM_ERRORS';
export const SET_FORM_INITIAL_DATA = 'SET_FORM_INITIAL_DATA'; export const SET_FORM_INITIAL_DATA = 'SET_FORM_INITIAL_DATA';
export const SET_SAVING_CUSTOM_STAGE = 'SET_SAVING_CUSTOM_STAGE';
export const CLEAR_SAVING_CUSTOM_STAGE = 'CLEAR_SAVING_CUSTOM_STAGE';
export const HIDE_FORM = 'SHOW_FORM'; export const HIDE_FORM = 'SHOW_FORM';
export const SHOW_CREATE_FORM = 'SHOW_CREATE_FORM'; export const SHOW_CREATE_FORM = 'SHOW_CREATE_FORM';
export const SHOW_EDIT_FORM = 'SHOW_EDIT_FORM'; export const SHOW_EDIT_FORM = 'SHOW_EDIT_FORM';
export const CLEAR_FORM_ERRORS = 'CLEAR_FORM_ERRORS'; export const CLEAR_FORM_ERRORS = 'CLEAR_FORM_ERRORS';
export const REQUEST_CREATE_STAGE = 'REQUEST_CREATE_STAGE';
export const RECEIVE_CREATE_STAGE_SUCCESS = 'RECEIVE_CREATE_STAGE_SUCCESS'; export const RECEIVE_CREATE_STAGE_SUCCESS = 'RECEIVE_CREATE_STAGE_SUCCESS';
export const RECEIVE_CREATE_STAGE_ERROR = 'RECEIVE_CREATE_STAGE_ERROR'; export const RECEIVE_CREATE_STAGE_ERROR = 'RECEIVE_CREATE_STAGE_ERROR';
...@@ -28,12 +28,17 @@ export default { ...@@ -28,12 +28,17 @@ export default {
state.formEvents = data.map(ev => convertObjectPropsToCamelCase(ev, { deep: true })); state.formEvents = data.map(ev => convertObjectPropsToCamelCase(ev, { deep: true }));
}, },
[types.SET_STAGE_FORM_ERRORS](state, errors) { [types.SET_STAGE_FORM_ERRORS](state, errors) {
state.isSavingCustomStage = false;
state.formErrors = convertObjectPropsToCamelCase(errors, { deep: true }); state.formErrors = convertObjectPropsToCamelCase(errors, { deep: true });
}, },
[types.SET_FORM_INITIAL_DATA](state, rawStageData = null) { [types.SET_FORM_INITIAL_DATA](state, rawStageData = null) {
state.formInitialData = extractFormFields(rawStageData); state.formInitialData = extractFormFields(rawStageData);
}, },
[types.SET_SAVING_CUSTOM_STAGE](state) {
state.isSavingCustomStage = true;
},
[types.CLEAR_SAVING_CUSTOM_STAGE](state) {
state.isSavingCustomStage = false;
},
[types.SHOW_CREATE_FORM](state) { [types.SHOW_CREATE_FORM](state) {
state.isEditingCustomStage = false; state.isEditingCustomStage = false;
state.isCreatingCustomStage = true; state.isCreatingCustomStage = true;
...@@ -46,7 +51,6 @@ export default { ...@@ -46,7 +51,6 @@ export default {
state.formErrors = null; state.formErrors = null;
}, },
[types.HIDE_FORM](state) { [types.HIDE_FORM](state) {
state.isSavingCustomStage = false;
state.isEditingCustomStage = false; state.isEditingCustomStage = false;
state.isCreatingCustomStage = false; state.isCreatingCustomStage = false;
state.formInitialData = null; state.formInitialData = null;
...@@ -55,15 +59,10 @@ export default { ...@@ -55,15 +59,10 @@ export default {
[types.CLEAR_FORM_ERRORS](state) { [types.CLEAR_FORM_ERRORS](state) {
state.formErrors = null; state.formErrors = null;
}, },
[types.REQUEST_CREATE_STAGE](state) {
state.isSavingCustomStage = true;
state.formErrors = {};
},
[types.RECEIVE_CREATE_STAGE_ERROR](state) { [types.RECEIVE_CREATE_STAGE_ERROR](state) {
state.isSavingCustomStage = false; state.isSavingCustomStage = false;
}, },
[types.RECEIVE_CREATE_STAGE_SUCCESS](state) { [types.RECEIVE_CREATE_STAGE_SUCCESS](state) {
state.isSavingCustomStage = false;
state.formErrors = null; state.formErrors = null;
state.formInitialData = null; state.formInitialData = null;
}, },
......
...@@ -28,7 +28,7 @@ const stageEndpoint = ({ stageId }) => ...@@ -28,7 +28,7 @@ const stageEndpoint = ({ stageId }) =>
jest.mock('~/flash'); jest.mock('~/flash');
describe('Cycle analytics actions', () => { describe.only('Cycle analytics actions', () => {
let state; let state;
let mock; let mock;
...@@ -382,7 +382,7 @@ describe('Cycle analytics actions', () => { ...@@ -382,7 +382,7 @@ describe('Cycle analytics actions', () => {
state = { selectedGroup }; state = { selectedGroup };
}); });
it('dispatches receiveUpdateStageSuccess with put request response data', () => { it('dispatches receiveUpdateStageSuccess and customStages/setSavingCustomStage', () => {
return testAction( return testAction(
actions.updateStage, actions.updateStage,
{ {
...@@ -393,6 +393,7 @@ describe('Cycle analytics actions', () => { ...@@ -393,6 +393,7 @@ describe('Cycle analytics actions', () => {
[], [],
[ [
{ type: 'requestUpdateStage' }, { type: 'requestUpdateStage' },
{ type: 'customStages/setSavingCustomStage' },
{ {
type: 'receiveUpdateStageSuccess', type: 'receiveUpdateStageSuccess',
payload, payload,
...@@ -420,6 +421,7 @@ describe('Cycle analytics actions', () => { ...@@ -420,6 +421,7 @@ describe('Cycle analytics actions', () => {
[], [],
[ [
{ type: 'requestUpdateStage' }, { type: 'requestUpdateStage' },
{ type: 'customStages/setSavingCustomStage' },
{ {
type: 'receiveUpdateStageError', type: 'receiveUpdateStageError',
payload: { payload: {
...@@ -703,7 +705,8 @@ describe('Cycle analytics actions', () => { ...@@ -703,7 +705,8 @@ describe('Cycle analytics actions', () => {
state, state,
[], [],
[ [
{ type: 'requestCreateStage' }, { type: 'clearFormErrors' },
{ type: 'setSavingCustomStage' },
{ {
type: 'receiveCreateStageSuccess', type: 'receiveCreateStageSuccess',
payload: { data: customStageData, status: 201 }, payload: { data: customStageData, status: 201 },
...@@ -740,7 +743,8 @@ describe('Cycle analytics actions', () => { ...@@ -740,7 +743,8 @@ describe('Cycle analytics actions', () => {
state, state,
[], [],
[ [
{ type: 'requestCreateStage' }, { type: 'clearFormErrors' },
{ type: 'setSavingCustomStage' },
{ {
type: 'receiveCreateStageError', type: 'receiveCreateStageError',
payload: { payload: {
...@@ -768,7 +772,12 @@ describe('Cycle analytics actions', () => { ...@@ -768,7 +772,12 @@ describe('Cycle analytics actions', () => {
response, response,
state, state,
[{ type: customStageTypes.RECEIVE_CREATE_STAGE_ERROR }], [{ type: customStageTypes.RECEIVE_CREATE_STAGE_ERROR }],
[{ type: 'setStageFormErrors', payload: {} }], [
{
type: 'setStageFormErrors',
payload: {},
},
],
)); ));
it('will flash an error message', () => { it('will flash an error message', () => {
...@@ -878,7 +887,7 @@ describe('Cycle analytics actions', () => { ...@@ -878,7 +887,7 @@ describe('Cycle analytics actions', () => {
response, response,
state, state,
[{ type: customStageTypes.RECEIVE_CREATE_STAGE_SUCCESS }], [{ type: customStageTypes.RECEIVE_CREATE_STAGE_SUCCESS }],
[{ type: 'fetchGroupStagesAndEvents', payload: null }], [{ type: 'fetchGroupStagesAndEvents', payload: null }, { type: 'clearSavingCustomStage' }],
)); ));
describe('with an error', () => { describe('with an error', () => {
......
...@@ -91,10 +91,9 @@ describe('Cycle analytics mutations', () => { ...@@ -91,10 +91,9 @@ describe('Cycle analytics mutations', () => {
${customStageTypes.SHOW_EDIT_FORM} | ${'isEditingCustomStage'} | ${true} ${customStageTypes.SHOW_EDIT_FORM} | ${'isEditingCustomStage'} | ${true}
${customStageTypes.SHOW_EDIT_FORM} | ${'isCreatingCustomStage'} | ${false} ${customStageTypes.SHOW_EDIT_FORM} | ${'isCreatingCustomStage'} | ${false}
${customStageTypes.SHOW_EDIT_FORM} | ${'formErrors'} | ${null} ${customStageTypes.SHOW_EDIT_FORM} | ${'formErrors'} | ${null}
${customStageTypes.REQUEST_CREATE_STAGE} | ${'isSavingCustomStage'} | ${true}
${customStageTypes.RECEIVE_CREATE_STAGE_SUCCESS} | ${'isSavingCustomStage'} | ${false}
${customStageTypes.RECEIVE_CREATE_STAGE_ERROR} | ${'isSavingCustomStage'} | ${false} ${customStageTypes.RECEIVE_CREATE_STAGE_ERROR} | ${'isSavingCustomStage'} | ${false}
${customStageTypes.SET_STAGE_FORM_ERRORS} | ${'isSavingCustomStage'} | ${false} ${customStageTypes.SET_SAVING_CUSTOM_STAGE} | ${'isSavingCustomStage'} | ${true}
${customStageTypes.CLEAR_SAVING_CUSTOM_STAGE} | ${'isSavingCustomStage'} | ${false}
`('$mutation will set $stateKey=$value', ({ mutation, stateKey, value }) => { `('$mutation will set $stateKey=$value', ({ mutation, stateKey, value }) => {
customStageMutations[mutation](state); customStageMutations[mutation](state);
......
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