diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue b/ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue index bbac7fd06bcc9a64b36628992a7eadff95e71048..587cb3082ac24c0ef21a47ca2530df7a3826a443 100644 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue +++ b/ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue @@ -63,9 +63,6 @@ export default { 'selectedValueStream', 'pagination', ]), - // NOTE: formEvents are fetched in the same request as the list of stages (fetchGroupStagesAndEvents) - // so i think its ok to bind formEvents here even though its only used as a prop to the custom-stage-form - ...mapState('customStages', ['isCreatingCustomStage', 'formEvents']), ...mapGetters([ 'hasNoAccessError', 'currentGroupPath', @@ -77,7 +74,6 @@ export default { 'isOverviewStageSelected', 'selectedStageCount', ]), - ...mapGetters('customStages', ['customStageFormActive']), shouldRenderEmptyState() { return !this.currentGroup && !this.isLoading; }, @@ -119,7 +115,6 @@ export default { }; }, }, - methods: { ...mapActions([ 'fetchCycleAnalyticsData', @@ -128,18 +123,13 @@ export default { 'setSelectedStage', 'setDefaultSelectedStage', 'setDateRange', - 'removeStage', - 'updateStage', - 'reorderStage', 'updateStageTablePagination', ]), - ...mapActions('customStages', ['hideForm', 'showCreateForm', 'showEditForm', 'createStage']), onProjectsSelect(projects) { this.setSelectedProjects(projects); this.fetchCycleAnalyticsData(); }, onStageSelect(stage) { - this.hideForm(); if (stage.slug === OVERVIEW_STAGE_ID) { this.setDefaultSelectedStage(); } else { @@ -147,25 +137,6 @@ export default { this.fetchStageData(stage.slug); } }, - onShowAddStageForm() { - this.showCreateForm(); - }, - onShowEditStageForm(initData = {}) { - this.setSelectedStage(initData); - this.showEditForm(initData); - }, - onCreateCustomStage(data) { - this.createStage(data); - }, - onUpdateCustomStage(data) { - this.updateStage(data); - }, - onRemoveStage(id) { - this.removeStage(id); - }, - onStageReorder(data) { - this.reorderStage(data); - }, onHandleUpdatePagination(data) { this.updateStageTablePagination(data); }, diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/components/value_stream_form.vue b/ee/app/assets/javascripts/analytics/cycle_analytics/components/value_stream_form.vue index e6af08df6d50c1151f13ec1bd53038a8aa07ca0c..153c83b6eeb00b292dbe3eb81e87469a1a6a2829 100644 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/components/value_stream_form.vue +++ b/ee/app/assets/javascripts/analytics/cycle_analytics/components/value_stream_form.vue @@ -93,8 +93,7 @@ export default { }; }, computed: { - ...mapState({ isCreating: 'isCreatingValueStream' }), - ...mapState('customStages', ['formEvents']), + ...mapState({ isCreating: 'isCreatingValueStream', formEvents: 'formEvents' }), isValueStreamNameValid() { return !this.nameError?.length; }, diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js index 9d257e1ed49836b359e48d8fee8bac2c3230e081..8d852fc3050d72be29e28cc5ebc003e2713a4f39 100644 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js +++ b/ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js @@ -2,12 +2,11 @@ import Api from 'ee/api'; import createFlash from '~/flash'; import { normalizeHeaders, parseIntPagination } from '~/lib/utils/common_utils'; import httpStatus from '~/lib/utils/http_status'; -import { __, sprintf } from '~/locale'; +import { __ } from '~/locale'; import { FETCH_VALUE_STREAM_DATA, OVERVIEW_STAGE_CONFIG } from '../constants'; import { removeFlash, throwIfUserForbidden, - isStageNameExistsError, checkForDataError, flashErrorIfStatusNotOk, } from '../utils'; @@ -215,7 +214,7 @@ export const setDefaultSelectedStage = ({ dispatch }) => export const receiveGroupStagesSuccess = ({ commit }, stages) => commit(types.RECEIVE_GROUP_STAGES_SUCCESS, stages); -export const fetchGroupStagesAndEvents = ({ dispatch, getters }) => { +export const fetchGroupStagesAndEvents = ({ dispatch, commit, getters }) => { const { currentValueStreamId: valueStreamId, currentGroupPath: groupId, @@ -223,7 +222,7 @@ export const fetchGroupStagesAndEvents = ({ dispatch, getters }) => { } = getters; dispatch('requestGroupStages'); - dispatch('customStages/setStageEvents', []); + commit(types.SET_STAGE_EVENTS, []); return Api.cycleAnalyticsGroupStagesAndEvents({ groupId, @@ -235,7 +234,7 @@ export const fetchGroupStagesAndEvents = ({ dispatch, getters }) => { }) .then(({ data: { stages = [], events = [] } }) => { dispatch('receiveGroupStagesSuccess', stages); - dispatch('customStages/setStageEvents', events); + commit(types.SET_STAGE_EVENTS, events); }) .catch((error) => { throwIfUserForbidden(error); @@ -243,89 +242,6 @@ export const fetchGroupStagesAndEvents = ({ dispatch, getters }) => { }); }; -export const requestUpdateStage = ({ commit }) => commit(types.REQUEST_UPDATE_STAGE); -export const receiveUpdateStageSuccess = ({ commit, dispatch }, updatedData) => { - commit(types.RECEIVE_UPDATE_STAGE_SUCCESS); - createFlash({ - message: __('Stage data updated'), - type: 'notice', - }); - return Promise.resolve() - .then(() => dispatch('fetchGroupStagesAndEvents')) - .then(() => dispatch('customStages/showEditForm', updatedData)) - .catch(() => { - createFlash({ - message: __('There was a problem refreshing the data, please try again'), - }); - }); -}; - -export const receiveUpdateStageError = ( - { commit, dispatch }, - { status, responseData: { errors = null } = {}, data = {} }, -) => { - commit(types.RECEIVE_UPDATE_STAGE_ERROR, { errors, data }); - - const { name = null } = data; - const message = - name && isStageNameExistsError({ status, errors }) - ? sprintf(__(`'%{name}' stage already exists`), { name }) - : __('There was a problem saving your custom stage, please try again'); - - createFlash({ - message: __(message), - }); - return dispatch('customStages/setStageFormErrors', errors); -}; - -export const updateStage = ({ dispatch, getters }, { id, ...params }) => { - const { currentGroupPath, currentValueStreamId } = getters; - - dispatch('requestUpdateStage'); - dispatch('customStages/setSavingCustomStage'); - - return Api.cycleAnalyticsUpdateStage({ - groupId: currentGroupPath, - valueStreamId: currentValueStreamId, - stageId: id, - data: params, - }) - .then(({ data }) => dispatch('receiveUpdateStageSuccess', data)) - .catch(({ response: { status = httpStatus.BAD_REQUEST, data: responseData } = {} }) => - dispatch('receiveUpdateStageError', { status, responseData, data: { id, ...params } }), - ); -}; - -export const requestRemoveStage = ({ commit }) => commit(types.REQUEST_REMOVE_STAGE); -export const receiveRemoveStageSuccess = ({ commit, dispatch }) => { - commit(types.RECEIVE_REMOVE_STAGE_RESPONSE); - createFlash({ - message: __('Stage removed'), - type: 'notice', - }); - return dispatch('fetchCycleAnalyticsData'); -}; - -export const receiveRemoveStageError = ({ commit }) => { - commit(types.RECEIVE_REMOVE_STAGE_RESPONSE); - createFlash({ - message: __('There was an error removing your custom stage, please try again'), - }); -}; - -export const removeStage = ({ dispatch, getters }, stageId) => { - const { currentGroupPath, currentValueStreamId } = getters; - dispatch('requestRemoveStage'); - - return Api.cycleAnalyticsRemoveStage({ - groupId: currentGroupPath, - valueStreamId: currentValueStreamId, - stageId, - }) - .then(() => dispatch('receiveRemoveStageSuccess')) - .catch((error) => dispatch('receiveRemoveStageError', error)); -}; - export const initializeCycleAnalyticsSuccess = ({ commit }) => commit(types.INITIALIZE_VALUE_STREAM_SUCCESS); @@ -372,37 +288,6 @@ export const initializeCycleAnalytics = ({ dispatch, commit }, initialData = {}) return dispatch('initializeCycleAnalyticsSuccess'); }; -export const requestReorderStage = ({ commit }) => commit(types.REQUEST_REORDER_STAGE); - -export const receiveReorderStageSuccess = ({ commit }) => - commit(types.RECEIVE_REORDER_STAGE_SUCCESS); - -export const receiveReorderStageError = ({ commit }) => { - commit(types.RECEIVE_REORDER_STAGE_ERROR); - createFlash({ - message: __('There was an error updating the stage order. Please try reloading the page.'), - }); -}; - -export const reorderStage = ({ dispatch, getters }, initialData) => { - dispatch('requestReorderStage'); - const { currentGroupPath, currentValueStreamId } = getters; - const { id, moveAfterId, moveBeforeId } = initialData; - - const params = moveAfterId ? { move_after_id: moveAfterId } : { move_before_id: moveBeforeId }; - - return Api.cycleAnalyticsUpdateStage({ - groupId: currentGroupPath, - valueStreamId: currentValueStreamId, - stageId: id, - data: params, - }) - .then(({ data }) => dispatch('receiveReorderStageSuccess', data)) - .catch(({ response: { status = httpStatus.BAD_REQUEST, data: responseData } = {} }) => - dispatch('receiveReorderStageError', { status, responseData }), - ); -}; - export const receiveCreateValueStreamSuccess = ({ commit, dispatch }, valueStream = {}) => { commit(types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS, valueStream); return dispatch('fetchCycleAnalyticsData'); diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/index.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/index.js index b60072d11428b786dea871a74a3cd0f029d9304c..4dfbe9a0de210846cdf47143fddb36a5fbaaa753 100644 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/index.js +++ b/ee/app/assets/javascripts/analytics/cycle_analytics/store/index.js @@ -3,7 +3,6 @@ import Vuex from 'vuex'; import filters from '~/vue_shared/components/filtered_search_bar/store/modules/filters'; import * as actions from './actions'; import * as getters from './getters'; -import customStages from './modules/custom_stages/index'; import durationChart from './modules/duration_chart/index'; import typeOfWork from './modules/type_of_work/index'; import mutations from './mutations'; @@ -17,5 +16,5 @@ export default () => getters, mutations, state, - modules: { customStages, durationChart, typeOfWork, filters }, + modules: { durationChart, typeOfWork, filters }, }); diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/actions.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/actions.js deleted file mode 100644 index be14e0143b2bf6c6b5046f898380f4525256cb50..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/actions.js +++ /dev/null @@ -1,94 +0,0 @@ -import Api from 'ee/api'; -import createFlash from '~/flash'; -import httpStatusCodes from '~/lib/utils/http_status'; -import { __, sprintf } from '~/locale'; -import { removeFlash, isStageNameExistsError } from '../../../utils'; -import * as types from './mutation_types'; - -export const setStageEvents = ({ commit }, data) => commit(types.SET_STAGE_EVENTS, data); -export const setStageFormErrors = ({ commit }, errors) => - commit(types.SET_STAGE_FORM_ERRORS, errors); - -export const hideForm = ({ commit }) => { - commit(types.HIDE_FORM); - removeFlash(); -}; - -export const showCreateForm = ({ commit }) => { - commit(types.SET_LOADING); - commit(types.SET_FORM_INITIAL_DATA); - commit(types.SHOW_CREATE_FORM); - removeFlash(); -}; - -export const showEditForm = ({ commit, dispatch }, selectedStage = {}) => { - commit(types.SET_LOADING); - commit(types.SET_FORM_INITIAL_DATA, selectedStage); - dispatch('setSelectedStage', selectedStage, { root: true }); - dispatch('clearSavingCustomStage'); - commit(types.SHOW_EDIT_FORM); - removeFlash(); -}; - -export const clearFormErrors = ({ commit }) => { - commit(types.CLEAR_FORM_ERRORS); - removeFlash(); -}; - -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 } }) => { - commit(types.RECEIVE_CREATE_STAGE_SUCCESS); - createFlash({ - message: sprintf(__(`Your custom stage '%{title}' was created`), { title }), - type: 'notice', - }); - - return Promise.resolve() - .then(() => dispatch('fetchGroupStagesAndEvents', null, { root: true })) - .then(() => dispatch('clearSavingCustomStage')) - .catch(() => { - createFlash({ - message: __('There was a problem refreshing the data, please try again'), - }); - }); -}; - -export const receiveCreateStageError = ( - { commit, dispatch }, - { status = httpStatusCodes.BAD_REQUEST, errors = {}, data = {} } = {}, -) => { - commit(types.RECEIVE_CREATE_STAGE_ERROR); - const { name = null } = data; - const flashMessage = - name && isStageNameExistsError({ status, errors }) - ? sprintf(__(`'%{name}' stage already exists`), { name }) - : __('There was a problem saving your custom stage, please try again'); - - createFlash({ - message: flashMessage, - }); - return dispatch('setStageFormErrors', errors); -}; - -export const createStage = ({ dispatch, rootGetters }, data) => { - const { currentGroupPath, currentValueStreamId } = rootGetters; - - dispatch('clearFormErrors'); - dispatch('setSavingCustomStage'); - - return Api.cycleAnalyticsCreateStage({ - groupId: currentGroupPath, - valueStreamId: currentValueStreamId, - data, - }) - .then((response) => { - const { status, data: responseData } = response; - return dispatch('receiveCreateStageSuccess', { status, data: responseData }); - }) - .catch(({ response } = {}) => { - const { data: { message, errors } = null, status = httpStatusCodes.BAD_REQUEST } = response; - dispatch('receiveCreateStageError', { data, message, errors, status }); - }); -}; diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/getters.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/getters.js deleted file mode 100644 index 1f9da872f1e5f0bf9c2de20ea80f27b0a7ca3b44..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/getters.js +++ /dev/null @@ -1,2 +0,0 @@ -export const customStageFormActive = ({ isCreatingCustomStage, isEditingCustomStage }) => - Boolean(isCreatingCustomStage || isEditingCustomStage); diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/index.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/index.js deleted file mode 100644 index 5fd1c80da864e796a269f3cd29394783e8fcd747..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import * as actions from './actions'; -import * as getters from './getters'; -import mutations from './mutations'; -import state from './state'; - -export default { - namespaced: true, - state, - mutations, - getters, - actions, -}; diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutation_types.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutation_types.js deleted file mode 100644 index f079fd9ac41331ccff8a34f0f5ce8dc07625e0d0..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutation_types.js +++ /dev/null @@ -1,14 +0,0 @@ -export const SET_LOADING = 'SET_LOADING'; -export const SET_STAGE_EVENTS = 'SET_STAGE_EVENTS'; -export const SET_STAGE_FORM_ERRORS = 'SET_STAGE_FORM_ERRORS'; -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 = 'HIDE_FORM'; -export const SHOW_CREATE_FORM = 'SHOW_CREATE_FORM'; -export const SHOW_EDIT_FORM = 'SHOW_EDIT_FORM'; -export const CLEAR_FORM_ERRORS = 'CLEAR_FORM_ERRORS'; - -export const RECEIVE_CREATE_STAGE_SUCCESS = 'RECEIVE_CREATE_STAGE_SUCCESS'; -export const RECEIVE_CREATE_STAGE_ERROR = 'RECEIVE_CREATE_STAGE_ERROR'; diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutations.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutations.js deleted file mode 100644 index 3fcddc9e281c17b519539fee20bffc29b90fcd0c..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/mutations.js +++ /dev/null @@ -1,76 +0,0 @@ -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; -import { transformRawStages } from '../../../utils'; -import * as types from './mutation_types'; - -const extractFormFields = (rawStage = {}) => { - const [ - { - id = null, - name = null, - startEventIdentifier = null, - startEventLabel: { id: startEventLabelId = null } = {}, - endEventIdentifier = null, - endEventLabel: { id: endEventLabelId = null } = {}, - }, - ] = transformRawStages([rawStage]); - return { - id, - name, - startEventIdentifier, - startEventLabelId, - endEventIdentifier, - endEventLabelId, - }; -}; - -export default { - [types.SET_STAGE_EVENTS](state, data = []) { - state.formEvents = data.map((ev) => convertObjectPropsToCamelCase(ev, { deep: true })); - }, - [types.SET_STAGE_FORM_ERRORS](state, errors) { - state.formErrors = convertObjectPropsToCamelCase(errors, { deep: true }); - }, - [types.SET_FORM_INITIAL_DATA](state, rawStageData = null) { - state.formInitialData = rawStageData ? extractFormFields(rawStageData) : null; - }, - [types.SET_SAVING_CUSTOM_STAGE](state) { - state.isSavingCustomStage = true; - }, - [types.SET_LOADING](state) { - state.isLoadingCustomStage = true; - }, - [types.CLEAR_SAVING_CUSTOM_STAGE](state) { - state.isSavingCustomStage = false; - }, - [types.SHOW_CREATE_FORM](state) { - state.isLoadingCustomStage = false; - state.isEditingCustomStage = false; - state.isCreatingCustomStage = true; - state.formInitialData = null; - state.formErrors = null; - }, - [types.SHOW_EDIT_FORM](state) { - state.isLoadingCustomStage = false; - state.isCreatingCustomStage = false; - state.isEditingCustomStage = true; - state.formErrors = null; - }, - [types.HIDE_FORM](state) { - state.isEditingCustomStage = false; - state.isCreatingCustomStage = false; - state.formInitialData = null; - state.formErrors = null; - }, - [types.CLEAR_FORM_ERRORS](state) { - state.formErrors = null; - }, - [types.RECEIVE_CREATE_STAGE_ERROR](state) { - state.isSavingCustomStage = false; - state.isCreatingCustomStage = false; - state.isEditingCustomStage = false; - }, - [types.RECEIVE_CREATE_STAGE_SUCCESS](state) { - state.formErrors = null; - state.formInitialData = null; - }, -}; diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/state.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/state.js deleted file mode 100644 index 0523f861f12d9fd6c10bb9cb1bc4ce21a5e30222..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/modules/custom_stages/state.js +++ /dev/null @@ -1,10 +0,0 @@ -export default () => ({ - isLoadingCustomStage: false, - isSavingCustomStage: false, - isCreatingCustomStage: false, - isEditingCustomStage: false, - - formEvents: [], - formErrors: null, - formInitialData: null, -}); diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutation_types.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutation_types.js index 515fb39d1e6d1bec171bf1501d25df294cc06c38..6ce7f845e6c896e024ec0b8a77cdee14535001e0 100644 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutation_types.js +++ b/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutation_types.js @@ -5,6 +5,7 @@ export const SET_SELECTED_STAGE = 'SET_SELECTED_STAGE'; export const SET_DATE_RANGE = 'SET_DATE_RANGE'; export const SET_SELECTED_VALUE_STREAM = 'SET_SELECTED_VALUE_STREAM'; export const SET_PAGINATION = 'SET_PAGINATION'; +export const SET_STAGE_EVENTS = 'SET_STAGE_EVENTS'; export const REQUEST_VALUE_STREAM_DATA = 'REQUEST_VALUE_STREAM_DATA'; export const RECEIVE_VALUE_STREAM_DATA_SUCCESS = 'RECEIVE_VALUE_STREAM_DATA_SUCCESS'; @@ -26,20 +27,9 @@ export const REQUEST_GROUP_STAGES = 'REQUEST_GROUP_STAGES'; export const RECEIVE_GROUP_STAGES_SUCCESS = 'RECEIVE_GROUP_STAGES_SUCCESS'; export const RECEIVE_GROUP_STAGES_ERROR = 'RECEIVE_GROUP_STAGES_ERROR'; -export const REQUEST_UPDATE_STAGE = 'REQUEST_UPDATE_STAGE'; -export const RECEIVE_UPDATE_STAGE_SUCCESS = 'RECEIVE_UPDATE_STAGE_SUCCESS'; -export const RECEIVE_UPDATE_STAGE_ERROR = 'RECEIVE_UPDATE_STAGE_ERROR'; - -export const REQUEST_REMOVE_STAGE = 'REQUEST_REMOVE_STAGE'; -export const RECEIVE_REMOVE_STAGE_RESPONSE = 'RECEIVE_REMOVE_STAGE_RESPONSE'; - export const INITIALIZE_VSA = 'INITIALIZE_VSA'; export const INITIALIZE_VALUE_STREAM_SUCCESS = 'INITIALIZE_VALUE_STREAM_SUCCESS'; -export const REQUEST_REORDER_STAGE = 'REQUEST_REORDER_STAGE'; -export const RECEIVE_REORDER_STAGE_SUCCESS = 'RECEIVE_REORDER_STAGE_SUCCESS'; -export const RECEIVE_REORDER_STAGE_ERROR = 'RECEIVE_REORDER_STAGE_ERROR'; - export const REQUEST_CREATE_VALUE_STREAM = 'REQUEST_CREATE_VALUE_STREAM'; export const RECEIVE_CREATE_VALUE_STREAM_SUCCESS = 'RECEIVE_CREATE_VALUE_STREAM_SUCCESS'; export const RECEIVE_CREATE_VALUE_STREAM_ERROR = 'RECEIVE_CREATE_VALUE_STREAM_ERROR'; diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js index 57eb28f2dcdabd90a89490f3685c2a6f273c1ac6..c56a2d104ff9fba4548bd193194e353002a2d759 100644 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js +++ b/ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js @@ -18,6 +18,9 @@ export default { state.startDate = startDate; state.endDate = endDate; }, + [types.SET_STAGE_EVENTS](state, data = []) { + state.formEvents = data.map((ev) => convertObjectPropsToCamelCase(ev, { deep: true })); + }, [types.REQUEST_VALUE_STREAM_DATA](state) { state.isLoading = true; }, @@ -77,21 +80,6 @@ export default { [types.RECEIVE_GROUP_STAGES_SUCCESS](state, stages) { state.stages = transformRawStages(stages); }, - [types.REQUEST_UPDATE_STAGE](state) { - state.isLoading = true; - }, - [types.RECEIVE_UPDATE_STAGE_SUCCESS](state) { - state.isLoading = false; - }, - [types.RECEIVE_UPDATE_STAGE_ERROR](state) { - state.isLoading = false; - }, - [types.REQUEST_REMOVE_STAGE](state) { - state.isLoading = true; - }, - [types.RECEIVE_REMOVE_STAGE_RESPONSE](state) { - state.isLoading = false; - }, [types.INITIALIZE_VSA]( state, { @@ -121,18 +109,6 @@ export default { [types.INITIALIZE_VALUE_STREAM_SUCCESS](state) { state.isLoading = false; }, - [types.REQUEST_REORDER_STAGE](state) { - state.isSavingStageOrder = true; - state.errorSavingStageOrder = false; - }, - [types.RECEIVE_REORDER_STAGE_SUCCESS](state) { - state.isSavingStageOrder = false; - state.errorSavingStageOrder = false; - }, - [types.RECEIVE_REORDER_STAGE_ERROR](state) { - state.isSavingStageOrder = false; - state.errorSavingStageOrder = true; - }, [types.REQUEST_CREATE_VALUE_STREAM](state) { state.isCreatingValueStream = true; state.createValueStreamErrors = {}; diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/store/state.js b/ee/app/assets/javascripts/analytics/cycle_analytics/store/state.js index 09146a6a87adc8533dd27209a2df97e02936b6cc..76ecb1d4e5da6ec6322af3a39cb7fcb87194e333 100644 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/store/state.js +++ b/ee/app/assets/javascripts/analytics/cycle_analytics/store/state.js @@ -12,9 +12,6 @@ export default () => ({ errorCode: null, - isSavingStageOrder: false, - errorSavingStageOrder: false, - currentGroup: null, selectedProjects: [], selectedStage: null, @@ -31,6 +28,7 @@ export default () => ({ deleteValueStreamError: null, stages: [], + formEvents: [], selectedStageError: '', summary: [], medians: {}, diff --git a/ee/app/assets/javascripts/analytics/cycle_analytics/utils.js b/ee/app/assets/javascripts/analytics/cycle_analytics/utils.js index 7632291d734bb3e293fe44493ba9708413da52d8..cf4918b0436603d19dfd6c71c15d8b63785d74f8 100644 --- a/ee/app/assets/javascripts/analytics/cycle_analytics/utils.js +++ b/ee/app/assets/javascripts/analytics/cycle_analytics/utils.js @@ -18,7 +18,6 @@ import { toYmd } from '../shared/utils'; import { OVERVIEW_STAGE_ID } from './constants'; const EVENT_TYPE_LABEL = 'label'; -const ERROR_NAME_RESERVED = 'is reserved'; export const removeFlash = (type = 'alert') => { const flashEl = document.querySelector(`.flash-${type}`); @@ -358,9 +357,6 @@ export const throwIfUserForbidden = (error) => { } }; -export const isStageNameExistsError = ({ status, errors }) => - status === httpStatus.UNPROCESSABLE_ENTITY && errors?.name?.includes(ERROR_NAME_RESERVED); - export const timeSummaryForPathNavigation = ({ seconds, hours, days, minutes, weeks, months }) => { if (months) { return sprintf(s__('ValueStreamAnalytics|%{value}M'), { diff --git a/ee/app/assets/javascripts/api.js b/ee/app/assets/javascripts/api.js index 98221cddacc52e2d544a8d0fb95063aa5486f001..284fd3e43e96f29e40838a7832a5e5e2b08954e9 100644 --- a/ee/app/assets/javascripts/api.js +++ b/ee/app/assets/javascripts/api.js @@ -22,16 +22,8 @@ export default { cycleAnalyticsValueStreamsPath: '/groups/:id/-/analytics/value_stream_analytics/value_streams', cycleAnalyticsValueStreamPath: '/groups/:id/-/analytics/value_stream_analytics/value_streams/:value_stream_id', - cycleAnalyticsStageEventsPath: - '/groups/:id/-/analytics/value_stream_analytics/value_streams/:value_stream_id/stages/:stage_id/records', - cycleAnalyticsStageMedianPath: - '/groups/:id/-/analytics/value_stream_analytics/value_streams/:value_stream_id/stages/:stage_id/median', - cycleAnalyticsStageCountPath: - '/groups/:id/-/analytics/value_stream_analytics/value_streams/:value_stream_id/stages/:stage_id/count', cycleAnalyticsStagePath: '/groups/:id/-/analytics/value_stream_analytics/value_streams/:value_stream_id/stages/:stage_id', - cycleAnalyticsDurationChartPath: - '/groups/:id/-/analytics/value_stream_analytics/value_streams/:value_stream_id/stages/:stage_id/average_duration_chart', cycleAnalyticsGroupLabelsPath: '/groups/:namespace_path/-/labels.json', codeReviewAnalyticsPath: '/api/:version/analytics/code_review', groupActivityIssuesPath: '/api/:version/analytics/group_activity/issues_count', @@ -172,40 +164,23 @@ export default { }, cycleAnalyticsStageEvents({ groupId, valueStreamId, stageId, params = {} }) { - const url = Api.buildUrl(this.cycleAnalyticsStageEventsPath) - .replace(':id', groupId) - .replace(':value_stream_id', valueStreamId) - .replace(':stage_id', stageId); - + const stageBase = this.cycleAnalyticsStageUrl({ groupId, valueStreamId, stageId }); + const url = `${stageBase}/records`; return axios.get(url, { params }); }, cycleAnalyticsStageMedian({ groupId, valueStreamId, stageId, params = {} }) { - const url = Api.buildUrl(this.cycleAnalyticsStageMedianPath) - .replace(':id', groupId) - .replace(':value_stream_id', valueStreamId) - .replace(':stage_id', stageId); - + const stageBase = this.cycleAnalyticsStageUrl({ groupId, valueStreamId, stageId }); + const url = `${stageBase}/median`; return axios.get(url, { params }); }, cycleAnalyticsStageCount({ groupId, valueStreamId, stageId, params = {} }) { - const url = Api.buildUrl(this.cycleAnalyticsStageCountPath) - .replace(':id', groupId) - .replace(':value_stream_id', valueStreamId) - .replace(':stage_id', stageId); - + const stageBase = this.cycleAnalyticsStageUrl({ groupId, valueStreamId, stageId }); + const url = `${stageBase}/count`; return axios.get(url, { params }); }, - cycleAnalyticsCreateStage({ groupId, valueStreamId, data }) { - const url = Api.buildUrl(this.cycleAnalyticsGroupStagesAndEventsPath) - .replace(':id', groupId) - .replace(':value_stream_id', valueStreamId); - - return axios.post(url, data); - }, - cycleAnalyticsCreateValueStream(groupId, data) { const url = Api.buildUrl(this.cycleAnalyticsValueStreamsPath).replace(':id', groupId); return axios.post(url, data); @@ -237,27 +212,10 @@ export default { .replace(':stage_id', stageId); }, - cycleAnalyticsUpdateStage({ groupId, valueStreamId, stageId, data }) { - const url = this.cycleAnalyticsStageUrl({ groupId, valueStreamId, stageId }); - - return axios.put(url, data); - }, - - cycleAnalyticsRemoveStage({ groupId, valueStreamId, stageId }) { - const url = this.cycleAnalyticsStageUrl({ groupId, valueStreamId, stageId }); - - return axios.delete(url); - }, - cycleAnalyticsDurationChart({ groupId, valueStreamId, stageId, params = {} }) { - const url = Api.buildUrl(this.cycleAnalyticsDurationChartPath) - .replace(':id', groupId) - .replace(':value_stream_id', valueStreamId) - .replace(':stage_id', stageId); - - return axios.get(url, { - params, - }); + const stageBase = this.cycleAnalyticsStageUrl({ groupId, valueStreamId, stageId }); + const url = `${stageBase}/average_duration_chart`; + return axios.get(url, { params }); }, cycleAnalyticsGroupLabels(groupId, params = { search: null }) { diff --git a/ee/spec/frontend/analytics/cycle_analytics/components/value_stream_form_spec.js b/ee/spec/frontend/analytics/cycle_analytics/components/value_stream_form_spec.js index 99f0bdf9720c67823ef5fe036fc2b51f73b5acc0..625497f9de91044700881fc07bfbb48af6022f44 100644 --- a/ee/spec/frontend/analytics/cycle_analytics/components/value_stream_form_spec.js +++ b/ee/spec/frontend/analytics/cycle_analytics/components/value_stream_form_spec.js @@ -48,19 +48,12 @@ describe('ValueStreamForm', () => { new Vuex.Store({ state: { isCreatingValueStream: false, + formEvents, }, actions: { createValueStream: createValueStreamMock, updateValueStream: updateValueStreamMock, }, - modules: { - customStages: { - namespaced: true, - state: { - formEvents, - }, - }, - }, }); const createComponent = ({ props = {}, data = {}, stubs = {} } = {}) => diff --git a/ee/spec/frontend/analytics/cycle_analytics/mock_data.js b/ee/spec/frontend/analytics/cycle_analytics/mock_data.js index 9988d39de0ffb174bc065820939691fccd159f4f..260b298f0e152afa3b0c68fd95a140a2756a751b 100644 --- a/ee/spec/frontend/analytics/cycle_analytics/mock_data.js +++ b/ee/spec/frontend/analytics/cycle_analytics/mock_data.js @@ -213,13 +213,6 @@ export const labelStopEvent = customStageLabelEvents.find( (ev) => ev.identifier === labelStartEvent.allowedEndEvents[0], ); -export const rawCustomStageFormErrors = { - name: ['is reserved', 'cant be blank'], - start_event_identifier: ['cant be blank'], -}; - -export const customStageFormErrors = convertObjectPropsToCamelCase(rawCustomStageFormErrors); - const dateRange = getDatesInRange(startDate, endDate, toYmd); export const apiTasksByTypeData = getJSONFixture( diff --git a/ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js b/ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js index c6a440c235c5099cae627a6943b53a876d04b527..6525deb205ac6dbe4297370ddd189b3d0593bddc 100644 --- a/ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js +++ b/ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js @@ -45,9 +45,6 @@ const mockGetters = { currentValueStreamId: () => selectedValueStream.id, }; -const stageEndpoint = ({ stageId }) => - `/groups/${currentGroup.fullPath}/-/analytics/value_stream_analytics/value_streams/${selectedValueStream.id}/stages/${stageId}`; - jest.mock('~/flash'); describe('Value Stream Analytics actions', () => { @@ -422,248 +419,6 @@ describe('Value Stream Analytics actions', () => { }); }); - describe('updateStage', () => { - const stageId = 'cool-stage'; - const payload = { hidden: true }; - - beforeEach(() => { - mock.onPut(stageEndpoint({ stageId }), payload).replyOnce(httpStatusCodes.OK, payload); - }); - - it('dispatches receiveUpdateStageSuccess and customStages/setSavingCustomStage', () => { - return testAction( - actions.updateStage, - { - id: stageId, - ...payload, - }, - state, - [], - [ - { type: 'requestUpdateStage' }, - { type: 'customStages/setSavingCustomStage' }, - { - type: 'receiveUpdateStageSuccess', - payload, - }, - ], - ); - }); - - describe('with a failed request', () => { - beforeEach(() => { - mock = new MockAdapter(axios); - mock.onPut(stageEndpoint({ stageId })).replyOnce(httpStatusCodes.NOT_FOUND); - }); - - it('dispatches receiveUpdateStageError', () => { - const data = { - id: stageId, - name: 'issue', - ...payload, - }; - return testAction( - actions.updateStage, - data, - state, - [], - [ - { type: 'requestUpdateStage' }, - { type: 'customStages/setSavingCustomStage' }, - { - type: 'receiveUpdateStageError', - payload: { - status: httpStatusCodes.NOT_FOUND, - data, - }, - }, - ], - ); - }); - - it('flashes an error if the stage name already exists', () => { - return actions - .receiveUpdateStageError( - { - commit: () => {}, - dispatch: () => Promise.resolve(), - state, - }, - { - status: httpStatusCodes.UNPROCESSABLE_ENTITY, - responseData: { - errors: { name: ['is reserved'] }, - }, - data: { - name: stageId, - }, - }, - ) - .then(() => { - expect(createFlash).toHaveBeenCalledWith({ - message: `'${stageId}' stage already exists`, - }); - }); - }); - - it('flashes an error message', () => { - return actions - .receiveUpdateStageError( - { - dispatch: () => Promise.resolve(), - commit: () => {}, - state, - }, - { status: httpStatusCodes.BAD_REQUEST }, - ) - .then(() => { - expect(createFlash).toHaveBeenCalledWith({ - message: 'There was a problem saving your custom stage, please try again', - }); - }); - }); - }); - - describe('receiveUpdateStageSuccess', () => { - const response = { - title: 'NEW - COOL', - }; - - it('will dispatch fetchGroupStagesAndEvents', () => - testAction( - actions.receiveUpdateStageSuccess, - response, - state, - [{ type: types.RECEIVE_UPDATE_STAGE_SUCCESS }], - [ - { type: 'fetchGroupStagesAndEvents' }, - { type: 'customStages/showEditForm', payload: response }, - ], - )); - - it('will flash a success message', () => { - return actions - .receiveUpdateStageSuccess( - { - dispatch: () => {}, - commit: () => {}, - }, - response, - ) - .then(() => { - expect(createFlash).toHaveBeenCalledWith({ - message: 'Stage data updated', - type: 'notice', - }); - }); - }); - - describe('with an error', () => { - it('will flash an error message', () => - actions - .receiveUpdateStageSuccess( - { - dispatch: () => Promise.reject(), - commit: () => {}, - }, - response, - ) - .then(() => { - expect(createFlash).toHaveBeenCalledWith({ - message: 'There was a problem refreshing the data, please try again', - }); - })); - }); - }); - }); - - describe('removeStage', () => { - const stageId = 'cool-stage'; - - beforeEach(() => { - mock.onDelete(stageEndpoint({ stageId })).replyOnce(httpStatusCodes.OK); - }); - - it('dispatches receiveRemoveStageSuccess with put request response data', () => { - return testAction( - actions.removeStage, - stageId, - state, - [], - [ - { type: 'requestRemoveStage' }, - { - type: 'receiveRemoveStageSuccess', - }, - ], - ); - }); - - describe('with a failed request', () => { - beforeEach(() => { - mock = new MockAdapter(axios); - mock.onDelete(stageEndpoint({ stageId })).replyOnce(httpStatusCodes.NOT_FOUND); - }); - - it('dispatches receiveRemoveStageError', () => { - return testAction( - actions.removeStage, - stageId, - state, - [], - [ - { type: 'requestRemoveStage' }, - { - type: 'receiveRemoveStageError', - payload: error, - }, - ], - ); - }); - - it('flashes an error message', () => { - actions.receiveRemoveStageError({ commit: () => {}, state }, {}); - expect(createFlash).toHaveBeenCalledWith({ - message: 'There was an error removing your custom stage, please try again', - }); - }); - }); - }); - - describe('receiveRemoveStageSuccess', () => { - const stageId = 'cool-stage'; - - beforeEach(() => { - mock.onDelete(stageEndpoint({ stageId })).replyOnce(httpStatusCodes.OK); - state = { currentGroup }; - }); - - it('dispatches fetchCycleAnalyticsData', () => { - return testAction( - actions.receiveRemoveStageSuccess, - stageId, - state, - [{ type: 'RECEIVE_REMOVE_STAGE_RESPONSE' }], - [{ type: 'fetchCycleAnalyticsData' }], - ); - }); - - it('flashes a success message', () => { - return actions - .receiveRemoveStageSuccess( - { - dispatch: () => Promise.resolve(), - commit: () => {}, - state, - }, - {}, - ) - .then(() => - expect(createFlash).toHaveBeenCalledWith({ message: 'Stage removed', type: 'notice' }), - ); - }); - }); - describe('fetchStageMedianValues', () => { let mockDispatch = jest.fn(); const fetchMedianResponse = activeStages.map(({ slug: id }) => ({ events: [], id })); @@ -900,80 +655,6 @@ describe('Value Stream Analytics actions', () => { )); }); - describe('reorderStage', () => { - const stageId = 'cool-stage'; - const payload = { id: stageId, move_after_id: '2', move_before_id: '8' }; - - describe('with no errors', () => { - beforeEach(() => { - mock.onPut(stageEndpoint({ stageId })).replyOnce(httpStatusCodes.OK); - }); - - it(`dispatches the ${types.REQUEST_REORDER_STAGE} and ${types.RECEIVE_REORDER_STAGE_SUCCESS} actions`, () => { - return testAction( - actions.reorderStage, - payload, - state, - [], - [{ type: 'requestReorderStage' }, { type: 'receiveReorderStageSuccess' }], - ); - }); - }); - - describe('with errors', () => { - beforeEach(() => { - mock.onPut(stageEndpoint({ stageId })).replyOnce(httpStatusCodes.NOT_FOUND); - }); - - it(`dispatches the ${types.REQUEST_REORDER_STAGE} and ${types.RECEIVE_REORDER_STAGE_ERROR} actions `, () => { - return testAction( - actions.reorderStage, - payload, - state, - [], - [ - { type: 'requestReorderStage' }, - { type: 'receiveReorderStageError', payload: { status: httpStatusCodes.NOT_FOUND } }, - ], - ); - }); - }); - }); - - describe('receiveReorderStageError', () => { - beforeEach(() => {}); - - it(`commits the ${types.RECEIVE_REORDER_STAGE_ERROR} mutation and flashes an error`, () => { - return testAction( - actions.receiveReorderStageError, - null, - state, - [ - { - type: types.RECEIVE_REORDER_STAGE_ERROR, - }, - ], - [], - ).then(() => { - expect(createFlash).toHaveBeenCalledWith({ - message: 'There was an error updating the stage order. Please try reloading the page.', - }); - }); - }); - }); - - describe('receiveReorderStageSuccess', () => { - it(`commits the ${types.RECEIVE_REORDER_STAGE_SUCCESS} mutation`, () => { - return testAction( - actions.receiveReorderStageSuccess, - null, - state, - [{ type: types.RECEIVE_REORDER_STAGE_SUCCESS }], - [], - ); - }); - }); - describe('createValueStream', () => { const payload = { name: 'cool value stream', diff --git a/ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/actions_spec.js b/ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/actions_spec.js deleted file mode 100644 index a48c50af5731e5dbfc0b19e234f3b39461a2b964..0000000000000000000000000000000000000000 --- a/ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/actions_spec.js +++ /dev/null @@ -1,260 +0,0 @@ -import axios from 'axios'; -import MockAdapter from 'axios-mock-adapter'; -import * as actions from 'ee/analytics/cycle_analytics/store/modules/custom_stages/actions'; -import * as types from 'ee/analytics/cycle_analytics/store/modules/custom_stages/mutation_types'; -import testAction from 'helpers/vuex_action_helper'; -import createFlash from '~/flash'; -import httpStatusCodes from '~/lib/utils/http_status'; -import { currentGroup, endpoints, rawCustomStage } from '../../../mock_data'; - -jest.mock('~/flash'); - -describe('Custom stage actions', () => { - let state; - let mock; - const selectedStage = rawCustomStage; - - beforeEach(() => { - mock = new MockAdapter(axios); - }); - - afterEach(() => { - mock.restore(); - state = { currentGroup: null }; - }); - - describe('createStage', () => { - describe('with valid data', () => { - const customStageData = { - startEventIdentifier: 'start_event', - endEventIdentifier: 'end_event', - name: 'cool-new-stage', - }; - - beforeEach(() => { - state = { ...state, currentGroup }; - mock.onPost(endpoints.baseStagesEndpointstageData).reply(201, customStageData); - }); - - it(`dispatches the 'receiveCreateStageSuccess' action`, () => - testAction( - actions.createStage, - customStageData, - state, - [], - [ - { type: 'clearFormErrors' }, - { type: 'setSavingCustomStage' }, - { - type: 'receiveCreateStageSuccess', - payload: { data: customStageData, status: 201 }, - }, - ], - )); - }); - - describe('with errors', () => { - const message = 'failed'; - const errors = { - endEventIdentifier: ['Cant be blank'], - }; - const customStageData = { - startEventIdentifier: 'start_event', - endEventIdentifier: '', - name: 'cool-new-stage', - }; - - beforeEach(() => { - state = { ...state, currentGroup }; - mock - .onPost(endpoints.baseStagesEndpointstageData) - .reply(httpStatusCodes.UNPROCESSABLE_ENTITY, { - message, - errors, - }); - }); - - it(`dispatches the 'receiveCreateStageError' action`, () => - testAction( - actions.createStage, - customStageData, - state, - [], - [ - { type: 'clearFormErrors' }, - { type: 'setSavingCustomStage' }, - { - type: 'receiveCreateStageError', - payload: { - data: customStageData, - errors, - message, - status: httpStatusCodes.UNPROCESSABLE_ENTITY, - }, - }, - ], - )); - }); - }); - - describe('receiveCreateStageError', () => { - const response = { - data: { name: 'uh oh' }, - }; - - beforeEach(() => {}); - - it('will commit the RECEIVE_CREATE_STAGE_ERROR mutation', () => - testAction( - actions.receiveCreateStageError, - response, - state, - [{ type: types.RECEIVE_CREATE_STAGE_ERROR }], - [{ type: 'setStageFormErrors', payload: {} }], - )); - - it('will flash an error message', () => { - return actions - .receiveCreateStageError( - { - dispatch: () => Promise.resolve(), - commit: () => {}, - }, - response, - ) - .then(() => { - expect(createFlash).toHaveBeenCalledWith({ - message: 'There was a problem saving your custom stage, please try again', - }); - }); - }); - - describe('with a stage name error', () => { - it('will flash an error message', () => { - return actions - .receiveCreateStageError( - { - dispatch: () => Promise.resolve(), - commit: () => {}, - }, - { - ...response, - status: httpStatusCodes.UNPROCESSABLE_ENTITY, - errors: { name: ['is reserved'] }, - }, - ) - .then(() => { - expect(createFlash).toHaveBeenCalledWith({ message: "'uh oh' stage already exists" }); - }); - }); - }); - }); - - describe('receiveCreateStageSuccess', () => { - const response = { - data: { - title: 'COOL', - }, - }; - - it('will dispatch fetchGroupStagesAndEvents', () => - testAction( - actions.receiveCreateStageSuccess, - response, - state, - [{ type: types.RECEIVE_CREATE_STAGE_SUCCESS }], - [{ type: 'fetchGroupStagesAndEvents', payload: null }, { type: 'clearSavingCustomStage' }], - )); - - describe('with an error', () => { - it('will flash an error message', () => - actions - .receiveCreateStageSuccess( - { - dispatch: () => Promise.reject(), - commit: () => {}, - }, - response, - ) - .then(() => { - expect(createFlash).toHaveBeenCalledWith({ - message: 'There was a problem refreshing the data, please try again', - }); - })); - }); - }); - - describe('setStageFormErrors', () => { - it('commits the "SET_STAGE_FORM_ERRORS" mutation', () => { - return testAction( - actions.setStageFormErrors, - [], - state, - [{ type: types.SET_STAGE_FORM_ERRORS, payload: [] }], - [], - ); - }); - }); - - describe('clearFormErrors', () => { - it('commits the "CLEAR_FORM_ERRORS" mutation', () => { - return testAction( - actions.clearFormErrors, - [], - state, - [{ type: types.CLEAR_FORM_ERRORS }], - [], - ); - }); - }); - - describe('setStageEvents', () => { - it('commits the "SET_STAGE_EVENTS" mutation', () => { - return testAction( - actions.setStageEvents, - [], - state, - [{ type: types.SET_STAGE_EVENTS, payload: [] }], - [], - ); - }); - }); - - describe('hideForm', () => { - it('commits the "HIDE_FORM" mutation', () => { - return testAction(actions.hideForm, null, state, [{ type: types.HIDE_FORM }], []); - }); - }); - - describe('showCreateForm', () => { - it('commits the "SHOW_CREATE_FORM" mutation', () => { - return testAction( - actions.showCreateForm, - null, - state, - [ - { type: types.SET_LOADING }, - { type: types.SET_FORM_INITIAL_DATA }, - { type: types.SHOW_CREATE_FORM }, - ], - [], - ); - }); - }); - - describe('showEditForm', () => { - it('commits the "SHOW_EDIT_FORM" mutation with initial data', () => { - return testAction( - actions.showEditForm, - selectedStage, - state, - [ - { type: types.SET_LOADING }, - { type: types.SET_FORM_INITIAL_DATA, payload: rawCustomStage }, - { type: types.SHOW_EDIT_FORM }, - ], - [{ type: 'setSelectedStage', payload: rawCustomStage }, { type: 'clearSavingCustomStage' }], - ); - }); - }); -}); diff --git a/ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/getters_spec.js b/ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/getters_spec.js deleted file mode 100644 index 85480021a5bafa09307c85f178b2075a93d1cb48..0000000000000000000000000000000000000000 --- a/ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/getters_spec.js +++ /dev/null @@ -1,15 +0,0 @@ -import * as getters from 'ee/analytics/cycle_analytics/store/modules/custom_stages/getters'; - -describe('Custom stages getters', () => { - describe.each` - state | result - ${{ isCreatingCustomStage: true, isEditingCustomStage: true }} | ${true} - ${{ isCreatingCustomStage: false, isEditingCustomStage: true }} | ${true} - ${{ isCreatingCustomStage: true, isEditingCustomStage: false }} | ${true} - ${{ isCreatingCustomStage: false, isEditingCustomStage: false }} | ${false} - `('customStageFormActive', ({ state, result }) => { - it(`with state ${state} returns ${result}`, () => { - expect(getters.customStageFormActive(state)).toEqual(result); - }); - }); -}); diff --git a/ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/mutations_spec.js b/ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/mutations_spec.js deleted file mode 100644 index af1adfebf0f4fb0ab697cca5e62f838a7c8cb282..0000000000000000000000000000000000000000 --- a/ee/spec/frontend/analytics/cycle_analytics/store/modules/custom_stages/mutations_spec.js +++ /dev/null @@ -1,78 +0,0 @@ -import * as types from 'ee/analytics/cycle_analytics/store/modules/custom_stages/mutation_types'; -import mutations from 'ee/analytics/cycle_analytics/store/modules/custom_stages/mutations'; -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; -import { rawCustomStageEvents, camelCasedStageEvents, rawCustomStage } from '../../../mock_data'; - -let state = null; - -describe('Custom stage mutations', () => { - beforeEach(() => { - state = {}; - }); - - afterEach(() => { - state = null; - }); - - it.each` - mutation | stateKey | value - ${types.HIDE_FORM} | ${'isCreatingCustomStage'} | ${false} - ${types.HIDE_FORM} | ${'isEditingCustomStage'} | ${false} - ${types.HIDE_FORM} | ${'formErrors'} | ${null} - ${types.HIDE_FORM} | ${'formInitialData'} | ${null} - ${types.CLEAR_FORM_ERRORS} | ${'formErrors'} | ${null} - ${types.SHOW_CREATE_FORM} | ${'isCreatingCustomStage'} | ${true} - ${types.SHOW_CREATE_FORM} | ${'isEditingCustomStage'} | ${false} - ${types.SHOW_CREATE_FORM} | ${'formErrors'} | ${null} - ${types.SHOW_CREATE_FORM} | ${'formInitialData'} | ${null} - ${types.SHOW_EDIT_FORM} | ${'isEditingCustomStage'} | ${true} - ${types.SHOW_EDIT_FORM} | ${'isCreatingCustomStage'} | ${false} - ${types.SHOW_EDIT_FORM} | ${'formErrors'} | ${null} - ${types.RECEIVE_CREATE_STAGE_SUCCESS} | ${'formErrors'} | ${null} - ${types.RECEIVE_CREATE_STAGE_SUCCESS} | ${'formInitialData'} | ${null} - ${types.RECEIVE_CREATE_STAGE_ERROR} | ${'isSavingCustomStage'} | ${false} - ${types.SET_SAVING_CUSTOM_STAGE} | ${'isSavingCustomStage'} | ${true} - ${types.CLEAR_SAVING_CUSTOM_STAGE} | ${'isSavingCustomStage'} | ${false} - ${types.SET_LOADING} | ${'isLoadingCustomStage'} | ${true} - `('$mutation will set $stateKey=$value', ({ mutation, stateKey, value }) => { - mutations[mutation](state); - - expect(state[stateKey]).toEqual(value); - }); - - describe(`${types.SET_STAGE_EVENTS}`, () => { - it('will set formEvents', () => { - state = {}; - mutations[types.SET_STAGE_EVENTS](state, rawCustomStageEvents); - expect(state.formEvents).toEqual(camelCasedStageEvents); - }); - }); - - describe(`${types.SET_STAGE_FORM_ERRORS}`, () => { - const mockFormError = { start_identifier: ['Cant be blank'] }; - it('will set formErrors', () => { - state = {}; - mutations[types.SET_STAGE_FORM_ERRORS](state, mockFormError); - - expect(state.formErrors).toEqual(convertObjectPropsToCamelCase(mockFormError)); - }); - }); - - describe(`${types.SET_FORM_INITIAL_DATA}`, () => { - const mockStage = { - endEventIdentifier: 'issue_first_added_to_board', - endEventLabelId: null, - id: 18, - name: 'Coolest beans stage', - startEventIdentifier: 'issue_first_mentioned_in_commit', - startEventLabelId: null, - }; - - it('will set formInitialData', () => { - state = {}; - mutations[types.SET_FORM_INITIAL_DATA](state, rawCustomStage); - - expect(state.formInitialData).toEqual(mockStage); - }); - }); -}); diff --git a/ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js b/ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js index a4b47248166b6ea30dff842afad04598c9b7f22a..30017153a35dcfb2f551a16b119ebc08a2dc462a 100644 --- a/ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js +++ b/ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js @@ -16,6 +16,8 @@ import { selectedProjects, customizableStagesAndEvents, valueStreams, + rawCustomStageEvents, + camelCasedStageEvents, } from '../mock_data'; let state = null; @@ -41,11 +43,6 @@ describe('Value Stream Analytics mutations', () => { ${types.REQUEST_VALUE_STREAM_DATA} | ${'isLoading'} | ${true} ${types.RECEIVE_GROUP_STAGES_ERROR} | ${'stages'} | ${[]} ${types.REQUEST_GROUP_STAGES} | ${'stages'} | ${[]} - ${types.REQUEST_UPDATE_STAGE} | ${'isLoading'} | ${true} - ${types.RECEIVE_UPDATE_STAGE_SUCCESS} | ${'isLoading'} | ${false} - ${types.RECEIVE_UPDATE_STAGE_ERROR} | ${'isLoading'} | ${false} - ${types.REQUEST_REMOVE_STAGE} | ${'isLoading'} | ${true} - ${types.RECEIVE_REMOVE_STAGE_RESPONSE} | ${'isLoading'} | ${false} ${types.REQUEST_STAGE_MEDIANS} | ${'medians'} | ${{}} ${types.RECEIVE_STAGE_MEDIANS_ERROR} | ${'medians'} | ${{}} ${types.REQUEST_CREATE_VALUE_STREAM} | ${'isCreatingValueStream'} | ${true} @@ -64,6 +61,7 @@ describe('Value Stream Analytics mutations', () => { ${types.INITIALIZE_VALUE_STREAM_SUCCESS} | ${'isLoading'} | ${false} ${types.REQUEST_STAGE_COUNTS} | ${'stageCounts'} | ${{}} ${types.RECEIVE_STAGE_COUNTS_ERROR} | ${'stageCounts'} | ${{}} + ${types.SET_STAGE_EVENTS} | ${'formEvents'} | ${[]} `('$mutation will set $stateKey=$value', ({ mutation, stateKey, value }) => { mutations[mutation](state); @@ -100,6 +98,7 @@ describe('Value Stream Analytics mutations', () => { ${types.RECEIVE_UPDATE_VALUE_STREAM_SUCCESS} | ${valueStreams[1]} | ${{ selectedValueStream: valueStreams[1] }} ${types.SET_PAGINATION} | ${pagination} | ${{ pagination: { ...pagination, sort: PAGINATION_SORT_FIELD_END_EVENT, direction: PAGINATION_SORT_DIRECTION_DESC } }} ${types.SET_PAGINATION} | ${{ ...pagination, sort: 'duration', direction: 'asc' }} | ${{ pagination: { ...pagination, sort: 'duration', direction: 'asc' } }} + ${types.SET_STAGE_EVENTS} | ${rawCustomStageEvents} | ${{ formEvents: camelCasedStageEvents }} `( '$mutation with payload $payload will update state with $expectedState', ({ mutation, payload, expectedState }) => { diff --git a/ee/spec/frontend/api_spec.js b/ee/spec/frontend/api_spec.js index 7cfb51c1392e34b522225a51e41eed416cf88ecb..7b3fb84e3387d0de6634a1f6c50db615b50b3a56 100644 --- a/ee/spec/frontend/api_spec.js +++ b/ee/spec/frontend/api_spec.js @@ -478,75 +478,6 @@ describe('Api', () => { }); }); - describe('cycleAnalyticsCreateStage', () => { - it('submit the custom stage data', (done) => { - const response = {}; - const customStage = { - name: 'cool-stage', - start_event_identifier: 'issue_created', - start_event_label_id: null, - end_event_identifier: 'issue_closed', - end_event_label_id: null, - }; - const expectedUrl = valueStreamBaseUrl({ - id: valueStreamId, - resource: 'stages', - }); - mock.onPost(expectedUrl).reply(httpStatus.OK, response); - - Api.cycleAnalyticsCreateStage({ groupId, valueStreamId, data: customStage }) - .then(({ data, config: { data: reqData, url } }) => { - expect(data).toEqual(response); - expect(JSON.parse(reqData)).toMatchObject(customStage); - expect(url).toEqual(expectedUrl); - }) - - .then(done) - .catch(done.fail); - }); - }); - - describe('cycleAnalyticsUpdateStage', () => { - it('updates the stage data', (done) => { - const response = { id: stageId, custom: false, hidden: true, name: 'nice-stage' }; - const stageData = { name: 'nice-stage', hidden: true }; - const expectedUrl = valueStreamBaseUrl({ - id: valueStreamId, - resource: `stages/${stageId}`, - }); - mock.onPut(expectedUrl).reply(httpStatus.OK, response); - - Api.cycleAnalyticsUpdateStage({ groupId, valueStreamId, stageId, data: stageData }) - .then(({ data, config: { data: reqData, url } }) => { - expect(data).toEqual(response); - expect(JSON.parse(reqData)).toMatchObject(stageData); - expect(url).toEqual(expectedUrl); - }) - .then(done) - .catch(done.fail); - }); - }); - - describe('cycleAnalyticsRemoveStage', () => { - it('deletes the specified data', (done) => { - const response = { id: stageId, hidden: true, custom: true }; - const expectedUrl = valueStreamBaseUrl({ - id: valueStreamId, - resource: `stages/${stageId}`, - }); - mock.onDelete(expectedUrl).reply(httpStatus.OK, response); - - Api.cycleAnalyticsRemoveStage({ groupId, valueStreamId, stageId }) - .then(({ data, config: { url } }) => { - expect(data).toEqual(response); - - expect(url).toEqual(expectedUrl); - }) - .then(done) - .catch(done.fail); - }); - }); - describe('cycleAnalyticsDurationChart', () => { it('fetches stage duration data', (done) => { const response = []; diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 42e398f1fa1fb3f88e792ed8948bba4be2aa63c9..3492a910ba5529383b4acf6cfdac8a9712b72208 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1044,9 +1044,6 @@ msgstr "" msgid "'%{name}' Value Stream saved" msgstr "" -msgid "'%{name}' stage already exists" -msgstr "" - msgid "'%{source}' is not a import source" msgstr "" @@ -30745,12 +30742,6 @@ msgstr "" msgid "Stage" msgstr "" -msgid "Stage data updated" -msgstr "" - -msgid "Stage removed" -msgstr "" - msgid "StageName|Build" msgstr "" @@ -32752,12 +32743,6 @@ msgstr "" msgid "There was a problem fetching users." msgstr "" -msgid "There was a problem refreshing the data, please try again" -msgstr "" - -msgid "There was a problem saving your custom stage, please try again" -msgstr "" - msgid "There was a problem sending the confirmation email" msgstr "" @@ -32851,9 +32836,6 @@ msgstr "" msgid "There was an error removing the e-mail." msgstr "" -msgid "There was an error removing your custom stage, please try again" -msgstr "" - msgid "There was an error resetting group pipeline minutes." msgstr "" @@ -32896,9 +32878,6 @@ msgstr "" msgid "There was an error updating the dashboard, branch named: %{branch} already exists." msgstr "" -msgid "There was an error updating the stage order. Please try reloading the page." -msgstr "" - msgid "There was an error when reseting email token." msgstr "" @@ -37648,9 +37627,6 @@ msgstr "" msgid "Your comment will be discarded." msgstr "" -msgid "Your custom stage '%{title}' was created" -msgstr "" - msgid "Your dashboard has been copied. You can %{web_ide_link_start}edit it here%{web_ide_link_end}." msgstr ""