Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/cycle_analytics/store')
-rw-r--r--app/assets/javascripts/cycle_analytics/store/actions.js94
-rw-r--r--app/assets/javascripts/cycle_analytics/store/getters.js10
-rw-r--r--app/assets/javascripts/cycle_analytics/store/index.js2
-rw-r--r--app/assets/javascripts/cycle_analytics/store/mutation_types.js10
-rw-r--r--app/assets/javascripts/cycle_analytics/store/mutations.js49
-rw-r--r--app/assets/javascripts/cycle_analytics/store/state.js5
6 files changed, 139 insertions, 31 deletions
diff --git a/app/assets/javascripts/cycle_analytics/store/actions.js b/app/assets/javascripts/cycle_analytics/store/actions.js
index fe3c6d6b3ba..faf1c37d86a 100644
--- a/app/assets/javascripts/cycle_analytics/store/actions.js
+++ b/app/assets/javascripts/cycle_analytics/store/actions.js
@@ -1,27 +1,60 @@
+import {
+ getProjectValueStreamStages,
+ getProjectValueStreams,
+ getProjectValueStreamStageData,
+ getProjectValueStreamMetrics,
+} from '~/api/analytics_api';
import createFlash from '~/flash';
-import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
-import { DEFAULT_DAYS_TO_DISPLAY } from '../constants';
+import { DEFAULT_DAYS_TO_DISPLAY, DEFAULT_VALUE_STREAM } from '../constants';
import * as types from './mutation_types';
-export const fetchCycleAnalyticsData = ({
- state: { requestPath, startDate },
- dispatch,
- commit,
-}) => {
+export const setSelectedValueStream = ({ commit, dispatch }, valueStream) => {
+ commit(types.SET_SELECTED_VALUE_STREAM, valueStream);
+ return dispatch('fetchValueStreamStages');
+};
+
+export const fetchValueStreamStages = ({ commit, state }) => {
+ const { fullPath, selectedValueStream } = state;
+ commit(types.REQUEST_VALUE_STREAM_STAGES);
+
+ return getProjectValueStreamStages(fullPath, selectedValueStream.id)
+ .then(({ data }) => commit(types.RECEIVE_VALUE_STREAM_STAGES_SUCCESS, data))
+ .catch(({ response: { status } }) => {
+ commit(types.RECEIVE_VALUE_STREAM_STAGES_ERROR, status);
+ });
+};
+
+export const receiveValueStreamsSuccess = ({ commit, dispatch }, data = []) => {
+ commit(types.RECEIVE_VALUE_STREAMS_SUCCESS, data);
+ if (data.length) {
+ const [firstStream] = data;
+ return dispatch('setSelectedValueStream', firstStream);
+ }
+ return dispatch('setSelectedValueStream', DEFAULT_VALUE_STREAM);
+};
+
+export const fetchValueStreams = ({ commit, dispatch, state }) => {
+ const { fullPath } = state;
+ commit(types.REQUEST_VALUE_STREAMS);
+
+ return getProjectValueStreams(fullPath)
+ .then(({ data }) => dispatch('receiveValueStreamsSuccess', data))
+ .then(() => dispatch('setSelectedStage'))
+ .catch(({ response: { status } }) => {
+ commit(types.RECEIVE_VALUE_STREAMS_ERROR, status);
+ });
+};
+
+export const fetchCycleAnalyticsData = ({ state: { requestPath, startDate }, commit }) => {
commit(types.REQUEST_CYCLE_ANALYTICS_DATA);
- return axios
- .get(requestPath, {
- params: { 'cycle_analytics[start_date]': startDate },
- })
+ return getProjectValueStreamMetrics(requestPath, { 'cycle_analytics[start_date]': startDate })
.then(({ data }) => commit(types.RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS, data))
- .then(() => dispatch('setSelectedStage'))
- .then(() => dispatch('fetchStageData'))
.catch(() => {
commit(types.RECEIVE_CYCLE_ANALYTICS_DATA_ERROR);
createFlash({
- message: __('There was an error while fetching value stream analytics data.'),
+ message: __('There was an error while fetching value stream summary data.'),
});
});
};
@@ -29,23 +62,42 @@ export const fetchCycleAnalyticsData = ({
export const fetchStageData = ({ state: { requestPath, selectedStage, startDate }, commit }) => {
commit(types.REQUEST_STAGE_DATA);
- return axios
- .get(`${requestPath}/events/${selectedStage.name}.json`, {
- params: { 'cycle_analytics[start_date]': startDate },
+ return getProjectValueStreamStageData({
+ requestPath,
+ stageId: selectedStage.id,
+ params: { 'cycle_analytics[start_date]': startDate },
+ })
+ .then(({ data }) => {
+ // when there's a query timeout, the request succeeds but the error is encoded in the response data
+ if (data?.error) {
+ commit(types.RECEIVE_STAGE_DATA_ERROR, data.error);
+ } else {
+ commit(types.RECEIVE_STAGE_DATA_SUCCESS, data);
+ }
})
- .then(({ data }) => commit(types.RECEIVE_STAGE_DATA_SUCCESS, data))
.catch(() => commit(types.RECEIVE_STAGE_DATA_ERROR));
};
-export const setSelectedStage = ({ commit, state: { stages } }, selectedStage = null) => {
+export const setSelectedStage = ({ dispatch, commit, state: { stages } }, selectedStage = null) => {
const stage = selectedStage || stages[0];
commit(types.SET_SELECTED_STAGE, stage);
+ return dispatch('fetchStageData');
+};
+
+const refetchData = (dispatch, commit) => {
+ commit(types.SET_LOADING, true);
+ return Promise.resolve()
+ .then(() => dispatch('fetchValueStreams'))
+ .then(() => dispatch('fetchCycleAnalyticsData'))
+ .finally(() => commit(types.SET_LOADING, false));
};
-export const setDateRange = ({ commit }, { startDate = DEFAULT_DAYS_TO_DISPLAY }) =>
+export const setDateRange = ({ dispatch, commit }, { startDate = DEFAULT_DAYS_TO_DISPLAY }) => {
commit(types.SET_DATE_RANGE, { startDate });
+ return refetchData(dispatch, commit);
+};
export const initializeVsa = ({ commit, dispatch }, initialData = {}) => {
commit(types.INITIALIZE_VSA, initialData);
- return dispatch('fetchCycleAnalyticsData');
+ return refetchData(dispatch, commit);
};
diff --git a/app/assets/javascripts/cycle_analytics/store/getters.js b/app/assets/javascripts/cycle_analytics/store/getters.js
new file mode 100644
index 00000000000..c60a70ef147
--- /dev/null
+++ b/app/assets/javascripts/cycle_analytics/store/getters.js
@@ -0,0 +1,10 @@
+import { transformStagesForPathNavigation, filterStagesByHiddenStatus } from '../utils';
+
+export const pathNavigationData = ({ stages, medians, stageCounts, selectedStage }) => {
+ return transformStagesForPathNavigation({
+ stages: filterStagesByHiddenStatus(stages, false),
+ medians,
+ stageCounts,
+ selectedStage,
+ });
+};
diff --git a/app/assets/javascripts/cycle_analytics/store/index.js b/app/assets/javascripts/cycle_analytics/store/index.js
index ab47538dcf5..c6ca88ea492 100644
--- a/app/assets/javascripts/cycle_analytics/store/index.js
+++ b/app/assets/javascripts/cycle_analytics/store/index.js
@@ -8,6 +8,7 @@
import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
+import * as getters from './getters';
import mutations from './mutations';
import state from './state';
@@ -16,6 +17,7 @@ Vue.use(Vuex);
export default () =>
new Vuex.Store({
actions,
+ getters,
mutations,
state,
});
diff --git a/app/assets/javascripts/cycle_analytics/store/mutation_types.js b/app/assets/javascripts/cycle_analytics/store/mutation_types.js
index 00aae49ae9f..4f3d430ec9f 100644
--- a/app/assets/javascripts/cycle_analytics/store/mutation_types.js
+++ b/app/assets/javascripts/cycle_analytics/store/mutation_types.js
@@ -1,8 +1,18 @@
export const INITIALIZE_VSA = 'INITIALIZE_VSA';
+export const SET_LOADING = 'SET_LOADING';
+export const SET_SELECTED_VALUE_STREAM = 'SET_SELECTED_VALUE_STREAM';
export const SET_SELECTED_STAGE = 'SET_SELECTED_STAGE';
export const SET_DATE_RANGE = 'SET_DATE_RANGE';
+export const REQUEST_VALUE_STREAMS = 'REQUEST_VALUE_STREAMS';
+export const RECEIVE_VALUE_STREAMS_SUCCESS = 'RECEIVE_VALUE_STREAMS_SUCCESS';
+export const RECEIVE_VALUE_STREAMS_ERROR = 'RECEIVE_VALUE_STREAMS_ERROR';
+
+export const REQUEST_VALUE_STREAM_STAGES = 'REQUEST_VALUE_STREAM_STAGES';
+export const RECEIVE_VALUE_STREAM_STAGES_SUCCESS = 'RECEIVE_VALUE_STREAM_STAGES_SUCCESS';
+export const RECEIVE_VALUE_STREAM_STAGES_ERROR = 'RECEIVE_VALUE_STREAM_STAGES_ERROR';
+
export const REQUEST_CYCLE_ANALYTICS_DATA = 'REQUEST_CYCLE_ANALYTICS_DATA';
export const RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS = 'RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS';
export const RECEIVE_CYCLE_ANALYTICS_DATA_ERROR = 'RECEIVE_CYCLE_ANALYTICS_DATA_ERROR';
diff --git a/app/assets/javascripts/cycle_analytics/store/mutations.js b/app/assets/javascripts/cycle_analytics/store/mutations.js
index 8fd5c78339a..0ae80116cd2 100644
--- a/app/assets/javascripts/cycle_analytics/store/mutations.js
+++ b/app/assets/javascripts/cycle_analytics/store/mutations.js
@@ -1,33 +1,61 @@
-import { decorateData, decorateEvents } from '../utils';
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { decorateData, decorateEvents, formatMedianValues } from '../utils';
import * as types from './mutation_types';
export default {
- [types.INITIALIZE_VSA](state, { requestPath }) {
+ [types.INITIALIZE_VSA](state, { requestPath, fullPath }) {
state.requestPath = requestPath;
+ state.fullPath = fullPath;
+ },
+ [types.SET_LOADING](state, loadingState) {
+ state.isLoading = loadingState;
+ },
+ [types.SET_SELECTED_VALUE_STREAM](state, selectedValueStream = {}) {
+ state.selectedValueStream = convertObjectPropsToCamelCase(selectedValueStream, { deep: true });
},
[types.SET_SELECTED_STAGE](state, stage) {
- state.isLoadingStage = true;
state.selectedStage = stage;
- state.isLoadingStage = false;
},
[types.SET_DATE_RANGE](state, { startDate }) {
state.startDate = startDate;
},
+ [types.REQUEST_VALUE_STREAMS](state) {
+ state.valueStreams = [];
+ },
+ [types.RECEIVE_VALUE_STREAMS_SUCCESS](state, valueStreams = []) {
+ state.valueStreams = valueStreams;
+ },
+ [types.RECEIVE_VALUE_STREAMS_ERROR](state) {
+ state.valueStreams = [];
+ },
+ [types.REQUEST_VALUE_STREAM_STAGES](state) {
+ state.stages = [];
+ },
+ [types.RECEIVE_VALUE_STREAM_STAGES_SUCCESS](state, { stages = [] }) {
+ state.stages = stages.map((s) => ({
+ ...convertObjectPropsToCamelCase(s, { deep: true }),
+ // NOTE: we set the component type here to match the current behaviour
+ // this can be removed when we migrate to the update stage table
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/326704
+ component: `stage-${s.id}-component`,
+ }));
+ },
+ [types.RECEIVE_VALUE_STREAM_STAGES_ERROR](state) {
+ state.stages = [];
+ },
[types.REQUEST_CYCLE_ANALYTICS_DATA](state) {
state.isLoading = true;
- state.stages = [];
state.hasError = false;
},
[types.RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS](state, data) {
- state.isLoading = false;
- const { stages, summary } = decorateData(data);
- state.stages = stages;
+ const { summary, medians } = decorateData(data);
+ state.permissions = data.permissions;
state.summary = summary;
+ state.medians = formatMedianValues(medians);
state.hasError = false;
},
[types.RECEIVE_CYCLE_ANALYTICS_DATA_ERROR](state) {
state.isLoading = false;
- state.stages = [];
state.hasError = true;
},
[types.REQUEST_STAGE_DATA](state) {
@@ -43,10 +71,11 @@ export default {
state.selectedStageEvents = decorateEvents(events, selectedStage);
state.hasError = false;
},
- [types.RECEIVE_STAGE_DATA_ERROR](state) {
+ [types.RECEIVE_STAGE_DATA_ERROR](state, error) {
state.isLoadingStage = false;
state.isEmptyStage = true;
state.selectedStageEvents = [];
state.hasError = true;
+ state.selectedStageError = error;
},
};
diff --git a/app/assets/javascripts/cycle_analytics/store/state.js b/app/assets/javascripts/cycle_analytics/store/state.js
index 5db4e1878a9..02f953d9517 100644
--- a/app/assets/javascripts/cycle_analytics/store/state.js
+++ b/app/assets/javascripts/cycle_analytics/store/state.js
@@ -2,16 +2,21 @@ import { DEFAULT_DAYS_TO_DISPLAY } from '../constants';
export default () => ({
requestPath: '',
+ fullPath: '',
startDate: DEFAULT_DAYS_TO_DISPLAY,
stages: [],
summary: [],
analytics: [],
stats: [],
+ valueStreams: [],
+ selectedValueStream: {},
selectedStage: {},
selectedStageEvents: [],
+ selectedStageError: '',
medians: {},
hasError: false,
isLoading: false,
isLoadingStage: false,
isEmptyStage: false,
+ permissions: {},
});