UNPKG

@pipe0/react-sdk

Version:

React utils to work with pipe0

142 lines (141 loc) 5.35 kB
import { getInitialSearchTableData, getSearchTableDataAggregates, } from "@pipe0/client-sdk"; import { createColumnHelper, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, useReactTable, } from "@tanstack/react-table"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; const globalFilterFn = (row, columnId, filterValue) => { const value = row.getValue(columnId); if (Array.isArray(value)) { return value.some((item) => String(item).toLowerCase().includes(filterValue.toLowerCase())); } return String(value).toLowerCase().includes(filterValue.toLowerCase()); }; function useDebounce(cb, config = {}) { const { initialValue = "", timeout = 400 } = config; const [value, setValue] = useState(initialValue); const cbRef = useRef(cb); cbRef.current = cb; const setImmediately = useCallback((v) => { setValue(v); cbRef.current(v); }, []); useEffect(() => { const handle = setTimeout(() => { cbRef.current(value); }, timeout); return () => clearTimeout(handle); }, [value, timeout]); return [value, setValue, setImmediately]; } const columnHelper = createColumnHelper(); const columns = [ columnHelper.accessor("searchId", { filterFn: "includesString", enableGlobalFilter: true, }), columnHelper.accessor((row) => row.defaultOutputFields || [], { id: "outputFields", filterFn: "arrIncludes", enableGlobalFilter: true, }), columnHelper.accessor((row) => row.tags || [], { id: "tags", filterFn: "arrIncludes", enableGlobalFilter: true, }), columnHelper.accessor((row) => row.provider, { id: "providers", enableGlobalFilter: true, }), ]; export function useSearchCatalogTable(config = {}) { const [category, setCategory] = useState(null); const { initialColumnFilters: initialColumnFilters = [] } = config; const initialSearchTableData = useMemo(() => getInitialSearchTableData(category), [category]); const table = useReactTable({ columns, data: initialSearchTableData, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel(), getFilteredRowModel: getFilteredRowModel(), globalFilterFn: globalFilterFn, getColumnCanGlobalFilter: (column) => column.columnDef.enableGlobalFilter !== false, initialState: { columnFilters: initialColumnFilters, pagination: { pageSize: 10, }, }, }); const columnFilters = table.getState().columnFilters; const { searchIdsByOutputField, searchIdsByTag, searchIdsByProvider, sortedTagEntries, sortedOutputFieldEntries, sortedProviderEntries, searchEntriesByBaseSearch, } = useMemo(() => { return getSearchTableDataAggregates(initialSearchTableData, category); }, [category, initialSearchTableData]); const [expandedSidebarSections, setExpandedSidebarSections] = useState(["tags"]); const [globalFilterInput, setGlobalFilterInput, setGlobalFilterImmediately] = useDebounce((v) => { if (v === table.getState().globalFilter) return; table.setGlobalFilter(v); if (v) { setCategory(null); table.setColumnFilters([]); } }); const addColumnFilter = (id, value) => { setGlobalFilterImmediately(""); table.setColumnFilters([ { id: "categories", value: category }, { id, value }, ]); }; const resetColumnFilters = () => { setGlobalFilterImmediately(""); table.setColumnFilters([{ id: "categories", value: null }]); }; const removeColumnFilter = (id) => { table.getColumn(id)?.setFilterValue(null); }; const isFilterChecked = (id, value) => { return columnFilters.some((f) => f.id === id && f.value === value); }; const filterByField = (id, fieldName) => { setExpandedSidebarSections([id]); setGlobalFilterImmediately(""); table.setColumnFilters([ { id: "categories", value: null }, { id, value: fieldName }, ]); }; const tableState = table.getState(); const showFeaturedSearches = !globalFilterInput && category === null && tableState.columnFilters.every((e) => e.id === "categories") && tableState.pagination.pageIndex === 0; const handleCategoryChange = useCallback((category) => { setCategory(category); table.setColumnFilters([]); setGlobalFilterImmediately(""); }, [table, setGlobalFilterImmediately]); return { table, sidebar: { sortedOutputFieldEntries, sortedTagEntries, sortedProviderEntries, searchIdsByOutputField, searchIdsByProvider, searchIdsByTag, expandedSidebarSections, setExpandedSidebarSections, removeColumnFilter, addColumnFilter, }, searchEntriesByBaseSearch, filterByField, globalFilterInput, setGlobalFilterInput, isFilterChecked, resetColumnFilters, category, setCategory: handleCategoryChange, showFeaturedSearches, }; }