import React, { cloneElement, ComponentProps, ReactElement, ReactNode, useState, } from 'react'; import {TableDataItem} from '../ui/tables/types/table-data-item'; import {BackendFilter} from './filters/backend-filter'; import {MessageDescriptor} from '../i18n/message-descriptor'; import {ColumnConfig} from './column-config'; import {useTrans} from '../i18n/use-trans'; import {useBackendFilterUrlParams} from './filters/backend-filter-url-params'; import { GetDatatableDataParams, useDatatableData, } from './requests/paginated-resources'; import {DataTableContext} from './page/data-table-context'; import {AnimatePresence, m} from 'framer-motion'; import {ProgressBar} from '../ui/progress/progress-bar'; import {Table, TableProps} from '../ui/tables/table'; import {DataTablePaginationFooter} from './data-table-pagination-footer'; import {DataTableHeader} from './data-table-header'; import {FilterList} from './filters/filter-list/filter-list'; import {SelectedStateDatatableHeader} from '@common/datatable/selected-state-datatable-header'; import clsx from 'clsx'; import {useIsMobileMediaQuery} from '@common/utils/hooks/is-mobile-media-query'; import {BackendFiltersUrlKey} from '@common/datatable/filters/backend-filters-url-key'; import {opacityAnimation} from '@common/ui/animation/opacity-animation'; import {FilterListSkeleton} from '@common/datatable/filters/filter-list/filter-list-skeleton'; export interface DataTableProps { filters?: BackendFilter[]; filtersLoading?: boolean; columns: ColumnConfig[]; searchPlaceholder?: MessageDescriptor; queryParams?: Record; endpoint: string; resourceName?: ReactNode; emptyStateMessage: ReactElement<{isFiltering: boolean}>; actions?: ReactNode; enableSelection?: boolean; selectionStyle?: TableProps['selectionStyle']; selectedActions?: ReactNode; onRowAction?: TableProps['onAction']; tableDomProps?: ComponentProps<'table'>; children?: ReactNode; collapseTableOnMobile?: boolean; cellHeight?: string; } export function DataTable({ filters, filtersLoading, columns, searchPlaceholder, queryParams, endpoint, actions, selectedActions, emptyStateMessage, tableDomProps, onRowAction, enableSelection = true, selectionStyle = 'checkbox', children, cellHeight, collapseTableOnMobile = true, }: DataTableProps) { const isMobile = useIsMobileMediaQuery(); const {trans} = useTrans(); const {encodedFilters} = useBackendFilterUrlParams(filters); const [params, setParams] = useState({perPage: 15}); const [selectedRows, setSelectedRows] = useState<(string | number)[]>([]); const query = useDatatableData( endpoint, { ...params, ...queryParams, [BackendFiltersUrlKey]: encodedFilters, }, undefined, () => setSelectedRows([]), ); const isFiltering = !!(params.query || params.filters || encodedFilters); const pagination = query.data?.pagination; return ( {children} {selectedRows.length ? ( ) : ( setParams({...params, query})} actions={actions} filters={filters} filtersLoading={filtersLoading} key="default" /> )} {filters && (
{filtersLoading && encodedFilters ? ( ) : ( )}
)}
{query.isFetching && ( )}
{ setParams({...params, ...descriptor}); }} selectedRows={selectedRows} enableSelection={enableSelection} selectionStyle={selectionStyle} onSelectionChange={setSelectedRows} onAction={onRowAction} collapseOnMobile={collapseTableOnMobile} cellHeight={cellHeight} /> {(query.isFetched || query.isPlaceholderData) && !pagination?.data.length ? (
{cloneElement(emptyStateMessage, { isFiltering, })}
) : undefined} setParams({...params, page})} onPerPageChange={perPage => setParams({...params, perPage})} /> ); }