diff --git a/docker/data/storage/notebooks/DEMO.md b/docker/data/storage/notebooks/DEMO.md index 9db7ef902..19fff5579 100644 --- a/docker/data/storage/notebooks/DEMO.md +++ b/docker/data/storage/notebooks/DEMO.md @@ -97,7 +97,7 @@ def picker(): ) -p = picker() +result = picker() ``` ## Using Tables @@ -197,7 +197,7 @@ def stock_table_input(source, default_sym="", default_exchange=""): return [ ui.panel( # Add a callback for when user double clicks a row in the table - ui.table(t1).on_row_double_press(handle_row_double_press), + ui.table(t1, on_row_double_press=handle_row_double_press), title="Stock Row Press", ), ui.panel(t2, title="Stock Filtered Table"), @@ -226,7 +226,7 @@ def hist_demo(source, column): x=column, nbins=bin_count, ), - {bin_count, hist_range, source, column}, + [bin_count, hist_range, source, column], ) return [ @@ -271,7 +271,7 @@ def order_table(): ), [], ) - t = ui.use_memo(lambda: blink_to_append_only(blink_table), {blink_table}) + t = ui.use_memo(lambda: blink_to_append_only(blink_table), [blink_table]) def submit_order(order_sym, order_size, side): publisher.add( @@ -322,7 +322,7 @@ def table_tabs(source): return ui.tabs( ui.tab_list( ui.item("Unfiltered", key="Unfiltered"), - ui.item(ui.icon("vsGithubAlt"), "CAT", key="CAT"), + ui.item(ui.icon("vsGithubAlt"), ui.text("CAT"), key="CAT"), ui.item("DOG", key="DOG"), ), ui.tab_panels( @@ -437,18 +437,18 @@ def multiwave(): f"y_tan={amplitude}*Math.tan({frequency}*x+{phase})", ] ), - {amplitude, frequency, phase}, + [amplitude, frequency, phase], ) p_sin = use_memo( - lambda: Figure().plot_xy(series_name="Sine", t=t, x="x", y="y_sin").show(), {t} + lambda: Figure().plot_xy(series_name="Sine", t=t, x="x", y="y_sin").show(), [t] ) p_cos = use_memo( lambda: Figure().plot_xy(series_name="Cosine", t=t, x="x", y="y_cos").show(), - {t}, + [t], ) p_tan = use_memo( lambda: Figure().plot_xy(series_name="Tangent", t=t, x="x", y="y_tan").show(), - {t}, + [t], ) return ui.column( diff --git a/package-lock.json b/package-lock.json index efcea6308..8e3458bf9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35385,24 +35385,25 @@ }, "plugins/ui/src/js": { "name": "@deephaven/js-plugin-ui", - "version": "0.8.0", + "version": "0.9.0", "license": "Apache-2.0", "dependencies": { "@adobe/react-spectrum": "^3.34.1", - "@deephaven/chart": "^0.67.0", - "@deephaven/components": "^0.67.0", - "@deephaven/dashboard": "^0.67.0", - "@deephaven/dashboard-core-plugins": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/iris-grid": "^0.67.0", - "@deephaven/jsapi-bootstrap": "^0.67.0", - "@deephaven/jsapi-components": "^0.67.0", + "@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": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/plugin": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/redux": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "@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", "@fortawesome/react-fontawesome": "^0.2.0", "@react-types/shared": "^3.22.0", "json-rpc-2.0": "^1.6.0", @@ -35423,17 +35424,17 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/chart": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.67.0.tgz", - "integrity": "sha512-Jkq9Lh647JWRvUSuqKnyqeMWjsSDDQY+uUpcAkw9F4J2Fl+j80TcG6Pk9xyocEJ1KwvCVojNtZbDlQHHPkVIMQ==", - "dependencies": { - "@deephaven/components": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.68.0.tgz", + "integrity": "sha512-KDrQm6id+MCPY8v+rraORQOaUbamyjFYeMFz5gAgJka1ls/gkEDCXTynEkEHseDjTKXb/S1y7Yy7MXGjNeKH6Q==", + "dependencies": { + "@deephaven/components": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/utils": "^0.68.0", "deep-equal": "^2.0.5", "lodash.debounce": "^4.0.8", "lodash.set": "^4.3.2", @@ -35450,16 +35451,21 @@ "react": "^17.x" } }, + "plugins/ui/src/js/node_modules/@deephaven/chart/node_modules/@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + }, "plugins/ui/src/js/node_modules/@deephaven/components": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.67.0.tgz", - "integrity": "sha512-wpyBFL+/ePadhtxFu2+lG55UbWfzcwGyFtarLL7x3aVJdTTcwi5YtgUdYxHgbpmBfhG+mht2aLU59mLh2dhZ0A==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.68.0.tgz", + "integrity": "sha512-3AJaLtUvHrduXxl8CprviR/5lQfR5rsvnWQJBgVRPs6XZxcwyEPmBu0c1UEu5JFXYYDVnnt47TbMaZA9kB7ZFw==", "dependencies": { "@adobe/react-spectrum": "^3.34.1", - "@deephaven/icons": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", "@react-spectrum/theme-default": "^3.5.1", @@ -35488,19 +35494,19 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/console": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.67.0.tgz", - "integrity": "sha512-umMLDPdaAyLafXW35fr7kWk/5ZfEd44lyTgu9GDVVththSLyKj3hpIBUWpfIGekwTrb46wfZbVmRbPKEmZNa4w==", - "dependencies": { - "@deephaven/chart": "^0.67.0", - "@deephaven/components": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/jsapi-bootstrap": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/storage": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.68.0.tgz", + "integrity": "sha512-aRg6L6n+/6RgE+Qad6EGdrka4Qd/9kaRqPPp3bqom5QSowOB0ZZ8auf4hBp9fT6/u7nxdTbz0uVKhI3lCXn7Bw==", + "dependencies": { + "@deephaven/chart": "^0.68.0", + "@deephaven/components": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/jsapi-bootstrap": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/storage": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "linkifyjs": "^4.1.0", @@ -35523,17 +35529,22 @@ "react-dom": "^17.x" } }, + "plugins/ui/src/js/node_modules/@deephaven/console/node_modules/@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + }, "plugins/ui/src/js/node_modules/@deephaven/dashboard": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.67.0.tgz", - "integrity": "sha512-Sx16vqAxPKkF1x1xDfgKnntn7JW37mEBiV1D8qUgCHYUOM+uYiHoh1/UIU/cJfGrdx9ln+vUN21bkLDs++e1iQ==", - "dependencies": { - "@deephaven/components": "^0.67.0", - "@deephaven/golden-layout": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/redux": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.68.0.tgz", + "integrity": "sha512-jPd9dU/ZwGTAc6BSM/Yfu+vAzTJyfSLziNWRHFqAA3xA3r2+a2QiRhfkEVYN4Kua2QVhO3NGQMY6th7t0gTQAw==", + "dependencies": { + "@deephaven/components": "^0.68.0", + "@deephaven/golden-layout": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/redux": "^0.68.0", + "@deephaven/utils": "^0.68.0", "deep-equal": "^2.0.5", "lodash.ismatch": "^4.1.1", "lodash.throttle": "^4.1.1", @@ -35551,30 +35562,30 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.67.0.tgz", - "integrity": "sha512-1XrHcvLclyIZLttFO0hgCncK/jEPT02NTObI/7OHLeTKpl6OgHuzmabYFxB0QrPAWqmlPaURtaDCH/kun4t54A==", - "dependencies": { - "@deephaven/chart": "^0.67.0", - "@deephaven/components": "^0.67.0", - "@deephaven/console": "^0.67.0", - "@deephaven/dashboard": "^0.67.0", - "@deephaven/file-explorer": "^0.67.0", - "@deephaven/filters": "^0.67.0", - "@deephaven/golden-layout": "^0.67.0", - "@deephaven/grid": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/iris-grid": "^0.67.0", - "@deephaven/jsapi-bootstrap": "^0.67.0", - "@deephaven/jsapi-components": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/plugin": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/redux": "^0.67.0", - "@deephaven/storage": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.68.0.tgz", + "integrity": "sha512-ivYF6cYj20sKf9HNzhKwnEaX1VfwsMSTWRhdvXyy67XQbcV3+v/kgiZnrCQKw3547nsETWT1EI4UuIX2L59S+w==", + "dependencies": { + "@deephaven/chart": "^0.68.0", + "@deephaven/components": "^0.68.0", + "@deephaven/console": "^0.68.0", + "@deephaven/dashboard": "^0.68.0", + "@deephaven/file-explorer": "^0.68.0", + "@deephaven/filters": "^0.68.0", + "@deephaven/golden-layout": "^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.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/plugin": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/redux": "^0.68.0", + "@deephaven/storage": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "deep-equal": "^2.0.5", @@ -35602,16 +35613,21 @@ "react-redux": "^7.2.4" } }, + "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + }, "plugins/ui/src/js/node_modules/@deephaven/file-explorer": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.67.0.tgz", - "integrity": "sha512-Be4E+PK7lgwzGpOY3rnD2PssY/7cVBVcn7RMq9cPnWAcQZpkQg0IGCYpu+ahmRwqv3joeDiHUS7Vr1Fim73j+Q==", - "dependencies": { - "@deephaven/components": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/storage": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.68.0.tgz", + "integrity": "sha512-78PMW1dAOULDSwXTyLnn/d8T8OwTrGd53k4p0py8XFfXtIgsIouJElER6v4+5p5oeK1rHI9DC1CjvNWUUqvvHQ==", + "dependencies": { + "@deephaven/components": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/storage": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", @@ -35626,19 +35642,19 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/filters": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.67.0.tgz", - "integrity": "sha512-k/qSHXmvAzfDn/EkA+hpsB5nwB/LUYntDH9lHUDix9ygnvalI72I2LgkQ2BBNri3VTKRGLXdummuWrNDVBvZvA==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.68.0.tgz", + "integrity": "sha512-H6eOMdbbzqTsRRDRwILbVjdQnCOaKRE1B3gHHPdUvRoKIAlNqQxBh4L+DW3WbuOBYjAuCcMutRHpy5gohaPchw==", "engines": { "node": ">=16" } }, "plugins/ui/src/js/node_modules/@deephaven/golden-layout": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.67.0.tgz", - "integrity": "sha512-Yt9cVBOdjNLsFJrk0BH7Ld/Y3IzLX9gU8uzxcOZ13JyVKf8Jl9sIvZA/MvMVUbKwqTMeAcmz2AUVuP5RVLP0jw==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.68.0.tgz", + "integrity": "sha512-+kwnRD2NCir0RrfPQRdc+03TLtORzfe2bIbzxTDBZro0FDPBifPgNUAO5IUsTDw0wfDrTezyEk1KtMzHf/U7vA==", "dependencies": { - "@deephaven/components": "^0.67.0", + "@deephaven/components": "^0.68.0", "jquery": "^3.6.0" }, "peerDependencies": { @@ -35647,11 +35663,11 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/grid": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.67.0.tgz", - "integrity": "sha512-/UQf3OjQzCqbZ4+hliUzxPs+oCCK1sdiDblhcXfQnBCFVWlnrIXOQGf+5purPAoa5pfocgnXGTsZG3TEIkfyfQ==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.68.0.tgz", + "integrity": "sha512-cSEWNq3ANtLCAWAgzXz/4ifGGAjYR9/Aex2p+xJWS73fmFHtAw7IsI63K5QB+9mxqVdH9TNZ1IztdDbucEwq8Q==", "dependencies": { - "@deephaven/utils": "^0.67.0", + "@deephaven/utils": "^0.68.0", "classnames": "^2.3.1", "color-convert": "^2.0.1", "event-target-shim": "^6.0.2", @@ -35669,9 +35685,9 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/icons": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.67.0.tgz", - "integrity": "sha512-2m4Ufnwcf+ZWnH0JigPpJbxb4QNdu7RKrjaGt0wXEzml5N8arurx1kWMktOhk6Cz25DYJDCe/RMXuHjTqH2vUQ==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.68.0.tgz", + "integrity": "sha512-FUF+eKocoqr1l5sKN3+vA7BBJGWhHRndofwt8QQmt7nv6Oh6SM/I3x37Jx/riacuMN+yUqes5yuEgWqS0QM+Nw==", "dependencies": { "@fortawesome/fontawesome-common-types": "^6.1.1" }, @@ -35681,22 +35697,22 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/iris-grid": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.67.0.tgz", - "integrity": "sha512-LMttYlLIRD4NXxBOFc/F36zEsv6C0cZWXmFmeYJdFF1w2qugQpbLubxgu5roJt4qP9ZKNm00IhQs6sVfll1zhg==", - "dependencies": { - "@deephaven/components": "^0.67.0", - "@deephaven/console": "^0.67.0", - "@deephaven/filters": "^0.67.0", - "@deephaven/grid": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/jsapi-components": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/storage": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.68.0.tgz", + "integrity": "sha512-6LP6rOdWfCQrumQNZAxMZnYpSZFOC/sKYDgs3oDSpIbGSLxsLVcdp9z6/sCQ0I+KwRcWAEzq47QZ6UjTe2QH/Q==", + "dependencies": { + "@deephaven/components": "^0.68.0", + "@deephaven/console": "^0.68.0", + "@deephaven/filters": "^0.68.0", + "@deephaven/grid": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/jsapi-components": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/storage": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@dnd-kit/core": "^6.1.0", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.2", @@ -35722,15 +35738,20 @@ "react-dom": "^17.x" } }, + "plugins/ui/src/js/node_modules/@deephaven/iris-grid/node_modules/@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + }, "plugins/ui/src/js/node_modules/@deephaven/jsapi-bootstrap": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.67.0.tgz", - "integrity": "sha512-vFEm6YH33TOO3kQBWCxlxJNCZllGBw2RumkhfijS6JhTRPFQMJeb7l3g71W9j128z5eKp0g5c3rnasuQ/R0/fg==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.68.0.tgz", + "integrity": "sha512-i0Tlnh50yhnPXuotw2JSzPgjNe76bVh2MrAGHE9AUkhvO1P/3kFQ1EfVXIvxQ4K2z/9Uhq8b3uFWi6iAGiZ7Hg==", "dependencies": { - "@deephaven/components": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0" + "@deephaven/components": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0" }, "engines": { "node": ">=16" @@ -35739,18 +35760,23 @@ "react": "^17.x" } }, + "plugins/ui/src/js/node_modules/@deephaven/jsapi-bootstrap/node_modules/@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + }, "plugins/ui/src/js/node_modules/@deephaven/jsapi-components": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.67.0.tgz", - "integrity": "sha512-TbdVypvpCHd6eIAnDeDnpIbyLEGq3uB8BSZXGEj1QZhgEZCNUihBKU8PUCr2KcA8gYcYROuEXKFHNvi4NVwRpw==", - "dependencies": { - "@deephaven/components": "^0.67.0", - "@deephaven/jsapi-bootstrap": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.68.0.tgz", + "integrity": "sha512-eiVLFFVORP8tOEueYjLvvjTF9hd6B/gMi7zZMcNMWYEzCvtF1v0/8qakK02pEo659g28ixRBKQQQPyni00B09Q==", + "dependencies": { + "@deephaven/components": "^0.68.0", + "@deephaven/jsapi-bootstrap": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@types/js-cookie": "^3.0.3", "classnames": "^2.3.2", "js-cookie": "^3.0.5", @@ -35764,6 +35790,11 @@ "react": "^17.x" } }, + "plugins/ui/src/js/node_modules/@deephaven/jsapi-components/node_modules/@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + }, "plugins/ui/src/js/node_modules/@deephaven/jsapi-types": { "version": "0.67.0", "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-0.67.0.tgz", @@ -35773,14 +35804,14 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/jsapi-utils": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.67.0.tgz", - "integrity": "sha512-4s5KLSsM8mF+9Uv8f5ftanWU25WLErn5kKCrxZWBGQgJORMPm834KGiHQeD4HMpeZ84s/gMK4rtiWxJ4u9eaHg==", - "dependencies": { - "@deephaven/filters": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.68.0.tgz", + "integrity": "sha512-bQ4+ZLmpaYlMBc6p7YI0n/OJvQA5zUManW+3bFf9WaZsYI8rxeyDzDtGn8NdI0jQirl0rt/9Uvak7AelqEInJw==", + "dependencies": { + "@deephaven/filters": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/log": "^0.68.0", + "@deephaven/utils": "^0.68.0", "lodash.clamp": "^4.0.3", "shortid": "^2.2.16" }, @@ -35788,10 +35819,15 @@ "node": ">=16" } }, + "plugins/ui/src/js/node_modules/@deephaven/jsapi-utils/node_modules/@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + }, "plugins/ui/src/js/node_modules/@deephaven/log": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.67.0.tgz", - "integrity": "sha512-tfYUThfC3JXTBXB7bVr8IN0go3xbKxlU42XPKtQaShpRxrXgWDmLAuzHtoqCTTlunYxzXa/m8SAIaJ5qGztN6A==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.68.0.tgz", + "integrity": "sha512-F3kZYudez4Jxnunwhw97WcWySol/4Maqd4wD93fydmnMPMe05WA+Hya9b4CQ4J3XZIbRnuV9kS3laf6YEI6xig==", "dependencies": { "event-target-shim": "^6.0.2" }, @@ -35800,17 +35836,17 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/plugin": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.67.0.tgz", - "integrity": "sha512-DiNmjqaclXub0vPVxXWGNQpFkTiwO+m9OqUtGTqIRzggZCK3IfqHFcjzUJx3GlCkf/efLIrJMQQVWPONMudRMw==", - "dependencies": { - "@deephaven/components": "^0.67.0", - "@deephaven/golden-layout": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/iris-grid": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.68.0.tgz", + "integrity": "sha512-FlSF6CSKTKAGi88iLF9mEEROTJ6BnPOSbMAUAFTXEGJSngcEZ4EaybwjYV0HxMrSKhbs0MtpHJZaAVLfQjfRPw==", + "dependencies": { + "@deephaven/components": "^0.68.0", + "@deephaven/golden-layout": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/iris-grid": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", "@fortawesome/fontawesome-common-types": "^6.1.1", "@fortawesome/react-fontawesome": "^0.2.0" }, @@ -35821,14 +35857,19 @@ "react": "^17.x" } }, + "plugins/ui/src/js/node_modules/@deephaven/plugin/node_modules/@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + }, "plugins/ui/src/js/node_modules/@deephaven/react-hooks": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.67.0.tgz", - "integrity": "sha512-WbjYbYhBpXvLnq7TA8ISpIQhP4ViMdv98pFiLfKCW8Sld/5DARG8AcIbYpk+Q4QSsklhr8gGQJNWlzSqMSvz2g==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.68.0.tgz", + "integrity": "sha512-d7mWy2utLGVkXqKO+LT1Xrg1KjPPcGsahPETAlnrTKRf777woyHzuHb3DTMD+ghnt0JjZdireyShIorrlDLAyw==", "dependencies": { "@adobe/react-spectrum": "^3.34.1", - "@deephaven/log": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "@deephaven/log": "^0.68.0", + "@deephaven/utils": "^0.68.0", "lodash.debounce": "^4.0.8", "shortid": "^2.2.16" }, @@ -35840,14 +35881,14 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/redux": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.67.0.tgz", - "integrity": "sha512-wV/2/q4sM/DktKmOGZoyo3c/cIwuGBvIOI3TG7JYpKXUfRyWf9gVxnBwp9wgu3yO3eNYAcq9xW74qYHGtYyqow==", - "dependencies": { - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/plugin": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.68.0.tgz", + "integrity": "sha512-GPA+5Z79RumLpwzse4eQ0qyfBigDZx6n8YK6yMdYMIbOB8u6EtwFucz+K3uBYSmCp1sGLExyn9d4SIE6yyYMpw==", + "dependencies": { + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/plugin": "^0.68.0", "deep-equal": "^2.0.5", "redux-thunk": "2.4.1" }, @@ -35858,13 +35899,18 @@ "redux": "^4.2.0" } }, + "plugins/ui/src/js/node_modules/@deephaven/redux/node_modules/@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + }, "plugins/ui/src/js/node_modules/@deephaven/storage": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.67.0.tgz", - "integrity": "sha512-KA/NycHgdqsgY/WDs3srw8Bk4ln3/v17ev3Is8TPOoht+lPddzXvN145CcpyunljKTjd24eWoXXZPBVtuyW81A==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.68.0.tgz", + "integrity": "sha512-B7mXYFTeR4pcmgVr5wKwDygdaLWwyo9n9XFZ7aOvUXx2m7knsGVxUVuXGl3WDTNbdknHkNSNG5PMGGC93IefaA==", "dependencies": { - "@deephaven/filters": "^0.67.0", - "@deephaven/log": "^0.67.0", + "@deephaven/filters": "^0.68.0", + "@deephaven/log": "^0.68.0", "lodash.throttle": "^4.1.1" }, "engines": { @@ -35875,9 +35921,9 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/utils": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.67.0.tgz", - "integrity": "sha512-bA6pU5QOYDWNZV+fSW8LgDNh/mZ0G3M4zpropcHx1w0iRoLL4xC0b6UgAWCieG9ehi76wsjIDGOo9cy3iYP6WQ==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.68.0.tgz", + "integrity": "sha512-Nl8PO0q7a17ejAO3dehQdcJSuuaCWqE0PVGmuIDXALGC2OcUYta6AjZH+HgKFHIUepqXCHP160YFGDV7K8evOg==", "engines": { "node": ">=16" } @@ -39712,20 +39758,21 @@ "version": "file:plugins/ui/src/js", "requires": { "@adobe/react-spectrum": "^3.34.1", - "@deephaven/chart": "^0.67.0", - "@deephaven/components": "^0.67.0", - "@deephaven/dashboard": "^0.67.0", - "@deephaven/dashboard-core-plugins": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/iris-grid": "^0.67.0", - "@deephaven/jsapi-bootstrap": "^0.67.0", - "@deephaven/jsapi-components": "^0.67.0", + "@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": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/plugin": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/redux": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "@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", "@fortawesome/react-fontawesome": "^0.2.0", "@react-types/shared": "^3.22.0", "@types/react": "^17.0.2", @@ -39740,17 +39787,17 @@ }, "dependencies": { "@deephaven/chart": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.67.0.tgz", - "integrity": "sha512-Jkq9Lh647JWRvUSuqKnyqeMWjsSDDQY+uUpcAkw9F4J2Fl+j80TcG6Pk9xyocEJ1KwvCVojNtZbDlQHHPkVIMQ==", - "requires": { - "@deephaven/components": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.68.0.tgz", + "integrity": "sha512-KDrQm6id+MCPY8v+rraORQOaUbamyjFYeMFz5gAgJka1ls/gkEDCXTynEkEHseDjTKXb/S1y7Yy7MXGjNeKH6Q==", + "requires": { + "@deephaven/components": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/utils": "^0.68.0", "deep-equal": "^2.0.5", "lodash.debounce": "^4.0.8", "lodash.set": "^4.3.2", @@ -39759,18 +39806,25 @@ "plotly.js": "^2.29.1", "prop-types": "^15.7.2", "react-plotly.js": "^2.6.0" + }, + "dependencies": { + "@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + } } }, "@deephaven/components": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.67.0.tgz", - "integrity": "sha512-wpyBFL+/ePadhtxFu2+lG55UbWfzcwGyFtarLL7x3aVJdTTcwi5YtgUdYxHgbpmBfhG+mht2aLU59mLh2dhZ0A==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.68.0.tgz", + "integrity": "sha512-3AJaLtUvHrduXxl8CprviR/5lQfR5rsvnWQJBgVRPs6XZxcwyEPmBu0c1UEu5JFXYYDVnnt47TbMaZA9kB7ZFw==", "requires": { "@adobe/react-spectrum": "^3.34.1", - "@deephaven/icons": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", "@react-spectrum/theme-default": "^3.5.1", @@ -39792,19 +39846,19 @@ } }, "@deephaven/console": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.67.0.tgz", - "integrity": "sha512-umMLDPdaAyLafXW35fr7kWk/5ZfEd44lyTgu9GDVVththSLyKj3hpIBUWpfIGekwTrb46wfZbVmRbPKEmZNa4w==", - "requires": { - "@deephaven/chart": "^0.67.0", - "@deephaven/components": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/jsapi-bootstrap": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/storage": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.68.0.tgz", + "integrity": "sha512-aRg6L6n+/6RgE+Qad6EGdrka4Qd/9kaRqPPp3bqom5QSowOB0ZZ8auf4hBp9fT6/u7nxdTbz0uVKhI3lCXn7Bw==", + "requires": { + "@deephaven/chart": "^0.68.0", + "@deephaven/components": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/jsapi-bootstrap": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/storage": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "linkifyjs": "^4.1.0", @@ -39818,19 +39872,26 @@ "prop-types": "^15.7.2", "shell-quote": "^1.7.2", "shortid": "^2.2.16" + }, + "dependencies": { + "@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + } } }, "@deephaven/dashboard": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.67.0.tgz", - "integrity": "sha512-Sx16vqAxPKkF1x1xDfgKnntn7JW37mEBiV1D8qUgCHYUOM+uYiHoh1/UIU/cJfGrdx9ln+vUN21bkLDs++e1iQ==", - "requires": { - "@deephaven/components": "^0.67.0", - "@deephaven/golden-layout": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/redux": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.68.0.tgz", + "integrity": "sha512-jPd9dU/ZwGTAc6BSM/Yfu+vAzTJyfSLziNWRHFqAA3xA3r2+a2QiRhfkEVYN4Kua2QVhO3NGQMY6th7t0gTQAw==", + "requires": { + "@deephaven/components": "^0.68.0", + "@deephaven/golden-layout": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/redux": "^0.68.0", + "@deephaven/utils": "^0.68.0", "deep-equal": "^2.0.5", "lodash.ismatch": "^4.1.1", "lodash.throttle": "^4.1.1", @@ -39839,30 +39900,30 @@ } }, "@deephaven/dashboard-core-plugins": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.67.0.tgz", - "integrity": "sha512-1XrHcvLclyIZLttFO0hgCncK/jEPT02NTObI/7OHLeTKpl6OgHuzmabYFxB0QrPAWqmlPaURtaDCH/kun4t54A==", - "requires": { - "@deephaven/chart": "^0.67.0", - "@deephaven/components": "^0.67.0", - "@deephaven/console": "^0.67.0", - "@deephaven/dashboard": "^0.67.0", - "@deephaven/file-explorer": "^0.67.0", - "@deephaven/filters": "^0.67.0", - "@deephaven/golden-layout": "^0.67.0", - "@deephaven/grid": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/iris-grid": "^0.67.0", - "@deephaven/jsapi-bootstrap": "^0.67.0", - "@deephaven/jsapi-components": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/plugin": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/redux": "^0.67.0", - "@deephaven/storage": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.68.0.tgz", + "integrity": "sha512-ivYF6cYj20sKf9HNzhKwnEaX1VfwsMSTWRhdvXyy67XQbcV3+v/kgiZnrCQKw3547nsETWT1EI4UuIX2L59S+w==", + "requires": { + "@deephaven/chart": "^0.68.0", + "@deephaven/components": "^0.68.0", + "@deephaven/console": "^0.68.0", + "@deephaven/dashboard": "^0.68.0", + "@deephaven/file-explorer": "^0.68.0", + "@deephaven/filters": "^0.68.0", + "@deephaven/golden-layout": "^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.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/plugin": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/redux": "^0.68.0", + "@deephaven/storage": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "deep-equal": "^2.0.5", @@ -39880,18 +39941,25 @@ "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", "shortid": "^2.2.16" + }, + "dependencies": { + "@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + } } }, "@deephaven/file-explorer": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.67.0.tgz", - "integrity": "sha512-Be4E+PK7lgwzGpOY3rnD2PssY/7cVBVcn7RMq9cPnWAcQZpkQg0IGCYpu+ahmRwqv3joeDiHUS7Vr1Fim73j+Q==", - "requires": { - "@deephaven/components": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/storage": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.68.0.tgz", + "integrity": "sha512-78PMW1dAOULDSwXTyLnn/d8T8OwTrGd53k4p0py8XFfXtIgsIouJElER6v4+5p5oeK1rHI9DC1CjvNWUUqvvHQ==", + "requires": { + "@deephaven/components": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/storage": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", @@ -39900,25 +39968,25 @@ } }, "@deephaven/filters": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.67.0.tgz", - "integrity": "sha512-k/qSHXmvAzfDn/EkA+hpsB5nwB/LUYntDH9lHUDix9ygnvalI72I2LgkQ2BBNri3VTKRGLXdummuWrNDVBvZvA==" + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.68.0.tgz", + "integrity": "sha512-H6eOMdbbzqTsRRDRwILbVjdQnCOaKRE1B3gHHPdUvRoKIAlNqQxBh4L+DW3WbuOBYjAuCcMutRHpy5gohaPchw==" }, "@deephaven/golden-layout": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.67.0.tgz", - "integrity": "sha512-Yt9cVBOdjNLsFJrk0BH7Ld/Y3IzLX9gU8uzxcOZ13JyVKf8Jl9sIvZA/MvMVUbKwqTMeAcmz2AUVuP5RVLP0jw==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.68.0.tgz", + "integrity": "sha512-+kwnRD2NCir0RrfPQRdc+03TLtORzfe2bIbzxTDBZro0FDPBifPgNUAO5IUsTDw0wfDrTezyEk1KtMzHf/U7vA==", "requires": { - "@deephaven/components": "^0.67.0", + "@deephaven/components": "^0.68.0", "jquery": "^3.6.0" } }, "@deephaven/grid": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.67.0.tgz", - "integrity": "sha512-/UQf3OjQzCqbZ4+hliUzxPs+oCCK1sdiDblhcXfQnBCFVWlnrIXOQGf+5purPAoa5pfocgnXGTsZG3TEIkfyfQ==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.68.0.tgz", + "integrity": "sha512-cSEWNq3ANtLCAWAgzXz/4ifGGAjYR9/Aex2p+xJWS73fmFHtAw7IsI63K5QB+9mxqVdH9TNZ1IztdDbucEwq8Q==", "requires": { - "@deephaven/utils": "^0.67.0", + "@deephaven/utils": "^0.68.0", "classnames": "^2.3.1", "color-convert": "^2.0.1", "event-target-shim": "^6.0.2", @@ -39930,30 +39998,30 @@ } }, "@deephaven/icons": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.67.0.tgz", - "integrity": "sha512-2m4Ufnwcf+ZWnH0JigPpJbxb4QNdu7RKrjaGt0wXEzml5N8arurx1kWMktOhk6Cz25DYJDCe/RMXuHjTqH2vUQ==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.68.0.tgz", + "integrity": "sha512-FUF+eKocoqr1l5sKN3+vA7BBJGWhHRndofwt8QQmt7nv6Oh6SM/I3x37Jx/riacuMN+yUqes5yuEgWqS0QM+Nw==", "requires": { "@fortawesome/fontawesome-common-types": "^6.1.1" } }, "@deephaven/iris-grid": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.67.0.tgz", - "integrity": "sha512-LMttYlLIRD4NXxBOFc/F36zEsv6C0cZWXmFmeYJdFF1w2qugQpbLubxgu5roJt4qP9ZKNm00IhQs6sVfll1zhg==", - "requires": { - "@deephaven/components": "^0.67.0", - "@deephaven/console": "^0.67.0", - "@deephaven/filters": "^0.67.0", - "@deephaven/grid": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/jsapi-components": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/storage": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.68.0.tgz", + "integrity": "sha512-6LP6rOdWfCQrumQNZAxMZnYpSZFOC/sKYDgs3oDSpIbGSLxsLVcdp9z6/sCQ0I+KwRcWAEzq47QZ6UjTe2QH/Q==", + "requires": { + "@deephaven/components": "^0.68.0", + "@deephaven/console": "^0.68.0", + "@deephaven/filters": "^0.68.0", + "@deephaven/grid": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/jsapi-components": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/storage": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@dnd-kit/core": "^6.1.0", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.2", @@ -39970,36 +40038,57 @@ "react-beautiful-dnd": "^13.1.0", "react-transition-group": "^4.4.2", "shortid": "^2.2.16" + }, + "dependencies": { + "@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + } } }, "@deephaven/jsapi-bootstrap": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.67.0.tgz", - "integrity": "sha512-vFEm6YH33TOO3kQBWCxlxJNCZllGBw2RumkhfijS6JhTRPFQMJeb7l3g71W9j128z5eKp0g5c3rnasuQ/R0/fg==", - "requires": { - "@deephaven/components": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0" + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.68.0.tgz", + "integrity": "sha512-i0Tlnh50yhnPXuotw2JSzPgjNe76bVh2MrAGHE9AUkhvO1P/3kFQ1EfVXIvxQ4K2z/9Uhq8b3uFWi6iAGiZ7Hg==", + "requires": { + "@deephaven/components": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0" + }, + "dependencies": { + "@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + } } }, "@deephaven/jsapi-components": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.67.0.tgz", - "integrity": "sha512-TbdVypvpCHd6eIAnDeDnpIbyLEGq3uB8BSZXGEj1QZhgEZCNUihBKU8PUCr2KcA8gYcYROuEXKFHNvi4NVwRpw==", - "requires": { - "@deephaven/components": "^0.67.0", - "@deephaven/jsapi-bootstrap": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.68.0.tgz", + "integrity": "sha512-eiVLFFVORP8tOEueYjLvvjTF9hd6B/gMi7zZMcNMWYEzCvtF1v0/8qakK02pEo659g28ixRBKQQQPyni00B09Q==", + "requires": { + "@deephaven/components": "^0.68.0", + "@deephaven/jsapi-bootstrap": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", + "@deephaven/utils": "^0.68.0", "@types/js-cookie": "^3.0.3", "classnames": "^2.3.2", "js-cookie": "^3.0.5", "lodash.debounce": "^4.0.8", "prop-types": "^15.8.1" + }, + "dependencies": { + "@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + } } }, "@deephaven/jsapi-types": { @@ -40008,81 +40097,102 @@ "integrity": "sha512-KOI6tI7NeFSDi3RbW2u75qH5qFoH81AJREOsZqVs0nSdoHuPXqvbwy/cpuh2bJdPLFAJ5fgzcuAw4nB8HQ1MkA==" }, "@deephaven/jsapi-utils": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.67.0.tgz", - "integrity": "sha512-4s5KLSsM8mF+9Uv8f5ftanWU25WLErn5kKCrxZWBGQgJORMPm834KGiHQeD4HMpeZ84s/gMK4rtiWxJ4u9eaHg==", - "requires": { - "@deephaven/filters": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.68.0.tgz", + "integrity": "sha512-bQ4+ZLmpaYlMBc6p7YI0n/OJvQA5zUManW+3bFf9WaZsYI8rxeyDzDtGn8NdI0jQirl0rt/9Uvak7AelqEInJw==", + "requires": { + "@deephaven/filters": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/log": "^0.68.0", + "@deephaven/utils": "^0.68.0", "lodash.clamp": "^4.0.3", "shortid": "^2.2.16" + }, + "dependencies": { + "@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + } } }, "@deephaven/log": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.67.0.tgz", - "integrity": "sha512-tfYUThfC3JXTBXB7bVr8IN0go3xbKxlU42XPKtQaShpRxrXgWDmLAuzHtoqCTTlunYxzXa/m8SAIaJ5qGztN6A==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.68.0.tgz", + "integrity": "sha512-F3kZYudez4Jxnunwhw97WcWySol/4Maqd4wD93fydmnMPMe05WA+Hya9b4CQ4J3XZIbRnuV9kS3laf6YEI6xig==", "requires": { "event-target-shim": "^6.0.2" } }, "@deephaven/plugin": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.67.0.tgz", - "integrity": "sha512-DiNmjqaclXub0vPVxXWGNQpFkTiwO+m9OqUtGTqIRzggZCK3IfqHFcjzUJx3GlCkf/efLIrJMQQVWPONMudRMw==", - "requires": { - "@deephaven/components": "^0.67.0", - "@deephaven/golden-layout": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/iris-grid": "^0.67.0", - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.68.0.tgz", + "integrity": "sha512-FlSF6CSKTKAGi88iLF9mEEROTJ6BnPOSbMAUAFTXEGJSngcEZ4EaybwjYV0HxMrSKhbs0MtpHJZaAVLfQjfRPw==", + "requires": { + "@deephaven/components": "^0.68.0", + "@deephaven/golden-layout": "^0.68.0", + "@deephaven/icons": "^0.68.0", + "@deephaven/iris-grid": "^0.68.0", + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/log": "^0.68.0", + "@deephaven/react-hooks": "^0.68.0", "@fortawesome/fontawesome-common-types": "^6.1.1", "@fortawesome/react-fontawesome": "^0.2.0" + }, + "dependencies": { + "@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + } } }, "@deephaven/react-hooks": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.67.0.tgz", - "integrity": "sha512-WbjYbYhBpXvLnq7TA8ISpIQhP4ViMdv98pFiLfKCW8Sld/5DARG8AcIbYpk+Q4QSsklhr8gGQJNWlzSqMSvz2g==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.68.0.tgz", + "integrity": "sha512-d7mWy2utLGVkXqKO+LT1Xrg1KjPPcGsahPETAlnrTKRf777woyHzuHb3DTMD+ghnt0JjZdireyShIorrlDLAyw==", "requires": { "@adobe/react-spectrum": "^3.34.1", - "@deephaven/log": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "@deephaven/log": "^0.68.0", + "@deephaven/utils": "^0.68.0", "lodash.debounce": "^4.0.8", "shortid": "^2.2.16" } }, "@deephaven/redux": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.67.0.tgz", - "integrity": "sha512-wV/2/q4sM/DktKmOGZoyo3c/cIwuGBvIOI3TG7JYpKXUfRyWf9gVxnBwp9wgu3yO3eNYAcq9xW74qYHGtYyqow==", - "requires": { - "@deephaven/jsapi-types": "^0.67.0", - "@deephaven/jsapi-utils": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/plugin": "^0.67.0", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.68.0.tgz", + "integrity": "sha512-GPA+5Z79RumLpwzse4eQ0qyfBigDZx6n8YK6yMdYMIbOB8u6EtwFucz+K3uBYSmCp1sGLExyn9d4SIE6yyYMpw==", + "requires": { + "@deephaven/jsapi-types": "1.0.0-dev0.33.1", + "@deephaven/jsapi-utils": "^0.68.0", + "@deephaven/log": "^0.68.0", + "@deephaven/plugin": "^0.68.0", "deep-equal": "^2.0.5", "redux-thunk": "2.4.1" + }, + "dependencies": { + "@deephaven/jsapi-types": { + "version": "1.0.0-dev0.33.1", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.33.1.tgz", + "integrity": "sha512-1f0ZsR7zpXGQFs6vyRovBUECUPg7tNYrzCuHA0iJCrTlJ0FfFDVcDg8uZxsH+11cERcAEs5xdSHXqpo/fM6dKQ==" + } } }, "@deephaven/storage": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.67.0.tgz", - "integrity": "sha512-KA/NycHgdqsgY/WDs3srw8Bk4ln3/v17ev3Is8TPOoht+lPddzXvN145CcpyunljKTjd24eWoXXZPBVtuyW81A==", + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.68.0.tgz", + "integrity": "sha512-B7mXYFTeR4pcmgVr5wKwDygdaLWwyo9n9XFZ7aOvUXx2m7knsGVxUVuXGl3WDTNbdknHkNSNG5PMGGC93IefaA==", "requires": { - "@deephaven/filters": "^0.67.0", - "@deephaven/log": "^0.67.0", + "@deephaven/filters": "^0.68.0", + "@deephaven/log": "^0.68.0", "lodash.throttle": "^4.1.1" } }, "@deephaven/utils": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.67.0.tgz", - "integrity": "sha512-bA6pU5QOYDWNZV+fSW8LgDNh/mZ0G3M4zpropcHx1w0iRoLL4xC0b6UgAWCieG9ehi76wsjIDGOo9cy3iYP6WQ==" + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.68.0.tgz", + "integrity": "sha512-Nl8PO0q7a17ejAO3dehQdcJSuuaCWqE0PVGmuIDXALGC2OcUYta6AjZH+HgKFHIUepqXCHP160YFGDV7K8evOg==" }, "color-convert": { "version": "2.0.1", diff --git a/package.json b/package.json index e656220ed..dacf6f0b5 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "test:ci:unit": "jest --config jest.config.unit.cjs --ci --cacheDirectory $PWD/.jest-cache", "test:ci:lint": "jest --config jest.config.lint.cjs --ci --cacheDirectory $PWD/.jest-cache", "e2e": "playwright run", - "e2e:docker": "./tools/run_docker.sh e2e-tests", + "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" }, diff --git a/plugins/example-theme/src/js/package.json b/plugins/example-theme/src/js/package.json index 09fb97e93..1da28d1e5 100644 --- a/plugins/example-theme/src/js/package.json +++ b/plugins/example-theme/src/js/package.json @@ -14,5 +14,6 @@ "@deephaven/plugin": "^0.58.0", "typescript": "^5.2.2", "vite": "^5.0.8" - } + }, + "private": true } diff --git a/plugins/ui/CHANGELOG.md b/plugins/ui/CHANGELOG.md index ec7714be2..fc06c4663 100644 --- a/plugins/ui/CHANGELOG.md +++ b/plugins/ui/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines. - - - +## ui-v0.9.0 - 2024-03-09 +#### Bug Fixes +- Tab Panels contents should take up the full height (#340) - (6028195) - mofojed +- Remove tooltip prop (#334) - (cbe2140) - Joe +- add missing dependencies params for liveness scope and table listener hooks (#291) - (9d6b7de) - niloc132 +- added missing picker imports (#332) - (272cdf9) - Joe +#### Build system +- Update dh ui packages to ^0.66.1 (#330) - (9433a98) - bmingles +#### Features +- Add ui.table press event listener support (#346) - (b805683) - mofojed +- UI Picker JS (#333) - (e3af9f5) - bmingles + +- - - + ## ui-v0.8.0 - 2024-02-28 #### Bug Fixes - Use correct formatting settings for ui.table (#326) - (4762053) - mofojed diff --git a/plugins/ui/DESIGN.md b/plugins/ui/DESIGN.md index 1a1ce29bc..4ab2d6be6 100644 --- a/plugins/ui/DESIGN.md +++ b/plugins/ui/DESIGN.md @@ -1024,11 +1024,11 @@ ui.item( ``` ###### Parameters -| Parameter | Type | Description | -|----------------|--------------|----------------------------------------| -| `*children` | `Stringable` | The options to render within the item. | -| `**props` | `Any` | Any other Item prop | +| Parameter | Type | Description | +| ----------- | ------------ | -------------------------------------- | +| `*children` | `Stringable` | The options to render within the item. | +| `**props` | `Any` | Any other Item prop | ##### ui.section @@ -1044,18 +1044,20 @@ ui.section( ``` ###### Parameters -| Parameter | Type | Description | -|-----------------------|-----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| -| `*children` | `PickerItem` | The options to render within the section. | -| `title` | `str \| None` | The title of the section. | -| `**props` | `Any` | Any other Section prop | + +| Parameter | Type | Description | +| ----------- | ------------- | ----------------------------------------- | +| `*children` | `PickerItem` | The options to render within the section. | +| `title` | `str \| None` | The title of the section. | +| `**props` | `Any` | Any other Section prop | ##### ui.picker + A picker that can be used to select from a list. Children should be one of four types: If children are of type `PickerItem`, they are the dropdown options. If children are of type `SectionElement`, they are the dropdown sections. -If children are of type `Table`, the values in the table are the dropdown options. There can only be one child, the `Table`. -If children are of type `PartitionedTable`, the values in the table are the dropdown options and the partitions create multiple sections. There can only be one child, the `PartitionedTable`. +If children are of type `Table`, the values in the table are the dropdown options. There can only be one child, the `Table`. +If children are of type `PartitionedTable`, the values in the table are the dropdown options and the partitions create multiple sections. There can only be one child, the `PartitionedTable`. ```py import deephaven.ui as ui @@ -1068,26 +1070,27 @@ ui.picker( title_column: ColumnName | None = None, default_selected_key: Key | None = None, selected_key: Key | None = None, - on_selection_change: Callable[[Key], None] | None = None, + on_selection_change: Callable[[Key], None] | None = None, on_change: Callable[[Key], None] | None = None, **props: Any ) -> ItemElement ``` ###### Parameters -| Parameter | Type | Description | -|------------------------|--------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `*children` | `PickerItem \| SectionElement \| Table \| PartitionedTable` | The options to render within the picker. | -| `key_column` | `ColumnName \| None` | Only valid if children are of type `Table` or `PartitionedTable`. The column of values to use as item keys. Defaults to the first column. | -| `label_column` | `ColumnName \| None` | Only valid if children are of type `Table` or `PartitionedTable`. The column of values to display as primary text. Defaults to the `key_column` value. | -| `description_column` | `ColumnName \| None` | Only valid if children are of type `Table` or `PartitionedTable`. The column of values to display as descriptions. | -| `icon_column` | `ColumnName \| None` | Only valid if children are of type `Table` or `PartitionedTable`. The column of values to map to icons. | -| `title_column` | `ColumnName \| None` | Only valid if children is of type `PartitionedTable`. The column of values to display as section names. Should be the same for all values in the constituent `Table`. If not specified, the section titles will be created from the `key_columns` of the `PartitionedTable`. | -| `default_selected_key` | `Key \| None` | The initial selected key in the collection (uncontrolled). | -| `selected_key` | `Key \| None` | The currently selected key in the collection (controlled). | -| `on_selection_change` | `Callable[[Key], None] \| None` | Handler that is called when the selection changes. | -| `on_change` | `Callable[[Key], None] \| None` | Alias of `on_selection_change`. Handler that is called when the selection changes. | -| `**props` | `Any` | Any other [Picker](https://react-spectrum.adobe.com/react-spectrum/Picker.html) prop, with the exception of `items`, `validate`, `errorMessage` (as a callback) and `onLoadMore` | + +| Parameter | Type | Description | +| ---------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `*children` | `PickerItem \| SectionElement \| Table \| PartitionedTable` | The options to render within the picker. | +| `key_column` | `ColumnName \| None` | Only valid if children are of type `Table` or `PartitionedTable`. The column of values to use as item keys. Defaults to the first column. | +| `label_column` | `ColumnName \| None` | Only valid if children are of type `Table` or `PartitionedTable`. The column of values to display as primary text. Defaults to the `key_column` value. | +| `description_column` | `ColumnName \| None` | Only valid if children are of type `Table` or `PartitionedTable`. The column of values to display as descriptions. | +| `icon_column` | `ColumnName \| None` | Only valid if children are of type `Table` or `PartitionedTable`. The column of values to map to icons. | +| `title_column` | `ColumnName \| None` | Only valid if children is of type `PartitionedTable`. The column of values to display as section names. Should be the same for all values in the constituent `Table`. If not specified, the section titles will be created from the `key_columns` of the `PartitionedTable`. | +| `default_selected_key` | `Key \| None` | The initial selected key in the collection (uncontrolled). | +| `selected_key` | `Key \| None` | The currently selected key in the collection (controlled). | +| `on_selection_change` | `Callable[[Key], None] \| None` | Handler that is called when the selection changes. | +| `on_change` | `Callable[[Key], None] \| None` | Alias of `on_selection_change`. Handler that is called when the selection changes. | +| `**props` | `Any` | Any other [Picker](https://react-spectrum.adobe.com/react-spectrum/Picker.html) prop, with the exception of `items`, `validate`, `errorMessage` (as a callback) and `onLoadMore` | ```py import deephaven.ui as ui @@ -1219,7 +1222,7 @@ Other props that can be passed into `ui.table` are defined below. ```py ui_table( - table: Table, + table: Table, always_fetch_columns: ColumnNameCombination | None, back_columns: ColumnNameCombination | None, freeze_columns: ColumnNameCombination | None, @@ -1239,8 +1242,8 @@ ui_table( column_display_names: dict[ColumnName, ColumnNameCombination] | None, on_row_press: Callable[[RowIndex, RowData], None] | None, on_row_double_press: Callable[[RowIndex, RowData], None] | None - on_cell_press: Callable[[CellIndex, Any], None] | None, - on_cell_double_press: Callable[[CellIndex, Any], None] | None + on_cell_press: Callable[[CellIndex, CellData], None] | None, + on_cell_double_press: Callable[[CellIndex, CellData], None] | None on_column_press: Callable[[ColumnName], None] | None, on_columns_double_press: Callable[[ColumnName], None] | None, on_search: Callable[[str], None], @@ -1251,36 +1254,36 @@ ui_table( ) -> UITable ``` -| Parameter | Type | Description | -|-----------------------------------|---------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `always_fetch_columns` | `ColumnNameCombination \| None` | The columns to always fetch from the server. May be a single column name. These will not be affected by the users current viewport/horizontal scrolling. Useful if you have a column with key value data that you want to always include in the data sent for row click operations. | -| `back_columns` | `ColumnNameCombination \| None` | The columns to show at the back of the table. May be a single column name. These will not be moveable in the UI. | -| `freeze_columns` | `ColumnNameCombination \| None` | The columns to freeze to the front of the table. May be a single column name. These will always be visible and not affected by horizontal scrolling. | -| `front_columns` | `ColumnNameCombination \| None` | The columns to show at the front of the table. May be a single column name. These will not be moveable in the UI. | -| `hide_columns` | `ColumnNameCombination \| None` | The columns to hide by default from the table. May be a single column name. The user can still resize the columns to view them. | -| `quick_filters` | `dict[ColumnName, QuickFilterExpression] \| None` | Quick filters for the UI to apply to the table. | -| `show_search` | `bool \| None` | `True` to show the search bar by default, `False` to not. | -| `show_quick_filters` | `bool \| None` | `True` to show the quick filters by default, `False` to not. | -| `show_column_headers` | `bool \| None` | `True` to show the column headers by default, `False` to not. | -| `selection_mode` | `SelectionMode \| None` | Can be `MULTIPLE` to allow multiple selection or `SINGLE` to not allow it. | -| `selection_area` | `SelectionArea \| None` | The unit that is selected on press. Can be `ROW`, `COLUMN`, or `CELL`. | -| `selection_style` | `SelectionStyleCombination \| None` | The style of the selection. Can be `HIGHLIGHT`, `CHECKBOX`, or a combination of those. | -| `selected_rows` | `RowIndexCombination \| None` | The rows that are selected by default. Only valid if `selection_area` is `ROW`. | -| `selected_columns` | `ColumnIndexCombination \| None` | The columns that are selected by default. Only valid if `selection_area` is `COLUMN`. | -| `selected_cells` | `CellIndexCombination \| None` | The cells that are selected by default. Only valid if `selection_area` is `CELL`. | -| `density` | `DensityMode \| None` | The density of the table. Can be `COMPACT`, `REGULAR`, or `SPACIOUS`. | -| `column_display_names` | `dict[ColumnName, ColumnNameCombination] \| None` | The display names. If a sequence of column names is provided for a column, the display name will be set to the longest column name that can be fully displayed. | -| `on_row_press` | `Callable[[RowIndex, RowData], None] \| None` | The callback function to run when a cell in a row is released (such as a click). The first parameter is the row index, and the second is the row data provided in a dictionary where the column names are the keys. | -| `on_row_double_press` | `Callable[[RowIndex, RowData], None] \| None` | The callback function to run when a cell in a row is double pressed. The first parameter is the row index, and the second is the row data provided in a dictionary where the column names are the keys. | -| `on_cell_press` | `Callable[[CellIndex, Any], None] \| None` | The callback function to run when a cell is released (such as a click). The first parameter is the cell index, and the second is the cell data. | -| `on_cell_double_press` | `Callable[[CellIndex, Any], None] \| None` | The callback function to run when a cell is double pressed. The first parameter is the cell index, and the second is the cell data. | -| `on_column_press` | `Callable[[ColumnName], None] \| None` | The callback function to run when a column is released (such as a click). The only parameter is the column name. | -| `on_column_double_press` | `Callable[[ColumnName], None] \| None` | The callback function to run when a cell in a column is double pressed. The only parameter is the column name. | -| `on_search` | `Callable[[str], None] \| None` | The callback function to run when the search bar is used. The only parameter is the search string. | -| `on_quick_filter` | `Callable[[ColumnName, QuickFilterExpression], None] \| None` | The callback function to run when a quick filter is applied. The first parameter is the column name, and the second is the quick filter expression. | -| `on_freeze_column` | `Callable[[ColumnName], None] \| None` | The callback function to run when a column is frozen. The only parameter is the frozen column name. | -| `on_hide_column` | `Callable[[ColumnName], None] \| None` | The callback function to run when a column is hidden. The only parameter is the hidden column name. | -| `on_sort` | `Callable[[ColumnName, LiteralSortDirection], None] \| None` | The callback function to run when a column is sorted. The first parameter is the column name, and the second is the sort direction. | +| Parameter | Type | Description | +| ------------------------ | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `always_fetch_columns` | `ColumnNameCombination \| None` | The columns to always fetch from the server. May be a single column name. These will not be affected by the users current viewport/horizontal scrolling. Useful if you have a column with key value data that you want to always include in the data sent for row click operations. | +| `back_columns` | `ColumnNameCombination \| None` | The columns to show at the back of the table. May be a single column name. These will not be moveable in the UI. | +| `freeze_columns` | `ColumnNameCombination \| None` | The columns to freeze to the front of the table. May be a single column name. These will always be visible and not affected by horizontal scrolling. | +| `front_columns` | `ColumnNameCombination \| None` | The columns to show at the front of the table. May be a single column name. These will not be moveable in the UI. | +| `hide_columns` | `ColumnNameCombination \| None` | The columns to hide by default from the table. May be a single column name. The user can still resize the columns to view them. | +| `quick_filters` | `dict[ColumnName, QuickFilterExpression] \| None` | Quick filters for the UI to apply to the table. | +| `show_search` | `bool \| None` | `True` to show the search bar by default, `False` to not. | +| `show_quick_filters` | `bool \| None` | `True` to show the quick filters by default, `False` to not. | +| `show_column_headers` | `bool \| None` | `True` to show the column headers by default, `False` to not. | +| `selection_mode` | `SelectionMode \| None` | Can be `MULTIPLE` to allow multiple selection or `SINGLE` to not allow it. | +| `selection_area` | `SelectionArea \| None` | The unit that is selected on press. Can be `ROW`, `COLUMN`, or `CELL`. | +| `selection_style` | `SelectionStyleCombination \| None` | The style of the selection. Can be `HIGHLIGHT`, `CHECKBOX`, or a combination of those. | +| `selected_rows` | `RowIndexCombination \| None` | The rows that are selected by default. Only valid if `selection_area` is `ROW`. | +| `selected_columns` | `ColumnIndexCombination \| None` | The columns that are selected by default. Only valid if `selection_area` is `COLUMN`. | +| `selected_cells` | `CellIndexCombination \| None` | The cells that are selected by default. Only valid if `selection_area` is `CELL`. | +| `density` | `DensityMode \| None` | The density of the table. Can be `COMPACT`, `REGULAR`, or `SPACIOUS`. | +| `column_display_names` | `dict[ColumnName, ColumnNameCombination] \| None` | The display names. If a sequence of column names is provided for a column, the display name will be set to the longest column name that can be fully displayed. | +| `on_row_press` | `Callable[[RowIndex, RowData], None] \| None` | The callback function to run when a cell in a row is released (such as a click). The first parameter is the row index, and the second is the row data provided in a dictionary where the column names are the keys. | +| `on_row_double_press` | `Callable[[RowIndex, RowData], None] \| None` | The callback function to run when a cell in a row is double pressed. The first parameter is the row index, and the second is the row data provided in a dictionary where the column names are the keys. | +| `on_cell_press` | `Callable[[CellIndex, CellData], None] \| None` | The callback function to run when a cell is released (such as a click). The first parameter is the cell index, and the second is the cell data. | +| `on_cell_double_press` | `Callable[[CellIndex, CellData], None] \| None` | The callback function to run when a cell is double pressed. The first parameter is the cell index, and the second is the cell data. | +| `on_column_press` | `Callable[[ColumnName], None] \| None` | The callback function to run when a column is released (such as a click). The only parameter is the column name. | +| `on_column_double_press` | `Callable[[ColumnName], None] \| None` | The callback function to run when a cell in a column is double pressed. The only parameter is the column name. | +| `on_search` | `Callable[[str], None] \| None` | The callback function to run when the search bar is used. The only parameter is the search string. | +| `on_quick_filter` | `Callable[[ColumnName, QuickFilterExpression], None] \| None` | The callback function to run when a quick filter is applied. The first parameter is the column name, and the second is the quick filter expression. | +| `on_freeze_column` | `Callable[[ColumnName], None] \| None` | The callback function to run when a column is frozen. The only parameter is the frozen column name. | +| `on_hide_column` | `Callable[[ColumnName], None] \| None` | The callback function to run when a column is hidden. The only parameter is the hidden column name. | +| `on_sort` | `Callable[[ColumnName, LiteralSortDirection], None] \| None` | The callback function to run when a column is sorted. The first parameter is the column name, and the second is the sort direction. | `ui.table` will also support the below methods. @@ -1504,7 +1507,7 @@ ui_fragment = ui.fragment(*children: Element) -> Element The functionality provided my `ui.table` replaces some of the existing functions on `Table`. Below are the functions that are planned for deprecation/deletion of the `Table` interface, and their replacements with the new `ui.table` interface. | Table Function | ui.table Replacement | -| ----------------------------------------------------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------| +| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | `format_columns`
`format_column_where`
`format_row_where` | [color_column](#color_column)
[color_row](#color_row)
[format](#format) | | `layout_hints` | [Props](#Parameters-5) of back_columns, front_columns, freeze_columns, hide_columns, and show_search, as well as method of [column_group](#column_groups) | | `dropColumnFormats` | No replacement | @@ -1660,18 +1663,17 @@ use_cell_data( | `table` | `Table` | The table to create a viewport on. | | `sentinel` | `Sentinel` | A sentinel value to return if the cell is still loading. Default `None`. | - - #### Custom Types Below are some of the custom types that are used in the above API definitions: ```py AggregationOperation = Literal["COUNT", "COUNT_DISTINCT", "DISTINCT", "MIN", "MAX", "SUM", "ABS_SUM", "VAR", "AVG", "STD", "FIRST", "LAST", "UNIQUE", "SKIP"] -CellIndex = [RowIndex, ColumnIndex] +# An index of None means a header was selected +GridIndex = [ColumnIndex | None, RowIndex | None] +CellIndex = [ColumnIndex, RowIndex] Color = DeephavenColor | HexColor -# A ColumnIndex of None indicates a header row -ColumnIndex = int | None +ColumnIndex = int ColumnName = str ColumnData = list[Any] # ID of a component. Used for linking. @@ -1687,10 +1689,9 @@ DeephavenColor = Literal[...] HexColor = str LockType = Literal["shared", "exclusive"] QuickFilterExpression = str -RowData = dict[ColumnName, Any] -# A RowIndex of None indicates a header column -RowIndex = int | None -SelectionStyle = Literal["HIGHLIGHT", "CHECKBOX"] +RowData = dict[ColumnName, RowDataValue] +RowIndex = int +SelectionStyle = Literal["HIGHLIGHT", "CHECKBOX"] SelectionArea = Literal["CELL", "ROW", "COLUMN"] SelectionMode = Literal["SINGLE", "MULTIPLE"] DensityMode = Literal["COMPACT", "REGULAR", "SPACIOUS"] @@ -1713,6 +1714,17 @@ ColumnIndexCombination = Combination[ColumnIndex] CellIndexCombination = Combination[CellIndex] SelectionStyleCombination = Combination[SelectionStyle] +# Data for one cell. Returned with click handlers. +class CellData(TypedDict): + type: str + text: str + value: Any + +# Data for value of one column in a row. Returned with row press handlers. +class RowDataValue(CellData): + isExpandable: bool + isGrouped: bool + # Set a filter for a dashboard. Filter will apply to all items with a matching column/type, except for items specified in the `exclude_ids` parameter class DashboardFilter(TypedDict): # Name of column to filter on diff --git a/plugins/ui/examples/README.md b/plugins/ui/examples/README.md index 2675b3ce8..958477489 100644 --- a/plugins/ui/examples/README.md +++ b/plugins/ui/examples/README.md @@ -758,7 +758,7 @@ def stock_table_input(source, default_sym="", default_exchange=""): return [ ui.panel( - ui.table(t1).on_row_double_press(handle_row_double_press), + ui.table(t1, on_row_double_press=handle_row_double_press), title="Stock Table Input", ), ui.panel(t2, title="Stock Filtered Table"), @@ -769,6 +769,29 @@ def stock_table_input(source, default_sym="", default_exchange=""): sti = stock_table_input(stocks, "CAT", "TPET") ``` +### ui.table Events + +The `ui.table` component has a few events that you can listen to. You can listen to different kinds of press events that include the data about the region pressed. + +```py +import deephaven.ui as ui +import deephaven.plot.express as dx + +te = ui.table( + dx.data.stocks(), + on_row_press=lambda row, data: print(f"Row Press: {row}, {data}"), + on_row_double_press=lambda row, data: print(f"Row Double Press: {row}, {data}"), + on_cell_press=lambda cell_index, data: print(f"Cell Press: {cell_index}, {data}"), + on_cell_double_press=lambda cell_index, data: print( + f"Cell Double Press: {cell_index}, {data}" + ), + on_column_press=lambda column: print(f"Column Press: {column}"), + on_column_double_press=lambda column: print(f"Column Double Press: {column}"), +) +``` + +![Table events](table_events.png) + ## Re-using components In a previous example, we created a text_filter_table component. We can re-use that component, and display two tables with an input filter side-by-side: diff --git a/plugins/ui/examples/assets/table_events.png b/plugins/ui/examples/assets/table_events.png new file mode 100644 index 000000000..121c830f8 Binary files /dev/null and b/plugins/ui/examples/assets/table_events.png differ diff --git a/plugins/ui/setup.cfg b/plugins/ui/setup.cfg index cc9bb3235..14e5882a4 100644 --- a/plugins/ui/setup.cfg +++ b/plugins/ui/setup.cfg @@ -28,6 +28,7 @@ install_requires = deephaven-core>=0.31.0 deephaven-plugin>=0.6.0 json-rpc + typing_extensions include_package_data = True [options.packages.find] diff --git a/plugins/ui/src/deephaven/ui/__init__.py b/plugins/ui/src/deephaven/ui/__init__.py index fb39b0d78..fad0cf4d9 100644 --- a/plugins/ui/src/deephaven/ui/__init__.py +++ b/plugins/ui/src/deephaven/ui/__init__.py @@ -10,7 +10,7 @@ from .hooks import * from .object_types import * -__version__ = "0.8.0.dev0" +__version__ = "0.9.0.dev0" class UIRegistration(Registration): diff --git a/plugins/ui/src/deephaven/ui/components/table.py b/plugins/ui/src/deephaven/ui/components/table.py index 4f0200c6a..9f4e8226a 100644 --- a/plugins/ui/src/deephaven/ui/components/table.py +++ b/plugins/ui/src/deephaven/ui/components/table.py @@ -1,9 +1,46 @@ +from __future__ import annotations + from deephaven.table import Table from ..elements import UITable +from ..types import ( + CellPressCallback, + ColumnPressCallback, + RowPressCallback, +) -def table(table: Table) -> UITable: +def table( + table: Table, + *, + on_row_press: RowPressCallback | None = None, + on_row_double_press: RowPressCallback | None = None, + on_cell_press: CellPressCallback | None = None, + on_cell_double_press: CellPressCallback | None = None, + on_column_press: ColumnPressCallback | None = None, + on_column_double_press: ColumnPressCallback | None = None, +) -> UITable: """ - Add some extra methods to the Table class for giving hints to displaying a table + Customization to how a table is displayed, how it behaves, and listen to UI events. + + Args: + table: The table to wrap + on_row_press: The callback function to run when a row is clicked. + The first parameter is the row index, and the second is the row data provided in a dictionary where the + column names are the keys. + on_row_double_press: The callback function to run when a row is double clicked. + The first parameter is the row index, and the second is the row data provided in a dictionary where the + column names are the keys. + on_cell_press: The callback function to run when a cell is clicked. + The first parameter is the cell index, and the second is the row data provided in a dictionary where the + column names are the keys. + on_cell_double_press: The callback function to run when a cell is double clicked. + The first parameter is the cell index, and the second is the row data provided in a dictionary where the + column names are the keys. + on_column_press: The callback function to run when a column is clicked. + The first parameter is the column name. + on_column_double_press: The callback function to run when a column is double clicked. + The first parameter is the column name. """ - return UITable(table) + props = locals() + del props["table"] + return UITable(table, **props) diff --git a/plugins/ui/src/deephaven/ui/elements/UITable.py b/plugins/ui/src/deephaven/ui/elements/UITable.py index 45dd51a5c..19084f3a8 100644 --- a/plugins/ui/src/deephaven/ui/elements/UITable.py +++ b/plugins/ui/src/deephaven/ui/elements/UITable.py @@ -1,8 +1,15 @@ from __future__ import annotations -import collections import logging +import sys from typing import Callable, Literal, Sequence, Any, cast +from warnings import warn + +if sys.version_info < (3, 11): + from typing_extensions import TypedDict, NotRequired +else: + from typing import TypedDict, NotRequired + from deephaven.table import Table from deephaven import SortDirection from .Element import Element @@ -14,6 +21,8 @@ Color, ContextMenuAction, CellIndex, + CellPressCallback, + ColumnPressCallback, RowData, ContextMenuMode, DataBarAxis, @@ -48,33 +57,83 @@ def remap_sort_direction(direction: TableSortDirection | str) -> Literal["ASC", raise ValueError(f"Invalid table sort direction: {direction}") -class UITable(Element): +class UITableProps(TypedDict): + can_search: NotRequired[bool] """ - Wrap a Table with some extra props for giving hints to displaying a table + Whether the search bar is accessible or not. Use the system default if no value set. + """ + + on_row_press: NotRequired[RowPressCallback] + """ + Callback function to run when a row is clicked. + The first parameter is the row index, and the second is the row data provided in a dictionary where the + column names are the keys. + """ + + on_row_double_press: NotRequired[RowPressCallback] + """ + The callback function to run when a row is double clicked. + The first parameter is the row index, and the second is the row data provided in a dictionary where the + column names are the keys. """ - _table: Table + on_cell_press: NotRequired[CellPressCallback] """ - The table that is wrapped with some extra props + The callback function to run when a cell is clicked. + The first parameter is the cell index, and the second is the row data provided in a dictionary where the + column names are the keys. """ - _props: dict[str, Any] + on_cell_double_press: NotRequired[CellPressCallback] """ - The extra props that are added by each method + The callback function to run when a cell is double clicked. + The first parameter is the cell index, and the second is the row data provided in a dictionary where the + column names are the keys. """ - def __init__(self, table: Table, props: dict[str, Any] = {}): + on_column_press: NotRequired[ColumnPressCallback] + """ + The callback function to run when a column is clicked. + The first parameter is the column name. + """ + + on_column_double_press: NotRequired[ColumnPressCallback] + """ + The callback function to run when a column is double clicked. + The first parameter is the column name. + """ + + table: Table + """ + The table to wrap + """ + + +class UITable(Element): + """ + Wrap a Table with some extra props for giving hints to displaying a table + """ + + _props: UITableProps + """ + The props that are passed to the frontend + """ + + def __init__( + self, + table: Table, + **props: Any, + ): """ Create a UITable from the passed in table. UITable provides an [immutable fluent interface](https://en.wikipedia.org/wiki/Fluent_interface#Immutability) for adding UI hints to a table. Args: table: The table to wrap + props: UITableProps props to pass to the frontend. """ - self._table = table - # Store the extra props that are added by each method - # This is a shallow copy of the props so that we don't mutate the passed in props dict - self._props = {**props} + # Store all the props that were passed in + self._props = UITableProps(**props, table=table) @property def name(self): @@ -92,7 +151,7 @@ def _with_prop(self, key: str, value: Any) -> "UITable": A new UITable with the passed in prop added to the existing props """ logger.debug("_with_prop(%s, %s)", key, value) - return UITable(self._table, {**self._props, key: value}) + return UITable(**{**self._props, key: value}) def _with_appendable_prop(self, key: str, value: Any) -> "UITable": """ @@ -114,9 +173,9 @@ def _with_appendable_prop(self, key: str, value: Any) -> "UITable": value = value if isinstance(value, list) else [value] - return UITable(self._table, {**self._props, key: existing + value}) + return UITable(**{**self._props, key: existing + value}) - def _with_dict_prop(self, prop_name: str, value: dict) -> "UITable": + def _with_dict_prop(self, key: str, value: dict[str, Any]) -> "UITable": """ Create a new UITable with the passed in prop in a dictionary. This will override any existing prop with the same key within @@ -130,14 +189,13 @@ def _with_dict_prop(self, prop_name: str, value: dict) -> "UITable": Returns: A new UITable with the passed in prop added to the existing props """ - logger.debug("_with_dict_prop(%s, %s)", prop_name, value) - existing = self._props.get(prop_name, {}) - new = {**existing, **value} - return UITable(self._table, {**self._props, prop_name: new}) + logger.debug("_with_dict_prop(%s, %s)", key, value) + existing = self._props.get(key, {}) + return UITable(**{**self._props, key: {**existing, **value}}) # type: ignore def render(self, context: RenderContext) -> dict[str, Any]: logger.debug("Returning props %s", self._props) - return dict_to_camel_case({**self._props, "table": self._table}) + return dict_to_camel_case({**self._props}) def aggregations( self, @@ -278,9 +336,13 @@ def color_row( def context_menu( self, - items: ContextMenuAction - | list[ContextMenuAction] - | Callable[[CellIndex, RowData], ContextMenuAction | list[ContextMenuAction]], + items: ( + ContextMenuAction + | list[ContextMenuAction] + | Callable[ + [CellIndex, RowData], ContextMenuAction | list[ContextMenuAction] + ] + ), mode: ContextMenuMode = "CELL", ) -> "UITable": """ @@ -395,23 +457,10 @@ def hide_columns(self, columns: str | list[str]) -> "UITable": """ raise NotImplementedError() - def on_row_press(self, callback: RowPressCallback) -> "UITable": - """ - Add a callback for when a press on a row is released (e.g. a row is clicked). - - Args: - callback: The callback function to run when a row is clicked. - The first parameter is the row index, and the second is the row data provided in a dictionary where the - column names are the keys. - - Returns: - A new UITable - """ - raise NotImplementedError() - def on_row_double_press(self, callback: RowPressCallback) -> "UITable": """ Add a callback for when a row is double clicked. + *Deprecated: Use the on_row_double_press keyword arg instead. Args: callback: The callback function to run when a row is double clicked. @@ -421,6 +470,11 @@ def on_row_double_press(self, callback: RowPressCallback) -> "UITable": Returns: A new UITable """ + warn( + "on_row_double_press function is deprecated. Use the on_row_double_press keyword arg instead.", + DeprecationWarning, + stacklevel=2, + ) return self._with_prop("on_row_double_press", callback) def quick_filter( @@ -481,7 +535,7 @@ def sort( remap_sort_direction(direction) for direction in direction_list_unmapped ] - by_list = by if isinstance(by, Sequence) else [by] + by_list = [by] if isinstance(by, str) else by if direction and len(direction_list) != len(by_list): raise ValueError("by and direction must be the same length") diff --git a/plugins/ui/src/deephaven/ui/hooks/use_callback.py b/plugins/ui/src/deephaven/ui/hooks/use_callback.py index 7496e1205..a5fedf436 100644 --- a/plugins/ui/src/deephaven/ui/hooks/use_callback.py +++ b/plugins/ui/src/deephaven/ui/hooks/use_callback.py @@ -3,9 +3,10 @@ from typing import Callable, Any, Sequence from .use_ref import use_ref, Ref +from ..types import Dependencies -def use_callback(func: Callable, dependencies: set[Any] | Sequence[Any]) -> Callable: +def use_callback(func: Callable, dependencies: Dependencies) -> Callable: """ Create a stable handle for a callback function. The callback will only be recreated if the dependencies change. diff --git a/plugins/ui/src/deephaven/ui/hooks/use_effect.py b/plugins/ui/src/deephaven/ui/hooks/use_effect.py index 713c3324e..e11e05fa6 100644 --- a/plugins/ui/src/deephaven/ui/hooks/use_effect.py +++ b/plugins/ui/src/deephaven/ui/hooks/use_effect.py @@ -4,9 +4,10 @@ from .use_ref import use_ref, Ref from deephaven.liveness_scope import LivenessScope from .._internal import get_context +from ..types import Dependencies -def use_effect(func: Callable[[], Any], dependencies: set[Any] | Sequence[Any]): +def use_effect(func: Callable[[], Any], dependencies: Dependencies): """ Call a function when the dependencies change. Optionally return a cleanup function to be called when dependencies change again or component is unmounted. diff --git a/plugins/ui/src/deephaven/ui/hooks/use_execution_context.py b/plugins/ui/src/deephaven/ui/hooks/use_execution_context.py index 93f1c9045..2cfc808a1 100644 --- a/plugins/ui/src/deephaven/ui/hooks/use_execution_context.py +++ b/plugins/ui/src/deephaven/ui/hooks/use_execution_context.py @@ -35,6 +35,6 @@ def use_execution_context( Returns: A callable that will take any callable and invoke it within the current exec context """ - exec_ctx = use_memo(lambda: exec_ctx if exec_ctx else get_exec_ctx(), {exec_ctx}) - exec_fn = use_memo(lambda: partial(func_with_ctx, exec_ctx), {exec_ctx}) + exec_ctx = use_memo(lambda: exec_ctx if exec_ctx else get_exec_ctx(), [exec_ctx]) + exec_fn = use_memo(lambda: partial(func_with_ctx, exec_ctx), [exec_ctx]) return exec_fn diff --git a/plugins/ui/src/deephaven/ui/hooks/use_liveness_scope.py b/plugins/ui/src/deephaven/ui/hooks/use_liveness_scope.py index 1cce94bdd..87acd3958 100644 --- a/plugins/ui/src/deephaven/ui/hooks/use_liveness_scope.py +++ b/plugins/ui/src/deephaven/ui/hooks/use_liveness_scope.py @@ -5,9 +5,10 @@ from .use_ref import use_ref, Ref from typing import Callable from deephaven.liveness_scope import LivenessScope +from ..types import Dependencies -def use_liveness_scope(func: Callable, dependencies: set) -> Callable: +def use_liveness_scope(func: Callable, dependencies: Dependencies) -> Callable: """ Wraps a Callable in a liveness scope, and ensures that when invoked, if that callable causes the component to render, the scope will be retained by that render pass. It is diff --git a/plugins/ui/src/deephaven/ui/hooks/use_memo.py b/plugins/ui/src/deephaven/ui/hooks/use_memo.py index 39b384449..406714539 100644 --- a/plugins/ui/src/deephaven/ui/hooks/use_memo.py +++ b/plugins/ui/src/deephaven/ui/hooks/use_memo.py @@ -4,11 +4,12 @@ from .._internal import ValueWithLiveness, get_context from typing import Any, Callable, TypeVar, cast, Union, Sequence from deephaven.liveness_scope import LivenessScope +from ..types import Dependencies T = TypeVar("T") -def use_memo(func: Callable[[], T], dependencies: set[Any] | Sequence[Any]) -> T: +def use_memo(func: Callable[[], T], dependencies: Dependencies) -> T: """ Memoize the result of a function call. The function will only be called again if the dependencies change. @@ -19,6 +20,11 @@ def use_memo(func: Callable[[], T], dependencies: set[Any] | Sequence[Any]) -> T Returns: The memoized result of the function call. """ + if not isinstance(dependencies, (list, tuple)): + raise TypeError( + f"dependencies must be a list or tuple, got {type(dependencies)}" + ) + deps_ref: Ref[set[Any] | Sequence[Any] | None] = use_ref(None) value_ref: Ref[ValueWithLiveness[T | None]] = use_ref( ValueWithLiveness(value=cast(Union[T, None], None), liveness_scope=None) diff --git a/plugins/ui/src/deephaven/ui/hooks/use_table_data.py b/plugins/ui/src/deephaven/ui/hooks/use_table_data.py index 985002e3f..3f2714612 100644 --- a/plugins/ui/src/deephaven/ui/hooks/use_table_data.py +++ b/plugins/ui/src/deephaven/ui/hooks/use_table_data.py @@ -143,7 +143,7 @@ def use_table_data( table_updated = lambda: _set_new_data(table, sentinel, set_data, set_is_sentinel) ui.use_table_listener( - table, partial(_on_update, ctx, table_updated, executor_name), set() + table, partial(_on_update, ctx, table_updated, executor_name), [] ) return transform(data, is_sentinel) diff --git a/plugins/ui/src/deephaven/ui/hooks/use_table_listener.py b/plugins/ui/src/deephaven/ui/hooks/use_table_listener.py index da19b87a4..a7eef4ad5 100644 --- a/plugins/ui/src/deephaven/ui/hooks/use_table_listener.py +++ b/plugins/ui/src/deephaven/ui/hooks/use_table_listener.py @@ -8,7 +8,7 @@ from deephaven.execution_context import get_exec_ctx, ExecutionContext from .use_effect import use_effect -from ..types import LockType +from ..types import LockType, Dependencies def listener_with_ctx( @@ -67,7 +67,7 @@ def wrap_listener( def use_table_listener( table: Table, listener: Callable[[TableUpdate, bool], None] | TableListener, - dependencies: set[Any] | Sequence[Any], + dependencies: Dependencies, description: str | None = None, do_replay: bool = False, replay_lock: LockType = "shared", @@ -109,5 +109,5 @@ def start_listener() -> Callable[[], None]: use_effect( start_listener, - {table, listener, description, do_replay, replay_lock} | set(dependencies), + [table, listener, description, do_replay, replay_lock] + list(dependencies), ) diff --git a/plugins/ui/src/deephaven/ui/types/types.py b/plugins/ui/src/deephaven/ui/types/types.py index bba82c963..7962f207d 100644 --- a/plugins/ui/src/deephaven/ui/types/types.py +++ b/plugins/ui/src/deephaven/ui/types/types.py @@ -1,9 +1,70 @@ -from typing import Any, Dict, Literal, Union, List, Tuple, Optional, Callable, TypedDict +from typing import Any, Dict, Literal, Union, List, Tuple, Callable, TypedDict from deephaven import SortDirection -RowIndex = Optional[int] + +class CellData(TypedDict): + """ + Data for one cell. Returned with click handlers. + """ + + type: str + """ + Type of the cell data + """ + + text: str + """ + Text of the cell data + """ + + value: Any + """ + Raw value of the cell data + """ + + +class RowDataValue(CellData): + """ + Data for value of one column in a row. Returned with row press handlers. + """ + + isExpandable: bool + """ + Whether this row is expandable. + """ + + isGrouped: bool + """ + Whether this row is grouped. + """ + + +ColumnIndex = int +""" +Index of a column in a table. +""" + +RowIndex = int +""" +Index of a row in a table. +""" + +CellIndex = Tuple[ColumnIndex, RowIndex] +""" +Index of a cell in a table. +""" + +GridIndex = Tuple[Union[ColumnIndex, None], Union[RowIndex, None]] +""" +Index of a spot on the grid. A value of None indicates a header row or column. +""" + + +ColumnName = str RowDataMap = Dict[str, Any] RowPressCallback = Callable[[RowIndex, RowDataMap], None] +CellPressCallback = Callable[[CellIndex, CellData], None] +ColumnPressCallback = Callable[[ColumnName], None] AggregationOperation = Literal[ "COUNT", "COUNT_DISTINCT", @@ -20,13 +81,9 @@ "UNIQUE", "SKIP", ] -ColumnIndex = Union[int, None] -CellIndex = Tuple[RowIndex, ColumnIndex] DeephavenColor = Literal["salmon", "lemonchiffon"] HexColor = str Color = Union[DeephavenColor, HexColor] -# A ColumnIndex of None indicates a header row -ColumnName = str ContextMenuAction = Dict[str, Any] ContextMenuModeOption = Literal["CELL", "ROW_HEADER", "COLUMN_HEADER"] ContextMenuMode = Union[ContextMenuModeOption, List[ContextMenuModeOption], None] @@ -37,8 +94,6 @@ LockType = Literal["shared", "exclusive"] QuickFilterExpression = str RowData = Dict[ColumnName, Any] -# A RowIndex of None indicates a header column -RowIndex = Optional[int] ColumnData = List[Any] TableData = Dict[ColumnName, ColumnData] SearchMode = Literal["SHOW", "HIDE", "DEFAULT"] @@ -50,3 +105,4 @@ # Stringable is a type that is naturally convertible to a string Stringable = Union[str, int, float, bool] Key = Stringable +Dependencies = Union[Tuple[Any], List[Any]] diff --git a/plugins/ui/src/js/package.json b/plugins/ui/src/js/package.json index 5b5631edd..086755d38 100644 --- a/plugins/ui/src/js/package.json +++ b/plugins/ui/src/js/package.json @@ -1,6 +1,6 @@ { "name": "@deephaven/js-plugin-ui", - "version": "0.8.0", + "version": "0.9.0", "description": "Deephaven UI plugin", "keywords": [ "Deephaven", @@ -42,20 +42,21 @@ }, "dependencies": { "@adobe/react-spectrum": "^3.34.1", - "@deephaven/chart": "^0.67.0", - "@deephaven/components": "^0.67.0", - "@deephaven/dashboard": "^0.67.0", - "@deephaven/dashboard-core-plugins": "^0.67.0", - "@deephaven/icons": "^0.67.0", - "@deephaven/iris-grid": "^0.67.0", - "@deephaven/jsapi-bootstrap": "^0.67.0", - "@deephaven/jsapi-components": "^0.67.0", + "@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": "^0.67.0", - "@deephaven/log": "^0.67.0", - "@deephaven/plugin": "^0.67.0", - "@deephaven/react-hooks": "^0.67.0", - "@deephaven/redux": "^0.67.0", - "@deephaven/utils": "^0.67.0", + "@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", "@fortawesome/react-fontawesome": "^0.2.0", "@react-types/shared": "^3.22.0", "json-rpc-2.0": "^1.6.0", diff --git a/plugins/ui/src/js/src/elements/UITable.tsx b/plugins/ui/src/js/src/elements/UITable.tsx index c522e7e15..c8fd58fc6 100644 --- a/plugins/ui/src/js/src/elements/UITable.tsx +++ b/plugins/ui/src/js/src/elements/UITable.tsx @@ -12,11 +12,18 @@ import { useApi } from '@deephaven/jsapi-bootstrap'; import type { Table } from '@deephaven/jsapi-types'; import Log from '@deephaven/log'; import { getSettings } from '@deephaven/redux'; +import { EMPTY_ARRAY } from '@deephaven/utils'; import { UITableProps } from './UITableUtils'; +import UITableMouseHandler from './UITableMouseHandler'; const log = Log.module('@deephaven/js-plugin-ui/UITable'); function UITable({ + onCellPress, + onCellDoublePress, + onColumnPress, + onColumnDoublePress, + onRowPress, onRowDoublePress, canSearch, filters, @@ -77,9 +84,35 @@ function UITable({ }; }, [dh, exportedTable]); + const mouseHandlers = useMemo( + () => + model + ? [ + new UITableMouseHandler( + model, + onCellPress, + onCellDoublePress, + onColumnPress, + onColumnDoublePress, + onRowPress, + onRowDoublePress + ), + ] + : EMPTY_ARRAY, + [ + model, + onCellPress, + onCellDoublePress, + onColumnPress, + onColumnDoublePress, + onRowPress, + onRowDoublePress, + ] + ); + const irisGridProps: Partial = useMemo( () => ({ - onDataSelected: onRowDoublePress, + mouseHandlers, alwaysFetchColumns, showSearchBar: canSearch, sorts: hydratedSorts, @@ -87,7 +120,7 @@ function UITable({ settings, }), [ - onRowDoublePress, + mouseHandlers, alwaysFetchColumns, canSearch, hydratedSorts, diff --git a/plugins/ui/src/js/src/elements/UITableMouseHandler.ts b/plugins/ui/src/js/src/elements/UITableMouseHandler.ts new file mode 100644 index 000000000..c8ba66d20 --- /dev/null +++ b/plugins/ui/src/js/src/elements/UITableMouseHandler.ts @@ -0,0 +1,127 @@ +import { + EventHandlerResult, + GridMouseHandler, + GridPoint, + isExpandableGridModel, +} from '@deephaven/grid'; +import { IrisGridModel, RowIndex } from '@deephaven/iris-grid'; +import { + CellData, + ColumnIndex, + RowDataMap, + UITableProps, +} from './UITableUtils'; + +function getCellData( + columnIndex: ColumnIndex, + rowIndex: RowIndex, + model: IrisGridModel +): CellData { + const column = model.columns[columnIndex]; + const { type } = column; + const value = model.valueForCell(columnIndex, rowIndex); + const text = model.textForCell(columnIndex, rowIndex); + return { + value, + text, + type, + }; +} + +/** + * Get the data map for the given row + * @param rowIndex Row to get the data map for + * @returns Data map for the row + */ +function getRowDataMap(rowIndex: RowIndex, model: IrisGridModel): RowDataMap { + const { columns, groupedColumns } = model; + const dataMap: RowDataMap = {}; + for (let i = 0; i < columns.length; i += 1) { + const column = columns[i]; + const { name } = column; + const isExpandable = + isExpandableGridModel(model) && model.isRowExpandable(rowIndex); + const isGrouped = groupedColumns.find(c => c.name === name) != null; + dataMap[name] = { + ...getCellData(i, rowIndex, model), + isGrouped, + isExpandable, + }; + } + return dataMap; +} + +/** + * Mouse handler for UITable. Will call the appropriate callbacks when a cell, row, or column is clicked or double clicked with the data structure expected. + */ +class UITableMouseHandler extends GridMouseHandler { + private model: IrisGridModel; + + private onCellPress: UITableProps['onCellPress']; + + private onCellDoublePress: UITableProps['onCellDoublePress']; + + private onColumnPress: UITableProps['onColumnPress']; + + private onColumnDoublePress: UITableProps['onColumnDoublePress']; + + private onRowPress: UITableProps['onRowPress']; + + private onRowDoublePress: UITableProps['onRowDoublePress']; + + constructor( + model: IrisGridModel, + onCellPress: UITableProps['onCellPress'], + onCellDoublePress: UITableProps['onCellDoublePress'], + onColumnPress: UITableProps['onColumnPress'], + onColumnDoublePress: UITableProps['onColumnDoublePress'], + onRowPress: UITableProps['onRowPress'], + onRowDoublePress: UITableProps['onRowDoublePress'] + ) { + super(890); + this.model = model; + this.onCellPress = onCellPress; + this.onCellDoublePress = onCellDoublePress; + this.onColumnPress = onColumnPress; + this.onColumnDoublePress = onColumnDoublePress; + this.onRowPress = onRowPress; + this.onRowDoublePress = onRowDoublePress; + } + + onClick(gridPoint: GridPoint): EventHandlerResult { + const { column, row } = gridPoint; + const { model, onCellPress, onRowPress, onColumnPress } = this; + if (onCellPress != null && column != null && row != null) { + const cellData = getCellData(column, row, model); + onCellPress([column, row], cellData); + } + if (onRowPress != null && row != null) { + const rowData = getRowDataMap(row, model); + onRowPress(row, rowData); + } + if (onColumnPress && column != null) { + onColumnPress(model.columns[column].name); + } + return false; + } + + onDoubleClick(gridPoint: GridPoint): EventHandlerResult { + const { column, row } = gridPoint; + const { model, onCellDoublePress, onRowDoublePress, onColumnDoublePress } = + this; + if (onCellDoublePress != null && column != null && row != null) { + const cellData = getCellData(column, row, model); + onCellDoublePress([column, row], cellData); + } + if (onRowDoublePress != null && row != null) { + const rowData = getRowDataMap(row, model); + onRowDoublePress(row, rowData); + } + if (onColumnDoublePress && column != null) { + onColumnDoublePress(model.columns[column].name); + } + return false; + } +} + +export default UITableMouseHandler; diff --git a/plugins/ui/src/js/src/elements/UITableUtils.tsx b/plugins/ui/src/js/src/elements/UITableUtils.tsx index 1d80866bb..4573c000c 100644 --- a/plugins/ui/src/js/src/elements/UITableUtils.tsx +++ b/plugins/ui/src/js/src/elements/UITableUtils.tsx @@ -1,14 +1,34 @@ import type { WidgetExportedObject } from '@deephaven/jsapi-types'; -import { DehydratedSort } from '@deephaven/iris-grid'; +import { ColumnName, DehydratedSort, RowIndex } from '@deephaven/iris-grid'; import { ELEMENT_KEY, ElementNode, isElementNode } from './ElementUtils'; import { UITableElementName, UITABLE_ELEMENT_TYPE } from './ElementConstants'; +export type CellData = { + type: string; + text: string; + value: unknown; +}; + +export type RowDataValue = CellData & { + isExpandable: boolean; + isGrouped: boolean; +}; + +export type ColumnIndex = number; + +export type RowDataMap = Record; + export interface UITableProps { table: WidgetExportedObject; - onRowDoublePress?: ( - rowIndex: number, - rowData: Record + onCellPress?: (cellIndex: [ColumnIndex, RowIndex], data: CellData) => void; + onCellDoublePress?: ( + cellIndex: [ColumnIndex, RowIndex], + data: CellData ) => void; + onRowPress?: (rowIndex: RowIndex, rowData: RowDataMap) => void; + onRowDoublePress?: (rowIndex: RowIndex, rowData: RowDataMap) => void; + onColumnPress?: (columnName: ColumnName) => void; + onColumnDoublePress?: (columnName: ColumnName) => void; alwaysFetchColumns?: string[]; canSearch?: boolean; filters?: Record; diff --git a/plugins/ui/test/deephaven/ui/test_hooks.py b/plugins/ui/test/deephaven/ui/test_hooks.py index 1a9fcfb8c..dce874bb1 100644 --- a/plugins/ui/test/deephaven/ui/test_hooks.py +++ b/plugins/ui/test/deephaven/ui/test_hooks.py @@ -108,7 +108,7 @@ def test_memo(self): from deephaven.ui.hooks import use_memo def _test_memo(fn=lambda: "foo", a=1, b=2): - return use_memo(fn, {a, b}) + return use_memo(fn, [a, b]) # Initial render render_result = render_hook(_test_memo) @@ -140,6 +140,12 @@ def _test_memo(fn=lambda: "foo", a=1, b=2): self.assertEqual(result, "biz") self.assertEqual(mock.call_count, 1) + def _test_memo_set(fn=lambda: "foo"): + return use_memo(fn, {}) + + # passing in a non-list/tuple for dependencies should raise a TypeError + self.assertRaises(TypeError, render_hook, _test_memo_set) + def verify_table_updated(self, table_writer, table, update): from deephaven.ui.hooks import use_table_listener from deephaven.table_listener import TableUpdate @@ -541,7 +547,7 @@ def start_thread(): thread.start() thread.join() - use_memo(start_thread, set()) + use_memo(start_thread, []) render_hook(_test_execution_context) @@ -564,7 +570,7 @@ def start_thread(): thread = threading.Thread(target=thread_func) thread.start() - use_memo(start_thread, set()) + use_memo(start_thread, []) render_hook(_test_execution_context) @@ -595,7 +601,7 @@ def _test_reused_tables(): a, set_a = use_state(lambda: table.where("X=1")) # When "a" changes, recompute table - don't return or otherwise track this table w.r.t. liveness - replace_a = use_liveness_scope(lambda: set_a(table.where("X=2")), set()) + replace_a = use_liveness_scope(lambda: set_a(table.where("X=2")), []) return a.size @@ -664,7 +670,7 @@ def helper(): now = dh_now() return table.where("Timestamp > now").last_by(by=["X"]) - local_rows = use_memo(helper, {a}) + local_rows = use_memo(helper, [a]) return local_rows.size diff --git a/plugins/ui/test/deephaven/ui/test_ui_table.py b/plugins/ui/test/deephaven/ui/test_ui_table.py index 7311d3840..d832bf243 100644 --- a/plugins/ui/test/deephaven/ui/test_ui_table.py +++ b/plugins/ui/test/deephaven/ui/test_ui_table.py @@ -34,7 +34,7 @@ def test_on_row_double_press(self): def callback(row): pass - t = ui.table(self.source).on_row_double_press(callback) + t = ui.table(self.source, on_row_double_press=callback) self.expect_render( t, diff --git a/tools/run_docker.sh b/tools/run_docker.sh index fabde4f5e..2fe74ceee 100755 --- a/tools/run_docker.sh +++ b/tools/run_docker.sh @@ -4,7 +4,11 @@ pushd "$(dirname "$0")" # Start the containers -docker compose run --service-ports --rm --build "$@" +if [[ -z "${CI}" ]]; then + docker compose run --service-ports --rm --build "$@" +else + docker compose run --service-ports --rm --build -e CI=true "$@" +fi exit_code=$? docker logs deephaven-plugins > /tmp/server-log.txt 2>&1 docker compose down