Adding table scrolling

This commit is contained in:
Laurent Nguyen
2024-02-29 13:39:24 +01:00
parent c6cec71fd9
commit 82c7760af2
5 changed files with 149 additions and 58 deletions

View File

@@ -14,7 +14,7 @@ import { LocalStorageUtility, StorageKey } from 'Shared/StorageUtility';
import { Action } from 'Shared/Telemetry/TelemetryConstants';
import { userContext } from "UserContext";
import { logConsoleError } from 'Utils/NotificationConsoleUtils';
import React, { KeyboardEventHandler, useEffect, useMemo, useState } from "react";
import React, { KeyboardEventHandler, useEffect, useMemo, useRef, useState } from "react";
import { format } from "react-string-format";
import CloseIcon from "../../../../images/close-black.svg";
import * as Constants from "../../../Common/Constants";
@@ -442,6 +442,24 @@ const DocumentsTabComponent: React.FunctionComponent<{
setCurrentDocument(content);
});
const tableContainerRef = useRef(null);
const [tableContainerHeightPx, setTableContainerHeightPx] = useState<number>(undefined);
useEffect(() => {
if (!tableContainerRef.current) {
return undefined;
}
const resizeObserver = new ResizeObserver(() => {
// Do what you want to do when the size of the element changes
setTableContainerHeightPx(tableContainerRef.current.offsetHeight);
console.log('height', tableContainerRef.current.offsetHeight);
});
resizeObserver.observe(tableContainerRef.current);
return () => resizeObserver.disconnect(); // clean up
}, []);
return <FluentProvider theme={dataExplorerLightTheme} style={{ height: "100%" }}>
<div
className="tab-pane active"
@@ -551,10 +569,11 @@ const DocumentsTabComponent: React.FunctionComponent<{
{/* <!-- Filter - End --> */}
{/* <Split> doesn't like to be a flex child */}
<div style={{ overflow: "hidden" }}>
<div style={{ overflow: "hidden", height: "100%" }}>
<Split>
<div style={{ minWidth: 440, width: "20%" }}>
<DocumentsTableComponent style={{ width: "100%", height: "100%" }} items={tableItems} onSelectedItem={onSelectedDocument} />
<div style={{ minWidth: 440, width: "20%", display: "flex", flexDirection: "column", height: "100%" }}
ref={tableContainerRef}>
<DocumentsTableComponent style={{ width: "100%", height: "100%" }} items={tableItems} onSelectedItem={onSelectedDocument} height={tableContainerHeightPx} />
</div>
<div style={{ minWidth: "20%" }}><pre>{JSON.stringify(currentDocument, undefined, " ")}</pre></div>
</Split>

View File

@@ -1,5 +1,6 @@
import { Menu, MenuItem, MenuList, MenuPopover, MenuTrigger, Table, TableBody, TableCell, TableCellLayout, TableColumnDefinition, TableColumnSizingOptions, TableHeader, TableHeaderCell, TableRow, TableRowId, TableSelectionCell, createTableColumn, useArrowNavigationGroup, useTableColumnSizing_unstable, useTableFeatures, useTableSelection } from '@fluentui/react-components';
import { 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 React, { useEffect } from 'react';
import { FixedSizeList as List, ListChildComponentProps } from "react-window";
export type DocumentsTableComponentItem = {
id: string;
@@ -9,6 +10,7 @@ export type DocumentsTableComponentItem = {
export interface IDocumentsTableComponentProps {
items: DocumentsTableComponentItem[];
onSelectedItem: (index: number) => void;
height: number;
style?: React.CSSProperties;
}
@@ -43,9 +45,52 @@ const columns: TableColumnDefinition<DocumentsTableComponentItem>[] = [
}),
];
interface TableRowData extends RowStateBase<DocumentsTableComponentItem> {
onClick: (e: React.MouseEvent) => void;
onKeyDown: (e: React.KeyboardEvent) => void;
selected: boolean;
appearance: "brand" | "none";
}
interface ReactWindowRenderFnProps extends ListChildComponentProps {
data: TableRowData[];
}
const RenderRow = ({ index, style, data }: ReactWindowRenderFnProps) => {
const { item, selected, appearance, onClick, onKeyDown } = data[index];
return <TableRow
aria-rowindex={index + 2}
style={style}
key={item.id}
// onClick={onClick}
// onKeyDown={onKeyDown}
aria-selected={selected}
appearance={appearance}
>
<TableSelectionCell
checked={selected}
checkboxIndicator={{ "aria-label": "Select row" }}
onClick={onClick}
onKeyDown={onKeyDown}
/>
{columns.map((column) => (
<TableCell
key={column.columnId}
// onClick={(/* e */) => setSelectedRows(new Set<TableRowId>([index]))}
onKeyDown={onKeyDown}
// {...columnSizing.getTableCellProps(column.columnId)}
>
{column.renderCell(item)}
</TableCell>
))}
</TableRow>;
};
export const DocumentsTableComponent: React.FC<IDocumentsTableComponentProps> = ({
items, onSelectedItem, style,
items, onSelectedItem, style, height,
}: IDocumentsTableComponentProps) => {
const { targetDocument } = useFluent();
const scrollbarWidth = useScrollbarWidth({ targetDocument });
const [activeItemIndex, setActiveItemIndex] = React.useState<number>(undefined);
const [columnSizingOptions, setColumnSizingOptions] = React.useState<TableColumnSizingOptions>({
@@ -99,7 +144,7 @@ export const DocumentsTableComponent: React.FC<IDocumentsTableComponentProps> =
]
);
const rows = getRows((row) => {
const rows: TableRowData[] = getRows((row) => {
const selected = isRowSelected(row.rowId);
return {
...row,
@@ -150,7 +195,7 @@ export const DocumentsTableComponent: React.FC<IDocumentsTableComponentProps> =
};
return (
<Table {...tableProps}>
<Table noNativeElements {...tableProps}>
<TableHeader>
<TableRow>
<TableSelectionCell
@@ -184,35 +229,20 @@ export const DocumentsTableComponent: React.FC<IDocumentsTableComponentProps> =
</MenuPopover>
</Menu>
))}
{/** Scrollbar alignment for the header */}
<div role="presentation" style={{ width: scrollbarWidth }} />
</TableRow>
</TableHeader>
<TableBody>
{rows.map(({ item, selected, onClick, onKeyDown, appearance }, index: number) => (
<TableRow
key={item.id}
// onClick={onClick}
// onKeyDown={onKeyDown}
aria-selected={selected}
appearance={appearance}
>
<TableSelectionCell
checked={selected}
checkboxIndicator={{ "aria-label": "Select row" }}
onClick={onClick}
onKeyDown={onKeyDown}
/>
{columns.map((column) => (
<TableCell
key={column.columnId}
onClick={(/* e */) => setSelectedRows(new Set<TableRowId>([index]))}
onKeyDown={onKeyDown}
{...columnSizing.getTableCellProps(column.columnId)}
>
{column.renderCell(item)}
</TableCell>
))}
</TableRow>
))}
<TableBody style={{ height: "100%", flex: 1 }}>
<List
height={height - 32}
itemCount={items.length}
itemSize={45}
width="100%"
itemData={rows}
>
{RenderRow}
</List>
</TableBody>
</Table>
);