import type { UseQueryResult } from '@tanstack/react-query'; import { Column, Row, SearchField } from '@umami/react-zen'; import { cloneElement, isValidElement, type ReactElement, type ReactNode, useCallback, useState, } from 'react'; import { Empty } from '@/components/common/Empty'; import { LoadingPanel } from '@/components/common/LoadingPanel'; import { Pager } from '@/components/common/Pager'; import { useMessages, useMobile, useNavigation } from '@/components/hooks'; import type { PageResult } from '@/lib/types'; const DEFAULT_SEARCH_DELAY = 600; export interface DataGridProps { query: UseQueryResult, any>; searchDelay?: number; allowSearch?: boolean; allowPaging?: boolean; autoFocus?: boolean; renderActions?: () => ReactNode; renderEmpty?: () => ReactNode; children: ReactNode | ((data: any) => ReactNode); } export function DataGrid({ query, searchDelay = 600, allowSearch, allowPaging = true, autoFocus, renderActions, renderEmpty = () => , children, }: DataGridProps) { const { formatMessage, labels } = useMessages(); const { data, error, isLoading, isFetching } = query; const { router, updateParams, query: queryParams } = useNavigation(); const [search, setSearch] = useState(queryParams?.search || data?.search || ''); const showPager = allowPaging && data && data.count > data.pageSize; const { isMobile } = useMobile(); const displayMode = isMobile ? 'cards' : undefined; const handleSearch = (value: string) => { if (value !== search) { setSearch(value); router.push(updateParams({ search: value, page: 1 })); } }; const handlePageChange = useCallback( (page: number) => { router.push(updateParams({ search, page })); }, [search], ); const child = data ? (typeof children === 'function' ? children(data) : children) : null; return ( {allowSearch && ( {renderActions?.()} )} {data && ( <> {isValidElement(child) ? cloneElement(child as ReactElement, { displayMode }) : child} {showPager && ( )} )} ); }