UNPKG

@pipe0/react-sdk

Version:

React utils to work with pipe0

178 lines (177 loc) 6.79 kB
import { getDefaultOutputFields, getDefaultPipeProviders, getInitialTableData, getTableDataAggregates, } from "@pipe0/ops"; import { createColumnHelper, getCoreRowModel, getFilteredRowModel, useReactTable, } from "@tanstack/react-table"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { fuzzyFilter } from "../utils/helpers.js"; 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("pipeId", { filterFn: "includesString", enableGlobalFilter: true, }), columnHelper.accessor("label", { filterFn: "fuzzy", enableGlobalFilter: true, }), columnHelper.accessor("description", { filterFn: "fuzzy", enableGlobalFilter: true, }), columnHelper.accessor((row) => row.defaultInputGroups.flatMap((g) => Object.keys(g.fields)) || [], { id: "inputFields", filterFn: "arrIncludes", enableGlobalFilter: false, }), columnHelper.accessor((row) => getDefaultOutputFields(row) || [], { id: "outputFields", filterFn: "arrIncludes", enableGlobalFilter: false, }), columnHelper.accessor((row) => row.tags || [], { id: "tags", filterFn: "arrIncludes", enableGlobalFilter: true, }), columnHelper.accessor((row) => getDefaultPipeProviders(row.pipeId) || [], { id: "providers", filterFn: "arrIncludes", enableGlobalFilter: true, }), ]; export function usePipeCatalogTable(config = {}) { const [category, setCategory] = useState(null); const { initialColumnFilters: initialColumnFilters = [] } = config; const initialTableData = useMemo(() => getInitialTableData(category), [category]); const table = useReactTable({ columns, data: initialTableData, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), globalFilterFn: fuzzyFilter, filterFns: { fuzzy: fuzzyFilter, }, getColumnCanGlobalFilter: (column) => column.columnDef.enableGlobalFilter !== false, initialState: { columnFilters: initialColumnFilters, pagination: { pageSize: 10, }, }, }); const columnFilters = table.getState().columnFilters; // const category: PipeCategory | null = useMemo( // () => // (columnFilters.find((e) => e.id === "categories" && e.value) // ?.value as PipeCategory) || null, // [columnFilters] // ); const { pipeIdsByInputField, pipeIdsByOutputField, pipeIdsByTag, pipeIdsByProvider, sortedTagEntries, sortedInputFieldEntries, sortedOutputFieldEntries, sortedProviderEntries, pipeEntriesByBasePipe, } = useMemo(() => { return getTableDataAggregates(initialTableData, category); }, [category, initialTableData]); const [expandedSidebarSections, setExpandedSidebarSections] = useState(["tags"]); // const setCategory = useCallback( // (category: PipeCategory | null) => { // table.setGlobalFilter(null); // if (category) { // table.setColumnFilters([{ id: "categories", value: category }]); // } else { // table.setColumnFilters([]); // } // }, // [table] // ); const [globalFilterInput, setGlobalFilterInput, setGlobalFilterImmediately] = useDebounce((v) => { if (v === table.getState().globalFilter) return; table.setGlobalFilter(v); if (v) { setCategory(null); table.setColumnFilters([]); } }); const addColumnFilter = useCallback((id, value) => { setGlobalFilterImmediately(""); table.setColumnFilters([{ id, value }]); }, [setGlobalFilterImmediately, table]); const handleCategoryChange = useCallback((category) => { setCategory(category); table.setColumnFilters([]); setGlobalFilterImmediately(""); }, [table, setGlobalFilterImmediately]); const resetColumnFilters = useCallback(() => { setGlobalFilterImmediately(""); setCategory(null); }, [setGlobalFilterImmediately]); const removeColumnFilter = useCallback((id) => { table.getColumn(id)?.setFilterValue(null); }, [table]); const isFilterChecked = useCallback((id, value) => { return columnFilters.some((f) => f.id === id && f.value === value); }, [columnFilters]); const getColumnFilterValue = useCallback((id) => { const res = columnFilters.find((f) => f.id === id)?.value; return res; }, [columnFilters]); const filterByField = useCallback((id, fieldName) => { setExpandedSidebarSections([id]); setGlobalFilterImmediately(""); setCategory(null); table.setColumnFilters([{ id, value: fieldName }]); }, [table, setExpandedSidebarSections, setGlobalFilterImmediately]); const tableState = table.getState(); const showFeaturedPipes = !globalFilterInput && category === null && tableState.columnFilters.every((e) => e.id === "categories") && tableState.pagination.pageIndex === 0; return { table, sidebar: { sortedInputFieldEntries, sortedOutputFieldEntries, sortedTagEntries, sortedProviderEntries, pipeIdsByInputField, pipeIdsByOutputField, pipeIdsByProvider, pipeIdsByTag, expandedSidebarSections, setExpandedSidebarSections, removeColumnFilter, addColumnFilter, }, pipeEntriesByBasePipe, filterByField, globalFilterInput, setGlobalFilterInput, isFilterChecked, resetColumnFilters, category, setCategory: handleCategoryChange, showFeaturedPipes, getColumnFilterValue, }; }