import { useEffect } from "react" import type { Fields, Filters, FinalSchemas, GetSchemaFromName, GetSchemaNames, Include, Meta, RecordType, PaginationObject, } from "@hatchifyjs/rest-client" import type { PartialSchema } from "@hatchifyjs/core" import type { HatchifyReactRest } from "@hatchifyjs/react-rest" import type { HatchifyDataGridPage, HatchifyDataGridSelectedState, HatchifyDataGridSort, SortObject, } from "../presentation/index.js" import usePage from "./usePage.js" import useSort from "./useSort.js" import useSelected from "./useSelected.js" import useFilter from "./useFilter.js" export interface DataGridState< TSchemas extends Record, TSchemaName extends GetSchemaNames, > { data: Array< RecordType, false, true> > meta: Meta fields?: Fields include?: Include> filter: Filters setFilter: (filters: Filters) => void page: HatchifyDataGridPage["page"] setPage: HatchifyDataGridPage["setPage"] sort: HatchifyDataGridSort["sort"] setSort: HatchifyDataGridSort["setSort"] selected?: HatchifyDataGridSelectedState setSelected?: (selected: HatchifyDataGridSelectedState) => void finalSchemas: FinalSchemas partialSchemas: TSchemas schemaName: TSchemaName } export default function useDataGridState< const TSchemas extends Record, const TSchemaName extends GetSchemaNames, >( finalSchemas: FinalSchemas, partialSchemas: TSchemas, schemaName: TSchemaName, restClient: HatchifyReactRest, { defaultSelected, onSelectedChange, fields, include, defaultPage, defaultSort, alwaysSorted, baseFilter, minimumLoadTime, }: { defaultSelected?: HatchifyDataGridSelectedState onSelectedChange?: (selected: HatchifyDataGridSelectedState) => void fields?: Fields include?: Include> defaultPage?: PaginationObject defaultSort?: SortObject alwaysSorted?: boolean baseFilter?: Filters minimumLoadTime?: number } = {}, ): DataGridState { if (typeof schemaName !== "string") { throw new Error( `Expected schemaName to be a string, received ${typeof schemaName}`, ) } const { page, setPage } = usePage(defaultPage) const { sort, sortQueryString, setSort } = useSort(defaultSort, alwaysSorted) const { filter, setFilter } = useFilter() const { selected, setSelected } = useSelected( defaultSelected, onSelectedChange, ) const [data, meta] = restClient[schemaName].useAll( { page, sort: sortQueryString, filter, fields, include, }, baseFilter, minimumLoadTime, ) useEffect(() => { setSelected({ all: selected?.all ? data.length > 0 : false, ids: selected?.all ? data.map((record) => record.id) : [], }) }, [data]) return { data, meta, fields, include, filter, setFilter, page, setPage, sort, setSort, selected: onSelectedChange !== undefined ? selected : undefined, setSelected: onSelectedChange !== undefined ? setSelected : undefined, finalSchemas, partialSchemas, schemaName, } }