Skip to content

Commit 2f84c96

Browse files
authored
feat: Picker table support (#382)
* Picker table support * update-dh-packages script now excludes jsapi-types package from custom target version since it has its own version cadence * Updated DHC packages to ^0.71.0 * Updated jsapi-types to ^1.0.0-dev0.33.3
1 parent 2f0a8a0 commit 2f84c96

8 files changed

Lines changed: 635 additions & 487 deletions

File tree

package-lock.json

Lines changed: 512 additions & 458 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"e2e": "playwright run",
2020
"e2e:docker": "DEEPHAVEN_PORT=10001 ./tools/run_docker.sh e2e-tests",
2121
"e2e:update-snapshots": "./tools/run_docker.sh update-snapshots",
22-
"update-dh-packages": "lerna run update-dh-packages"
22+
"update-dh-packages": "lerna run --concurrency 1 update-dh-packages"
2323
},
2424
"devDependencies": {
2525
"@deephaven/babel-preset": "^0.40.0",

plugins/ui/src/js/package.json

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,21 @@
4242
},
4343
"dependencies": {
4444
"@adobe/react-spectrum": "^3.34.1",
45-
"@deephaven/chart": "^0.68.0",
46-
"@deephaven/components": "^0.68.0",
47-
"@deephaven/dashboard": "^0.68.0",
48-
"@deephaven/dashboard-core-plugins": "^0.68.0",
49-
"@deephaven/grid": "^0.68.0",
50-
"@deephaven/icons": "^0.68.0",
51-
"@deephaven/iris-grid": "^0.68.0",
52-
"@deephaven/jsapi-bootstrap": "^0.68.0",
53-
"@deephaven/jsapi-components": "^0.68.0",
54-
"@deephaven/jsapi-types": "1.0.0-dev0.33.2",
55-
"@deephaven/log": "^0.68.0",
56-
"@deephaven/plugin": "^0.68.0",
57-
"@deephaven/react-hooks": "^0.68.0",
58-
"@deephaven/redux": "^0.68.0",
59-
"@deephaven/utils": "^0.68.0",
45+
"@deephaven/chart": "^0.71.0",
46+
"@deephaven/components": "^0.71.0",
47+
"@deephaven/dashboard": "^0.71.0",
48+
"@deephaven/dashboard-core-plugins": "^0.71.0",
49+
"@deephaven/grid": "^0.71.0",
50+
"@deephaven/icons": "^0.71.0",
51+
"@deephaven/iris-grid": "^0.71.0",
52+
"@deephaven/jsapi-bootstrap": "^0.71.0",
53+
"@deephaven/jsapi-components": "^0.71.0",
54+
"@deephaven/jsapi-types": "^1.0.0-dev0.33.3",
55+
"@deephaven/log": "^0.71.0",
56+
"@deephaven/plugin": "^0.71.0",
57+
"@deephaven/react-hooks": "^0.71.0",
58+
"@deephaven/redux": "^0.71.0",
59+
"@deephaven/utils": "^0.71.0",
6060
"@fortawesome/react-fontawesome": "^0.2.0",
6161
"@react-types/shared": "^3.22.0",
6262
"json-rpc-2.0": "^1.6.0",

plugins/ui/src/js/src/DashboardPlugin.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export function DashboardPlugin(
145145
break;
146146
}
147147
default: {
148-
log.error('Unknown widget type', type);
148+
break;
149149
}
150150
}
151151
},

plugins/ui/src/js/src/elements/ElementUtils.test.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,36 @@ import React from 'react';
22
import { Text } from '@adobe/react-spectrum';
33
import type { dh } from '@deephaven/jsapi-types';
44
import { TestUtils } from '@deephaven/utils';
5-
import { ELEMENT_KEY, isPrimitive, wrapElementChildren } from './ElementUtils';
5+
import {
6+
ELEMENT_KEY,
7+
fetchReexportedTable,
8+
isPrimitive,
9+
wrapElementChildren,
10+
} from './ElementUtils';
611
import ObjectView from './ObjectView';
712
import { ITEM_ELEMENT_NAME } from './ElementConstants';
813

9-
const { createMockProxy } = TestUtils;
14+
const { asMock, createMockProxy } = TestUtils;
15+
16+
describe('fetchReexportedTable', () => {
17+
it('should return null for null object', async () => {
18+
const actual = await fetchReexportedTable(null);
19+
expect(actual).toBeNull();
20+
});
21+
22+
it('should return table for non-null object', async () => {
23+
const table = createMockProxy<dh.Table>();
24+
25+
const reexported = createMockProxy<dh.WidgetExportedObject>();
26+
asMock(reexported.fetch).mockResolvedValue(table);
27+
28+
const exported = createMockProxy<dh.WidgetExportedObject>();
29+
asMock(exported.reexport).mockResolvedValue(reexported);
30+
31+
const actual = await fetchReexportedTable(exported);
32+
expect(actual).toBe(table);
33+
});
34+
});
1035

1136
describe('isPrimitive', () => {
1237
it.each(['test', 444, true, false])(

plugins/ui/src/js/src/elements/ElementUtils.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,23 @@ export function isObjectNode(obj: unknown): obj is ObjectNode {
4646
return obj != null && typeof obj === 'object' && OBJECT_KEY in obj;
4747
}
4848

49+
/**
50+
* Re-export and fetch the table from the given exported object.
51+
* @param exportedObject
52+
* @returns Promise that resolves to the table or null if given
53+
* object is null
54+
*/
55+
export async function fetchReexportedTable(
56+
exportedObject: dh.WidgetExportedObject | null
57+
): Promise<dh.Table | null> {
58+
if (exportedObject == null) {
59+
return null;
60+
}
61+
62+
const reexportedTable = await exportedObject.reexport();
63+
return reexportedTable.fetch();
64+
}
65+
4966
/**
5067
* Type guard for `ElementNode` objects. If `name` is provided, it will also check
5168
* that the element name matches the provided name.
Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,48 @@
1-
import React from 'react';
1+
import React, { ReactElement } from 'react';
22
import {
33
Picker as DHPicker,
44
PickerProps as DHPickerProps,
55
} from '@deephaven/components';
6+
import {
7+
Picker as DHPickerJSApi,
8+
PickerProps as DHPickerJSApiProps,
9+
useTableClose,
10+
} from '@deephaven/jsapi-components';
11+
import { isElementOfType, usePromiseFactory } from '@deephaven/react-hooks';
612
import { SerializedPickerEventProps, usePickerProps } from './usePickerProps';
13+
import ObjectView, { ObjectViewProps } from './ObjectView';
14+
import { fetchReexportedTable } from './ElementUtils';
15+
16+
type WrappedDHPickerJSApiProps = Omit<DHPickerJSApiProps, 'table'> & {
17+
children: ReactElement<ObjectViewProps>;
18+
};
719

8-
function Picker(props: DHPickerProps & SerializedPickerEventProps) {
20+
export type PickerProps = (DHPickerProps | WrappedDHPickerJSApiProps) &
21+
SerializedPickerEventProps;
22+
23+
function Picker({ children, ...props }: PickerProps) {
924
const pickerProps = usePickerProps(props);
1025

26+
const isObjectView = isElementOfType(children, ObjectView);
27+
28+
const maybeExportedTable =
29+
isObjectView && children.props.object.type === 'Table'
30+
? children.props.object
31+
: null;
32+
33+
const { data: table } = usePromiseFactory(fetchReexportedTable, [
34+
maybeExportedTable,
35+
]);
36+
37+
useTableClose(table);
38+
39+
if (isObjectView) {
40+
// eslint-disable-next-line react/jsx-props-no-spreading
41+
return table && <DHPickerJSApi {...pickerProps} table={table} />;
42+
}
43+
1144
// eslint-disable-next-line react/jsx-props-no-spreading
12-
return <DHPicker {...pickerProps} />;
45+
return <DHPicker {...pickerProps}>{children}</DHPicker>;
1346
}
1447

1548
export default Picker;

tools/update-dh-packages.mjs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*
1616
* Or for a specific plugin via:
1717
* `npm run update-dh-packages -- --scope=@deephaven/js-plugin-ui`
18+
*
19+
* To target a specific version, pass the version as an argument:
20+
* `npm run update-dh-packages -- --scope=@deephaven/js-plugin-ui -- 0.70.1-alpha-picker-table.34`
1821
*/
1922

2023
/* eslint-disable no-console */
@@ -23,13 +26,18 @@ import { promises as fs } from 'fs';
2326
import path from 'path';
2427
import process from 'process';
2528

26-
// Optional targetVersion argument or fallback to 'latest'
27-
const targetVersion = process.argv[2] ?? 'latest';
28-
console.log('targetVersion:', targetVersion);
29+
// Optional targetVersionOverride argument
30+
const targetVersionOverride = process.argv[2];
31+
const targetVersionDefault = 'latest';
32+
33+
console.log('targetVersion:', {
34+
default: targetVersionDefault,
35+
override: targetVersionOverride,
36+
});
2937

3038
// Read package.json to get dependency lists
3139
const packageJsonPath = path.join(process.cwd(), 'package.json');
32-
const { dependencies, devDependencies } = JSON.parse(
40+
const { dependencies = {}, devDependencies = {} } = JSON.parse(
3341
String(await fs.readFile(packageJsonPath, 'utf8'))
3442
);
3543

@@ -42,17 +50,28 @@ const dhPackageNames = [
4250
),
4351
];
4452

53+
const dhPackageUpdates = new Map(
54+
dhPackageNames.map(name => [
55+
name,
56+
// If targetVersionOverride is set, use it for all packages except for
57+
// `@deephaven/jsapi-types` since it has it's own versioning cadence.
58+
targetVersionOverride == null || name === '@deephaven/jsapi-types'
59+
? targetVersionDefault
60+
: targetVersionOverride,
61+
])
62+
);
63+
4564
if (dhPackageNames.length === 0) {
4665
console.log(
4766
'No @deephaven packages found in dependencies or devDependencies.'
4867
);
4968
process.exit(0);
5069
}
5170

52-
console.log('Updating packages:', dhPackageNames);
71+
console.log('Updating packages:', dhPackageUpdates);
5372

54-
const cmd = `npm i --save ${dhPackageNames
55-
.map(name => `${name}@${targetVersion}`)
73+
const cmd = `npm i --save ${[...dhPackageUpdates.entries()]
74+
.map(([name, version]) => `${name}@${version}`)
5675
.join(' ')}`;
5776

5877
console.log(cmd);

0 commit comments

Comments
 (0)