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

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 +63 -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;;;;;;;;;;;;;;;;;;;;;;;CA8MpC,CAAC;AAaF,eAAe,eAAe,CAAC"}
@@ -1,87 +1,50 @@
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 [isDashboardInitialized, setIsDashboardInitialized] = useState(false);
46
+ var hydrateMap = useMemo(() => new Map(), []);
47
+ var dehydrateMap = useMemo(() => new Map(), []);
85
48
  var store = useStore();
86
49
  var registerComponent = useCallback(function (name, componentType) {
87
50
  var hydrate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : hydrateDefault;
@@ -95,8 +58,10 @@ export var DashboardLayout = function DashboardLayout(_ref) {
95
58
  var CType = componentType; // Props supplied by GoldenLayout
96
59
  // eslint-disable-next-line react/prop-types
97
60
 
98
- var glContainer = props.glContainer,
99
- glEventHub = props.glEventHub;
61
+ var {
62
+ glContainer,
63
+ glEventHub
64
+ } = props;
100
65
  return /*#__PURE__*/React.createElement(Provider, {
101
66
  store: store
102
67
  }, /*#__PURE__*/React.createElement(PanelErrorBoundary, {
@@ -113,30 +78,36 @@ export var DashboardLayout = function DashboardLayout(_ref) {
113
78
  dehydrateMap.set(name, dehydrate);
114
79
  return cleanup;
115
80
  }, [hydrateMap, dehydrateMap, layout, store]);
116
- var hydrateComponent = useCallback(function (name, props) {
81
+ var hydrateComponent = useCallback((name, props) => {
117
82
  var _hydrateMap$get;
118
83
 
119
84
  return ((_hydrateMap$get = hydrateMap.get(name)) !== null && _hydrateMap$get !== void 0 ? _hydrateMap$get : FALLBACK_CALLBACK)(props, id);
120
85
  }, [hydrateMap, id]);
121
- var dehydrateComponent = useCallback(function (name, config) {
86
+ var dehydrateComponent = useCallback((name, config) => {
122
87
  var _dehydrateMap$get;
123
88
 
124
89
  return ((_dehydrateMap$get = dehydrateMap.get(name)) !== null && _dehydrateMap$get !== void 0 ? _dehydrateMap$get : FALLBACK_CALLBACK)(config, id);
125
90
  }, [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 () {
91
+ var panelManager = useMemo(() => new PanelManager(layout, hydrateComponent, dehydrateComponent, new Map(), initialClosedPanels, (_ref2) => {
92
+ var {
93
+ closed,
94
+ openedMap
95
+ } = _ref2;
96
+ dispatch(updateDashboardData(id, {
97
+ closed,
98
+ openedMap
99
+ }));
100
+ }), [dehydrateComponent, dispatch, hydrateComponent, id, initialClosedPanels, layout]);
101
+ var handleLayoutStateChanged = useCallback(() => {
137
102
  // we don't want to emit stateChanges that happen during item drags or else
138
103
  // we risk the last saved state being one without that panel in the layout entirely
139
104
  if (isItemDragging) return;
105
+
106
+ if (!isDashboardInitialized) {
107
+ onLayoutInitialized();
108
+ setIsDashboardInitialized(true);
109
+ }
110
+
140
111
  var glConfig = layout.toConfig();
141
112
  var contentConfig = glConfig.content;
142
113
  var dehydratedLayoutConfig = LayoutUtils.dehydrateLayoutConfig(contentConfig, dehydrateComponent);
@@ -148,14 +119,14 @@ export var DashboardLayout = function DashboardLayout(_ref) {
148
119
  setLastConfig(dehydratedLayoutConfig);
149
120
  onLayoutChange(dehydratedLayoutConfig);
150
121
  }
151
- }, [dehydrateComponent, isItemDragging, lastConfig, layout, onLayoutChange]);
152
- var handleLayoutItemPickedUp = useCallback(function () {
122
+ }, [dehydrateComponent, isDashboardInitialized, isItemDragging, lastConfig, layout, onLayoutChange, onLayoutInitialized]);
123
+ var handleLayoutItemPickedUp = useCallback(() => {
153
124
  setIsItemDragging(true);
154
125
  }, []);
155
- var handleLayoutItemDropped = useCallback(function () {
126
+ var handleLayoutItemDropped = useCallback(() => {
156
127
  setIsItemDragging(false);
157
128
  }, []);
158
- var handleComponentCreated = useCallback(function (item) {
129
+ var handleComponentCreated = useCallback(item => {
159
130
  log.debug2('handleComponentCreated', item);
160
131
 
161
132
  if (!item || !item.config || !item.config.component || !item.element) {
@@ -172,7 +143,7 @@ export var DashboardLayout = function DashboardLayout(_ref) {
172
143
  useListener(layout, 'componentCreated', handleComponentCreated);
173
144
  useListener(layout.eventHub, PanelEvent.TITLE_CHANGED, handleLayoutStateChanged);
174
145
  var previousLayoutConfig = usePrevious(layoutConfig);
175
- useEffect(function () {
146
+ useEffect(() => {
176
147
  if (previousLayoutConfig !== layoutConfig && layoutConfig !== lastConfig) {
177
148
  log.debug('Setting new layout content...');
178
149
  var content = LayoutUtils.hydrateLayoutConfig(layoutConfig, hydrateComponent); // Remove the old layout before add the new one
@@ -189,14 +160,12 @@ export var DashboardLayout = function DashboardLayout(_ref) {
189
160
  setIsDashboardEmpty(layout.root.contentItems.length === 0);
190
161
  }
191
162
  }, [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
- }));
163
+ return /*#__PURE__*/React.createElement(React.Fragment, null, isDashboardEmpty && emptyDashboard, React.Children.map(children, child => child ? /*#__PURE__*/React.cloneElement(child, {
164
+ id,
165
+ layout,
166
+ panelManager,
167
+ registerComponent
168
+ }) : null));
200
169
  };
201
170
  DashboardLayout.propTypes = {
202
171
  id: PropTypes.string.isRequired,
@@ -205,7 +174,8 @@ DashboardLayout.propTypes = {
205
174
  emptyDashboard: PropTypes.node,
206
175
  layout: GLPropTypes.Layout.isRequired,
207
176
  layoutConfig: PropTypes.arrayOf(PropTypes.shape({})),
208
- onLayoutChange: PropTypes.func
177
+ onLayoutChange: PropTypes.func,
178
+ onLayoutInitialized: PropTypes.func
209
179
  };
210
180
  export default DashboardLayout;
211
181
  //# 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":";;;;;;;;;;;;;;AAAA,OAAOA,KAAP,IAGEC,WAHF,EAIEC,SAJF,EAKEC,OALF,EAMEC,QANF,QAOO,OAPP;AAQA,OAAOC,SAAP,MAAsB,YAAtB;AAEA,OAAOC,GAAP,MAAgB,gBAAhB;AACA,SAASC,WAAT,QAA4B,wBAA5B;AACA,SAASC,QAAT,EAAmBC,WAAnB,EAAgCC,WAAhC,EAA6CC,QAA7C,QAA6D,aAA7D;AACA,OAAOC,YAAP,MAA2C,gBAA3C;AACA,OAAOC,kBAAP,MAA+B,sBAA/B;AACA,OAAOC,WAAP,MAAwB,sBAAxB;AACA,SACEC,SAAS,IAAIC,gBADf,EAEEC,OAAO,IAAIC,cAFb,QAGO,kBAHP;AAIA,OAAOC,UAAP,MAAuB,cAAvB;AACA,SAASC,WAAT,EAAsBC,WAAtB,QAAyC,UAAzC;AACA,SAASC,gBAAT,EAA2BC,mBAA3B,QAAsD,SAAtD;AAIA,IAAMC,GAAG,GAAGlB,GAAG,CAACmB,MAAJ,CAAW,iBAAX,CAAZ;AAEA,IAAMC,YAAY,GAAGC,MAAM,CAACC,MAAP,CAAc,EAAd,CAArB;AAEA,IAAMC,qBAA4C,GAAG,EAArD;;AAEA,IAAMC,gBAAgB,GAAG,SAAnBA,gBAAmB;AAAA,SAAMC,SAAN;AAAA,CAAzB,C,CAEA;;;AACA,IAAMC,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,KAAD;AAAA,SAAoBA,KAApB;AAAA,CAA1B;;AAgBA;AACA;AACA;AACA,OAAO,IAAMC,eAAe,GAAG,SAAlBA,eAAkB,OAOU;AAAA;;AAAA,MANvCC,EAMuC,QANvCA,EAMuC;AAAA,MALvCC,QAKuC,QALvCA,QAKuC;AAAA,iCAJvCC,cAIuC;AAAA,MAJvCA,cAIuC,iDAJtB,uDAIsB;AAAA,MAHvCC,MAGuC,QAHvCA,MAGuC;AAAA,+BAFvCC,YAEuC;AAAA,MAFvCA,YAEuC,kCAFxBV,qBAEwB;AAAA,iCADvCW,cACuC;AAAA,MADvCA,cACuC,oCADtBV,gBACsB;AACvC,MAAMW,QAAQ,GAAGhC,WAAW,EAA5B;AACA,MAAMiC,IAAI,mBACRhC,WAAW,CAAC,UAAAiC,KAAK;AAAA,WAAIrB,gBAAgB,CAACqB,KAAD,EAAQR,EAAR,CAApB;AAAA,GAAN,CADH,uDAC6CT,YADvD;;AAGA,kBAAgDtB,QAAQ,CAAC,KAAD,CAAxD;AAAA;AAAA,MAAOwC,gBAAP;AAAA,MAAyBC,mBAAzB;;AACA,mBAA4CzC,QAAQ,CAAC,KAAD,CAApD;AAAA;AAAA,MAAO0C,cAAP;AAAA,MAAuBC,iBAAvB;;AACA,mBAAoC3C,QAAQ,EAA5C;AAAA;AAAA,MAAO4C,UAAP;AAAA,MAAmBC,aAAnB;;AACA,mBAA8B7C,QAAQ,iBAACsC,IAAD,aAACA,IAAD,uBAACA,IAAI,CAAEQ,MAAP,uDAAiB,EAAjB,CAAtC;AAAA;AAAA,MAAOC,mBAAP;;AAEA,MAAMC,UAAU,GAAGjD,OAAO,CAAC;AAAA,WAAM,IAAIkD,GAAJ,EAAN;AAAA,GAAD,EAAkB,EAAlB,CAA1B;AACA,MAAMC,YAAY,GAAGnD,OAAO,CAAC;AAAA,WAAM,IAAIkD,GAAJ,EAAN;AAAA,GAAD,EAAkB,EAAlB,CAA5B;AACA,MAAME,KAAK,GAAG5C,QAAQ,EAAtB;AACA,MAAM6C,iBAAiB,GAAGvD,WAAW,CACnC,UACEwD,IADF,EAEEC,aAFF,EAKK;AAAA,QAFHzC,OAEG,uEAFOC,cAEP;AAAA,QADHH,SACG,uEADSC,gBACT;AACHQ,IAAAA,GAAG,CAACmC,MAAJ,CAAW,mBAAX,EAAgCF,IAAhC,EAAsCC,aAAtC,EAAqDzC,OAArD,EAA8DF,SAA9D;;AAEA,aAAS6C,eAAT,CACE3B,KADF,EAEE4B,GAFF,EAGE;AACA;AACA;AACA;AACA,UAAMC,KAAK,GAAGJ,aAAd,CAJA,CAMA;AACA;;AACA,UAAQK,WAAR,GAAoC9B,KAApC,CAAQ8B,WAAR;AAAA,UAAqBC,UAArB,GAAoC/B,KAApC,CAAqB+B,UAArB;AACA,0BACE,oBAAC,QAAD;AAAU,QAAA,KAAK,EAAET;AAAjB,sBACE,oBAAC,kBAAD;AACE,QAAA,WAAW,EAAEQ,WADf;AAEE,QAAA,UAAU,EAAEC;AAFd,sBAKE,oBAAC,KAAD,eAAW/B,KAAX;AAAkB,QAAA,GAAG,EAAE4B;AAAvB,SALF,CADF,CADF;AAWD;;AAED,QAAMI,gBAAgB,gBAAGjE,KAAK,CAACkE,UAAN,CAAiBN,eAAjB,CAAzB;AACA,QAAMO,OAAO,GAAG7B,MAAM,CAACkB,iBAAP,CAAyBC,IAAzB,EAA+BQ,gBAA/B,CAAhB;AACAb,IAAAA,UAAU,CAACgB,GAAX,CAAeX,IAAf,EAAqBxC,OAArB;AACAqC,IAAAA,YAAY,CAACc,GAAb,CAAiBX,IAAjB,EAAuB1C,SAAvB;AACA,WAAOoD,OAAP;AACD,GAvCkC,EAwCnC,CAACf,UAAD,EAAaE,YAAb,EAA2BhB,MAA3B,EAAmCiB,KAAnC,CAxCmC,CAArC;AA0CA,MAAMc,gBAAgB,GAAGpE,WAAW,CAClC,UAACwD,IAAD,EAAOxB,KAAP;AAAA;;AAAA,WAAiB,oBAACmB,UAAU,CAACkB,GAAX,CAAeb,IAAf,CAAD,6DAAyBzB,iBAAzB,EAA4CC,KAA5C,EAAmDE,EAAnD,CAAjB;AAAA,GADkC,EAElC,CAACiB,UAAD,EAAajB,EAAb,CAFkC,CAApC;AAIA,MAAMoC,kBAAkB,GAAGtE,WAAW,CACpC,UAACwD,IAAD,EAAOe,MAAP;AAAA;;AAAA,WAAkB,sBAAClB,YAAY,CAACgB,GAAb,CAAiBb,IAAjB,CAAD,iEAA2BzB,iBAA3B,EAA8CwC,MAA9C,EAAsDrC,EAAtD,CAAlB;AAAA,GADoC,EAEpC,CAACmB,YAAD,EAAenB,EAAf,CAFoC,CAAtC;AAIA,MAAMsC,YAAY,GAAGtE,OAAO,CAC1B;AAAA,WACE,IAAIS,YAAJ,CACE0B,MADF,EAEE+B,gBAFF,EAGEE,kBAHF,EAIE,IAAIlB,GAAJ,EAJF,EAKEF,mBALF,EAME,iBAA2B;AAAA,UAAxBD,MAAwB,SAAxBA,MAAwB;AAAA,UAAhBwB,SAAgB,SAAhBA,SAAgB;AACzBjC,MAAAA,QAAQ,CAAClB,mBAAmB,CAACY,EAAD,EAAK;AAAEe,QAAAA,MAAM,EAANA,MAAF;AAAUwB,QAAAA,SAAS,EAATA;AAAV,OAAL,CAApB,CAAR;AACD,KARH,CADF;AAAA,GAD0B,EAY1B,CACEH,kBADF,EAEE9B,QAFF,EAGE4B,gBAHF,EAIElC,EAJF,EAKEgB,mBALF,EAMEb,MANF,CAZ0B,CAA5B;AAsBA,MAAMqC,wBAAwB,GAAG1E,WAAW,CAAC,YAAM;AACjD;AACA;AACA,QAAI6C,cAAJ,EAAoB;AAEpB,QAAM8B,QAAQ,GAAGtC,MAAM,CAACuC,QAAP,EAAjB;AACA,QAAMC,aAAa,GAAGF,QAAQ,CAACG,OAA/B;AACA,QAAMC,sBAAsB,GAAGlE,WAAW,CAACmE,qBAAZ,CAC7BH,aAD6B,EAE7BP,kBAF6B,CAA/B;AAIA,QAAMW,UAAU,GACdlC,UAAU,IAAI,IAAd,IACA,CAAClC,WAAW,CAACqE,OAAZ,CAAoBnC,UAApB,EAAgCgC,sBAAhC,CAFH;AAIAxD,IAAAA,GAAG,CAAC4D,KAAJ,CACE,0BADF,EAEEF,UAFF,EAGEJ,aAHF,EAIEE,sBAJF;;AAOA,QAAIE,UAAJ,EAAgB;AACdrC,MAAAA,mBAAmB,CAACP,MAAM,CAAC+C,IAAP,CAAYC,YAAZ,CAAyBC,MAAzB,KAAoC,CAArC,CAAnB;AAEAtC,MAAAA,aAAa,CAAC+B,sBAAD,CAAb;AAEAxC,MAAAA,cAAc,CAACwC,sBAAD,CAAd;AACD;AACF,GA7B2C,EA6BzC,CAACT,kBAAD,EAAqBzB,cAArB,EAAqCE,UAArC,EAAiDV,MAAjD,EAAyDE,cAAzD,CA7ByC,CAA5C;AA+BA,MAAMgD,wBAAwB,GAAGvF,WAAW,CAAC,YAAM;AACjD8C,IAAAA,iBAAiB,CAAC,IAAD,CAAjB;AACD,GAF2C,EAEzC,EAFyC,CAA5C;AAIA,MAAM0C,uBAAuB,GAAGxF,WAAW,CAAC,YAAM;AAChD8C,IAAAA,iBAAiB,CAAC,KAAD,CAAjB;AACD,GAF0C,EAExC,EAFwC,CAA3C;AAIA,MAAM2C,sBAAsB,GAAGzF,WAAW,CAAC,UAAA0F,IAAI,EAAI;AACjDnE,IAAAA,GAAG,CAACmC,MAAJ,CAAW,wBAAX,EAAqCgC,IAArC;;AAEA,QAAI,CAACA,IAAD,IAAS,CAACA,IAAI,CAACnB,MAAf,IAAyB,CAACmB,IAAI,CAACnB,MAAL,CAAYoB,SAAtC,IAAmD,CAACD,IAAI,CAACE,OAA7D,EAAsE;AACpE;AACD;;AAED,QAAMC,YAAY,GAAGH,IAAI,CAACnB,MAAL,CAAYoB,SAAZ,CAClBG,OADkB,CACV,iBADU,EACS,OADT,EAElBC,WAFkB,EAArB;AAGA,QAAMC,QAAQ,aAAMH,YAAN,eAAd;AACAH,IAAAA,IAAI,CAACE,OAAL,CAAaK,QAAb,CAAsBD,QAAtB;AACD,GAZyC,EAYvC,EAZuC,CAA1C;AAcA5E,EAAAA,WAAW,CAACiB,MAAD,EAAS,cAAT,EAAyBqC,wBAAzB,CAAX;AACAtD,EAAAA,WAAW,CAACiB,MAAD,EAAS,cAAT,EAAyBkD,wBAAzB,CAAX;AACAnE,EAAAA,WAAW,CAACiB,MAAD,EAAS,aAAT,EAAwBmD,uBAAxB,CAAX;AACApE,EAAAA,WAAW,CAACiB,MAAD,EAAS,kBAAT,EAA6BoD,sBAA7B,CAAX;AACArE,EAAAA,WAAW,CACTiB,MAAM,CAAC6D,QADE,EAEThF,UAAU,CAACiF,aAFF,EAGTzB,wBAHS,CAAX;AAMA,MAAM0B,oBAAoB,GAAG9F,WAAW,CAACgC,YAAD,CAAxC;AACArC,EAAAA,SAAS,CAAC,YAAM;AACd,QAAImG,oBAAoB,KAAK9D,YAAzB,IAAyCA,YAAY,KAAKS,UAA9D,EAA0E;AACxExB,MAAAA,GAAG,CAAC4D,KAAJ,CAAU,+BAAV;AACA,UAAML,OAAO,GAAGjE,WAAW,CAACwF,mBAAZ,CACd/D,YADc,EAEd8B,gBAFc,CAAhB,CAFwE,CAMxE;;AACA,aAAO/B,MAAM,CAAC+C,IAAP,CAAYC,YAAZ,CAAyBC,MAAzB,GAAkC,CAAzC,EAA4C;AAC1CjD,QAAAA,MAAM,CAAC+C,IAAP,CAAYC,YAAZ,CAAyB,CAAzB,EAA4BiB,MAA5B;AACD,OATuE,CAWxE;;;AACA,WAAK,IAAIC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGzB,OAAO,CAACQ,MAA5B,EAAoCiB,CAAC,IAAI,CAAzC,EAA4C;AAC1ClE,QAAAA,MAAM,CAAC+C,IAAP,CAAYoB,QAAZ,CAAqB1B,OAAO,CAACyB,CAAD,CAA5B;AACD;;AAED3D,MAAAA,mBAAmB,CAACP,MAAM,CAAC+C,IAAP,CAAYC,YAAZ,CAAyBC,MAAzB,KAAoC,CAArC,CAAnB;AACD;AACF,GAnBQ,EAmBN,CACDlB,gBADC,EAED/B,MAFC,EAGDC,YAHC,EAIDS,UAJC,EAKDyB,YALC,EAMD4B,oBANC,CAnBM,CAAT;AA4BA,sBACE,0CACGzD,gBAAgB,IAAIP,cADvB,EAEGrC,KAAK,CAAC0G,QAAN,CAAeC,GAAf,CAAmBvE,QAAnB,EAA6B,UAAAwE,KAAK;AAAA,WACjCA,KAAK,gBACD5G,KAAK,CAAC6G,YAAN,CAAmBD,KAAnB,EAA0C;AACxCzE,MAAAA,EAAE,EAAFA,EADwC;AAExCG,MAAAA,MAAM,EAANA,MAFwC;AAGxCmC,MAAAA,YAAY,EAAZA,YAHwC;AAIxCjB,MAAAA,iBAAiB,EAAjBA;AAJwC,KAA1C,CADC,GAOD,IAR6B;AAAA,GAAlC,CAFH,CADF;AAeD,CAvMM;AAyMPtB,eAAe,CAAC4E,SAAhB,GAA4B;AAC1B3E,EAAAA,EAAE,EAAE9B,SAAS,CAAC0G,MAAV,CAAiBC,UADK;AAE1B5E,EAAAA,QAAQ,EAAE/B,SAAS,CAAC4G,IAFM;AAG1BvE,EAAAA,IAAI,EAAErC,SAAS,CAAC6G,KAAV,CAAgB,EAAhB,CAHoB;AAI1B7E,EAAAA,cAAc,EAAEhC,SAAS,CAAC4G,IAJA;AAK1B3E,EAAAA,MAAM,EAAElB,WAAW,CAAC+F,MAAZ,CAAmBH,UALD;AAM1BzE,EAAAA,YAAY,EAAElC,SAAS,CAAC+G,OAAV,CAAkB/G,SAAS,CAAC6G,KAAV,CAAgB,EAAhB,CAAlB,CANY;AAO1B1E,EAAAA,cAAc,EAAEnC,SAAS,CAACgH;AAPA,CAA5B;AAUA,eAAenF,eAAf","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","isDashboardInitialized","setIsDashboardInitialized","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 const [isDashboardInitialized, setIsDashboardInitialized] = useState(false);\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 if (!isDashboardInitialized) {\n onLayoutInitialized();\n setIsDashboardInitialized(true);\n }\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 }, [\n dehydrateComponent,\n isDashboardInitialized,\n isItemDragging,\n lastConfig,\n layout,\n onLayoutChange,\n onLayoutInitialized,\n ]);\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 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"}