///
import { createContext, useContext, useEffect, useMemo, useState } from 'react';
import {
Column as TableColumn,
CellProps as TableCellProps,
CoreUIColumn,
HeaderGroup,
IdType,
Row,
SortByFn,
TableBodyPropGetter,
TableBodyProps,
useBlockLayout,
useExpanded,
useFilters,
useGlobalFilter,
useRowSelect,
useSortBy,
useTable,
defaultColumn,
} from 'react-table';
import { useMemoCompare } from '../../hooks';
import { Box } from '../box/Box';
import { ConstrainedText } from '../constrainedtext/Constrainedtext.component';
import { Tooltip } from '../tooltip/Tooltip.component';
import { MultiSelectableContent } from './MultiSelectableContent';
import { TableSearch as Search } from './Search';
import { SearchWithQueryParams } from './SearchWithQueryParams';
import { SingleSelectableContent } from './SingleSelectableContent';
import { TableWrapper, TooltipContent } from './Tablestyle';
import { compareHealth, TableHeightKeyType } from './TableUtils';
import { useCheckbox } from './useCheckbox';
import { Icon } from '../icon/Icon.component';
import { TableSync } from './TableSync';
type UpdateTableData<
DATA_ROW extends Record = Record,
> = {
updateTableData?: (
rowId: string,
columnName: DATA_ROW_KEY,
value: DATA_ROW[DATA_ROW_KEY],
) => void;
};
export type Column> = CoreUIColumn;
export type CellProps<
D extends Record,
V = unknown,
> = TableCellProps & UpdateTableData;
export type TableProps<
DATA_ROW extends Record = Record,
> = {
columns: Array>;
defaultSortingKey?: string;
// We don't display the default sort key in the URL, so we need to specify here
data: DATA_ROW[];
children: JSX.Element | JSX.Element[];
getRowId?: (
originalRow: DATA_ROW,
relativeIndex: number,
parent?: Row,
) => string;
sortTypes?: Record>;
globalFilter?: string;
onBottom?: (rowLength: number) => void;
onBottomOffset?: number;
allFilters?: { id: string; value: string }[];
status?: 'idle' | 'loading' | 'error' | 'success';
entityName?: {
en: { singular: string; plural: string };
fr?: { singular: string; plural: string };
};
initiallySelectedRowsIds?: Set;
//To call it from the Cell renderer to update the original data
} & UpdateTableData;
type setHiddenColumnFuncType = (oldHidden: string[]) => string[];
type TableContextType<
DATA_ROW extends Record = Record,
> = {
headerGroups: HeaderGroup[];
rows: Row[];
prepareRow: (row: Row) => void;
getTableBodyProps: (
propGetter?: TableBodyPropGetter,
) => TableBodyProps;
rowHeight: TableHeightKeyType;
setRowHeight: (rowHeight: TableHeightKeyType) => void;
selectedRowIds: Record;
selectedFlatRows: Row[];
preGlobalFilteredRows: Row[];
setGlobalFilter: (filterValue: string) => void;
globalFilter: any;
setFilter: (columnId: string, updater: any) => void;
onBottom?: (rowLength: number) => void;
onBottomOffset?: number;
setHiddenColumns: (param: string[] | setHiddenColumnFuncType) => void;
isAllRowsSelected?: boolean;
toggleAllRowsSelected: (value?: boolean) => void;
status?: 'idle' | 'loading' | 'error' | 'success';
entityName?: {
en: { singular: string; plural: string };
fr?: { singular: string; plural: string };
};
syncScrollListener: ((event: Event) => void) | null;
setSyncScrollListener: (listener: (event: Event) => void) => void;
setHasScrollbar: React.Dispatch>;
hasScrollbar?: boolean;
};
const TableContext = createContext(null);
export const useTableContext = <
DATA_ROW extends Record = Record,
>() => {
const tableProps = useContext(TableContext);
if (!tableProps) {
throw new Error(
'The useTableContext hook can only be used within the ',
);
}
return tableProps as TableContextType; //Todo figure out a way to transfer the type to the context provider
};
export const EmptyCell = ({
tooltipContent,
mr = 4,
}: {
tooltipContent?: string | JSX.Element;
mr?: number;
}) => {
return (
{tooltipContent || 'unknown'}}
>
);
};
const DefaultRenderer = ({ value }) => {
const { rowHeight } = useTableContext();
if (!value && value !== 0) {
return ;
}
if (typeof value === 'string') {
const lineClamp =
rowHeight === 'h32'
? 1
: rowHeight === 'h40' || rowHeight === 'h48'
? 2
: 3;
return (
);
}
return value;
};
function Table<
DATA_ROW extends Record = Record,
>({
columns,
data,
defaultSortingKey,
getRowId,
children,
sortTypes,
globalFilter,
allFilters,
onBottom,
onBottomOffset = 10,
initiallySelectedRowsIds,
updateTableData,
status,
entityName,
}: TableProps) {
sortTypes = {
health: (row1, row2) => {
return compareHealth(row2.values.health, row1.values.health) || 0;
},
...sortTypes,
};
const stringifyFilter = useMemo(() => {
return (rows: Row