UNPKG

@1771technologies/lytenyte-pro

Version:

Blazingly fast headless React data grid with 100s of features.

102 lines (101 loc) 3.58 kB
import { useEffect, useMemo, useState } from "react"; import { useVirtualizedTree } from "../../tree-view/virtualized/use-virtualized-tree.js"; import { useEvent } from "@1771technologies/lytenyte-core/yinternal"; export function useFilterTree({ grid, column, treeItemHeight = 24, pivotMode, applyChangesImmediately = false, query, }) { const [items, setItems] = useState([]); const [expansions, onExpansionChange] = useState({}); const [loading, setLoading] = useState(false); const [error, setError] = useState(); const rds = grid.state.rowDataSource.useValue(); const filterModel = grid.state.filterInModel.useValue(); const pivotModel = grid.state.columnPivotModel.useValue().filtersIn; const currentPivotMode = grid.state.columnPivotMode.useValue(); const model = (pivotMode ?? currentPivotMode) ? pivotModel : filterModel; const existingFilter = useMemo(() => { const filter = model[column.id]; return filter ?? { kind: "in", operator: "not_in", value: new Set() }; }, [column.id, model]); const [changes, setChanges] = useState(() => existingFilter); // Keep in sync with any external changes. useEffect(() => { setChanges(existingFilter); }, [existingFilter]); const fetchItems = useEvent(() => { const items = rds.inFilterItems(column); if ("then" in items) { setLoading(true); items .then((res) => { setItems(res); setError(null); }) .catch((error) => setError(error)) .finally(() => setLoading(false)); } else { setItems(items); setError(null); setLoading(false); } }); useEffect(() => { fetchItems(); }, [column, fetchItems, rds]); const filteredItems = useMemo(() => { if (!query) return items; return items.filter((c) => c.label.toLowerCase().includes(query.toLowerCase())); }, [items, query]); const itemsWithSelectAll = useMemo(() => { return [{ id: "__LNG__SELECT_ALL", label: "(Select All)", value: "" }, ...filteredItems]; }, [filteredItems]); const virt = useVirtualizedTree({ itemHeight: treeItemHeight, paths: itemsWithSelectAll, expansions, expansionDefault: true, nonAdjacentPathTrees: false, }); const apply = useEvent(() => { if (applyChangesImmediately) return; if (pivotMode) { grid.state.columnPivotModel.set((prev) => { return { ...prev, filtersIn: { ...prev.filtersIn, [column.id]: changes }, }; }); } else { grid.state.filterInModel.set((prev) => ({ ...prev, [column.id]: changes })); } }); const reset = useEvent(() => { if (applyChangesImmediately) return; setChanges(existingFilter); }); return { rootProps: { fetchItems, items, grid, columnId: column.id, expansions, pivotMode: pivotMode ?? currentPivotMode, onExpansionChange, treeRef: virt.ref, loading, error, filterIn: changes, filterInChange: setChanges, applyChangesImmediately, ...virt.rootProps, }, spacer: virt.spacer, tree: virt.virtualTree, apply, reset, }; }