Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment/table select api #1271

Merged
merged 2 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions vuu-ui/packages/vuu-data-types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ export type DataSourceRow = [
...VuuRowDataItemType[]
];

export type DataSourceRowObject = {
index: number;
key: string;
isGroupRow: boolean;
isSelected: boolean;
data: VuuDataRowDto;
};

export type DataSourceRowPredicate = (row: DataSourceRow) => boolean;

export interface ContextMenuItemBase {
Expand Down
17 changes: 13 additions & 4 deletions vuu-ui/packages/vuu-table-types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import type {
VuuSortType,
VuuTable,
} from "@finos/vuu-protocol-types";
import type { VuuDataRow } from "@finos/vuu-protocol-types";
import type { ClientSideValidationChecker } from "@finos/vuu-ui-controls";
import type { DateTimePattern } from "@finos/vuu-utils";
import { DataSourceRow } from "@finos/vuu-data-types";
import { DataSourceRow, DataSourceRowObject } from "@finos/vuu-data-types";
import type { FunctionComponent, MouseEvent } from "react";
import type { HTMLAttributes } from "react";

Expand Down Expand Up @@ -45,9 +44,19 @@ export type DataItemCommitHandler<
T extends VuuRowDataItemType = VuuRowDataItemType
> = (value: T) => CommitResponse;

export type TableRowClickHandler = (row: VuuDataRow) => void;
export type TableRowSelectHandler = (row: DataSourceRowObject | null) => void;
export type TableRowSelectHandlerInternal = (row: DataSourceRow | null) => void;

export type RowClickHandler = (
/**
* Fired when user clicks a row, returning the row object (DataSourceRowObject)
*/
export type TableRowClickHandler = (
evt: MouseEvent<HTMLDivElement>,
row: DataSourceRowObject
) => void;

export type TableRowClickHandlerInternal = (
evt: MouseEvent<HTMLDivElement>,
row: DataSourceRow,
rangeSelect: boolean,
keepExistingSelection: boolean
Expand Down
6 changes: 3 additions & 3 deletions vuu-ui/packages/vuu-table/src/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { DataSourceRow } from "@finos/vuu-data-types";
import {
DataCellEditHandler,
RuntimeColumnDescriptor,
RowClickHandler,
TableRowClickHandlerInternal,
} from "@finos/vuu-table-types";
import {
ColumnMap,
Expand Down Expand Up @@ -34,7 +34,7 @@ export interface RowProps {
highlighted?: boolean;
row: DataSourceRow;
offset: number;
onClick?: RowClickHandler;
onClick?: TableRowClickHandlerInternal;
onDataEdited?: DataCellEditHandler;
onToggleGroup?: (row: DataSourceRow, column: RuntimeColumnDescriptor) => void;
style?: CSSProperties;
Expand Down Expand Up @@ -89,7 +89,7 @@ export const Row = memo(
(evt: MouseEvent<HTMLDivElement>) => {
const rangeSelect = evt.shiftKey;
const keepExistingSelection = evt.ctrlKey || evt.metaKey; /* mac only */
onClick?.(row, rangeSelect, keepExistingSelection);
onClick?.(evt, row, rangeSelect, keepExistingSelection);
},
[onClick, row]
);
Expand Down
4 changes: 1 addition & 3 deletions vuu-ui/packages/vuu-table/src/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
DataSource,
DataSourceRow,
SchemaColumn,
SelectionChangeHandler,
VuuFeatureInvocationMessage,
Expand All @@ -10,6 +9,7 @@ import {
TableConfig,
TableConfigChangeHandler,
TableRowClickHandler,
TableRowSelectHandler,
TableSelectionModel,
} from "@finos/vuu-table-types";
import {
Expand Down Expand Up @@ -44,8 +44,6 @@ const classBase = "vuuTable";

const { IDX, RENDER_IDX } = metadataKeys;

// TODO implement a Model object to represent a row data for better API
export type TableRowSelectHandler = (row: DataSourceRow) => void;
export type TableNavigationStyle = "none" | "cell" | "row";

export interface TableProps
Expand Down
18 changes: 9 additions & 9 deletions vuu-ui/packages/vuu-table/src/useSelection.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { RowClickHandler, TableSelectionModel } from "@finos/vuu-table-types";
import {
TableRowClickHandlerInternal,
TableRowSelectHandlerInternal,
TableSelectionModel,
} from "@finos/vuu-table-types";
import {
deselectItem,
dispatchMouseEvent,
isRowSelected,
metadataKeys,
selectItem,
} from "@finos/vuu-utils";
import {
DataSourceRow,
Selection,
SelectionChangeHandler,
} from "@finos/vuu-data-types";
import { Selection, SelectionChangeHandler } from "@finos/vuu-data-types";
import {
KeyboardEvent,
KeyboardEventHandler,
Expand All @@ -29,7 +29,7 @@ export interface SelectionHookProps {
highlightedIndexRef: MutableRefObject<number | undefined>;
selectionKeys?: string[];
selectionModel: TableSelectionModel;
onSelect?: (row: DataSourceRow) => void;
onSelect?: TableRowSelectHandlerInternal;
onSelectionChange: SelectionChangeHandler;
}

Expand All @@ -49,8 +49,8 @@ export const useSelection = ({
[selectionKeys]
);

const handleRowClick = useCallback<RowClickHandler>(
(row, rangeSelect, keepExistingSelection) => {
const handleRowClick = useCallback<TableRowClickHandlerInternal>(
(evt, row, rangeSelect, keepExistingSelection) => {
const { [IDX]: idx } = row;
const { current: active } = lastActiveRef;
const { current: selected } = selectedRef;
Expand Down
31 changes: 21 additions & 10 deletions vuu-ui/packages/vuu-table/src/useTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import {
import {
ColumnDescriptor,
DataCellEditHandler,
RowClickHandler,
TableRowClickHandlerInternal,
RuntimeColumnDescriptor,
TableColumnResizeHandler,
TableConfig,
TableSelectionModel,
TableRowSelectHandlerInternal,
} from "@finos/vuu-table-types";
import { VuuRange, VuuSortType } from "@finos/vuu-protocol-types";
import {
Expand All @@ -22,6 +23,7 @@ import {
} from "@finos/vuu-ui-controls";
import {
applySort,
asDataSourceRowObject,
buildColumnMap,
getIndexFromRowElement,
isGroupColumn,
Expand Down Expand Up @@ -557,16 +559,33 @@ export const useTable = ({
[dataSource, onSelectionChange]
);

const handleSelect = useCallback<TableRowSelectHandlerInternal>(
(row) => {
if (onSelect) {
onSelect(row === null ? null : asDataSourceRowObject(row, columnMap));
}
},
[columnMap, onSelect]
);

const {
onKeyDown: selectionHookKeyDown,
onRowClick: selectionHookOnRowClick,
} = useSelection({
highlightedIndexRef,
onSelect,
onSelect: handleSelect,
onSelectionChange: handleSelectionChange,
selectionModel,
});

const handleRowClick = useCallback<TableRowClickHandlerInternal>(
(evt, row, rangeSelect, keepExistingSelection) => {
selectionHookOnRowClick(evt, row, rangeSelect, keepExistingSelection);
onRowClickProp?.(evt, asDataSourceRowObject(row, columnMap));
},
[columnMap, onRowClickProp, selectionHookOnRowClick]
);

const handleKeyDown = useCallback(
(e: KeyboardEvent<HTMLElement>) => {
navigationKeyDown(e);
Expand All @@ -580,14 +599,6 @@ export const useTable = ({
[navigationKeyDown, editingKeyDown, selectionHookKeyDown]
);

const handleRowClick = useCallback<RowClickHandler>(
(row, rangeSelect, keepExistingSelection) => {
selectionHookOnRowClick(row, rangeSelect, keepExistingSelection);
onRowClickProp?.(row);
},
[onRowClickProp, selectionHookOnRowClick]
);

const onMoveColumn = useCallback(
(columns: ColumnDescriptor[]) => {
const newTableConfig = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DataSourceRow, TableSchema } from "@finos/vuu-data-types";
import { Table, TableProps, TableRowSelectHandler } from "@finos/vuu-table";
import { DataSourceRowObject, TableSchema } from "@finos/vuu-data-types";
import { Table, TableProps } from "@finos/vuu-table";
import { ColumnMap, useId } from "@finos/vuu-utils";
import { Input } from "@salt-ds/core";
import { ForwardedRef, forwardRef, HTMLAttributes, useMemo } from "react";
Expand All @@ -16,7 +16,8 @@ if (typeof SearchCell !== "function") {
}

export interface InstrumentPickerProps
extends Omit<HTMLAttributes<HTMLElement>, "onSelect"> {
extends Omit<HTMLAttributes<HTMLElement>, "onSelect">,
Pick<TableProps, "onSelect"> {
TableProps: Pick<TableProps, "config" | "dataSource">;
columnMap: ColumnMap;
disabled?: boolean;
Expand All @@ -27,10 +28,9 @@ export interface InstrumentPickerProps
* @param row DataSourceRow
* @returns string
*/
itemToString?: (row: DataSourceRow) => string;
itemToString?: (row: DataSourceRowObject) => string;
onClose?: () => void;
onOpenChange?: OpenChangeHandler;
onSelect: TableRowSelectHandler;
schema: TableSchema;
searchColumns: string[];
width?: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { DataSource, DataSourceRow } from "@finos/vuu-data-types";
import { ColumnDescriptor } from "@finos/vuu-table-types";
import { DataSource, DataSourceRowObject } from "@finos/vuu-data-types";
import {
ColumnDescriptor,
TableRowSelectHandler,
useControlledTableNavigation,
} from "@finos/vuu-table";
import { ColumnMap } from "@finos/vuu-utils";
} from "@finos/vuu-table-types";
import { useControlledTableNavigation } from "@finos/vuu-table";
import { ChangeEvent, useCallback, useMemo, useState } from "react";
import { useControlled } from "../common-hooks";
import { OpenChangeHandler } from "../dropdown";
Expand All @@ -21,19 +20,14 @@ export interface InstrumentPickerHookProps
isOpen?: boolean;
}

const defaultItemToString =
(columns: ColumnDescriptor[], columnMap: ColumnMap) =>
(row: DataSourceRow) => {
return columns.map(({ name }) => row[columnMap[name]]).join(" ");
};
const defaultItemToString = (row: DataSourceRowObject) =>
Object.values(row.data).join(" ");

export const useInstrumentPicker = ({
columnMap,
columns,
dataSource,
defaultIsOpen,
isOpen: isOpenProp,
itemToString = defaultItemToString(columns, columnMap),
itemToString = defaultItemToString,
onOpenChange,
onSelect,
searchColumns,
Expand Down Expand Up @@ -85,9 +79,9 @@ export const useInstrumentPicker = ({

const handleSelectRow = useCallback<TableRowSelectHandler>(
(row) => {
const value = itemToString(row);
const value = row === null ? "" : itemToString(row);
setValue(value);
onSelect(row);
onSelect?.(row);
handleOpenChange?.(false, "select");
},
[handleOpenChange, itemToString, onSelect]
Expand Down
33 changes: 30 additions & 3 deletions vuu-ui/packages/vuu-utils/src/row-utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//TODO this all probably belongs in vuu-table
import type { DataSourceRow } from "@finos/vuu-data-types";
import type { DataSourceRow, DataSourceRowObject } from "@finos/vuu-data-types";
import type { MutableRefObject } from "react";
import { metadataKeys } from "./column-utils";
import { ColumnMap, metadataKeys } from "./column-utils";

const { IDX } = metadataKeys;
const { IS_LEAF, KEY, IDX, SELECTED } = metadataKeys;

export type RowOffsetFunc = (
row: DataSourceRow,
Expand Down Expand Up @@ -90,3 +90,30 @@ export const getIndexFromRowElement = (rowElement: HTMLElement) => {
);
}
};

export const asDataSourceRowObject = (
row: DataSourceRow,
columnMap: ColumnMap
): DataSourceRowObject => {
console.log({ columnMap });
const {
[IS_LEAF]: isLeaf,
[KEY]: key,
[IDX]: index,
[SELECTED]: selected,
} = row;

const rowObject: DataSourceRowObject = {
key,
index,
isGroupRow: !isLeaf,
isSelected: selected > 0,
data: {},
};

for (const [colName, colIdx] of Object.entries(columnMap)) {
rowObject.data[colName] = row[colIdx];
}

return rowObject;
};
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const BasketSelectorRow = ({
(evt: MouseEvent<HTMLDivElement>) => {
const rangeSelect = evt.shiftKey;
const keepExistingSelection = evt.ctrlKey || evt.metaKey; /* mac only */
onClick?.(row, rangeSelect, keepExistingSelection);
onClick?.(evt, row, rangeSelect, keepExistingSelection);
},
[onClick, row]
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { TableRowClickHandler } from "@finos/vuu-table-types";
import { TableProps } from "@finos/vuu-table";
import { OpenChangeHandler, useControlled } from "@finos/vuu-ui-controls";
import { buildColumnMap } from "@finos/vuu-utils";
import { useCallback, useMemo, useRef } from "react";
import { BasketSelectorProps } from "./BasketSelector";
import { BasketSelectorRow } from "./BasketSelectorRow";
Expand Down Expand Up @@ -33,11 +32,6 @@ export const useBasketSelector = ({
name: "useDropdownList",
});

const columnMap = useMemo(
() => buildColumnMap(dataSourceBasketTradingSearch.columns),
[dataSourceBasketTradingSearch.columns]
);

const handleOpenChange = useCallback<OpenChangeHandler>(
(open, closeReason) => {
setIsOpen(open);
Expand All @@ -55,12 +49,12 @@ export const useBasketSelector = ({
);

const handleRowClick = useCallback<TableRowClickHandler>(
(row) => {
const instanceId = row[columnMap.instanceId] as string;
(_evt, row) => {
const instanceId = row.data.instanceId as string;
handleOpenChange(false, "select");
onSelectBasket?.(instanceId);
},
[columnMap.instanceId, handleOpenChange, onSelectBasket]
[handleOpenChange, onSelectBasket]
);

const handleClickAddBasket = useCallback(() => {
Expand Down
Loading
Loading