diff --git a/.github/workflows/make-docs.yml b/.github/workflows/make-docs.yml index 42a6e9531..2619546a5 100644 --- a/.github/workflows/make-docs.yml +++ b/.github/workflows/make-docs.yml @@ -25,7 +25,7 @@ jobs: path: plugins/${{ inputs.package }}/dist/ - name: Install requirements - run: pip install -r plugins/${{ inputs.package }}/requirements.txt + run: pip install -r plugins/${{ inputs.package }}/sphinx-requirements.txt - name: Install wheel run: pip install plugins/${{ inputs.package }}/dist/*.whl diff --git a/.github/workflows/modified-plugin.yml b/.github/workflows/modified-plugin.yml index 789a8e250..fd6c0cb47 100644 --- a/.github/workflows/modified-plugin.yml +++ b/.github/workflows/modified-plugin.yml @@ -36,6 +36,7 @@ jobs: plotly-express: - plugins/plotly-express/** - .github/workflows/test-*.yml + - sphinx_ext/* plotly: - plugins/plotly/** - .github/workflows/test-*.yml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 77c43c96b..bce1062e5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: rev: v1.1.334 hooks: - id: pyright - files: plugins.*\/src.*\.py + files: (plugins\/.*\/src|sphinx_ext)\/.*\.py additional_dependencies: [ pandas, @@ -23,7 +23,8 @@ repos: plotly, json-rpc, matplotlib, - deephaven-plugin-utilities + deephaven-plugin-utilities, + sphinx, ] - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.2.2 diff --git a/package-lock.json b/package-lock.json index e6277070f..6d7913ada 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,6 @@ "@types/jest": "^29.2.5", "@types/node": "^20.11.17", "@types/prop-types": "^15.7.10", - "@types/shortid": "^0.0.29", "eslint": "^8.37.0", "identity-obj-proxy": "^3.0.0", "jest": "^29.6.2", @@ -11643,11 +11642,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/shortid": { - "version": "0.0.29", - "dev": true, - "license": "MIT" - }, "node_modules/@types/stack-utils": { "version": "2.0.3", "dev": true, @@ -23897,20 +23891,20 @@ "license": "ISC" }, "node_modules/nanoid": { - "version": "3.3.7", - "dev": true, + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", + "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { - "nanoid": "bin/nanoid.cjs" + "nanoid": "bin/nanoid.js" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^18 || >=20" } }, "node_modules/native-promise-only": { @@ -26064,6 +26058,24 @@ "license": "MIT", "peer": true }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/potpack": { "version": "1.0.2", "license": "ISC" @@ -30360,8 +30372,8 @@ "@deephaven/dashboard": "^0.40.0", "@deephaven/jsapi-types": "^0.40.0", "@deephaven/log": "^0.40.0", - "react-json-view": "^1.21.3", - "shortid": "^2.2.16" + "nanoid": "^5.0.7", + "react-json-view": "^1.21.3" }, "devDependencies": { "@types/react": "^17.0.2", @@ -31234,8 +31246,7 @@ "@deephaven/jsapi-bootstrap": "^0.58.0", "@deephaven/jsapi-types": "^0.58.0", "@deephaven/log": "^0.58.0", - "@deephaven/plugin": "^0.58.0", - "shortid": "^2.2.16" + "@deephaven/plugin": "^0.58.0" }, "devDependencies": { "@types/react": "^17.0.2", @@ -31623,11 +31634,11 @@ "@deephaven/plugin": "0.75.0", "@deephaven/utils": "0.75.0", "deep-equal": "^2.2.1", + "nanoid": "^5.0.7", "plotly.js": "^2.29.1", "plotly.js-dist-min": "^2.29.1", "react-plotly.js": "^2.4.0", - "react-redux": "^7.2.9", - "shortid": "^2.2.16" + "react-redux": "^7.2.9" }, "devDependencies": { "@deephaven/jsapi-types": "1.0.0-dev0.34.0", @@ -32123,10 +32134,10 @@ "@deephaven/jsapi-types": "^0.40.0", "@deephaven/log": "^0.40.0", "@deephaven/utils": "^0.40.0", + "nanoid": "^5.0.7", "plotly.js-dist-min": "^2.29.1", "prop-types": "^15.8.1", - "react-plotly.js": "^2.4.0", - "shortid": "^2.2.16" + "react-plotly.js": "^2.4.0" }, "devDependencies": { "@types/react": "^17.0.2", @@ -32187,27 +32198,28 @@ "version": "0.16.0", "license": "Apache-2.0", "dependencies": { - "@deephaven/chart": "^0.84.0", - "@deephaven/components": "^0.84.0", - "@deephaven/dashboard": "^0.84.0", - "@deephaven/dashboard-core-plugins": "^0.84.0", - "@deephaven/grid": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/iris-grid": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", - "@deephaven/jsapi-components": "^0.84.0", + "@deephaven/chart": "^0.85.0", + "@deephaven/components": "^0.85.0", + "@deephaven/dashboard": "^0.85.0", + "@deephaven/dashboard-core-plugins": "^0.85.0", + "@deephaven/golden-layout": "^0.85.0", + "@deephaven/grid": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/iris-grid": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", + "@deephaven/jsapi-components": "^0.85.0", "@deephaven/jsapi-types": "^1.0.0-dev0.35.0", - "@deephaven/log": "^0.84.0", - "@deephaven/plugin": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/redux": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/plugin": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/redux": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/react-fontawesome": "^0.2.0", "@react-types/shared": "^3.22.0", "classnames": "^2.5.1", "json-rpc-2.0": "^1.6.0", - "react-redux": "^7.x", - "shortid": "^2.2.16" + "nanoid": "^5.0.7", + "react-redux": "^7.x" }, "devDependencies": { "@types/react": "^17.0.2", @@ -32223,17 +32235,17 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/chart": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.84.0.tgz", - "integrity": "sha512-UUtwO27zr8m213ZTmmO/Xv9XL28phSIb/OLBSpKtbW4iL+rXdzFf3t42q7kGfukXf4MUG2i+CyG/GKiKe+3vZw==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.85.0.tgz", + "integrity": "sha512-eKL0nofz+09u1arEHt+jrpunnOGy0L1DbWUv8gqUwIZwHIXrQZYTdJXbV++fcEmyuxoD6kdLNLGLJ1Opm4VrKw==", "dependencies": { - "@deephaven/components": "^0.84.0", - "@deephaven/icons": "^0.84.0", + "@deephaven/components": "^0.85.0", + "@deephaven/icons": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/utils": "^0.85.0", "buffer": "^6.0.3", "fast-deep-equal": "^3.1.3", "lodash.debounce": "^4.0.8", @@ -32256,15 +32268,15 @@ "license": "Apache-2.0" }, "plugins/ui/src/js/node_modules/@deephaven/components": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.84.0.tgz", - "integrity": "sha512-3lUz+JGQQMxdG9MmQbReHfWr4h0FiIOJtH17DIQnelYP+VDoiqWFfg4c/uEs7EMRIQAtKi8NI88DrXzoEwhS7w==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.85.0.tgz", + "integrity": "sha512-pvMi4g4aJMYX8z1+bUCu4h5lAyjsZQh/XPcffWe6xLhkPpWbmJOePN8X771iM/LzmNPin+bs3CM18tqQo2ucKg==", "dependencies": { "@adobe/react-spectrum": "3.35.1", - "@deephaven/icons": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", "@react-spectrum/theme-default": "^3.5.1", @@ -32296,16 +32308,16 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/dashboard": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.84.0.tgz", - "integrity": "sha512-AsYI6ppk0OtB3p/S+VVMuWO/RJJ/V3XcLQsBy5oA1GG+2sD6AMjtFG5QbTGQopI995UPEcUWnLODWr3CcPItQg==", - "dependencies": { - "@deephaven/components": "^0.84.0", - "@deephaven/golden-layout": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/redux": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.85.0.tgz", + "integrity": "sha512-xhwqYs30e39ZfyxXpekGRVRjyIf+mVMh510Wa+7i+k+U2mf0+ZRA7tyni9gzIdkm692O7ennvFs78JqM3o0t+w==", + "dependencies": { + "@deephaven/components": "^0.85.0", + "@deephaven/golden-layout": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/redux": "^0.85.0", + "@deephaven/utils": "^0.85.0", "fast-deep-equal": "^3.1.3", "lodash.ismatch": "^4.1.1", "lodash.throttle": "^4.1.1", @@ -32323,30 +32335,30 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.84.0.tgz", - "integrity": "sha512-rhEO3M8f34fA0Dn5vex/lUwkgEqhkaOuAXmYjmKIK5TI220uxia930aaVaDBFw/vhacktNEH6KGNRR1ZWjugxg==", - "dependencies": { - "@deephaven/chart": "^0.84.0", - "@deephaven/components": "^0.84.0", - "@deephaven/console": "^0.84.0", - "@deephaven/dashboard": "^0.84.0", - "@deephaven/file-explorer": "^0.84.0", - "@deephaven/filters": "^0.84.0", - "@deephaven/golden-layout": "^0.84.0", - "@deephaven/grid": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/iris-grid": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", - "@deephaven/jsapi-components": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.85.0.tgz", + "integrity": "sha512-UrWpDsYmYcS5N2r7C3Ycy6knFuEkvhmN++yUmLNfFbYeFUWeyacfLfg5IKd7b5/9Yx2mmzVIZBdCH5O//inE0g==", + "dependencies": { + "@deephaven/chart": "^0.85.0", + "@deephaven/components": "^0.85.0", + "@deephaven/console": "^0.85.0", + "@deephaven/dashboard": "^0.85.0", + "@deephaven/file-explorer": "^0.85.0", + "@deephaven/filters": "^0.85.0", + "@deephaven/golden-layout": "^0.85.0", + "@deephaven/grid": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/iris-grid": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", + "@deephaven/jsapi-components": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/plugin": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/redux": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/plugin": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/redux": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "fast-deep-equal": "^3.1.3", @@ -32374,19 +32386,19 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/console": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.84.0.tgz", - "integrity": "sha512-S5QAkns4vt5e1r2T3VQ/c8YhOnXNi+blTk/n4rHE1VAhH6qphRp1pehF9TQzRG859cSXT3JH2CBoe9efi7WVbw==", - "dependencies": { - "@deephaven/chart": "^0.84.0", - "@deephaven/components": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.85.0.tgz", + "integrity": "sha512-V603KnHLKdWNyy7ibzZ18hoUJCkLSU5rYMsRSsNYx/+GOrw3ozbvCYm3rYc+BheLPicybCb89OWJt9pIBkXnbA==", + "dependencies": { + "@deephaven/chart": "^0.85.0", + "@deephaven/components": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "linkifyjs": "^4.1.0", @@ -32410,15 +32422,15 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/file-explorer": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.84.0.tgz", - "integrity": "sha512-AJ1kJZXhkRz+b2H26eolfr9eYkDxbWL1AsNjwu42Quv54/cncOu2WaDXkbOhVwlpLfae20f1P3X0JnTVFFP20w==", - "dependencies": { - "@deephaven/components": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.85.0.tgz", + "integrity": "sha512-cRXClp9GwHwpdOSFH+JXCPMuHuiNOZhkFmmGa+pzrFyp3/fTYrRkw3//1s2KBCdHLUzJi5gbQLmxTHhNlGfQ6Q==", + "dependencies": { + "@deephaven/components": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", @@ -32432,32 +32444,18 @@ "react": ">=16.8.0" } }, - "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/golden-layout": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.84.0.tgz", - "integrity": "sha512-Pmy157rhKbf7U5YV6rBg7/r1ZHTHATw2UMQ501JEKAbOThrHIWrzktKk2Kfd4kpDs1CYPZsNJEuYwkzd+Xy2wA==", - "dependencies": { - "@deephaven/components": "^0.84.0", - "jquery": "^3.6.0", - "nanoid": "^5.0.7" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/jsapi-types": { "version": "1.0.0-dev0.34.0", "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.34.0.tgz", "integrity": "sha512-UiIbmCaMx5mPOGCWdgOCfZtccMhh55jv3qzeN3qBp3YUi46uGfWY5kfCU3hWRtaQvUgO7n0XhBKTd4K/pxv9ng==" }, "plugins/ui/src/js/node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/storage": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.84.0.tgz", - "integrity": "sha512-P/KJT2U04WypIxvx1Ws7l/02jUwIPdkonfUH9ezUK5YXzakwmMiXBvV2/jTBGrRpw/BfDZOkj25FlpDA4yib/A==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.85.0.tgz", + "integrity": "sha512-n+ytjBqFAbK4q/K6BfGjssqHVy6yN7iXU1aGtRkgoK90g6mdLr+2UjHE2eG2xa/qprITXDgutpKb2aKvlkixhw==", "dependencies": { - "@deephaven/filters": "^0.84.0", - "@deephaven/log": "^0.84.0", + "@deephaven/filters": "^0.85.0", + "@deephaven/log": "^0.85.0", "lodash.throttle": "^4.1.1" }, "engines": { @@ -32467,12 +32465,20 @@ "react": ">=16.8.0" } }, - "plugins/ui/src/js/node_modules/@deephaven/dashboard/node_modules/@deephaven/golden-layout": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.84.0.tgz", - "integrity": "sha512-Pmy157rhKbf7U5YV6rBg7/r1ZHTHATw2UMQ501JEKAbOThrHIWrzktKk2Kfd4kpDs1CYPZsNJEuYwkzd+Xy2wA==", + "plugins/ui/src/js/node_modules/@deephaven/filters": { + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.85.0.tgz", + "integrity": "sha512-vwoNVJn/0U3xCESAgIJ8gXtOoym5LZ2XmMOkW37hNgCPp4lTk/SGE7StmaXzMQMZPGH6sLZWFGQ6ssIG2rbPng==", + "engines": { + "node": ">=16" + } + }, + "plugins/ui/src/js/node_modules/@deephaven/golden-layout": { + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.85.0.tgz", + "integrity": "sha512-LM66CUKoHaAmZQinvQRFtvL2ZyYolqIb1WvTxf/qQeZDFCESVq3+Ns7aKk1AJxeSZqu3fD7t3YVD+f4uVzSdyQ==", "dependencies": { - "@deephaven/components": "^0.84.0", + "@deephaven/components": "^0.85.0", "jquery": "^3.6.0", "nanoid": "^5.0.7" }, @@ -32481,20 +32487,12 @@ "react-dom": ">=16.8.0" } }, - "plugins/ui/src/js/node_modules/@deephaven/filters": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.84.0.tgz", - "integrity": "sha512-hu6DiGoFrMrJKP2sNFmBjHkMx6CKLDNTNlnt6WAdCbfw+tUZmc60seD0/l0Z5P/Z70TJUxqWyjUcWnE2KToMog==", - "engines": { - "node": ">=16" - } - }, "plugins/ui/src/js/node_modules/@deephaven/grid": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.84.0.tgz", - "integrity": "sha512-IHCkad8zEO/M11ykLFhunDI40bKwJGadXf+NcsyTHdSkvATYlMe/EHaKZKXhzQtnoQmEv4kwkFSomiZ+oU4N0g==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.85.0.tgz", + "integrity": "sha512-F/jh85vZonp2wgYm4SpsiYRIdcVC+QlOsgq/Dwb+Fbm0ogcLy5ATZb/MKBKcbfBQ1TeaEgDZJkUmQQ64YnXQPQ==", "dependencies": { - "@deephaven/utils": "^0.84.0", + "@deephaven/utils": "^0.85.0", "classnames": "^2.3.1", "color-convert": "^2.0.1", "event-target-shim": "^6.0.2", @@ -32512,9 +32510,9 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/icons": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.84.0.tgz", - "integrity": "sha512-aynGI8lBV0xLt4ivWAYIzULtyfJQwmgA/4npZruorSrS+x9ELrwAsZtPGqXAmZ0kDTLHenTKIBVOj1nSo9NvAg==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.85.0.tgz", + "integrity": "sha512-8G77T/RPLs+SRdxWJJmOAFV0cS14U63L7hwJ8aqhMQmQkNqTqeDKrPXugXpOGN4iw3rkN05UPgV6ypS9XtbEgA==", "dependencies": { "@fortawesome/fontawesome-common-types": "^6.1.1" }, @@ -32524,22 +32522,22 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/iris-grid": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.84.0.tgz", - "integrity": "sha512-ilM9FxcsKeRIANgw5p5yN2cu5OtxRYHRLJ8dyF21ND9xjQ0e58hByqBnIclVuhakuaTl6qacxkCebjZgooxOIg==", - "dependencies": { - "@deephaven/components": "^0.84.0", - "@deephaven/console": "^0.84.0", - "@deephaven/filters": "^0.84.0", - "@deephaven/grid": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/jsapi-components": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.85.0.tgz", + "integrity": "sha512-jpuw7shjpMHTbWKuykm1wBqKpJ2SBvVmtTcSUlFEUJwkJZe3Ax+nqJdm3cthCcI8RQiKwavVTDppMSu7IoETgA==", + "dependencies": { + "@deephaven/components": "^0.85.0", + "@deephaven/console": "^0.85.0", + "@deephaven/filters": "^0.85.0", + "@deephaven/grid": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/jsapi-components": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@dnd-kit/core": "^6.1.0", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.2", @@ -32566,19 +32564,19 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/iris-grid/node_modules/@deephaven/console": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.84.0.tgz", - "integrity": "sha512-S5QAkns4vt5e1r2T3VQ/c8YhOnXNi+blTk/n4rHE1VAhH6qphRp1pehF9TQzRG859cSXT3JH2CBoe9efi7WVbw==", - "dependencies": { - "@deephaven/chart": "^0.84.0", - "@deephaven/components": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.85.0.tgz", + "integrity": "sha512-V603KnHLKdWNyy7ibzZ18hoUJCkLSU5rYMsRSsNYx/+GOrw3ozbvCYm3rYc+BheLPicybCb89OWJt9pIBkXnbA==", + "dependencies": { + "@deephaven/chart": "^0.85.0", + "@deephaven/components": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "linkifyjs": "^4.1.0", @@ -32607,12 +32605,12 @@ "integrity": "sha512-UiIbmCaMx5mPOGCWdgOCfZtccMhh55jv3qzeN3qBp3YUi46uGfWY5kfCU3hWRtaQvUgO7n0XhBKTd4K/pxv9ng==" }, "plugins/ui/src/js/node_modules/@deephaven/iris-grid/node_modules/@deephaven/storage": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.84.0.tgz", - "integrity": "sha512-P/KJT2U04WypIxvx1Ws7l/02jUwIPdkonfUH9ezUK5YXzakwmMiXBvV2/jTBGrRpw/BfDZOkj25FlpDA4yib/A==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.85.0.tgz", + "integrity": "sha512-n+ytjBqFAbK4q/K6BfGjssqHVy6yN7iXU1aGtRkgoK90g6mdLr+2UjHE2eG2xa/qprITXDgutpKb2aKvlkixhw==", "dependencies": { - "@deephaven/filters": "^0.84.0", - "@deephaven/log": "^0.84.0", + "@deephaven/filters": "^0.85.0", + "@deephaven/log": "^0.85.0", "lodash.throttle": "^4.1.1" }, "engines": { @@ -32623,15 +32621,15 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/jsapi-bootstrap": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.84.0.tgz", - "integrity": "sha512-Aew3Lo+T9DRV1MLL89jeWORiMZ940gBQNz3kWbW7z/stcTQR89Wxynjt7tiaNRnBxBb0TgYrhphjlz01LAKjUw==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.85.0.tgz", + "integrity": "sha512-ATDdYQ15fHq1Nlg5OyRxWZF/WHgEgdeZAnwfD5uMFo4UoPpLcaNbe5IV8E97RAWA1eVD2jvVWz9yxHzFd9qY8g==", "dependencies": { - "@deephaven/components": "^0.84.0", + "@deephaven/components": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/utils": "^0.84.0" + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/utils": "^0.85.0" }, "engines": { "node": ">=16" @@ -32646,17 +32644,17 @@ "integrity": "sha512-UiIbmCaMx5mPOGCWdgOCfZtccMhh55jv3qzeN3qBp3YUi46uGfWY5kfCU3hWRtaQvUgO7n0XhBKTd4K/pxv9ng==" }, "plugins/ui/src/js/node_modules/@deephaven/jsapi-components": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.84.0.tgz", - "integrity": "sha512-suo2BSyBxNoR7KxS2DCX+FxCBdvaq3eFrrSjqLG3HmxOg3ps3qLdqoiLEpn6cVw0cZTqS0K2jGbkE9oyoDj+tA==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.85.0.tgz", + "integrity": "sha512-zFePfFtfnI7vFsDXqlpyM+Nl/wl/YnVf4Gk6OsgDSrpyI2RpnKwM1t8bD/jHCGb6QjfjYDVaxW4d8X9Uoq4M/Q==", "dependencies": { - "@deephaven/components": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", + "@deephaven/components": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@types/js-cookie": "^3.0.3", "classnames": "^2.3.2", "js-cookie": "^3.0.5", @@ -32681,14 +32679,14 @@ "integrity": "sha512-X35g2ktmXbiTwjMNF20IkuNawJJ6Tlvrv23VuUVIjWHkpWcmyCYWIBle2zo7QAF6nnJpkccwFKJiC+TIkWl7hg==" }, "plugins/ui/src/js/node_modules/@deephaven/jsapi-utils": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.84.0.tgz", - "integrity": "sha512-CwYs9NHPs3wb+D0PM4VTBrqXzaHNHmuHTkep8XitZHAr814jOGcQhnkTauSpo+ulPwnheweO8C8wMjjBH/VojQ==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.85.0.tgz", + "integrity": "sha512-oWb0kC04McWCfPtVRpacCgNSM/g9xSWmvXSo7icDEoJVTogICElB3qxcnr6hJJmrghsGi2us0HKK/Ds7eUJYfQ==", "dependencies": { - "@deephaven/filters": "^0.84.0", + "@deephaven/filters": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/utils": "^0.85.0", "lodash.clamp": "^4.0.3", "nanoid": "^5.0.7" }, @@ -32702,9 +32700,9 @@ "integrity": "sha512-UiIbmCaMx5mPOGCWdgOCfZtccMhh55jv3qzeN3qBp3YUi46uGfWY5kfCU3hWRtaQvUgO7n0XhBKTd4K/pxv9ng==" }, "plugins/ui/src/js/node_modules/@deephaven/log": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.84.0.tgz", - "integrity": "sha512-B3KS2n/dT8GPblR8Top9GPB53pMmUglAMUVg93V3X10EPemE1jwiYEoJuceZ20JpRncCfRVuazrNYP7GItjWPQ==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.85.0.tgz", + "integrity": "sha512-RGPolUsmIBdfp1ym2SXlFnXhc7lDvKhaJ5t2MoEx/mL4MAsD1MWmO9A3x0F0zONS5XJGUDpLOgWbZVY0ld7JXg==", "dependencies": { "event-target-shim": "^6.0.2" }, @@ -32713,17 +32711,17 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/plugin": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.84.0.tgz", - "integrity": "sha512-G3f3WGc159TVUZOekZPmUAChshdDqE7OzuigGXeFlv/CCmlQhX5t1BWwqfYRFXkHwV5zk9UUyuQEhrNAUS+Zmg==", - "dependencies": { - "@deephaven/components": "^0.84.0", - "@deephaven/golden-layout": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/iris-grid": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.85.0.tgz", + "integrity": "sha512-q1cEe7SnF3PvyE9nCEpyu/cPu9NwwitU5tGqMUe/II7wG1QgBHhz1OA4a4VZzgMEJbf4w8StfkRntRy1ushRUA==", + "dependencies": { + "@deephaven/components": "^0.85.0", + "@deephaven/golden-layout": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/iris-grid": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", "@fortawesome/fontawesome-common-types": "^6.1.1", "@fortawesome/react-fontawesome": "^0.2.0" }, @@ -32734,33 +32732,19 @@ "react": ">=16.8.0" } }, - "plugins/ui/src/js/node_modules/@deephaven/plugin/node_modules/@deephaven/golden-layout": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.84.0.tgz", - "integrity": "sha512-Pmy157rhKbf7U5YV6rBg7/r1ZHTHATw2UMQ501JEKAbOThrHIWrzktKk2Kfd4kpDs1CYPZsNJEuYwkzd+Xy2wA==", - "dependencies": { - "@deephaven/components": "^0.84.0", - "jquery": "^3.6.0", - "nanoid": "^5.0.7" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, "plugins/ui/src/js/node_modules/@deephaven/plugin/node_modules/@deephaven/jsapi-types": { "version": "1.0.0-dev0.34.0", "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.34.0.tgz", "integrity": "sha512-UiIbmCaMx5mPOGCWdgOCfZtccMhh55jv3qzeN3qBp3YUi46uGfWY5kfCU3hWRtaQvUgO7n0XhBKTd4K/pxv9ng==" }, "plugins/ui/src/js/node_modules/@deephaven/react-hooks": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.84.0.tgz", - "integrity": "sha512-VIcBAkfdyKI5JbITW5kouDfyfEm1ggUhbAYNWRUFlRSPNkoWxFfflc4eplQAfmj/VDjaVAizWNjc1JbH8OG/tg==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.85.0.tgz", + "integrity": "sha512-HMOH9ZEiJiWpveFovuU+63D2uhmjJKUolETtzalf3a6Emtnl4DkPMGllgnr/S6z94oFfC3yP2bwS2CqQQv6qVQ==", "dependencies": { "@adobe/react-spectrum": "3.35.1", - "@deephaven/log": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/utils": "^0.85.0", "lodash.debounce": "^4.0.8", "lodash.throttle": "^4.1.1", "nanoid": "^5.0.7" @@ -32773,14 +32757,14 @@ } }, "plugins/ui/src/js/node_modules/@deephaven/redux": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.84.0.tgz", - "integrity": "sha512-mj05IMOPtKhol5eLdiHORdyvnUv/bH7/sSV18q8hYJ3eHtpKyvuou3256s4NSpvgUCjyxTvQbknR9qemk1fVAw==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.85.0.tgz", + "integrity": "sha512-z36GulgLNXRTV4NgSU8wR/4TiCOJAqV5avr3EC4IkSNc7E41bQ2gYqIkuaJpT/AWKUofsFpu0nmLKhqtpes76A==", "dependencies": { "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/plugin": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/plugin": "^0.85.0", "fast-deep-equal": "^3.1.3", "proxy-memoize": "^3.0.0", "redux-thunk": "2.4.1" @@ -32798,9 +32782,9 @@ "integrity": "sha512-UiIbmCaMx5mPOGCWdgOCfZtccMhh55jv3qzeN3qBp3YUi46uGfWY5kfCU3hWRtaQvUgO7n0XhBKTd4K/pxv9ng==" }, "plugins/ui/src/js/node_modules/@deephaven/utils": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.84.0.tgz", - "integrity": "sha512-eWTlmxtdYFuV7q127AwMyLnf5j0FGpPG6gJ+2ChpFeMS+ZfOHpgcRHZC2+j3y/b5z4mGm2bIjzQDJpMNPL4thg==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.85.0.tgz", + "integrity": "sha512-tlz7rzZ9O9Y1OiMZSt4vKNGFvCH3P6GWU8ZkLLIj83dsXbAO442jCxBvPfMpC4NbSa2294fel+Mnl23ZOY4big==", "engines": { "node": ">=16" } @@ -32853,22 +32837,6 @@ "url": "https://github.com/sponsors/mysticatea" } }, - "plugins/ui/src/js/node_modules/nanoid": { - "version": "5.0.7", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.js" - }, - "engines": { - "node": "^18 || >=20" - } - }, "plugins/ui/src/js/node_modules/redux-thunk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", @@ -35138,10 +35106,10 @@ "@deephaven/log": "^0.40.0", "@types/react": "^17.0.2", "@vitejs/plugin-react-swc": "^3.0.0", + "nanoid": "^5.0.7", "react": "^17.0.2", "react-json-view": "^1.21.3", "sass": "^1.60.0", - "shortid": "^2.2.16", "typescript": "^4.5.4", "vite": "~4.1.4" }, @@ -35626,7 +35594,6 @@ "@types/react-dom": "^17.0.2", "@vitejs/plugin-react-swc": "^3.0.0", "react": "^17.0.2", - "shortid": "^2.2.16", "typescript": "^4.5.4", "vite": "~4.1.4" }, @@ -35878,11 +35845,11 @@ "@deephaven/utils": "^0.40.0", "@types/react": "^17.0.2", "@vitejs/plugin-react-swc": "^3.0.0", + "nanoid": "^5.0.7", "plotly.js-dist-min": "^2.29.1", "prop-types": "^15.8.1", "react": "^17.0.2", "react-plotly.js": "^2.4.0", - "shortid": "^2.2.16", "typescript": "^4.5.4", "vite": "~4.1.4" }, @@ -35913,13 +35880,13 @@ "@types/react-plotly.js": "^2.6.0", "@vitejs/plugin-react-swc": "^3.0.0", "deep-equal": "^2.2.1", + "nanoid": "^5.0.7", "plotly.js": "^2.29.1", "plotly.js-dist-min": "^2.29.1", "react": "^17.0.2", "react-dom": "^17.0.2", "react-plotly.js": "^2.4.0", "react-redux": "^7.2.9", - "shortid": "^2.2.16", "typescript": "^4.5.4", "vite": "~4.1.4" }, @@ -36293,47 +36260,48 @@ "@deephaven/js-plugin-ui": { "version": "file:plugins/ui/src/js", "requires": { - "@deephaven/chart": "^0.84.0", - "@deephaven/components": "^0.84.0", - "@deephaven/dashboard": "^0.84.0", - "@deephaven/dashboard-core-plugins": "^0.84.0", - "@deephaven/grid": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/iris-grid": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", - "@deephaven/jsapi-components": "^0.84.0", + "@deephaven/chart": "^0.85.0", + "@deephaven/components": "^0.85.0", + "@deephaven/dashboard": "^0.85.0", + "@deephaven/dashboard-core-plugins": "^0.85.0", + "@deephaven/golden-layout": "^0.85.0", + "@deephaven/grid": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/iris-grid": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", + "@deephaven/jsapi-components": "^0.85.0", "@deephaven/jsapi-types": "^1.0.0-dev0.35.0", - "@deephaven/log": "^0.84.0", - "@deephaven/plugin": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/redux": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/plugin": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/redux": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/react-fontawesome": "^0.2.0", "@react-types/shared": "^3.22.0", "@types/react": "^17.0.2", "@vitejs/plugin-react-swc": "^3.0.0", "classnames": "^2.5.1", "json-rpc-2.0": "^1.6.0", + "nanoid": "^5.0.7", "react": "^17.0.2", "react-dom": "^17.0.2", "react-redux": "^7.x", - "shortid": "^2.2.16", "typescript": "^4.5.4", "vite": "~4.1.4" }, "dependencies": { "@deephaven/chart": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.84.0.tgz", - "integrity": "sha512-UUtwO27zr8m213ZTmmO/Xv9XL28phSIb/OLBSpKtbW4iL+rXdzFf3t42q7kGfukXf4MUG2i+CyG/GKiKe+3vZw==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.85.0.tgz", + "integrity": "sha512-eKL0nofz+09u1arEHt+jrpunnOGy0L1DbWUv8gqUwIZwHIXrQZYTdJXbV++fcEmyuxoD6kdLNLGLJ1Opm4VrKw==", "requires": { - "@deephaven/components": "^0.84.0", - "@deephaven/icons": "^0.84.0", + "@deephaven/components": "^0.85.0", + "@deephaven/icons": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/utils": "^0.85.0", "buffer": "^6.0.3", "fast-deep-equal": "^3.1.3", "lodash.debounce": "^4.0.8", @@ -36351,15 +36319,15 @@ } }, "@deephaven/components": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.84.0.tgz", - "integrity": "sha512-3lUz+JGQQMxdG9MmQbReHfWr4h0FiIOJtH17DIQnelYP+VDoiqWFfg4c/uEs7EMRIQAtKi8NI88DrXzoEwhS7w==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.85.0.tgz", + "integrity": "sha512-pvMi4g4aJMYX8z1+bUCu4h5lAyjsZQh/XPcffWe6xLhkPpWbmJOePN8X771iM/LzmNPin+bs3CM18tqQo2ucKg==", "requires": { "@adobe/react-spectrum": "3.35.1", - "@deephaven/icons": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", "@react-spectrum/theme-default": "^3.5.1", @@ -36384,60 +36352,48 @@ } }, "@deephaven/dashboard": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.84.0.tgz", - "integrity": "sha512-AsYI6ppk0OtB3p/S+VVMuWO/RJJ/V3XcLQsBy5oA1GG+2sD6AMjtFG5QbTGQopI995UPEcUWnLODWr3CcPItQg==", - "requires": { - "@deephaven/components": "^0.84.0", - "@deephaven/golden-layout": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/redux": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.85.0.tgz", + "integrity": "sha512-xhwqYs30e39ZfyxXpekGRVRjyIf+mVMh510Wa+7i+k+U2mf0+ZRA7tyni9gzIdkm692O7ennvFs78JqM3o0t+w==", + "requires": { + "@deephaven/components": "^0.85.0", + "@deephaven/golden-layout": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/redux": "^0.85.0", + "@deephaven/utils": "^0.85.0", "fast-deep-equal": "^3.1.3", "lodash.ismatch": "^4.1.1", "lodash.throttle": "^4.1.1", "nanoid": "^5.0.7", "prop-types": "^15.7.2" - }, - "dependencies": { - "@deephaven/golden-layout": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.84.0.tgz", - "integrity": "sha512-Pmy157rhKbf7U5YV6rBg7/r1ZHTHATw2UMQ501JEKAbOThrHIWrzktKk2Kfd4kpDs1CYPZsNJEuYwkzd+Xy2wA==", - "requires": { - "@deephaven/components": "^0.84.0", - "jquery": "^3.6.0", - "nanoid": "^5.0.7" - } - } } }, "@deephaven/dashboard-core-plugins": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.84.0.tgz", - "integrity": "sha512-rhEO3M8f34fA0Dn5vex/lUwkgEqhkaOuAXmYjmKIK5TI220uxia930aaVaDBFw/vhacktNEH6KGNRR1ZWjugxg==", - "requires": { - "@deephaven/chart": "^0.84.0", - "@deephaven/components": "^0.84.0", - "@deephaven/console": "^0.84.0", - "@deephaven/dashboard": "^0.84.0", - "@deephaven/file-explorer": "^0.84.0", - "@deephaven/filters": "^0.84.0", - "@deephaven/golden-layout": "^0.84.0", - "@deephaven/grid": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/iris-grid": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", - "@deephaven/jsapi-components": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.85.0.tgz", + "integrity": "sha512-UrWpDsYmYcS5N2r7C3Ycy6knFuEkvhmN++yUmLNfFbYeFUWeyacfLfg5IKd7b5/9Yx2mmzVIZBdCH5O//inE0g==", + "requires": { + "@deephaven/chart": "^0.85.0", + "@deephaven/components": "^0.85.0", + "@deephaven/console": "^0.85.0", + "@deephaven/dashboard": "^0.85.0", + "@deephaven/file-explorer": "^0.85.0", + "@deephaven/filters": "^0.85.0", + "@deephaven/golden-layout": "^0.85.0", + "@deephaven/grid": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/iris-grid": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", + "@deephaven/jsapi-components": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/plugin": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/redux": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/plugin": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/redux": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "fast-deep-equal": "^3.1.3", @@ -36457,19 +36413,19 @@ }, "dependencies": { "@deephaven/console": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.84.0.tgz", - "integrity": "sha512-S5QAkns4vt5e1r2T3VQ/c8YhOnXNi+blTk/n4rHE1VAhH6qphRp1pehF9TQzRG859cSXT3JH2CBoe9efi7WVbw==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.85.0.tgz", + "integrity": "sha512-V603KnHLKdWNyy7ibzZ18hoUJCkLSU5rYMsRSsNYx/+GOrw3ozbvCYm3rYc+BheLPicybCb89OWJt9pIBkXnbA==", "requires": { - "@deephaven/chart": "^0.84.0", - "@deephaven/components": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", + "@deephaven/chart": "^0.85.0", + "@deephaven/components": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "linkifyjs": "^4.1.0", @@ -36486,15 +36442,15 @@ } }, "@deephaven/file-explorer": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.84.0.tgz", - "integrity": "sha512-AJ1kJZXhkRz+b2H26eolfr9eYkDxbWL1AsNjwu42Quv54/cncOu2WaDXkbOhVwlpLfae20f1P3X0JnTVFFP20w==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.85.0.tgz", + "integrity": "sha512-cRXClp9GwHwpdOSFH+JXCPMuHuiNOZhkFmmGa+pzrFyp3/fTYrRkw3//1s2KBCdHLUzJi5gbQLmxTHhNlGfQ6Q==", "requires": { - "@deephaven/components": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/components": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", @@ -36502,44 +36458,44 @@ "prop-types": "^15.7.2" } }, - "@deephaven/golden-layout": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.84.0.tgz", - "integrity": "sha512-Pmy157rhKbf7U5YV6rBg7/r1ZHTHATw2UMQ501JEKAbOThrHIWrzktKk2Kfd4kpDs1CYPZsNJEuYwkzd+Xy2wA==", - "requires": { - "@deephaven/components": "^0.84.0", - "jquery": "^3.6.0", - "nanoid": "^5.0.7" - } - }, "@deephaven/jsapi-types": { "version": "1.0.0-dev0.34.0", "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.34.0.tgz", "integrity": "sha512-UiIbmCaMx5mPOGCWdgOCfZtccMhh55jv3qzeN3qBp3YUi46uGfWY5kfCU3hWRtaQvUgO7n0XhBKTd4K/pxv9ng==" }, "@deephaven/storage": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.84.0.tgz", - "integrity": "sha512-P/KJT2U04WypIxvx1Ws7l/02jUwIPdkonfUH9ezUK5YXzakwmMiXBvV2/jTBGrRpw/BfDZOkj25FlpDA4yib/A==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.85.0.tgz", + "integrity": "sha512-n+ytjBqFAbK4q/K6BfGjssqHVy6yN7iXU1aGtRkgoK90g6mdLr+2UjHE2eG2xa/qprITXDgutpKb2aKvlkixhw==", "requires": { - "@deephaven/filters": "^0.84.0", - "@deephaven/log": "^0.84.0", + "@deephaven/filters": "^0.85.0", + "@deephaven/log": "^0.85.0", "lodash.throttle": "^4.1.1" } } } }, "@deephaven/filters": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.84.0.tgz", - "integrity": "sha512-hu6DiGoFrMrJKP2sNFmBjHkMx6CKLDNTNlnt6WAdCbfw+tUZmc60seD0/l0Z5P/Z70TJUxqWyjUcWnE2KToMog==" + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.85.0.tgz", + "integrity": "sha512-vwoNVJn/0U3xCESAgIJ8gXtOoym5LZ2XmMOkW37hNgCPp4lTk/SGE7StmaXzMQMZPGH6sLZWFGQ6ssIG2rbPng==" + }, + "@deephaven/golden-layout": { + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.85.0.tgz", + "integrity": "sha512-LM66CUKoHaAmZQinvQRFtvL2ZyYolqIb1WvTxf/qQeZDFCESVq3+Ns7aKk1AJxeSZqu3fD7t3YVD+f4uVzSdyQ==", + "requires": { + "@deephaven/components": "^0.85.0", + "jquery": "^3.6.0", + "nanoid": "^5.0.7" + } }, "@deephaven/grid": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.84.0.tgz", - "integrity": "sha512-IHCkad8zEO/M11ykLFhunDI40bKwJGadXf+NcsyTHdSkvATYlMe/EHaKZKXhzQtnoQmEv4kwkFSomiZ+oU4N0g==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.85.0.tgz", + "integrity": "sha512-F/jh85vZonp2wgYm4SpsiYRIdcVC+QlOsgq/Dwb+Fbm0ogcLy5ATZb/MKBKcbfBQ1TeaEgDZJkUmQQ64YnXQPQ==", "requires": { - "@deephaven/utils": "^0.84.0", + "@deephaven/utils": "^0.85.0", "classnames": "^2.3.1", "color-convert": "^2.0.1", "event-target-shim": "^6.0.2", @@ -36551,30 +36507,30 @@ } }, "@deephaven/icons": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.84.0.tgz", - "integrity": "sha512-aynGI8lBV0xLt4ivWAYIzULtyfJQwmgA/4npZruorSrS+x9ELrwAsZtPGqXAmZ0kDTLHenTKIBVOj1nSo9NvAg==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.85.0.tgz", + "integrity": "sha512-8G77T/RPLs+SRdxWJJmOAFV0cS14U63L7hwJ8aqhMQmQkNqTqeDKrPXugXpOGN4iw3rkN05UPgV6ypS9XtbEgA==", "requires": { "@fortawesome/fontawesome-common-types": "^6.1.1" } }, "@deephaven/iris-grid": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.84.0.tgz", - "integrity": "sha512-ilM9FxcsKeRIANgw5p5yN2cu5OtxRYHRLJ8dyF21ND9xjQ0e58hByqBnIclVuhakuaTl6qacxkCebjZgooxOIg==", - "requires": { - "@deephaven/components": "^0.84.0", - "@deephaven/console": "^0.84.0", - "@deephaven/filters": "^0.84.0", - "@deephaven/grid": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/jsapi-components": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.85.0.tgz", + "integrity": "sha512-jpuw7shjpMHTbWKuykm1wBqKpJ2SBvVmtTcSUlFEUJwkJZe3Ax+nqJdm3cthCcI8RQiKwavVTDppMSu7IoETgA==", + "requires": { + "@deephaven/components": "^0.85.0", + "@deephaven/console": "^0.85.0", + "@deephaven/filters": "^0.85.0", + "@deephaven/grid": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/jsapi-components": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@dnd-kit/core": "^6.1.0", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.2", @@ -36594,19 +36550,19 @@ }, "dependencies": { "@deephaven/console": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.84.0.tgz", - "integrity": "sha512-S5QAkns4vt5e1r2T3VQ/c8YhOnXNi+blTk/n4rHE1VAhH6qphRp1pehF9TQzRG859cSXT3JH2CBoe9efi7WVbw==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.85.0.tgz", + "integrity": "sha512-V603KnHLKdWNyy7ibzZ18hoUJCkLSU5rYMsRSsNYx/+GOrw3ozbvCYm3rYc+BheLPicybCb89OWJt9pIBkXnbA==", "requires": { - "@deephaven/chart": "^0.84.0", - "@deephaven/components": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", + "@deephaven/chart": "^0.85.0", + "@deephaven/components": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/storage": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/storage": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/react-fontawesome": "^0.2.0", "classnames": "^2.3.1", "linkifyjs": "^4.1.0", @@ -36628,27 +36584,27 @@ "integrity": "sha512-UiIbmCaMx5mPOGCWdgOCfZtccMhh55jv3qzeN3qBp3YUi46uGfWY5kfCU3hWRtaQvUgO7n0XhBKTd4K/pxv9ng==" }, "@deephaven/storage": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.84.0.tgz", - "integrity": "sha512-P/KJT2U04WypIxvx1Ws7l/02jUwIPdkonfUH9ezUK5YXzakwmMiXBvV2/jTBGrRpw/BfDZOkj25FlpDA4yib/A==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.85.0.tgz", + "integrity": "sha512-n+ytjBqFAbK4q/K6BfGjssqHVy6yN7iXU1aGtRkgoK90g6mdLr+2UjHE2eG2xa/qprITXDgutpKb2aKvlkixhw==", "requires": { - "@deephaven/filters": "^0.84.0", - "@deephaven/log": "^0.84.0", + "@deephaven/filters": "^0.85.0", + "@deephaven/log": "^0.85.0", "lodash.throttle": "^4.1.1" } } } }, "@deephaven/jsapi-bootstrap": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.84.0.tgz", - "integrity": "sha512-Aew3Lo+T9DRV1MLL89jeWORiMZ940gBQNz3kWbW7z/stcTQR89Wxynjt7tiaNRnBxBb0TgYrhphjlz01LAKjUw==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.85.0.tgz", + "integrity": "sha512-ATDdYQ15fHq1Nlg5OyRxWZF/WHgEgdeZAnwfD5uMFo4UoPpLcaNbe5IV8E97RAWA1eVD2jvVWz9yxHzFd9qY8g==", "requires": { - "@deephaven/components": "^0.84.0", + "@deephaven/components": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/utils": "^0.84.0" + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/utils": "^0.85.0" }, "dependencies": { "@deephaven/jsapi-types": { @@ -36659,17 +36615,17 @@ } }, "@deephaven/jsapi-components": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.84.0.tgz", - "integrity": "sha512-suo2BSyBxNoR7KxS2DCX+FxCBdvaq3eFrrSjqLG3HmxOg3ps3qLdqoiLEpn6cVw0cZTqS0K2jGbkE9oyoDj+tA==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.85.0.tgz", + "integrity": "sha512-zFePfFtfnI7vFsDXqlpyM+Nl/wl/YnVf4Gk6OsgDSrpyI2RpnKwM1t8bD/jHCGb6QjfjYDVaxW4d8X9Uoq4M/Q==", "requires": { - "@deephaven/components": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", + "@deephaven/components": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@types/js-cookie": "^3.0.3", "classnames": "^2.3.2", "js-cookie": "^3.0.5", @@ -36690,14 +36646,14 @@ "integrity": "sha512-X35g2ktmXbiTwjMNF20IkuNawJJ6Tlvrv23VuUVIjWHkpWcmyCYWIBle2zo7QAF6nnJpkccwFKJiC+TIkWl7hg==" }, "@deephaven/jsapi-utils": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.84.0.tgz", - "integrity": "sha512-CwYs9NHPs3wb+D0PM4VTBrqXzaHNHmuHTkep8XitZHAr814jOGcQhnkTauSpo+ulPwnheweO8C8wMjjBH/VojQ==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.85.0.tgz", + "integrity": "sha512-oWb0kC04McWCfPtVRpacCgNSM/g9xSWmvXSo7icDEoJVTogICElB3qxcnr6hJJmrghsGi2us0HKK/Ds7eUJYfQ==", "requires": { - "@deephaven/filters": "^0.84.0", + "@deephaven/filters": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/utils": "^0.85.0", "lodash.clamp": "^4.0.3", "nanoid": "^5.0.7" }, @@ -36710,39 +36666,29 @@ } }, "@deephaven/log": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.84.0.tgz", - "integrity": "sha512-B3KS2n/dT8GPblR8Top9GPB53pMmUglAMUVg93V3X10EPemE1jwiYEoJuceZ20JpRncCfRVuazrNYP7GItjWPQ==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.85.0.tgz", + "integrity": "sha512-RGPolUsmIBdfp1ym2SXlFnXhc7lDvKhaJ5t2MoEx/mL4MAsD1MWmO9A3x0F0zONS5XJGUDpLOgWbZVY0ld7JXg==", "requires": { "event-target-shim": "^6.0.2" } }, "@deephaven/plugin": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.84.0.tgz", - "integrity": "sha512-G3f3WGc159TVUZOekZPmUAChshdDqE7OzuigGXeFlv/CCmlQhX5t1BWwqfYRFXkHwV5zk9UUyuQEhrNAUS+Zmg==", - "requires": { - "@deephaven/components": "^0.84.0", - "@deephaven/golden-layout": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/iris-grid": "^0.84.0", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.85.0.tgz", + "integrity": "sha512-q1cEe7SnF3PvyE9nCEpyu/cPu9NwwitU5tGqMUe/II7wG1QgBHhz1OA4a4VZzgMEJbf4w8StfkRntRy1ushRUA==", + "requires": { + "@deephaven/components": "^0.85.0", + "@deephaven/golden-layout": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/iris-grid": "^0.85.0", "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/log": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", "@fortawesome/fontawesome-common-types": "^6.1.1", "@fortawesome/react-fontawesome": "^0.2.0" }, "dependencies": { - "@deephaven/golden-layout": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.84.0.tgz", - "integrity": "sha512-Pmy157rhKbf7U5YV6rBg7/r1ZHTHATw2UMQ501JEKAbOThrHIWrzktKk2Kfd4kpDs1CYPZsNJEuYwkzd+Xy2wA==", - "requires": { - "@deephaven/components": "^0.84.0", - "jquery": "^3.6.0", - "nanoid": "^5.0.7" - } - }, "@deephaven/jsapi-types": { "version": "1.0.0-dev0.34.0", "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.34.0.tgz", @@ -36751,27 +36697,27 @@ } }, "@deephaven/react-hooks": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.84.0.tgz", - "integrity": "sha512-VIcBAkfdyKI5JbITW5kouDfyfEm1ggUhbAYNWRUFlRSPNkoWxFfflc4eplQAfmj/VDjaVAizWNjc1JbH8OG/tg==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.85.0.tgz", + "integrity": "sha512-HMOH9ZEiJiWpveFovuU+63D2uhmjJKUolETtzalf3a6Emtnl4DkPMGllgnr/S6z94oFfC3yP2bwS2CqQQv6qVQ==", "requires": { "@adobe/react-spectrum": "3.35.1", - "@deephaven/log": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/utils": "^0.85.0", "lodash.debounce": "^4.0.8", "lodash.throttle": "^4.1.1", "nanoid": "^5.0.7" } }, "@deephaven/redux": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.84.0.tgz", - "integrity": "sha512-mj05IMOPtKhol5eLdiHORdyvnUv/bH7/sSV18q8hYJ3eHtpKyvuou3256s4NSpvgUCjyxTvQbknR9qemk1fVAw==", + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.85.0.tgz", + "integrity": "sha512-z36GulgLNXRTV4NgSU8wR/4TiCOJAqV5avr3EC4IkSNc7E41bQ2gYqIkuaJpT/AWKUofsFpu0nmLKhqtpes76A==", "requires": { "@deephaven/jsapi-types": "1.0.0-dev0.34.0", - "@deephaven/jsapi-utils": "^0.84.0", - "@deephaven/log": "^0.84.0", - "@deephaven/plugin": "^0.84.0", + "@deephaven/jsapi-utils": "^0.85.0", + "@deephaven/log": "^0.85.0", + "@deephaven/plugin": "^0.85.0", "fast-deep-equal": "^3.1.3", "proxy-memoize": "^3.0.0", "redux-thunk": "2.4.1" @@ -36785,9 +36731,9 @@ } }, "@deephaven/utils": { - "version": "0.84.0", - "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.84.0.tgz", - "integrity": "sha512-eWTlmxtdYFuV7q127AwMyLnf5j0FGpPG6gJ+2ChpFeMS+ZfOHpgcRHZC2+j3y/b5z4mGm2bIjzQDJpMNPL4thg==" + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.85.0.tgz", + "integrity": "sha512-tlz7rzZ9O9Y1OiMZSt4vKNGFvCH3P6GWU8ZkLLIj83dsXbAO442jCxBvPfMpC4NbSa2294fel+Mnl23ZOY4big==" }, "buffer": { "version": "6.0.3", @@ -36812,9 +36758,6 @@ "event-target-shim": { "version": "6.0.2" }, - "nanoid": { - "version": "5.0.7" - }, "redux-thunk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", @@ -42351,10 +42294,6 @@ "version": "7.5.6", "dev": true }, - "@types/shortid": { - "version": "0.0.29", - "dev": true - }, "@types/stack-utils": { "version": "2.0.3", "dev": true @@ -50111,8 +50050,9 @@ "dev": true }, "nanoid": { - "version": "3.3.7", - "dev": true + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", + "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==" }, "native-promise-only": { "version": "0.8.1" @@ -51473,6 +51413,14 @@ "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.2.0" + }, + "dependencies": { + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + } } }, "postcss-resolve-nested-selector": { diff --git a/package.json b/package.json index cced88b7d..74105aff8 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "@types/jest": "^29.2.5", "@types/node": "^20.11.17", "@types/prop-types": "^15.7.10", - "@types/shortid": "^0.0.29", "eslint": "^8.37.0", "identity-obj-proxy": "^3.0.0", "jest": "^29.6.2", diff --git a/plugins/dashboard-object-viewer/src/js/package.json b/plugins/dashboard-object-viewer/src/js/package.json index 31edb95b3..8fdd4c665 100644 --- a/plugins/dashboard-object-viewer/src/js/package.json +++ b/plugins/dashboard-object-viewer/src/js/package.json @@ -23,8 +23,8 @@ "@deephaven/dashboard": "^0.40.0", "@deephaven/jsapi-types": "^0.40.0", "@deephaven/log": "^0.40.0", - "react-json-view": "^1.21.3", - "shortid": "^2.2.16" + "nanoid": "^5.0.7", + "react-json-view": "^1.21.3" }, "devDependencies": { "@types/react": "^17.0.2", diff --git a/plugins/dashboard-object-viewer/src/js/src/DashboardPlugin/DashboardPlugin.tsx b/plugins/dashboard-object-viewer/src/js/src/DashboardPlugin/DashboardPlugin.tsx index fde21fa0b..75e6c4cad 100644 --- a/plugins/dashboard-object-viewer/src/js/src/DashboardPlugin/DashboardPlugin.tsx +++ b/plugins/dashboard-object-viewer/src/js/src/DashboardPlugin/DashboardPlugin.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect } from 'react'; -import shortid from 'shortid'; +import { nanoid } from 'nanoid'; import type { DashboardPluginComponentProps } from '@deephaven/dashboard'; import LayoutUtils from '@deephaven/dashboard/dist/layout/LayoutUtils'; import { useListener } from '@deephaven/dashboard/dist/layout/hooks'; @@ -19,7 +19,7 @@ export function DashboardPlugin({ ({ dragEvent, fetch, - panelId = shortid.generate(), + panelId = nanoid(), widget, }: { dragEvent?: DragEvent; diff --git a/plugins/matplotlib/src/js/package.json b/plugins/matplotlib/src/js/package.json index 6d4fcd9c0..67e63e177 100644 --- a/plugins/matplotlib/src/js/package.json +++ b/plugins/matplotlib/src/js/package.json @@ -43,8 +43,7 @@ "@deephaven/jsapi-bootstrap": "^0.58.0", "@deephaven/jsapi-types": "^0.58.0", "@deephaven/log": "^0.58.0", - "@deephaven/plugin": "^0.58.0", - "shortid": "^2.2.16" + "@deephaven/plugin": "^0.58.0" }, "publishConfig": { "access": "public" diff --git a/plugins/plotly-express/README.md b/plugins/plotly-express/README.md index 8bfca30d0..2a5485f5e 100644 --- a/plugins/plotly-express/README.md +++ b/plugins/plotly-express/README.md @@ -60,7 +60,7 @@ Docs can be built locally Install the necessary dependencies: ```shell -pip install -r requirements.txt +pip install -r sphinx-requirements.txt pip install dist/deephaven_plugin_plotly_express-*.whl ``` then run the docs make script: diff --git a/plugins/plotly-express/conf.py b/plugins/plotly-express/conf.py index c9bbb23e9..3ed54c0fd 100644 --- a/plugins/plotly-express/conf.py +++ b/plugins/plotly-express/conf.py @@ -5,6 +5,8 @@ import os import sys +sys.path.append(os.path.abspath("../../sphinx_ext")) + # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information @@ -22,6 +24,7 @@ "sphinx.ext.napoleon", "sphinx_markdown_builder", "sphinx_autodoc_typehints", + "deephaven_autodoc", ] source_suffix = [".rst", ".md"] # Can use either rst or markdown files as input @@ -34,7 +37,6 @@ # options for sphinx_autodoc_typehints always_use_bars_union = True -typehints_defaults = "comma" from deephaven_server import Server diff --git a/plugins/plotly-express/docs/area.md b/plugins/plotly-express/docs/area.md index b94e36d25..960644d7e 100644 --- a/plugins/plotly-express/docs/area.md +++ b/plugins/plotly-express/docs/area.md @@ -14,5 +14,5 @@ Area plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.area +.. dhautofunction:: deephaven.plot.express.area ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/bar.md b/plugins/plotly-express/docs/bar.md index a058f3bd1..f50ad4941 100644 --- a/plugins/plotly-express/docs/bar.md +++ b/plugins/plotly-express/docs/bar.md @@ -15,5 +15,5 @@ Bar plots have limitations and are not suitable for certain scenarios. They are ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.bar +.. dhautofunction:: deephaven.plot.express.bar ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/box.md b/plugins/plotly-express/docs/box.md index 9a3de7284..7fea88941 100644 --- a/plugins/plotly-express/docs/box.md +++ b/plugins/plotly-express/docs/box.md @@ -13,5 +13,5 @@ Box plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.box +.. dhautofunction:: deephaven.plot.express.box ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/candlestick.md b/plugins/plotly-express/docs/candlestick.md index e5c1e40f7..c56ac79db 100644 --- a/plugins/plotly-express/docs/candlestick.md +++ b/plugins/plotly-express/docs/candlestick.md @@ -17,5 +17,5 @@ Candlestick plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.candlestick +.. dhautofunction:: deephaven.plot.express.candlestick ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/funnel-area.md b/plugins/plotly-express/docs/funnel-area.md index f68630746..38709c57b 100644 --- a/plugins/plotly-express/docs/funnel-area.md +++ b/plugins/plotly-express/docs/funnel-area.md @@ -13,5 +13,5 @@ Funnel area plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.funnel_area +.. dhautofunction:: deephaven.plot.express.funnel_area ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/funnel.md b/plugins/plotly-express/docs/funnel.md index 4b77abb61..523d431f0 100644 --- a/plugins/plotly-express/docs/funnel.md +++ b/plugins/plotly-express/docs/funnel.md @@ -12,5 +12,5 @@ Funnel plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.funnel +.. dhautofunction:: deephaven.plot.express.funnel ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/histogram.md b/plugins/plotly-express/docs/histogram.md index bf424c027..fedd71d69 100644 --- a/plugins/plotly-express/docs/histogram.md +++ b/plugins/plotly-express/docs/histogram.md @@ -13,5 +13,5 @@ Histogram plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.histogram +.. dhautofunction:: deephaven.plot.express.histogram ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/icicle.md b/plugins/plotly-express/docs/icicle.md index 0bd538918..916de4819 100644 --- a/plugins/plotly-express/docs/icicle.md +++ b/plugins/plotly-express/docs/icicle.md @@ -13,5 +13,5 @@ Icicle plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.icicle +.. dhautofunction:: deephaven.plot.express.icicle ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/layer-plots.md b/plugins/plotly-express/docs/layer-plots.md index 09da326f1..b0969d4e9 100644 --- a/plugins/plotly-express/docs/layer-plots.md +++ b/plugins/plotly-express/docs/layer-plots.md @@ -7,5 +7,5 @@ To "layer" or "stack" multiple plots on top of each other, use the `layer` funct ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.layer +.. dhautofunction:: deephaven.plot.express.layer ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/line-3d.md b/plugins/plotly-express/docs/line-3d.md index 8c45786ad..9177fa7c6 100644 --- a/plugins/plotly-express/docs/line-3d.md +++ b/plugins/plotly-express/docs/line-3d.md @@ -16,5 +16,5 @@ Alternatives to 3D line plots include: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.line_3d +.. dhautofunction:: deephaven.plot.express.line_3d ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/line-polar.md b/plugins/plotly-express/docs/line-polar.md index e1b186a84..353db5eff 100644 --- a/plugins/plotly-express/docs/line-polar.md +++ b/plugins/plotly-express/docs/line-polar.md @@ -13,5 +13,5 @@ Polar line plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.line_polar +.. dhautofunction:: deephaven.plot.express.line_polar ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/line-ternary.md b/plugins/plotly-express/docs/line-ternary.md index 2a309aa17..5a0dea2d0 100644 --- a/plugins/plotly-express/docs/line-ternary.md +++ b/plugins/plotly-express/docs/line-ternary.md @@ -11,5 +11,5 @@ Ternary line plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.line_ternary +.. dhautofunction:: deephaven.plot.express.line_ternary ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/line.md b/plugins/plotly-express/docs/line.md index 88e21ce6d..8396f11d4 100644 --- a/plugins/plotly-express/docs/line.md +++ b/plugins/plotly-express/docs/line.md @@ -398,5 +398,5 @@ scatter_plot_opacity = dx.scatter( ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.line +.. dhautofunction:: deephaven.plot.express.line ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/ohlc.md b/plugins/plotly-express/docs/ohlc.md index d9414b78c..46797b653 100644 --- a/plugins/plotly-express/docs/ohlc.md +++ b/plugins/plotly-express/docs/ohlc.md @@ -15,5 +15,5 @@ OHLC (Open-High-Low-Close) plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.ohlc +.. dhautofunction:: deephaven.plot.express.ohlc ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/pie.md b/plugins/plotly-express/docs/pie.md index 059882ef0..31c46ed86 100644 --- a/plugins/plotly-express/docs/pie.md +++ b/plugins/plotly-express/docs/pie.md @@ -16,5 +16,5 @@ Limitations of pie plots include: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.pie +.. dhautofunction:: deephaven.plot.express.pie ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/scatter-3d.md b/plugins/plotly-express/docs/scatter-3d.md index 95dfceeaa..c41f907a8 100644 --- a/plugins/plotly-express/docs/scatter-3d.md +++ b/plugins/plotly-express/docs/scatter-3d.md @@ -134,5 +134,5 @@ scatter_plot_color_column = dx.scatter_3d( ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.scatter_3d +.. dhautofunction:: deephaven.plot.express.scatter_3d ``` diff --git a/plugins/plotly-express/docs/scatter-polar.md b/plugins/plotly-express/docs/scatter-polar.md index 5c758721c..de07d79a1 100644 --- a/plugins/plotly-express/docs/scatter-polar.md +++ b/plugins/plotly-express/docs/scatter-polar.md @@ -13,5 +13,5 @@ Polar scatter plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.scatter_polar +.. dhautofunction:: deephaven.plot.express.scatter_polar ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/scatter-ternary.md b/plugins/plotly-express/docs/scatter-ternary.md index fcfa4241a..a84625fd1 100644 --- a/plugins/plotly-express/docs/scatter-ternary.md +++ b/plugins/plotly-express/docs/scatter-ternary.md @@ -13,5 +13,5 @@ Ternary scatter plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.scatter_ternary +.. dhautofunction:: deephaven.plot.express.scatter_ternary ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/scatter.md b/plugins/plotly-express/docs/scatter.md index 0108a0c30..044279d21 100644 --- a/plugins/plotly-express/docs/scatter.md +++ b/plugins/plotly-express/docs/scatter.md @@ -445,5 +445,5 @@ scatter_plot_opacity = dx.scatter( ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.scatter +.. dhautofunction:: deephaven.plot.express.scatter ``` diff --git a/plugins/plotly-express/docs/strip.md b/plugins/plotly-express/docs/strip.md index 2358ca213..992c5291c 100644 --- a/plugins/plotly-express/docs/strip.md +++ b/plugins/plotly-express/docs/strip.md @@ -14,5 +14,5 @@ Strip plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.strip +.. dhautofunction:: deephaven.plot.express.strip ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/sub-plots.md b/plugins/plotly-express/docs/sub-plots.md index 756876cbf..6782d9b4c 100644 --- a/plugins/plotly-express/docs/sub-plots.md +++ b/plugins/plotly-express/docs/sub-plots.md @@ -7,5 +7,5 @@ Multiple sub plots can be combined into one plot using the `make_subplots` funct ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.make_subplots +.. dhautofunction:: deephaven.plot.express.make_subplots ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/sunburst.md b/plugins/plotly-express/docs/sunburst.md index 3e81623bf..01758ed37 100644 --- a/plugins/plotly-express/docs/sunburst.md +++ b/plugins/plotly-express/docs/sunburst.md @@ -12,5 +12,5 @@ Sunburst plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.sunburst +.. dhautofunction:: deephaven.plot.express.sunburst ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/timeline.md b/plugins/plotly-express/docs/timeline.md index 9a2235c1b..701a31f7f 100644 --- a/plugins/plotly-express/docs/timeline.md +++ b/plugins/plotly-express/docs/timeline.md @@ -7,5 +7,5 @@ Timeline plots in offer a means to visualize time-related data, displaying event ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.timeline +.. dhautofunction:: deephaven.plot.express.timeline ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/treemap.md b/plugins/plotly-express/docs/treemap.md index 046342297..0078dcd12 100644 --- a/plugins/plotly-express/docs/treemap.md +++ b/plugins/plotly-express/docs/treemap.md @@ -13,5 +13,5 @@ Treemap plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.treemap +.. dhautofunction:: deephaven.plot.express.treemap ``` \ No newline at end of file diff --git a/plugins/plotly-express/docs/violin.md b/plugins/plotly-express/docs/violin.md index 1b15485d0..2335e3a0d 100644 --- a/plugins/plotly-express/docs/violin.md +++ b/plugins/plotly-express/docs/violin.md @@ -14,5 +14,5 @@ Violin plots are useful for: ## API Reference ```{eval-rst} -.. autofunction:: deephaven.plot.express.violin +.. dhautofunction:: deephaven.plot.express.violin ``` \ No newline at end of file diff --git a/plugins/plotly-express/make_docs.py b/plugins/plotly-express/make_docs.py index fa399006e..8f5b8d065 100644 --- a/plugins/plotly-express/make_docs.py +++ b/plugins/plotly-express/make_docs.py @@ -1,45 +1,79 @@ +from __future__ import annotations + import os +import contextlib +from typing import IO, Generator BUILT_DOCS = "docs/build/markdown" -# save original directory so we can return to it -cwd = os.getcwd() -# change to the directory of this file -dirname = os.path.dirname(__file__) -os.chdir(dirname) +@contextlib.contextmanager +def pushd() -> None: + """ + Change to the script directory, and return to the original directory when done. + """ + # save original directory so we can return to it + cwd = os.getcwd() -os.system("make clean") + # change to the directory of this file + dirname = os.path.dirname(__file__) + if dirname: + os.chdir(dirname) -print("Building markdown") -os.system("make markdown") + try: + yield + finally: + # ensure we always return to the original directory, even if an exception is raised + os.chdir(cwd) -print("Copying assets") -os.system(f"cp -r docs/_assets {BUILT_DOCS}/_assets") -os.system(f"cp docs/sidebar.json {BUILT_DOCS}/sidebar.json") -os.system(f"rm {BUILT_DOCS}/index.md") +def md_files() -> Generator[str, None, None]: + """ + Walk the built docs directory and yield the path to each markdown file. -try: - # go through each markdown file, look for ### deephaven.plot.express then add the syntax block + Returns: + Generator[str, None, None]: The path to each markdown file. + """ for root, dirs, files in os.walk(BUILT_DOCS): for file in files: if file.endswith(".md"): - with open(os.path.join(root, file), "r") as f: - lines = f.readlines() - with open(os.path.join(root, file), "w") as f: - for line in lines: - if "### deephaven.plot.express." in line: - # remove escaped \* with * as it's not needed when in a code block - line = line.replace("\\*", "*") - # first add the lines here - line = line.replace("### deephaven.plot.express.", "") - before = "\n\n```python\n" - after = "```\n\n\n" - line = before + line + after - # then here - f.write(line) - -finally: - # ensure we always return to the original directory, even if an exception is raised - os.chdir(cwd) + yield os.path.join(root, file) + + +def md_lines() -> Generator[tuple[IO, str], None, None]: + """ + Open each markdown file and yield the file object and each line in the file. + + Returns: + Generator[tuple[IO, str], None, None]: The file object and each line in the file. + """ + for file in md_files(): + with open(file, "r") as f: + lines = f.readlines() + with open(file, "w") as f: + for line in lines: + yield f, line + + +with pushd(): + os.system("make clean") + + print("Building markdown") + os.system("make markdown") + + print("Copying assets") + os.system(f"cp -r docs/_assets {BUILT_DOCS}/_assets") + os.system(f"cp docs/sidebar.json {BUILT_DOCS}/sidebar.json") + + os.system(f"rm {BUILT_DOCS}/index.md") + + for f, line in md_lines(): + if line.startswith("\n" + ): + # remove the comment markers + # these are added in deephaven_autodoc.py to prevent special characters from being escaped + # by the markdown renderer + line = line.replace("", "") + f.write(line) diff --git a/plugins/plotly-express/requirements.txt b/plugins/plotly-express/requirements.txt deleted file mode 100644 index 38f6fd426..000000000 --- a/plugins/plotly-express/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -deephaven-server -Sphinx -myst-parser -sphinx-markdown-builder -sphinx-autodoc-typehints \ No newline at end of file diff --git a/plugins/plotly-express/sphinx-requirements.txt b/plugins/plotly-express/sphinx-requirements.txt new file mode 100644 index 000000000..56cd10aff --- /dev/null +++ b/plugins/plotly-express/sphinx-requirements.txt @@ -0,0 +1,6 @@ +deephaven-server +Sphinx +myst-parser +sphinx-markdown-builder +sphinx-autodoc-typehints +typing_extensions;python_version<'3.11' \ No newline at end of file diff --git a/plugins/plotly-express/src/deephaven/plot/express/data/data_generators.py b/plugins/plotly-express/src/deephaven/plot/express/data/data_generators.py index 0acef0370..cf3c6ae66 100644 --- a/plugins/plotly-express/src/deephaven/plot/express/data/data_generators.py +++ b/plugins/plotly-express/src/deephaven/plot/express/data/data_generators.py @@ -110,10 +110,10 @@ def get_index(species: str) -> int: "timestamp = base_time + (long)((ii + df_len) * SECOND)", # pick a random species from the list, using the index as a seed "species = (String)species_list[(int)new Random(ii).nextInt(3)]", - "sepal_length = get_random_value(`sepal_length`, ii, species)", - "sepal_width = get_random_value(`sepal_width`, ii, species)", - "petal_length = get_random_value(`petal_length`, ii, species)", - "petal_width = get_random_value(`petal_width`, ii, species)", + "sepal_length = get_random_value(`sepal_length`, ii + 1, species)", + "sepal_width = get_random_value(`sepal_width`, ii + 2, species)", + "petal_length = get_random_value(`petal_length`, ii + 3, species)", + "petal_width = get_random_value(`petal_width`, ii + 4, species)", "species_id = get_index(species)", ] ) @@ -125,6 +125,135 @@ def get_index(species: str) -> int: return source_table +def jobs(ticking: bool = True) -> Table: + """ + Returns a synthetic dataset containing five different jobs and their durations over time. + + This dataset is intended to be used with a timeline plot. It demonstrates five different "jobs", each starting + two days after the previous, and each lasting 5 days in total. The job's "resource", or the name of the individual + assigned to the job, is randomly selected. The dataset continues to loop in this way, moving across time until + it is deleted or the server is shut down. + + Notes: + Contains the following columns: + - Job: a string column denoting the name of the job, ranging from Job1 to Job5 + - StartTime: a Java Instant column containing the start time of the job + - EndTime: a Java Instant column containing the end time of the job + - Resource: a string column indicating the name of the person that the job is assigned to + + Args: + ticking: + If true, the table will tick new data every second. + + Returns: + A Deephaven Table + + Examples: + ``` + from deephaven.plot import express as dx + jobs = dx.data.jobs() + ``` + """ + + def generate_resource(index: int) -> str: + random.seed(index) + return random.choice(["Mike", "Matti", "Steve", "John", "Jane"]) + + jobs_query_strings = [ + "Job = `Job` + String.valueOf((ii % 5) + 1)", + "StartTime = '2020-01-01T00:00:00Z' + ('P1d' * i * 2)", + "EndTime = StartTime + 'P5d'", + "Resource = generate_resource(ii)", + ] + + static_jobs = empty_table(5).update(jobs_query_strings) + + if not ticking: + return static_jobs + + ticking_jobs = merge( + [ + static_jobs, + time_table("PT1s") + .drop_columns("Timestamp") + .update(jobs_query_strings) + .update("StartTime = StartTime + 'P10d'"), + ] + ).last_by("Job") + + return ticking_jobs + + +def marketing(ticking: bool = True) -> Table: + """ + Returns a synthetic ticking dataset tracking the movement of customers from website visit to product purchase. + + This dataset is intended to be used with the `dx.funnel` and `dx.funnel_area` plot types. Each row in this dataset + represents an individual that has visited a company website. The individual may download an instance of the product, + be considered a potential customer, formally request the price of the product, or purchase the product and receive + an invoice. Each of these categories is a strict subset of the last, so it lends itself well to funnel plots. + + Notes: + Contains the following columns: + - Stage: a string column containing the stage of a customers interest: + VisitedWebsite, Downloaded, PotentialCustomer, RequestedPrice, and InvoiceSent + - Count: an integer column counting the number of customers to fall into each category + + Args: + ticking: + If true, the table will tick new data every second. + + Returns: + A Deephaven Table + + Examples: + ``` + from deephaven.plot import express as dx + marketing = dx.data.marketing() + ``` + """ + _ColsToRowsTransform = jpy.get_type( + "io.deephaven.engine.table.impl.util.ColumnsToRowsTransform" + ) + + def weighted_selection(prob: float, index: int) -> bool: + random.seed(index) + return random.uniform(0, 1) < prob + + marketing_query_strings = [ + "VisitedWebsite = true", # appearing in this table assumes a website visit + "Downloaded = VisitedWebsite ? weighted_selection(0.45, ii) : false", # 45% of visits download product + "PotentialCustomer = Downloaded ? weighted_selection(0.77, ii + 1) : false", # 77% of downloads are potential customers + "RequestedPrice = PotentialCustomer ? weighted_selection(0.82, ii + 2) : false", # 82% of flagged potential customers request price + "InvoiceSent = RequestedPrice ? weighted_selection(0.24, ii + 3) : false", # 24% of those who requested price get invoice + ] + + marketing_table = empty_table(100).update(marketing_query_strings) + + if ticking: + marketing_table = merge( + [ + marketing_table, + time_table("PT1s") + .update(marketing_query_strings) + .drop_columns("Timestamp"), + ] + ) + + return Table( + _ColsToRowsTransform.columnsToRows( + marketing_table.sum_by().j_table, + "Stage", + "Count", + "VisitedWebsite", + "Downloaded", + "PotentialCustomer", + "RequestedPrice", + "InvoiceSent", + ) + ) + + def stocks(ticking: bool = True, hours_of_data: int = 1) -> Table: """Returns a Deephaven table containing a generated example data set. @@ -353,23 +482,23 @@ def generate_sex(index: int) -> str: return random.choices(sex_list, weights=sex_probs)[0] def generate_smoker(index: int) -> str: - random.seed(index) + random.seed(index + 1) return random.choices(smoker_list, weights=smoker_probs)[0] def generate_day(index: int) -> str: - random.seed(index) + random.seed(index + 2) return random.choices(day_list, weights=day_probs)[0] def generate_time(index: int) -> str: - random.seed(index) + random.seed(index + 3) return random.choices(time_list, weights=time_probs)[0] def generate_size(index: int) -> int: - random.seed(index) + random.seed(index + 4) return random.choices(size_list, weights=size_probs)[0] def generate_total_bill(smoker: str, size: int, index: int) -> float: - random.seed(index) + random.seed(index + 5) return round( 3.68 + 3.08 * (smoker == "Yes") @@ -379,7 +508,7 @@ def generate_total_bill(smoker: str, size: int, index: int) -> float: ) def generate_tip(total_bill: float, index: int) -> float: - random.seed(index) + random.seed(index + 6) return max(1, round(0.92 + 0.11 * total_bill + random.gauss(0.0, 1.02), 2)) # create synthetic ticking version of the tips dataset that generates one new observation per period @@ -403,7 +532,7 @@ def generate_tip(total_bill: float, index: int) -> float: return merge([tips_table, ticking_table]) -def election(ticking: bool = True): +def election(ticking: bool = True) -> Table: """ Returns a ticking version of the Election dataset included in the plotly-express package. @@ -488,7 +617,7 @@ def get_long_val(column: str, index: int) -> int: return merge([election_table.head(STATIC_ROWS - 1), ticking_table]) -def wind(ticking: bool = True): +def wind(ticking: bool = True) -> Table: """ Returns a ticking version of the Wind dataset included in the plotly-express package. diff --git a/plugins/plotly-express/src/deephaven/plot/express/plots/distribution.py b/plugins/plotly-express/src/deephaven/plot/express/plots/distribution.py index a3f902977..41b894004 100644 --- a/plugins/plotly-express/src/deephaven/plot/express/plots/distribution.py +++ b/plugins/plotly-express/src/deephaven/plot/express/plots/distribution.py @@ -156,7 +156,7 @@ def box( See color_discrete_map for additional behaviors. hover_name: A column that contains names to bold in the hover tooltip. labels: A dictionary of labels mapping columns to new labels. - color_discrete_sequence | None: A list of colors to sequentially apply to + color_discrete_sequence: A list of colors to sequentially apply to the series. The colors loop, so if there are more series than colors, colors will be reused. color_discrete_map: If dict, the keys should be strings of the column values (or a tuple diff --git a/plugins/plotly-express/src/js/package.json b/plugins/plotly-express/src/js/package.json index 5a22602d1..e0aac7a72 100644 --- a/plugins/plotly-express/src/js/package.json +++ b/plugins/plotly-express/src/js/package.json @@ -63,11 +63,11 @@ "@deephaven/plugin": "0.75.0", "@deephaven/utils": "0.75.0", "deep-equal": "^2.2.1", + "nanoid": "^5.0.7", "plotly.js": "^2.29.1", "plotly.js-dist-min": "^2.29.1", "react-plotly.js": "^2.4.0", - "react-redux": "^7.2.9", - "shortid": "^2.2.16" + "react-redux": "^7.2.9" }, "publishConfig": { "access": "public" diff --git a/plugins/plotly-express/src/js/src/DashboardPlugin.tsx b/plugins/plotly-express/src/js/src/DashboardPlugin.tsx index 1774d9f3f..b6560a393 100644 --- a/plugins/plotly-express/src/js/src/DashboardPlugin.tsx +++ b/plugins/plotly-express/src/js/src/DashboardPlugin.tsx @@ -1,5 +1,5 @@ import { useCallback, DragEvent, useEffect } from 'react'; -import shortid from 'shortid'; +import { nanoid } from 'nanoid'; import { DashboardPluginComponentProps, LayoutUtils, @@ -20,7 +20,7 @@ export function DashboardPlugin( dragEvent, fetch, metadata = {}, - panelId = shortid.generate(), + panelId = nanoid(), widget, }: { dragEvent?: DragEvent; diff --git a/plugins/plotly/src/js/package.json b/plugins/plotly/src/js/package.json index 68059ff86..65836d11f 100644 --- a/plugins/plotly/src/js/package.json +++ b/plugins/plotly/src/js/package.json @@ -40,10 +40,10 @@ "@deephaven/jsapi-types": "^0.40.0", "@deephaven/log": "^0.40.0", "@deephaven/utils": "^0.40.0", + "nanoid": "^5.0.7", "plotly.js-dist-min": "^2.29.1", "prop-types": "^15.8.1", - "react-plotly.js": "^2.4.0", - "shortid": "^2.2.16" + "react-plotly.js": "^2.4.0" }, "publishConfig": { "access": "public" diff --git a/plugins/plotly/src/js/src/DashboardPlugin.tsx b/plugins/plotly/src/js/src/DashboardPlugin.tsx index e36b6cc6a..2aa1541a6 100644 --- a/plugins/plotly/src/js/src/DashboardPlugin.tsx +++ b/plugins/plotly/src/js/src/DashboardPlugin.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect } from 'react'; -import shortid from 'shortid'; +import { nanoid } from 'nanoid'; import { DashboardPluginComponentProps, LayoutUtils, @@ -27,7 +27,7 @@ export function DashboardPlugin( dragEvent, fetch, metadata = {}, - panelId = shortid.generate(), + panelId = nanoid(), widget, }: { dragEvent?: React.DragEvent; diff --git a/plugins/ui/DESIGN.md b/plugins/ui/DESIGN.md index b82315151..2c4e29e34 100644 --- a/plugins/ui/DESIGN.md +++ b/plugins/ui/DESIGN.md @@ -1020,11 +1020,12 @@ A tabs component can be used to organize content in a collection of tabs, allowi ###### Parameters -| Parameter | Type | Description | -| ----------- | ------------------------------- | ------------------------------------------------------------------------------------------- | -| `*children` | `Item \| TabList \| TabPanels` | The tab panels to render within the tabs component. | -| `on_change` | `Callable[[Key], None] \| None` | Alias of `on_selection_change`. Handler that is called when the tab selection changes. | -| `**props` | `Any` | Any other [Tabs](https://react-spectrum.adobe.com/react-spectrum/Tabs.html#tabs-props) prop | +| Parameter | Type | Description | +| ----------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `*children` | `Tab \| TabList \| TabPanels` | The tab panels to render within the tabs component. | +| `on_change` | `Callable[[Key], None] \| None` | Alias of `on_selection_change`. Handler that is called when the tab selection changes. | +| `**props` | `Any` | Any other [Tabs](https://react-spectrum.adobe.com/react-spectrum/Tabs.html#tabs-props) prop +| | @@ -1035,7 +1036,7 @@ If you're just using the default tab layout and don't need to customize the appe ```py from deephaven import empty_table, ui -ui.tabs( +t = ui.tabs( # Render a tab with the title "Tab 1" with "Content 1" as tab content, given that no key is passed, would be set to "Tab 1" ui.tab("Content 1", title="Tab 1"), @@ -1043,19 +1044,19 @@ ui.tabs( ui.tab("Content 2", title="Tab 2", key="Key 2"), # Content passed in that contains a flex, illustrating that tab content does not have to be a string - # Render a tab with the title "Tab 3" with "Hello World" header with a table beside it as the tab content, given that no key is passed, would be set to "Tab 1" + # Render a tab with the title "Tab 3" with "Hello World" with a table beside it as the tab content. Key will default to "Tab 3" ui.tab( ui.flex( "Hello World!", ui.flex(empty_table(10).update("I=i")), ), title="Tab 3", - key="Key 3", ), # Tab with text and icon as title - # Render "Content 4" in a tab called "Tab 4 ", keyed "Tab 4" - ui.tab("Content 4", title=ui.item("Tab 4", ui.icon("vsGithubAlt"))) + # Render "Content 4" in a tab called " Tab 4", keyed "Tab 4" + ui.tab("Content 4", title="Tab 4", icon=ui.icon("vsGithubAlt")), + aria_label="Some label" ) ``` @@ -1063,10 +1064,11 @@ ui.tabs( ```py from deephaven import ui -ui.tabs( +t = ui.tabs( # Render a tabs that have an on_change, which prints the selected tab key when a tab is selected ui.tab("Content 1", title="Tab 1", key="Key 1"), ui.tab("Content 2", title="Tab 2", key="Key 2"), + aria_label="Some label" on_change=lambda key: print(f"Selected key: {key}"), ) ``` @@ -1080,7 +1082,7 @@ With this method, the keys must be provided and match for the tabs declared in t ```py from deephaven import ui # Tabs specified by passing in tab_panels and tab_list -ui.tabs( +t = ui.tabs( # Render a Tab with a title of "Tab 1", with a content of "Content 1", keyed "Key 1" ui.tab_list(ui.item("Tab 1", key="Key 1"), ui.item("Tab 2", key="Key 2")), ui.tab_panels( @@ -1107,21 +1109,9 @@ t2 = ui.tabs( ui.tab("Content 2", title="Tab 2", key="Key 1"), ) -# Causes a KeyError, since there are mismatching keys for "Tab 2" -t3 = ui.tabs( - ui.tab_list(ui.item("Tab 1", key="Key 1"), ui.item("Tab 2", key="Key 2")), - ui.tab_panels( - ui.item("Content 3", key="Key 1"), - ui.item("Content 2", key="Key 3"), - flex_grow=1, - position="relative", - ), - flex_grow=1, -) - # Causes an error since cannot specify tabs with combination of ui.tab and ui.tab_panels and ui.tab_list -t4 = ui.tabs( - ui.tab("Content 1", title="Tab 1", key="Key 1"), +t3 = ui.tabs( + ui.tab("Content 1", title="Tab 1"), ui.tab_list(ui.item("Tab 2", key="Key 2")), ui.tab_panels( ui.item( @@ -1135,6 +1125,20 @@ t4 = ui.tabs( ), ), ) + +# Causes an error since there are mismatching keys +t4 = ui.tabs( + ui.tab_list( + ui.item("Tab 1", key="Key 1"), + ui.item("Tab 2", key="Key 2")), # No tab in tab_panels keyed "Key 2" + ui.tab_panels( + ui.item("Content 3", key="Key 1"), + ui.item("Content 2", key="Key 3"), # No item in tab list keyed "Key 3" + flex_grow=1, + position="relative", + ), + flex_grow=1, +) ``` #### Components diff --git a/plugins/ui/docs/README.md b/plugins/ui/docs/README.md index 856938da3..cbe59f909 100644 --- a/plugins/ui/docs/README.md +++ b/plugins/ui/docs/README.md @@ -1572,13 +1572,37 @@ For more information on liveness scopes and why they are needed, see the [livene ![Change Monitor](_assets/change_monitor.png) -## Tabs +## Tabs using ui.tab -You can add [Tabs](https://react-spectrum.adobe.com/react-spectrum/Tabs.html) within a panel by using the `ui.tabs` method. In this example, we create a tabbed panel with multiple tabs: +You can add [Tabs](https://react-spectrum.adobe.com/react-spectrum/Tabs.html) within a panel by using the `ui.tabs` method. In this example, we create a panel with two tabs by passing in two instances of `ui.tab` as children. -- Unfiltered table -- Table filtered on sym `CAT`. We also include an icon in the tab header. -- Table filtered on sym `DOG` +When specifying tabs with this format, the following must be noted: +- The `title` prop has to be unique, if not, the `key` prop has to be unique +- The `text_value` prop is an optional accessibility improvement prop + +```python +from deephaven import ui + + +@ui.component +def ui_tabs(): + return ui.tabs( + ui.tab("Content 1", title="Tab 1"), + ui.tab("Content 2", title="Tab 2", key="Key 2"), + ui.tab("Content 3", title="Tab 3", icon=ui.icon("vsGithubAlt")), + ) + + +my_tabs = ui_tabs() +``` + +## Tabs using ui.tab_panels and ui.tab_list + +You can add [Tabs](https://react-spectrum.adobe.com/react-spectrum/Tabs.html) within a panel by using the `ui.tabs` method. In this example, we create a tabbed panel with multiple tabs by passing in the `ui.tab_panels` and `ui.tab_list` as children: + +`tab_list` is the container of tab headers. It expects children of `ui.item` which have a unique key. `text_value` may be added for accessibility, but by default the `key` will be used for accessibility. + +`tab_panels` is the content of the tabs. It expects children of `ui.item` which have a matching key with an item in the `tab_list`. ```python from deephaven import ui @@ -1588,7 +1612,7 @@ stocks = dx.data.stocks() @ui.component -def table_tabs(source): +def ui_tabs(source): return ui.tabs( ui.tab_list( ui.item("Unfiltered", key="Unfiltered"), @@ -1601,10 +1625,11 @@ def table_tabs(source): ui.item(source.where("sym=`DOG`"), key="DOG"), ), flex_grow=1, + aria_label="Tabs", # aria_label is set for aria accessibility and is otherwise optional ) -tt = table_tabs(stocks) +my_tabs = ui_tabs(stocks) ``` ## Using Table Data Hooks diff --git a/plugins/ui/src/deephaven/ui/components/__init__.py b/plugins/ui/src/deephaven/ui/components/__init__.py index abd022bf3..06f21319b 100644 --- a/plugins/ui/src/deephaven/ui/components/__init__.py +++ b/plugins/ui/src/deephaven/ui/components/__init__.py @@ -6,7 +6,6 @@ icon_wrapper, form, switch, - tabs, tab_list, tab_panels, text, @@ -42,7 +41,9 @@ from .section import section from .slider import slider from .stack import stack +from .tab import tab from .table import table +from .tabs import tabs from .text_field import text_field from .toggle_button import toggle_button from .view import view @@ -95,6 +96,7 @@ "tab_list", "tab_panels", "tabs", + "tab", "text", "text_field", "toggle_button", diff --git a/plugins/ui/src/deephaven/ui/components/action_menu.py b/plugins/ui/src/deephaven/ui/components/action_menu.py index 640dae31d..4529b4e4f 100644 --- a/plugins/ui/src/deephaven/ui/components/action_menu.py +++ b/plugins/ui/src/deephaven/ui/components/action_menu.py @@ -4,7 +4,6 @@ from .item import Item from .section import SectionElement -from ..types import Key, ActionKey, ActionMenuDirection from .basic import component_element from ..elements import Element diff --git a/plugins/ui/src/deephaven/ui/components/basic.py b/plugins/ui/src/deephaven/ui/components/basic.py index ce008d6f8..877e5caf1 100644 --- a/plugins/ui/src/deephaven/ui/components/basic.py +++ b/plugins/ui/src/deephaven/ui/components/basic.py @@ -39,14 +39,6 @@ def switch(*children, **props): return component_element("Switch", *children, **props) -def tabs(*children, **props): - """ - Python implementation for the Adobe React Spectrum Tabs component. - https://react-spectrum.adobe.com/react-spectrum/Tabs.html - """ - return component_element("Tabs", *children, **props) - - def tab_list(*children, **props): """ Python implementation for the Adobe React Spectrum TabList component. diff --git a/plugins/ui/src/deephaven/ui/components/icon.py b/plugins/ui/src/deephaven/ui/components/icon.py index 18c43c571..0250fd66b 100644 --- a/plugins/ui/src/deephaven/ui/components/icon.py +++ b/plugins/ui/src/deephaven/ui/components/icon.py @@ -1,8 +1,117 @@ -from ..elements import BaseElement +from __future__ import annotations +from ..elements import BaseElement, Element +from typing import Any +from .types import ( + AlignSelf, + CSSProperties, + DimensionValue, + JustifySelf, + LayoutFlex, + Position, + IconSize, + IconColor, +) +from .._internal.utils import create_props -def icon(name: str, *children, **props): +def icon( + name: str, + size: IconSize | None = None, + color: IconColor | None = None, + flex: LayoutFlex | None = None, + flex_grow: float | None = None, + flex_shrink: float | None = None, + flex_basis: DimensionValue | None = None, + align_self: AlignSelf | None = None, + justify_self: JustifySelf | None = None, + order: int | None = None, + grid_area: str | None = None, + grid_row: str | None = None, + grid_column: str | None = None, + grid_column_start: str | None = None, + grid_column_end: str | None = None, + grid_row_start: str | None = None, + grid_row_end: str | None = None, + slot: str = "icon", + margin: DimensionValue | None = None, + margin_top: DimensionValue | None = None, + margin_bottom: DimensionValue | None = None, + margin_start: DimensionValue | None = None, + margin_end: DimensionValue | None = None, + margin_x: DimensionValue | None = None, + margin_y: DimensionValue | None = None, + width: DimensionValue | None = None, + height: DimensionValue | None = None, + min_width: DimensionValue | None = None, + min_height: DimensionValue | None = None, + max_width: DimensionValue | None = None, + max_height: DimensionValue | None = None, + position: Position | None = None, + top: DimensionValue | None = None, + bottom: DimensionValue | None = None, + left: DimensionValue | None = None, + right: DimensionValue | None = None, + start: DimensionValue | None = None, + end: DimensionValue | None = None, + z_index: int | None = None, + is_hidden: bool | None = None, + id: str | None = None, + aria_label: str | None = None, + aria_hidden: bool | None = None, + aria_labelledby: str | None = None, + aria_describedby: str | None = None, + aria_details: str | None = None, + UNSAFE_class_name: str | None = None, + UNSAFE_style: CSSProperties | None = None, +) -> Element: """ Get a Deephaven icon by name. + + Args: + name: The name of the icon to get. + size: The size of the icon (changes based on scale). + color: The color of the icon. + flex: When used in a flex layout, specifies how the element will grow or shrink to fit the space available. + flex_grow: When used in a flex layout, specifies how the element will grow to fit the space available. + flex_shrink: When used in a flex layout, specifies how the element will shrink to fit the space available. + flex_basis: When used in a flex layout, specifies the initial main size of the element. + align_self: Overrides the alignItems property of a flex or grid container. + justify_self: Species how the element is justified inside a flex or grid container. + order: The layout order for the element within a flex or grid container. + grid_area: When used in a grid layout specifies, specifies the named grid area that the element should be placed in within the grid. + grid_row: When used in a grid layout, specifies the row the element should be placed in within the grid. + grid_column: When used in a grid layout, specifies the column the element should be placed in within the grid. + grid_row_start: When used in a grid layout, specifies the starting row to span within the grid. + grid_row_end: When used in a grid layout, specifies the ending row to span within the grid. + grid_column_start: When used in a grid layout, specifies the starting column to span within the grid. + grid_column_end: When used in a grid layout, specifies the ending column to span within the grid. + slot: A slot to place the icon in. + margin: The margin for all four sides of the element. + margin_top: The margin for the top side of the element. + margin_bottom: The margin for the bottom side of the element. + margin_start: The margin for the logical start side of the element, depending on layout direction. + margin_end: The margin for the logical end side of the element, depending on layout direction. + margin_x: The margin for the left and right sides of the element. + margin_y: The margin for the top and bottom sides of the element. + width: The width of the element. + height: The height of the element. + min_width: The minimum width of the element. + min_height: The minimum height of the element. + max_width: The maximum width of the element. + max_height: The maximum height of the element. + position: Specifies how the element is position. + top: The top position of the element. + bottom: The bottom position of the element. + left: The left position of the element. + right: The right position of the element. + start: The logical start position of the element, depending on layout direction. + end: The logical end position of the element, depending on layout direction. + z_index: The stacking order for the element + is_hidden: Hides the element. + id: The unique identifier of the element. + UNSAFE_class_name: Set the CSS className for the element. Only use as a last resort. Use style props instead. + UNSAFE_style: Set the inline style for the element. Only use as a last resort. Use style props instead. """ + + children, props = create_props(locals()) return BaseElement(f"deephaven.ui.icons.{name}", *children, **props) diff --git a/plugins/ui/src/deephaven/ui/components/illustrated_message.py b/plugins/ui/src/deephaven/ui/components/illustrated_message.py index 92c625057..ac99d327b 100644 --- a/plugins/ui/src/deephaven/ui/components/illustrated_message.py +++ b/plugins/ui/src/deephaven/ui/components/illustrated_message.py @@ -99,20 +99,21 @@ def illustrated_message( UNSAFE_style: Set the inline style for the element. Only use as a last resort. Use style props instead. Examples: - prompt = ui.illustrated_message( - ui.heading("Enter URL above"), - ui.content("Enter a URL of a CSV above and click 'Load' to load it"), + no_results = ui.illustrated_message( + ui.heading("No Results"), + ui.content("Try another search"), ) warning = ui.illustrated_message( ui.icon("vsWarning"), - ui.heading("Warning"), - ui.content("This is a warning message."), + ui.heading("Invalid input"), + ui.content("No special characters allowed."), ) error_message = ui.illustrated_message( - ui.icon("vsWarning", size="XXL", margin_bottom="size-10"), - ui.heading("Invalid Input"), - ui.content("Please enter 'Sym' and 'Exchange' above"), + ui.icon("vsError"), + ui.heading("Access denied"), + ui.content("You do not have permissions to access this page."), ) + """ return component_element( "IllustratedMessage", diff --git a/plugins/ui/src/deephaven/ui/components/panel.py b/plugins/ui/src/deephaven/ui/components/panel.py index acec3dc0a..58fbf2d7c 100644 --- a/plugins/ui/src/deephaven/ui/components/panel.py +++ b/plugins/ui/src/deephaven/ui/components/panel.py @@ -20,7 +20,7 @@ def panel( wrap: Wrap | None = None, justify_content: JustifyContent | None = None, align_content: AlignContent | None = None, - align_items: AlignItems | None = None, + align_items: AlignItems | None = "start", gap: DimensionValue | None = "size-100", column_gap: DimensionValue | None = None, row_gap: DimensionValue | None = None, diff --git a/plugins/ui/src/deephaven/ui/components/tab.py b/plugins/ui/src/deephaven/ui/components/tab.py new file mode 100644 index 000000000..abaf467b1 --- /dev/null +++ b/plugins/ui/src/deephaven/ui/components/tab.py @@ -0,0 +1,30 @@ +from __future__ import annotations +from typing import Any + +from .basic import component_element + +from ..elements import Element + +from ..types import Key + + +def tab( + *children: Any, + title: Any | None = None, + key: Key | None = None, + icon: Element | None = None, + text_value: str | None = None, +): + """ + Tab item implementation for tabs component. + + Args: + *children: Content of the tab item. + title: The title of the tab item. + key: The unique key of the tab item. Defaults to title. + icon: The icon of the tab item. + text_value: The text value of the tab item. + """ + return component_element( + "Tab", *children, title=title, key=key, icon=icon, text_value=text_value + ) diff --git a/plugins/ui/src/deephaven/ui/components/table.py b/plugins/ui/src/deephaven/ui/components/table.py index 443d5d1f3..4319bc3fc 100644 --- a/plugins/ui/src/deephaven/ui/components/table.py +++ b/plugins/ui/src/deephaven/ui/components/table.py @@ -43,21 +43,19 @@ def table( 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 visible row data provided in a dictionary where the + The callback is invoked with the visible 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 visible row data provided in a dictionary where the + The callback is invoked with the visible 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 cell data provided in a dictionary where the - column names are the keys. + The callback is invoked with the cell data. 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 cell data provided in a dictionary where the - column names are the keys. + The callback is invoked with the cell data. on_column_press: The callback function to run when a column is clicked. - The first parameter is the column name. + The callback is invoked with 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. + The callback is invoked with the column name. quick_filters: The quick filters to apply to the table. Dictionary of column name to filter value. show_quick_filters: Whether to show the quick filter bar by default. show_search: Whether to show the search bar by default. diff --git a/plugins/ui/src/deephaven/ui/components/tabs.py b/plugins/ui/src/deephaven/ui/components/tabs.py new file mode 100644 index 000000000..b99a12fc0 --- /dev/null +++ b/plugins/ui/src/deephaven/ui/components/tabs.py @@ -0,0 +1,218 @@ +from __future__ import annotations +from typing import Any, Callable, Iterable, Union + +from .basic import component_element + +from .types import ( + KeyboardActivationType, + Orientation, + AlignSelf, + CSSProperties, + DimensionValue, + JustifySelf, + LayoutFlex, + Position, +) + +from ..types import Key, TabDensity + + +def tabs( + *children: Any, + disabled_keys: Iterable[Key] | None = None, + is_disabled: bool | None = None, + is_quiet: bool | None = None, + is_emphasized: bool | None = None, + density: TabDensity | None = "regular", + keyboard_activation: KeyboardActivationType | None = "automatic", + orientation: Orientation | None = "horizontal", + disallow_empty_selection: bool | None = None, + selected_key: Key | None = None, + default_selected_key: Key | None = None, + on_selection_change: Callable[[Key], None] | None = None, + on_change: Callable[[Key], None] | None = None, + flex: LayoutFlex | None = None, + flex_grow: float | None = 1, + flex_shrink: float | None = None, + flex_basis: DimensionValue | None = None, + align_self: AlignSelf | None = None, + justify_self: JustifySelf | None = None, + order: int | None = None, + grid_area: str | None = None, + grid_row: str | None = None, + grid_column: str | None = None, + grid_row_start: str | None = None, + grid_row_end: str | None = None, + grid_column_start: str | None = None, + grid_column_end: str | None = None, + margin: DimensionValue | None = None, + margin_top: DimensionValue | None = None, + margin_bottom: DimensionValue | None = None, + margin_start: DimensionValue | None = None, + margin_end: DimensionValue | None = None, + margin_x: DimensionValue | None = None, + margin_y: DimensionValue | None = None, + width: DimensionValue | None = None, + height: DimensionValue | None = None, + min_width: DimensionValue | None = None, + min_height: DimensionValue | None = None, + max_width: DimensionValue | None = None, + max_height: DimensionValue | None = None, + position: Position | None = None, + top: DimensionValue | None = None, + bottom: DimensionValue | None = None, + left: DimensionValue | None = None, + right: DimensionValue | None = None, + start: DimensionValue | None = None, + end: DimensionValue | None = None, + z_index: int | None = None, + is_hidden: bool | None = None, + id: str | None = None, + aria_label: str | None = None, + aria_labelled_by: str | None = None, + aria_described_by: str | None = None, + aria_details: str | None = None, + UNSAFE_class_name: str | None = None, + UNSAFE_style: CSSProperties | None = None, +): + """ + Python implementation for the Adobe React Spectrum Tabs component. + https://react-spectrum.adobe.com/react-spectrum/Tabs.html + + Args: + *children: The children of the tabs component outline how the tabs will be created, they can be either: + ui.tab: A tab item that is a shorthand way to create a tab item. + ui.tab_list & ui.tab_panels: A tab list and tab panels allow for more customization when creating tabs. + disabled_keys: The keys of the tabs that are disabled. These tabs cannot be selected, focused, or otherwise interacted with. + is_disabled: Whether the Tabs are disabled. + is_quiet: Whether the tabs are displayed in a quiet style. + is_emphasized: Whether the tabs are displayed in an emphasized style. + density: The amount of space between the tabs. + keyboard_activation: Whether tabs are activated automatically on focus or manually. + orientation: The orientation of the tabs. + disallow_empty_selection: Whether the collection allows empty selection. + selected_key: The currently selected key in the collection (controlled). + default_selected_key: The initial selected key in the collection (uncontrolled). + on_selection_change: Callback for when the selected key changes. + on_change: + Alias of `on_selection_change`. Handler that is called when the selection changes. + flex: When used in a flex layout, specifies how the element will grow or shrink to fit the space available. + flex_grow: When used in a flex layout, specifies how the element will grow to fit the space available. + flex_shrink: When used in a flex layout, specifies how the element will shrink to fit the space available. + flex_basis: When used in a flex layout, specifies the initial main size of the element. + align_self: Overrides the alignItems property of a flex or grid container. + justify_self: Species how the element is justified inside a flex or grid container. + order: The layout order for the element within a flex or grid container. + grid_area: When used in a grid layout specifies, specifies the named grid area that the element should be placed in within the grid. + grid_row: When used in a grid layout, specifies the row the element should be placed in within the grid. + grid_column: When used in a grid layout, specifies the column the element should be placed in within the grid. + grid_row_start: When used in a grid layout, specifies the starting row to span within the grid. + grid_row_end: When used in a grid layout, specifies the ending row to span within the grid. + grid_column_start: When used in a grid layout, specifies the starting column to span within the grid. + grid_column_end: When used in a grid layout, specifies the ending column to span within the grid. + margin: The margin for all four sides of the element. + margin_top: The margin for the top side of the element. + margin_bottom: The margin for the bottom side of the element. + margin_start: The margin for the logical start side of the element, depending on layout direction. + margin_end: The margin for the logical end side of the element, depending on layout direction. + margin_x: The margin for the left and right sides of the element. + margin_y: The margin for the top and bottom sides of the element. + position: Specifies how the element is position. + top: The top position of the element. + bottom: The bottom position of the element. + left: The left position of the element. + right: The right position of the element. + start: The logical start position of the element, depending on layout direction. + end: The logical end position of the element, depending on layout direction. + z_index: The stacking order for the element + is_hidden: Hides the element. + id: The unique identifier of the element. + aria_label: Defines a string value that labels the current element. + aria_labelled_by: Identifies the element (or elements) that labels the current element. + aria_described_by: Identifies the element (or elements) that describes the object. + aria_details: Identifies the element (or elements) that provide a detailed, extended description for the object. + UNSAFE_class_name: Set the CSS className for the element. Only use as a last resort. Use style props instead. + UNSAFE_style: Set the inline style for the element. Only use as a last resort. Use style props instead. + """ + if not children: + raise ValueError("Tabs must have at least one child.") + + tab_children = [ + child for child in children if child.name == "deephaven.ui.spectrum.Tab" + ] + + tab_list_children = [ + child for child in children if child.name == "deephaven.ui.spectrum.TabList" + ] + tab_panels_children = [ + child for child in children if child.name == "deephaven.ui.spectrum.TabPanels" + ] + + tab_list_keys = {list_child.key for list_child in tab_list_children} + tab_panels_keys = {panel_child.key for panel_child in tab_panels_children} + + if tab_list_keys != tab_panels_keys: + raise ValueError("Mismatching keys found between tab list and tab panels.") + + if tab_children and (tab_list_children and tab_panels_children): + raise TypeError("Tabs cannot have both Tab and TabList or TabPanels children.") + + return component_element( + "Tabs", + *children, + disabled_keys=disabled_keys, + is_disabled=is_disabled, + is_quiet=is_quiet, + is_emphasized=is_emphasized, + density=density, + keyboard_activation=keyboard_activation, + orientation=orientation, + disallow_empty_selection=disallow_empty_selection, + selected_key=selected_key, + default_selected_key=default_selected_key, + on_selection_change=on_selection_change, + on_change=on_change, + flex=flex, + flex_grow=flex_grow, + flex_shrink=flex_shrink, + flex_basis=flex_basis, + align_self=align_self, + justify_self=justify_self, + order=order, + grid_area=grid_area, + grid_row=grid_row, + grid_column=grid_column, + grid_row_start=grid_row_start, + grid_row_end=grid_row_end, + grid_column_start=grid_column_start, + grid_column_end=grid_column_end, + margin=margin, + margin_top=margin_top, + margin_bottom=margin_bottom, + margin_start=margin_start, + margin_end=margin_end, + margin_x=margin_x, + margin_y=margin_y, + width=width, + height=height, + min_width=min_width, + min_height=min_height, + max_width=max_width, + max_height=max_height, + position=position, + top=top, + bottom=bottom, + left=left, + right=right, + start=start, + end=end, + z_index=z_index, + is_hidden=is_hidden, + id=id, + aria_label=aria_label, + aria_labelled_by=aria_labelled_by, + aria_described_by=aria_described_by, + aria_details=aria_details, + UNSAFE_class_name=UNSAFE_class_name, + UNSAFE_style=UNSAFE_style, + ) diff --git a/plugins/ui/src/deephaven/ui/components/types/events.py b/plugins/ui/src/deephaven/ui/components/types/events.py index 90d7d7322..45c4c84e9 100644 --- a/plugins/ui/src/deephaven/ui/components/types/events.py +++ b/plugins/ui/src/deephaven/ui/components/types/events.py @@ -114,6 +114,7 @@ class SliderChange(TypedDict): PointerType = Literal["mouse", "touch", "pen", "keyboard", "virtual"] PressEventType = Literal["pressstart", "pressend", "pressup", "press"] TriggerType = Literal["press", "longPress"] +KeyboardActivationType = Literal["automatic", "manual"] StaticColor = Literal["white", "black"] ButtonType = Literal["button", "submit", "reset"] diff --git a/plugins/ui/src/deephaven/ui/components/types/layout.py b/plugins/ui/src/deephaven/ui/components/types/layout.py index 0795b3eaf..a469f100e 100644 --- a/plugins/ui/src/deephaven/ui/components/types/layout.py +++ b/plugins/ui/src/deephaven/ui/components/types/layout.py @@ -160,3 +160,5 @@ "medium", "large", ] +IconSize = Literal["XXS", "XS", "S", "M", "L", "XL", "XXL"] +IconColor = Literal["negative", "notice", "positive", "informative"] diff --git a/plugins/ui/src/deephaven/ui/types/types.py b/plugins/ui/src/deephaven/ui/types/types.py index b027e876b..dd770a023 100644 --- a/plugins/ui/src/deephaven/ui/types/types.py +++ b/plugins/ui/src/deephaven/ui/types/types.py @@ -207,32 +207,10 @@ class SliderChange(TypedDict): SliderChangeCallable = Callable[[SliderChange], None] - -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] +RowDataMap = Dict[ColumnName, RowDataValue] +RowPressCallback = Callable[[RowDataMap], None] +CellPressCallback = Callable[[CellData], None] ColumnPressCallback = Callable[[ColumnName], None] AggregationOperation = Literal[ "COUNT", @@ -303,5 +281,6 @@ class SliderChange(TypedDict): Granularity = Literal["DAY", "HOUR", "MINUTE", "SECOND"] ListViewDensity = Literal["COMPACT", "NORMAL", "SPACIOUS"] ActionGroupDensity = Literal["compact", "regular"] +TabDensity = Literal["compact", "regular"] Dependencies = Union[Tuple[Any], List[Any]] Selection = Sequence[Key] diff --git a/plugins/ui/src/js/package.json b/plugins/ui/src/js/package.json index 71affb24f..3d5cf4120 100644 --- a/plugins/ui/src/js/package.json +++ b/plugins/ui/src/js/package.json @@ -41,27 +41,28 @@ "react-dom": "^17.0.2" }, "dependencies": { - "@deephaven/chart": "^0.84.0", - "@deephaven/components": "^0.84.0", - "@deephaven/dashboard": "^0.84.0", - "@deephaven/dashboard-core-plugins": "^0.84.0", - "@deephaven/grid": "^0.84.0", - "@deephaven/icons": "^0.84.0", - "@deephaven/iris-grid": "^0.84.0", - "@deephaven/jsapi-bootstrap": "^0.84.0", - "@deephaven/jsapi-components": "^0.84.0", + "@deephaven/chart": "^0.85.0", + "@deephaven/components": "^0.85.0", + "@deephaven/dashboard": "^0.85.0", + "@deephaven/dashboard-core-plugins": "^0.85.0", + "@deephaven/golden-layout": "^0.85.0", + "@deephaven/grid": "^0.85.0", + "@deephaven/icons": "^0.85.0", + "@deephaven/iris-grid": "^0.85.0", + "@deephaven/jsapi-bootstrap": "^0.85.0", + "@deephaven/jsapi-components": "^0.85.0", "@deephaven/jsapi-types": "^1.0.0-dev0.35.0", - "@deephaven/log": "^0.84.0", - "@deephaven/plugin": "^0.84.0", - "@deephaven/react-hooks": "^0.84.0", - "@deephaven/redux": "^0.84.0", - "@deephaven/utils": "^0.84.0", + "@deephaven/log": "^0.85.0", + "@deephaven/plugin": "^0.85.0", + "@deephaven/react-hooks": "^0.85.0", + "@deephaven/redux": "^0.85.0", + "@deephaven/utils": "^0.85.0", "@fortawesome/react-fontawesome": "^0.2.0", "@react-types/shared": "^3.22.0", "classnames": "^2.5.1", "json-rpc-2.0": "^1.6.0", - "react-redux": "^7.x", - "shortid": "^2.2.16" + "nanoid": "^5.0.7", + "react-redux": "^7.x" }, "publishConfig": { "access": "public" diff --git a/plugins/ui/src/js/src/DashboardPlugin.tsx b/plugins/ui/src/js/src/DashboardPlugin.tsx index 5bf7417fb..0b22fc62e 100644 --- a/plugins/ui/src/js/src/DashboardPlugin.tsx +++ b/plugins/ui/src/js/src/DashboardPlugin.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import shortid from 'shortid'; +import { nanoid } from 'nanoid'; import { DashboardPluginComponentProps, LayoutManagerContext, @@ -77,7 +77,7 @@ export function DashboardPlugin( const handleWidgetOpen = useCallback( ({ - widgetId = shortid.generate(), + widgetId = nanoid(), widget, }: { widgetId: string; @@ -119,7 +119,7 @@ export function DashboardPlugin( const handlePanelOpen = useCallback( ({ - panelId: widgetId = shortid.generate(), + panelId: widgetId = nanoid(), widget, }: PanelOpenEventDetail) => { const { type } = widget; diff --git a/plugins/ui/src/js/src/elements/IllustratedMessage.tsx b/plugins/ui/src/js/src/elements/IllustratedMessage.tsx new file mode 100644 index 000000000..ba75de9e4 --- /dev/null +++ b/plugins/ui/src/js/src/elements/IllustratedMessage.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { + IllustratedMessage as DHCIllustratedMessage, + IllustratedMessageProps as DHCIllustratedMessageProps, + Icon, +} from '@deephaven/components'; +import { isElementOfType } from '@deephaven/react-hooks'; + +export function IllustratedMessage( + props: DHCIllustratedMessageProps +): JSX.Element { + const { children, ...otherProps } = props; + + /* eslint-disable-next-line react/jsx-props-no-spreading */ + if (children === undefined) return ; + + const newChildren = React.Children.map(children, element => { + if (isElementOfType(element, Icon) === true) { + const size = element.props.size ?? 'XXL'; + const marginBottom = + element.props.margin ?? + element.props.marginY ?? + element.props.marginBottom ?? + 'size-10'; + + return React.cloneElement(element, { + ...element.props, + size, + marginBottom, + }); + } + + return element; + }); + + return ( + /* eslint-disable-next-line react/jsx-props-no-spreading */ + {newChildren} + ); +} + +export default IllustratedMessage; diff --git a/plugins/ui/src/js/src/elements/RadioGroup.tsx b/plugins/ui/src/js/src/elements/RadioGroup.tsx index b30e41393..4efe804a2 100644 --- a/plugins/ui/src/js/src/elements/RadioGroup.tsx +++ b/plugins/ui/src/js/src/elements/RadioGroup.tsx @@ -2,6 +2,7 @@ import { RadioGroup as DHRadioGroup, RadioGroupProps as DHRadioGroupProps, } from '@deephaven/components'; +// TODO: web-client-ui#2084 Re-export @react-types/shared types import { Orientation } from '@react-types/shared'; import { SerializedFocusEventProps } from './model/SerializedPropTypes'; import { useFocusEventCallback } from './hooks/useFocusEventCallback'; diff --git a/plugins/ui/src/js/src/elements/Tabs.tsx b/plugins/ui/src/js/src/elements/Tabs.tsx new file mode 100644 index 000000000..55c4426b7 --- /dev/null +++ b/plugins/ui/src/js/src/elements/Tabs.tsx @@ -0,0 +1,161 @@ +import React, { Key, ReactElement, useMemo } from 'react'; +import { + Tabs as DHCTabs, + TabsProps, + TabList, + Item, + TabPanelsProps, + Text, + TabListProps, +} from '@deephaven/components'; +import { isElementOfType } from '@deephaven/react-hooks'; +import { ensureArray } from '@deephaven/utils'; +import { TabPanels } from './TabPanels'; + +type TabProps = { + children: ReactElement; + title: string; + key: string | null; + icon?: ReactElement; + textValue?: string; +}; + +type TabComponentProps = TabsProps & { + children: TabChild | TabChild[]; + onChange?: (key: Key) => void; + onSelectionChange?: (key: Key) => void; +}; + +type TabChild = + | ReactElement + | ReactElement, typeof TabList> + | ReactElement, typeof TabPanels>; + +function containsDuplicateKeys(childrenArray: JSX.Element[]) { + const keys = childrenArray.map(child => child.key); + return new Set(keys).size !== keys.length; +} + +/** + * `transformTabsToItems` processes an array of React elements representing tab children, + * mapping them to a collection of `Item` components for the React Spectrum `TabList` and `TabPanels` components. + * + * @param childrenArray An array of React elements, each representing a tab child with props. + * @param data A boolean indicating if the current processing is for a TabList, changing how content is structured within each resulting `Item`. + */ +function transformTabsToItems( + childrenArray: ReactElement[], + isTabList: boolean +) { + const items = childrenArray.map(({ key: propKey, props }) => { + const key = propKey ?? props.title; + const textValue = props.textValue ?? props.title; + let content = props.children; + + if (isTabList) { + if (props.icon) { + content = ( + <> + {props.icon} + {props.title} + + ); + } else { + content = {props.title}; + } + } + return ( + + {content} + + ); + }); + if (containsDuplicateKeys(items)) { + throw new Error('Duplicate keys found in Tab items.'); + } + return items; +} + +export function Tabs(props: TabComponentProps): JSX.Element { + const { + children, + onSelectionChange: onSelectionChangeProp, + onChange, + ...otherTabProps + } = props; + const childrenArray = useMemo(() => ensureArray(children), [children]); + + const onSelectionChange = onSelectionChangeProp ?? onChange; + + const tabPanelsOrLists = childrenArray.filter( + child => + isElementOfType(child, TabList) || isElementOfType(child, TabPanels) + ); + const hasTabPanelsOrLists = tabPanelsOrLists.length > 0; + + const tabItems = childrenArray.filter(child => isElementOfType(child, Item)); + const hasTabItems = tabItems.length > 0; + + const hasUnsupportedChild = + tabPanelsOrLists.length + tabItems.length !== childrenArray.length; + + if (hasTabPanelsOrLists && hasTabItems) { + throw new Error( + 'Cannot declare tabs with ui.tab and ui.tab_list/ui.tab_panels at the same time.' + ); + } + + if (hasUnsupportedChild) { + throw new Error( + 'Unknown child in tabs component. Only use ui.tab or ui.tab_list/ui.tab_panels.' + ); + } + + const tabListChildren = useMemo( + () => + hasTabPanelsOrLists + ? [] + : transformTabsToItems( + childrenArray as unknown as ReactElement[], + true + ), + [hasTabPanelsOrLists, childrenArray] + ); + + const tabPanelsChildren = useMemo( + () => + hasTabPanelsOrLists + ? [] + : transformTabsToItems( + childrenArray as unknown as ReactElement[], + false + ), + [hasTabPanelsOrLists, childrenArray] + ); + + if (hasTabPanelsOrLists) { + return ( + + {children} + + ); + } + + return ( + + {tabListChildren} + {tabPanelsChildren} + + ); +} + +Tabs.displayName = 'Tabs'; +export default Tabs; diff --git a/plugins/ui/src/js/src/elements/UITable/UITable.tsx b/plugins/ui/src/js/src/elements/UITable/UITable.tsx index 4383da4c4..56bb492a8 100644 --- a/plugins/ui/src/js/src/elements/UITable/UITable.tsx +++ b/plugins/ui/src/js/src/elements/UITable/UITable.tsx @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux'; import { DehydratedQuickFilter, IrisGrid, - IrisGridType, + type IrisGridType, type IrisGridContextMenuData, IrisGridModel, IrisGridModelFactory, @@ -118,6 +118,7 @@ export function UITable({ ? ([ new UITableMouseHandler( model, + irisGrid, onCellPress, onCellDoublePress, onColumnPress, diff --git a/plugins/ui/src/js/src/elements/UITable/UITableMouseHandler.ts b/plugins/ui/src/js/src/elements/UITable/UITableMouseHandler.ts index f4a4d14cc..40e39f0f0 100644 --- a/plugins/ui/src/js/src/elements/UITable/UITableMouseHandler.ts +++ b/plugins/ui/src/js/src/elements/UITable/UITableMouseHandler.ts @@ -4,7 +4,11 @@ import { GridPoint, isExpandableGridModel, } from '@deephaven/grid'; -import { IrisGridModel, RowIndex } from '@deephaven/iris-grid'; +import { + IrisGridModel, + type IrisGridType, + RowIndex, +} from '@deephaven/iris-grid'; import { CellData, ColumnIndex, @@ -61,6 +65,8 @@ function getRowDataMap(rowIndex: RowIndex, model: IrisGridModel): RowDataMap { class UITableMouseHandler extends GridMouseHandler { private model: IrisGridModel; + private irisGrid: IrisGridType; + private onCellPress: UITableProps['onCellPress']; private onCellDoublePress: UITableProps['onCellDoublePress']; @@ -75,6 +81,7 @@ class UITableMouseHandler extends GridMouseHandler { constructor( model: IrisGridModel, + irisGrid: IrisGridType, onCellPress: UITableProps['onCellPress'], onCellDoublePress: UITableProps['onCellDoublePress'], onColumnPress: UITableProps['onColumnPress'], @@ -84,6 +91,7 @@ class UITableMouseHandler extends GridMouseHandler { ) { super(890); this.model = model; + this.irisGrid = irisGrid; this.onCellPress = onCellPress; this.onCellDoublePress = onCellDoublePress; this.onColumnPress = onColumnPress; @@ -93,36 +101,49 @@ class UITableMouseHandler extends GridMouseHandler { } 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); + const { column: visibleColumn, row: visibleRow } = gridPoint; + const { model, irisGrid, onCellPress, onRowPress, onColumnPress } = this; + + const modelColumn = irisGrid.getModelColumn(visibleColumn); + const modelRow = irisGrid.getModelRow(visibleRow); + + if (onCellPress != null && modelColumn != null && modelRow != null) { + const cellData = getCellData(modelColumn, modelRow, model); + onCellPress(cellData); } - if (onRowPress != null && row != null) { - const rowData = getRowDataMap(row, model); - onRowPress(row, rowData); + if (onRowPress != null && modelRow != null) { + const rowData = getRowDataMap(modelRow, model); + onRowPress(rowData); } - if (onColumnPress && column != null) { - onColumnPress(model.columns[column].name); + if (onColumnPress && modelColumn != null) { + onColumnPress(model.columns[modelColumn].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); + const { column: visibleColumn, row: visibleRow } = gridPoint; + const { + model, + irisGrid, + onCellDoublePress, + onRowDoublePress, + onColumnDoublePress, + } = this; + + const modelColumn = irisGrid.getModelColumn(visibleColumn); + const modelRow = irisGrid.getModelRow(visibleRow); + + if (onCellDoublePress != null && modelColumn != null && modelRow != null) { + const cellData = getCellData(modelColumn, modelRow, model); + onCellDoublePress(cellData); } - if (onRowDoublePress != null && row != null) { - const rowData = getRowDataMap(row, model); - onRowDoublePress(row, rowData); + if (onRowDoublePress != null && modelRow != null) { + const rowData = getRowDataMap(modelRow, model); + onRowDoublePress(rowData); } - if (onColumnDoublePress && column != null) { - onColumnDoublePress(model.columns[column].name); + if (onColumnDoublePress && modelColumn != null) { + onColumnDoublePress(model.columns[modelColumn].name); } return false; } diff --git a/plugins/ui/src/js/src/elements/UITable/UITableUtils.tsx b/plugins/ui/src/js/src/elements/UITable/UITableUtils.tsx index f72b7da53..abccb9162 100644 --- a/plugins/ui/src/js/src/elements/UITable/UITableUtils.tsx +++ b/plugins/ui/src/js/src/elements/UITable/UITableUtils.tsx @@ -3,7 +3,6 @@ import { ColumnName, DehydratedSort, IrisGridContextMenuData, - RowIndex, } from '@deephaven/iris-grid'; import type { ContextAction, @@ -57,13 +56,10 @@ type ResolvableUIContextItem = export type UITableProps = { table: dh.WidgetExportedObject; - 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; + onCellPress?: (data: CellData) => void; + onCellDoublePress?: (data: CellData) => void; + onRowPress?: (rowData: RowDataMap) => void; + onRowDoublePress?: (rowData: RowDataMap) => void; onColumnPress?: (columnName: ColumnName) => void; onColumnDoublePress?: (columnName: ColumnName) => void; alwaysFetchColumns?: string[]; diff --git a/plugins/ui/src/js/src/elements/hooks/useListViewProps.ts b/plugins/ui/src/js/src/elements/hooks/useListViewProps.ts index 415dd1035..c88c1e12c 100644 --- a/plugins/ui/src/js/src/elements/hooks/useListViewProps.ts +++ b/plugins/ui/src/js/src/elements/hooks/useListViewProps.ts @@ -1,8 +1,9 @@ import { ReactElement } from 'react'; +// TODO: web-client-ui#2084 Re-export @react-types/shared types import type { SelectionMode } from '@react-types/shared'; import { ListViewProps as DHListViewProps } from '@deephaven/components'; import { ListViewProps as DHListViewJSApiProps } from '@deephaven/jsapi-components'; -import { ObjectViewProps } from '../ObjectView'; +import ObjectView, { ObjectViewProps } from '../ObjectView'; import { SerializedSelectionProps, useSelectionProps, @@ -11,7 +12,7 @@ import { type Density = Required['density']; type WrappedDHListViewJSApiProps = Omit & { - children: ReactElement; + children: ReactElement; }; type WrappedDHListViewProps = Omit< diff --git a/plugins/ui/src/js/src/elements/hooks/usePickerProps.ts b/plugins/ui/src/js/src/elements/hooks/usePickerProps.ts index 55666d769..a1f0531b0 100644 --- a/plugins/ui/src/js/src/elements/hooks/usePickerProps.ts +++ b/plugins/ui/src/js/src/elements/hooks/usePickerProps.ts @@ -1,7 +1,7 @@ import { PickerProps as DHPickerProps } from '@deephaven/components'; import { PickerProps as DHPickerJSApiProps } from '@deephaven/jsapi-components'; import { ReactElement } from 'react'; -import { ObjectViewProps } from '../ObjectView'; +import ObjectView, { ObjectViewProps } from '../ObjectView'; import { SerializedFocusEventCallback, useFocusEventCallback, @@ -26,7 +26,7 @@ export interface SerializedPickerEventProps { } type WrappedDHPickerJSApiProps = Omit & { - children: ReactElement; + children: ReactElement; }; export type SerializedPickerProps = ( diff --git a/plugins/ui/src/js/src/elements/hooks/usePressEventCallback.ts b/plugins/ui/src/js/src/elements/hooks/usePressEventCallback.ts index 1aff194c5..023ac0e2f 100644 --- a/plugins/ui/src/js/src/elements/hooks/usePressEventCallback.ts +++ b/plugins/ui/src/js/src/elements/hooks/usePressEventCallback.ts @@ -1,4 +1,5 @@ import { useCallback } from 'react'; +// TODO: web-client-ui#2084 Re-export @react-types/shared types import { PressEvent } from '@react-types/shared'; import { getTargetName } from '../utils'; diff --git a/plugins/ui/src/js/src/elements/hooks/useSelectionProps.ts b/plugins/ui/src/js/src/elements/hooks/useSelectionProps.ts index cd5a91634..f815c6448 100644 --- a/plugins/ui/src/js/src/elements/hooks/useSelectionProps.ts +++ b/plugins/ui/src/js/src/elements/hooks/useSelectionProps.ts @@ -1,4 +1,5 @@ import { useCallback } from 'react'; +// TODO: web-client-ui#2084 Re-export @react-types/shared types import type { SelectionMode } from '@react-types/shared'; import type { ItemKey, ItemSelection } from '@deephaven/components'; diff --git a/plugins/ui/src/js/src/elements/index.ts b/plugins/ui/src/js/src/elements/index.ts index b91c6c9ba..5527dbc1d 100644 --- a/plugins/ui/src/js/src/elements/index.ts +++ b/plugins/ui/src/js/src/elements/index.ts @@ -5,6 +5,7 @@ export * from './Form'; export * from './hooks'; export * from './HTMLElementView'; export * from './IconElementView'; +export * from './IllustratedMessage'; export * from './ListView'; export * from './model'; export * from './ObjectView'; @@ -13,6 +14,7 @@ export * from './Radio'; export * from './RadioGroup'; export * from './RangeSlider'; export * from './Slider'; +export * from './Tabs'; export * from './TabPanels'; export * from './TextField'; export * from './UITable/UITable'; diff --git a/plugins/ui/src/js/src/elements/model/ElementConstants.ts b/plugins/ui/src/js/src/elements/model/ElementConstants.ts index 22d4610ce..94f2de96e 100644 --- a/plugins/ui/src/js/src/elements/model/ElementConstants.ts +++ b/plugins/ui/src/js/src/elements/model/ElementConstants.ts @@ -52,6 +52,7 @@ export const ELEMENT_NAME = { tabList: uiComponentName('TabList'), tabPanels: uiComponentName('TabPanels'), tabs: uiComponentName('Tabs'), + tab: uiComponentName('Tab'), text: uiComponentName('Text'), textField: uiComponentName('TextField'), toggleButton: uiComponentName('ToggleButton'), diff --git a/plugins/ui/src/js/src/layout/ReactPanel.tsx b/plugins/ui/src/js/src/layout/ReactPanel.tsx index cf3fdebd0..184ffb536 100644 --- a/plugins/ui/src/js/src/layout/ReactPanel.tsx +++ b/plugins/ui/src/js/src/layout/ReactPanel.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import ReactDOM from 'react-dom'; -import shortid from 'shortid'; +import { nanoid } from 'nanoid'; import { LayoutUtils, PanelEvent, @@ -65,7 +65,7 @@ function ReactPanel({ wrap, justifyContent, alignContent, - alignItems, + alignItems = 'start', gap = 'size-100', rowGap, columnGap, @@ -94,7 +94,7 @@ function ReactPanel({ // We want to regenerate the key every time the metadata changes, so that the portal is re-rendered // eslint-disable-next-line react-hooks/exhaustive-deps - const contentKey = useMemo(() => shortid.generate(), [metadata]); + const contentKey = useMemo(() => nanoid(), [metadata]); const parent = useParentItem(); const { eventHub } = layoutManager; diff --git a/plugins/ui/src/js/src/widget/DocumentHandler.tsx b/plugins/ui/src/js/src/widget/DocumentHandler.tsx index f0ae8a48e..7d4f3c400 100644 --- a/plugins/ui/src/js/src/widget/DocumentHandler.tsx +++ b/plugins/ui/src/js/src/widget/DocumentHandler.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useMemo, useRef, useState } from 'react'; -import shortid from 'shortid'; +import { nanoid } from 'nanoid'; import { WidgetDescriptor } from '@deephaven/dashboard'; import Log from '@deephaven/log'; import { EMPTY_FUNCTION } from '@deephaven/utils'; @@ -101,7 +101,7 @@ function DocumentHandler({ // If there are no more known IDs, generate a new one. // This can happen if the document hasn't been opened before, or if it's rehydrated and a new panel is added. // Note that if the order of panels changes, the worst case scenario is that panels appear in the wrong location in the layout. - const panelId = widgetData.panelIds?.[panelIdIndex.current] ?? shortid(); + const panelId = widgetData.panelIds?.[panelIdIndex.current] ?? nanoid(); panelIdIndex.current += 1; return panelId; }, [widgetData]); diff --git a/plugins/ui/src/js/src/widget/WidgetUtils.tsx b/plugins/ui/src/js/src/widget/WidgetUtils.tsx index ebec26892..595758e60 100644 --- a/plugins/ui/src/js/src/widget/WidgetUtils.tsx +++ b/plugins/ui/src/js/src/widget/WidgetUtils.tsx @@ -13,7 +13,6 @@ import { Flex, Grid, Heading, - IllustratedMessage, Item, ListActionGroup, ListActionMenu, @@ -21,7 +20,6 @@ import { Section, Switch, TabList, - Tabs, Text, ToggleButton, View, @@ -53,6 +51,7 @@ import { ActionGroup, Button, Form, + IllustratedMessage, ListView, Picker, Radio, @@ -62,6 +61,7 @@ import { TabPanels, TextField, UITable, + Tabs, } from '../elements'; /** @@ -119,6 +119,7 @@ export const elementComponentMap = { [ELEMENT_NAME.switch]: Switch, [ELEMENT_NAME.tabList]: TabList, [ELEMENT_NAME.tabPanels]: TabPanels, + [ELEMENT_NAME.tab]: Item, [ELEMENT_NAME.tabs]: Tabs, [ELEMENT_NAME.text]: Text, [ELEMENT_NAME.textField]: TextField, diff --git a/sphinx_ext/.gitignore b/sphinx_ext/.gitignore new file mode 100644 index 000000000..ba0430d26 --- /dev/null +++ b/sphinx_ext/.gitignore @@ -0,0 +1 @@ +__pycache__/ \ No newline at end of file diff --git a/sphinx_ext/deephaven_autodoc.py b/sphinx_ext/deephaven_autodoc.py new file mode 100644 index 000000000..2ab1aa75f --- /dev/null +++ b/sphinx_ext/deephaven_autodoc.py @@ -0,0 +1,316 @@ +from __future__ import annotations + +import re +import json +import sys +from typing import TypedDict, Union, List, Dict + +if sys.version_info < (3, 11): + from typing_extensions import NotRequired +else: + from typing import NotRequired + +import docutils.nodes +import sphinx.addnodes +from sphinx.ext.autodoc.directive import AutodocDirective + +from sphinx.application import Sphinx + + +class ParamData(TypedDict): + name: str + type: str + description: str + default: NotRequired[str | None] + + +Params = List[ParamData] +ParamDefaults = Dict[str, str] + + +class FunctionMetadata(TypedDict): + module_name: str + name: str + + +class SignatureData(TypedDict): + parameters: Params + return_description: str + return_type: str + module_name: str + name: str + description: str + + +SignatureValue = Union[str, Params] + + +def extract_parameter_defaults( + node: sphinx.addnodes.desc_parameterlist, +) -> ParamDefaults: + """ + Extract the default values for the parameters from the parameter list + + Args: + node: The node to extract the defaults from + + Returns: + The parameter defaults + """ + defaults = {} + for child in node.children: + params = child.astext().split("=") + if len(params) == 2: + defaults[params[0]] = params[1] + # otherwise, no default value - do not add it because None is not the same as no default + return defaults + + +def extract_signature_data( + node: sphinx.addnodes.desc_signature, +) -> tuple[FunctionMetadata, ParamDefaults]: + """ + Extract the signature data from the signature node + + Args: + node: The node to extract the signature data from + + Returns: + The function metadata and the parameter defaults + """ + result = {} + param_defaults = {} + for child in node.children: + if isinstance(child, sphinx.addnodes.desc_addname): + result["module_name"] = child.astext() + elif isinstance(child, sphinx.addnodes.desc_name): + result["name"] = child.astext() + elif isinstance(child, sphinx.addnodes.desc_parameterlist): + param_defaults = extract_parameter_defaults(child) + return FunctionMetadata(**result), param_defaults + + +def extract_list_item(node: docutils.nodes.list_item) -> ParamData: + """ + Extract the param data from a list item + + Args: + node: The node to extract the param data from + + Returns: + The param data + """ + field = node.astext().replace("\n", " ") + try: + match = re.match(r"(.+) \((.*)\) -- (.+)", field) + if match is None: + raise ValueError(f"Could not match {field} to extract param data") + matched = match.groups() + except AttributeError: + raise ValueError(f"Could not match {field}") + return ParamData(name=matched[0], type=matched[1], description=matched[2]) + + +def extract_list_items(node: docutils.nodes.bullet_list) -> Params: + """ + Extract the param data from a list of items + + Args: + node: The node to extract the param data from + + Returns: + The param data + """ + return list(map(extract_list_item, node.children)) + + +def extract_field_body(node: docutils.nodes.field_body) -> SignatureValue: + """ + Extract the body of a field node + If a list, extract the list items + If a paragraph, extract the text + + Args: + node: The node to extract the body from + + Returns: + The extracted body + """ + # There should only be one child, a paragraph or a list + child = node.children[0] + if isinstance(child, docutils.nodes.paragraph): + return node.astext().replace("\n", " ") + elif isinstance(child, docutils.nodes.bullet_list): + return extract_list_items(child) + raise ValueError(f"Could not extract field body from {node}") + + +def extract_field(node: docutils.nodes.field) -> dict[str, SignatureValue]: + """ + Extract the field data from a field node + + Args: + node: The node to extract the field data from + + Returns: + The extracted field data + """ + name = None + body = None + for node in node.children: + if isinstance(node, docutils.nodes.field_name): + name = node.astext() + elif isinstance(node, docutils.nodes.field_body): + body = extract_field_body(node) + if name is None or body is None: + raise ValueError(f"Could not extract field data from {node}") + return {name: body} + + +def extract_field_list(node: docutils.nodes.field_list) -> dict[str, SignatureValue]: + """ + Extract the field data from a field list node + + Args: + node: The node to extract the field data from + + Returns: + The extracted field data + """ + result = {} + for node in node.children: + if isinstance(node, docutils.nodes.field): + result.update(extract_field(node)) + return result + + +def extract_content_data( + node: sphinx.addnodes.desc_content, +) -> dict[str, SignatureValue]: + """ + Extract the content data from a content node + Children are either field lists or paragraphs + Field lists contain the parameter data + Paragraphs are the description + + Args: + node: The node to extract the content data from + + Returns: + The extracted content data + """ + result = {} + for child_node in node.children: + if isinstance(child_node, docutils.nodes.field_list): + result.update(extract_field_list(child_node)) + elif isinstance(child_node, docutils.nodes.paragraph): + result["description"] = child_node.astext().replace("\n", " ") + + return result + + +def attach_parameter_defaults(params: Params, param_defaults: ParamDefaults) -> None: + """ + Attach the parameter defaults to the parameters + + Args: + params: The parameters to attach the defaults to + param_defaults: The defaults to attach + """ + for param in params: + if "name" in param and (name := param["name"]) in param_defaults: + param["default"] = param_defaults[name] + + +def extract_desc_data(node: sphinx.addnodes.desc) -> SignatureData: + """ + Extract the content of the description. + Parameter defaults are extracted from the description signature + + Args: + node: The node to extract the data from + + Returns: + The extracted data + """ + result = {} + param_defaults = {} + for child_node in node.children: + if isinstance(child_node, sphinx.addnodes.desc_signature): + signature_results, param_defaults = extract_signature_data(child_node) + result.update(signature_results) + elif isinstance(child_node, sphinx.addnodes.desc_content): + result.update(extract_content_data(child_node)) + # map all to lowercase for consistency + result["parameters"] = result.pop("Parameters") + result["return_description"] = result.pop("Returns") + result["return_type"] = result.pop("Return type") + + attach_parameter_defaults(result["parameters"], param_defaults) + + return SignatureData(**result) + + +def to_mdx(node: sphinx.addnodes.desc) -> docutils.nodes.comment: + """ + Convert the provided description node to a node that is a mdx component + + Args: + node: The node to convert + + Returns: + The resulting component + """ + result = extract_desc_data(node) + + dat = json.dumps(result) + + param_table = f"" + + # This is a little hacky, but this way the markdown renderer will not escape the special characters + # such as * and \. The comment markers will be removed by make_docs.py. + return docutils.nodes.comment("", "", docutils.nodes.raw("", param_table)) + + +class DeephavenAutodoc(AutodocDirective): + def __init__(self, *args, **kwargs): + # this is mostly just passthrough, but set the name to autofunction so it is processed correctly + # by sphinx autodoc and other extensions before we extract the data + super().__init__(*args, **kwargs) + self.name = "autofunction" + + def run(self) -> list[docutils.nodes.TextElement]: + """ + Create the mdx components for the autodoc directive. + + Returns: + The mdx components. + """ + nodes = super().run() + + new_data = [] + + for node in nodes: + if isinstance(node, sphinx.addnodes.desc): + new_data.append(to_mdx(node)) + return new_data + + +def setup(app: Sphinx): + """ + Setup the deephaven autodoc extension + Adds the deephaven autodoc directive to the app + + Args: + app: The Sphinx application + + Returns: + The metadata for the extension + """ + app.add_directive("dhautofunction", DeephavenAutodoc) + + return { + "version": "0.1", + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/templates/widget/{{ cookiecutter.python_project_name }}/src/js/package-lock.json b/templates/widget/{{ cookiecutter.python_project_name }}/src/js/package-lock.json index 9f649285e..b67c4267d 100644 --- a/templates/widget/{{ cookiecutter.python_project_name }}/src/js/package-lock.json +++ b/templates/widget/{{ cookiecutter.python_project_name }}/src/js/package-lock.json @@ -177,7 +177,7 @@ "react-transition-group": "^4.4.2", "react-virtualized-auto-sizer": "1.0.6", "react-window": "^1.8.6", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=10" @@ -213,7 +213,7 @@ "popper.js": "^1.16.1", "prop-types": "^15.7.2", "shell-quote": "^1.7.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=16" @@ -238,7 +238,7 @@ "lodash.ismatch": "^4.1.1", "lodash.throttle": "^4.1.1", "prop-types": "^15.7.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=16" @@ -336,7 +336,7 @@ "prop-types": "^15.7.2", "react-beautiful-dnd": "^13.1.0", "react-transition-group": "^4.4.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=10" @@ -381,7 +381,7 @@ "@deephaven/log": "^0.58.0", "@deephaven/utils": "^0.58.0", "lodash.clamp": "^4.0.3", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=16" @@ -429,7 +429,7 @@ "@deephaven/log": "^0.58.0", "@deephaven/utils": "^0.58.0", "lodash.debounce": "^4.0.8", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=16" @@ -6898,15 +6898,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/shortid": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", - "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dependencies": { - "nanoid": "^2.1.0" - } - }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -7478,7 +7469,7 @@ "react-transition-group": "^4.4.2", "react-virtualized-auto-sizer": "1.0.6", "react-window": "^1.8.6", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/console": { @@ -7507,7 +7498,7 @@ "popper.js": "^1.16.1", "prop-types": "^15.7.2", "shell-quote": "^1.7.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/dashboard": { @@ -7525,7 +7516,7 @@ "lodash.ismatch": "^4.1.1", "lodash.throttle": "^4.1.1", "prop-types": "^15.7.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/filters": { @@ -7597,7 +7588,7 @@ "prop-types": "^15.7.2", "react-beautiful-dnd": "^13.1.0", "react-transition-group": "^4.4.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/jsapi-bootstrap": { @@ -7626,7 +7617,7 @@ "@deephaven/log": "^0.58.0", "@deephaven/utils": "^0.58.0", "lodash.clamp": "^4.0.3", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/log": { @@ -7662,7 +7653,7 @@ "@deephaven/log": "^0.58.0", "@deephaven/utils": "^0.58.0", "lodash.debounce": "^4.0.8", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/redux": { @@ -12683,14 +12674,6 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" }, - "shortid": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", - "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", - "requires": { - "nanoid": "^2.1.0" - } - }, "side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", diff --git a/templates/widget/{{ cookiecutter.python_project_name }}/src/js/src/package-lock.json b/templates/widget/{{ cookiecutter.python_project_name }}/src/js/src/package-lock.json index 33d1c1aae..8d4b53f88 100644 --- a/templates/widget/{{ cookiecutter.python_project_name }}/src/js/src/package-lock.json +++ b/templates/widget/{{ cookiecutter.python_project_name }}/src/js/src/package-lock.json @@ -16,7 +16,7 @@ "@deephaven/jsapi-types": "^0.58.0", "@deephaven/log": "^0.58.0", "@deephaven/plugin": "^0.58.0", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "devDependencies": { "@deephaven/tsconfig": "^0.72.0", @@ -175,7 +175,7 @@ "react-transition-group": "^4.4.2", "react-virtualized-auto-sizer": "1.0.6", "react-window": "^1.8.6", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=10" @@ -211,7 +211,7 @@ "popper.js": "^1.16.1", "prop-types": "^15.7.2", "shell-quote": "^1.7.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=16" @@ -236,7 +236,7 @@ "lodash.ismatch": "^4.1.1", "lodash.throttle": "^4.1.1", "prop-types": "^15.7.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=16" @@ -334,7 +334,7 @@ "prop-types": "^15.7.2", "react-beautiful-dnd": "^13.1.0", "react-transition-group": "^4.4.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=10" @@ -379,7 +379,7 @@ "@deephaven/log": "^0.58.0", "@deephaven/utils": "^0.58.0", "lodash.clamp": "^4.0.3", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=16" @@ -427,7 +427,7 @@ "@deephaven/log": "^0.58.0", "@deephaven/utils": "^0.58.0", "lodash.debounce": "^4.0.8", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" }, "engines": { "node": ">=16" @@ -6896,15 +6896,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/shortid": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", - "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dependencies": { - "nanoid": "^2.1.0" - } - }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -7476,7 +7467,7 @@ "react-transition-group": "^4.4.2", "react-virtualized-auto-sizer": "1.0.6", "react-window": "^1.8.6", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/console": { @@ -7505,7 +7496,7 @@ "popper.js": "^1.16.1", "prop-types": "^15.7.2", "shell-quote": "^1.7.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/dashboard": { @@ -7523,7 +7514,7 @@ "lodash.ismatch": "^4.1.1", "lodash.throttle": "^4.1.1", "prop-types": "^15.7.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/filters": { @@ -7595,7 +7586,7 @@ "prop-types": "^15.7.2", "react-beautiful-dnd": "^13.1.0", "react-transition-group": "^4.4.2", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/jsapi-bootstrap": { @@ -7624,7 +7615,7 @@ "@deephaven/log": "^0.58.0", "@deephaven/utils": "^0.58.0", "lodash.clamp": "^4.0.3", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/log": { @@ -7660,7 +7651,7 @@ "@deephaven/log": "^0.58.0", "@deephaven/utils": "^0.58.0", "lodash.debounce": "^4.0.8", - "shortid": "^2.2.16" + "nanoid": "^5.0.7" } }, "@deephaven/redux": { @@ -12681,14 +12672,6 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" }, - "shortid": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", - "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", - "requires": { - "nanoid": "^2.1.0" - } - }, "side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", diff --git a/tests/app.d/ui_render_all.py b/tests/app.d/ui_render_all.py index 3d138a3c5..c35906623 100644 --- a/tests/app.d/ui_render_all.py +++ b/tests/app.d/ui_render_all.py @@ -64,7 +64,11 @@ def ui_components(): ui.heading("Heading"), ui.icon("vsSymbolMisc"), # TODO: #526 ui.icon_wrapper("TODO: fix this"), - ui.illustrated_message(ui.icon("vsSymbolMisc"), "Illustrated Message"), + ui.illustrated_message( + ui.icon("vsWarning"), + ui.heading("Warning"), + ui.content("This is a warning message."), + ), ui.list_view( _item_table_source_with_action_group, aria_label="List View - List action group", @@ -130,7 +134,12 @@ def ui_html_elements(): ui.stack( ui.panel( ui.table(_column_types), - ui.grid(_my_components, _my_html_elements, columns=["1fr", "1fr", "1fr"]), + ui.grid( + _my_components, + _my_html_elements, + columns=["1fr", "1fr", "1fr"], + width="100%", + ), title="Panel B", ), ) diff --git a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-chromium-linux.png b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-chromium-linux.png index 497c29423..9cf9ed48f 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-chromium-linux.png and b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-chromium-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-firefox-linux.png b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-firefox-linux.png index 84b32377c..a317fac6e 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-firefox-linux.png and b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-firefox-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-webkit-linux.png b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-webkit-linux.png index 456fb28df..8c9f65732 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-webkit-linux.png and b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-webkit-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-loads-1-chromium-linux.png b/tests/ui.spec.ts-snapshots/UI-loads-1-chromium-linux.png index 44c520c36..53b7b52f9 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-loads-1-chromium-linux.png and b/tests/ui.spec.ts-snapshots/UI-loads-1-chromium-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-loads-1-firefox-linux.png b/tests/ui.spec.ts-snapshots/UI-loads-1-firefox-linux.png index 5fae88d85..c47db947b 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-loads-1-firefox-linux.png and b/tests/ui.spec.ts-snapshots/UI-loads-1-firefox-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-loads-1-webkit-linux.png b/tests/ui.spec.ts-snapshots/UI-loads-1-webkit-linux.png index 813549a39..6642779f3 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-loads-1-webkit-linux.png and b/tests/ui.spec.ts-snapshots/UI-loads-1-webkit-linux.png differ diff --git a/tools/update-dh-packages.mjs b/tools/update-dh-packages.mjs index a7c1b5bef..3266301d1 100644 --- a/tools/update-dh-packages.mjs +++ b/tools/update-dh-packages.mjs @@ -45,22 +45,12 @@ const { dependencies = {}, devDependencies = {} } = JSON.parse( const dhPackageNames = [ ...new Set( [...Object.keys(dependencies), ...Object.keys(devDependencies)].filter( - name => name.startsWith('@deephaven') + // Don't include jsapi-types, that is on a different cadence, with the deephaven-core version + name => name !== '@deephaven/jsapi-types' && name.startsWith('@deephaven') ) ), ]; -const dhPackageUpdates = new Map( - dhPackageNames.map(name => [ - name, - // If targetVersionOverride is set, use it for all packages except for - // `@deephaven/jsapi-types` since it has it's own versioning cadence. - targetVersionOverride == null || name === '@deephaven/jsapi-types' - ? targetVersionDefault - : targetVersionOverride, - ]) -); - if (dhPackageNames.length === 0) { console.log( 'No @deephaven packages found in dependencies or devDependencies.' @@ -68,6 +58,13 @@ if (dhPackageNames.length === 0) { process.exit(0); } +const dhPackageUpdates = new Map( + dhPackageNames.map(name => [ + name, + targetVersionOverride ?? targetVersionDefault, + ]) +); + console.log('Updating packages:', dhPackageUpdates); const cmd = `npm i --save ${[...dhPackageUpdates.entries()]