summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/analytics/cycle_analytics/store/actions.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/analytics/cycle_analytics/store/actions.js')
-rw-r--r--app/assets/javascripts/analytics/cycle_analytics/store/actions.js209
1 files changed, 209 insertions, 0 deletions
diff --git a/app/assets/javascripts/analytics/cycle_analytics/store/actions.js b/app/assets/javascripts/analytics/cycle_analytics/store/actions.js
new file mode 100644
index 00000000000..4a201e00582
--- /dev/null
+++ b/app/assets/javascripts/analytics/cycle_analytics/store/actions.js
@@ -0,0 +1,209 @@
+import {
+ getProjectValueStreamStages,
+ getProjectValueStreams,
+ getValueStreamStageMedian,
+ getValueStreamStageRecords,
+ getValueStreamStageCounts,
+} from '~/api/analytics_api';
+import { normalizeHeaders, parseIntPagination } from '~/lib/utils/common_utils';
+import { createAlert } from '~/flash';
+import { __ } from '~/locale';
+import { DEFAULT_VALUE_STREAM, I18N_VSA_ERROR_STAGE_MEDIAN } from '../constants';
+import * as types from './mutation_types';
+
+export const setSelectedValueStream = ({ commit, dispatch }, valueStream) => {
+ commit(types.SET_SELECTED_VALUE_STREAM, valueStream);
+ return dispatch('fetchValueStreamStages');
+};
+
+export const fetchValueStreamStages = ({ commit, state }) => {
+ const {
+ endpoints: { fullPath },
+ selectedValueStream: { id },
+ } = state;
+ commit(types.REQUEST_VALUE_STREAM_STAGES);
+
+ return getProjectValueStreamStages(fullPath, 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 {
+ endpoints: { fullPath },
+ } = state;
+ commit(types.REQUEST_VALUE_STREAMS);
+
+ return getProjectValueStreams(fullPath)
+ .then(({ data }) => dispatch('receiveValueStreamsSuccess', data))
+ .catch(({ response: { status } }) => {
+ commit(types.RECEIVE_VALUE_STREAMS_ERROR, status);
+ });
+};
+
+export const fetchStageData = ({
+ getters: { requestParams, filterParams, paginationParams },
+ commit,
+}) => {
+ commit(types.REQUEST_STAGE_DATA);
+
+ return getValueStreamStageRecords(requestParams, { ...filterParams, ...paginationParams })
+ .then(({ data, headers }) => {
+ // 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);
+ const { page = null, nextPage = null } = parseIntPagination(normalizeHeaders(headers));
+ commit(types.SET_PAGINATION, { ...paginationParams, page, hasNextPage: Boolean(nextPage) });
+ }
+ })
+ .catch(() => commit(types.RECEIVE_STAGE_DATA_ERROR));
+};
+
+const getStageMedians = ({ stageId, vsaParams, filterParams = {} }) => {
+ return getValueStreamStageMedian({ ...vsaParams, stageId }, filterParams).then(({ data }) => ({
+ id: stageId,
+ value: data?.value || null,
+ }));
+};
+
+export const fetchStageMedians = ({
+ state: { stages },
+ getters: { requestParams: vsaParams, filterParams },
+ commit,
+}) => {
+ commit(types.REQUEST_STAGE_MEDIANS);
+ return Promise.all(
+ stages.map(({ id: stageId }) =>
+ getStageMedians({
+ vsaParams,
+ stageId,
+ filterParams,
+ }),
+ ),
+ )
+ .then((data) => commit(types.RECEIVE_STAGE_MEDIANS_SUCCESS, data))
+ .catch((error) => {
+ commit(types.RECEIVE_STAGE_MEDIANS_ERROR, error);
+ createAlert({ message: I18N_VSA_ERROR_STAGE_MEDIAN });
+ });
+};
+
+const getStageCounts = ({ stageId, vsaParams, filterParams = {} }) => {
+ return getValueStreamStageCounts({ ...vsaParams, stageId }, filterParams).then(({ data }) => ({
+ id: stageId,
+ ...data,
+ }));
+};
+
+export const fetchStageCountValues = ({
+ state: { stages },
+ getters: { requestParams: vsaParams, filterParams },
+ commit,
+}) => {
+ commit(types.REQUEST_STAGE_COUNTS);
+ return Promise.all(
+ stages.map(({ id: stageId }) =>
+ getStageCounts({
+ vsaParams,
+ stageId,
+ filterParams,
+ }),
+ ),
+ )
+ .then((data) => commit(types.RECEIVE_STAGE_COUNTS_SUCCESS, data))
+ .catch((error) => {
+ commit(types.RECEIVE_STAGE_COUNTS_ERROR, error);
+ createAlert({
+ message: __('There was an error fetching stage total counts'),
+ });
+ });
+};
+
+export const fetchValueStreamStageData = ({ dispatch }) =>
+ Promise.all([
+ dispatch('fetchStageData'),
+ dispatch('fetchStageMedians'),
+ dispatch('fetchStageCountValues'),
+ ]);
+
+export const refetchStageData = async ({ dispatch, commit }) => {
+ commit(types.SET_LOADING, true);
+ await dispatch('fetchValueStreamStageData');
+ commit(types.SET_LOADING, false);
+};
+
+export const setSelectedStage = ({ dispatch, commit }, selectedStage = null) => {
+ commit(types.SET_SELECTED_STAGE, selectedStage);
+ return dispatch('refetchStageData');
+};
+
+export const setFilters = ({ dispatch }) => dispatch('refetchStageData');
+
+export const setDateRange = ({ dispatch, commit }, { createdAfter, createdBefore }) => {
+ commit(types.SET_DATE_RANGE, { createdAfter, createdBefore });
+ return dispatch('refetchStageData');
+};
+
+export const setInitialStage = ({ dispatch, commit, state: { stages } }, stage) => {
+ if (!stages.length && !stage) {
+ commit(types.SET_NO_ACCESS_ERROR);
+ return null;
+ }
+
+ const selectedStage = stage || stages[0];
+ commit(types.SET_SELECTED_STAGE, selectedStage);
+ return dispatch('fetchValueStreamStageData');
+};
+
+export const updateStageTablePagination = (
+ { commit, dispatch, state: { selectedStage } },
+ paginationParams,
+) => {
+ commit(types.SET_PAGINATION, paginationParams);
+ return dispatch('fetchStageData', selectedStage.id);
+};
+
+export const initializeVsa = async ({ commit, dispatch }, initialData = {}) => {
+ commit(types.INITIALIZE_VSA, initialData);
+
+ const {
+ endpoints: { fullPath, groupPath, milestonesPath = '', labelsPath = '' },
+ selectedAuthor,
+ selectedMilestone,
+ selectedAssigneeList,
+ selectedLabelList,
+ selectedStage = null,
+ } = initialData;
+
+ dispatch('filters/setEndpoints', {
+ labelsEndpoint: labelsPath,
+ milestonesEndpoint: milestonesPath,
+ groupEndpoint: groupPath,
+ projectEndpoint: fullPath,
+ });
+
+ dispatch('filters/initialize', {
+ selectedAuthor,
+ selectedMilestone,
+ selectedAssigneeList,
+ selectedLabelList,
+ });
+
+ commit(types.SET_LOADING, true);
+ await dispatch('fetchValueStreams');
+ await dispatch('setInitialStage', selectedStage);
+ commit(types.SET_LOADING, false);
+};