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

feat: Picker table support #382

Merged
merged 10 commits into from
Apr 3, 2024
970 changes: 512 additions & 458 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"e2e": "playwright run",
"e2e:docker": "DEEPHAVEN_PORT=10001 ./tools/run_docker.sh e2e-tests",
"e2e:update-snapshots": "./tools/run_docker.sh update-snapshots",
"update-dh-packages": "lerna run update-dh-packages"
"update-dh-packages": "lerna run --concurrency 1 update-dh-packages"
},
"devDependencies": {
"@deephaven/babel-preset": "^0.40.0",
Expand Down
30 changes: 15 additions & 15 deletions plugins/ui/src/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,21 @@
},
"dependencies": {
"@adobe/react-spectrum": "^3.34.1",
"@deephaven/chart": "^0.68.0",
"@deephaven/components": "^0.68.0",
"@deephaven/dashboard": "^0.68.0",
"@deephaven/dashboard-core-plugins": "^0.68.0",
"@deephaven/grid": "^0.68.0",
"@deephaven/icons": "^0.68.0",
"@deephaven/iris-grid": "^0.68.0",
"@deephaven/jsapi-bootstrap": "^0.68.0",
"@deephaven/jsapi-components": "^0.68.0",
"@deephaven/jsapi-types": "1.0.0-dev0.33.2",
"@deephaven/log": "^0.68.0",
"@deephaven/plugin": "^0.68.0",
"@deephaven/react-hooks": "^0.68.0",
"@deephaven/redux": "^0.68.0",
"@deephaven/utils": "^0.68.0",
"@deephaven/chart": "^0.71.0",
"@deephaven/components": "^0.71.0",
"@deephaven/dashboard": "^0.71.0",
"@deephaven/dashboard-core-plugins": "^0.71.0",
"@deephaven/grid": "^0.71.0",
"@deephaven/icons": "^0.71.0",
"@deephaven/iris-grid": "^0.71.0",
"@deephaven/jsapi-bootstrap": "^0.71.0",
"@deephaven/jsapi-components": "^0.71.0",
"@deephaven/jsapi-types": "^1.0.0-dev0.33.3",
"@deephaven/log": "^0.71.0",
"@deephaven/plugin": "^0.71.0",
"@deephaven/react-hooks": "^0.71.0",
"@deephaven/redux": "^0.71.0",
"@deephaven/utils": "^0.71.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@react-types/shared": "^3.22.0",
"json-rpc-2.0": "^1.6.0",
Expand Down
2 changes: 1 addition & 1 deletion plugins/ui/src/js/src/DashboardPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export function DashboardPlugin(
break;
}
default: {
log.error('Unknown widget type', type);
break;
}
}
},
Expand Down
29 changes: 27 additions & 2 deletions plugins/ui/src/js/src/elements/ElementUtils.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,36 @@ import React from 'react';
import { Text } from '@adobe/react-spectrum';
import type { dh } from '@deephaven/jsapi-types';
import { TestUtils } from '@deephaven/utils';
import { ELEMENT_KEY, isPrimitive, wrapElementChildren } from './ElementUtils';
import {
ELEMENT_KEY,
fetchReexportedTable,
isPrimitive,
wrapElementChildren,
} from './ElementUtils';
import ObjectView from './ObjectView';
import { ITEM_ELEMENT_NAME } from './ElementConstants';

const { createMockProxy } = TestUtils;
const { asMock, createMockProxy } = TestUtils;

describe('fetchReexportedTable', () => {
it('should return null for null object', async () => {
const actual = await fetchReexportedTable(null);
expect(actual).toBeNull();
});

it('should return table for non-null object', async () => {
const table = createMockProxy<dh.Table>();

const reexported = createMockProxy<dh.WidgetExportedObject>();
asMock(reexported.fetch).mockResolvedValue(table);

const exported = createMockProxy<dh.WidgetExportedObject>();
asMock(exported.reexport).mockResolvedValue(reexported);

const actual = await fetchReexportedTable(exported);
expect(actual).toBe(table);
});
});

describe('isPrimitive', () => {
it.each(['test', 444, true, false])(
Expand Down
17 changes: 17 additions & 0 deletions plugins/ui/src/js/src/elements/ElementUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ export function isObjectNode(obj: unknown): obj is ObjectNode {
return obj != null && typeof obj === 'object' && OBJECT_KEY in obj;
}

/**
* Re-export and fetch the table from the given exported object.
* @param exportedObject
* @returns Promise that resolves to the table or null if given
* object is null
*/
export async function fetchReexportedTable(
exportedObject: dh.WidgetExportedObject | null
): Promise<dh.Table | null> {
if (exportedObject == null) {
return null;
}

const reexportedTable = await exportedObject.reexport();
return reexportedTable.fetch();
}

/**
* Type guard for `ElementNode` objects. If `name` is provided, it will also check
* that the element name matches the provided name.
Expand Down
39 changes: 36 additions & 3 deletions plugins/ui/src/js/src/elements/Picker.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,48 @@
import React from 'react';
import React, { ReactElement } from 'react';
import {
Picker as DHPicker,
PickerProps as DHPickerProps,
} from '@deephaven/components';
import {
Picker as DHPickerJSApi,
PickerProps as DHPickerJSApiProps,
useTableClose,
} from '@deephaven/jsapi-components';
import { isElementOfType, usePromiseFactory } from '@deephaven/react-hooks';
import { SerializedPickerEventProps, usePickerProps } from './usePickerProps';
import ObjectView, { ObjectViewProps } from './ObjectView';
import { fetchReexportedTable } from './ElementUtils';

type WrappedDHPickerJSApiProps = Omit<DHPickerJSApiProps, 'table'> & {
children: ReactElement<ObjectViewProps>;
};

function Picker(props: DHPickerProps & SerializedPickerEventProps) {
export type PickerProps = (DHPickerProps | WrappedDHPickerJSApiProps) &
SerializedPickerEventProps;

function Picker({ children, ...props }: PickerProps) {
const pickerProps = usePickerProps(props);

const isObjectView = isElementOfType(children, ObjectView);

const maybeExportedTable =
isObjectView && children.props.object.type === 'Table'
? children.props.object
: null;

const { data: table } = usePromiseFactory(fetchReexportedTable, [
maybeExportedTable,
]);

useTableClose(table);

if (isObjectView) {
// eslint-disable-next-line react/jsx-props-no-spreading
return table && <DHPickerJSApi {...pickerProps} table={table} />;
}

// eslint-disable-next-line react/jsx-props-no-spreading
return <DHPicker {...pickerProps} />;
return <DHPicker {...pickerProps}>{children}</DHPicker>;
}

export default Picker;
33 changes: 26 additions & 7 deletions tools/update-dh-packages.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*
* Or for a specific plugin via:
* `npm run update-dh-packages -- --scope=@deephaven/js-plugin-ui`
*
* To target a specific version, pass the version as an argument:
* `npm run update-dh-packages -- --scope=@deephaven/js-plugin-ui -- 0.70.1-alpha-picker-table.34`
*/

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

// Optional targetVersion argument or fallback to 'latest'
const targetVersion = process.argv[2] ?? 'latest';
console.log('targetVersion:', targetVersion);
// Optional targetVersionOverride argument
const targetVersionOverride = process.argv[2];
const targetVersionDefault = 'latest';

console.log('targetVersion:', {
default: targetVersionDefault,
override: targetVersionOverride,
});

// Read package.json to get dependency lists
const packageJsonPath = path.join(process.cwd(), 'package.json');
const { dependencies, devDependencies } = JSON.parse(
const { dependencies = {}, devDependencies = {} } = JSON.parse(
String(await fs.readFile(packageJsonPath, 'utf8'))
);

Expand All @@ -42,17 +50,28 @@ const dhPackageNames = [
),
];

const dhPackageUpdates = new Map(
dhPackageNames.map(name => [
name,
// If targetVersionOverride is set, use it for all packages except for
// `@deephaven/jsapi-types` since it has it's own versioning cadence.
targetVersionOverride == null || name === '@deephaven/jsapi-types'
? targetVersionDefault
: targetVersionOverride,
])
);

if (dhPackageNames.length === 0) {
console.log(
'No @deephaven packages found in dependencies or devDependencies.'
);
process.exit(0);
}

console.log('Updating packages:', dhPackageNames);
console.log('Updating packages:', dhPackageUpdates);

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

console.log(cmd);
Expand Down
Loading