import { Button, Menu, MenuItem, MenuList, MenuPopover, MenuTrigger, TableRowData as RowStateBase, Table, TableBody, TableCell, TableCellLayout, TableColumnDefinition, TableColumnSizingOptions, TableHeader, TableHeaderCell, TableRow, TableRowId, TableSelectionCell, createTableColumn, useArrowNavigationGroup, useFluent, useScrollbarWidth, useTableColumnSizing_unstable, useTableFeatures, useTableSelection, } from "@fluentui/react-components"; import { ArrowClockwise16Filled } from "@fluentui/react-icons"; import React, { useEffect, useMemo } from "react"; import { FixedSizeList as List, ListChildComponentProps } from "react-window"; export type DocumentsTableComponentItem = { id: string; } & Record; export type ColumnHeaders = { idHeader: string; partitionKeyHeaders: string[]; }; export interface IDocumentsTableComponentProps { items: DocumentsTableComponentItem[]; onItemClicked: (index: number) => void; onSelectedRowsChange: (selectedItemsIndices: Set) => void; selectedRows: Set; size: { height: number; width: number }; columnHeaders: ColumnHeaders; onRefreshClicked: () => void; style?: React.CSSProperties; } interface TableRowData extends RowStateBase { onClick: (e: React.MouseEvent) => void; onKeyDown: (e: React.KeyboardEvent) => void; selected: boolean; appearance: "brand" | "none"; } interface ReactWindowRenderFnProps extends ListChildComponentProps { data: TableRowData[]; } export const DocumentsTableComponent: React.FC = ({ items, onItemClicked, onSelectedRowsChange, selectedRows, style, size, columnHeaders, onRefreshClicked, }: IDocumentsTableComponentProps) => { const { targetDocument } = useFluent(); const scrollbarWidth = useScrollbarWidth({ targetDocument }); const [activeItemIndex, setActiveItemIndex] = React.useState(undefined); const initialSizingOptions: TableColumnSizingOptions = { id: { idealWidth: 280, // minWidth: 273, }, }; columnHeaders.partitionKeyHeaders.forEach((pkHeader) => { initialSizingOptions[pkHeader] = { idealWidth: 200, minWidth: 50, }; }); const [columnSizingOptions, setColumnSizingOptions] = React.useState(initialSizingOptions); const onColumnResize = React.useCallback((_, { columnId, width }) => { setColumnSizingOptions((state) => ({ ...state, [columnId]: { ...state[columnId], idealWidth: width, }, })); }, []); // Columns must be a static object and cannot change on re-renders otherwise React will complain about too many refreshes const columns: TableColumnDefinition[] = useMemo( () => [ createTableColumn({ columnId: "id", compare: (a, b) => a.id.localeCompare(b.id), renderHeaderCell: () => "id", renderCell: (item) => {item.id}, }), ].concat( columnHeaders.partitionKeyHeaders.map((pkHeader, index) => createTableColumn({ columnId: pkHeader, compare: (a, b) => a[pkHeader].localeCompare(b[pkHeader]), // Show Refresh button on last column renderHeaderCell: () => index >= columnHeaders.partitionKeyHeaders.length - 1 ? ( <> {`/${pkHeader}`}