Skip to content

Commit

Permalink
row based keyboard nav in tables, showcase basket test data (finos#972)
Browse files Browse the repository at this point in the history
* add data update to test tables, remove redundant generators

* table supports row highlightingh

* fix scroll on instrument search

* controlled row highlighting for table

* handle focus in NewBasket prompt

* keyboard navigation row mode tables

* improve UX arouns basket selector

* type fixes

* format notional values

* drag drop across components

* WIP

* use columnMap in BackGround cell rensderer

* remove console.log
  • Loading branch information
heswell authored Nov 20, 2023
1 parent 9e30b2c commit f98649b
Show file tree
Hide file tree
Showing 95 changed files with 4,155 additions and 1,117 deletions.
27 changes: 25 additions & 2 deletions vuu-ui/packages/vuu-data-test/src/Table.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import { TableSchema } from "@finos/vuu-data";
import { VuuRowDataItemType } from "@finos/vuu-protocol-types";
import { EventEmitter } from "@finos/vuu-utils";
import { ColumnMap, EventEmitter } from "@finos/vuu-utils";

export type TableEvents = {
delete: (row: VuuRowDataItemType[]) => void;
insert: (row: VuuRowDataItemType[]) => void;
update: (row: VuuRowDataItemType[], columnName: string) => void;
};

export class Table extends EventEmitter<TableEvents> {
#data: VuuRowDataItemType[][];
#dataMap: ColumnMap;
#indexOfKey: number;
#schema: TableSchema;
constructor(schema: TableSchema, data: VuuRowDataItemType[][]) {
constructor(
schema: TableSchema,
data: VuuRowDataItemType[][],
dataMap: ColumnMap
) {
super();
this.#data = data;
this.#dataMap = dataMap;
this.#schema = schema;
this.#indexOfKey = dataMap[schema.key];
}

get data() {
Expand All @@ -24,4 +33,18 @@ export class Table extends EventEmitter<TableEvents> {
this.#data.push(row);
this.emit("insert", row);
}

update(key: string, columnName: string, value: VuuRowDataItemType) {
const rowIndex = this.#data.findIndex(
(row) => row[this.#indexOfKey] === key
);
const colIndex = this.#dataMap[columnName];
if (rowIndex !== -1) {
const row = this.#data[rowIndex];
const newRow = row.slice();
newRow[colIndex] = value;
this.#data[rowIndex] = newRow;
this.emit("update", newRow, columnName);
}
}
}
14 changes: 14 additions & 0 deletions vuu-ui/packages/vuu-data-test/src/TickingArrayDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
VuuRange,
VuuRowDataItemType,
} from "@finos/vuu-protocol-types";
import { metadataKeys } from "@finos/vuu-utils";
import { UpdateGenerator, UpdateHandler } from "./rowUpdates";
import { Table } from "./Table";

Expand All @@ -35,6 +36,7 @@ export interface TickingArrayDataSourceConstructorProps
export class TickingArrayDataSource extends ArrayDataSource {
#rpcServices: RpcService[] | undefined;
#updateGenerator: UpdateGenerator | undefined;
#table?: Table;

constructor({
data,
Expand All @@ -54,11 +56,13 @@ export class TickingArrayDataSource extends ArrayDataSource {
this._menu = menu;
this.#rpcServices = rpcServices;
this.#updateGenerator = updateGenerator;
this.#table = table;
updateGenerator?.setDataSource(this);
updateGenerator?.setUpdateHandler(this.processUpdates);

if (table) {
table.on("insert", this.insert);
table.on("update", this.update);
}
}

Expand Down Expand Up @@ -139,6 +143,16 @@ export class TickingArrayDataSource extends ArrayDataSource {
}, []);
}

applyEdit(
row: DataSourceRow,
columnName: string,
value: VuuRowDataItemType
): Promise<true> {
const key = row[metadataKeys.KEY];
this.#table?.update(key, columnName, value);
return Promise.resolve(true);
}

async menuRpcCall(
rpcRequest: Omit<ClientToServerMenuRPC, "vpId"> | ClientToServerEditRpc
): Promise<
Expand Down
131 changes: 80 additions & 51 deletions vuu-ui/packages/vuu-data-test/src/basket/basket-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ const buildDataColumnMap = (tableName: BasketsTableName) =>
{}
);

const tableMaps: Record<BasketsTableName, ColumnMap> = {
algoType: buildDataColumnMap("algoType"),
basket: buildDataColumnMap("basket"),
basketTrading: buildDataColumnMap("basketTrading"),
basketTradingConstituent: buildDataColumnMap("basketTradingConstituent"),
basketConstituent: buildDataColumnMap("basketConstituent"),
basketTradingConstituentJoin: buildDataColumnMap(
"basketTradingConstituentJoin"
),
priceStrategyType: buildDataColumnMap("priceStrategyType"),
};

//---------------

const { KEY } = metadataKeys;
Expand Down Expand Up @@ -72,40 +84,55 @@ for (const row of sp500) {

const basketConstituent = new Table(
schemas.basketConstituent,
basketConstituentData
basketConstituentData,
tableMaps.basketConstituent
);

/**
* BasketTrading
*/
const basketTrading = new Table(schemas.basketTrading, []);
const basketTrading = new Table(
schemas.basketTrading,
[],
tableMaps.basketTrading
);

let basketIncrement = 1;
/**
* BasketTradingConstituent
*/
const basketTradingConstituent = new Table(
schemas.basketTradingConstituent,
[]
[],
tableMaps.basketTradingConstituent
);
const basketTradingConstituentJoin = new Table(
schemas.basketTradingConstituentJoin,
[]
[],
tableMaps.basketTradingConstituentJoin
);

// export as convenience for showcase examples
export const createBasketTradingRow = (
basketId: string,
basketName: string,
side = "BUY",
status = "OFF MARKET"
) => [
basketId,
basketName,
0,
1.25,
`steve-${basketIncrement++}`,
side,
status,
1_000_000,
1_250_000,
100,
];

function createTradingBasket(basketId: string, basketName: string) {
const instanceId = `steve-${basketIncrement++}`;
const basketTradingRow = [
basketId,
basketName,
0,
1.25,
instanceId,
"OFF MARKET",
1_000_000,
1_250_000,
100,
];
const basketTradingRow = createBasketTradingRow(basketId, basketName);

basketTrading.insert(basketTradingRow);

Expand All @@ -126,13 +153,15 @@ function createTradingBasket(basketId: string, basketName: string) {
const side = "BUY";
const venue = "venue";

const { instanceId } = tableMaps.basketTrading;
const basketInstanceId = basketTradingRow[instanceId];
const basketTradingConstituentRow: VuuRowDataItemType[] = [
algo,
algoParams,
basketId,
description,
instanceId,
`${instanceId}-${ric}`,
basketInstanceId,
`${basketInstanceId}-${ric}`,
limitPrice,
notionalLocal,
notionalUsd,
Expand Down Expand Up @@ -168,8 +197,8 @@ function createTradingBasket(basketId: string, basketName: string) {
bidSize,
close,
description,
instanceId,
`${instanceId}-${ric}`,
basketInstanceId,
`${basketInstanceId}-${ric}`,
last,
limitPrice,
notionalLocal,
Expand Down Expand Up @@ -202,42 +231,42 @@ async function createNewBasket(rpcRequest: any) {

//-------------------

const tableMaps: Record<BasketsTableName, ColumnMap> = {
algoType: buildDataColumnMap("algoType"),
basket: buildDataColumnMap("basket"),
basketTrading: buildDataColumnMap("basketTrading"),
basketTradingConstituent: buildDataColumnMap("basketTradingConstituent"),
basketConstituent: buildDataColumnMap("basketConstituent"),
basketTradingConstituentJoin: buildDataColumnMap(
"basketTradingConstituentJoin"
),
priceStrategyType: buildDataColumnMap("priceStrategyType"),
};

export const tables: Record<BasketsTableName, Table> = {
algoType: new Table(schemas.algoType, [
["Sniper", 0],
["Dark Liquidity", 1],
["VWAP", 2],
["POV", 3],
["Dynamic Close", 4],
]),
basket: new Table(schemas.basket, [
[".NASDAQ100", ".NASDAQ100", 0, 0],
[".HSI", ".HSI", 0, 0],
[".FTSE100", ".FTSE100", 0, 0],
[".SP500", ".SP500", 0, 0],
]),
algoType: new Table(
schemas.algoType,
[
["Sniper", 0],
["Dark Liquidity", 1],
["VWAP", 2],
["POV", 3],
["Dynamic Close", 4],
],
tableMaps.algoType
),
basket: new Table(
schemas.basket,
[
[".NASDAQ100", ".NASDAQ100", 0, 0],
[".HSI", ".HSI", 0, 0],
[".FTSE100", ".FTSE100", 0, 0],
[".SP500", ".SP500", 0, 0],
],
tableMaps.basket
),
basketConstituent,
basketTrading,
basketTradingConstituent,
basketTradingConstituentJoin,
priceStrategyType: new Table(schemas.priceStrategyType, [
["Peg to Near Touch", 0],
["Far Touch", 1],
["Limit", 2],
["Algo", 3],
]),
priceStrategyType: new Table(
schemas.priceStrategyType,
[
["Peg to Near Touch", 0],
["Far Touch", 1],
["Limit", 2],
["Algo", 3],
],
tableMaps.priceStrategyType
),
};

const menus: Record<BasketsTableName, VuuMenu | undefined> = {
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

18 changes: 0 additions & 18 deletions vuu-ui/packages/vuu-data-test/src/basket/data-generators/index.ts

This file was deleted.

Loading

0 comments on commit f98649b

Please sign in to comment.