From aea1ec24efc9410a4d32e288cd0a1606f96e4dd9 Mon Sep 17 00:00:00 2001 From: Simon Larsen Date: Thu, 9 May 2024 12:01:31 +0100 Subject: [PATCH] refactor: Update EntityFilter to handle FieldType.Entity and FieldType.EntityArray filters --- .../StatementGenerator.test.ts | 4 +- .../src/Components/Filters/DropdownFilter.tsx | 61 +++++++++++++++++++ .../src/Components/Filters/EntityFilter.tsx | 6 +- CommonUI/src/Components/Filters/Filter.tsx | 15 ++++- CommonUI/src/Components/List/List.tsx | 3 +- .../Components/ModelTable/BaseModelTable.tsx | 2 +- CommonUI/src/Components/Table/Table.tsx | 3 +- 7 files changed, 86 insertions(+), 8 deletions(-) create mode 100644 CommonUI/src/Components/Filters/DropdownFilter.tsx diff --git a/CommonServer/Tests/Utils/AnalyticsDatabase/StatementGenerator.test.ts b/CommonServer/Tests/Utils/AnalyticsDatabase/StatementGenerator.test.ts index d2791cb5da..e1b0eeb767 100644 --- a/CommonServer/Tests/Utils/AnalyticsDatabase/StatementGenerator.test.ts +++ b/CommonServer/Tests/Utils/AnalyticsDatabase/StatementGenerator.test.ts @@ -199,7 +199,9 @@ describe('StatementGenerator', () => { createdAt: true, updatedAt: true, }); - expect(statement.query).toBe('{p0:Identifier}, {p1:Identifier}, {p2:Identifier}'); + expect(statement.query).toBe( + '{p0:Identifier}, {p1:Identifier}, {p2:Identifier}' + ); expect(statement.query_params).toStrictEqual({ p0: '_id', p1: 'createdAt', diff --git a/CommonUI/src/Components/Filters/DropdownFilter.tsx b/CommonUI/src/Components/Filters/DropdownFilter.tsx new file mode 100644 index 0000000000..ed233030d2 --- /dev/null +++ b/CommonUI/src/Components/Filters/DropdownFilter.tsx @@ -0,0 +1,61 @@ +import React, { ReactElement } from 'react'; +import Dropdown, { DropdownValue } from '../Dropdown/Dropdown'; +import Filter from './Types/Filter'; +import GenericObject from 'Common/Types/GenericObject'; +import FieldType from '../Types/FieldType'; +import FilterData from './Types/FilterData'; + +export interface ComponentProps { + filter: Filter; + onFilterChanged?: undefined | ((filterData: FilterData) => void); + filterData: FilterData; +} + +type DropdownFilterFunction = ( + props: ComponentProps +) => ReactElement; + +const DropdownFilter: DropdownFilterFunction = ( + props: ComponentProps +): ReactElement => { + const filter: Filter = props.filter; + const filterData: FilterData = { ...props.filterData }; + + if ( + filter.type !== FieldType.Entity && + filter.type !== FieldType.EntityArray && + filter.filterDropdownOptions + ) { + return ( + | null + ) => { + if (!filter.key) { + return; + } + + if ( + !value || + (Array.isArray(value) && value.length === 0) + ) { + delete filterData[filter.key]; + } else { + filterData[filter.key] = value; + } + + if (props.onFilterChanged) { + props.onFilterChanged(filterData); + } + }} + isMultiSelect={false} + placeholder={`Filter by ${filter.title}`} + /> + ); + } + + return <>; +}; + +export default DropdownFilter; diff --git a/CommonUI/src/Components/Filters/EntityFilter.tsx b/CommonUI/src/Components/Filters/EntityFilter.tsx index 58838692fe..97b6f3fdaa 100644 --- a/CommonUI/src/Components/Filters/EntityFilter.tsx +++ b/CommonUI/src/Components/Filters/EntityFilter.tsx @@ -22,8 +22,8 @@ const EntityFilter: EntityFilterFunction = ( const filterData: FilterData = { ...props.filterData }; if ( - filter.type !== FieldType.Entity && - filter.type !== FieldType.EntityArray && + (filter.type === FieldType.Entity || + filter.type === FieldType.EntityArray) && filter.filterDropdownOptions ) { return ( @@ -49,7 +49,7 @@ const EntityFilter: EntityFilterFunction = ( props.onFilterChanged(filterData); } }} - isMultiSelect={false} + isMultiSelect={filter.type === FieldType.EntityArray} placeholder={`Filter by ${filter.title}`} /> ); diff --git a/CommonUI/src/Components/Filters/Filter.tsx b/CommonUI/src/Components/Filters/Filter.tsx index 9ef69bb998..599656d0a1 100644 --- a/CommonUI/src/Components/Filters/Filter.tsx +++ b/CommonUI/src/Components/Filters/Filter.tsx @@ -7,6 +7,7 @@ import FilterData from './Types/FilterData'; import EntityFilter from './EntityFilter'; import BooleanFilter from './BooleanFilter'; import TextFilter from './TextFilter'; +import DropdownFilter from './DropdownFilter'; export interface ComponentProps { filters: Array>; @@ -36,7 +37,11 @@ const FilterComponent: FilterComponentFunction = ( return <>; } - const changeFilterData = (filterData: FilterData) => { + type ChangeFilterDataFunction = (filterData: FilterData) => void; + + const changeFilterData: ChangeFilterDataFunction = ( + filterData: FilterData + ): void => { setFilterData(filterData); if (props.onFilterChanged) { props.onFilterChanged(filterData); @@ -74,16 +79,24 @@ const FilterComponent: FilterComponentFunction = ( {filter.title} + + + + { diff --git a/CommonUI/src/Components/ModelTable/BaseModelTable.tsx b/CommonUI/src/Components/ModelTable/BaseModelTable.tsx index b02f2b359f..4378dec4f6 100644 --- a/CommonUI/src/Components/ModelTable/BaseModelTable.tsx +++ b/CommonUI/src/Components/ModelTable/BaseModelTable.tsx @@ -74,10 +74,10 @@ import { } from 'Common/Types/FunctionTypes'; import { GetReactElementFunction } from '../../Types/FunctionTypes'; import SelectEntityField from '../../Types/SelectEntityField'; -import { FilterData } from '../Filters/Filter'; import ClassicFilterType from '../Filters/Types/Filter'; import { getRefreshButton } from '../Card/CardButtons/Refresh'; import GroupBy from '../../Utils/BaseDatabase/GroupBy'; +import FilterData from '../Filters/Types/FilterData'; export enum ShowAs { Table, diff --git a/CommonUI/src/Components/Table/Table.tsx b/CommonUI/src/Components/Table/Table.tsx index 0611868b28..e15c302b66 100644 --- a/CommonUI/src/Components/Table/Table.tsx +++ b/CommonUI/src/Components/Table/Table.tsx @@ -8,7 +8,8 @@ import ActionButtonSchema from '../ActionButton/ActionButtonSchema'; import ErrorMessage from '../ErrorMessage/ErrorMessage'; import ComponentLoader from '../ComponentLoader/ComponentLoader'; import { DragDropContext, DropResult } from 'react-beautiful-dnd'; -import Filter, { FilterData } from '../Filters/Filter'; +import Filter from '../Filters/Filter'; +import FilterData from '../Filters/Types/FilterData'; import FilterType from '../Filters/Types/Filter'; import { GetReactElementFunction } from '../../Types/FunctionTypes'; import GenericObject from 'Common/Types/GenericObject';