From ce9db575a63e1ab4e74826d426b4e044e4a41b42 Mon Sep 17 00:00:00 2001 From: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:21:11 -0500 Subject: [PATCH] fix: table search filter (#683) --- .../sort-and-filter-modal/utils.js | 15 ++- .../sort-and-filter-modal/utils.test.js | 25 ++++ .../generic/table-components/utils.js | 22 +++- .../generic/table-components/utils.test.js | 109 ++++++++++++++++++ 4 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 src/files-and-videos/generic/table-components/utils.test.js diff --git a/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.js b/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.js index 9f3f738f3..149aed54c 100644 --- a/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.js +++ b/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.js @@ -1,4 +1,4 @@ -import { isEmpty } from 'lodash'; +import { isArray, isEmpty } from 'lodash'; export const getFilterOptions = (columns) => { const allOptions = []; @@ -37,7 +37,6 @@ export const getFilterOptions = (columns) => { export const getCheckedFilters = (state) => { const { filters } = state; const allFilters = []; - filters.forEach(filter => { const { id, value } = filter; let updatedValues = value; @@ -56,7 +55,11 @@ export const getCheckedFilters = (state) => { break; } - allFilters.push(...updatedValues); + if (isArray(updatedValues)) { + allFilters.push(...updatedValues); + } else { + allFilters.push([id, updatedValues]); + } }); return allFilters; @@ -66,6 +69,12 @@ export const processFilters = (filters, columns, setAllFilters) => { const filterableColumns = columns.filter(column => column?.filterChoices); const allFilters = []; + const [displayNameFilter] = filters.filter(filter => isArray(filter)); + if (displayNameFilter) { + const [id, filterValue] = displayNameFilter; + allFilters.push({ id, value: [filterValue] }); + } + filterableColumns.forEach(({ id, filterChoices }) => { const filterValues = filterChoices.map(choice => choice.value); let processedFilters = filters; diff --git a/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.test.js b/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.test.js index 39d37b2f2..55fdb3a24 100644 --- a/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.test.js +++ b/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.test.js @@ -92,6 +92,18 @@ describe('getCheckboxFilters', () => { expect(actual).toEqual(expected); }); }); + + describe('filter with serach bar', () => { + it('should equal array in array with displayName and value', () => { + const state = { + filters: [{ id: 'displayName', value: 'filter' }], + }; + const expected = [['displayName', 'filter']]; + const actual = getCheckedFilters(state); + + expect(actual).toEqual(expected); + }); + }); }); describe('getFilterOptions', () => { @@ -301,4 +313,17 @@ describe('processFilters', () => { expect(setAllFilters).toHaveBeenCalledWith(expectedParameter); }); }); + + describe('filter with serach bar', () => { + it('should call setAllFitlers with displayName filter', () => { + const filters = [['displayName', 'search']]; + const columns = [ + { id: 'test', filterChoices: [{ name: 'Filter', value: 'filter' }] }, + ]; + const expectedParameter = [{ id: 'displayName', value: ['search'] }]; + processFilters(filters, columns, setAllFilters); + + expect(setAllFilters).toHaveBeenCalledWith(expectedParameter); + }); + }); }); diff --git a/src/files-and-videos/generic/table-components/utils.js b/src/files-and-videos/generic/table-components/utils.js index d4bb6fd9d..15dc4ea86 100644 --- a/src/files-and-videos/generic/table-components/utils.js +++ b/src/files-and-videos/generic/table-components/utils.js @@ -1,4 +1,4 @@ -import { isEmpty } from 'lodash'; +import { isEmpty, isArray } from 'lodash'; import messages from '../messages'; const getFilterDisplayName = (column, values) => { @@ -15,19 +15,35 @@ export const getFilters = (state, columns) => { const { filters } = state; const filterableColumns = columns.filter(column => column?.filterChoices); const allFilters = []; + filters.forEach(filter => { const { id, value } = filter; const [filterColumn] = filterableColumns.filter(column => column.id === id); - const currentFilters = getFilterDisplayName(filterColumn, value); + let currentFilters; + + if (filterColumn) { + currentFilters = getFilterDisplayName(filterColumn, value); + } else { + const [serachValue] = value; + currentFilters = [{ name: serachValue, value: serachValue }]; + } allFilters.push(...currentFilters); }); + return allFilters; }; export const removeFilter = (filter, setFilter, setAllFilters, state) => { const { filters } = state; const [editedFilter] = filters.filter(currentFilter => currentFilter.value.includes(filter)); - const updatedFilterValue = editedFilter.value.filter(value => value !== filter); + + let updatedFilterValue; + if (isArray(editedFilter?.value)) { + updatedFilterValue = editedFilter.value.filter(value => value !== filter); + } else { + updatedFilterValue = filter.includes(editedFilter?.value) ? [] : editedFilter.value; + } + if (isEmpty(updatedFilterValue)) { const updatedFilters = filters.filter(currentFilter => currentFilter.id !== editedFilter.id); setAllFilters(updatedFilters); diff --git a/src/files-and-videos/generic/table-components/utils.test.js b/src/files-and-videos/generic/table-components/utils.test.js new file mode 100644 index 000000000..cd9fd1063 --- /dev/null +++ b/src/files-and-videos/generic/table-components/utils.test.js @@ -0,0 +1,109 @@ +import { getCurrentViewRange, getFilters, removeFilter } from './utils'; + +describe('getCurrentViewRange', () => { + const intl = { + formatMessage: (name, { fileCount, rowCount }) => ( + `Showing ${fileCount} of ${rowCount}` + ), + }; + + it('should return with intials row count', () => { + const data = { + filterRowCount: 25, + initialRowCount: 25, + fileCount: 12, + intl, + }; + const expected = 'Showing 12 of 25'; + const actual = getCurrentViewRange(data); + + expect(actual).toEqual(expected); + }); + + it('should return with filter row count', () => { + const data = { + filterRowCount: 12, + initialRowCount: 25, + fileCount: 12, + intl, + }; + const expected = 'Showing 12 of 12'; + const actual = getCurrentViewRange(data); + + expect(actual).toEqual(expected); + }); +}); + +describe('getFilters', () => { + it('should return filter when columns is empty', () => { + const state = { filters: [{ id: 'test', value: ['unknown'] }] }; + const columns = []; + const expected = [{ name: 'unknown', value: 'unknown' }]; + const actual = getFilters(state, columns); + + expect(actual).toEqual(expected); + }); + + it('should return filtern for specific column', () => { + const state = { filters: [{ id: 'validColumn', value: ['filter1'] }] }; + const columns = [{ + id: 'validColumn', + filterChoices: [ + { name: 'Filter 1', value: 'filter1' }, + { name: 'Filter 2', value: 'filter2' }, + ], + }]; + const expected = [{ name: 'Filter 1', value: 'filter1' }]; + const acutal = getFilters(state, columns); + + expect(acutal).toEqual(expected); + }); +}); + +describe('removeFilter', () => { + const setAllFilters = jest.fn(); + const setFilter = jest.fn(); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('state filter.value is an array', () => { + it('should call setAllFilters', () => { + const state = { + filters: [ + { id: 'test', value: ['filter1'] }, + ], + }; + const filter = 'filter1'; + removeFilter(filter, setFilter, setAllFilters, state); + + expect(setAllFilters).toHaveBeenCalled(); + }); + + it('should call setFilter', () => { + const state = { + filters: [ + { id: 'test', value: ['filter1', 'filter2'] }, + ], + }; + const filter = 'filter1'; + removeFilter(filter, setFilter, setAllFilters, state); + + expect(setFilter).toHaveBeenCalled(); + }); + }); + describe('state filter.value is not an array', () => { + it('should call setAllFilters', () => { + const state = { + filters: [ + { id: 'test', value: 'filter1' }, + ], + }; + const filter = 'filter1'; + removeFilter(filter, setFilter, setAllFilters, state); + + expect(setAllFilters).toHaveBeenCalled(); + }); + }); +});