UNPKG

@pipe0/react-sdk

Version:

React utils to work with pipe0

159 lines (158 loc) 6.2 kB
import { getDefaultOutputFields, getDefaultPipeProviders, getInitialTableData, getTableDataAggregates, } 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("pipeId", { filterFn: "includesString", enableGlobalFilter: true, }), columnHelper.accessor((row) => row.defaultInputGroups.flatMap((g) => Object.keys(g.fields)) || [], { id: "inputFields", filterFn: "arrIncludes", enableGlobalFilter: true, }), columnHelper.accessor((row) => getDefaultOutputFields(row) || [], { id: "outputFields", filterFn: "arrIncludes", enableGlobalFilter: true, }), columnHelper.accessor((row) => row.tags || [], { id: "tags", filterFn: "arrIncludes", enableGlobalFilter: true, }), columnHelper.accessor((row) => getDefaultPipeProviders(row.pipeId) || [], { id: "providers", filterFn: "arrIncludes", enableGlobalFilter: true, }), columnHelper.accessor((row) => row.categories || [], { id: "categories", filterFn: "arrIncludes", enableGlobalFilter: true, }), ]; export function usePipeCatalogTable(config = {}) { const { initialColumnFilters: initialColumnFilters = [] } = config; const initialTableData = useMemo(() => getInitialTableData(), []); const table = useReactTable({ columns, data: initialTableData, 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 category = useMemo(() => columnFilters.find((e) => e.id === "categories" && e.value) ?.value || 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) => { 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) { table.setColumnFilters([]); } }); const addColumnFilter = useCallback((id, value) => { setGlobalFilterImmediately(""); table.setColumnFilters([ { id: "categories", value: category }, { id, value }, ]); }, [category, setGlobalFilterImmediately, table]); const resetColumnFilters = useCallback(() => { setGlobalFilterImmediately(""); table.setColumnFilters([{ id: "categories", value: null }]); }, [setGlobalFilterImmediately, table]); 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 filterByField = useCallback((id, fieldName) => { setExpandedSidebarSections([id]); setGlobalFilterImmediately(""); table.setColumnFilters([ { id: "categories", value: null }, { 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, showFeaturedPipes, }; }