Commit 18e636ed authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'ek-fix-fetching-vsa-data-in-translated-stages' into 'master'

Replace vsa stage slug with id

See merge request gitlab-org/gitlab!69640
parents dd9bd814 97d5c52a
...@@ -124,7 +124,7 @@ export default { ...@@ -124,7 +124,7 @@ export default {
this.setSelectedProjects(projects); this.setSelectedProjects(projects);
}, },
onStageSelect(stage) { onStageSelect(stage) {
if (stage.slug === OVERVIEW_STAGE_ID) { if (stage.id === OVERVIEW_STAGE_ID) {
this.setDefaultSelectedStage(); this.setDefaultSelectedStage();
} else { } else {
this.setSelectedStage(stage); this.setSelectedStage(stage);
......
...@@ -25,7 +25,6 @@ export const FETCH_VALUE_STREAM_DATA = 'fetchValueStreamData'; ...@@ -25,7 +25,6 @@ export const FETCH_VALUE_STREAM_DATA = 'fetchValueStreamData';
export const OVERVIEW_STAGE_CONFIG = { export const OVERVIEW_STAGE_CONFIG = {
id: OVERVIEW_STAGE_ID, id: OVERVIEW_STAGE_ID,
slug: OVERVIEW_STAGE_ID,
title: __('Overview'), title: __('Overview'),
icon: 'home', icon: 'home',
}; };
......
...@@ -78,7 +78,7 @@ export const fetchStageMedianValues = ({ dispatch, commit, getters }) => { ...@@ -78,7 +78,7 @@ export const fetchStageMedianValues = ({ dispatch, commit, getters }) => {
activeStages, activeStages,
currentValueStreamId, currentValueStreamId,
} = getters; } = getters;
const stageIds = activeStages.map((s) => s.slug); const stageIds = activeStages.map((s) => s.id);
dispatch('requestStageMedianValues'); dispatch('requestStageMedianValues');
return Promise.all( return Promise.all(
...@@ -115,7 +115,7 @@ export const fetchStageCountValues = ({ commit, getters }) => { ...@@ -115,7 +115,7 @@ export const fetchStageCountValues = ({ commit, getters }) => {
activeStages, activeStages,
currentValueStreamId, currentValueStreamId,
} = getters; } = getters;
const stageIds = activeStages.map((s) => s.slug); const stageIds = activeStages.map((s) => s.id);
commit(types.REQUEST_STAGE_COUNTS); commit(types.REQUEST_STAGE_COUNTS);
return Promise.all( return Promise.all(
......
...@@ -25,16 +25,16 @@ export const fetchDurationData = ({ dispatch, commit, rootGetters }) => { ...@@ -25,16 +25,16 @@ export const fetchDurationData = ({ dispatch, commit, rootGetters }) => {
} = rootGetters; } = rootGetters;
return Promise.all( return Promise.all(
activeStages.map((stage) => { activeStages.map((stage) => {
const { slug } = stage; const { id } = stage;
return Api.cycleAnalyticsDurationChart({ return Api.cycleAnalyticsDurationChart({
groupId: currentGroupPath, groupId: currentGroupPath,
valueStreamId: currentValueStreamId, valueStreamId: currentValueStreamId,
stageId: slug, stageId: id,
params: cycleAnalyticsRequestParams, params: cycleAnalyticsRequestParams,
}) })
.then(checkForDataError) .then(checkForDataError)
.then(({ data }) => ({ slug, selected: true, data })); .then(({ data }) => ({ id, selected: true, data }));
}), }),
) )
.then((data) => commit(types.RECEIVE_DURATION_DATA_SUCCESS, data)) .then((data) => commit(types.RECEIVE_DURATION_DATA_SUCCESS, data))
...@@ -45,7 +45,7 @@ export const updateSelectedDurationChartStages = ({ state, commit }, stages) => ...@@ -45,7 +45,7 @@ export const updateSelectedDurationChartStages = ({ state, commit }, stages) =>
const setSelectedPropertyOnStages = (data) => const setSelectedPropertyOnStages = (data) =>
data.map((stage) => { data.map((stage) => {
const selected = stages.reduce((result, object) => { const selected = stages.reduce((result, object) => {
if (object.slug === stage.slug) return true; if (object.id === stage.id) return true;
return result; return result;
}, false); }, false);
......
import dateFormat from 'dateformat'; import dateFormat from 'dateformat';
import { isNumber, uniqBy } from 'lodash'; import { uniqBy } from 'lodash';
import { dateFormats } from '~/analytics/shared/constants'; import { dateFormats } from '~/analytics/shared/constants';
import { toYmd } from '~/analytics/shared/utils'; import { toYmd } from '~/analytics/shared/utils';
import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants'; import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants';
...@@ -8,7 +8,6 @@ import createFlash from '~/flash'; ...@@ -8,7 +8,6 @@ import createFlash from '~/flash';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { newDate, dayAfter, secondsToDays, getDatesInRange } from '~/lib/utils/datetime_utility'; import { newDate, dayAfter, secondsToDays, getDatesInRange } from '~/lib/utils/datetime_utility';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
import { convertToSnakeCase } from '~/lib/utils/text_utility';
const EVENT_TYPE_LABEL = 'label'; const EVENT_TYPE_LABEL = 'label';
...@@ -45,45 +44,12 @@ export const isLabelEvent = (labelEvents = [], ev = null) => ...@@ -45,45 +44,12 @@ export const isLabelEvent = (labelEvents = [], ev = null) =>
export const getLabelEventsIdentifiers = (events = []) => export const getLabelEventsIdentifiers = (events = []) =>
events.filter((ev) => ev.type && ev.type === EVENT_TYPE_LABEL).map((i) => i.identifier); events.filter((ev) => ev.type && ev.type === EVENT_TYPE_LABEL).map((i) => i.identifier);
/**
* Checks if the specified stage is in memory or persisted to storage based on the id
*
* Default value stream analytics stages are initially stored in memory, when they are first
* created the id for the stage is the name of the stage in lowercase. This string id
* is used to fetch stage data (events, median calculation)
*
* When either a custom stage is created or an edit is made to a default stage then the
* default stages get persisted to storage and will have a numeric id. The new numeric
* id should then be used to access stage data
*
*/
export const isPersistedStage = ({ custom, id }) => custom || isNumber(id);
/**
* Returns the the correct slug to use for a stage
* default stages use the snakecased title of the stage, while custom
* stages will have a numeric id
*
* @param {Object} obj
* @param {string} obj.title - title of the stage
* @param {number} obj.id - numerical object id available for custom stages
* @param {boolean} obj.custom - boolean flag indicating a custom stage
* @returns {(number|string)} Returns a numerical id for customs stages and string for default stages
*/
const stageUrlSlug = ({ id, title, custom = false }) => {
if (custom) return id;
return convertToSnakeCase(title);
};
export const transformRawStages = (stages = []) => export const transformRawStages = (stages = []) =>
stages.map(({ id, title, name = '', custom = false, ...rest }) => ({ stages.map(({ id, title, name = '', custom = false, ...rest }) => ({
...convertObjectPropsToCamelCase(rest, { deep: true }), ...convertObjectPropsToCamelCase(rest, { deep: true }),
id, id,
title, title,
custom, custom,
slug: isPersistedStage({ custom, id }) ? id : stageUrlSlug({ custom, id, title }),
// the name field is used to create a stage, but the get request returns title
name: name.length ? name : title, name: name.length ? name : title,
})); }));
...@@ -113,7 +79,7 @@ export const prepareStageErrors = (stages, errors) => ...@@ -113,7 +79,7 @@ export const prepareStageErrors = (stages, errors) =>
* each potentially having multiple data entries. * each potentially having multiple data entries.
* [ * [
* { * {
* slug: 'issue', * id: 'issue',
* selected: true, * selected: true,
* data: [ * data: [
* { * {
...@@ -159,7 +125,7 @@ export const flattenDurationChartData = (data) => ...@@ -159,7 +125,7 @@ export const flattenDurationChartData = (data) =>
* each potentially having multiple data entries. * each potentially having multiple data entries.
* [ * [
* { * {
* slug: 'issue', * id: 'issue',
* selected: true, * selected: true,
* data: [ * data: [
* { * {
......
...@@ -10,7 +10,6 @@ Array [ ...@@ -10,7 +10,6 @@ Array [
"id": 18, "id": 18,
"legend": "Cool legend", "legend": "Cool legend",
"name": "Coolest beans stage", "name": "Coolest beans stage",
"slug": 18,
"startEventIdentifier": "issue_first_mentioned_in_commit", "startEventIdentifier": "issue_first_mentioned_in_commit",
"title": "Coolest beans stage", "title": "Coolest beans stage",
}, },
......
...@@ -414,8 +414,8 @@ describe('EE Value Stream Analytics component', () => { ...@@ -414,8 +414,8 @@ describe('EE Value Stream Analytics component', () => {
}); });
describe('Path navigation', () => { describe('Path navigation', () => {
const selectedStage = { title: 'Plan', slug: 2 }; const selectedStage = { id: 2, title: 'Plan' };
const overviewStage = { title: 'Overview', slug: OVERVIEW_STAGE_ID }; const overviewStage = { id: OVERVIEW_STAGE_ID, title: 'Overview' };
let actionSpies = {}; let actionSpies = {};
beforeEach(async () => { beforeEach(async () => {
......
...@@ -241,12 +241,12 @@ export const rawDurationData = [ ...@@ -241,12 +241,12 @@ export const rawDurationData = [
export const transformedDurationData = [ export const transformedDurationData = [
{ {
slug: 1, id: 1,
selected: true, selected: true,
data: rawDurationData, data: rawDurationData,
}, },
{ {
slug: 2, id: 2,
selected: true, selected: true,
data: rawDurationData, data: rawDurationData,
}, },
......
...@@ -217,7 +217,7 @@ describe('Value Stream Analytics actions / stages', () => { ...@@ -217,7 +217,7 @@ describe('Value Stream Analytics actions / stages', () => {
describe('fetchStageMedianValues', () => { describe('fetchStageMedianValues', () => {
let mockDispatch = jest.fn(); let mockDispatch = jest.fn();
const fetchMedianResponse = activeStages.map(({ slug: id }) => ({ events: [], id })); const fetchMedianResponse = activeStages.map(({ id }) => ({ events: [], id }));
beforeEach(() => { beforeEach(() => {
state = { ...state, stages, currentGroup }; state = { ...state, stages, currentGroup };
...@@ -257,7 +257,7 @@ describe('Value Stream Analytics actions / stages', () => { ...@@ -257,7 +257,7 @@ describe('Value Stream Analytics actions / stages', () => {
describe(`Status ${httpStatusCodes.OK} and error message in response`, () => { describe(`Status ${httpStatusCodes.OK} and error message in response`, () => {
const dataError = 'Too much data'; const dataError = 'Too much data';
const payload = activeStages.map(({ slug: id }) => ({ value: null, id, error: dataError })); const payload = activeStages.map(({ id }) => ({ value: null, id, error: dataError }));
beforeEach(() => { beforeEach(() => {
mock.onGet(endpoints.stageMedian).reply(httpStatusCodes.OK, { error: dataError }); mock.onGet(endpoints.stageMedian).reply(httpStatusCodes.OK, { error: dataError });
...@@ -316,7 +316,7 @@ describe('Value Stream Analytics actions / stages', () => { ...@@ -316,7 +316,7 @@ describe('Value Stream Analytics actions / stages', () => {
}); });
describe('fetchStageCountValues', () => { describe('fetchStageCountValues', () => {
const fetchCountResponse = activeStages.map(({ slug: id }) => ({ events: [], id })); const fetchCountResponse = activeStages.map(({ id }) => ({ events: [], id }));
beforeEach(() => { beforeEach(() => {
state = { state = {
......
...@@ -9,7 +9,6 @@ import { ...@@ -9,7 +9,6 @@ import {
flattenDurationChartData, flattenDurationChartData,
getDurationChartData, getDurationChartData,
transformRawStages, transformRawStages,
isPersistedStage,
getTasksByTypeData, getTasksByTypeData,
flattenTaskByTypeSeries, flattenTaskByTypeSeries,
orderByDate, orderByDate,
...@@ -160,13 +159,6 @@ describe('Value Stream Analytics utils', () => { ...@@ -160,13 +159,6 @@ describe('Value Stream Analytics utils', () => {
}); });
}); });
it('sets the slug to the value of the stage id', () => {
const transformed = transformRawStages([issueStage, rawCustomStage]);
transformed.forEach((t) => {
expect(t.slug).toEqual(t.id);
});
});
it('sets the name to the value of the stage title if its not set', () => { it('sets the name to the value of the stage title if its not set', () => {
const transformed = transformRawStages([issueStage, rawCustomStage]); const transformed = transformRawStages([issueStage, rawCustomStage]);
transformed.forEach((t) => { transformed.forEach((t) => {
...@@ -199,18 +191,6 @@ describe('Value Stream Analytics utils', () => { ...@@ -199,18 +191,6 @@ describe('Value Stream Analytics utils', () => {
}); });
}); });
describe('isPersistedStage', () => {
it.each`
custom | id | expected
${true} | ${'this-is-a-string'} | ${true}
${true} | ${42} | ${true}
${false} | ${42} | ${true}
${false} | ${'this-is-a-string'} | ${false}
`('with custom=$custom and id=$id', ({ custom, id, expected }) => {
expect(isPersistedStage({ custom, id })).toEqual(expected);
});
});
describe('flattenTaskByTypeSeries', () => { describe('flattenTaskByTypeSeries', () => {
const dummySeries = Object.fromEntries([ const dummySeries = Object.fromEntries([
['2019-01-16', 40], ['2019-01-16', 40],
......
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