import React from 'react'; import type {PopupProps} from '@gravity-ui/uikit'; import {HelpMark} from '@gravity-ui/uikit'; import {ResizeHandler} from './ResizeHandler'; import { ASCENDING, DEFAULT_RESIZEABLE, DEFAULT_SORT_ORDER, DEFAULT_TABLE_ROW_HEIGHT, DESCENDING, } from './constants'; import {b} from './shared'; import type { AlignType, Column, HandleTableColumnsResize, OnSort, SortOrderType, SortParams, } from './types'; // Icon similar to original DataTable icons to keep the same tables across diferent pages and tabs const SortIcon = ({order}: {order?: SortOrderType}) => { return ( ); }; interface ColumnSortIconProps { sortOrder?: SortOrderType; sortable?: boolean; defaultSortOrder: SortOrderType; } const ColumnSortIcon = ({sortOrder, sortable, defaultSortOrder}: ColumnSortIconProps) => { if (sortable) { return ( ); } else { return null; } }; const columnAlignToHelpMarkPlacement: Record> = { left: 'right', right: 'left', center: 'right', }; interface TableHeadCellProps { column: Column; resizeable?: boolean; sortOrder?: SortOrderType; defaultSortOrder: SortOrderType; onSort?: (columnName: string) => void; rowHeight: number; onColumnsResize?: HandleTableColumnsResize; } export const TableHeadCell = ({ column, resizeable, sortOrder, defaultSortOrder, onSort, rowHeight, onColumnsResize, }: TableHeadCellProps) => { const cellWrapperRef = React.useRef(null); const getCurrentColumnWidth = React.useCallback(() => { return cellWrapperRef.current?.getBoundingClientRect().width; }, []); const handleResize = React.useCallback( (newWidth: number) => { onColumnsResize?.(column.name, newWidth); }, [onColumnsResize, column.name], ); const content = column.header ?? column.name; const style = { height: `${rowHeight}px`, width: `${column.width}px`, // Additional minWidth and maxWidth for resizeable columns to ensure proper resize minWidth: resizeable ? `${column.width}px` : undefined, maxWidth: resizeable ? `${column.width}px` : undefined, }; return (
{ if (column.sortable) { onSort?.(column.name); } }} >
{content}
{column.note && ( {column.note} )}
{resizeable ? ( ) : null} ); }; interface TableHeadProps { columns: Column[]; onSort?: OnSort; onColumnsResize?: HandleTableColumnsResize; defaultSortOrder?: SortOrderType; rowHeight?: number; } export const TableHead = ({ columns, onSort, onColumnsResize, defaultSortOrder = DEFAULT_SORT_ORDER, rowHeight = DEFAULT_TABLE_ROW_HEIGHT, }: TableHeadProps) => { const [sortParams, setSortParams] = React.useState({}); const handleSort = (columnId: string) => { let newSortParams: SortParams = {}; // Order is changed in following order: // 1. Inactive Sort Order - grey icon of default order // 2. Active default order // 3. Active not default order if (columnId === sortParams.columnId) { if (sortParams.sortOrder && sortParams.sortOrder !== defaultSortOrder) { setSortParams(newSortParams); onSort?.(newSortParams); return; } const newSortOrder = sortParams.sortOrder === ASCENDING ? DESCENDING : ASCENDING; newSortParams = { sortOrder: newSortOrder, columnId: columnId, }; } else { newSortParams = { sortOrder: defaultSortOrder, columnId: columnId, }; } onSort?.(newSortParams); setSortParams(newSortParams); }; const renderTableColGroups = () => { return ( {columns.map((column) => { return ; })} ); }; const renderTableHead = () => { return ( {columns.map((column) => { const sortOrder = sortParams.columnId === column.name ? sortParams.sortOrder : undefined; const resizeable = onColumnsResize && (column.resizeable ?? DEFAULT_RESIZEABLE); return ( ); })} ); }; return ( {renderTableColGroups()} {renderTableHead()} ); };