Refactor Filter type to accept Is, Is Not, Contains, Does not Contain (#128)

* Refactor Filter type to accept Is, Is Not, Contains, Does not Contain

* Remove any and add tests
This commit is contained in:
Charles Bochet
2023-05-18 15:32:57 +02:00
committed by GitHub
parent 4211d5872b
commit 5286dfd695
20 changed files with 241 additions and 336 deletions

View File

@ -1,58 +1,67 @@
import { ReactNode } from 'react';
import { SearchConfigType, SearchableType } from '../search/interface';
import { Person } from '../entities/person.interface';
import { Company } from '../entities/company.interface';
import { User } from '../entities/user.interface';
import { SearchConfigType } from '../search/interface';
import { AnyEntity, BoolExpType } from '../entities/generic.interface';
export type FilterableFieldsType = Person | Company;
export type FilterWhereType = Person | Company | User | AnyEntity;
export type FilterableFieldsType = AnyEntity;
export type FilterWhereRelationType = AnyEntity;
type UnknownType = void;
export type FilterWhereType = FilterWhereRelationType | string | UnknownType;
export type FilterConfigType<
FilteredType extends FilterableFieldsType,
WhereType extends FilterWhereType = any,
WhereType extends FilterWhereType = UnknownType,
> = {
key: string;
label: string;
icon: ReactNode;
operands: FilterOperandType<FilteredType, WhereType>[];
searchConfig: WhereType extends SearchableType
? SearchConfigType<WhereType>
: null;
selectedValueRender: (selected: WhereType) => string;
};
} & (WhereType extends UnknownType
? { searchConfig?: SearchConfigType<UnknownType> }
: WhereType extends AnyEntity
? { searchConfig: SearchConfigType<WhereType> }
: WhereType extends string
? object
: never) &
(WhereType extends UnknownType
? { selectedValueRender?: (selected: any) => string }
: WhereType extends AnyEntity
? { selectedValueRender: (selected: WhereType) => string }
: WhereType extends string
? object
: never);
export type FilterOperandType<
FilteredType extends FilterableFieldsType,
WhereType extends FilterWhereType = AnyEntity,
> =
| FilterOperandExactMatchType<FilteredType, WhereType>
| FilterOperandComparativeType<FilteredType, WhereType>;
WhereType extends FilterWhereType = UnknownType,
> = WhereType extends UnknownType
? any
: WhereType extends FilterWhereRelationType
? FilterOperandRelationType<FilteredType, WhereType>
: WhereType extends string
? FilterOperandFieldType<FilteredType>
: never;
type FilterOperandExactMatchType<
type FilterOperandRelationType<
FilteredType extends FilterableFieldsType,
WhereType extends FilterWhereType,
> = {
label: 'Equal' | 'Not equal';
id: 'equal' | 'not-equal';
label: 'Is' | 'Is not';
id: 'is' | 'is_not';
whereTemplate: (value: WhereType) => BoolExpType<FilteredType>;
};
type FilterOperandComparativeType<
FilteredType extends FilterableFieldsType,
WhereType extends FilterWhereType,
> = {
label: 'Like' | 'Not like' | 'Include';
id: 'like' | 'not_like' | 'include';
whereTemplate: (value: WhereType) => BoolExpType<FilteredType>;
type FilterOperandFieldType<FilteredType extends FilterableFieldsType> = {
label: 'Contains' | 'Does not contain';
id: 'like' | 'not_like';
whereTemplate: (value: string) => BoolExpType<FilteredType>;
};
export type SelectedFilterType<
FilteredType extends FilterableFieldsType,
WhereType extends FilterWhereType = AnyEntity,
WhereType extends FilterWhereType = UnknownType,
> = {
key: string;
value: WhereType;
value: WhereType extends UnknownType ? any : WhereType;
displayValue: string;
label: string;
icon: ReactNode;

View File

@ -5,20 +5,25 @@ import {
People_Bool_Exp,
Users_Bool_Exp,
} from '../../generated/graphql';
import { Person } from '../entities/person.interface';
import { Company } from '../entities/company.interface';
import { User } from '../entities/user.interface';
import { GqlType } from '../entities/generic.interface';
import { AnyEntity, GqlType } from '../entities/generic.interface';
export type SearchableType = Person | Company | User;
type UnknownType = void;
export type SearchConfigType<SearchType extends SearchableType> = {
query: DocumentNode;
template: (
searchInput: string,
) => People_Bool_Exp | Companies_Bool_Exp | Users_Bool_Exp;
resultMapper: (data: GqlType<SearchType>) => {
value: SearchType;
render: (value: SearchType) => ReactNode;
};
};
export type SearchConfigType<
SearchType extends AnyEntity | UnknownType = AnyEntity,
> = SearchType extends AnyEntity
? {
query: DocumentNode;
template: (
searchInput: string,
) => People_Bool_Exp | Companies_Bool_Exp | Users_Bool_Exp;
resultMapper: (data: GqlType<SearchType>) => {
value: SearchType;
render: (value: SearchType) => ReactNode;
};
}
: {
query: DocumentNode;
template: (searchInput: string) => any;
resultMapper: (data: any) => any;
};