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 {
},
},
computed: {
...mapGetters('filters', ['getFilter', 'getSelectedOptions']),
...mapGetters('filters', ['getFilter', 'getSelectedOptions', 'getSelectedOptionNames']),
filter() {
return this.getFilter(this.filterId);
},
selectedOptionText() {
const [selectedOption] = this.getSelectedOptions(this.filterId);
return (selectedOption && selectedOption.name) || '-';
return this.getSelectedOptionNames(this.filterId) || '-';
},
},
methods: {
......
......@@ -6,6 +6,14 @@ export const getSelectedOptions = (state, getters) => filterId =>
export const getSelectedOptionIds = (state, getters) => filterId =>
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);
/**
......
......@@ -4,13 +4,28 @@ export default {
[types.SET_FILTER](state, payload) {
const { filterId, optionId } = payload;
const activeFilter = state.filters.find(filter => filter.id === filterId);
if (activeFilter) {
activeFilter.options = [
...activeFilter.options.map(option => ({
let activeOptions;
if (optionId === 'all') {
activeOptions = activeFilter.options.map(option => ({
...option,
selected: option.id === optionId,
})),
];
selected: option.id === 'all',
}));
} else {
activeOptions = activeFilter.options.map(option => {
const selected =
option.id === optionId ? !option.selected : option.selected && option.id !== 'all';
return {
...option,
selected,
};
});
}
activeFilter.options = activeOptions;
}
},
};
......@@ -28,14 +28,32 @@ describe('filters module getters', () => {
});
describe('getSelectedOptions', () => {
it('should return "All" as the selcted option', () => {
const state = createState();
const selectedOptions = getters.getSelectedOptions(state, mockedGetters(state))(
'report_type',
);
describe('with one selected option', () => {
it('should return "all" as the selcted option', () => {
const state = createState();
const selectedOptions = getters.getSelectedOptions(state, mockedGetters(state))(
'report_type',
);
expect(selectedOptions).toHaveLength(1);
expect(selectedOptions[0].name).toEqual('All');
});
});
expect(selectedOptions).toHaveLength(1);
expect(selectedOptions[0].name).toEqual('All');
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);
});
});
});
......@@ -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', () => {
it('should return no severity filters', () => {
const state = createState();
......
......@@ -5,26 +5,39 @@ import mutations from 'ee/security_dashboard/store/modules/filters/mutations';
describe('filters module mutations', () => {
describe('SET_FILTER', () => {
let state;
let typeFilter;
let sastOption;
let severityFilter;
let criticalOption;
let highOption;
beforeEach(() => {
state = createState();
[typeFilter] = state.filters;
[, sastOption] = typeFilter.options;
[severityFilter] = state.filters;
[, criticalOption, highOption] = severityFilter.options;
mutations[types.SET_FILTER](state, {
filterId: typeFilter.id,
optionId: sastOption.id,
filterId: severityFilter.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);
});
it('should remove ALL as the selected option', () => {
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