Commit 38329479 authored by samdbeckham's avatar samdbeckham

Adds multi select to the GSD filters

- Updates the `SET_FILTER` mutation to allow multiple selects
- Adds a special case for the "ALL" option
- Adds a special getter for selected filter text
- Tests for the above
parent fcd81c77
...@@ -22,13 +22,12 @@ export default { ...@@ -22,13 +22,12 @@ export default {
}, },
}, },
computed: { computed: {
...mapGetters('filters', ['getFilter', 'getSelectedOptions']), ...mapGetters('filters', ['getFilter', 'getSelectedOptions', 'getSelectedOptionNames']),
filter() { filter() {
return this.getFilter(this.filterId); return this.getFilter(this.filterId);
}, },
selectedOptionText() { selectedOptionText() {
const [selectedOption] = this.getSelectedOptions(this.filterId); return this.getSelectedOptionNames(this.filterId) || '-';
return (selectedOption && selectedOption.name) || '-';
}, },
}, },
methods: { methods: {
......
...@@ -6,6 +6,14 @@ export const getSelectedOptions = (state, getters) => filterId => ...@@ -6,6 +6,14 @@ export const getSelectedOptions = (state, getters) => filterId =>
export const getSelectedOptionIds = (state, getters) => filterId => export const getSelectedOptionIds = (state, getters) => filterId =>
getters.getSelectedOptions(filterId).map(option => option.id); getters.getSelectedOptions(filterId).map(option => option.id);
export const getSelectedOptionNames = (state, getters) => filterId => {
const selectedOptions = getters.getSelectedOptions(filterId);
const [firstOption] = selectedOptions.map(option => option.name);
return selectedOptions.length > 1
? `${firstOption} +${selectedOptions.length - 1} more`
: `${firstOption}`;
};
export const getFilterIds = state => state.filters.map(filter => filter.id); export const getFilterIds = state => state.filters.map(filter => filter.id);
/** /**
......
...@@ -4,13 +4,28 @@ export default { ...@@ -4,13 +4,28 @@ export default {
[types.SET_FILTER](state, payload) { [types.SET_FILTER](state, payload) {
const { filterId, optionId } = payload; const { filterId, optionId } = payload;
const activeFilter = state.filters.find(filter => filter.id === filterId); const activeFilter = state.filters.find(filter => filter.id === filterId);
if (activeFilter) { if (activeFilter) {
activeFilter.options = [ let activeOptions;
...activeFilter.options.map(option => ({
if (optionId === 'all') {
activeOptions = activeFilter.options.map(option => ({
...option,
selected: option.id === 'all',
}));
} else {
activeOptions = activeFilter.options.map(option => {
const selected =
option.id === optionId ? !option.selected : option.selected && option.id !== 'all';
return {
...option, ...option,
selected: option.id === optionId, selected,
})), };
]; });
}
activeFilter.options = activeOptions;
} }
}, },
}; };
...@@ -28,7 +28,8 @@ describe('filters module getters', () => { ...@@ -28,7 +28,8 @@ describe('filters module getters', () => {
}); });
describe('getSelectedOptions', () => { describe('getSelectedOptions', () => {
it('should return "All" as the selcted option', () => { describe('with one selected option', () => {
it('should return "all" as the selcted option', () => {
const state = createState(); const state = createState();
const selectedOptions = getters.getSelectedOptions(state, mockedGetters(state))( const selectedOptions = getters.getSelectedOptions(state, mockedGetters(state))(
'report_type', 'report_type',
...@@ -39,6 +40,23 @@ describe('filters module getters', () => { ...@@ -39,6 +40,23 @@ describe('filters module getters', () => {
}); });
}); });
describe('with multiple selected options', () => {
it('should return both "High" and "Critical" ', () => {
const state = {
filters: [
{
id: 'severity',
options: [{ id: 'critical', selected: true }, { id: 'high', selected: true }],
},
],
};
const selectedOptions = getters.getSelectedOptions(state, mockedGetters(state))('severity');
expect(selectedOptions).toHaveLength(2);
});
});
});
describe('getSelectedOptionIds', () => { describe('getSelectedOptionIds', () => {
it('should return "one" as the selcted project ID', () => { it('should return "one" as the selcted project ID', () => {
const state = createState(); const state = createState();
...@@ -56,6 +74,33 @@ describe('filters module getters', () => { ...@@ -56,6 +74,33 @@ describe('filters module getters', () => {
}); });
}); });
describe('getSelectedOptionNames', () => {
it('should return "All" as the selected option', () => {
const state = createState();
const selectedOptionNames = getters.getSelectedOptionNames(state, mockedGetters(state))(
'severity',
);
expect(selectedOptionNames).toEqual('All');
});
it('should return the correct message when multiple filters are selected', () => {
const state = {
filters: [
{
id: 'severity',
options: [{ name: 'Critical', selected: true }, { name: 'High', selected: true }],
},
],
};
const selectedOptionNames = getters.getSelectedOptionNames(state, mockedGetters(state))(
'severity',
);
expect(selectedOptionNames).toEqual('Critical +1 more');
});
});
describe('activeFilters', () => { describe('activeFilters', () => {
it('should return no severity filters', () => { it('should return no severity filters', () => {
const state = createState(); const state = createState();
......
...@@ -5,26 +5,39 @@ import mutations from 'ee/security_dashboard/store/modules/filters/mutations'; ...@@ -5,26 +5,39 @@ import mutations from 'ee/security_dashboard/store/modules/filters/mutations';
describe('filters module mutations', () => { describe('filters module mutations', () => {
describe('SET_FILTER', () => { describe('SET_FILTER', () => {
let state; let state;
let typeFilter; let severityFilter;
let sastOption; let criticalOption;
let highOption;
beforeEach(() => { beforeEach(() => {
state = createState(); state = createState();
[typeFilter] = state.filters; [severityFilter] = state.filters;
[, sastOption] = typeFilter.options; [, criticalOption, highOption] = severityFilter.options;
mutations[types.SET_FILTER](state, { mutations[types.SET_FILTER](state, {
filterId: typeFilter.id, filterId: severityFilter.id,
optionId: sastOption.id, optionId: criticalOption.id,
}); });
}); });
it('should make SAST the selected option', () => { it('should make critical the selected option', () => {
expect(state.filters[0].options[1].selected).toEqual(true); expect(state.filters[0].options[1].selected).toEqual(true);
}); });
it('should remove ALL as the selected option', () => { it('should remove ALL as the selected option', () => {
expect(state.filters[0].options[0].selected).toEqual(false); expect(state.filters[0].options[0].selected).toEqual(false);
}); });
describe('on subsequent changes', () => {
it('should add "high" to the selected options', () => {
mutations[types.SET_FILTER](state, {
filterId: severityFilter.id,
optionId: highOption.id,
});
expect(state.filters[0].options[1].selected).toEqual(true);
expect(state.filters[0].options[2].selected).toEqual(true);
});
});
}); });
}); });
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