{"version":3,"file":"PaginatedTable.mjs","sources":["../../../../../../../../../web/src/adminPortal/shared/components/PaginatedTable.tsx"],"sourcesContent":["import {\n  CircularProgress,\n  iconButtonClasses,\n  styled,\n  SxProps,\n  TablePagination,\n  tablePaginationClasses,\n  TablePaginationProps,\n  Theme,\n} from '@mui/material';\nimport React, { ComponentType, useRef } from 'react';\n\nimport { useUniqueId } from '../../../utils/uniqueId';\nimport { InjectedComponents } from './componentInjection';\nimport { TableCoreProps } from './Table';\nimport { useToast } from './Toast';\n\nexport const DEFAULT_TABLE_ROWS_PER_PAGE = 20;\nconst LOAD_NEXT_PAGE_ERROR = 'Failed to load the next page.';\nconst ZERO_RESULTS_MESSAGE = 'No results found.';\nconst PAGINATED_TABLE_ID = 'paginated-table';\n\nconst TablePaginationContainer = styled('div')(({ theme }) => ({\n  [`& .${tablePaginationClasses.actions} .${iconButtonClasses.root}`]: {\n    padding: theme.spacing(1),\n  },\n  alignItems: 'center',\n  display: 'flex',\n  justifyContent: 'flex-end',\n  padding: 0,\n}));\n\nconst EmptyTable = styled('div')<{ height?: number }>(({ height, theme }) => ({\n  alignItems: 'flex-start',\n  display: 'flex',\n  justifyContent: 'center',\n  padding: theme.spacing(4),\n  height,\n}));\n\nexport type PaginatedTableCoreProps<T> = TableCoreProps<T> & {\n  /**\n   * The page number currently being displayed.  0-indexed.\n   */\n  currentPage: number;\n  /**\n   * A callback to call when the next page or previous page buttons are clicked.\n   */\n  setCurrentPage(page: number): void;\n  /**\n   * The number of rows to display per page.\n   */\n  rowsPerPage?: number;\n  /**\n   * If data is loaded lazily, this function will be called when the next page is requested.\n   */\n  loadNext(): void;\n  /**\n   * Whether the table is currently loading data and should display a loading spinner.\n   */\n  isLoading?: boolean;\n  /**\n   * Metadata about the paginated data\n   * cursor: The cursor to use to fetch the next page of data\n   * total: The total number of items in the paginated data\n   */\n  metadata?: {\n    cursor: string;\n    total: number;\n  };\n  rowsPerPageOptions?: readonly number[];\n  onRowsPerPageChange?: React.ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement>;\n  keepConsistentContentHeight?: boolean;\n  tablePaginationSx?: SxProps<Theme>;\n};\n\nconst defaultRowsPerPageOptions: number[] = [];\n\nexport const PaginatedTableCore = <T extends object>({\n  currentPage,\n  loadNext,\n  isLoading,\n  metadata,\n  setCurrentPage,\n  rowsPerPage = DEFAULT_TABLE_ROWS_PER_PAGE,\n  rowsPerPageOptions = defaultRowsPerPageOptions,\n  onRowsPerPageChange,\n  keepConsistentContentHeight = true,\n  tablePaginationSx,\n  TableComponent: Table,\n  TypographyComponent: Typography,\n  ...tableProps\n}: PaginatedTableCoreProps<T> &\n  InjectedComponents<'Typography'> & { TableComponent: ComponentType<TableCoreProps<T>> }): JSX.Element => {\n  const { items } = tableProps;\n  const tableId = useUniqueId(PAGINATED_TABLE_ID);\n  const { openToast } = useToast();\n  const tableRowHeight = useRef<number>();\n  const currFirstRowIndex = currentPage * rowsPerPage;\n\n  const loadNextHandler = async (newPage: number) => {\n    tableRowHeight.current = document.querySelector(`#${tableId} tbody tr`)?.clientHeight;\n    const totalLoadedResults = items ? items.length : 0;\n    if (metadata?.cursor && totalLoadedResults <= newPage * rowsPerPage) {\n      try {\n        await loadNext();\n      } catch {\n        openToast({ type: 'error', text: LOAD_NEXT_PAGE_ERROR });\n      }\n    }\n  };\n\n  const handleChangePage: TablePaginationProps['onPageChange'] = async (_, newPage) => {\n    await loadNextHandler(newPage);\n    setCurrentPage(newPage);\n  };\n\n  const pageResults = items.slice(currFirstRowIndex, currFirstRowIndex + rowsPerPage);\n\n  const showLoading = isLoading;\n  const showNoResults = !isLoading && items.length === 0;\n  const showEmptyTable = showLoading || showNoResults;\n\n  // [BACK-3158] Some searches will return -1 to indicate that the Total count was too expensive to be returned\n  // In that case, we should _always_ show pagination controls\n  let countForPagination: number;\n  let moreRowsToShow: boolean;\n  if (metadata?.total === -1) {\n    // Pass -1 to the pagination component to enable pagination for an unknown # of items\n    // Unless there's no cursor - in which case we know the total # of items\n    countForPagination = metadata.cursor ? -1 : items.length;\n    moreRowsToShow = true;\n  } else {\n    countForPagination = metadata?.total ?? 0;\n    moreRowsToShow = (metadata?.total ?? 0) > rowsPerPage;\n  }\n\n  const showPagination = (!showEmptyTable && moreRowsToShow) || rowsPerPageOptions.length > 1;\n\n  const paginationMarginTop = (rowsPerPage - pageResults.length) * (tableRowHeight.current ?? 0) - 1;\n\n  return (\n    <div id={tableId}>\n      <Table {...tableProps} items={showEmptyTable ? [] : pageResults} />\n      {showEmptyTable && (\n        <EmptyTable\n          height={\n            tableRowHeight.current ? Math.min(rowsPerPage, pageResults.length) * tableRowHeight.current : undefined\n          }\n        >\n          {showLoading && <CircularProgress color=\"inherit\" />}\n          {showNoResults && <Typography>{ZERO_RESULTS_MESSAGE}</Typography>}\n        </EmptyTable>\n      )}\n      {showPagination && (\n        <TablePaginationContainer style={keepConsistentContentHeight ? { marginTop: paginationMarginTop } : undefined}>\n          <TablePagination\n            sx={tablePaginationSx}\n            component=\"div\"\n            count={countForPagination}\n            onPageChange={handleChangePage}\n            page={currentPage}\n            rowsPerPage={rowsPerPage}\n            rowsPerPageOptions={rowsPerPageOptions as number[]}\n            onRowsPerPageChange={onRowsPerPageChange}\n          />\n        </TablePaginationContainer>\n      )}\n    </div>\n  );\n};\n"],"names":["DEFAULT_TABLE_ROWS_PER_PAGE","LOAD_NEXT_PAGE_ERROR","ZERO_RESULTS_MESSAGE","PAGINATED_TABLE_ID","TablePaginationContainer","styled","theme","tablePaginationClasses","actions","iconButtonClasses","root","padding","spacing","alignItems","display","justifyContent","EmptyTable","height","defaultRowsPerPageOptions","PaginatedTableCore","currentPage","loadNext","isLoading","metadata","setCurrentPage","rowsPerPage","rowsPerPageOptions","onRowsPerPageChange","keepConsistentContentHeight","tablePaginationSx","TableComponent","Table","TypographyComponent","Typography","tableProps","items","tableId","useUniqueId","openToast","useToast","tableRowHeight","useRef","currFirstRowIndex","loadNextHandler","newPage","current","document","querySelector","clientHeight","totalLoadedResults","length","cursor","type","text","handleChangePage","_","pageResults","slice","showLoading","showNoResults","showEmptyTable","countForPagination","moreRowsToShow","total","showPagination","paginationMarginTop","React","div","id","Math","min","undefined","CircularProgress","color","style","marginTop","TablePagination","sx","component","count","onPageChange","page"],"mappings":"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"}