Commit 911a5546 authored by Martin Wortschack's avatar Martin Wortschack Committed by Clement Ho

Remove main chart selection on filter change

- Removes any items selected on the main chart
when the user changes a global filter
parent 243664c7
...@@ -102,13 +102,13 @@ export default { ...@@ -102,13 +102,13 @@ export default {
...mapActions('charts', [ ...mapActions('charts', [
'fetchChartData', 'fetchChartData',
'setMetricType', 'setMetricType',
'chartItemClicked', 'updateSelectedItems',
'setChartEnabled', 'setChartEnabled',
]), ]),
...mapActions('table', ['setSortField', 'setPage', 'toggleSortOrder', 'setColumnMetric']), ...mapActions('table', ['setSortField', 'setPage', 'toggleSortOrder', 'setColumnMetric']),
onMainChartItemClicked({ params }) { onMainChartItemClicked({ params }) {
const itemValue = params.data.value[0]; const itemValue = params.data.value[0];
this.chartItemClicked({ chartKey: this.chartKeys.main, item: itemValue }); this.updateSelectedItems({ chartKey: this.chartKeys.main, item: itemValue });
}, },
getColumnChartOption(chartKey) { getColumnChartOption(chartKey) {
return { return {
......
...@@ -50,14 +50,19 @@ export const setMetricType = ({ commit, dispatch }, { chartKey, metricType }) => ...@@ -50,14 +50,19 @@ export const setMetricType = ({ commit, dispatch }, { chartKey, metricType }) =>
dispatch('fetchChartData', chartKey); dispatch('fetchChartData', chartKey);
}; };
export const chartItemClicked = ({ commit, dispatch }, { chartKey, item }) => { export const updateSelectedItems = (
{ commit, dispatch },
{ chartKey, item, skipReload = false },
) => {
commit(types.UPDATE_SELECTED_CHART_ITEMS, { chartKey, item }); commit(types.UPDATE_SELECTED_CHART_ITEMS, { chartKey, item });
// update secondary charts if (!skipReload) {
dispatch('fetchSecondaryChartData'); // update secondary charts
dispatch('fetchSecondaryChartData');
// let's reset the page on the MR table and fetch data // let's reset the page on the MR table and fetch data
dispatch('table/setPage', 0, { root: true }); dispatch('table/setPage', 0, { root: true });
}
}; };
export const setChartEnabled = ({ commit }, { chartKey, isEnabled }) => export const setChartEnabled = ({ commit }, { chartKey, isEnabled }) =>
......
...@@ -22,11 +22,15 @@ export default { ...@@ -22,11 +22,15 @@ export default {
state.charts[chartKey].params.metricType = metricType; state.charts[chartKey].params.metricType = metricType;
}, },
[types.UPDATE_SELECTED_CHART_ITEMS](state, { chartKey, item }) { [types.UPDATE_SELECTED_CHART_ITEMS](state, { chartKey, item }) {
const idx = state.charts[chartKey].selected.indexOf(item); if (!item) {
if (idx === -1) { state.charts[chartKey].selected = [];
state.charts[chartKey].selected.push(item);
} else { } else {
state.charts[chartKey].selected.splice(idx, 1); const idx = state.charts[chartKey].selected.indexOf(item);
if (idx === -1) {
state.charts[chartKey].selected.push(item);
} else {
state.charts[chartKey].selected.splice(idx, 1);
}
} }
}, },
[types.SET_CHART_ENABLED](state, { chartKey, isEnabled }) { [types.SET_CHART_ENABLED](state, { chartKey, isEnabled }) {
......
...@@ -4,6 +4,14 @@ import { chartKeys } from '../../../constants'; ...@@ -4,6 +4,14 @@ import { chartKeys } from '../../../constants';
export const setGroupNamespace = ({ commit, dispatch }, groupNamespace) => { export const setGroupNamespace = ({ commit, dispatch }, groupNamespace) => {
commit(types.SET_GROUP_NAMESPACE, groupNamespace); commit(types.SET_GROUP_NAMESPACE, groupNamespace);
// let's reset the current selection first
// with skipReload=true we avoid data from being fetched here
dispatch(
'charts/updateSelectedItems',
{ chartKey: chartKeys.main, item: null, skipReload: true },
{ root: true },
);
// let's fetch the main chart data first to see if the user has access to the selected group // let's fetch the main chart data first to see if the user has access to the selected group
// if there's no 403, then we fetch all remaining chart data and table data // if there's no 403, then we fetch all remaining chart data and table data
return dispatch('charts/fetchChartData', chartKeys.main, { root: true }).then(() => { return dispatch('charts/fetchChartData', chartKeys.main, { root: true }).then(() => {
...@@ -16,6 +24,12 @@ export const setGroupNamespace = ({ commit, dispatch }, groupNamespace) => { ...@@ -16,6 +24,12 @@ export const setGroupNamespace = ({ commit, dispatch }, groupNamespace) => {
export const setProjectPath = ({ commit, dispatch }, projectPath) => { export const setProjectPath = ({ commit, dispatch }, projectPath) => {
commit(types.SET_PROJECT_PATH, projectPath); commit(types.SET_PROJECT_PATH, projectPath);
dispatch(
'charts/updateSelectedItems',
{ chartKey: chartKeys.main, item: null, skipReload: true },
{ root: true },
);
return dispatch('charts/fetchChartData', chartKeys.main, { root: true }).then(() => { return dispatch('charts/fetchChartData', chartKeys.main, { root: true }).then(() => {
dispatch('charts/fetchSecondaryChartData', null, { root: true }); dispatch('charts/fetchSecondaryChartData', null, { root: true });
// let's reset the page on the MR table and fetch data // let's reset the page on the MR table and fetch data
...@@ -26,6 +40,12 @@ export const setProjectPath = ({ commit, dispatch }, projectPath) => { ...@@ -26,6 +40,12 @@ export const setProjectPath = ({ commit, dispatch }, projectPath) => {
export const setPath = ({ commit, dispatch }, path) => { export const setPath = ({ commit, dispatch }, path) => {
commit(types.SET_PATH, path); commit(types.SET_PATH, path);
dispatch(
'charts/updateSelectedItems',
{ chartKey: chartKeys.main, item: null, skipReload: true },
{ root: true },
);
return dispatch('charts/fetchChartData', chartKeys.main, { root: true }).then(() => { return dispatch('charts/fetchChartData', chartKeys.main, { root: true }).then(() => {
dispatch('charts/fetchSecondaryChartData', null, { root: true }); dispatch('charts/fetchSecondaryChartData', null, { root: true });
// let's reset the page on the MR table and fetch data // let's reset the page on the MR table and fetch data
...@@ -36,6 +56,12 @@ export const setPath = ({ commit, dispatch }, path) => { ...@@ -36,6 +56,12 @@ export const setPath = ({ commit, dispatch }, path) => {
export const setDaysInPast = ({ commit, dispatch }, days) => { export const setDaysInPast = ({ commit, dispatch }, days) => {
commit(types.SET_DAYS_IN_PAST, days); commit(types.SET_DAYS_IN_PAST, days);
dispatch(
'charts/updateSelectedItems',
{ chartKey: chartKeys.main, item: null, skipReload: true },
{ root: true },
);
return dispatch('charts/fetchChartData', chartKeys.main, { root: true }).then(() => { return dispatch('charts/fetchChartData', chartKeys.main, { root: true }).then(() => {
dispatch('charts/fetchSecondaryChartData', null, { root: true }); dispatch('charts/fetchSecondaryChartData', null, { root: true });
// let's reset the page on the MR table and fetch data // let's reset the page on the MR table and fetch data
......
...@@ -25,7 +25,7 @@ describe('ProductivityApp component', () => { ...@@ -25,7 +25,7 @@ describe('ProductivityApp component', () => {
}; };
const actionSpies = { const actionSpies = {
chartItemClicked: jest.fn(), updateSelectedItems: jest.fn(),
setSortField: jest.fn(), setSortField: jest.fn(),
setPage: jest.fn(), setPage: jest.fn(),
toggleSortOrder: jest.fn(), toggleSortOrder: jest.fn(),
...@@ -170,8 +170,8 @@ describe('ProductivityApp component', () => { ...@@ -170,8 +170,8 @@ describe('ProductivityApp component', () => {
.vm.$emit('chartItemClicked', data); .vm.$emit('chartItemClicked', data);
}); });
it('dispatches chartItemClicked action', () => { it('dispatches updateSelectedItems action', () => {
expect(actionSpies.chartItemClicked).toHaveBeenCalledWith({ expect(actionSpies.updateSelectedItems).toHaveBeenCalledWith({
chartKey: chartKeys.main, chartKey: chartKeys.main,
item: 0, item: 0,
}); });
......
...@@ -13,7 +13,7 @@ describe('Productivity analytics chart actions', () => { ...@@ -13,7 +13,7 @@ describe('Productivity analytics chart actions', () => {
let mockedState; let mockedState;
let mock; let mock;
const chartKey = 'main'; const chartKey = chartKeys.main;
const globalParams = { const globalParams = {
group_id: 'gitlab-org', group_id: 'gitlab-org',
project_id: 'gitlab-org/gitlab-test', project_id: 'gitlab-org/gitlab-test',
...@@ -212,17 +212,37 @@ describe('Productivity analytics chart actions', () => { ...@@ -212,17 +212,37 @@ describe('Productivity analytics chart actions', () => {
}); });
}); });
describe('chartItemClicked', () => { describe('updateSelectedItems', () => {
const item = 5; describe('when skipReload is false (by default)', () => {
it('should commit selected chart item', done => { const item = 5;
testAction( it('should commit selected chart item and dispatch fetchSecondaryChartData and setPage', done => {
actions.chartItemClicked, testAction(
{ chartKey, item }, actions.updateSelectedItems,
mockedContext.state, { chartKey, item },
[{ type: types.UPDATE_SELECTED_CHART_ITEMS, payload: { chartKey, item } }], mockedContext.state,
[{ type: 'fetchSecondaryChartData' }, { type: 'table/setPage', payload: 0 }], [{ type: types.UPDATE_SELECTED_CHART_ITEMS, payload: { chartKey, item } }],
done, [{ type: 'fetchSecondaryChartData' }, { type: 'table/setPage', payload: 0 }],
); done,
);
});
});
describe('when skipReload is true', () => {
it('should commit selected chart and it should not dispatch any further actions', done => {
testAction(
actions.updateSelectedItems,
{ chartKey, item: null, skipReload: true },
mockedContext.state,
[
{
type: types.UPDATE_SELECTED_CHART_ITEMS,
payload: { chartKey: chartKeys.main, item: null },
},
],
[],
done,
);
});
}); });
}); });
......
...@@ -71,6 +71,12 @@ describe('Productivity analytics chart mutations', () => { ...@@ -71,6 +71,12 @@ describe('Productivity analytics chart mutations', () => {
chartKey = chartKeys.timeBasedHistogram; chartKey = chartKeys.timeBasedHistogram;
const item = 5; const item = 5;
it('sets the list of selected items to [] when the item is null', () => {
mutations[types.UPDATE_SELECTED_CHART_ITEMS](state, { chartKey, item: null });
expect(state.charts[chartKey].selected).toEqual([]);
});
it('adds the item to the list of selected items when not included', () => { it('adds the item to the list of selected items when not included', () => {
mutations[types.UPDATE_SELECTED_CHART_ITEMS](state, { chartKey, item }); mutations[types.UPDATE_SELECTED_CHART_ITEMS](state, { chartKey, item });
......
...@@ -21,18 +21,24 @@ describe('Productivity analytics filter actions', () => { ...@@ -21,18 +21,24 @@ describe('Productivity analytics filter actions', () => {
expect(store.commit).toHaveBeenCalledWith(types.SET_GROUP_NAMESPACE, groupNamespace); expect(store.commit).toHaveBeenCalledWith(types.SET_GROUP_NAMESPACE, groupNamespace);
expect(store.dispatch.mock.calls[0]).toEqual([ expect(store.dispatch.mock.calls[0]).toEqual([
'charts/updateSelectedItems',
{ chartKey: chartKeys.main, item: null, skipReload: true },
{ root: true },
]);
expect(store.dispatch.mock.calls[1]).toEqual([
'charts/fetchChartData', 'charts/fetchChartData',
chartKeys.main, chartKeys.main,
{ root: true }, { root: true },
]); ]);
expect(store.dispatch.mock.calls[1]).toEqual([ expect(store.dispatch.mock.calls[2]).toEqual([
'charts/fetchSecondaryChartData', 'charts/fetchSecondaryChartData',
null, null,
{ root: true }, { root: true },
]); ]);
expect(store.dispatch.mock.calls[2]).toEqual(['table/setPage', 0, { root: true }]); expect(store.dispatch.mock.calls[3]).toEqual(['table/setPage', 0, { root: true }]);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
...@@ -52,18 +58,24 @@ describe('Productivity analytics filter actions', () => { ...@@ -52,18 +58,24 @@ describe('Productivity analytics filter actions', () => {
expect(store.commit).toHaveBeenCalledWith(types.SET_PROJECT_PATH, projectPath); expect(store.commit).toHaveBeenCalledWith(types.SET_PROJECT_PATH, projectPath);
expect(store.dispatch.mock.calls[0]).toEqual([ expect(store.dispatch.mock.calls[0]).toEqual([
'charts/updateSelectedItems',
{ chartKey: chartKeys.main, item: null, skipReload: true },
{ root: true },
]);
expect(store.dispatch.mock.calls[1]).toEqual([
'charts/fetchChartData', 'charts/fetchChartData',
chartKeys.main, chartKeys.main,
{ root: true }, { root: true },
]); ]);
expect(store.dispatch.mock.calls[1]).toEqual([ expect(store.dispatch.mock.calls[2]).toEqual([
'charts/fetchSecondaryChartData', 'charts/fetchSecondaryChartData',
null, null,
{ root: true }, { root: true },
]); ]);
expect(store.dispatch.mock.calls[2]).toEqual(['table/setPage', 0, { root: true }]); expect(store.dispatch.mock.calls[3]).toEqual(['table/setPage', 0, { root: true }]);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
...@@ -83,18 +95,24 @@ describe('Productivity analytics filter actions', () => { ...@@ -83,18 +95,24 @@ describe('Productivity analytics filter actions', () => {
expect(store.commit).toHaveBeenCalledWith(types.SET_PATH, path); expect(store.commit).toHaveBeenCalledWith(types.SET_PATH, path);
expect(store.dispatch.mock.calls[0]).toEqual([ expect(store.dispatch.mock.calls[0]).toEqual([
'charts/updateSelectedItems',
{ chartKey: chartKeys.main, item: null, skipReload: true },
{ root: true },
]);
expect(store.dispatch.mock.calls[1]).toEqual([
'charts/fetchChartData', 'charts/fetchChartData',
chartKeys.main, chartKeys.main,
{ root: true }, { root: true },
]); ]);
expect(store.dispatch.mock.calls[1]).toEqual([ expect(store.dispatch.mock.calls[2]).toEqual([
'charts/fetchSecondaryChartData', 'charts/fetchSecondaryChartData',
null, null,
{ root: true }, { root: true },
]); ]);
expect(store.dispatch.mock.calls[2]).toEqual(['table/setPage', 0, { root: true }]); expect(store.dispatch.mock.calls[3]).toEqual(['table/setPage', 0, { root: true }]);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
...@@ -114,18 +132,24 @@ describe('Productivity analytics filter actions', () => { ...@@ -114,18 +132,24 @@ describe('Productivity analytics filter actions', () => {
expect(store.commit).toHaveBeenCalledWith(types.SET_DAYS_IN_PAST, daysInPast); expect(store.commit).toHaveBeenCalledWith(types.SET_DAYS_IN_PAST, daysInPast);
expect(store.dispatch.mock.calls[0]).toEqual([ expect(store.dispatch.mock.calls[0]).toEqual([
'charts/updateSelectedItems',
{ chartKey: chartKeys.main, item: null, skipReload: true },
{ root: true },
]);
expect(store.dispatch.mock.calls[1]).toEqual([
'charts/fetchChartData', 'charts/fetchChartData',
chartKeys.main, chartKeys.main,
{ root: true }, { root: true },
]); ]);
expect(store.dispatch.mock.calls[1]).toEqual([ expect(store.dispatch.mock.calls[2]).toEqual([
'charts/fetchSecondaryChartData', 'charts/fetchSecondaryChartData',
null, null,
{ root: true }, { root: true },
]); ]);
expect(store.dispatch.mock.calls[2]).toEqual(['table/setPage', 0, { root: true }]); expect(store.dispatch.mock.calls[3]).toEqual(['table/setPage', 0, { root: true }]);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
......
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