@deephaven/dashboard 0.5.2-beta.0 → 0.6.1-demo.8

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/Dashboard.d.ts +2 -1
  2. package/dist/Dashboard.d.ts.map +1 -1
  3. package/dist/Dashboard.js +37 -61
  4. package/dist/Dashboard.js.map +1 -1
  5. package/dist/DashboardLayout.d.ts +3 -1
  6. package/dist/DashboardLayout.d.ts.map +1 -1
  7. package/dist/DashboardLayout.js +57 -93
  8. package/dist/DashboardLayout.js.map +1 -1
  9. package/dist/DashboardUtils.js +16 -9
  10. package/dist/DashboardUtils.js.map +1 -1
  11. package/dist/PanelErrorBoundary.js +41 -73
  12. package/dist/PanelErrorBoundary.js.map +1 -1
  13. package/dist/PanelManager.js +216 -259
  14. package/dist/PanelManager.js.map +1 -1
  15. package/dist/PanelPlaceholder.js +3 -3
  16. package/dist/PanelPlaceholder.js.map +1 -1
  17. package/dist/index.js +13 -13
  18. package/dist/index.js.map +1 -1
  19. package/dist/layout/GLPropTypes.js +3 -3
  20. package/dist/layout/GLPropTypes.js.map +1 -1
  21. package/dist/layout/GoldenLayoutThemeExport.js.map +1 -1
  22. package/dist/layout/LayoutUtils.d.ts +8 -1
  23. package/dist/layout/LayoutUtils.d.ts.map +1 -1
  24. package/dist/layout/LayoutUtils.js +632 -677
  25. package/dist/layout/LayoutUtils.js.map +1 -1
  26. package/dist/layout/golden-layout.js +2 -2
  27. package/dist/layout/golden-layout.js.map +1 -1
  28. package/dist/layout/hooks.js +7 -9
  29. package/dist/layout/hooks.js.map +1 -1
  30. package/dist/layout/index.js +4 -4
  31. package/dist/layout/index.js.map +1 -1
  32. package/dist/redux/actions.js +8 -14
  33. package/dist/redux/actions.js.map +1 -1
  34. package/dist/redux/index.js +6 -21
  35. package/dist/redux/index.js.map +1 -1
  36. package/dist/redux/reducers/dashboardData.js +1 -1
  37. package/dist/redux/reducers/dashboardData.js.map +1 -1
  38. package/dist/redux/reducers/index.js +2 -2
  39. package/dist/redux/reducers/index.js.map +1 -1
  40. package/dist/redux/selectors.js +4 -6
  41. package/dist/redux/selectors.js.map +1 -1
  42. package/dist/tsconfig.tsbuildinfo +1 -1
  43. package/package.json +19 -24
@@ -10,8 +10,9 @@ export declare type DashboardProps = {
10
10
  layoutSettings?: Record<string, unknown>;
11
11
  onLayoutConfigChange?: () => void;
12
12
  onGoldenLayoutChange?: (goldenLayout: GoldenLayout) => void;
13
+ onLayoutInitialized?: () => void;
13
14
  fallbackComponent?: ForwardRefExoticComponent<RefAttributes<unknown>>;
14
15
  };
15
- export declare const Dashboard: ({ id, children, emptyDashboard, layoutConfig, layoutSettings, onLayoutConfigChange, onGoldenLayoutChange, fallbackComponent, }: DashboardProps) => JSX.Element;
16
+ export declare const Dashboard: ({ id, children, emptyDashboard, layoutConfig, layoutSettings, onLayoutConfigChange, onGoldenLayoutChange, onLayoutInitialized, fallbackComponent, }: DashboardProps) => JSX.Element;
16
17
  export default Dashboard;
17
18
  //# sourceMappingURL=Dashboard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../src/Dashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,yBAAyB,EACzB,aAAa,EAKd,MAAM,OAAO,CAAC;AAEf,OAAO,YAAY,EAAE,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,wBAAwB,CAAC;AAIhC,OAAO,kBAAkB,CAAC;AAQ1B,oBAAY,cAAc,GAAG;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;IAC/C,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,oBAAoB,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5D,iBAAiB,CAAC,EAAE,yBAAyB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;CACvE,CAAC;AAEF,eAAO,MAAM,SAAS,mIASnB,cAAc,KAAG,WAiFnB,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../src/Dashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,yBAAyB,EACzB,aAAa,EAKd,MAAM,OAAO,CAAC;AAEf,OAAO,YAAY,EAAE,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,wBAAwB,CAAC;AAIhC,OAAO,kBAAkB,CAAC;AAQ1B,oBAAY,cAAc,GAAG;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;IAC/C,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,oBAAoB,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5D,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,iBAAiB,CAAC,EAAE,yBAAyB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;CACvE,CAAC;AAEF,eAAO,MAAM,SAAS,wJAUnB,cAAc,KAAG,WA8EnB,CAAC;AAEF,eAAe,SAAS,CAAC"}
package/dist/Dashboard.js CHANGED
@@ -4,71 +4,48 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
4
4
 
5
5
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
6
 
7
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
8
-
9
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
10
-
11
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
12
-
13
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
14
-
15
- function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
16
-
17
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
18
-
19
7
  import React, { useEffect, useMemo, useRef, useState } from 'react';
20
8
  import throttle from 'lodash.throttle';
21
9
  import GoldenLayout from '@deephaven/golden-layout';
22
- import './layout/golden-layout';
23
- import LayoutUtils from './layout/LayoutUtils';
24
- import PanelPlaceholder from './PanelPlaceholder';
25
- import DashboardLayout from './DashboardLayout';
10
+ import "./layout/golden-layout.js";
11
+ import LayoutUtils from "./layout/LayoutUtils.js";
12
+ import PanelPlaceholder from "./PanelPlaceholder.js";
13
+ import DashboardLayout from "./DashboardLayout.js";
26
14
  import "./Dashboard.css";
27
15
  var RESIZE_THROTTLE = 100;
28
16
 
29
- var DEFAULT_CALLBACK = function DEFAULT_CALLBACK() {
30
- return undefined;
31
- };
17
+ var DEFAULT_CALLBACK = () => undefined;
32
18
 
33
19
  var EMPTY_OBJECT = Object.freeze({});
34
- export var Dashboard = function Dashboard(_ref) {
35
- var _ref$id = _ref.id,
36
- id = _ref$id === void 0 ? 'default' : _ref$id,
37
- children = _ref.children,
38
- emptyDashboard = _ref.emptyDashboard,
39
- layoutConfig = _ref.layoutConfig,
40
- _ref$layoutSettings = _ref.layoutSettings,
41
- layoutSettings = _ref$layoutSettings === void 0 ? EMPTY_OBJECT : _ref$layoutSettings,
42
- _ref$onLayoutConfigCh = _ref.onLayoutConfigChange,
43
- onLayoutConfigChange = _ref$onLayoutConfigCh === void 0 ? DEFAULT_CALLBACK : _ref$onLayoutConfigCh,
44
- _ref$onGoldenLayoutCh = _ref.onGoldenLayoutChange,
45
- onGoldenLayoutChange = _ref$onGoldenLayoutCh === void 0 ? DEFAULT_CALLBACK : _ref$onGoldenLayoutCh,
46
- _ref$fallbackComponen = _ref.fallbackComponent,
47
- fallbackComponent = _ref$fallbackComponen === void 0 ? PanelPlaceholder : _ref$fallbackComponen;
20
+ export var Dashboard = (_ref) => {
21
+ var {
22
+ id = 'default',
23
+ children,
24
+ emptyDashboard,
25
+ layoutConfig,
26
+ layoutSettings = EMPTY_OBJECT,
27
+ onLayoutConfigChange = DEFAULT_CALLBACK,
28
+ onGoldenLayoutChange = DEFAULT_CALLBACK,
29
+ onLayoutInitialized = DEFAULT_CALLBACK,
30
+ fallbackComponent = PanelPlaceholder
31
+ } = _ref;
48
32
  var layoutElement = useRef(null);
49
-
50
- var _useState = useState(false),
51
- _useState2 = _slicedToArray(_useState, 2),
52
- isInitialized = _useState2[0],
53
- setIsInitialized = _useState2[1];
54
-
55
- var _useState3 = useState(),
56
- _useState4 = _slicedToArray(_useState3, 2),
57
- layout = _useState4[0],
58
- setLayout = _useState4[1];
59
-
60
- useEffect(function () {
33
+ var [isInitialized, setIsInitialized] = useState(false);
34
+ var [layout, setLayout] = useState();
35
+ useEffect(() => {
61
36
  if (!layoutElement.current) {
62
37
  setLayout(undefined);
63
38
  return;
64
39
  }
65
40
 
66
- var newLayout = new GoldenLayout(_objectSpread(_objectSpread(_objectSpread({}, LayoutUtils.makeDefaultLayout()), layoutSettings), {}, {
67
- // Load our content later after plugins have registered
68
- content: []
69
- }), layoutElement.current);
41
+ var config = _objectSpread({}, LayoutUtils.makeDefaultLayout());
70
42
 
71
- var onInit = function onInit() {
43
+ Object.assign(config.settings, layoutSettings); // Load our content later after plugins have registered
44
+
45
+ config.content = [];
46
+ var newLayout = new GoldenLayout(config, layoutElement.current);
47
+
48
+ var onInit = () => {
72
49
  newLayout.off('initialised', onInit);
73
50
  setIsInitialized(true);
74
51
  };
@@ -82,20 +59,18 @@ export var Dashboard = function Dashboard(_ref) {
82
59
  newLayout.init();
83
60
  setLayout(newLayout);
84
61
  onGoldenLayoutChange(newLayout);
85
- return function () {
62
+ return () => {
86
63
  newLayout.destroy();
87
64
  };
88
65
  }, [layoutSettings, fallbackComponent, onGoldenLayoutChange, setIsInitialized, setLayout]);
89
- var handleResize = useMemo(function () {
90
- return throttle(function () {
91
- if (layout !== null && layout !== void 0 && layout.isInitialised) {
92
- layout === null || layout === void 0 ? void 0 : layout.updateSize();
93
- }
94
- }, RESIZE_THROTTLE);
95
- }, [layout]);
96
- useEffect(function () {
66
+ var handleResize = useMemo(() => throttle(() => {
67
+ if (layout !== null && layout !== void 0 && layout.isInitialised) {
68
+ layout === null || layout === void 0 ? void 0 : layout.updateSize();
69
+ }
70
+ }, RESIZE_THROTTLE), [layout]);
71
+ useEffect(() => {
97
72
  window.addEventListener('resize', handleResize);
98
- return function () {
73
+ return () => {
99
74
  window.removeEventListener('resize', handleResize);
100
75
  };
101
76
  }, [handleResize]);
@@ -109,7 +84,8 @@ export var Dashboard = function Dashboard(_ref) {
109
84
  id: id,
110
85
  layout: layout,
111
86
  layoutConfig: layoutConfig,
112
- onLayoutChange: onLayoutConfigChange
87
+ onLayoutChange: onLayoutConfigChange,
88
+ onLayoutInitialized: onLayoutInitialized
113
89
  }, children));
114
90
  };
115
91
  export default Dashboard;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Dashboard.tsx"],"names":["React","useEffect","useMemo","useRef","useState","throttle","GoldenLayout","LayoutUtils","PanelPlaceholder","DashboardLayout","RESIZE_THROTTLE","DEFAULT_CALLBACK","undefined","EMPTY_OBJECT","Object","freeze","Dashboard","id","children","emptyDashboard","layoutConfig","layoutSettings","onLayoutConfigChange","onGoldenLayoutChange","fallbackComponent","layoutElement","isInitialized","setIsInitialized","layout","setLayout","current","newLayout","makeDefaultLayout","content","onInit","off","on","setFallbackComponent","init","destroy","handleResize","isInitialised","updateSize","window","addEventListener","removeEventListener"],"mappings":"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","sourcesContent":["import React, {\n ForwardRefExoticComponent,\n RefAttributes,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport throttle from 'lodash.throttle';\nimport GoldenLayout, { ItemConfigType } from '@deephaven/golden-layout';\nimport './layout/golden-layout';\nimport LayoutUtils from './layout/LayoutUtils';\nimport PanelPlaceholder from './PanelPlaceholder';\nimport DashboardLayout from './DashboardLayout';\nimport './Dashboard.scss';\n\nconst RESIZE_THROTTLE = 100;\n\nconst DEFAULT_CALLBACK = () => undefined;\n\nconst EMPTY_OBJECT = Object.freeze({});\n\nexport type DashboardProps = {\n id?: string;\n children?: React.ReactNode | React.ReactNode[];\n emptyDashboard?: React.ReactNode;\n layoutConfig?: ItemConfigType[];\n layoutSettings?: Record<string, unknown>;\n onLayoutConfigChange?: () => void;\n onGoldenLayoutChange?: (goldenLayout: GoldenLayout) => void;\n fallbackComponent?: ForwardRefExoticComponent<RefAttributes<unknown>>;\n};\n\nexport const Dashboard = ({\n id = 'default',\n children,\n emptyDashboard,\n layoutConfig,\n layoutSettings = EMPTY_OBJECT,\n onLayoutConfigChange = DEFAULT_CALLBACK,\n onGoldenLayoutChange = DEFAULT_CALLBACK,\n fallbackComponent = PanelPlaceholder,\n}: DashboardProps): JSX.Element => {\n const layoutElement = useRef<HTMLDivElement>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [layout, setLayout] = useState<GoldenLayout>();\n\n useEffect(() => {\n if (!layoutElement.current) {\n setLayout(undefined);\n return;\n }\n const newLayout = new GoldenLayout(\n {\n ...LayoutUtils.makeDefaultLayout(),\n ...layoutSettings,\n\n // Load our content later after plugins have registered\n content: [],\n },\n layoutElement.current\n );\n\n const onInit = () => {\n newLayout.off('initialised', onInit);\n setIsInitialized(true);\n };\n newLayout.on('initialised', onInit);\n\n if (fallbackComponent) {\n newLayout.setFallbackComponent(fallbackComponent);\n }\n\n newLayout.init();\n\n setLayout(newLayout);\n\n onGoldenLayoutChange(newLayout);\n\n return () => {\n newLayout.destroy();\n };\n }, [\n layoutSettings,\n fallbackComponent,\n onGoldenLayoutChange,\n setIsInitialized,\n setLayout,\n ]);\n\n const handleResize = useMemo(\n () =>\n throttle(() => {\n if (layout?.isInitialised) {\n layout?.updateSize();\n }\n }, RESIZE_THROTTLE),\n [layout]\n );\n\n useEffect(() => {\n window.addEventListener('resize', handleResize);\n return () => {\n window.removeEventListener('resize', handleResize);\n };\n }, [handleResize]);\n\n return (\n <div className=\"dashboard-container w-100 h-100\">\n <div className=\"w-100 h-100\" ref={layoutElement} />\n {isInitialized && layout && (\n <DashboardLayout\n emptyDashboard={emptyDashboard}\n id={id}\n layout={layout}\n layoutConfig={layoutConfig}\n onLayoutChange={onLayoutConfigChange}\n >\n {children}\n </DashboardLayout>\n )}\n </div>\n );\n};\n\nexport default Dashboard;\n"],"file":"Dashboard.js"}
1
+ {"version":3,"sources":["../src/Dashboard.tsx"],"names":["React","useEffect","useMemo","useRef","useState","throttle","GoldenLayout","LayoutUtils","PanelPlaceholder","DashboardLayout","RESIZE_THROTTLE","DEFAULT_CALLBACK","undefined","EMPTY_OBJECT","Object","freeze","Dashboard","id","children","emptyDashboard","layoutConfig","layoutSettings","onLayoutConfigChange","onGoldenLayoutChange","onLayoutInitialized","fallbackComponent","layoutElement","isInitialized","setIsInitialized","layout","setLayout","current","config","makeDefaultLayout","assign","settings","content","newLayout","onInit","off","on","setFallbackComponent","init","destroy","handleResize","isInitialised","updateSize","window","addEventListener","removeEventListener"],"mappings":"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","sourcesContent":["import React, {\n ForwardRefExoticComponent,\n RefAttributes,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport throttle from 'lodash.throttle';\nimport GoldenLayout, { ItemConfigType } from '@deephaven/golden-layout';\nimport './layout/golden-layout';\nimport LayoutUtils from './layout/LayoutUtils';\nimport PanelPlaceholder from './PanelPlaceholder';\nimport DashboardLayout from './DashboardLayout';\nimport './Dashboard.scss';\n\nconst RESIZE_THROTTLE = 100;\n\nconst DEFAULT_CALLBACK = () => undefined;\n\nconst EMPTY_OBJECT = Object.freeze({});\n\nexport type DashboardProps = {\n id?: string;\n children?: React.ReactNode | React.ReactNode[];\n emptyDashboard?: React.ReactNode;\n layoutConfig?: ItemConfigType[];\n layoutSettings?: Record<string, unknown>;\n onLayoutConfigChange?: () => void;\n onGoldenLayoutChange?: (goldenLayout: GoldenLayout) => void;\n onLayoutInitialized?: () => void;\n fallbackComponent?: ForwardRefExoticComponent<RefAttributes<unknown>>;\n};\n\nexport const Dashboard = ({\n id = 'default',\n children,\n emptyDashboard,\n layoutConfig,\n layoutSettings = EMPTY_OBJECT,\n onLayoutConfigChange = DEFAULT_CALLBACK,\n onGoldenLayoutChange = DEFAULT_CALLBACK,\n onLayoutInitialized = DEFAULT_CALLBACK,\n fallbackComponent = PanelPlaceholder,\n}: DashboardProps): JSX.Element => {\n const layoutElement = useRef<HTMLDivElement>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [layout, setLayout] = useState<GoldenLayout>();\n\n useEffect(() => {\n if (!layoutElement.current) {\n setLayout(undefined);\n return;\n }\n const config: GoldenLayout.Config = { ...LayoutUtils.makeDefaultLayout() };\n Object.assign(config.settings, layoutSettings);\n // Load our content later after plugins have registered\n config.content = [];\n\n const newLayout = new GoldenLayout(config, layoutElement.current);\n\n const onInit = () => {\n newLayout.off('initialised', onInit);\n setIsInitialized(true);\n };\n newLayout.on('initialised', onInit);\n\n if (fallbackComponent) {\n newLayout.setFallbackComponent(fallbackComponent);\n }\n\n newLayout.init();\n\n setLayout(newLayout);\n\n onGoldenLayoutChange(newLayout);\n\n return () => {\n newLayout.destroy();\n };\n }, [\n layoutSettings,\n fallbackComponent,\n onGoldenLayoutChange,\n setIsInitialized,\n setLayout,\n ]);\n\n const handleResize = useMemo(\n () =>\n throttle(() => {\n if (layout?.isInitialised) {\n layout?.updateSize();\n }\n }, RESIZE_THROTTLE),\n [layout]\n );\n\n useEffect(() => {\n window.addEventListener('resize', handleResize);\n return () => {\n window.removeEventListener('resize', handleResize);\n };\n }, [handleResize]);\n\n return (\n <div className=\"dashboard-container w-100 h-100\">\n <div className=\"w-100 h-100\" ref={layoutElement} />\n {isInitialized && layout && (\n <DashboardLayout\n emptyDashboard={emptyDashboard}\n id={id}\n layout={layout}\n layoutConfig={layoutConfig}\n onLayoutChange={onLayoutConfigChange}\n onLayoutInitialized={onLayoutInitialized}\n >\n {children}\n </DashboardLayout>\n )}\n </div>\n );\n};\n\nexport default Dashboard;\n"],"file":"Dashboard.js"}
@@ -11,6 +11,7 @@ interface DashboardLayoutProps {
11
11
  layout: GoldenLayout;
12
12
  layoutConfig?: DashboardLayoutConfig;
13
13
  onLayoutChange?: (dehydratedLayout: DashboardLayoutConfig) => void;
14
+ onLayoutInitialized?: () => void;
14
15
  data?: DashboardData;
15
16
  children?: React.ReactNode | React.ReactNode[];
16
17
  emptyDashboard?: React.ReactNode;
@@ -19,7 +20,7 @@ interface DashboardLayoutProps {
19
20
  * DashboardLayout component. Handles hydrating, dehydrating components, listening for dragging panels.
20
21
  */
21
22
  export declare const DashboardLayout: {
22
- ({ id, children, emptyDashboard, layout, layoutConfig, onLayoutChange, }: DashboardLayoutProps): JSX.Element;
23
+ ({ id, children, emptyDashboard, layout, layoutConfig, onLayoutChange, onLayoutInitialized, }: DashboardLayoutProps): JSX.Element;
23
24
  propTypes: {
24
25
  id: PropTypes.Validator<string>;
25
26
  children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
@@ -40,6 +41,7 @@ export declare const DashboardLayout: {
40
41
  }>>;
41
42
  layoutConfig: PropTypes.Requireable<(PropTypes.InferProps<{}> | null | undefined)[]>;
42
43
  onLayoutChange: PropTypes.Requireable<(...args: any[]) => any>;
44
+ onLayoutInitialized: PropTypes.Requireable<(...args: any[]) => any>;
43
45
  };
44
46
  };
45
47
  export default DashboardLayout;
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardLayout.d.ts","sourceRoot":"","sources":["../src/DashboardLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,YAAY,EAAE,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAIxE,OAAqB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAW5D,oBAAY,qBAAqB,GAAG,cAAc,EAAE,CAAC;AAarD,aAAK,aAAa,GAAG;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,cAAc,CAAC,EAAE,CAAC,gBAAgB,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACnE,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;IAC/C,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAClC;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;8EAOzB,oBAAoB,GAAG,WAAW;;;;;;;;;;;;;;;;;;;;;;CAgMpC,CAAC;AAYF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"DashboardLayout.d.ts","sourceRoot":"","sources":["../src/DashboardLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,YAAY,EAAE,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAIxE,OAAqB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAW5D,oBAAY,qBAAqB,GAAG,cAAc,EAAE,CAAC;AAarD,aAAK,aAAa,GAAG;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,cAAc,CAAC,EAAE,CAAC,gBAAgB,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACnE,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;IAC/C,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAClC;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;mGAQzB,oBAAoB,GAAG,WAAW;;;;;;;;;;;;;;;;;;;;;;;CAkMpC,CAAC;AAaF,eAAe,eAAe,CAAC"}
@@ -1,87 +1,49 @@
1
1
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
 
3
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
4
-
5
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
6
-
7
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
8
-
9
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
10
-
11
- function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
12
-
13
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
14
-
15
3
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
16
4
  import PropTypes from 'prop-types';
17
5
  import Log from '@deephaven/log';
18
6
  import { usePrevious } from '@deephaven/react-hooks';
19
7
  import { Provider, useDispatch, useSelector, useStore } from 'react-redux';
20
- import PanelManager from './PanelManager';
21
- import PanelErrorBoundary from './PanelErrorBoundary';
22
- import LayoutUtils from './layout/LayoutUtils';
23
- import { dehydrate as dehydrateDefault, hydrate as hydrateDefault } from './DashboardUtils';
24
- import PanelEvent from './PanelEvent';
25
- import { GLPropTypes, useListener } from './layout';
26
- import { getDashboardData, updateDashboardData } from './redux';
8
+ import PanelManager from "./PanelManager.js";
9
+ import PanelErrorBoundary from "./PanelErrorBoundary.js";
10
+ import LayoutUtils from "./layout/LayoutUtils.js";
11
+ import { dehydrate as dehydrateDefault, hydrate as hydrateDefault } from "./DashboardUtils.js";
12
+ import PanelEvent from "./PanelEvent.js";
13
+ import { GLPropTypes, useListener } from "./layout/index.js";
14
+ import { getDashboardData, updateDashboardData } from "./redux/index.js";
27
15
  var log = Log.module('DashboardLayout');
28
16
  var EMPTY_OBJECT = Object.freeze({});
29
17
  var DEFAULT_LAYOUT_CONFIG = [];
30
18
 
31
- var DEFAULT_CALLBACK = function DEFAULT_CALLBACK() {
32
- return undefined;
33
- }; // If a component isn't registered, just pass through the props so they are saved if a plugin is loaded later
19
+ var DEFAULT_CALLBACK = () => undefined; // If a component isn't registered, just pass through the props so they are saved if a plugin is loaded later
34
20
 
35
21
 
36
- var FALLBACK_CALLBACK = function FALLBACK_CALLBACK(props) {
37
- return props;
38
- };
22
+ var FALLBACK_CALLBACK = props => props;
39
23
 
40
24
  /**
41
25
  * DashboardLayout component. Handles hydrating, dehydrating components, listening for dragging panels.
42
26
  */
43
- export var DashboardLayout = function DashboardLayout(_ref) {
27
+ export var DashboardLayout = (_ref) => {
44
28
  var _useSelector, _data$closed;
45
29
 
46
- var id = _ref.id,
47
- children = _ref.children,
48
- _ref$emptyDashboard = _ref.emptyDashboard,
49
- emptyDashboard = _ref$emptyDashboard === void 0 ? /*#__PURE__*/React.createElement("div", null, "Dashboard is empty.") : _ref$emptyDashboard,
50
- layout = _ref.layout,
51
- _ref$layoutConfig = _ref.layoutConfig,
52
- layoutConfig = _ref$layoutConfig === void 0 ? DEFAULT_LAYOUT_CONFIG : _ref$layoutConfig,
53
- _ref$onLayoutChange = _ref.onLayoutChange,
54
- onLayoutChange = _ref$onLayoutChange === void 0 ? DEFAULT_CALLBACK : _ref$onLayoutChange;
30
+ var {
31
+ id,
32
+ children,
33
+ emptyDashboard = /*#__PURE__*/React.createElement("div", null, "Dashboard is empty."),
34
+ layout,
35
+ layoutConfig = DEFAULT_LAYOUT_CONFIG,
36
+ onLayoutChange = DEFAULT_CALLBACK,
37
+ onLayoutInitialized = DEFAULT_CALLBACK
38
+ } = _ref;
55
39
  var dispatch = useDispatch();
56
- var data = (_useSelector = useSelector(function (state) {
57
- return getDashboardData(state, id);
58
- })) !== null && _useSelector !== void 0 ? _useSelector : EMPTY_OBJECT;
59
-
60
- var _useState = useState(false),
61
- _useState2 = _slicedToArray(_useState, 2),
62
- isDashboardEmpty = _useState2[0],
63
- setIsDashboardEmpty = _useState2[1];
64
-
65
- var _useState3 = useState(false),
66
- _useState4 = _slicedToArray(_useState3, 2),
67
- isItemDragging = _useState4[0],
68
- setIsItemDragging = _useState4[1];
69
-
70
- var _useState5 = useState(),
71
- _useState6 = _slicedToArray(_useState5, 2),
72
- lastConfig = _useState6[0],
73
- setLastConfig = _useState6[1];
74
-
75
- var _useState7 = useState((_data$closed = data === null || data === void 0 ? void 0 : data.closed) !== null && _data$closed !== void 0 ? _data$closed : []),
76
- _useState8 = _slicedToArray(_useState7, 1),
77
- initialClosedPanels = _useState8[0];
78
-
79
- var hydrateMap = useMemo(function () {
80
- return new Map();
81
- }, []);
82
- var dehydrateMap = useMemo(function () {
83
- return new Map();
84
- }, []);
40
+ var data = (_useSelector = useSelector(state => getDashboardData(state, id))) !== null && _useSelector !== void 0 ? _useSelector : EMPTY_OBJECT;
41
+ var [isDashboardEmpty, setIsDashboardEmpty] = useState(false);
42
+ var [isItemDragging, setIsItemDragging] = useState(false);
43
+ var [lastConfig, setLastConfig] = useState();
44
+ var [initialClosedPanels] = useState((_data$closed = data === null || data === void 0 ? void 0 : data.closed) !== null && _data$closed !== void 0 ? _data$closed : []);
45
+ var hydrateMap = useMemo(() => new Map(), []);
46
+ var dehydrateMap = useMemo(() => new Map(), []);
85
47
  var store = useStore();
86
48
  var registerComponent = useCallback(function (name, componentType) {
87
49
  var hydrate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : hydrateDefault;
@@ -95,8 +57,10 @@ export var DashboardLayout = function DashboardLayout(_ref) {
95
57
  var CType = componentType; // Props supplied by GoldenLayout
96
58
  // eslint-disable-next-line react/prop-types
97
59
 
98
- var glContainer = props.glContainer,
99
- glEventHub = props.glEventHub;
60
+ var {
61
+ glContainer,
62
+ glEventHub
63
+ } = props;
100
64
  return /*#__PURE__*/React.createElement(Provider, {
101
65
  store: store
102
66
  }, /*#__PURE__*/React.createElement(PanelErrorBoundary, {
@@ -113,27 +77,27 @@ export var DashboardLayout = function DashboardLayout(_ref) {
113
77
  dehydrateMap.set(name, dehydrate);
114
78
  return cleanup;
115
79
  }, [hydrateMap, dehydrateMap, layout, store]);
116
- var hydrateComponent = useCallback(function (name, props) {
80
+ var hydrateComponent = useCallback((name, props) => {
117
81
  var _hydrateMap$get;
118
82
 
119
83
  return ((_hydrateMap$get = hydrateMap.get(name)) !== null && _hydrateMap$get !== void 0 ? _hydrateMap$get : FALLBACK_CALLBACK)(props, id);
120
84
  }, [hydrateMap, id]);
121
- var dehydrateComponent = useCallback(function (name, config) {
85
+ var dehydrateComponent = useCallback((name, config) => {
122
86
  var _dehydrateMap$get;
123
87
 
124
88
  return ((_dehydrateMap$get = dehydrateMap.get(name)) !== null && _dehydrateMap$get !== void 0 ? _dehydrateMap$get : FALLBACK_CALLBACK)(config, id);
125
89
  }, [dehydrateMap, id]);
126
- var panelManager = useMemo(function () {
127
- return new PanelManager(layout, hydrateComponent, dehydrateComponent, new Map(), initialClosedPanels, function (_ref2) {
128
- var closed = _ref2.closed,
129
- openedMap = _ref2.openedMap;
130
- dispatch(updateDashboardData(id, {
131
- closed: closed,
132
- openedMap: openedMap
133
- }));
134
- });
135
- }, [dehydrateComponent, dispatch, hydrateComponent, id, initialClosedPanels, layout]);
136
- var handleLayoutStateChanged = useCallback(function () {
90
+ var panelManager = useMemo(() => new PanelManager(layout, hydrateComponent, dehydrateComponent, new Map(), initialClosedPanels, (_ref2) => {
91
+ var {
92
+ closed,
93
+ openedMap
94
+ } = _ref2;
95
+ dispatch(updateDashboardData(id, {
96
+ closed,
97
+ openedMap
98
+ }));
99
+ }), [dehydrateComponent, dispatch, hydrateComponent, id, initialClosedPanels, layout]);
100
+ var handleLayoutStateChanged = useCallback(() => {
137
101
  // we don't want to emit stateChanges that happen during item drags or else
138
102
  // we risk the last saved state being one without that panel in the layout entirely
139
103
  if (isItemDragging) return;
@@ -149,13 +113,13 @@ export var DashboardLayout = function DashboardLayout(_ref) {
149
113
  onLayoutChange(dehydratedLayoutConfig);
150
114
  }
151
115
  }, [dehydrateComponent, isItemDragging, lastConfig, layout, onLayoutChange]);
152
- var handleLayoutItemPickedUp = useCallback(function () {
116
+ var handleLayoutItemPickedUp = useCallback(() => {
153
117
  setIsItemDragging(true);
154
118
  }, []);
155
- var handleLayoutItemDropped = useCallback(function () {
119
+ var handleLayoutItemDropped = useCallback(() => {
156
120
  setIsItemDragging(false);
157
121
  }, []);
158
- var handleComponentCreated = useCallback(function (item) {
122
+ var handleComponentCreated = useCallback(item => {
159
123
  log.debug2('handleComponentCreated', item);
160
124
 
161
125
  if (!item || !item.config || !item.config.component || !item.element) {
@@ -172,7 +136,7 @@ export var DashboardLayout = function DashboardLayout(_ref) {
172
136
  useListener(layout, 'componentCreated', handleComponentCreated);
173
137
  useListener(layout.eventHub, PanelEvent.TITLE_CHANGED, handleLayoutStateChanged);
174
138
  var previousLayoutConfig = usePrevious(layoutConfig);
175
- useEffect(function () {
139
+ useEffect(() => {
176
140
  if (previousLayoutConfig !== layoutConfig && layoutConfig !== lastConfig) {
177
141
  log.debug('Setting new layout content...');
178
142
  var content = LayoutUtils.hydrateLayoutConfig(layoutConfig, hydrateComponent); // Remove the old layout before add the new one
@@ -187,16 +151,15 @@ export var DashboardLayout = function DashboardLayout(_ref) {
187
151
  }
188
152
 
189
153
  setIsDashboardEmpty(layout.root.contentItems.length === 0);
154
+ onLayoutInitialized();
190
155
  }
191
- }, [hydrateComponent, layout, layoutConfig, lastConfig, panelManager, previousLayoutConfig]);
192
- return /*#__PURE__*/React.createElement(React.Fragment, null, isDashboardEmpty && emptyDashboard, React.Children.map(children, function (child) {
193
- return child ? /*#__PURE__*/React.cloneElement(child, {
194
- id: id,
195
- layout: layout,
196
- panelManager: panelManager,
197
- registerComponent: registerComponent
198
- }) : null;
199
- }));
156
+ }, [hydrateComponent, layout, layoutConfig, lastConfig, panelManager, previousLayoutConfig, onLayoutInitialized]);
157
+ return /*#__PURE__*/React.createElement(React.Fragment, null, isDashboardEmpty && emptyDashboard, React.Children.map(children, child => child ? /*#__PURE__*/React.cloneElement(child, {
158
+ id,
159
+ layout,
160
+ panelManager,
161
+ registerComponent
162
+ }) : null));
200
163
  };
201
164
  DashboardLayout.propTypes = {
202
165
  id: PropTypes.string.isRequired,
@@ -205,7 +168,8 @@ DashboardLayout.propTypes = {
205
168
  emptyDashboard: PropTypes.node,
206
169
  layout: GLPropTypes.Layout.isRequired,
207
170
  layoutConfig: PropTypes.arrayOf(PropTypes.shape({})),
208
- onLayoutChange: PropTypes.func
171
+ onLayoutChange: PropTypes.func,
172
+ onLayoutInitialized: PropTypes.func
209
173
  };
210
174
  export default DashboardLayout;
211
175
  //# sourceMappingURL=DashboardLayout.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/DashboardLayout.tsx"],"names":["React","useCallback","useEffect","useMemo","useState","PropTypes","Log","usePrevious","Provider","useDispatch","useSelector","useStore","PanelManager","PanelErrorBoundary","LayoutUtils","dehydrate","dehydrateDefault","hydrate","hydrateDefault","PanelEvent","GLPropTypes","useListener","getDashboardData","updateDashboardData","log","module","EMPTY_OBJECT","Object","freeze","DEFAULT_LAYOUT_CONFIG","DEFAULT_CALLBACK","undefined","FALLBACK_CALLBACK","props","DashboardLayout","id","children","emptyDashboard","layout","layoutConfig","onLayoutChange","dispatch","data","state","isDashboardEmpty","setIsDashboardEmpty","isItemDragging","setIsItemDragging","lastConfig","setLastConfig","closed","initialClosedPanels","hydrateMap","Map","dehydrateMap","store","registerComponent","name","componentType","debug2","renderComponent","ref","CType","glContainer","glEventHub","wrappedComponent","forwardRef","cleanup","set","hydrateComponent","get","dehydrateComponent","config","panelManager","openedMap","handleLayoutStateChanged","glConfig","toConfig","contentConfig","content","dehydratedLayoutConfig","dehydrateLayoutConfig","hasChanged","isEqual","debug","root","contentItems","length","handleLayoutItemPickedUp","handleLayoutItemDropped","handleComponentCreated","item","component","element","cssComponent","replace","toLowerCase","cssClass","addClass","eventHub","TITLE_CHANGED","previousLayoutConfig","hydrateLayoutConfig","remove","i","addChild","Children","map","child","cloneElement","propTypes","string","isRequired","node","shape","Layout","arrayOf","func"],"mappings":"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","sourcesContent":["import React, {\n ComponentType,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport PropTypes from 'prop-types';\nimport GoldenLayout, { ItemConfigType } from '@deephaven/golden-layout';\nimport Log from '@deephaven/log';\nimport { usePrevious } from '@deephaven/react-hooks';\nimport { Provider, useDispatch, useSelector, useStore } from 'react-redux';\nimport PanelManager, { ClosedPanels } from './PanelManager';\nimport PanelErrorBoundary from './PanelErrorBoundary';\nimport LayoutUtils from './layout/LayoutUtils';\nimport {\n dehydrate as dehydrateDefault,\n hydrate as hydrateDefault,\n} from './DashboardUtils';\nimport PanelEvent from './PanelEvent';\nimport { GLPropTypes, useListener } from './layout';\nimport { getDashboardData, updateDashboardData } from './redux';\n\nexport type DashboardLayoutConfig = ItemConfigType[];\n\nconst log = Log.module('DashboardLayout');\n\nconst EMPTY_OBJECT = Object.freeze({});\n\nconst DEFAULT_LAYOUT_CONFIG: DashboardLayoutConfig = [];\n\nconst DEFAULT_CALLBACK = () => undefined;\n\n// If a component isn't registered, just pass through the props so they are saved if a plugin is loaded later\nconst FALLBACK_CALLBACK = (props: unknown) => props;\n\ntype DashboardData = {\n closed?: ClosedPanels;\n};\n\ninterface DashboardLayoutProps {\n id: string;\n layout: GoldenLayout;\n layoutConfig?: DashboardLayoutConfig;\n onLayoutChange?: (dehydratedLayout: DashboardLayoutConfig) => void;\n data?: DashboardData;\n children?: React.ReactNode | React.ReactNode[];\n emptyDashboard?: React.ReactNode;\n}\n\n/**\n * DashboardLayout component. Handles hydrating, dehydrating components, listening for dragging panels.\n */\nexport const DashboardLayout = ({\n id,\n children,\n emptyDashboard = <div>Dashboard is empty.</div>,\n layout,\n layoutConfig = DEFAULT_LAYOUT_CONFIG,\n onLayoutChange = DEFAULT_CALLBACK,\n}: DashboardLayoutProps): JSX.Element => {\n const dispatch = useDispatch();\n const data =\n useSelector(state => getDashboardData(state, id)) ?? EMPTY_OBJECT;\n\n const [isDashboardEmpty, setIsDashboardEmpty] = useState(false);\n const [isItemDragging, setIsItemDragging] = useState(false);\n const [lastConfig, setLastConfig] = useState<DashboardLayoutConfig>();\n const [initialClosedPanels] = useState(data?.closed ?? []);\n\n const hydrateMap = useMemo(() => new Map(), []);\n const dehydrateMap = useMemo(() => new Map(), []);\n const store = useStore();\n const registerComponent = useCallback(\n (\n name: string,\n componentType: ComponentType,\n hydrate = hydrateDefault,\n dehydrate = dehydrateDefault\n ) => {\n log.debug2('registerComponent', name, componentType, hydrate, dehydrate);\n\n function renderComponent(\n props: { glContainer: unknown; glEventHub: unknown },\n ref: unknown\n ) {\n // Cast it to an `any` type so we can pass the ref in correctly.\n // ComponentType doesn't seem to work right, ReactNode is also incorrect\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const CType = componentType as any;\n\n // Props supplied by GoldenLayout\n // eslint-disable-next-line react/prop-types\n const { glContainer, glEventHub } = props;\n return (\n <Provider store={store}>\n <PanelErrorBoundary\n glContainer={glContainer}\n glEventHub={glEventHub}\n >\n {/* eslint-disable-next-line react/jsx-props-no-spreading */}\n <CType {...props} ref={ref} />\n </PanelErrorBoundary>\n </Provider>\n );\n }\n\n const wrappedComponent = React.forwardRef(renderComponent);\n const cleanup = layout.registerComponent(name, wrappedComponent);\n hydrateMap.set(name, hydrate);\n dehydrateMap.set(name, dehydrate);\n return cleanup;\n },\n [hydrateMap, dehydrateMap, layout, store]\n );\n const hydrateComponent = useCallback(\n (name, props) => (hydrateMap.get(name) ?? FALLBACK_CALLBACK)(props, id),\n [hydrateMap, id]\n );\n const dehydrateComponent = useCallback(\n (name, config) => (dehydrateMap.get(name) ?? FALLBACK_CALLBACK)(config, id),\n [dehydrateMap, id]\n );\n const panelManager = useMemo(\n () =>\n new PanelManager(\n layout,\n hydrateComponent,\n dehydrateComponent,\n new Map(),\n initialClosedPanels,\n ({ closed, openedMap }) => {\n dispatch(updateDashboardData(id, { closed, openedMap }));\n }\n ),\n [\n dehydrateComponent,\n dispatch,\n hydrateComponent,\n id,\n initialClosedPanels,\n layout,\n ]\n );\n\n const handleLayoutStateChanged = useCallback(() => {\n // we don't want to emit stateChanges that happen during item drags or else\n // we risk the last saved state being one without that panel in the layout entirely\n if (isItemDragging) return;\n\n const glConfig = layout.toConfig();\n const contentConfig = glConfig.content;\n const dehydratedLayoutConfig = LayoutUtils.dehydrateLayoutConfig(\n contentConfig,\n dehydrateComponent\n );\n const hasChanged =\n lastConfig == null ||\n !LayoutUtils.isEqual(lastConfig, dehydratedLayoutConfig);\n\n log.debug(\n 'handleLayoutStateChanged',\n hasChanged,\n contentConfig,\n dehydratedLayoutConfig\n );\n\n if (hasChanged) {\n setIsDashboardEmpty(layout.root.contentItems.length === 0);\n\n setLastConfig(dehydratedLayoutConfig);\n\n onLayoutChange(dehydratedLayoutConfig);\n }\n }, [dehydrateComponent, isItemDragging, lastConfig, layout, onLayoutChange]);\n\n const handleLayoutItemPickedUp = useCallback(() => {\n setIsItemDragging(true);\n }, []);\n\n const handleLayoutItemDropped = useCallback(() => {\n setIsItemDragging(false);\n }, []);\n\n const handleComponentCreated = useCallback(item => {\n log.debug2('handleComponentCreated', item);\n\n if (!item || !item.config || !item.config.component || !item.element) {\n return;\n }\n\n const cssComponent = item.config.component\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .toLowerCase();\n const cssClass = `${cssComponent}-component`;\n item.element.addClass(cssClass);\n }, []);\n\n useListener(layout, 'stateChanged', handleLayoutStateChanged);\n useListener(layout, 'itemPickedUp', handleLayoutItemPickedUp);\n useListener(layout, 'itemDropped', handleLayoutItemDropped);\n useListener(layout, 'componentCreated', handleComponentCreated);\n useListener(\n layout.eventHub,\n PanelEvent.TITLE_CHANGED,\n handleLayoutStateChanged\n );\n\n const previousLayoutConfig = usePrevious(layoutConfig);\n useEffect(() => {\n if (previousLayoutConfig !== layoutConfig && layoutConfig !== lastConfig) {\n log.debug('Setting new layout content...');\n const content = LayoutUtils.hydrateLayoutConfig(\n layoutConfig,\n hydrateComponent\n );\n // Remove the old layout before add the new one\n while (layout.root.contentItems.length > 0) {\n layout.root.contentItems[0].remove();\n }\n\n // Add the new content. It is usally just one item from the root\n for (let i = 0; i < content.length; i += 1) {\n layout.root.addChild(content[i]);\n }\n\n setIsDashboardEmpty(layout.root.contentItems.length === 0);\n }\n }, [\n hydrateComponent,\n layout,\n layoutConfig,\n lastConfig,\n panelManager,\n previousLayoutConfig,\n ]);\n\n return (\n <>\n {isDashboardEmpty && emptyDashboard}\n {React.Children.map(children, child =>\n child\n ? React.cloneElement(child as ReactElement, {\n id,\n layout,\n panelManager,\n registerComponent,\n })\n : null\n )}\n </>\n );\n};\n\nDashboardLayout.propTypes = {\n id: PropTypes.string.isRequired,\n children: PropTypes.node,\n data: PropTypes.shape({}),\n emptyDashboard: PropTypes.node,\n layout: GLPropTypes.Layout.isRequired,\n layoutConfig: PropTypes.arrayOf(PropTypes.shape({})),\n onLayoutChange: PropTypes.func,\n};\n\nexport default DashboardLayout;\n"],"file":"DashboardLayout.js"}
1
+ {"version":3,"sources":["../src/DashboardLayout.tsx"],"names":["React","useCallback","useEffect","useMemo","useState","PropTypes","Log","usePrevious","Provider","useDispatch","useSelector","useStore","PanelManager","PanelErrorBoundary","LayoutUtils","dehydrate","dehydrateDefault","hydrate","hydrateDefault","PanelEvent","GLPropTypes","useListener","getDashboardData","updateDashboardData","log","module","EMPTY_OBJECT","Object","freeze","DEFAULT_LAYOUT_CONFIG","DEFAULT_CALLBACK","undefined","FALLBACK_CALLBACK","props","DashboardLayout","id","children","emptyDashboard","layout","layoutConfig","onLayoutChange","onLayoutInitialized","dispatch","data","state","isDashboardEmpty","setIsDashboardEmpty","isItemDragging","setIsItemDragging","lastConfig","setLastConfig","initialClosedPanels","closed","hydrateMap","Map","dehydrateMap","store","registerComponent","name","componentType","debug2","renderComponent","ref","CType","glContainer","glEventHub","wrappedComponent","forwardRef","cleanup","set","hydrateComponent","get","dehydrateComponent","config","panelManager","openedMap","handleLayoutStateChanged","glConfig","toConfig","contentConfig","content","dehydratedLayoutConfig","dehydrateLayoutConfig","hasChanged","isEqual","debug","root","contentItems","length","handleLayoutItemPickedUp","handleLayoutItemDropped","handleComponentCreated","item","component","element","cssComponent","replace","toLowerCase","cssClass","addClass","eventHub","TITLE_CHANGED","previousLayoutConfig","hydrateLayoutConfig","remove","i","addChild","Children","map","child","cloneElement","propTypes","string","isRequired","node","shape","Layout","arrayOf","func"],"mappings":"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","sourcesContent":["import React, {\n ComponentType,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport PropTypes from 'prop-types';\nimport GoldenLayout, { ItemConfigType } from '@deephaven/golden-layout';\nimport Log from '@deephaven/log';\nimport { usePrevious } from '@deephaven/react-hooks';\nimport { Provider, useDispatch, useSelector, useStore } from 'react-redux';\nimport PanelManager, { ClosedPanels } from './PanelManager';\nimport PanelErrorBoundary from './PanelErrorBoundary';\nimport LayoutUtils from './layout/LayoutUtils';\nimport {\n dehydrate as dehydrateDefault,\n hydrate as hydrateDefault,\n} from './DashboardUtils';\nimport PanelEvent from './PanelEvent';\nimport { GLPropTypes, useListener } from './layout';\nimport { getDashboardData, updateDashboardData } from './redux';\n\nexport type DashboardLayoutConfig = ItemConfigType[];\n\nconst log = Log.module('DashboardLayout');\n\nconst EMPTY_OBJECT = Object.freeze({});\n\nconst DEFAULT_LAYOUT_CONFIG: DashboardLayoutConfig = [];\n\nconst DEFAULT_CALLBACK = () => undefined;\n\n// If a component isn't registered, just pass through the props so they are saved if a plugin is loaded later\nconst FALLBACK_CALLBACK = (props: unknown) => props;\n\ntype DashboardData = {\n closed?: ClosedPanels;\n};\n\ninterface DashboardLayoutProps {\n id: string;\n layout: GoldenLayout;\n layoutConfig?: DashboardLayoutConfig;\n onLayoutChange?: (dehydratedLayout: DashboardLayoutConfig) => void;\n onLayoutInitialized?: () => void;\n data?: DashboardData;\n children?: React.ReactNode | React.ReactNode[];\n emptyDashboard?: React.ReactNode;\n}\n\n/**\n * DashboardLayout component. Handles hydrating, dehydrating components, listening for dragging panels.\n */\nexport const DashboardLayout = ({\n id,\n children,\n emptyDashboard = <div>Dashboard is empty.</div>,\n layout,\n layoutConfig = DEFAULT_LAYOUT_CONFIG,\n onLayoutChange = DEFAULT_CALLBACK,\n onLayoutInitialized = DEFAULT_CALLBACK,\n}: DashboardLayoutProps): JSX.Element => {\n const dispatch = useDispatch();\n const data =\n useSelector(state => getDashboardData(state, id)) ?? EMPTY_OBJECT;\n\n const [isDashboardEmpty, setIsDashboardEmpty] = useState(false);\n const [isItemDragging, setIsItemDragging] = useState(false);\n const [lastConfig, setLastConfig] = useState<DashboardLayoutConfig>();\n const [initialClosedPanels] = useState(data?.closed ?? []);\n\n const hydrateMap = useMemo(() => new Map(), []);\n const dehydrateMap = useMemo(() => new Map(), []);\n const store = useStore();\n const registerComponent = useCallback(\n (\n name: string,\n componentType: ComponentType,\n hydrate = hydrateDefault,\n dehydrate = dehydrateDefault\n ) => {\n log.debug2('registerComponent', name, componentType, hydrate, dehydrate);\n\n function renderComponent(\n props: { glContainer: unknown; glEventHub: unknown },\n ref: unknown\n ) {\n // Cast it to an `any` type so we can pass the ref in correctly.\n // ComponentType doesn't seem to work right, ReactNode is also incorrect\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const CType = componentType as any;\n\n // Props supplied by GoldenLayout\n // eslint-disable-next-line react/prop-types\n const { glContainer, glEventHub } = props;\n return (\n <Provider store={store}>\n <PanelErrorBoundary\n glContainer={glContainer}\n glEventHub={glEventHub}\n >\n {/* eslint-disable-next-line react/jsx-props-no-spreading */}\n <CType {...props} ref={ref} />\n </PanelErrorBoundary>\n </Provider>\n );\n }\n\n const wrappedComponent = React.forwardRef(renderComponent);\n const cleanup = layout.registerComponent(name, wrappedComponent);\n hydrateMap.set(name, hydrate);\n dehydrateMap.set(name, dehydrate);\n return cleanup;\n },\n [hydrateMap, dehydrateMap, layout, store]\n );\n const hydrateComponent = useCallback(\n (name, props) => (hydrateMap.get(name) ?? FALLBACK_CALLBACK)(props, id),\n [hydrateMap, id]\n );\n const dehydrateComponent = useCallback(\n (name, config) => (dehydrateMap.get(name) ?? FALLBACK_CALLBACK)(config, id),\n [dehydrateMap, id]\n );\n const panelManager = useMemo(\n () =>\n new PanelManager(\n layout,\n hydrateComponent,\n dehydrateComponent,\n new Map(),\n initialClosedPanels,\n ({ closed, openedMap }) => {\n dispatch(updateDashboardData(id, { closed, openedMap }));\n }\n ),\n [\n dehydrateComponent,\n dispatch,\n hydrateComponent,\n id,\n initialClosedPanels,\n layout,\n ]\n );\n\n const handleLayoutStateChanged = useCallback(() => {\n // we don't want to emit stateChanges that happen during item drags or else\n // we risk the last saved state being one without that panel in the layout entirely\n if (isItemDragging) return;\n\n const glConfig = layout.toConfig();\n const contentConfig = glConfig.content;\n const dehydratedLayoutConfig = LayoutUtils.dehydrateLayoutConfig(\n contentConfig,\n dehydrateComponent\n );\n const hasChanged =\n lastConfig == null ||\n !LayoutUtils.isEqual(lastConfig, dehydratedLayoutConfig);\n\n log.debug(\n 'handleLayoutStateChanged',\n hasChanged,\n contentConfig,\n dehydratedLayoutConfig\n );\n\n if (hasChanged) {\n setIsDashboardEmpty(layout.root.contentItems.length === 0);\n\n setLastConfig(dehydratedLayoutConfig);\n\n onLayoutChange(dehydratedLayoutConfig);\n }\n }, [dehydrateComponent, isItemDragging, lastConfig, layout, onLayoutChange]);\n\n const handleLayoutItemPickedUp = useCallback(() => {\n setIsItemDragging(true);\n }, []);\n\n const handleLayoutItemDropped = useCallback(() => {\n setIsItemDragging(false);\n }, []);\n\n const handleComponentCreated = useCallback(item => {\n log.debug2('handleComponentCreated', item);\n\n if (!item || !item.config || !item.config.component || !item.element) {\n return;\n }\n\n const cssComponent = item.config.component\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .toLowerCase();\n const cssClass = `${cssComponent}-component`;\n item.element.addClass(cssClass);\n }, []);\n\n useListener(layout, 'stateChanged', handleLayoutStateChanged);\n useListener(layout, 'itemPickedUp', handleLayoutItemPickedUp);\n useListener(layout, 'itemDropped', handleLayoutItemDropped);\n useListener(layout, 'componentCreated', handleComponentCreated);\n useListener(\n layout.eventHub,\n PanelEvent.TITLE_CHANGED,\n handleLayoutStateChanged\n );\n\n const previousLayoutConfig = usePrevious(layoutConfig);\n useEffect(() => {\n if (previousLayoutConfig !== layoutConfig && layoutConfig !== lastConfig) {\n log.debug('Setting new layout content...');\n const content = LayoutUtils.hydrateLayoutConfig(\n layoutConfig,\n hydrateComponent\n );\n // Remove the old layout before add the new one\n while (layout.root.contentItems.length > 0) {\n layout.root.contentItems[0].remove();\n }\n\n // Add the new content. It is usally just one item from the root\n for (let i = 0; i < content.length; i += 1) {\n layout.root.addChild(content[i]);\n }\n\n setIsDashboardEmpty(layout.root.contentItems.length === 0);\n onLayoutInitialized();\n }\n }, [\n hydrateComponent,\n layout,\n layoutConfig,\n lastConfig,\n panelManager,\n previousLayoutConfig,\n onLayoutInitialized,\n ]);\n\n return (\n <>\n {isDashboardEmpty && emptyDashboard}\n {React.Children.map(children, child =>\n child\n ? React.cloneElement(child as ReactElement, {\n id,\n layout,\n panelManager,\n registerComponent,\n })\n : null\n )}\n </>\n );\n};\n\nDashboardLayout.propTypes = {\n id: PropTypes.string.isRequired,\n children: PropTypes.node,\n data: PropTypes.shape({}),\n emptyDashboard: PropTypes.node,\n layout: GLPropTypes.Layout.isRequired,\n layoutConfig: PropTypes.arrayOf(PropTypes.shape({})),\n onLayoutChange: PropTypes.func,\n onLayoutInitialized: PropTypes.func,\n};\n\nexport default DashboardLayout;\n"],"file":"DashboardLayout.js"}
@@ -12,14 +12,21 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
12
12
  * @returns The dehydrated PanelConfig
13
13
  */
14
14
  export function dehydrate(config) {
15
- var props = config.props,
16
- componentState = config.componentState;
17
- var metadata = props.metadata;
18
- var _props$panelState = props.panelState,
19
- panelState = _props$panelState === void 0 ? null : _props$panelState;
15
+ var {
16
+ props,
17
+ componentState
18
+ } = config;
19
+ var {
20
+ metadata
21
+ } = props;
22
+ var {
23
+ panelState = null
24
+ } = props;
20
25
 
21
26
  if (componentState) {
22
- panelState = componentState.panelState;
27
+ ({
28
+ panelState
29
+ } = componentState);
23
30
  }
24
31
 
25
32
  var newProps = {};
@@ -51,11 +58,11 @@ export function hydrate(props) {
51
58
  return _objectSpread(_objectSpread({
52
59
  metadata: {}
53
60
  }, props), {}, {
54
- localDashboardId: localDashboardId
61
+ localDashboardId
55
62
  });
56
63
  }
57
64
  export default {
58
- dehydrate: dehydrate,
59
- hydrate: hydrate
65
+ dehydrate,
66
+ hydrate
60
67
  };
61
68
  //# sourceMappingURL=DashboardUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/DashboardUtils.ts"],"names":["dehydrate","config","props","componentState","metadata","panelState","newProps","type","hydrate","localDashboardId"],"mappings":";;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,SAAT,CAAmBC,MAAnB,EAA4D;AACjE,MAAQC,KAAR,GAAkCD,MAAlC,CAAQC,KAAR;AAAA,MAAeC,cAAf,GAAkCF,MAAlC,CAAeE,cAAf;AACA,MAAQC,QAAR,GAAqBF,KAArB,CAAQE,QAAR;AACA,0BAA4BF,KAA5B,CAAMG,UAAN;AAAA,MAAMA,UAAN,kCAAmB,IAAnB;;AACA,MAAIF,cAAJ,EAAoB;AACfE,IAAAA,UADe,GACAF,cADA,CACfE,UADe;AAEnB;;AACD,MAAMC,QAAiC,GAAG,EAA1C;;AACA,MAAIF,QAAJ,EAAc;AACZE,IAAAA,QAAQ,CAACF,QAAT,GAAoBA,QAApB;AACD;;AACD,MAAIC,UAAJ,EAAgB;AACdC,IAAAA,QAAQ,CAACD,UAAT,GAAsBA,UAAtB;AACD;;AAED,yCACKJ,MADL;AAEEE,IAAAA,cAAc,EAAE,IAFlB;AAGED,IAAAA,KAAK,EAAEI,QAHT;AAIEC,IAAAA,IAAI,EAAE;AAJR;AAMD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,OAAO,SAASC,OAAT,CACLN,KADK,EAGgB;AAAA,MADrBO,gBACqB,uEADF,EACE;AACrB;AACEL,IAAAA,QAAQ,EAAE;AADZ,KAEKF,KAFL;AAGEO,IAAAA,gBAAgB,EAAhBA;AAHF;AAKD;AAED,eAAe;AACbT,EAAAA,SAAS,EAATA,SADa;AAEbQ,EAAAA,OAAO,EAAPA;AAFa,CAAf","sourcesContent":["import { PanelConfig, PanelProps } from './DashboardPlugin';\n\nexport type DashboardPanelProps = PanelProps & {\n localDashboardId: string;\n metadata?: Record<string, unknown>;\n};\n\n/**\n * Dehydrate an existing panel to allow it to be serialized/saved.\n * Just takes what's in the panels `metadata` in the props and `panelState` in\n * the component state, assumes it's serializable, and saves it.\n * @param config The panel config to dehydrate\n * @returns The dehydrated PanelConfig\n */\nexport function dehydrate(config: PanelConfig): PanelConfig | null {\n const { props, componentState } = config;\n const { metadata } = props;\n let { panelState = null } = props;\n if (componentState) {\n ({ panelState } = componentState);\n }\n const newProps: Record<string, unknown> = {};\n if (metadata) {\n newProps.metadata = metadata;\n }\n if (panelState) {\n newProps.panelState = panelState;\n }\n\n return {\n ...config,\n componentState: null,\n props: newProps,\n type: 'react-component',\n };\n}\n\n/**\n * Default hydration function. Just applies the dashboard ID. When used with dehydrate above,\n * the panels state will be stored in `panelState` prop.\n * @param props Panel props to hydrate\n * @param localDashboardId The local dashboard ID to hydrate the panel with\n * @returns The hydrated panel props\n */\nexport function hydrate(\n props: PanelProps,\n localDashboardId = ''\n): DashboardPanelProps {\n return {\n metadata: {},\n ...props,\n localDashboardId,\n };\n}\n\nexport default {\n dehydrate,\n hydrate,\n};\n"],"file":"DashboardUtils.js"}
1
+ {"version":3,"sources":["../src/DashboardUtils.ts"],"names":["dehydrate","config","props","componentState","metadata","panelState","newProps","type","hydrate","localDashboardId"],"mappings":";;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,SAAT,CAAmBC,MAAnB,EAA4D;AACjE,MAAM;AAAEC,IAAAA,KAAF;AAASC,IAAAA;AAAT,MAA4BF,MAAlC;AACA,MAAM;AAAEG,IAAAA;AAAF,MAAeF,KAArB;AACA,MAAI;AAAEG,IAAAA,UAAU,GAAG;AAAf,MAAwBH,KAA5B;;AACA,MAAIC,cAAJ,EAAoB;AAClB,KAAC;AAAEE,MAAAA;AAAF,QAAiBF,cAAlB;AACD;;AACD,MAAMG,QAAiC,GAAG,EAA1C;;AACA,MAAIF,QAAJ,EAAc;AACZE,IAAAA,QAAQ,CAACF,QAAT,GAAoBA,QAApB;AACD;;AACD,MAAIC,UAAJ,EAAgB;AACdC,IAAAA,QAAQ,CAACD,UAAT,GAAsBA,UAAtB;AACD;;AAED,yCACKJ,MADL;AAEEE,IAAAA,cAAc,EAAE,IAFlB;AAGED,IAAAA,KAAK,EAAEI,QAHT;AAIEC,IAAAA,IAAI,EAAE;AAJR;AAMD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,OAAO,SAASC,OAAT,CACLN,KADK,EAGgB;AAAA,MADrBO,gBACqB,uEADF,EACE;AACrB;AACEL,IAAAA,QAAQ,EAAE;AADZ,KAEKF,KAFL;AAGEO,IAAAA;AAHF;AAKD;AAED,eAAe;AACbT,EAAAA,SADa;AAEbQ,EAAAA;AAFa,CAAf","sourcesContent":["import { PanelConfig, PanelProps } from './DashboardPlugin';\n\nexport type DashboardPanelProps = PanelProps & {\n localDashboardId: string;\n metadata?: Record<string, unknown>;\n};\n\n/**\n * Dehydrate an existing panel to allow it to be serialized/saved.\n * Just takes what's in the panels `metadata` in the props and `panelState` in\n * the component state, assumes it's serializable, and saves it.\n * @param config The panel config to dehydrate\n * @returns The dehydrated PanelConfig\n */\nexport function dehydrate(config: PanelConfig): PanelConfig | null {\n const { props, componentState } = config;\n const { metadata } = props;\n let { panelState = null } = props;\n if (componentState) {\n ({ panelState } = componentState);\n }\n const newProps: Record<string, unknown> = {};\n if (metadata) {\n newProps.metadata = metadata;\n }\n if (panelState) {\n newProps.panelState = panelState;\n }\n\n return {\n ...config,\n componentState: null,\n props: newProps,\n type: 'react-component',\n };\n}\n\n/**\n * Default hydration function. Just applies the dashboard ID. When used with dehydrate above,\n * the panels state will be stored in `panelState` prop.\n * @param props Panel props to hydrate\n * @param localDashboardId The local dashboard ID to hydrate the panel with\n * @returns The hydrated panel props\n */\nexport function hydrate(\n props: PanelProps,\n localDashboardId = ''\n): DashboardPanelProps {\n return {\n metadata: {},\n ...props,\n localDashboardId,\n };\n}\n\nexport default {\n dehydrate,\n hydrate,\n};\n"],"file":"DashboardUtils.js"}