type NonEmptyArray<T> = [T, ...T[]];
export type AnyTableViewModelBase = Record<string, unknown>;
export type TablePaginationDefinition = null | {
parPage: number;
};
export type TableKeywordSearchDefinition = null | {
renderSearchInput: (props: {
value: string;
onChange: (value: string) => void;
}) => ReactNode;
encode: (value: string) => string;
decode: (value: string) => string | null;
};
export type NonNullColumnFilterDefinition<
TableViewModelBaseType extends AnyTableViewModelBase,
FilterCondition = any
> = {
renderPopupContent: (props: {
rows: TableViewModelBaseType[];
filter: FilterCondition | null;
setFilter: (filter: FilterCondition | null) => void;
isOpen: boolean;
onClose: () => void;
}) => ReactNode;
renderFilterChipContent: (props: { filter: FilterCondition }) => ReactNode;
encode: (filter: FilterCondition | null) => unknown;
decode: (filter: unknown) => FilterCondition | null;
initial: FilterCondition | null;
};
export type ColumnFilterDefinition<
TableViewModelBaseType extends AnyTableViewModelBase,
FilterCondition = any
> = null | NonNullColumnFilterDefinition<
TableViewModelBaseType,
FilterCondition
>;
export type ColumnVisibilityDefinition = {
initialVisibility: boolean;
};
export type ColumnDefinition<
TableViewModelType extends AnyTableViewModelBase,
K extends keyof TableViewModelType = keyof TableViewModelType,
TColumnFilterDefinition extends ColumnFilterDefinition<TableViewModelType> = ColumnFilterDefinition<TableViewModelType>,
TColumnSortDefinition extends boolean = boolean
> = {
key: K;
filter: TColumnFilterDefinition;
sortable: TColumnSortDefinition;
visibility: ColumnVisibilityDefinition;
renderHeadCell: () => string;
renderBodyCell: (props: {
rowIndex: number;
row: TableViewModelType;
data: TableViewModelType[];
}) => ReactNode;
};
export type TableDefinition<
TableViewModelBaseType extends AnyTableViewModelBase,
TablePaginationDefinitionType extends TablePaginationDefinition = TablePaginationDefinition,
TableKeywordSearchDefinitionType extends TableKeywordSearchDefinition = TableKeywordSearchDefinition,
ColumnDefinitions extends Array<
ColumnDefinition<TableViewModelBaseType>
> = Array<ColumnDefinition<TableViewModelBaseType>>
> = {
key: string;
pagination: TablePaginationDefinitionType;
keywordSearch: TableKeywordSearchDefinitionType;
columns: ColumnDefinitions;
};
export type TableKeywordSearchState<
TableViewModelBaseType extends AnyTableViewModelBase,
TableDefinitionType extends TableDefinition<TableViewModelBaseType>
> =
TableDefinitionType extends TableDefinition<
TableViewModelBaseType,
TablePaginationDefinition,
infer TableKeywordSearchDefinitionInfer extends TableKeywordSearchDefinition
>
? TableKeywordSearchDefinitionInfer extends null
? undefined
: string
: never;
type AnyTableSortState<
SortBy extends string = string,
SortOrder extends "asc" | "desc" = "asc" | "desc"
> = {
sortBy: SortBy;
sortOrder: SortOrder;
};
export type TableSortState<
TableViewModelBaseType extends AnyTableViewModelBase,
TableDefinitionType extends TableDefinition<TableViewModelBaseType>
> =
TableDefinitionType extends TableDefinition<
TableViewModelBaseType,
TablePaginationDefinition,
TableKeywordSearchDefinition,
infer ColumnDefinitionsInfer
>
? ColumnsSortKey<
TableViewModelBaseType,
ColumnDefinitionsInfer
> extends string
?
| AnyTableSortState<
ColumnsSortKey<TableViewModelBaseType, ColumnDefinitionsInfer>
>
| undefined
: undefined
: never;
type TableSortKey<
TableViewModelBaseType extends AnyTableViewModelBase,
TableDefinitionType extends TableDefinition<TableViewModelBaseType>
> = TableDefinitionType extends TableDefinition<
TableViewModelBaseType,
TablePaginationDefinition,
TableKeywordSearchDefinition,
infer ColumnDefinitions
>
? ColumnsSortKey<TableViewModelBaseType, ColumnDefinitions>
: never;
type ColumnsSortKey<
TableViewModelBaseType extends AnyTableViewModelBase,
ColumnDefinitions extends Array<ColumnDefinition<TableViewModelBaseType>>
> =
number extends ColumnDefinitions["length"]
? never
: ColumnDefinitions extends [
ColumnDefinition<
TableViewModelBaseType,
infer Key,
ColumnFilterDefinition<TableViewModelBaseType>,
infer ColumnSortDefinitionType
>,
...infer RestColumnDefinitions
]
?
| ColumnSortState<TableViewModelBaseType, Key, ColumnSortDefinitionType>
| (RestColumnDefinitions extends NonEmptyArray<
ColumnDefinition<TableViewModelBaseType>
>
?
ColumnsSortKey<TableViewModelBaseType, RestColumnDefinitions>
: never)
: never;
type ColumnSortState<
TableViewModelBaseType extends AnyTableViewModelBase,
Key extends keyof TableViewModelBaseType = keyof TableViewModelBaseType,
ColumnSortableDefinitionType extends boolean = boolean
> = ColumnSortableDefinitionType extends true ? Key : never;
type TableColumnVisibilityState<
TableViewModelBaseType extends AnyTableViewModelBase
> = Array<keyof TableViewModelBaseType>;
type TablePaginationState<
TableViewModelBaseType extends AnyTableViewModelBase,
TableDefinitionType extends TableDefinition<TableViewModelBaseType>
> =
TableDefinitionType extends TableDefinition<
TableViewModelBaseType,
infer TablePaginationDefinitionInfer
>
? TablePaginationDefinitionInfer extends null
? undefined
: number
: never;
type TableFilterColumnState<
TableViewModelBaseType extends AnyTableViewModelBase,
TableDefinitionType extends TableDefinition<TableViewModelBaseType>
> =
TableDefinitionType extends TableDefinition<
TableViewModelBaseType,
TablePaginationDefinition,
TableKeywordSearchDefinition,
infer ColumnDefinitions
>
? ColumnsFilterState<TableViewModelBaseType, ColumnDefinitions>
: never;
type ColumnsFilterState<
TableViewModelBaseType extends AnyTableViewModelBase,
ColumnDefinitions extends Array<ColumnDefinition<TableViewModelBaseType>>
> =
number extends ColumnDefinitions["length"]
? never
:
ColumnDefinitions extends [
ColumnDefinition<
TableViewModelBaseType,
infer Key,
infer ColumnFilterDefinitionType
>,
...infer RestColumnDefinitions
]
? ColumnFilterState<
TableViewModelBaseType,
Key,
ColumnFilterDefinitionType
> &
(RestColumnDefinitions extends NonEmptyArray<
ColumnDefinition<TableViewModelBaseType>
>
? ColumnsFilterState<TableViewModelBaseType, RestColumnDefinitions>
: Record<never, never>)
: never;
type ColumnFilterState<
TableViewModelBaseType extends AnyTableViewModelBase,
Key extends keyof TableViewModelBaseType,
ColumnFilterDefinitionType extends ColumnFilterDefinition<TableViewModelBaseType>
> = ColumnFilterDefinitionType extends null
? Record<never, never>
: ColumnFilterDefinitionType extends ColumnFilterDefinition<
TableViewModelBaseType,
infer FilterConditionInfer
>
? {
[key in Key]: FilterConditionInfer | null;
}
: never;
type TableColumnFilterCondition<
TableViewModelBaseType extends AnyTableViewModelBase,
TableDefinitionType extends TableDefinition<TableViewModelBaseType>,
ColumnKey extends keyof TableViewModelBaseType
> =
TableDefinitionType extends TableDefinition<
TableViewModelBaseType,
TablePaginationDefinition,
TableKeywordSearchDefinition,
infer ColumnDefinitions
>
? ColumnDefinitions[number] &
ColumnDefinition<
TableViewModelBaseType,
ColumnKey
> extends ColumnDefinition<
TableViewModelBaseType,
ColumnKey,
ColumnFilterDefinition<
TableViewModelBaseType,
infer FilterConditionInfer
>
>
? FilterConditionInfer
: never
: never;
export type TableState<
TableViewModelBaseType extends AnyTableViewModelBase,
TableDefinitionType extends TableDefinition<TableViewModelBaseType>
> = {
keywordSearch: TableKeywordSearchState<
TableViewModelBaseType,
TableDefinitionType
>;
sort: TableSortState<TableViewModelBaseType, TableDefinitionType>;
columnVisibility: TableColumnVisibilityState<TableViewModelBaseType>;
pagination: TablePaginationState<TableViewModelBaseType, TableDefinitionType>;
filter: TableFilterColumnState<TableViewModelBaseType, TableDefinitionType>;
};