Commit f8292c71 authored by Mike Greiling's avatar Mike Greiling
Browse files

Merge branch '38260-add-type-by-tasks-chart-feature-flag' into 'master'

Add tasks by type feature flag

See merge request gitlab-org/gitlab!21294
parents 9e7db9b1 0ebfc34c
......@@ -105,6 +105,7 @@ export default {
this.initDateRange();
this.setFeatureFlags({
hasDurationChart: this.glFeatures.cycleAnalyticsScatterplotEnabled,
hasTasksByTypeChart: this.glFeatures.tasksByTypeChart,
});
},
methods: {
......
......@@ -56,10 +56,14 @@ export const fetchStageData = ({ state, dispatch, getters }, slug) => {
};
 
export const requestCycleAnalyticsData = ({ commit }) => commit(types.REQUEST_CYCLE_ANALYTICS_DATA);
export const receiveCycleAnalyticsDataSuccess = ({ commit, dispatch }) => {
export const receiveCycleAnalyticsDataSuccess = ({ state, commit, dispatch }) => {
commit(types.RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS);
 
dispatch('fetchDurationData');
const { featureFlags: { hasDurationChart = false, hasTasksByTypeChart = false } = {} } = state;
const promises = [];
if (hasDurationChart) promises.push('fetchDurationData');
if (hasTasksByTypeChart) promises.push('fetchTasksByTypeData');
return Promise.all(promises.map(func => dispatch(func)));
};
 
export const receiveCycleAnalyticsDataError = ({ commit }, { response }) => {
......@@ -77,7 +81,6 @@ export const fetchCycleAnalyticsData = ({ dispatch }) => {
.then(() => dispatch('fetchGroupLabels'))
.then(() => dispatch('fetchGroupStagesAndEvents'))
.then(() => dispatch('fetchSummaryData'))
.then(() => dispatch('fetchTasksByTypeData'))
.then(() => dispatch('receiveCycleAnalyticsDataSuccess'))
.catch(error => dispatch('receiveCycleAnalyticsDataError', error));
};
......@@ -306,7 +309,6 @@ export const fetchDurationData = ({ state, dispatch }) => {
dispatch('requestDurationData');
 
const {
featureFlags: { hasDurationChart },
stages,
startDate,
endDate,
......@@ -314,29 +316,26 @@ export const fetchDurationData = ({ state, dispatch }) => {
selectedGroup: { fullPath },
} = state;
 
if (hasDurationChart) {
return Promise.all(
stages.map(stage => {
const { slug } = stage;
return Api.cycleAnalyticsDurationChart(slug, {
group_id: fullPath,
created_after: dateFormat(startDate, dateFormats.isoDate),
created_before: dateFormat(endDate, dateFormats.isoDate),
project_ids: selectedProjectIds,
}).then(({ data }) => ({
slug,
selected: true,
data,
}));
}),
)
.then(data => {
dispatch('receiveDurationDataSuccess', data);
})
.catch(() => dispatch('receiveDurationDataError'));
}
return false;
return Promise.all(
stages.map(stage => {
const { slug } = stage;
return Api.cycleAnalyticsDurationChart(slug, {
group_id: fullPath,
created_after: dateFormat(startDate, dateFormats.isoDate),
created_before: dateFormat(endDate, dateFormats.isoDate),
project_ids: selectedProjectIds,
}).then(({ data }) => ({
slug,
selected: true,
data,
}));
}),
)
.then(data => {
dispatch('receiveDurationDataSuccess', data);
})
.catch(() => dispatch('receiveDurationDataError'));
};
 
export const updateSelectedDurationChartStages = ({ state, commit }, stages) => {
......
......@@ -7,5 +7,6 @@ class Analytics::CycleAnalyticsController < Analytics::ApplicationController
before_action do
push_frontend_feature_flag(:customizable_cycle_analytics)
push_frontend_feature_flag(:cycle_analytics_scatterplot_enabled)
push_frontend_feature_flag(:tasks_by_type_chart)
end
end
......@@ -30,6 +30,7 @@ function createComponent({
shallow = true,
withStageSelected = false,
scatterplotEnabled = true,
tasksByTypeChartEnabled = true,
} = {}) {
const func = shallow ? shallowMount : mount;
const comp = func(Component, {
......@@ -43,7 +44,10 @@ function createComponent({
baseStagesEndpoint,
},
provide: {
glFeatures: { cycleAnalyticsScatterplotEnabled: scatterplotEnabled },
glFeatures: {
cycleAnalyticsScatterplotEnabled: scatterplotEnabled,
tasksByTypeChart: tasksByTypeChartEnabled,
},
},
...opts,
});
......@@ -351,7 +355,7 @@ describe('Cycle Analytics component', () => {
describe('with failed requests while loading', () => {
const { full_path: groupId } = mockData.group;
 
function mockRequestCycleAnalyticsData(overrides = {}, includeDutationDataRequests = true) {
function mockRequestCycleAnalyticsData(overrides = {}, includeDurationDataRequests = true) {
const defaultStatus = 200;
const defaultRequests = {
fetchSummaryData: {
......@@ -383,17 +387,17 @@ describe('Cycle Analytics component', () => {
...overrides,
};
 
Object.values(defaultRequests).forEach(({ endpoint, status, response }) => {
mock.onGet(endpoint).replyOnce(status, response);
});
if (includeDutationDataRequests) {
if (includeDurationDataRequests) {
mockData.defaultStages.forEach(stage => {
mock
.onGet(`${baseStagesEndpoint}/${stage}/duration_chart`)
.replyOnce(defaultStatus, [...mockData.rawDurationData]);
});
}
Object.values(defaultRequests).forEach(({ endpoint, status, response }) => {
mock.onGet(endpoint).replyOnce(status, response);
});
}
 
beforeEach(() => {
......
......@@ -46,6 +46,7 @@ describe('Cycle analytics actions', () => {
getters,
featureFlags: {
hasDurationChart: true,
hasTasksByTypeChart: true,
},
};
mock = new MockAdapter(axios);
......@@ -237,6 +238,7 @@ describe('Cycle analytics actions', () => {
receiveCycleAnalyticsDataSuccess:
overrides.receiveCycleAnalyticsDataSuccess || jest.fn().mockResolvedValue(),
fetchDurationData: overrides.fetchDurationData || jest.fn().mockResolvedValue(),
fetchTasksByTypeData: overrides.fetchTasksByTypeData || jest.fn().mockResolvedValue(),
};
return {
mocks,
......@@ -245,8 +247,8 @@ describe('Cycle analytics actions', () => {
.mockImplementationOnce(mocks.requestCycleAnalyticsData)
.mockImplementationOnce(mocks.fetchGroupStagesAndEvents)
.mockImplementationOnce(mocks.fetchSummaryData)
.mockImplementationOnce(mocks.receiveCycleAnalyticsDataSuccess)
.mockImplementationOnce(mocks.fetchDurationData),
.mockImplementationOnce(mocks.fetchDurationData)
.mockImplementationOnce(mocks.fetchTasksByTypeData),
};
}
 
......@@ -270,8 +272,9 @@ describe('Cycle analytics actions', () => {
expect(mocks.requestCycleAnalyticsData).toHaveBeenCalled();
expect(mocks.fetchGroupStagesAndEvents).toHaveBeenCalled();
expect(mocks.fetchSummaryData).toHaveBeenCalled();
expect(mocks.receiveCycleAnalyticsDataSuccess).toHaveBeenCalled();
expect(mocks.fetchDurationData).toHaveBeenCalled();
expect(mocks.fetchTasksByTypeData).toHaveBeenCalled();
done();
})
.catch(done.fail);
......
Supports Markdown
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