/* eslint-disable react-refresh/only-export-components */ import { type BaseGridColumn, type GridCell, GridCellKind } from '@glideapps/glide-data-grid'; import { ActionIcon, Select, Stack, TextInput } from '@mantine/core'; import { useDebouncedValue } from '@mantine/hooks'; import { IconX } from '@tabler/icons-react'; import { type ReactNode, useEffect, useState } from 'react'; import type { FilterOption, FilterOptionOperator, GridlerStoreState } from './GridlerStore'; export type GridCellLoose = { kind: GridCellKind | string; } & Omit; export interface GridlerColumn extends Partial { Cell?: ( row: any, col: number, colIndx: string, value: any, storeState: GridlerStoreState ) => Partial; defaultIcon?: string; disableFilter?: boolean; disableMove?: boolean; disableResize?: boolean; disableSort?: boolean; getMenuItems?: ( id: string, storeState: any, row?: any, col?: GridlerColumn, defaultItems?: Array ) => Array; id: string; maxWidth?: number; minWidth?: number; tooltip?: ((buffer: any, row: number, col: number) => ReactNode) | string; width?: number; } export const FilterOperators: Array<{ label: string; value: FilterOptionOperator }> = [ { label: 'Contains', value: 'contains' }, { label: 'Equal', value: 'eq' }, { label: 'Not Equal', value: 'neq' }, { label: 'Greater Than', value: 'gt' }, { label: 'Greater Than or Equal', value: 'gte' }, { label: 'Less Than', value: 'lt' }, { label: 'Less Than or Equal', value: 'lte' }, ]; export interface ColumnFilterSetProps { column: GridlerColumn; options?: Partial; storeState: GridlerStoreState; } export type GridlerColumns = Array; export const ColumnFilterInput = (props: ColumnFilterSetProps) => { const filterIndex = props.storeState?.colFilters?.findIndex((f) => f.id === props.column.id) ?? -1; const filter = props.storeState?.colFilters?.[filterIndex] ?? { id: props.column.id, value: '' }; const [filterValue, setFilterValue] = useState(filter?.value ?? ''); const [defferedFilterValue] = useDebouncedValue(filterValue, 900); useEffect(() => { props.storeState.setStateFN('colFilters', (state) => { const idx = state?.findIndex((f) => f.id === props.column.id) ?? -1; const filters = state ?? []; if (idx >= 0) { filters[idx] = { ...filters[idx], ...props.options, id: props.column.id, value: defferedFilterValue, }; } else { filters.push({ operator: 'contains', ...props.options, id: props.column.id, value: defferedFilterValue, }); } return filters; }); }, [defferedFilterValue, props.column.id, props.options, props.storeState]); return ( setFilterValue(e.target.value)} rightSection={ setFilterValue('')} variant="filled"> } value={filterValue ?? filter?.value} /> ); }; export const ColumnFilterInputOperator = (props: ColumnFilterSetProps) => { const filterIndex = props.storeState?.colFilters?.findIndex((f) => f.id === props.column.id) ?? -1; const filter = props.storeState?.colFilters?.[filterIndex] ?? { id: props.column.id, operator: 'contains', }; const [filterValue, setFilterValue] = useState( filter?.operator ?? 'contains' ); const [defferedFilterValue] = useDebouncedValue(filterValue, 900); useEffect(() => { props.storeState.setStateFN('colFilters', (state) => { const idx = state?.findIndex((f) => f.id === props.column.id) ?? -1; const filters = state ?? []; if (idx >= 0) { filters[idx] = { ...filters[idx], ...props.options, id: props.column.id, operator: defferedFilterValue, }; } else { filters.push({ ...props.options, id: props.column.id, operator: defferedFilterValue, value: '', }); } return filters; }); }, [defferedFilterValue, props.column.id, props.options, props.storeState]); return (