{basketId}
diff --git a/vuu-ui/sample-apps/feature-basket-trading/src/basket-selector/useBasketSelector.ts b/vuu-ui/sample-apps/feature-basket-trading/src/basket-selector/useBasketSelector.ts
index 805f8569d8..dcbf06ac61 100644
--- a/vuu-ui/sample-apps/feature-basket-trading/src/basket-selector/useBasketSelector.ts
+++ b/vuu-ui/sample-apps/feature-basket-trading/src/basket-selector/useBasketSelector.ts
@@ -1,7 +1,8 @@
-import { TableProps, TableRowClickHandler } from "@finos/vuu-table";
-import { buildColumnMap } from "@finos/vuu-utils";
+import { TableRowClickHandler } from "@finos/vuu-datagrid-types";
+import { TableProps } from "@finos/vuu-table";
import { OpenChangeHandler, useControlled } from "@finos/vuu-ui-controls";
-import { useCallback, useMemo } from "react";
+import { buildColumnMap } from "@finos/vuu-utils";
+import { useCallback, useMemo, useRef } from "react";
import { BasketSelectorProps } from "./BasketSelector";
import { BasketSelectorRow } from "./BasketSelectorRow";
@@ -25,6 +26,7 @@ export const useBasketSelector = ({
onOpenChange,
onSelectBasket,
}: BasketSelectorHookProps) => {
+ const triggerRef = useRef
(null);
const [isOpen, setIsOpen] = useControlled({
controlled: isOpenProp,
default: defaultIsOpen ?? false,
@@ -41,8 +43,12 @@ export const useBasketSelector = ({
setIsOpen(open);
onOpenChange?.(open, closeReason);
if (open === false) {
- console.log(`%cdisable basketSearch`, "color:red;font-weight:bold;");
dataSourceBasketTradingSearch.disable?.();
+ if (closeReason !== "Tab") {
+ setTimeout(() => {
+ triggerRef.current?.focus();
+ }, 100);
+ }
}
},
[dataSourceBasketTradingSearch, onOpenChange, setIsOpen]
@@ -68,7 +74,7 @@ export const useBasketSelector = ({
Row: BasketSelectorRow,
config: {
columns: [
- { name: "instanceId", width: 365 },
+ { name: "instanceId", width: 380 },
{ name: "basketId", width: 100, hidden: true },
{
name: "name",
@@ -105,5 +111,6 @@ export const useBasketSelector = ({
onClickAddBasket: handleClickAddBasket,
onOpenChange: handleOpenChange,
tableProps,
+ triggerRef,
};
};
diff --git a/vuu-ui/sample-apps/feature-basket-trading/src/basket-table-edit/BasketTableEdit.tsx b/vuu-ui/sample-apps/feature-basket-trading/src/basket-table-edit/BasketTableEdit.tsx
index 668974f036..3c73713ecb 100644
--- a/vuu-ui/sample-apps/feature-basket-trading/src/basket-table-edit/BasketTableEdit.tsx
+++ b/vuu-ui/sample-apps/feature-basket-trading/src/basket-table-edit/BasketTableEdit.tsx
@@ -31,11 +31,15 @@ export const BasketTableEdit = ({
[]
);
+ console.log({ dataSource });
+
return (
{
+ if (notional === undefined) {
+ return "";
+ } else {
+ return notional.toLocaleString();
+ }
+};
+
export type BasketChangeHandler = (
columnName: string,
value: VuuRowDataItemType
@@ -43,7 +51,6 @@ export const BasketToolbar = ({
onTakeOffMarket,
}: BasketToolbarProps) => {
const handleMenuAction: MenuActionHandler = () => {
- console.log("Menu Action");
return true;
};
@@ -92,7 +99,7 @@ export const BasketToolbar = ({
@@ -126,7 +133,7 @@ export const BasketToolbar = ({
Total USD Not
- {basket?.totalNotional ?? ""}
+ {formatNotional(basket?.totalNotional)}
);
@@ -135,7 +142,7 @@ export const BasketToolbar = ({
Total Not
- {basket?.totalNotionalUsd ?? ""}
+ {formatNotional(basket?.totalNotionalUsd)}
);
diff --git a/vuu-ui/sample-apps/feature-basket-trading/src/new-basket-panel/NewBasketPanel.tsx b/vuu-ui/sample-apps/feature-basket-trading/src/new-basket-panel/NewBasketPanel.tsx
index 6b1860b77b..a205b28bdc 100644
--- a/vuu-ui/sample-apps/feature-basket-trading/src/new-basket-panel/NewBasketPanel.tsx
+++ b/vuu-ui/sample-apps/feature-basket-trading/src/new-basket-panel/NewBasketPanel.tsx
@@ -12,7 +12,7 @@ import {
import { Button, FormField, FormFieldLabel } from "@salt-ds/core";
import cx from "classnames";
import { DataSourceRow } from "@finos/vuu-data-types";
-import { HTMLAttributes, useMemo } from "react";
+import { HTMLAttributes, RefCallback, useCallback, useMemo } from "react";
import "./NewBasketPanel.css";
import { useNewBasketPanel } from "./useNewBasketPanel";
@@ -45,6 +45,7 @@ export const NewBasketPanel = ({
onSave,
onSelectBasket,
saveButtonDisabled,
+ saveButtonRef,
} = useNewBasketPanel({
basketDataSource,
basketSchema,
@@ -70,6 +71,12 @@ export const NewBasketPanel = ({
const itemToString = displayName(columnMap.name);
+ const inputCallbackRef = useCallback>((el) => {
+ setTimeout(() => {
+ el?.querySelector("input")?.focus();
+ }, 100);
+ }, []);
+
return (
@@ -82,7 +89,11 @@ export const NewBasketPanel = ({
Basket Name
-
+
Basket Definition
@@ -102,9 +113,10 @@ export const NewBasketPanel = ({
Cancel
diff --git a/vuu-ui/sample-apps/feature-basket-trading/src/new-basket-panel/useNewBasketPanel.ts b/vuu-ui/sample-apps/feature-basket-trading/src/new-basket-panel/useNewBasketPanel.ts
index a2092bf17d..d16e2b8ad8 100644
--- a/vuu-ui/sample-apps/feature-basket-trading/src/new-basket-panel/useNewBasketPanel.ts
+++ b/vuu-ui/sample-apps/feature-basket-trading/src/new-basket-panel/useNewBasketPanel.ts
@@ -6,7 +6,7 @@ import {
import { TableRowSelectHandler } from "@finos/vuu-table";
import { Commithandler, OpenChangeHandler } from "@finos/vuu-ui-controls";
import { buildColumnMap, metadataKeys } from "@finos/vuu-utils";
-import { useCallback, useState } from "react";
+import { useCallback, useRef, useState } from "react";
import { NewBasketPanelProps } from "./NewBasketPanel";
const { KEY } = metadataKeys;
@@ -43,6 +43,7 @@ export const useNewBasketPanel = ({
const columnMap = buildColumnMap(basketSchema.columns);
const [basketName, setBasketName] = useState("");
const [basketId, setBasketId] = useState();
+ const saveButtonRef = useRef(null);
const saveBasket = useCallback(() => {
if (basketName && basketId) {
@@ -76,6 +77,9 @@ export const useNewBasketPanel = ({
const basketId = row[KEY] as string;
console.log({ basketId, columnMap });
setBasketId(basketId);
+ setTimeout(() => {
+ saveButtonRef.current?.focus();
+ }, 60);
},
[columnMap]
);
@@ -105,5 +109,6 @@ export const useNewBasketPanel = ({
onSave: saveBasket,
onSelectBasket: handleSelectBasket,
saveButtonDisabled: basketName === "" || basketId === undefined,
+ saveButtonRef,
};
};
diff --git a/vuu-ui/sample-apps/feature-basket-trading/src/useBasketContextMenus.ts b/vuu-ui/sample-apps/feature-basket-trading/src/useBasketContextMenus.ts
index 2a02733e10..b370a1d1bc 100644
--- a/vuu-ui/sample-apps/feature-basket-trading/src/useBasketContextMenus.ts
+++ b/vuu-ui/sample-apps/feature-basket-trading/src/useBasketContextMenus.ts
@@ -43,10 +43,11 @@ export const useBasketContextMenus = ({
content: {
type: "InstrumentSearch",
props: {
+ TableProps: {
+ allowDragDrop: "drag-copy",
+ id: "basket-instruments",
+ },
dataSource: dataSourceInstruments,
- // columnName: action.column.name,
- // onConfigChange,
- // tableConfig,
},
},
title: "Add Ticker",
@@ -56,5 +57,5 @@ export const useBasketContextMenus = ({
return false;
},
];
- }, []);
+ }, [dataSourceInstruments, dispatchLayoutAction]);
};
diff --git a/vuu-ui/sample-apps/feature-basket-trading/src/useBasketTrading.tsx b/vuu-ui/sample-apps/feature-basket-trading/src/useBasketTrading.tsx
index ad24129237..b6f8f2035f 100644
--- a/vuu-ui/sample-apps/feature-basket-trading/src/useBasketTrading.tsx
+++ b/vuu-ui/sample-apps/feature-basket-trading/src/useBasketTrading.tsx
@@ -10,6 +10,7 @@ import { NewBasketPanel } from "./new-basket-panel";
import { useBasketContextMenus } from "./useBasketContextMenus";
import { useBasketTradingDataSources } from "./useBasketTradingDatasources";
import { BasketTradingFeatureProps } from "./VuuBasketTradingFeature";
+import { VuuDataRow, VuuDataRowDto } from "packages/vuu-protocol-types";
export class Basket {
basketId: string;
@@ -28,7 +29,7 @@ export class Basket {
this.basketName = data[columnMap.basketName] as string;
this.filledPct = data[columnMap.filledPct] as number;
this.fxRateToUsd = data[columnMap.fxRateToUsd] as number;
- this.side = "BUY";
+ this.side = data[columnMap.side] as string;
this.totalNotional = data[columnMap.totalNotional] as number;
this.totalNotionalUsd = data[columnMap.totalNotionalUsd] as number;
this.units = data[columnMap.units] as number;
@@ -43,6 +44,13 @@ export type BasketTradingHookProps = Pick<
| "instrumentsSchema"
>;
+const toDataDto = (dataSourceRow: VuuDataRow, columnMap: ColumnMap) => {
+ Object.entries(columnMap).reduce((dto, [colName, index]) => {
+ dto[colName] = dataSourceRow[index];
+ return dto;
+ }, {});
+};
+
type BasketState = {
basketInstanceId?: string;
dialog?: JSX.Element;
@@ -89,10 +97,14 @@ export const useBasketTrading = ({
dialog: undefined,
});
- const columnMap = useMemo(
+ const columnMapBasketTrading = useMemo(
() => buildColumnMap(dataSourceBasketTradingControl.columns),
[dataSourceBasketTradingControl.columns]
);
+ const columnMapInstrument = useMemo(
+ () => buildColumnMap(dataSourceInstruments.columns),
+ [dataSourceInstruments.columns]
+ );
useMemo(() => {
dataSourceBasketTradingControl.subscribe(
@@ -105,7 +117,10 @@ export const useBasketTrading = ({
setBasketCount(message.size);
}
if (message.rows && message.rows.length > 0) {
- setBasket(new Basket(message.rows[0], columnMap));
+ const basket = new Basket(message.rows[0], columnMapBasketTrading);
+ console.log({ basket, row: message.rows[0] });
+
+ setBasket(new Basket(message.rows[0], columnMapBasketTrading));
}
}
}
@@ -115,7 +130,7 @@ export const useBasketTrading = ({
setTimeout(() => {
setBasketCount((count) => (count === -1 ? 0 : count));
}, 800);
- }, [columnMap, dataSourceBasketTradingControl]);
+ }, [columnMapBasketTrading, dataSourceBasketTradingControl]);
useEffect(() => {
return () => {
@@ -188,6 +203,7 @@ export const useBasketTrading = ({
const handleCommitBasketChange = useCallback(
(columnName, value) => {
if (basket) {
+ console.log(`handleCommitBasketChange ${columnName} => ${value}`);
const { dataSourceRow } = basket;
return dataSourceBasketTradingControl.applyEdit(
dataSourceRow,
@@ -226,6 +242,38 @@ export const useBasketTrading = ({
menuBuilder: buildViewserverMenuOptions,
};
+ const handleDropInstrument = useCallback(
+ (dragDropState) => {
+ console.log(`useBasketTrading handleDropInstrument`, {
+ instrument: dragDropState.payload,
+ });
+ const key = "steve-00001.AAA.L";
+ const data = {
+ algo: -1,
+ algoParams: "",
+ basketId: ".FTSE100",
+ description: "Test",
+ instanceId: "steve-00001",
+ instanceIdRic: "steve-00001.AAA.L",
+ limitPrice: 0,
+ notionalLocal: 0,
+ notionalUsd: 0,
+ pctFilled: 0,
+ priceSpread: 0,
+ priceStrategyId: 2,
+ quantity: 0,
+ ric: "AAL.L",
+ side: "BUY",
+ venue: "",
+ weighting: 1,
+ };
+ dataSourceBasketTradingControl.insertRow?.(key, data).then((response) => {
+ console.log({ response });
+ });
+ },
+ [dataSourceBasketTradingControl]
+ );
+
return {
...basketState,
activeTabIndex,
@@ -237,6 +285,7 @@ export const useBasketTrading = ({
dataSourceBasketTradingConstituentJoin,
onClickAddBasket: handleAddBasket,
onCommitBasketChange: handleCommitBasketChange,
+ onDropInstrument: handleDropInstrument,
onSendToMarket,
onTakeOffMarket,
};
diff --git a/vuu-ui/scripts/esbuild.mjs b/vuu-ui/scripts/esbuild.mjs
index 392ea30a79..254020925a 100644
--- a/vuu-ui/scripts/esbuild.mjs
+++ b/vuu-ui/scripts/esbuild.mjs
@@ -26,6 +26,8 @@ export async function build(config) {
define: {
"process.env.NODE_ENV": `"${env}"`,
"process.env.NODE_DEBUG": `false`,
+ "process.env.LOCAL": `true`,
+ "process.env.LAYOUT_BASE_URL": `"http://127.0.0.1:8081/api"`,
},
external,
footer,
diff --git a/vuu-ui/showcase/src/examples/Apps/NewTheme.examples.tsx b/vuu-ui/showcase/src/examples/Apps/NewTheme.examples.tsx
index 8a317b3aca..29f89b913a 100644
--- a/vuu-ui/showcase/src/examples/Apps/NewTheme.examples.tsx
+++ b/vuu-ui/showcase/src/examples/Apps/NewTheme.examples.tsx
@@ -15,9 +15,10 @@ import {
ColumnSettingsPanel,
TableSettingsPanel,
} from "@finos/vuu-table-extras";
-import { CSSProperties } from "react";
+import { CSSProperties, useMemo } from "react";
import { FilterTableFeatureProps } from "feature-vuu-filter-table";
import { getAllSchemas } from "@finos/vuu-data-test";
+import { DragDropProvider } from "@finos/vuu-ui-controls";
import "./NewTheme.examples.css";
@@ -97,34 +98,43 @@ const ShellWithNewTheme = () => {
const { buildMenuOptions, handleMenuAction } =
useLayoutContextMenuItems(setDialogState);
+ const dragSource = useMemo(
+ () => ({
+ "basket-instruments": { dropTargets: "basket-constituents" },
+ }),
+ []
+ );
+
return (
-
- }
- loginUrl={window.location.toString()}
- user={user}
- style={
- {
- "--vuuShell-height": "100vh",
- "--vuuShell-width": "100vw",
- } as CSSProperties
- }
- >
- {dialog}
-
+
+
+ }
+ loginUrl={window.location.toString()}
+ user={user}
+ style={
+ {
+ "--vuuShell-height": "100vh",
+ "--vuuShell-width": "100vw",
+ } as CSSProperties
+ }
+ >
+ {dialog}
+
+
);
};
diff --git a/vuu-ui/showcase/src/examples/Shell/AppHeader.examples.tsx b/vuu-ui/showcase/src/examples/Shell/AppHeader.examples.tsx
index d4b0b82bb0..fe5840d81f 100644
--- a/vuu-ui/showcase/src/examples/Shell/AppHeader.examples.tsx
+++ b/vuu-ui/showcase/src/examples/Shell/AppHeader.examples.tsx
@@ -3,6 +3,12 @@ import { AppHeader } from "@finos/vuu-shell";
let displaySequence = 1;
export const DefaultAppHeader = () => {
- return ;
+ return (
+ console.log("onNavigate")}
+ />
+ );
};
DefaultAppHeader.displaySequence = displaySequence++;
diff --git a/vuu-ui/showcase/src/examples/Shell/LoginPanel.examples.tsx b/vuu-ui/showcase/src/examples/Shell/LoginPanel.examples.tsx
index 29dda3843e..915720f71c 100644
--- a/vuu-ui/showcase/src/examples/Shell/LoginPanel.examples.tsx
+++ b/vuu-ui/showcase/src/examples/Shell/LoginPanel.examples.tsx
@@ -1,5 +1,5 @@
import { LoginPanel } from "@finos/vuu-shell";
export const DefaultLoginPanel = () => {
- return ;
+ return console.log("onSubmit")} />;
};
diff --git a/vuu-ui/showcase/src/examples/Table/TableNext.examples.tsx b/vuu-ui/showcase/src/examples/Table/TableNext.examples.tsx
index f0fc3130bc..1a86171388 100644
--- a/vuu-ui/showcase/src/examples/Table/TableNext.examples.tsx
+++ b/vuu-ui/showcase/src/examples/Table/TableNext.examples.tsx
@@ -3,10 +3,11 @@ import {
FlexboxLayout,
LayoutProvider,
registerComponent,
+ Toolbar,
View,
} from "@finos/vuu-layout";
import { ContextPanel } from "@finos/vuu-shell";
-import { TableNext } from "@finos/vuu-table";
+import { TableNext, TableProps } from "@finos/vuu-table";
import {
ColumnSettingsPanel,
TableSettingsPanel,
@@ -15,42 +16,104 @@ import { ColumnDescriptor, TableConfig } from "@finos/vuu-datagrid-types";
import { CSSProperties, useCallback, useMemo, useState } from "react";
import { useTableConfig, useTestDataSource } from "../utils";
import { GroupHeaderCellNext } from "@finos/vuu-table";
-import { getAllSchemas } from "@finos/vuu-data-test";
+import {
+ getAllSchemas,
+ getSchema,
+ SimulTableName,
+ vuuModule,
+} from "@finos/vuu-data-test";
import "./TableNext.examples.css";
+import { Button } from "@salt-ds/core";
let displaySequence = 1;
export const NavigationStyle = () => {
- const {
- typeaheadHook: _,
- config: configProp,
- ...props
- } = useTableConfig({
- rangeChangeRowset: "full",
- table: { module: "SIMUL", table: "instruments" },
- });
-
- const [config, setConfig] = useState(configProp);
+ const tableProps = useMemo>(() => {
+ const tableName: SimulTableName = "instruments";
+ return {
+ config: {
+ columns: getSchema(tableName).columns,
+ rowSeparators: true,
+ zebraStripes: true,
+ },
+ dataSource:
+ vuuModule("SIMUL").createDataSource(tableName),
+ };
+ }, []);
- const handleConfigChange = useCallback((config: TableConfig) => {
- setConfig(config);
+ const onSelect = useCallback((row) => {
+ console.log({ row });
+ }, []);
+ const onSelectionChange = useCallback((selected) => {
+ console.log({ selected });
}, []);
return (
);
};
NavigationStyle.displaySequence = displaySequence++;
+export const ControlledNavigation = () => {
+ const tableProps = useMemo>(() => {
+ const tableName: SimulTableName = "instruments";
+ return {
+ config: {
+ columns: getSchema(tableName).columns,
+ rowSeparators: true,
+ zebraStripes: true,
+ },
+ dataSource:
+ vuuModule("SIMUL").createDataSource(tableName),
+ };
+ }, []);
+ const [highlightedIndex, setHighlightedIndex] = useState(-1);
+
+ const handlePrevClick = useCallback(() => {
+ setHighlightedIndex((idx) => Math.max(0, idx - 1));
+ }, []);
+
+ const handleNextClick = useCallback(() => {
+ setHighlightedIndex((idx) => idx + 1);
+ }, []);
+
+ const handleHighlight = useCallback((idx: number) => {
+ setHighlightedIndex(idx);
+ }, []);
+
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+};
+ControlledNavigation.displaySequence = displaySequence++;
+
export const EditableTableNextArrayData = () => {
const { config, dataSource } = useTableConfig({
columnConfig: {
@@ -209,19 +272,10 @@ export const TableNextInLayoutWithContextPanel = () => {
table: { module: "SIMUL", table: "instruments" },
});
- const handleConfigChange = useCallback((tableConfig: TableConfig) => {
- console.log("config changed");
- }, []);
-
return (
-
+
@@ -239,11 +293,7 @@ export const AutoTableNext = () => {
table: { module: "SIMUL", table: "instruments" },
});
- const [config, setConfig] = useState(configProp);
-
- const handleConfigChange = (config: TableConfig) => {
- setConfig(config);
- };
+ const [config] = useState(configProp);
return (
{
config={{
...config,
}}
- onConfigChange={handleConfigChange}
renderBufferSize={0}
/>
);
diff --git a/vuu-ui/showcase/src/examples/UiControls/DragDrop.examples.tsx b/vuu-ui/showcase/src/examples/UiControls/DragDrop.examples.tsx
index 4552428332..90acc57d00 100644
--- a/vuu-ui/showcase/src/examples/UiControls/DragDrop.examples.tsx
+++ b/vuu-ui/showcase/src/examples/UiControls/DragDrop.examples.tsx
@@ -18,7 +18,7 @@ export const DraggableListsOneWayDrag = () => {
);
const dragSource = useMemo(
() => ({
- list1: { dropTargets: "list2" },
+ list1: { dropTargets: ["list1", "list2"] },
}),
[]
);
@@ -98,6 +98,7 @@ export const DraggableListsOneWayDrag = () => {
{
onDragStart={handleDragStart1}
onMoveListItem={handleMoveListItem1}
source={state1}
- allowDragDrop
+ width={200}
/>
{
onDrop={handleDrop2}
onMoveListItem={handleMoveListItem2}
source={state2}
- allowDragDrop
+ width={200}
/>
diff --git a/vuu-ui/showcase/src/examples/UiControls/InstrumentPicker.examples.tsx b/vuu-ui/showcase/src/examples/UiControls/InstrumentPicker.examples.tsx
index 0eed499d66..d56eb2e5a8 100644
--- a/vuu-ui/showcase/src/examples/UiControls/InstrumentPicker.examples.tsx
+++ b/vuu-ui/showcase/src/examples/UiControls/InstrumentPicker.examples.tsx
@@ -1,48 +1,57 @@
import { InstrumentPicker } from "@finos/vuu-ui-controls";
import {
- createArrayDataSource,
getAllSchemas,
getSchema,
+ SimulTableName,
+ vuuModule,
} from "@finos/vuu-data-test";
import { buildColumnMap, ColumnMap } from "@finos/vuu-utils";
import { useCallback, useMemo } from "react";
import { TableProps, TableRowSelectHandler } from "@finos/vuu-table";
import { ColumnDescriptor } from "@finos/vuu-datagrid-types";
import { useTestDataSource } from "../utils";
+import { DataSourceRow } from "packages/vuu-data-types";
let displaySequence = 0;
export const DefaultInstrumentPicker = () => {
- const schema = getSchema("instruments");
- const [columnMap, searchColumns, tableProps] = useMemo<
- [ColumnMap, string[], Pick]
- >(
- () => [
- buildColumnMap(schema.columns),
- ["bbg", "description"],
+ const tableName: SimulTableName = "instruments";
+ const schema = getSchema(tableName);
+
+ const [tableProps, columnMap, searchColumns] = useMemo<
+ [Pick, ColumnMap, string[]]
+ >(() => {
+ return [
{
config: {
- // TODO need to inject this value
- showHighlightedRow: true,
- columns: [
- { name: "bbg", serverDataType: "string" },
- { name: "description", serverDataType: "string", width: 280 },
- ] as ColumnDescriptor[],
+ columns: schema.columns,
+ rowSeparators: true,
+ zebraStripes: true,
},
- dataSource: createArrayDataSource({ table: schema.table }),
+ dataSource:
+ vuuModule("SIMUL").createDataSource(tableName),
},
- ],
- [schema]
+ buildColumnMap(schema.columns),
+ ["bbg", "description"],
+ ];
+ }, [schema.columns]);
+
+ const itemToString = useCallback(
+ (row: DataSourceRow) => {
+ return [row[columnMap.description]];
+ },
+ [columnMap.description]
);
- const handleSelect = useCallback((row) => {
- console.log(`row selected ${row.join(",")}`);
+ const handleSelect = useCallback((index) => {
+ console.log(`row selected ${index}`);
}, []);
return (
{
- const { dataSource } = useTableConfig({
- dataSourceConfig: {
- columns: ["bbg", "description"],
- },
- table: { module: "SIMUL", table: "instruments" },
- });
+ const dataSource = useMemo(
+ () => vuuModule("SIMUL").createDataSource("instruments"),
+ []
+ );
return (
@@ -22,10 +35,8 @@ export const DefaultInstrumentSearch = () => {
DefaultInstrumentSearch.displaySequence = displaySequence++;
export const InstrumentSearchVuuInstruments = () => {
- const schemas = getAllSchemas();
const { dataSource, error } = useTestDataSource({
- // bufferSize: 1000,
- schemas,
+ schemas: getAllSchemas(),
});
if (error) {
@@ -42,3 +53,74 @@ export const InstrumentSearchVuuInstruments = () => {
};
InstrumentSearchVuuInstruments.displaySequence = displaySequence++;
+
+type DropTargetProps = HTMLAttributes;
+const DropTarget = ({ id, ...htmlAttributes }: DropTargetProps) => {
+ const [instrument, setInstrument] = useState();
+ const { isDragSource, isDropTarget, register } = useDragDropProvider(id);
+
+ console.log(
+ `DropTarget isDragSource ${isDragSource} isDropTarget ${isDropTarget}`
+ );
+
+ const acceptDrop = useCallback((dragState) => {
+ console.log({ payload: dragState.payload });
+ setInstrument(dragState.payload as DataSourceRow);
+ }, []);
+
+ useEffect(() => {
+ if (id && (isDragSource || isDropTarget)) {
+ register(id, false, acceptDrop);
+ }
+ }, [acceptDrop, id, isDragSource, isDropTarget, register]);
+
+ return (
+
+ {instrument ? (
+ <>
+ {instrument[8]}
+ -
+ {instrument[10]}
+ >
+ ) : null}
+
+ );
+};
+
+export const InstrumentSearchDragDrop = () => {
+ const dataSource = useMemo(
+ () => vuuModule("SIMUL").createDataSource("instruments"),
+ []
+ );
+
+ const dragSource = useMemo(
+ () => ({
+ "source-table": { dropTargets: "drop-target" },
+ }),
+ []
+ );
+
+ const handleDragStart = useCallback(() => {
+ console.log("DragStart");
+ }, []);
+
+ return (
+
+
+
+
+
+
+ );
+};
+
+InstrumentSearchDragDrop.displaySequence = displaySequence++;
diff --git a/vuu-ui/showcase/src/examples/VuuFeatures/BasketSelector.examples.tsx b/vuu-ui/showcase/src/examples/VuuFeatures/BasketSelector.examples.tsx
index c83bdbe808..7d40a79079 100644
--- a/vuu-ui/showcase/src/examples/VuuFeatures/BasketSelector.examples.tsx
+++ b/vuu-ui/showcase/src/examples/VuuFeatures/BasketSelector.examples.tsx
@@ -1,21 +1,91 @@
import { BasketSelector } from "feature-basket-trading";
-import { useCallback, useState } from "react";
+import { useCallback, useMemo } from "react";
import { vuuModule } from "@finos/vuu-data-test";
import { Basket } from "feature-basket-trading";
+import { ArrayDataSource } from "@finos/vuu-data";
+import { createBasketTradingRow } from "@finos/vuu-data-test";
let displaySequence = 1;
+const testBaskets = [
+ ["Amber-0001", "Amber Basket", "OFF MARKET", "BUY"],
+ ["Blue-0002", "Blue Basket", "ON MARKET", "SELL"],
+ ["Charcoal-0003", "Charcoal Basket", "OFF MARKET", "BUY"],
+ ["Dandruff-0004", "Dandruff Basket", "ON MARKET", "BUY"],
+ ["Elephant-0005", "Elephant Basket", "OFF MARKET", "SELL"],
+ ["Frogger-0006", "Frogger Basket", "OFF MARKET", "BUY"],
+ ["Gray-0007", "Gray Basket", "ON MARKET", "SELL"],
+ ["Helium-0008", "Helium Basket", "OFF MARKET", "BUY"],
+ ["Indigo-0009", "Indigo Basket", "OFF MARKET", "BUY"],
+];
+
export const DefaultBasketSelector = () => {
- const [basket] = useState({
- basketId: "basket-001",
+ const testBasket: Basket = {
+ dataSourceRow: [] as any,
+ basketId: ".FTSE",
+ basketName: "Test Basket",
+ filledPct: 0,
+ fxRateToUsd: 1.25,
+ side: "BUY",
+ totalNotional: 1000,
+ totalNotionalUsd: 1000,
+ units: 120,
+ };
+
+ const dataSource = useMemo(() => {
+ const dataSource = vuuModule("BASKET").createDataSource(
+ "basketTrading"
+ ) as ArrayDataSource;
+ for (const [basketId, basketName, side, status] of testBaskets) {
+ dataSource["insert"](
+ createBasketTradingRow(basketId, basketName, status, side)
+ );
+ }
+ return dataSource;
+ }, []);
+
+ const handleClickAddBasket = useCallback(() => {
+ console.log("Add Basket");
+ }, []);
+
+ const handleSelectBasket = useCallback(() => {}, []);
+
+ return (
+
+ );
+};
+DefaultBasketSelector.displaySequence = displaySequence++;
+
+export const OpenBasketSelector = () => {
+ const testBasket: Basket = {
+ dataSourceRow: [] as any,
+ basketId: ".FTSE",
basketName: "Test Basket",
- filledPct: 0.7,
- fxRateToUsd: 1.234,
- totalNotional: 1_000_123,
- totalNotionalUsd: 1_234_000,
- units: 100,
- });
- const dataSource = vuuModule("BASKET").createDataSource("basketTrading");
+ filledPct: 0,
+ fxRateToUsd: 1.25,
+ side: "BUY",
+ totalNotional: 1000,
+ totalNotionalUsd: 1000,
+ units: 120,
+ };
+
+ const dataSource = useMemo(() => {
+ const dataSource = vuuModule("BASKET").createDataSource(
+ "basketTrading"
+ ) as ArrayDataSource;
+ for (const [basketId, basketName, side, status] of testBaskets) {
+ dataSource["insert"](
+ createBasketTradingRow(basketId, basketName, status, side)
+ );
+ }
+ return dataSource;
+ }, []);
const handleClickAddBasket = useCallback(() => {
console.log("Add Basket");
@@ -27,12 +97,13 @@ export const DefaultBasketSelector = () => {
return (
);
};
-DefaultBasketSelector.displaySequence = displaySequence++;
+OpenBasketSelector.displaySequence = displaySequence++;
diff --git a/vuu-ui/showcase/src/examples/html/html-table-components/Row.tsx b/vuu-ui/showcase/src/examples/html/html-table-components/Row.tsx
index 135547afbb..437b770b9b 100644
--- a/vuu-ui/showcase/src/examples/html/html-table-components/Row.tsx
+++ b/vuu-ui/showcase/src/examples/html/html-table-components/Row.tsx
@@ -1,6 +1,8 @@
import { DataSourceRow } from "@finos/vuu-data-types";
-import { KeyedColumnDescriptor } from "@finos/vuu-datagrid-types";
-import { RowClickHandler } from "@finos/vuu-table";
+import {
+ KeyedColumnDescriptor,
+ RowClickHandler,
+} from "@finos/vuu-datagrid-types";
import { ColumnMap, isGroupColumn, metadataKeys } from "@finos/vuu-utils";
import { CSSProperties, memo, MouseEvent, useCallback } from "react";
import { TableCell } from "./TableCell";
diff --git a/vuu-ui/showcase/src/examples/html/html-table-components/vuu-table/Row.tsx b/vuu-ui/showcase/src/examples/html/html-table-components/vuu-table/Row.tsx
index 1c35b701b1..f2a9c6b091 100644
--- a/vuu-ui/showcase/src/examples/html/html-table-components/vuu-table/Row.tsx
+++ b/vuu-ui/showcase/src/examples/html/html-table-components/vuu-table/Row.tsx
@@ -1,6 +1,8 @@
import { DataSourceRow } from "@finos/vuu-data-types";
-import { KeyedColumnDescriptor } from "@finos/vuu-datagrid-types";
-import { RowClickHandler } from "@finos/vuu-table";
+import {
+ KeyedColumnDescriptor,
+ RowClickHandler,
+} from "@finos/vuu-datagrid-types";
import {
ColumnMap,
isGroupColumn,
diff --git a/vuu-ui/showcase/vite.config.js b/vuu-ui/showcase/vite.config.js
index 1b58591527..a54edf443d 100644
--- a/vuu-ui/showcase/vite.config.js
+++ b/vuu-ui/showcase/vite.config.js
@@ -9,6 +9,7 @@ export default defineConfig({
define: {
"process.env.NODE_DEBUG": false,
"process.env.LOCAL": true,
+ "process.env.LAYOUT_BASE_URL": `"http://127.0.0.1:8081/api"`,
},
esbuild: {
jsx: `automatic`,
diff --git a/vuu/src/main/resources/runconfigurations/SimulMain.run.xml b/vuu/src/main/resources/runconfigurations/SimulMain.run.xml
index a9e6b0c2f2..ea5a58eae3 100644
--- a/vuu/src/main/resources/runconfigurations/SimulMain.run.xml
+++ b/vuu/src/main/resources/runconfigurations/SimulMain.run.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/vuu/src/main/scala/org/finos/vuu/core/filter/FilterSpecParser.scala b/vuu/src/main/scala/org/finos/vuu/core/filter/FilterSpecParser.scala
index e303669886..c0235c6888 100644
--- a/vuu/src/main/scala/org/finos/vuu/core/filter/FilterSpecParser.scala
+++ b/vuu/src/main/scala/org/finos/vuu/core/filter/FilterSpecParser.scala
@@ -19,7 +19,7 @@ object FilterSpecParser extends StrictLogging {
val input = CharStreams.fromString(s)
val lexer = new FilterLexer(input)
val tokens = new CommonTokenStream(lexer)
- val parser = new FilterParser(tokens)
+ val parser = new FilterParser(tokens)
// do not try to make sense of broken syntax
lexer.removeErrorListeners()
diff --git a/vuu/src/main/scala/org/finos/vuu/core/module/TableDefContainer.scala b/vuu/src/main/scala/org/finos/vuu/core/module/TableDefContainer.scala
index 42e3e5425d..dd6910a31a 100644
--- a/vuu/src/main/scala/org/finos/vuu/core/module/TableDefContainer.scala
+++ b/vuu/src/main/scala/org/finos/vuu/core/module/TableDefContainer.scala
@@ -3,7 +3,11 @@ package org.finos.vuu.core.module
import com.typesafe.scalalogging.StrictLogging
import org.finos.vuu.api.TableDef
-class TableDefContainer(var tablesByModule : Map[String, TableDefs]) extends StrictLogging {
+class TableDefContainer(var tablesByModule : Map[String, TableDefs] = Map()) extends StrictLogging {
+
+ def this() = {
+ this(Map())
+ }
def add(module: String, tableDefs: TableDefs): Unit = {
logger.info(s"Adding table defs for module $module " + this.hashCode() )
diff --git a/vuu/src/main/scala/org/finos/vuu/core/table/TableContainer.scala b/vuu/src/main/scala/org/finos/vuu/core/table/TableContainer.scala
index b1b45eff17..4b21d85521 100644
--- a/vuu/src/main/scala/org/finos/vuu/core/table/TableContainer.scala
+++ b/vuu/src/main/scala/org/finos/vuu/core/table/TableContainer.scala
@@ -34,7 +34,7 @@ class TableContainer(joinTableProvider: JoinTableProvider)(implicit val metrics:
val table = tables.get(name)
if (table == null)
- s"table not found with name ${name}"
+ s"table not found with name $name"
else {
val obByKey = table.getObserversByKey()
obByKey.map({ case (key, obs) => s"key=$key,obs=${obs.mkString(",")}" }).mkString("\n")
@@ -111,7 +111,7 @@ class TableContainer(joinTableProvider: JoinTableProvider)(implicit val metrics:
val table = new TreeSessionTableImpl(source, session, joinTableProvider)
//source.addSessionListener(table)
val existing = tables.put(table.name, table)
- assert(existing == null, "we should never replace an existing table with session id")
+ assert(existing == null, "we should never replace an existing table with session id name:" + table.name + " existing" + existing.name)
table
}
@@ -129,7 +129,7 @@ class TableContainer(joinTableProvider: JoinTableProvider)(implicit val metrics:
def createJoinTable(table: JoinTableDef): DataTable = {
val baseTable = tables.get(table.baseTable.name)
- val joinTableMap = table.joins.map(join => (join.table.name -> tables.get(join.table.name))).toMap //tables.get(table.right.name)
+ val joinTableMap = table.joins.map(join => join.table.name -> tables.get(join.table.name)).toMap //tables.get(table.right.name)
val baseTableMap = Map[String, DataTable](table.baseTable.name -> baseTable)
@@ -151,7 +151,7 @@ class TableContainer(joinTableProvider: JoinTableProvider)(implicit val metrics:
.map(_.getValue.asInstanceOf[SessionTable])
.toArray
- logger.info(s"Removing ${sessionTables.length} session tables on disconnect of ${session}")
+ logger.info(s"Removing ${sessionTables.length} session tables on disconnect of $session")
sessionTables.foreach(sessTable => tables.remove(sessTable.name))
}
diff --git a/vuu/src/main/scala/org/finos/vuu/core/tree/TreeSessionTableImpl.scala b/vuu/src/main/scala/org/finos/vuu/core/tree/TreeSessionTableImpl.scala
index a36b51d0d9..720212dc47 100644
--- a/vuu/src/main/scala/org/finos/vuu/core/tree/TreeSessionTableImpl.scala
+++ b/vuu/src/main/scala/org/finos/vuu/core/tree/TreeSessionTableImpl.scala
@@ -12,6 +12,7 @@ import org.finos.vuu.provider.JoinTableProvider
import org.finos.vuu.viewport._
import org.finos.vuu.viewport.tree.{EmptyTree, Tree, TreeNode}
+import java.util.UUID
import java.util.concurrent.{ConcurrentHashMap, ConcurrentMap}
import scala.jdk.CollectionConverters._
@@ -44,6 +45,8 @@ class TreeSessionTableImpl(val source: RowSource, val session: ClientSessionId,
final val createInstant = clock.now()
+ final val uuid: String = UUID.randomUUID().toString
+
override def linkableName: String = source.linkableName
private val wrappedObservers: ConcurrentMap[String, WrappedKeyObserver[RowKeyUpdate]] = new ConcurrentHashMap[String, WrappedKeyObserver[RowKeyUpdate]]()
@@ -58,18 +61,18 @@ class TreeSessionTableImpl(val source: RowSource, val session: ClientSessionId,
private var onRowUpdateFn: (String, RowWithData) => Unit = updateNoOp
@volatile
- private var onRowDeleteFn: (String) => Unit = deleteNoOp
+ private var onRowDeleteFn: String => Unit = deleteNoOp
private def updateNoOp(key: String, row: RowWithData): Unit = {}
private def deleteNoOp(key: String): Unit = {}
- def onRawUpdate(fn: (String, RowWithData) => Unit) = {
+ def onRawUpdate(fn: (String, RowWithData) => Unit): Unit = {
onRowUpdateFn = fn
}
- def onRawDelete(fn: (String) => Unit) = {
+ def onRawDelete(fn: String => Unit): Unit = {
onRowDeleteFn = fn
}
@@ -81,7 +84,7 @@ class TreeSessionTableImpl(val source: RowSource, val session: ClientSessionId,
override def processDelete(rowKey: String): Unit = super.processDelete(rowKey)
- override def toAscii(count: Int) = {
+ override def toAscii(count: Int): String = {
val columns = getTableDef.columns
val keys = primaryKeys
@@ -107,15 +110,13 @@ class TreeSessionTableImpl(val source: RowSource, val session: ClientSessionId,
override def delete(): Unit = {
this.removeAllObservers()
- MapHasAsScala(this.wrappedObservers).asScala.foreach({ case (key, v) => {
+ MapHasAsScala(this.wrappedObservers).asScala.foreach({ case (key, v) =>
v match {
case upko : WrappedUpdateHandlingKeyObserver[RowKeyUpdate] =>
this.sourceTable.removeKeyObserver(upko.originalKey, v)
case x =>
println("Error: ChrisChris")
}
- }
-
})
}
@@ -219,7 +220,7 @@ class TreeSessionTableImpl(val source: RowSource, val session: ClientSessionId,
}).toArray[Any]
}
- override def name: String = s"session:$session/groupBy-" + source.name + "_" + createInstant.toString
+ override def name: String = s"session:$session/groupBy-" + source.name + "_" + createInstant.toString + "-" + uuid
def tableId: String = name + "@" + hashCode()
@@ -252,7 +253,7 @@ class TreeSessionTableImpl(val source: RowSource, val session: ClientSessionId,
val mapped = rowUpdate.copy(key = treeKey, source = this)
if(mapped != null) {
- logger.debug(s"Found node for originalKey ${nodeKey} mapped to ${treeKey}")
+ logger.debug(s"Found node for originalKey $nodeKey mapped to $treeKey")
}
mapped
@@ -268,7 +269,7 @@ class TreeSessionTableImpl(val source: RowSource, val session: ClientSessionId,
val originalKey = node.originalKey
- logger.debug(s"Adding key observer${originalKey} for tree key ${key}")
+ logger.debug(s"Adding key observer$originalKey for tree key $key")
val wappedObserver = new WrappedUpdateHandlingKeyObserver[RowKeyUpdate](mapKeyToTreeKey(originalKey, key, _), observer, originalKey)
@@ -296,7 +297,7 @@ class TreeSessionTableImpl(val source: RowSource, val session: ClientSessionId,
//remove it
case wo: WrappedUpdateHandlingKeyObserver[RowKeyUpdate] =>
this.wrappedObservers.remove(key)
- logger.debug(s"Removing wrapped observer: ${key} -> ${wo.originalKey}")
+ logger.debug(s"Removing wrapped observer: $key -> ${wo.originalKey}")
sourceTable.removeKeyObserver(wo.originalKey, wo)
case null =>
logger.debug(s"remove normal key observer:$key")