@deephaven/jsapi-components 0.43.0 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/ColumnNameError.js +11 -0
  2. package/dist/ColumnNameError.js.map +1 -0
  3. package/dist/HookTestUtils.js +16 -0
  4. package/dist/HookTestUtils.js.map +1 -0
  5. package/dist/RefreshTokenBootstrap.js +38 -0
  6. package/dist/RefreshTokenBootstrap.js.map +1 -0
  7. package/dist/RefreshTokenUtils.js +44 -0
  8. package/dist/RefreshTokenUtils.js.map +1 -0
  9. package/dist/TableDisconnectError.js +11 -0
  10. package/dist/TableDisconnectError.js.map +1 -0
  11. package/dist/TableInput.css +14 -0
  12. package/dist/TableInput.css.map +1 -0
  13. package/dist/TableInput.js +216 -0
  14. package/dist/TableInput.js.map +1 -0
  15. package/dist/index.js +18 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/useBroadcastChannel.js +33 -0
  18. package/dist/useBroadcastChannel.js.map +1 -0
  19. package/dist/useBroadcastLoginListener.js +15 -0
  20. package/dist/useBroadcastLoginListener.js.map +1 -0
  21. package/dist/useDebouncedViewportSearch.js +46 -0
  22. package/dist/useDebouncedViewportSearch.js.map +1 -0
  23. package/dist/useInitializeViewportData.js +62 -0
  24. package/dist/useInitializeViewportData.js.map +1 -0
  25. package/dist/useSelectDistinctTable.js +43 -0
  26. package/dist/useSelectDistinctTable.js.map +1 -0
  27. package/dist/useSetPaddedViewportCallback.js +20 -0
  28. package/dist/useSetPaddedViewportCallback.js.map +1 -0
  29. package/dist/useTable.js +63 -0
  30. package/dist/useTable.js.map +1 -0
  31. package/dist/useTableClose.js +19 -0
  32. package/dist/useTableClose.js.map +1 -0
  33. package/dist/useTableColumn.js +25 -0
  34. package/dist/useTableColumn.js.map +1 -0
  35. package/dist/useTableListener.js +13 -0
  36. package/dist/useTableListener.js.map +1 -0
  37. package/dist/useTableSize.js +20 -0
  38. package/dist/useTableSize.js.map +1 -0
  39. package/dist/useTableUtils.js +12 -0
  40. package/dist/useTableUtils.js.map +1 -0
  41. package/dist/useViewportData.js +55 -0
  42. package/dist/useViewportData.js.map +1 -0
  43. package/package.json +10 -10
@@ -0,0 +1,11 @@
1
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
+ class ColumnNameError extends Error {
5
+ constructor() {
6
+ super(...arguments);
7
+ _defineProperty(this, "isColumnNameError", true);
8
+ }
9
+ }
10
+ export default ColumnNameError;
11
+ //# sourceMappingURL=ColumnNameError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColumnNameError.js","names":["ColumnNameError","Error"],"sources":["../src/ColumnNameError.ts"],"sourcesContent":["class ColumnNameError extends Error {\n isColumnNameError = true;\n}\n\nexport default ColumnNameError;\n"],"mappings":";;;AAAA,MAAMA,eAAe,SAASC,KAAK,CAAC;EAAA;IAAA;IAAA,2CACd,IAAI;EAAA;AAC1B;AAEA,eAAeD,eAAe"}
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { ApiContext } from '@deephaven/jsapi-bootstrap';
3
+ export function makeApiContextWrapper(dh) {
4
+ return function ApiContextWrapper(_ref) {
5
+ var {
6
+ children
7
+ } = _ref;
8
+ return /*#__PURE__*/React.createElement(ApiContext.Provider, {
9
+ value: dh
10
+ }, children);
11
+ };
12
+ }
13
+ export default {
14
+ makeApiContextWrapper
15
+ };
16
+ //# sourceMappingURL=HookTestUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HookTestUtils.js","names":["React","ApiContext","makeApiContextWrapper","dh","ApiContextWrapper","children"],"sources":["../src/HookTestUtils.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport { ApiContext } from '@deephaven/jsapi-bootstrap';\nimport type { dh as DhType } from '@deephaven/jsapi-types';\n\nexport function makeApiContextWrapper(dh: DhType) {\n return function ApiContextWrapper({ children }: { children?: ReactNode }) {\n return <ApiContext.Provider value={dh}>{children}</ApiContext.Provider>;\n };\n}\n\nexport default {\n makeApiContextWrapper,\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAqB,OAAO;AACxC,SAASC,UAAU,QAAQ,4BAA4B;AAGvD,OAAO,SAASC,qBAAqB,CAACC,EAAU,EAAE;EAChD,OAAO,SAASC,iBAAiB,OAAyC;IAAA,IAAxC;MAAEC;IAAmC,CAAC;IACtE,oBAAO,oBAAC,UAAU,CAAC,QAAQ;MAAC,KAAK,EAAEF;IAAG,GAAEE,QAAQ,CAAuB;EACzE,CAAC;AACH;AAEA,eAAe;EACbH;AACF,CAAC"}
@@ -0,0 +1,38 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import { useApi, useClient } from '@deephaven/jsapi-bootstrap';
3
+ import useBroadcastLoginListener from "./useBroadcastLoginListener.js";
4
+ import { readRefreshToken, RefreshTokenContext, storeRefreshToken } from "./RefreshTokenUtils.js";
5
+ /**
6
+ * RefreshTokenBootstrap component. Handles storing and reading the refresh token.
7
+ */
8
+ export function RefreshTokenBootstrap(_ref) {
9
+ var {
10
+ children
11
+ } = _ref;
12
+ var api = useApi();
13
+ var client = useClient();
14
+ var [token, setToken] = useState(readRefreshToken());
15
+ useEffect(function listenForTokenUpdates() {
16
+ var cleanup = client.addEventListener(api.CoreClient.EVENT_REFRESH_TOKEN_UPDATED, event => {
17
+ var {
18
+ detail: newToken
19
+ } = event;
20
+ storeRefreshToken(newToken);
21
+ setToken(newToken);
22
+ });
23
+ return cleanup;
24
+ }, [api, client, token]);
25
+ var onLogin = useCallback(() => {
26
+ setToken(readRefreshToken());
27
+ }, []);
28
+ var onLogout = useCallback(() => {
29
+ storeRefreshToken(null);
30
+ setToken(null);
31
+ }, []);
32
+ useBroadcastLoginListener(onLogin, onLogout);
33
+ return /*#__PURE__*/React.createElement(RefreshTokenContext.Provider, {
34
+ value: token
35
+ }, children);
36
+ }
37
+ export default RefreshTokenBootstrap;
38
+ //# sourceMappingURL=RefreshTokenBootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RefreshTokenBootstrap.js","names":["React","useCallback","useEffect","useState","useApi","useClient","useBroadcastLoginListener","readRefreshToken","RefreshTokenContext","storeRefreshToken","RefreshTokenBootstrap","children","api","client","token","setToken","listenForTokenUpdates","cleanup","addEventListener","CoreClient","EVENT_REFRESH_TOKEN_UPDATED","event","detail","newToken","onLogin","onLogout"],"sources":["../src/RefreshTokenBootstrap.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useState } from 'react';\nimport { useApi, useClient } from '@deephaven/jsapi-bootstrap';\nimport useBroadcastLoginListener from './useBroadcastLoginListener';\nimport {\n readRefreshToken,\n RefreshTokenContext,\n storeRefreshToken,\n} from './RefreshTokenUtils';\n\nexport type RefreshTokenBootstrapProps = {\n /**\n * The children to render wrapped with the RefreshTokenContext.\n */\n children: React.ReactNode;\n};\n\n/**\n * RefreshTokenBootstrap component. Handles storing and reading the refresh token.\n */\nexport function RefreshTokenBootstrap({\n children,\n}: RefreshTokenBootstrapProps) {\n const api = useApi();\n const client = useClient();\n const [token, setToken] = useState(readRefreshToken());\n\n useEffect(\n function listenForTokenUpdates() {\n const cleanup = client.addEventListener(\n api.CoreClient.EVENT_REFRESH_TOKEN_UPDATED,\n (event: CustomEvent) => {\n const { detail: newToken } = event;\n storeRefreshToken(newToken);\n setToken(newToken);\n }\n );\n return cleanup;\n },\n [api, client, token]\n );\n\n const onLogin = useCallback(() => {\n setToken(readRefreshToken());\n }, []);\n\n const onLogout = useCallback(() => {\n storeRefreshToken(null);\n setToken(null);\n }, []);\n\n useBroadcastLoginListener(onLogin, onLogout);\n\n return (\n <RefreshTokenContext.Provider value={token}>\n {children}\n </RefreshTokenContext.Provider>\n );\n}\n\nexport default RefreshTokenBootstrap;\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC/D,SAASC,MAAM,EAAEC,SAAS,QAAQ,4BAA4B;AAAC,OACxDC,yBAAyB;AAAA,SAE9BC,gBAAgB,EAChBC,mBAAmB,EACnBC,iBAAiB;AAUnB;AACA;AACA;AACA,OAAO,SAASC,qBAAqB,OAEN;EAAA,IAFO;IACpCC;EAC0B,CAAC;EAC3B,IAAMC,GAAG,GAAGR,MAAM,EAAE;EACpB,IAAMS,MAAM,GAAGR,SAAS,EAAE;EAC1B,IAAM,CAACS,KAAK,EAAEC,QAAQ,CAAC,GAAGZ,QAAQ,CAACI,gBAAgB,EAAE,CAAC;EAEtDL,SAAS,CACP,SAASc,qBAAqB,GAAG;IAC/B,IAAMC,OAAO,GAAGJ,MAAM,CAACK,gBAAgB,CACrCN,GAAG,CAACO,UAAU,CAACC,2BAA2B,EACzCC,KAAkB,IAAK;MACtB,IAAM;QAAEC,MAAM,EAAEC;MAAS,CAAC,GAAGF,KAAK;MAClCZ,iBAAiB,CAACc,QAAQ,CAAC;MAC3BR,QAAQ,CAACQ,QAAQ,CAAC;IACpB,CAAC,CACF;IACD,OAAON,OAAO;EAChB,CAAC,EACD,CAACL,GAAG,EAAEC,MAAM,EAAEC,KAAK,CAAC,CACrB;EAED,IAAMU,OAAO,GAAGvB,WAAW,CAAC,MAAM;IAChCc,QAAQ,CAACR,gBAAgB,EAAE,CAAC;EAC9B,CAAC,EAAE,EAAE,CAAC;EAEN,IAAMkB,QAAQ,GAAGxB,WAAW,CAAC,MAAM;IACjCQ,iBAAiB,CAAC,IAAI,CAAC;IACvBM,QAAQ,CAAC,IAAI,CAAC;EAChB,CAAC,EAAE,EAAE,CAAC;EAENT,yBAAyB,CAACkB,OAAO,EAAEC,QAAQ,CAAC;EAE5C,oBACE,oBAAC,mBAAmB,CAAC,QAAQ;IAAC,KAAK,EAAEX;EAAM,GACxCH,QAAQ,CACoB;AAEnC;AAEA,eAAeD,qBAAqB"}
@@ -0,0 +1,44 @@
1
+ import { createContext } from 'react';
2
+ import Cookies from 'js-cookie';
3
+ import Log from '@deephaven/log';
4
+ export var REFRESH_TOKEN_KEY = 'io.deephaven.web.client.auth.refreshToken';
5
+ export var RefreshTokenContext = /*#__PURE__*/createContext(null);
6
+ var log = Log.module('RefreshTokenUtils');
7
+
8
+ /**
9
+ * Read the refresh token from our cookie store
10
+ * @returns RefreshToken if it exists, null otherwise
11
+ */
12
+ export function readRefreshToken() {
13
+ var cookieToken = Cookies.get(REFRESH_TOKEN_KEY);
14
+ try {
15
+ if (cookieToken != null) {
16
+ return JSON.parse(cookieToken);
17
+ }
18
+ } catch (e) {
19
+ log.error('Error parsing refresh token', cookieToken, e);
20
+ }
21
+ return null;
22
+ }
23
+
24
+ /**
25
+ * Store the provided refresh token as a cookie
26
+ * @param token The refresh token to store
27
+ */
28
+ export function storeRefreshToken(token) {
29
+ if (token == null) {
30
+ Cookies.remove(REFRESH_TOKEN_KEY);
31
+ return;
32
+ }
33
+ var cookieToken = JSON.stringify({
34
+ bytes: token.bytes,
35
+ expiry: token.expiry
36
+ });
37
+ var expires = new Date(token.expiry);
38
+ Cookies.set(REFRESH_TOKEN_KEY, cookieToken, {
39
+ secure: true,
40
+ sameSite: 'strict',
41
+ expires
42
+ });
43
+ }
44
+ //# sourceMappingURL=RefreshTokenUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RefreshTokenUtils.js","names":["createContext","Cookies","Log","REFRESH_TOKEN_KEY","RefreshTokenContext","log","module","readRefreshToken","cookieToken","get","JSON","parse","e","error","storeRefreshToken","token","remove","stringify","bytes","expiry","expires","Date","set","secure","sameSite"],"sources":["../src/RefreshTokenUtils.ts"],"sourcesContent":["import { createContext } from 'react';\nimport Cookies from 'js-cookie';\nimport Log from '@deephaven/log';\n\nexport const REFRESH_TOKEN_KEY = 'io.deephaven.web.client.auth.refreshToken';\n\nexport type RefreshToken = { bytes: string; expiry: number };\n\nexport const RefreshTokenContext = createContext<RefreshToken | null>(null);\n\nconst log = Log.module('RefreshTokenUtils');\n\n/**\n * Read the refresh token from our cookie store\n * @returns RefreshToken if it exists, null otherwise\n */\nexport function readRefreshToken(): RefreshToken | null {\n const cookieToken = Cookies.get(REFRESH_TOKEN_KEY);\n try {\n if (cookieToken != null) {\n return JSON.parse(cookieToken);\n }\n } catch (e) {\n log.error('Error parsing refresh token', cookieToken, e);\n }\n return null;\n}\n\n/**\n * Store the provided refresh token as a cookie\n * @param token The refresh token to store\n */\nexport function storeRefreshToken(token: RefreshToken | null) {\n if (token == null) {\n Cookies.remove(REFRESH_TOKEN_KEY);\n return;\n }\n\n const cookieToken = JSON.stringify({\n bytes: token.bytes,\n expiry: token.expiry,\n });\n const expires = new Date(token.expiry);\n\n Cookies.set(REFRESH_TOKEN_KEY, cookieToken, {\n secure: true,\n sameSite: 'strict',\n expires,\n });\n}\n"],"mappings":"AAAA,SAASA,aAAa,QAAQ,OAAO;AACrC,OAAOC,OAAO,MAAM,WAAW;AAC/B,OAAOC,GAAG,MAAM,gBAAgB;AAEhC,OAAO,IAAMC,iBAAiB,GAAG,2CAA2C;AAI5E,OAAO,IAAMC,mBAAmB,gBAAGJ,aAAa,CAAsB,IAAI,CAAC;AAE3E,IAAMK,GAAG,GAAGH,GAAG,CAACI,MAAM,CAAC,mBAAmB,CAAC;;AAE3C;AACA;AACA;AACA;AACA,OAAO,SAASC,gBAAgB,GAAwB;EACtD,IAAMC,WAAW,GAAGP,OAAO,CAACQ,GAAG,CAACN,iBAAiB,CAAC;EAClD,IAAI;IACF,IAAIK,WAAW,IAAI,IAAI,EAAE;MACvB,OAAOE,IAAI,CAACC,KAAK,CAACH,WAAW,CAAC;IAChC;EACF,CAAC,CAAC,OAAOI,CAAC,EAAE;IACVP,GAAG,CAACQ,KAAK,CAAC,6BAA6B,EAAEL,WAAW,EAAEI,CAAC,CAAC;EAC1D;EACA,OAAO,IAAI;AACb;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASE,iBAAiB,CAACC,KAA0B,EAAE;EAC5D,IAAIA,KAAK,IAAI,IAAI,EAAE;IACjBd,OAAO,CAACe,MAAM,CAACb,iBAAiB,CAAC;IACjC;EACF;EAEA,IAAMK,WAAW,GAAGE,IAAI,CAACO,SAAS,CAAC;IACjCC,KAAK,EAAEH,KAAK,CAACG,KAAK;IAClBC,MAAM,EAAEJ,KAAK,CAACI;EAChB,CAAC,CAAC;EACF,IAAMC,OAAO,GAAG,IAAIC,IAAI,CAACN,KAAK,CAACI,MAAM,CAAC;EAEtClB,OAAO,CAACqB,GAAG,CAACnB,iBAAiB,EAAEK,WAAW,EAAE;IAC1Ce,MAAM,EAAE,IAAI;IACZC,QAAQ,EAAE,QAAQ;IAClBJ;EACF,CAAC,CAAC;AACJ"}
@@ -0,0 +1,11 @@
1
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
+ class TableDisconnectError extends Error {
5
+ constructor() {
6
+ super(...arguments);
7
+ _defineProperty(this, "isTableDisconnectError", true);
8
+ }
9
+ }
10
+ export default TableDisconnectError;
11
+ //# sourceMappingURL=TableDisconnectError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableDisconnectError.js","names":["TableDisconnectError","Error"],"sources":["../src/TableDisconnectError.ts"],"sourcesContent":["class TableDisconnectError extends Error {\n isTableDisconnectError = true;\n}\n\nexport default TableDisconnectError;\n"],"mappings":";;;AAAA,MAAMA,oBAAoB,SAASC,KAAK,CAAC;EAAA;IAAA;IAAA,gDACd,IAAI;EAAA;AAC/B;AAEA,eAAeD,oBAAoB"}
@@ -0,0 +1,14 @@
1
+ /* stylelint-disable scss/at-import-no-partial-leading-underscore */
2
+ .table-input-container .select-value-list-scroll-pane {
3
+ min-height: 2.4rem;
4
+ max-height: 12rem;
5
+ z-index: 0;
6
+ }
7
+ .table-input-container .meta-row {
8
+ display: flex;
9
+ flex-wrap: wrap;
10
+ justify-content: space-between;
11
+ padding-top: 0.25rem;
12
+ }
13
+
14
+ /*# sourceMappingURL=TableInput.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sourceRoot":"","sources":["../../../node_modules/@deephaven/components/scss/custom.scss","../src/TableInput.scss","../../../node_modules/@deephaven/components/scss/new_variables.scss"],"names":[],"mappings":"AAAA;ACGE;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA,aCVO","file":"TableInput.css","sourcesContent":["/* stylelint-disable scss/at-import-no-partial-leading-underscore */\n// Consumers should be able to resolve bootstrap/ to node_modules/bootstrap\n\n//Make bootstrap functions available for use in overrides\n@import 'bootstrap/scss/_functions.scss';\n@import './bootstrap_overrides.scss';\n\n//_variable imports come after bootstrap default overrides,\n// makes all other variables and mixins from bootstrap available\n/// with just importing customer.scss\n@import 'bootstrap/scss/_variables.scss';\n@import 'bootstrap/scss/_mixins.scss';\n\n//New variables come after imports\n@import './new_variables.scss';\n","@import '@deephaven/components/scss/custom.scss';\n\n.table-input-container {\n .select-value-list-scroll-pane {\n min-height: 2.4rem;\n max-height: 12rem;\n z-index: 0;\n }\n .meta-row {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n padding-top: $spacer-1;\n }\n}\n","//Set of spacer variables from the spacer map\n$spacer-0: map-get($spacers, 0); //0\n$spacer-1: map-get($spacers, 1);\n$spacer-2: map-get($spacers, 2);\n$spacer-3: map-get($spacers, 3);\n$spacer-4: map-get($spacers, 4);\n$spacer-5: map-get($spacers, 5);\n\n//Marching Ants for golden layout dropzone and drag and drop\n//top bottom, left right.\n//create 4 background images that are 50% color 1, 50% color 2 using graidents, two veritical, two horizontal\n//size them to ant-size and thickness\n//position those images along the egdes and make top/bottom repeat-x and left/right repeat-y\n//then offest each of those background positions by ant-size in animation to make them march.\n$ant-size: 8px;\n$ant-thickness: 1px;\n\n@mixin ants-base($color-1: black, $color-2: white) {\n background-image: linear-gradient(to right, $color-2 50%, $color-1 50%),\n linear-gradient(to right, $color-2 50%, $color-1 50%),\n linear-gradient(to bottom, $color-2 50%, $color-1 50%),\n linear-gradient(to bottom, $color-2 50%, $color-1 50%);\n background-size: $ant-size $ant-thickness, $ant-size $ant-thickness,\n $ant-thickness $ant-size, $ant-thickness $ant-size;\n background-position: 0 top, 0 bottom, left 0, right 0;\n background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;\n animation: march 0.5s;\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n}\n\n@mixin drag-stack($pseudo-element) {\n &::#{$pseudo-element} {\n content: ' ';\n background: $primary;\n box-shadow: $box-shadow;\n border-radius: $border-radius;\n position: absolute;\n height: 100%;\n width: 100%;\n @content;\n }\n}\n\n$focus-bg-transparency: 0.12;\n$hover-bg-transparency: 0.14;\n$active-bg-transparency: 0.28;\n$exception-transparency: 0.13;\n"]}
@@ -0,0 +1,216 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
2
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
3
+ import React, { useCallback, useState, useRef, useEffect, useMemo } from 'react';
4
+ import classNames from 'classnames';
5
+ import { LoadingOverlay, SearchInput, SelectValueList } from '@deephaven/components';
6
+ import { PromiseUtils } from '@deephaven/utils';
7
+ import Log from '@deephaven/log';
8
+ import { Formatter, FormatterUtils } from '@deephaven/jsapi-utils';
9
+ import { useApi } from '@deephaven/jsapi-bootstrap';
10
+ import useTableColumn from "./useTableColumn.js";
11
+ import "./TableInput.css";
12
+ var log = Log.module('TableInput');
13
+ var SIZE_LIMIT = 250;
14
+ function TableInput(props) {
15
+ var _table$size, _error$message;
16
+ var {
17
+ className = undefined,
18
+ columnName,
19
+ settings,
20
+ defaultValue = [],
21
+ isInvalid = false,
22
+ onChange = () => false,
23
+ onBlur = () => false,
24
+ table: tablePromise
25
+ } = props;
26
+ var parentRef = useRef(null);
27
+ var dh = useApi();
28
+ var formatter = useMemo(() => {
29
+ var columnFormats = FormatterUtils.getColumnFormats(settings);
30
+ var dateTimeFormatterOptions = FormatterUtils.getDateTimeFormatterOptions(settings);
31
+ var {
32
+ defaultDecimalFormatOptions = {},
33
+ defaultIntegerFormatOptions = {}
34
+ } = settings;
35
+ return new Formatter(dh, columnFormats, dateTimeFormatterOptions, defaultDecimalFormatOptions, defaultIntegerFormatOptions);
36
+ }, [dh, settings]);
37
+ var [searchValue, setSearchValue] = useState('');
38
+ var [selection, setSelection] = useState(new Set(defaultValue));
39
+ var [table, setTable] = useState();
40
+ var listRef = useRef(null);
41
+ var itemCount = Math.min((_table$size = table === null || table === void 0 ? void 0 : table.size) !== null && _table$size !== void 0 ? _table$size : 0, SIZE_LIMIT);
42
+ var {
43
+ column,
44
+ data,
45
+ error
46
+ } = useTableColumn(table, 0, SIZE_LIMIT - 1, columnName);
47
+ var formatValue = useCallback(value => column ? formatter.getFormattedString(value, column.type, column.name) : "".concat(value), [column, formatter]);
48
+ var [items, updatedSelection] = useMemo(() => {
49
+ var removedItems = new Set(selection);
50
+ var result = [];
51
+ if (data == null) {
52
+ // Viewport not initialized
53
+ return [result, null];
54
+ }
55
+ data.forEach(v => {
56
+ var value = "".concat(v);
57
+ var isSelected = selection.has(value);
58
+ if (isSelected) {
59
+ removedItems.delete(value);
60
+ }
61
+ result.push({
62
+ value,
63
+ displayValue: formatValue(v),
64
+ isSelected
65
+ });
66
+ });
67
+ if (removedItems.size > 0) {
68
+ log.debug2('Selection has items that are missing from the viewport');
69
+ var newSelection = new Set(selection);
70
+ Array.from(removedItems).forEach(value => {
71
+ newSelection.delete(value);
72
+ });
73
+ return [result, newSelection];
74
+ }
75
+ return [result, null];
76
+ }, [data, selection, formatValue]);
77
+ useEffect(() => {
78
+ if (updatedSelection !== null) {
79
+ setSelection(updatedSelection);
80
+ onChange(Array.from(updatedSelection));
81
+ }
82
+ }, [onChange, updatedSelection]);
83
+ var initTable = useCallback( /*#__PURE__*/function () {
84
+ var _ref = _asyncToGenerator(function* (promise) {
85
+ try {
86
+ var resolved = yield promise;
87
+ log.debug('Table resolved', resolved);
88
+ setTable(resolved);
89
+ } catch (e) {
90
+ if (PromiseUtils.isCanceled(e)) {
91
+ return;
92
+ }
93
+ log.error(e);
94
+ }
95
+ });
96
+ return function (_x) {
97
+ return _ref.apply(this, arguments);
98
+ };
99
+ }(), []);
100
+ useEffect(() => {
101
+ var cancelablePromise = PromiseUtils.makeCancelable(tablePromise);
102
+ initTable(cancelablePromise);
103
+ return () => {
104
+ log.debug2('Cancel table promise');
105
+ cancelablePromise.cancel();
106
+ };
107
+ }, [tablePromise, initTable]);
108
+
109
+ // Scroll the item matching the input into view
110
+ var handleSearchChange = useCallback(e => {
111
+ var {
112
+ value
113
+ } = e.target;
114
+ setSearchValue(value);
115
+ var index = items.findIndex(item => item.displayValue.includes(value));
116
+ if (index > -1) {
117
+ var _listRef$current;
118
+ log.debug2("Found ".concat(value, " at index ").concat(index));
119
+ (_listRef$current = listRef.current) === null || _listRef$current === void 0 ? void 0 : _listRef$current.scrollIntoView(index);
120
+ } else {
121
+ log.debug2("".concat(value, " not found"));
122
+ }
123
+ }, [items, listRef]);
124
+ var handleSelect = useCallback(index => {
125
+ log.debug('handleSelect', index);
126
+ if (index >= items.length) {
127
+ log.error('Invalid index', index);
128
+ return;
129
+ }
130
+ var selectedValue = items[index].value;
131
+ var newSelection = new Set(selection);
132
+ if (items[index].isSelected) {
133
+ newSelection.delete(selectedValue);
134
+ } else {
135
+ newSelection.add(selectedValue);
136
+ }
137
+ setSelection(newSelection);
138
+ onChange(Array.from(newSelection));
139
+ }, [onChange, items, selection]);
140
+ var handleSelectAll = useCallback(() => {
141
+ var values = items.map(item => item.value);
142
+ var newSelection = new Set(values);
143
+ setSelection(newSelection);
144
+ onChange(values);
145
+ }, [items, onChange]);
146
+ var handleClearSelection = useCallback(() => {
147
+ setSelection(new Set());
148
+ onChange([]);
149
+ }, [onChange]);
150
+ var handleViewportChange = useCallback(() => {
151
+ // no-op
152
+ }, []);
153
+ var handleChildBlur = useCallback(e => {
154
+ var _parentRef$current;
155
+ var {
156
+ relatedTarget
157
+ } = e;
158
+ log.debug('handleChildBlur', relatedTarget, relatedTarget instanceof HTMLElement, parentRef.current, (_parentRef$current = parentRef.current) === null || _parentRef$current === void 0 ? void 0 : _parentRef$current.contains(relatedTarget));
159
+ if (!relatedTarget || parentRef.current && relatedTarget instanceof HTMLElement && !parentRef.current.contains(relatedTarget)) {
160
+ onBlur();
161
+ }
162
+ }, [onBlur]);
163
+ var isEmpty = items.length === 0;
164
+ return /*#__PURE__*/React.createElement("div", {
165
+ ref: parentRef,
166
+ className: classNames('table-input-container d-flex flex-column position-relative', className)
167
+ }, /*#__PURE__*/React.createElement(SearchInput, {
168
+ disabled: !!error || isEmpty,
169
+ value: searchValue,
170
+ placeholder: "Search",
171
+ onChange: handleSearchChange,
172
+ className: "mb-2 d-flex",
173
+ onBlur: handleChildBlur
174
+ }), /*#__PURE__*/React.createElement(SelectValueList, {
175
+ className: "table-input-list",
176
+ disabled: table === undefined || isEmpty,
177
+ isInvalid: isInvalid,
178
+ items: isEmpty ? [{
179
+ value: 'Empty',
180
+ isSelected: false
181
+ }] : items,
182
+ itemCount: itemCount,
183
+ offset: 0,
184
+ onSelect: handleSelect,
185
+ onViewportChange: handleViewportChange,
186
+ ref: listRef,
187
+ onBlur: handleChildBlur
188
+ }), table && /*#__PURE__*/React.createElement("div", {
189
+ className: "meta-row"
190
+ }, /*#__PURE__*/React.createElement("div", {
191
+ className: "d-flex align-items-center text-muted small"
192
+ }, table != null && table.size > itemCount && /*#__PURE__*/React.createElement(React.Fragment, null, "Table is too large, showing the first ", SIZE_LIMIT, " items.")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
193
+ type: "button",
194
+ className: "btn btn-link",
195
+ onBlur: handleChildBlur,
196
+ onClick: handleSelectAll
197
+ }, "Select All"), /*#__PURE__*/React.createElement("button", {
198
+ type: "button",
199
+ className: "btn btn-link mr-a",
200
+ onBlur: handleChildBlur,
201
+ onClick: handleClearSelection
202
+ }, "Clear"))), table == null || error && /*#__PURE__*/React.createElement("div", {
203
+ className: "h-100 w-100 position-absolute"
204
+ }, /*#__PURE__*/React.createElement(LoadingOverlay, {
205
+ isLoaded: table != null,
206
+ isLoading: table == null && error == null,
207
+ errorMessage: (_error$message = error === null || error === void 0 ? void 0 : error.message) !== null && _error$message !== void 0 ? _error$message : null
208
+ })));
209
+ }
210
+ TableInput.displayName = 'TableInput';
211
+ TableInput.defaultProps = {
212
+ isInvalid: false,
213
+ className: undefined
214
+ };
215
+ export default TableInput;
216
+ //# sourceMappingURL=TableInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableInput.js","names":["React","useCallback","useState","useRef","useEffect","useMemo","classNames","LoadingOverlay","SearchInput","SelectValueList","PromiseUtils","Log","Formatter","FormatterUtils","useApi","useTableColumn","log","module","SIZE_LIMIT","TableInput","props","className","undefined","columnName","settings","defaultValue","isInvalid","onChange","onBlur","table","tablePromise","parentRef","dh","formatter","columnFormats","getColumnFormats","dateTimeFormatterOptions","getDateTimeFormatterOptions","defaultDecimalFormatOptions","defaultIntegerFormatOptions","searchValue","setSearchValue","selection","setSelection","Set","setTable","listRef","itemCount","Math","min","size","column","data","error","formatValue","value","getFormattedString","type","name","items","updatedSelection","removedItems","result","forEach","v","isSelected","has","delete","push","displayValue","debug2","newSelection","Array","from","initTable","promise","resolved","debug","e","isCanceled","cancelablePromise","makeCancelable","cancel","handleSearchChange","target","index","findIndex","item","includes","current","scrollIntoView","handleSelect","length","selectedValue","add","handleSelectAll","values","map","handleClearSelection","handleViewportChange","handleChildBlur","relatedTarget","HTMLElement","contains","isEmpty","message","displayName","defaultProps"],"sources":["../src/TableInput.tsx"],"sourcesContent":["import React, {\n useCallback,\n useState,\n useRef,\n useEffect,\n useMemo,\n} from 'react';\nimport classNames from 'classnames';\nimport {\n LoadingOverlay,\n SearchInput,\n SelectValueList,\n} from '@deephaven/components';\nimport type { LongWrapper, Table } from '@deephaven/jsapi-types';\nimport { PromiseUtils } from '@deephaven/utils';\nimport Log from '@deephaven/log';\nimport { Formatter, FormatterUtils, Settings } from '@deephaven/jsapi-utils';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\nimport useTableColumn from './useTableColumn';\n\nimport './TableInput.scss';\n\nconst log = Log.module('TableInput');\n\ntype Value = LongWrapper | string;\n\ninterface SelectValueItem {\n displayValue: string;\n value: Value;\n isSelected: boolean;\n}\n\ninterface TableInputProps {\n className?: string;\n columnName: string;\n settings: Settings;\n defaultValue: Value[];\n isInvalid?: boolean;\n table: Promise<Table>;\n onChange(items: Value[]): void;\n onBlur?: () => void;\n}\n\nconst SIZE_LIMIT = 250;\n\nfunction TableInput(props: TableInputProps): JSX.Element {\n const {\n className = undefined,\n columnName,\n settings,\n defaultValue = [],\n isInvalid = false,\n onChange = () => false,\n onBlur = () => false,\n table: tablePromise,\n } = props;\n const parentRef = useRef<HTMLDivElement>(null);\n const dh = useApi();\n const formatter = useMemo(() => {\n const columnFormats = FormatterUtils.getColumnFormats(settings);\n const dateTimeFormatterOptions = FormatterUtils.getDateTimeFormatterOptions(\n settings\n );\n const {\n defaultDecimalFormatOptions = {},\n defaultIntegerFormatOptions = {},\n } = settings;\n return new Formatter(\n dh,\n columnFormats,\n dateTimeFormatterOptions,\n defaultDecimalFormatOptions,\n defaultIntegerFormatOptions\n );\n }, [dh, settings]);\n const [searchValue, setSearchValue] = useState('');\n const [selection, setSelection] = useState(new Set(defaultValue));\n const [table, setTable] = useState<Table | undefined>();\n const listRef = useRef<SelectValueList<Value>>(null);\n\n const itemCount = Math.min(table?.size ?? 0, SIZE_LIMIT);\n\n const { column, data, error } = useTableColumn(\n table,\n 0,\n SIZE_LIMIT - 1,\n columnName\n );\n\n const formatValue = useCallback(\n value =>\n column\n ? formatter.getFormattedString(value, column.type, column.name)\n : `${value}`,\n [column, formatter]\n );\n\n const [items, updatedSelection] = useMemo(() => {\n const removedItems = new Set(selection);\n const result: SelectValueItem[] = [];\n if (data == null) {\n // Viewport not initialized\n return [result, null];\n }\n (data as Value[]).forEach(v => {\n const value = `${v}`;\n const isSelected = selection.has(value);\n if (isSelected) {\n removedItems.delete(value);\n }\n result.push({\n value,\n displayValue: formatValue(v),\n isSelected,\n });\n });\n\n if (removedItems.size > 0) {\n log.debug2('Selection has items that are missing from the viewport');\n const newSelection = new Set(selection);\n Array.from(removedItems).forEach(value => {\n newSelection.delete(value);\n });\n return [result, newSelection];\n }\n return [result, null];\n }, [data, selection, formatValue]);\n\n useEffect(() => {\n if (updatedSelection !== null) {\n setSelection(updatedSelection);\n onChange(Array.from(updatedSelection));\n }\n }, [onChange, updatedSelection]);\n\n const initTable = useCallback(async promise => {\n try {\n const resolved = await promise;\n log.debug('Table resolved', resolved);\n setTable(resolved);\n } catch (e) {\n if (PromiseUtils.isCanceled(e)) {\n return;\n }\n log.error(e);\n }\n }, []);\n\n useEffect(() => {\n const cancelablePromise = PromiseUtils.makeCancelable(tablePromise);\n initTable(cancelablePromise);\n return () => {\n log.debug2('Cancel table promise');\n cancelablePromise.cancel();\n };\n }, [tablePromise, initTable]);\n\n // Scroll the item matching the input into view\n const handleSearchChange = useCallback(\n e => {\n const { value } = e.target;\n setSearchValue(value);\n const index = items.findIndex(item => item.displayValue.includes(value));\n if (index > -1) {\n log.debug2(`Found ${value} at index ${index}`);\n listRef.current?.scrollIntoView(index);\n } else {\n log.debug2(`${value} not found`);\n }\n },\n [items, listRef]\n );\n\n const handleSelect = useCallback(\n index => {\n log.debug('handleSelect', index);\n if (index >= items.length) {\n log.error('Invalid index', index);\n return;\n }\n const selectedValue = items[index].value;\n const newSelection = new Set(selection);\n if (items[index].isSelected) {\n newSelection.delete(selectedValue);\n } else {\n newSelection.add(selectedValue);\n }\n setSelection(newSelection);\n onChange(Array.from(newSelection));\n },\n [onChange, items, selection]\n );\n\n const handleSelectAll = useCallback(() => {\n const values = items.map(item => item.value);\n const newSelection = new Set(values);\n setSelection(newSelection);\n onChange(values);\n }, [items, onChange]);\n\n const handleClearSelection = useCallback(() => {\n setSelection(new Set());\n onChange([]);\n }, [onChange]);\n\n const handleViewportChange = useCallback(() => {\n // no-op\n }, []);\n\n const handleChildBlur = useCallback(\n (e: React.FocusEvent<Element>) => {\n const { relatedTarget } = e;\n log.debug(\n 'handleChildBlur',\n relatedTarget,\n relatedTarget instanceof HTMLElement,\n parentRef.current,\n parentRef.current?.contains(relatedTarget)\n );\n if (\n !relatedTarget ||\n (parentRef.current &&\n relatedTarget instanceof HTMLElement &&\n !parentRef.current.contains(relatedTarget))\n ) {\n onBlur();\n }\n },\n [onBlur]\n );\n\n const isEmpty = items.length === 0;\n\n return (\n <div\n ref={parentRef}\n className={classNames(\n 'table-input-container d-flex flex-column position-relative',\n className\n )}\n >\n <SearchInput\n disabled={!!error || isEmpty}\n value={searchValue}\n placeholder=\"Search\"\n onChange={handleSearchChange}\n className=\"mb-2 d-flex\"\n onBlur={handleChildBlur}\n />\n <SelectValueList\n className=\"table-input-list\"\n disabled={table === undefined || isEmpty}\n isInvalid={isInvalid}\n items={isEmpty ? [{ value: 'Empty', isSelected: false }] : items}\n itemCount={itemCount}\n offset={0}\n onSelect={handleSelect}\n onViewportChange={handleViewportChange}\n ref={listRef}\n onBlur={handleChildBlur}\n />\n\n {table && (\n <div className=\"meta-row\">\n <div className=\"d-flex align-items-center text-muted small\">\n {table != null && table.size > itemCount && (\n <>Table is too large, showing the first {SIZE_LIMIT} items.</>\n )}\n </div>\n <div>\n <button\n type=\"button\"\n className=\"btn btn-link\"\n onBlur={handleChildBlur}\n onClick={handleSelectAll}\n >\n Select All\n </button>\n <button\n type=\"button\"\n className=\"btn btn-link mr-a\"\n onBlur={handleChildBlur}\n onClick={handleClearSelection}\n >\n Clear\n </button>\n </div>\n </div>\n )}\n\n {table == null ||\n (error && (\n <div className=\"h-100 w-100 position-absolute\">\n <LoadingOverlay\n isLoaded={table != null}\n isLoading={table == null && error == null}\n errorMessage={error?.message ?? null}\n />\n </div>\n ))}\n </div>\n );\n}\n\nTableInput.displayName = 'TableInput';\n\nTableInput.defaultProps = {\n isInvalid: false,\n className: undefined,\n};\n\nexport default TableInput;\n"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ export * from "./HookTestUtils.js";
2
+ export { default as TableInput } from "./TableInput.js";
3
+ export * from "./RefreshTokenBootstrap.js";
4
+ export * from "./RefreshTokenUtils.js";
5
+ export { default as useBroadcastChannel } from "./useBroadcastChannel.js";
6
+ export { default as useBroadcastLoginListener } from "./useBroadcastLoginListener.js";
7
+ export { default as useDebouncedViewportSearch } from "./useDebouncedViewportSearch.js";
8
+ export { default as useInitializeViewportData } from "./useInitializeViewportData.js";
9
+ export { default as useTable } from "./useTable.js";
10
+ export { default as useTableColumn } from "./useTableColumn.js";
11
+ export { default as useTableListener } from "./useTableListener.js";
12
+ export { default as useSelectDistinctTable } from "./useSelectDistinctTable.js";
13
+ export { default as useSetPaddedViewportCallback } from "./useSetPaddedViewportCallback.js";
14
+ export { default as useTableClose } from "./useTableClose.js";
15
+ export { default as useTableSize } from "./useTableSize.js";
16
+ export { default as useTableUtils } from "./useTableUtils.js";
17
+ export { default as useViewportData } from "./useViewportData.js";
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["default","TableInput","useBroadcastChannel","useBroadcastLoginListener","useDebouncedViewportSearch","useInitializeViewportData","useTable","useTableColumn","useTableListener","useSelectDistinctTable","useSetPaddedViewportCallback","useTableClose","useTableSize","useTableUtils","useViewportData"],"sources":["../src/index.ts"],"sourcesContent":["export * from './HookTestUtils';\nexport { default as TableInput } from './TableInput';\nexport * from './RefreshTokenBootstrap';\nexport * from './RefreshTokenUtils';\nexport { default as useBroadcastChannel } from './useBroadcastChannel';\nexport { default as useBroadcastLoginListener } from './useBroadcastLoginListener';\nexport { default as useDebouncedViewportSearch } from './useDebouncedViewportSearch';\nexport { default as useInitializeViewportData } from './useInitializeViewportData';\nexport { default as useTable } from './useTable';\nexport { default as useTableColumn } from './useTableColumn';\nexport { default as useTableListener } from './useTableListener';\nexport { default as useSelectDistinctTable } from './useSelectDistinctTable';\nexport { default as useSetPaddedViewportCallback } from './useSetPaddedViewportCallback';\nexport { default as useTableClose } from './useTableClose';\nexport { default as useTableSize } from './useTableSize';\nexport { default as useTableUtils } from './useTableUtils';\nexport { default as useViewportData } from './useViewportData';\nexport type { UseSelectDistinctTableResult } from './useSelectDistinctTable';\nexport type { UseViewportDataResult } from './useViewportData';\n"],"mappings":";SACSA,OAAO,IAAIC,UAAU;AAAA;AAAA;AAAA,SAGrBD,OAAO,IAAIE,mBAAmB;AAAA,SAC9BF,OAAO,IAAIG,yBAAyB;AAAA,SACpCH,OAAO,IAAII,0BAA0B;AAAA,SACrCJ,OAAO,IAAIK,yBAAyB;AAAA,SACpCL,OAAO,IAAIM,QAAQ;AAAA,SACnBN,OAAO,IAAIO,cAAc;AAAA,SACzBP,OAAO,IAAIQ,gBAAgB;AAAA,SAC3BR,OAAO,IAAIS,sBAAsB;AAAA,SACjCT,OAAO,IAAIU,4BAA4B;AAAA,SACvCV,OAAO,IAAIW,aAAa;AAAA,SACxBX,OAAO,IAAIY,YAAY;AAAA,SACvBZ,OAAO,IAAIa,aAAa;AAAA,SACxBb,OAAO,IAAIc,eAAe"}
@@ -0,0 +1,33 @@
1
+ import { BROADCAST_CHANNEL_NAME, isMessage } from '@deephaven/jsapi-utils';
2
+ import Log from '@deephaven/log';
3
+ import { EMPTY_FUNCTION } from '@deephaven/utils';
4
+ import { useEffect, useMemo } from 'react';
5
+ var log = Log.module('useBroadcastChannel');
6
+ export function useBroadcastChannel() {
7
+ var onEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : EMPTY_FUNCTION;
8
+ var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : BROADCAST_CHANNEL_NAME;
9
+ var channel = useMemo(() => new BroadcastChannel(name), [name]);
10
+ useEffect(() => () => {
11
+ channel.close();
12
+ }, [channel]);
13
+ useEffect(() => {
14
+ function handleEvent(event) {
15
+ var {
16
+ data
17
+ } = event;
18
+ if (!isMessage(data)) {
19
+ log.debug('Ignoring non-deephaven message', data);
20
+ return;
21
+ }
22
+ log.debug('event received', data);
23
+ onEvent(event);
24
+ }
25
+ channel.addEventListener('message', handleEvent);
26
+ return () => {
27
+ channel.removeEventListener('message', handleEvent);
28
+ };
29
+ }, [channel, onEvent]);
30
+ return channel;
31
+ }
32
+ export default useBroadcastChannel;
33
+ //# sourceMappingURL=useBroadcastChannel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBroadcastChannel.js","names":["BROADCAST_CHANNEL_NAME","isMessage","Log","EMPTY_FUNCTION","useEffect","useMemo","log","module","useBroadcastChannel","onEvent","name","channel","BroadcastChannel","close","handleEvent","event","data","debug","addEventListener","removeEventListener"],"sources":["../src/useBroadcastChannel.ts"],"sourcesContent":["import {\n BROADCAST_CHANNEL_NAME,\n isMessage,\n Message,\n} from '@deephaven/jsapi-utils';\nimport Log from '@deephaven/log';\nimport { EMPTY_FUNCTION } from '@deephaven/utils';\nimport { useEffect, useMemo } from 'react';\n\nconst log = Log.module('useBroadcastChannel');\n\nexport function useBroadcastChannel(\n onEvent: (event: MessageEvent<Message<unknown>>) => void = EMPTY_FUNCTION,\n name = BROADCAST_CHANNEL_NAME\n) {\n const channel = useMemo(() => new BroadcastChannel(name), [name]);\n useEffect(\n () => () => {\n channel.close();\n },\n [channel]\n );\n\n useEffect(() => {\n function handleEvent(event: MessageEvent) {\n const { data } = event;\n if (!isMessage(data)) {\n log.debug('Ignoring non-deephaven message', data);\n return;\n }\n log.debug('event received', data);\n onEvent(event);\n }\n channel.addEventListener('message', handleEvent);\n return () => {\n channel.removeEventListener('message', handleEvent);\n };\n }, [channel, onEvent]);\n\n return channel;\n}\n\nexport default useBroadcastChannel;\n"],"mappings":"AAAA,SACEA,sBAAsB,EACtBC,SAAS,QAEJ,wBAAwB;AAC/B,OAAOC,GAAG,MAAM,gBAAgB;AAChC,SAASC,cAAc,QAAQ,kBAAkB;AACjD,SAASC,SAAS,EAAEC,OAAO,QAAQ,OAAO;AAE1C,IAAMC,GAAG,GAAGJ,GAAG,CAACK,MAAM,CAAC,qBAAqB,CAAC;AAE7C,OAAO,SAASC,mBAAmB,GAGjC;EAAA,IAFAC,OAAwD,uEAAGN,cAAc;EAAA,IACzEO,IAAI,uEAAGV,sBAAsB;EAE7B,IAAMW,OAAO,GAAGN,OAAO,CAAC,MAAM,IAAIO,gBAAgB,CAACF,IAAI,CAAC,EAAE,CAACA,IAAI,CAAC,CAAC;EACjEN,SAAS,CACP,MAAM,MAAM;IACVO,OAAO,CAACE,KAAK,EAAE;EACjB,CAAC,EACD,CAACF,OAAO,CAAC,CACV;EAEDP,SAAS,CAAC,MAAM;IACd,SAASU,WAAW,CAACC,KAAmB,EAAE;MACxC,IAAM;QAAEC;MAAK,CAAC,GAAGD,KAAK;MACtB,IAAI,CAACd,SAAS,CAACe,IAAI,CAAC,EAAE;QACpBV,GAAG,CAACW,KAAK,CAAC,gCAAgC,EAAED,IAAI,CAAC;QACjD;MACF;MACAV,GAAG,CAACW,KAAK,CAAC,gBAAgB,EAAED,IAAI,CAAC;MACjCP,OAAO,CAACM,KAAK,CAAC;IAChB;IACAJ,OAAO,CAACO,gBAAgB,CAAC,SAAS,EAAEJ,WAAW,CAAC;IAChD,OAAO,MAAM;MACXH,OAAO,CAACQ,mBAAmB,CAAC,SAAS,EAAEL,WAAW,CAAC;IACrD,CAAC;EACH,CAAC,EAAE,CAACH,OAAO,EAAEF,OAAO,CAAC,CAAC;EAEtB,OAAOE,OAAO;AAChB;AAEA,eAAeH,mBAAmB"}
@@ -0,0 +1,15 @@
1
+ import { isBroadcastLoginMessage, isBroadcastLogoutMessage } from '@deephaven/jsapi-utils';
2
+ import { useCallback } from 'react';
3
+ import useBroadcastChannel from "./useBroadcastChannel.js";
4
+ export function useBroadcastLoginListener(onLogin, onLogout) {
5
+ var onMessage = useCallback(event => {
6
+ if (isBroadcastLoginMessage(event.data)) {
7
+ onLogin === null || onLogin === void 0 ? void 0 : onLogin(event.data);
8
+ } else if (isBroadcastLogoutMessage(event.data)) {
9
+ onLogout === null || onLogout === void 0 ? void 0 : onLogout(event.data);
10
+ }
11
+ }, [onLogin, onLogout]);
12
+ useBroadcastChannel(onMessage);
13
+ }
14
+ export default useBroadcastLoginListener;
15
+ //# sourceMappingURL=useBroadcastLoginListener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBroadcastLoginListener.js","names":["isBroadcastLoginMessage","isBroadcastLogoutMessage","useCallback","useBroadcastChannel","useBroadcastLoginListener","onLogin","onLogout","onMessage","event","data"],"sources":["../src/useBroadcastLoginListener.ts"],"sourcesContent":["import {\n BroadcastLoginMessage,\n BroadcastLogoutMessage,\n isBroadcastLoginMessage,\n isBroadcastLogoutMessage,\n Message,\n} from '@deephaven/jsapi-utils';\nimport { useCallback } from 'react';\nimport useBroadcastChannel from './useBroadcastChannel';\n\nexport function useBroadcastLoginListener(\n onLogin?: (message: BroadcastLoginMessage) => void,\n onLogout?: (message: BroadcastLogoutMessage) => void\n) {\n const onMessage = useCallback(\n (event: MessageEvent<Message<unknown>>) => {\n if (isBroadcastLoginMessage(event.data)) {\n onLogin?.(event.data);\n } else if (isBroadcastLogoutMessage(event.data)) {\n onLogout?.(event.data);\n }\n },\n [onLogin, onLogout]\n );\n\n useBroadcastChannel(onMessage);\n}\n\nexport default useBroadcastLoginListener;\n"],"mappings":"AAAA,SAGEA,uBAAuB,EACvBC,wBAAwB,QAEnB,wBAAwB;AAC/B,SAASC,WAAW,QAAQ,OAAO;AAAC,OAC7BC,mBAAmB;AAE1B,OAAO,SAASC,yBAAyB,CACvCC,OAAkD,EAClDC,QAAoD,EACpD;EACA,IAAMC,SAAS,GAAGL,WAAW,CAC1BM,KAAqC,IAAK;IACzC,IAAIR,uBAAuB,CAACQ,KAAK,CAACC,IAAI,CAAC,EAAE;MACvCJ,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAGG,KAAK,CAACC,IAAI,CAAC;IACvB,CAAC,MAAM,IAAIR,wBAAwB,CAACO,KAAK,CAACC,IAAI,CAAC,EAAE;MAC/CH,QAAQ,aAARA,QAAQ,uBAARA,QAAQ,CAAGE,KAAK,CAACC,IAAI,CAAC;IACxB;EACF,CAAC,EACD,CAACJ,OAAO,EAAEC,QAAQ,CAAC,CACpB;EAEDH,mBAAmB,CAACI,SAAS,CAAC;AAChC;AAEA,eAAeH,yBAAyB"}
@@ -0,0 +1,46 @@
1
+ import debounce from 'lodash.debounce';
2
+ import { TableUtils } from '@deephaven/jsapi-utils';
3
+ import { useApi } from '@deephaven/jsapi-bootstrap';
4
+ import Log from '@deephaven/log';
5
+ import { useEffect, useMemo } from 'react';
6
+ var log = Log.module('useDebouncedViewportSearch');
7
+ export var DEBOUNCE_VIEWPORT_SEARCH_MS = 200;
8
+
9
+ /**
10
+ * React hook that returns a debounced search callback for filtering a table
11
+ * viewport.
12
+ * @param viewportData Table viewport to filter
13
+ * @param columnName Column name to filter by
14
+ * @param debounceMs Millisecond value to debounce
15
+ * @returns A debounced search function
16
+ */
17
+ export default function useDebouncedViewportSearch(viewportData, columnName) {
18
+ var debounceMs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEBOUNCE_VIEWPORT_SEARCH_MS;
19
+ var dh = useApi();
20
+ var tableUtils = useMemo(() => new TableUtils(dh), [dh]);
21
+ var {
22
+ table,
23
+ applyFiltersAndRefresh
24
+ } = viewportData;
25
+ var debouncedSearch = useMemo(() => debounce(searchText => {
26
+ log.debug("Applying debounced searchText '".concat(searchText, "'"));
27
+ if (table == null) {
28
+ return;
29
+ }
30
+ var searchTextTrimmed = searchText.trim();
31
+ if (searchTextTrimmed === '') {
32
+ applyFiltersAndRefresh([]);
33
+ return;
34
+ }
35
+ var column = table.findColumn(columnName);
36
+ var value = tableUtils.makeFilterValue(column.type, searchTextTrimmed);
37
+ var filter = [column.filter().contains(value)];
38
+ applyFiltersAndRefresh(filter);
39
+ }, debounceMs), [applyFiltersAndRefresh, columnName, debounceMs, table, tableUtils]);
40
+ useEffect(() => () => {
41
+ log.debug('Cancelling debounced search function');
42
+ debouncedSearch.cancel();
43
+ }, [debouncedSearch]);
44
+ return debouncedSearch;
45
+ }
46
+ //# sourceMappingURL=useDebouncedViewportSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDebouncedViewportSearch.js","names":["debounce","TableUtils","useApi","Log","useEffect","useMemo","log","module","DEBOUNCE_VIEWPORT_SEARCH_MS","useDebouncedViewportSearch","viewportData","columnName","debounceMs","dh","tableUtils","table","applyFiltersAndRefresh","debouncedSearch","searchText","debug","searchTextTrimmed","trim","column","findColumn","value","makeFilterValue","type","filter","contains","cancel"],"sources":["../src/useDebouncedViewportSearch.ts"],"sourcesContent":["import debounce from 'lodash.debounce';\nimport type { Table, TreeTable } from '@deephaven/jsapi-types';\nimport { TableUtils } from '@deephaven/jsapi-utils';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\nimport Log from '@deephaven/log';\nimport { useEffect, useMemo } from 'react';\nimport { UseViewportDataResult } from './useViewportData';\n\nconst log = Log.module('useDebouncedViewportSearch');\n\nexport const DEBOUNCE_VIEWPORT_SEARCH_MS = 200;\n\n/**\n * React hook that returns a debounced search callback for filtering a table\n * viewport.\n * @param viewportData Table viewport to filter\n * @param columnName Column name to filter by\n * @param debounceMs Millisecond value to debounce\n * @returns A debounced search function\n */\nexport default function useDebouncedViewportSearch<\n I,\n T extends Table | TreeTable\n>(\n viewportData: UseViewportDataResult<I, T>,\n columnName: string,\n debounceMs = DEBOUNCE_VIEWPORT_SEARCH_MS\n): (searchText: string) => void {\n const dh = useApi();\n const tableUtils = useMemo(() => new TableUtils(dh), [dh]);\n const { table, applyFiltersAndRefresh } = viewportData;\n\n const debouncedSearch = useMemo(\n () =>\n debounce((searchText: string) => {\n log.debug(`Applying debounced searchText '${searchText}'`);\n\n if (table == null) {\n return;\n }\n\n const searchTextTrimmed = searchText.trim();\n\n if (searchTextTrimmed === '') {\n applyFiltersAndRefresh([]);\n return;\n }\n\n const column = table.findColumn(columnName);\n const value = tableUtils.makeFilterValue(\n column.type,\n searchTextTrimmed\n );\n const filter = [column.filter().contains(value)];\n\n applyFiltersAndRefresh(filter);\n }, debounceMs),\n [applyFiltersAndRefresh, columnName, debounceMs, table, tableUtils]\n );\n\n useEffect(\n () => () => {\n log.debug('Cancelling debounced search function');\n debouncedSearch.cancel();\n },\n [debouncedSearch]\n );\n\n return debouncedSearch;\n}\n"],"mappings":"AAAA,OAAOA,QAAQ,MAAM,iBAAiB;AAEtC,SAASC,UAAU,QAAQ,wBAAwB;AACnD,SAASC,MAAM,QAAQ,4BAA4B;AACnD,OAAOC,GAAG,MAAM,gBAAgB;AAChC,SAASC,SAAS,EAAEC,OAAO,QAAQ,OAAO;AAG1C,IAAMC,GAAG,GAAGH,GAAG,CAACI,MAAM,CAAC,4BAA4B,CAAC;AAEpD,OAAO,IAAMC,2BAA2B,GAAG,GAAG;;AAE9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,0BAA0B,CAIhDC,YAAyC,EACzCC,UAAkB,EAEY;EAAA,IAD9BC,UAAU,uEAAGJ,2BAA2B;EAExC,IAAMK,EAAE,GAAGX,MAAM,EAAE;EACnB,IAAMY,UAAU,GAAGT,OAAO,CAAC,MAAM,IAAIJ,UAAU,CAACY,EAAE,CAAC,EAAE,CAACA,EAAE,CAAC,CAAC;EAC1D,IAAM;IAAEE,KAAK;IAAEC;EAAuB,CAAC,GAAGN,YAAY;EAEtD,IAAMO,eAAe,GAAGZ,OAAO,CAC7B,MACEL,QAAQ,CAAEkB,UAAkB,IAAK;IAC/BZ,GAAG,CAACa,KAAK,0CAAmCD,UAAU,OAAI;IAE1D,IAAIH,KAAK,IAAI,IAAI,EAAE;MACjB;IACF;IAEA,IAAMK,iBAAiB,GAAGF,UAAU,CAACG,IAAI,EAAE;IAE3C,IAAID,iBAAiB,KAAK,EAAE,EAAE;MAC5BJ,sBAAsB,CAAC,EAAE,CAAC;MAC1B;IACF;IAEA,IAAMM,MAAM,GAAGP,KAAK,CAACQ,UAAU,CAACZ,UAAU,CAAC;IAC3C,IAAMa,KAAK,GAAGV,UAAU,CAACW,eAAe,CACtCH,MAAM,CAACI,IAAI,EACXN,iBAAiB,CAClB;IACD,IAAMO,MAAM,GAAG,CAACL,MAAM,CAACK,MAAM,EAAE,CAACC,QAAQ,CAACJ,KAAK,CAAC,CAAC;IAEhDR,sBAAsB,CAACW,MAAM,CAAC;EAChC,CAAC,EAAEf,UAAU,CAAC,EAChB,CAACI,sBAAsB,EAAEL,UAAU,EAAEC,UAAU,EAAEG,KAAK,EAAED,UAAU,CAAC,CACpE;EAEDV,SAAS,CACP,MAAM,MAAM;IACVE,GAAG,CAACa,KAAK,CAAC,sCAAsC,CAAC;IACjDF,eAAe,CAACY,MAAM,EAAE;EAC1B,CAAC,EACD,CAACZ,eAAe,CAAC,CAClB;EAED,OAAOA,eAAe;AACxB"}
@@ -0,0 +1,62 @@
1
+ import { useEffect } from 'react';
2
+ import { useListData } from '@react-stately/data';
3
+ import { generateEmptyKeyedItems } from '@deephaven/jsapi-utils';
4
+ import { usePrevious } from '@deephaven/react-hooks';
5
+ import useTableSize from "./useTableSize.js";
6
+ /**
7
+ * Initializes a ListData instance that can be used for windowed views of a
8
+ * Table. The list must always contain a KeyedItem for every record in the table,
9
+ * so it is pre-populated with empty items that can be updated with real data as
10
+ * the window changes.
11
+ *
12
+ * IMPORTANT: this will create an empty KeyedItem object for every row in the
13
+ * source table. This is intended for "human" sized tables such as those used in
14
+ * admin panels. This is not suitable for "machine" scale with millions+ rows.
15
+ * @param table The table that will be used to determine the list size.
16
+ * @returns a React Stately ListData object. Note that this object is recreated
17
+ * by React Stately on every render.
18
+ */
19
+ export default function useInitializeViewportData(table) {
20
+ var viewportData = useListData({});
21
+ var prevTable = usePrevious(table);
22
+
23
+ // If the table changes size, we need to re-initialize it.
24
+ var size = Math.max(0, useTableSize(table));
25
+
26
+ // We only want this to fire 1x once the table exists. Note that `useListData`
27
+ // has no way to respond to a reference change of the `table` instance so we
28
+ // have to manually delete any previous keyed items from the list.
29
+ useEffect(() => {
30
+ var currentSize = viewportData.items.length;
31
+
32
+ // If our table instance has changed, we want to clear all items from state
33
+ if (table !== prevTable && currentSize) {
34
+ viewportData.remove(...viewportData.items.map(_ref => {
35
+ var {
36
+ key
37
+ } = _ref;
38
+ return key;
39
+ }));
40
+ currentSize = 0;
41
+ }
42
+ if (!table) {
43
+ return;
44
+ }
45
+ if (size > currentSize) {
46
+ viewportData.insert(currentSize, ...generateEmptyKeyedItems(currentSize, size - 1));
47
+ } else if (size < currentSize) {
48
+ var keys = viewportData.items.slice(size).map(_ref2 => {
49
+ var {
50
+ key
51
+ } = _ref2;
52
+ return key;
53
+ });
54
+ viewportData.remove(...keys);
55
+ }
56
+
57
+ // Intentionally excluding viewportData since it changes on every render.
58
+ // eslint-disable-next-line react-hooks/exhaustive-deps
59
+ }, [size, table]);
60
+ return viewportData;
61
+ }
62
+ //# sourceMappingURL=useInitializeViewportData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInitializeViewportData.js","names":["useEffect","useListData","generateEmptyKeyedItems","usePrevious","useTableSize","useInitializeViewportData","table","viewportData","prevTable","size","Math","max","currentSize","items","length","remove","map","key","insert","keys","slice"],"sources":["../src/useInitializeViewportData.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { ListData, useListData } from '@react-stately/data';\nimport type { Table, TreeTable } from '@deephaven/jsapi-types';\nimport { KeyedItem, generateEmptyKeyedItems } from '@deephaven/jsapi-utils';\nimport { usePrevious } from '@deephaven/react-hooks';\nimport useTableSize from './useTableSize';\n\n/**\n * Initializes a ListData instance that can be used for windowed views of a\n * Table. The list must always contain a KeyedItem for every record in the table,\n * so it is pre-populated with empty items that can be updated with real data as\n * the window changes.\n *\n * IMPORTANT: this will create an empty KeyedItem object for every row in the\n * source table. This is intended for \"human\" sized tables such as those used in\n * admin panels. This is not suitable for \"machine\" scale with millions+ rows.\n * @param table The table that will be used to determine the list size.\n * @returns a React Stately ListData object. Note that this object is recreated\n * by React Stately on every render.\n */\nexport default function useInitializeViewportData<T>(\n table: Table | TreeTable | null\n): ListData<KeyedItem<T>> {\n const viewportData = useListData<KeyedItem<T>>({});\n\n const prevTable = usePrevious(table);\n\n // If the table changes size, we need to re-initialize it.\n const size = Math.max(0, useTableSize(table));\n\n // We only want this to fire 1x once the table exists. Note that `useListData`\n // has no way to respond to a reference change of the `table` instance so we\n // have to manually delete any previous keyed items from the list.\n useEffect(() => {\n let currentSize = viewportData.items.length;\n\n // If our table instance has changed, we want to clear all items from state\n if (table !== prevTable && currentSize) {\n viewportData.remove(...viewportData.items.map(({ key }) => key));\n currentSize = 0;\n }\n\n if (!table) {\n return;\n }\n\n if (size > currentSize) {\n viewportData.insert(\n currentSize,\n ...generateEmptyKeyedItems<T>(currentSize, size - 1)\n );\n } else if (size < currentSize) {\n const keys = viewportData.items.slice(size).map(({ key }) => key);\n viewportData.remove(...keys);\n }\n\n // Intentionally excluding viewportData since it changes on every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [size, table]);\n\n return viewportData;\n}\n"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AACjC,SAAmBC,WAAW,QAAQ,qBAAqB;AAE3D,SAAoBC,uBAAuB,QAAQ,wBAAwB;AAC3E,SAASC,WAAW,QAAQ,wBAAwB;AAAC,OAC9CC,YAAY;AAEnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,yBAAyB,CAC/CC,KAA+B,EACP;EACxB,IAAMC,YAAY,GAAGN,WAAW,CAAe,CAAC,CAAC,CAAC;EAElD,IAAMO,SAAS,GAAGL,WAAW,CAACG,KAAK,CAAC;;EAEpC;EACA,IAAMG,IAAI,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEP,YAAY,CAACE,KAAK,CAAC,CAAC;;EAE7C;EACA;EACA;EACAN,SAAS,CAAC,MAAM;IACd,IAAIY,WAAW,GAAGL,YAAY,CAACM,KAAK,CAACC,MAAM;;IAE3C;IACA,IAAIR,KAAK,KAAKE,SAAS,IAAII,WAAW,EAAE;MACtCL,YAAY,CAACQ,MAAM,CAAC,GAAGR,YAAY,CAACM,KAAK,CAACG,GAAG,CAAC;QAAA,IAAC;UAAEC;QAAI,CAAC;QAAA,OAAKA,GAAG;MAAA,EAAC,CAAC;MAChEL,WAAW,GAAG,CAAC;IACjB;IAEA,IAAI,CAACN,KAAK,EAAE;MACV;IACF;IAEA,IAAIG,IAAI,GAAGG,WAAW,EAAE;MACtBL,YAAY,CAACW,MAAM,CACjBN,WAAW,EACX,GAAGV,uBAAuB,CAAIU,WAAW,EAAEH,IAAI,GAAG,CAAC,CAAC,CACrD;IACH,CAAC,MAAM,IAAIA,IAAI,GAAGG,WAAW,EAAE;MAC7B,IAAMO,IAAI,GAAGZ,YAAY,CAACM,KAAK,CAACO,KAAK,CAACX,IAAI,CAAC,CAACO,GAAG,CAAC;QAAA,IAAC;UAAEC;QAAI,CAAC;QAAA,OAAKA,GAAG;MAAA,EAAC;MACjEV,YAAY,CAACQ,MAAM,CAAC,GAAGI,IAAI,CAAC;IAC9B;;IAEA;IACA;EACF,CAAC,EAAE,CAACV,IAAI,EAAEH,KAAK,CAAC,CAAC;EAEjB,OAAOC,YAAY;AACrB"}
@@ -0,0 +1,43 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
2
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
3
+ import { useCallback, useEffect } from 'react';
4
+ import { usePromiseFactory } from '@deephaven/react-hooks';
5
+
6
+ /**
7
+ * Return type of `useSelectDistinctTable` hook.
8
+ */
9
+
10
+ /**
11
+ * Creates and subscribes to a `selectDistinct` derived table and unsubscribes
12
+ * on unmount.
13
+ * @param table The table to call `selectDistinct` on.
14
+ * @param columnNames The list of column names to pass to `selectDistinct`.
15
+ */
16
+ export default function useSelectDistinctTable(table) {
17
+ for (var _len = arguments.length, columnNames = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
18
+ columnNames[_key - 1] = arguments[_key];
19
+ }
20
+ var selectDistinct = useCallback( /*#__PURE__*/_asyncToGenerator(function* () {
21
+ var _table$selectDistinct;
22
+ return (_table$selectDistinct = table === null || table === void 0 ? void 0 : table.selectDistinct(table.findColumns(columnNames))) !== null && _table$selectDistinct !== void 0 ? _table$selectDistinct : null;
23
+ }),
24
+ // Disabling the exhaustive checks due to the spreading of `columnNames`
25
+ // eslint-disable-next-line react-hooks/exhaustive-deps
26
+ [table, ...columnNames]);
27
+ var {
28
+ data: distinctTable,
29
+ error,
30
+ isError,
31
+ isLoading
32
+ } = usePromiseFactory(selectDistinct, []);
33
+ useEffect(() => () => {
34
+ distinctTable === null || distinctTable === void 0 ? void 0 : distinctTable.close();
35
+ }, [distinctTable]);
36
+ return {
37
+ distinctTable,
38
+ error,
39
+ isError,
40
+ isLoading
41
+ };
42
+ }
43
+ //# sourceMappingURL=useSelectDistinctTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSelectDistinctTable.js","names":["useCallback","useEffect","usePromiseFactory","useSelectDistinctTable","table","columnNames","selectDistinct","findColumns","data","distinctTable","error","isError","isLoading","close"],"sources":["../src/useSelectDistinctTable.ts"],"sourcesContent":["import { useCallback, useEffect } from 'react';\nimport type { Table, TreeTable } from '@deephaven/jsapi-types';\nimport { usePromiseFactory } from '@deephaven/react-hooks';\n\n/**\n * Return type of `useSelectDistinctTable` hook.\n */\nexport interface UseSelectDistinctTableResult {\n distinctTable: Table | null;\n error: string | Error | null;\n isError: boolean;\n isLoading: boolean;\n}\n\n/**\n * Creates and subscribes to a `selectDistinct` derived table and unsubscribes\n * on unmount.\n * @param table The table to call `selectDistinct` on.\n * @param columnNames The list of column names to pass to `selectDistinct`.\n */\nexport default function useSelectDistinctTable(\n table: Table | TreeTable | null,\n ...columnNames: string[]\n): UseSelectDistinctTableResult {\n const selectDistinct = useCallback(\n async () => table?.selectDistinct(table.findColumns(columnNames)) ?? null,\n // Disabling the exhaustive checks due to the spreading of `columnNames`\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [table, ...columnNames]\n );\n\n const { data: distinctTable, error, isError, isLoading } = usePromiseFactory(\n selectDistinct,\n []\n );\n\n useEffect(\n () => () => {\n distinctTable?.close();\n },\n [distinctTable]\n );\n\n return { distinctTable, error, isError, isLoading };\n}\n"],"mappings":";;AAAA,SAASA,WAAW,EAAEC,SAAS,QAAQ,OAAO;AAE9C,SAASC,iBAAiB,QAAQ,wBAAwB;;AAE1D;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,sBAAsB,CAC5CC,KAA+B,EAED;EAAA,kCAD3BC,WAAW;IAAXA,WAAW;EAAA;EAEd,IAAMC,cAAc,GAAGN,WAAW,iCAChC;IAAA;IAAA,gCAAYI,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEE,cAAc,CAACF,KAAK,CAACG,WAAW,CAACF,WAAW,CAAC,CAAC,yEAAI,IAAI;EAAA;EACzE;EACA;EACA,CAACD,KAAK,EAAE,GAAGC,WAAW,CAAC,CACxB;EAED,IAAM;IAAEG,IAAI,EAAEC,aAAa;IAAEC,KAAK;IAAEC,OAAO;IAAEC;EAAU,CAAC,GAAGV,iBAAiB,CAC1EI,cAAc,EACd,EAAE,CACH;EAEDL,SAAS,CACP,MAAM,MAAM;IACVQ,aAAa,aAAbA,aAAa,uBAAbA,aAAa,CAAEI,KAAK,EAAE;EACxB,CAAC,EACD,CAACJ,aAAa,CAAC,CAChB;EAED,OAAO;IAAEA,aAAa;IAAEC,KAAK;IAAEC,OAAO;IAAEC;EAAU,CAAC;AACrD"}
@@ -0,0 +1,20 @@
1
+ import { useCallback } from 'react';
2
+ import { getSize, padFirstAndLastRow } from '@deephaven/jsapi-utils';
3
+
4
+ /**
5
+ * Creates a callback function that will set a Table viewport. The callback has
6
+ * a closure over the Table, a desired viewport size, and additional padding.
7
+ * These will be combined with a first row index passed to the callback to
8
+ * calculate the final viewport.
9
+ * @param table Table to call `setViewport` on.
10
+ * @param viewportSize The desired viewport size.
11
+ * @param viewportPadding Padding to add before and after the viewport.
12
+ * @returns A callback function for setting the viewport.
13
+ */
14
+ export default function useSetPaddedViewportCallback(table, viewportSize, viewportPadding) {
15
+ return useCallback(function setPaddedViewport(firstRow) {
16
+ var [first, last] = padFirstAndLastRow(firstRow, viewportSize, viewportPadding, getSize(table));
17
+ table === null || table === void 0 ? void 0 : table.setViewport(first, last);
18
+ }, [table, viewportPadding, viewportSize]);
19
+ }
20
+ //# sourceMappingURL=useSetPaddedViewportCallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSetPaddedViewportCallback.js","names":["useCallback","getSize","padFirstAndLastRow","useSetPaddedViewportCallback","table","viewportSize","viewportPadding","setPaddedViewport","firstRow","first","last","setViewport"],"sources":["../src/useSetPaddedViewportCallback.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport type { Table, TreeTable } from '@deephaven/jsapi-types';\nimport { getSize, padFirstAndLastRow } from '@deephaven/jsapi-utils';\n\n/**\n * Creates a callback function that will set a Table viewport. The callback has\n * a closure over the Table, a desired viewport size, and additional padding.\n * These will be combined with a first row index passed to the callback to\n * calculate the final viewport.\n * @param table Table to call `setViewport` on.\n * @param viewportSize The desired viewport size.\n * @param viewportPadding Padding to add before and after the viewport.\n * @returns A callback function for setting the viewport.\n */\nexport default function useSetPaddedViewportCallback(\n table: Table | TreeTable | null,\n viewportSize: number,\n viewportPadding: number\n) {\n return useCallback(\n function setPaddedViewport(firstRow: number) {\n const [first, last] = padFirstAndLastRow(\n firstRow,\n viewportSize,\n viewportPadding,\n getSize(table)\n );\n\n table?.setViewport(first, last);\n },\n [table, viewportPadding, viewportSize]\n );\n}\n"],"mappings":"AAAA,SAASA,WAAW,QAAQ,OAAO;AAEnC,SAASC,OAAO,EAAEC,kBAAkB,QAAQ,wBAAwB;;AAEpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,4BAA4B,CAClDC,KAA+B,EAC/BC,YAAoB,EACpBC,eAAuB,EACvB;EACA,OAAON,WAAW,CAChB,SAASO,iBAAiB,CAACC,QAAgB,EAAE;IAC3C,IAAM,CAACC,KAAK,EAAEC,IAAI,CAAC,GAAGR,kBAAkB,CACtCM,QAAQ,EACRH,YAAY,EACZC,eAAe,EACfL,OAAO,CAACG,KAAK,CAAC,CACf;IAEDA,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEO,WAAW,CAACF,KAAK,EAAEC,IAAI,CAAC;EACjC,CAAC,EACD,CAACN,KAAK,EAAEE,eAAe,EAAED,YAAY,CAAC,CACvC;AACH"}
@@ -0,0 +1,63 @@
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { useApi } from '@deephaven/jsapi-bootstrap';
3
+ import Log from '@deephaven/log';
4
+ import useTableListener from "./useTableListener.js";
5
+ import ColumnNameError from "./ColumnNameError.js";
6
+ import TableDisconnectError from "./TableDisconnectError.js";
7
+ var log = Log.module('useTable');
8
+ var useTable = (table, firstRow, lastRow, columnNames) => {
9
+ var dh = useApi();
10
+ var [columns, setColumns] = useState(undefined);
11
+ var [data, setData] = useState([]);
12
+ var [columnError, setColumnError] = useState(null);
13
+ var [tableError, setTableError] = useState(null);
14
+ useEffect(() => {
15
+ if (columnNames === undefined) {
16
+ setColumns(table === null || table === void 0 ? void 0 : table.columns);
17
+ setColumnError(null);
18
+ return;
19
+ }
20
+ try {
21
+ setColumns(table === null || table === void 0 ? void 0 : table.findColumns(columnNames));
22
+ setColumnError(null);
23
+ } catch (e) {
24
+ log.error("Column not found", e, columnNames);
25
+ setColumnError(new ColumnNameError('Invalid columnNames argument'));
26
+ }
27
+ }, [table, columnNames]);
28
+ useEffect(() => {
29
+ if (!columns || !table) {
30
+ log.debug2('Table or column not initialized, skip viewport update.');
31
+ return;
32
+ }
33
+ log.debug2('Setting viewport', firstRow, lastRow);
34
+ table.setViewport(firstRow, lastRow, columns);
35
+ }, [columns, table, firstRow, lastRow]);
36
+ var handleUpdate = useCallback(_ref => {
37
+ var {
38
+ detail
39
+ } = _ref;
40
+ if (!columns) {
41
+ log.error('Columns not initialized.');
42
+ return;
43
+ }
44
+ var viewportData = columns.map(column => detail.rows.map(r => r.get(column)));
45
+ setData(viewportData);
46
+ }, [columns]);
47
+ var handleDisconnect = useCallback(() => {
48
+ setTableError(new TableDisconnectError('Table disconnected'));
49
+ }, []);
50
+ var handleReconnect = useCallback(() => {
51
+ setTableError(null);
52
+ }, []);
53
+ useTableListener(table, dh.Table.EVENT_UPDATED, handleUpdate);
54
+ useTableListener(table, dh.Table.EVENT_DISCONNECT, handleDisconnect);
55
+ useTableListener(table, dh.Table.EVENT_RECONNECT, handleReconnect);
56
+ return {
57
+ columns,
58
+ data,
59
+ error: tableError !== null && tableError !== void 0 ? tableError : columnError
60
+ };
61
+ };
62
+ export default useTable;
63
+ //# sourceMappingURL=useTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTable.js","names":["useCallback","useEffect","useState","useApi","Log","useTableListener","ColumnNameError","TableDisconnectError","log","module","useTable","table","firstRow","lastRow","columnNames","dh","columns","setColumns","undefined","data","setData","columnError","setColumnError","tableError","setTableError","findColumns","e","error","debug2","setViewport","handleUpdate","detail","viewportData","map","column","rows","r","get","handleDisconnect","handleReconnect","Table","EVENT_UPDATED","EVENT_DISCONNECT","EVENT_RECONNECT"],"sources":["../src/useTable.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\nimport type { Column, Row, Table } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport useTableListener from './useTableListener';\nimport ColumnNameError from './ColumnNameError';\nimport TableDisconnectError from './TableDisconnectError';\n\nconst log = Log.module('useTable');\n\nconst useTable = (\n table: Table | undefined,\n firstRow: number,\n lastRow: number,\n columnNames?: string[]\n): {\n columns: Column[] | undefined;\n data: unknown[][];\n error: Error | null;\n} => {\n const dh = useApi();\n const [columns, setColumns] = useState<Column[] | undefined>(undefined);\n const [data, setData] = useState<unknown[][]>([]);\n const [columnError, setColumnError] = useState<Error | null>(null);\n const [tableError, setTableError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (columnNames === undefined) {\n setColumns(table?.columns);\n setColumnError(null);\n return;\n }\n try {\n setColumns(table?.findColumns(columnNames));\n setColumnError(null);\n } catch (e) {\n log.error(`Column not found`, e, columnNames);\n setColumnError(new ColumnNameError('Invalid columnNames argument'));\n }\n }, [table, columnNames]);\n\n useEffect(() => {\n if (!columns || !table) {\n log.debug2('Table or column not initialized, skip viewport update.');\n return;\n }\n log.debug2('Setting viewport', firstRow, lastRow);\n table.setViewport(firstRow, lastRow, columns);\n }, [columns, table, firstRow, lastRow]);\n\n const handleUpdate = useCallback(\n ({ detail }) => {\n if (!columns) {\n log.error('Columns not initialized.');\n return;\n }\n const viewportData = columns.map(column =>\n (detail.rows as Row[]).map(r => r.get(column))\n );\n setData(viewportData);\n },\n [columns]\n );\n\n const handleDisconnect = useCallback(() => {\n setTableError(new TableDisconnectError('Table disconnected'));\n }, []);\n\n const handleReconnect = useCallback(() => {\n setTableError(null);\n }, []);\n\n useTableListener(table, dh.Table.EVENT_UPDATED, handleUpdate);\n useTableListener(table, dh.Table.EVENT_DISCONNECT, handleDisconnect);\n useTableListener(table, dh.Table.EVENT_RECONNECT, handleReconnect);\n\n return { columns, data, error: tableError ?? columnError };\n};\n\nexport default useTable;\n"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { useEffect } from 'react';
2
+ import { isClosed } from '@deephaven/jsapi-utils';
3
+
4
+ /**
5
+ * React hook that closes a given table when the reference changes or when the
6
+ * component unmounts.
7
+ * @param table
8
+ */
9
+ export default function useTableClose(table) {
10
+ useEffect(() => () => {
11
+ if (table == null) {
12
+ return;
13
+ }
14
+ if (!isClosed(table)) {
15
+ table.close();
16
+ }
17
+ }, [table]);
18
+ }
19
+ //# sourceMappingURL=useTableClose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableClose.js","names":["useEffect","isClosed","useTableClose","table","close"],"sources":["../src/useTableClose.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport type { Table, TreeTable } from '@deephaven/jsapi-types';\nimport { isClosed } from '@deephaven/jsapi-utils';\n\n/**\n * React hook that closes a given table when the reference changes or when the\n * component unmounts.\n * @param table\n */\nexport default function useTableClose(\n table: Table | TreeTable | null | undefined\n): void {\n useEffect(\n () => () => {\n if (table == null) {\n return;\n }\n\n if (!isClosed(table)) {\n table.close();\n }\n },\n [table]\n );\n}\n"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AAEjC,SAASC,QAAQ,QAAQ,wBAAwB;;AAEjD;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,aAAa,CACnCC,KAA2C,EACrC;EACNH,SAAS,CACP,MAAM,MAAM;IACV,IAAIG,KAAK,IAAI,IAAI,EAAE;MACjB;IACF;IAEA,IAAI,CAACF,QAAQ,CAACE,KAAK,CAAC,EAAE;MACpBA,KAAK,CAACC,KAAK,EAAE;IACf;EACF,CAAC,EACD,CAACD,KAAK,CAAC,CACR;AACH"}
@@ -0,0 +1,25 @@
1
+ import { useMemo } from 'react';
2
+ import useTable from "./useTable.js";
3
+ /**
4
+ * Subscribe to viewport updates on a single table column
5
+ * @param table Table to get the data from
6
+ * @param firstRow First viewport row
7
+ * @param lastRow Last viewport row
8
+ * @param columnName Column to get the data from
9
+ * @returns Column object, data array for the column, error, setViewport method
10
+ */
11
+ var useTableColumn = (table, firstRow, lastRow, columnName) => {
12
+ var columnNames = useMemo(() => [columnName], [columnName]);
13
+ var {
14
+ columns = [],
15
+ data = [],
16
+ error
17
+ } = useTable(table, firstRow, lastRow, columnNames);
18
+ return {
19
+ column: columns[0],
20
+ data: data[0],
21
+ error
22
+ };
23
+ };
24
+ export default useTableColumn;
25
+ //# sourceMappingURL=useTableColumn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableColumn.js","names":["useMemo","useTable","useTableColumn","table","firstRow","lastRow","columnName","columnNames","columns","data","error","column"],"sources":["../src/useTableColumn.ts"],"sourcesContent":["import { useMemo } from 'react';\nimport type { Column, Table } from '@deephaven/jsapi-types';\nimport useTable from './useTable';\n\n/**\n * Subscribe to viewport updates on a single table column\n * @param table Table to get the data from\n * @param firstRow First viewport row\n * @param lastRow Last viewport row\n * @param columnName Column to get the data from\n * @returns Column object, data array for the column, error, setViewport method\n */\nconst useTableColumn = (\n table: Table | undefined,\n firstRow: number,\n lastRow: number,\n columnName: string\n): {\n column: Column | undefined;\n data: unknown[];\n error: Error | null;\n} => {\n const columnNames = useMemo(() => [columnName], [columnName]);\n const { columns = [], data = [], error } = useTable(\n table,\n firstRow,\n lastRow,\n columnNames\n );\n return {\n column: columns[0],\n data: data[0],\n error,\n };\n};\n\nexport default useTableColumn;\n"],"mappings":"AAAA,SAASA,OAAO,QAAQ,OAAO;AAAC,OAEzBC,QAAQ;AAEf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMC,cAAc,GAAG,CACrBC,KAAwB,EACxBC,QAAgB,EAChBC,OAAe,EACfC,UAAkB,KAKf;EACH,IAAMC,WAAW,GAAGP,OAAO,CAAC,MAAM,CAACM,UAAU,CAAC,EAAE,CAACA,UAAU,CAAC,CAAC;EAC7D,IAAM;IAAEE,OAAO,GAAG,EAAE;IAAEC,IAAI,GAAG,EAAE;IAAEC;EAAM,CAAC,GAAGT,QAAQ,CACjDE,KAAK,EACLC,QAAQ,EACRC,OAAO,EACPE,WAAW,CACZ;EACD,OAAO;IACLI,MAAM,EAAEH,OAAO,CAAC,CAAC,CAAC;IAClBC,IAAI,EAAEA,IAAI,CAAC,CAAC,CAAC;IACbC;EACF,CAAC;AACH,CAAC;AAED,eAAeR,cAAc"}
@@ -0,0 +1,13 @@
1
+ import { useEffect } from 'react';
2
+ import Log from '@deephaven/log';
3
+ var log = Log.module('useTableListener');
4
+ export var useTableListener = (eventEmitter, eventName, callback) => useEffect(function initEventEmitter() {
5
+ if (eventEmitter == null) {
6
+ log.debug2('Emitter undefined, skipping addEventListener', eventName);
7
+ return;
8
+ }
9
+ log.debug2('Adding listener', eventName);
10
+ return eventEmitter.addEventListener(eventName, callback);
11
+ }, [eventEmitter, eventName, callback]);
12
+ export default useTableListener;
13
+ //# sourceMappingURL=useTableListener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableListener.js","names":["useEffect","Log","log","module","useTableListener","eventEmitter","eventName","callback","initEventEmitter","debug2","addEventListener"],"sources":["../src/useTableListener.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport type { Evented, EventListener } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\n\nconst log = Log.module('useTableListener');\n\nexport const useTableListener = (\n eventEmitter: Evented | undefined | null,\n eventName: string,\n callback: EventListener\n): void =>\n useEffect(\n function initEventEmitter() {\n if (eventEmitter == null) {\n log.debug2('Emitter undefined, skipping addEventListener', eventName);\n return;\n }\n log.debug2('Adding listener', eventName);\n return eventEmitter.addEventListener(eventName, callback);\n },\n [eventEmitter, eventName, callback]\n );\n\nexport default useTableListener;\n"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AAEjC,OAAOC,GAAG,MAAM,gBAAgB;AAEhC,IAAMC,GAAG,GAAGD,GAAG,CAACE,MAAM,CAAC,kBAAkB,CAAC;AAE1C,OAAO,IAAMC,gBAAgB,GAAG,CAC9BC,YAAwC,EACxCC,SAAiB,EACjBC,QAAuB,KAEvBP,SAAS,CACP,SAASQ,gBAAgB,GAAG;EAC1B,IAAIH,YAAY,IAAI,IAAI,EAAE;IACxBH,GAAG,CAACO,MAAM,CAAC,8CAA8C,EAAEH,SAAS,CAAC;IACrE;EACF;EACAJ,GAAG,CAACO,MAAM,CAAC,iBAAiB,EAAEH,SAAS,CAAC;EACxC,OAAOD,YAAY,CAACK,gBAAgB,CAACJ,SAAS,EAAEC,QAAQ,CAAC;AAC3D,CAAC,EACD,CAACF,YAAY,EAAEC,SAAS,EAAEC,QAAQ,CAAC,CACpC;AAEH,eAAeH,gBAAgB"}
@@ -0,0 +1,20 @@
1
+ import { useState } from 'react';
2
+ import { useApi } from '@deephaven/jsapi-bootstrap';
3
+ import { getSize } from '@deephaven/jsapi-utils';
4
+ import useTableListener from "./useTableListener.js";
5
+ /**
6
+ * React hook that returns the size of a given table or zero if table is null or
7
+ * undefined. The hook subscribes to the dh.Table.EVENT_SIZECHANGED event and
8
+ * triggers a re-render if any events are received to ensure we have the current
9
+ * size.
10
+ * @param table The table to check the size on.
11
+ */
12
+ export default function useTableSize(table) {
13
+ var [, forceRerender] = useState(0);
14
+ var dh = useApi();
15
+ useTableListener(table, dh.Table.EVENT_SIZECHANGED, () => {
16
+ forceRerender(i => i + 1);
17
+ });
18
+ return getSize(table);
19
+ }
20
+ //# sourceMappingURL=useTableSize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableSize.js","names":["useState","useApi","getSize","useTableListener","useTableSize","table","forceRerender","dh","Table","EVENT_SIZECHANGED","i"],"sources":["../src/useTableSize.ts"],"sourcesContent":["import { useState } from 'react';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\nimport type { Table, TreeTable } from '@deephaven/jsapi-types';\nimport { getSize } from '@deephaven/jsapi-utils';\nimport useTableListener from './useTableListener';\n\n/**\n * React hook that returns the size of a given table or zero if table is null or\n * undefined. The hook subscribes to the dh.Table.EVENT_SIZECHANGED event and\n * triggers a re-render if any events are received to ensure we have the current\n * size.\n * @param table The table to check the size on.\n */\nexport default function useTableSize(\n table: Table | TreeTable | null | undefined\n): number {\n const [, forceRerender] = useState(0);\n\n const dh = useApi();\n\n useTableListener(table, dh.Table.EVENT_SIZECHANGED, () => {\n forceRerender(i => i + 1);\n });\n\n return getSize(table);\n}\n"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,OAAO;AAChC,SAASC,MAAM,QAAQ,4BAA4B;AAEnD,SAASC,OAAO,QAAQ,wBAAwB;AAAC,OAC1CC,gBAAgB;AAEvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,YAAY,CAClCC,KAA2C,EACnC;EACR,IAAM,GAAGC,aAAa,CAAC,GAAGN,QAAQ,CAAC,CAAC,CAAC;EAErC,IAAMO,EAAE,GAAGN,MAAM,EAAE;EAEnBE,gBAAgB,CAACE,KAAK,EAAEE,EAAE,CAACC,KAAK,CAACC,iBAAiB,EAAE,MAAM;IACxDH,aAAa,CAACI,CAAC,IAAIA,CAAC,GAAG,CAAC,CAAC;EAC3B,CAAC,CAAC;EAEF,OAAOR,OAAO,CAACG,KAAK,CAAC;AACvB"}
@@ -0,0 +1,12 @@
1
+ import { useMemo } from 'react';
2
+ import { useApi } from '@deephaven/jsapi-bootstrap';
3
+ import { TableUtils } from '@deephaven/jsapi-utils';
4
+
5
+ /**
6
+ * Get a `TableUtils` instance using `dh` api from the current context.
7
+ */
8
+ export default function useTableUtils() {
9
+ var dh = useApi();
10
+ return useMemo(() => new TableUtils(dh), [dh]);
11
+ }
12
+ //# sourceMappingURL=useTableUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableUtils.js","names":["useMemo","useApi","TableUtils","useTableUtils","dh"],"sources":["../src/useTableUtils.ts"],"sourcesContent":["import { useMemo } from 'react';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\nimport { TableUtils } from '@deephaven/jsapi-utils';\n\n/**\n * Get a `TableUtils` instance using `dh` api from the current context.\n */\nexport default function useTableUtils(): TableUtils {\n const dh = useApi();\n return useMemo(() => new TableUtils(dh), [dh]);\n}\n"],"mappings":"AAAA,SAASA,OAAO,QAAQ,OAAO;AAC/B,SAASC,MAAM,QAAQ,4BAA4B;AACnD,SAASC,UAAU,QAAQ,wBAAwB;;AAEnD;AACA;AACA;AACA,eAAe,SAASC,aAAa,GAAe;EAClD,IAAMC,EAAE,GAAGH,MAAM,EAAE;EACnB,OAAOD,OAAO,CAAC,MAAM,IAAIE,UAAU,CAACE,EAAE,CAAC,EAAE,CAACA,EAAE,CAAC,CAAC;AAChD"}
@@ -0,0 +1,55 @@
1
+ import { useCallback, useEffect } from 'react';
2
+ import { createOnTableUpdatedHandler, defaultRowDeserializer, isClosed } from '@deephaven/jsapi-utils';
3
+ import { useApi } from '@deephaven/jsapi-bootstrap';
4
+ import useInitializeViewportData from "./useInitializeViewportData.js";
5
+ import useSetPaddedViewportCallback from "./useSetPaddedViewportCallback.js";
6
+ import useTableListener from "./useTableListener.js";
7
+ import useTableSize from "./useTableSize.js";
8
+ /**
9
+ * Sets up state management for windowed Table viewports. Returns a ListData
10
+ * instance for managing items associated with the Table + a `setViewport`
11
+ * callback for changing the current viewport.
12
+ *
13
+ * IMPORTANT: this will create an empty KeyedItem object for every row in the
14
+ * source table. This is intended for "human" sized tables such as those used in
15
+ * admin panels. This is not suitable for "machine" scale with millions+ rows.
16
+ * @param table
17
+ * @param viewportSize
18
+ * @param viewportPadding
19
+ * @returns An object for managing Table viewport state. Note that the returned
20
+ * object changes on every render due to the `viewportData` not being memoized.
21
+ * This is due to the underlying React Stately `useListData` implementation that
22
+ * also changes its returned object on every render.
23
+ */
24
+ export default function useViewportData(_ref) {
25
+ var {
26
+ table,
27
+ viewportSize = 10,
28
+ viewportPadding = 50,
29
+ deserializeRow = defaultRowDeserializer
30
+ } = _ref;
31
+ var viewportData = useInitializeViewportData(table);
32
+ var setViewport = useSetPaddedViewportCallback(table, viewportSize, viewportPadding);
33
+ var applyFiltersAndRefresh = useCallback(filters => {
34
+ table === null || table === void 0 ? void 0 : table.applyFilter(filters);
35
+ setViewport(0);
36
+ }, [setViewport, table]);
37
+ var dh = useApi();
38
+ useTableListener(table, dh.Table.EVENT_UPDATED, createOnTableUpdatedHandler(viewportData, deserializeRow));
39
+ var size = useTableSize(table);
40
+ useEffect(() => {
41
+ if (table && !isClosed(table)) {
42
+ // Hydrate the viewport with real data. This will fetch data from index
43
+ // 0 to the end of the viewport + padding.
44
+ setViewport(0);
45
+ }
46
+ }, [table, setViewport, size]);
47
+ return {
48
+ viewportData,
49
+ size,
50
+ table,
51
+ applyFiltersAndRefresh,
52
+ setViewport
53
+ };
54
+ }
55
+ //# sourceMappingURL=useViewportData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useViewportData.js","names":["useCallback","useEffect","createOnTableUpdatedHandler","defaultRowDeserializer","isClosed","useApi","useInitializeViewportData","useSetPaddedViewportCallback","useTableListener","useTableSize","useViewportData","table","viewportSize","viewportPadding","deserializeRow","viewportData","setViewport","applyFiltersAndRefresh","filters","applyFilter","dh","Table","EVENT_UPDATED","size"],"sources":["../src/useViewportData.ts"],"sourcesContent":["import { useCallback, useEffect } from 'react';\nimport { ListData } from '@react-stately/data';\nimport type { FilterCondition, Table, TreeTable } from '@deephaven/jsapi-types';\nimport {\n KeyedItem,\n RowDeserializer,\n createOnTableUpdatedHandler,\n defaultRowDeserializer,\n isClosed,\n} from '@deephaven/jsapi-utils';\nimport { useApi } from '@deephaven/jsapi-bootstrap';\nimport useInitializeViewportData from './useInitializeViewportData';\nimport useSetPaddedViewportCallback from './useSetPaddedViewportCallback';\nimport useTableListener from './useTableListener';\nimport useTableSize from './useTableSize';\n\nexport interface UseViewportDataProps<TItem, TTable extends Table | TreeTable> {\n table: TTable | null;\n viewportSize?: number;\n viewportPadding?: number;\n deserializeRow?: RowDeserializer<TItem>;\n}\n\nexport interface UseViewportDataResult<\n TItem,\n TTable extends Table | TreeTable\n> {\n /** Manages deserialized row items associated with a DH Table */\n viewportData: ListData<KeyedItem<TItem>>;\n /** Size of the underlying Table */\n size: number;\n\n table: TTable | null;\n /** Apply filters and refresh viewport. */\n applyFiltersAndRefresh: (filters: FilterCondition[]) => void;\n /** Set the viewport of the Table */\n setViewport: (firstRow: number) => void;\n}\n\n/**\n * Sets up state management for windowed Table viewports. Returns a ListData\n * instance for managing items associated with the Table + a `setViewport`\n * callback for changing the current viewport.\n *\n * IMPORTANT: this will create an empty KeyedItem object for every row in the\n * source table. This is intended for \"human\" sized tables such as those used in\n * admin panels. This is not suitable for \"machine\" scale with millions+ rows.\n * @param table\n * @param viewportSize\n * @param viewportPadding\n * @returns An object for managing Table viewport state. Note that the returned\n * object changes on every render due to the `viewportData` not being memoized.\n * This is due to the underlying React Stately `useListData` implementation that\n * also changes its returned object on every render.\n */\nexport default function useViewportData<\n TItem,\n TTable extends Table | TreeTable\n>({\n table,\n viewportSize = 10,\n viewportPadding = 50,\n deserializeRow = defaultRowDeserializer,\n}: UseViewportDataProps<TItem, TTable>): UseViewportDataResult<TItem, TTable> {\n const viewportData = useInitializeViewportData<TItem>(table);\n\n const setViewport = useSetPaddedViewportCallback(\n table,\n viewportSize,\n viewportPadding\n );\n\n const applyFiltersAndRefresh = useCallback(\n (filters: FilterCondition[]) => {\n table?.applyFilter(filters);\n setViewport(0);\n },\n [setViewport, table]\n );\n\n const dh = useApi();\n\n useTableListener(\n table,\n dh.Table.EVENT_UPDATED,\n createOnTableUpdatedHandler(viewportData, deserializeRow)\n );\n\n const size = useTableSize(table);\n\n useEffect(() => {\n if (table && !isClosed(table)) {\n // Hydrate the viewport with real data. This will fetch data from index\n // 0 to the end of the viewport + padding.\n setViewport(0);\n }\n }, [table, setViewport, size]);\n\n return {\n viewportData,\n size,\n table,\n applyFiltersAndRefresh,\n setViewport,\n };\n}\n"],"mappings":"AAAA,SAASA,WAAW,EAAEC,SAAS,QAAQ,OAAO;AAG9C,SAGEC,2BAA2B,EAC3BC,sBAAsB,EACtBC,QAAQ,QACH,wBAAwB;AAC/B,SAASC,MAAM,QAAQ,4BAA4B;AAAC,OAC7CC,yBAAyB;AAAA,OACzBC,4BAA4B;AAAA,OAC5BC,gBAAgB;AAAA,OAChBC,YAAY;AAyBnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,eAAe,OAQuC;EAAA,IAL5E;IACAC,KAAK;IACLC,YAAY,GAAG,EAAE;IACjBC,eAAe,GAAG,EAAE;IACpBC,cAAc,GAAGX;EACkB,CAAC;EACpC,IAAMY,YAAY,GAAGT,yBAAyB,CAAQK,KAAK,CAAC;EAE5D,IAAMK,WAAW,GAAGT,4BAA4B,CAC9CI,KAAK,EACLC,YAAY,EACZC,eAAe,CAChB;EAED,IAAMI,sBAAsB,GAAGjB,WAAW,CACvCkB,OAA0B,IAAK;IAC9BP,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEQ,WAAW,CAACD,OAAO,CAAC;IAC3BF,WAAW,CAAC,CAAC,CAAC;EAChB,CAAC,EACD,CAACA,WAAW,EAAEL,KAAK,CAAC,CACrB;EAED,IAAMS,EAAE,GAAGf,MAAM,EAAE;EAEnBG,gBAAgB,CACdG,KAAK,EACLS,EAAE,CAACC,KAAK,CAACC,aAAa,EACtBpB,2BAA2B,CAACa,YAAY,EAAED,cAAc,CAAC,CAC1D;EAED,IAAMS,IAAI,GAAGd,YAAY,CAACE,KAAK,CAAC;EAEhCV,SAAS,CAAC,MAAM;IACd,IAAIU,KAAK,IAAI,CAACP,QAAQ,CAACO,KAAK,CAAC,EAAE;MAC7B;MACA;MACAK,WAAW,CAAC,CAAC,CAAC;IAChB;EACF,CAAC,EAAE,CAACL,KAAK,EAAEK,WAAW,EAAEO,IAAI,CAAC,CAAC;EAE9B,OAAO;IACLR,YAAY;IACZQ,IAAI;IACJZ,KAAK;IACLM,sBAAsB;IACtBD;EACF,CAAC;AACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deephaven/jsapi-components",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
4
4
  "description": "Deephaven JSAPI Components",
5
5
  "author": "Deephaven Data Labs LLC",
6
6
  "license": "Apache-2.0",
@@ -22,13 +22,13 @@
22
22
  "build:sass": "sass --embed-sources --load-path=../../node_modules ./src:./dist"
23
23
  },
24
24
  "dependencies": {
25
- "@deephaven/components": "^0.43.0",
26
- "@deephaven/jsapi-bootstrap": "^0.43.0",
27
- "@deephaven/jsapi-types": "^0.43.0",
28
- "@deephaven/jsapi-utils": "^0.43.0",
29
- "@deephaven/log": "^0.43.0",
30
- "@deephaven/react-hooks": "^0.43.0",
31
- "@deephaven/utils": "^0.43.0",
25
+ "@deephaven/components": "^0.44.0",
26
+ "@deephaven/jsapi-bootstrap": "^0.44.0",
27
+ "@deephaven/jsapi-types": "^0.44.0",
28
+ "@deephaven/jsapi-utils": "^0.44.0",
29
+ "@deephaven/log": "^0.44.0",
30
+ "@deephaven/react-hooks": "^0.44.0",
31
+ "@deephaven/utils": "^0.44.0",
32
32
  "@react-stately/data": "^3.9.1",
33
33
  "@types/js-cookie": "^3.0.3",
34
34
  "classnames": "^2.3.2",
@@ -37,7 +37,7 @@
37
37
  "prop-types": "^15.8.1"
38
38
  },
39
39
  "devDependencies": {
40
- "@deephaven/jsapi-shim": "^0.43.0",
40
+ "@deephaven/jsapi-shim": "^0.44.0",
41
41
  "react-test-renderer": "^17.0.2"
42
42
  },
43
43
  "peerDependencies": {
@@ -52,5 +52,5 @@
52
52
  "publishConfig": {
53
53
  "access": "public"
54
54
  },
55
- "gitHead": "b16776b5bdc15a02cd2897cd79d562ea38c60ed8"
55
+ "gitHead": "ba13c9139b3b7a5f5d64d79069f1de9d4727eeb6"
56
56
  }