@deephaven/dashboard 0.50.1-beta.2 → 0.50.1-beta.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardLayout.d.ts","sourceRoot":"","sources":["../src/DashboardLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,aAAa,EAMd,MAAM,OAAO,CAAC;AACf,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,YAAY,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,EAEV,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAKlC,OAAqB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAU5D,OAAO,EAGL,sBAAsB,EACtB,oBAAoB,EAErB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,MAAM,qBAAqB,GAAG,cAAc,EAAE,CAAC;AAarD,KAAK,aAAa,GAAG;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IAGX,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,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;IAEjC,wCAAwC;IACxC,YAAY,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,QAAQ,EACR,cAA+C,EAC/C,MAAM,EACN,YAAoC,EACpC,cAAiC,EACjC,mBAAsC,EACtC,OAAwB,EACxB,SAA4B,EAC5B,YAAoC,GACrC,EAAE,oBAAoB,GAAG,GAAG,CAAC,OAAO,CAsQpC;yBAjRe,eAAe;;;;;;;;;;;;;;;;;;;;;;;;AA8R/B,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"DashboardLayout.d.ts","sourceRoot":"","sources":["../src/DashboardLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,aAAa,EAMd,MAAM,OAAO,CAAC;AACf,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,YAAY,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,EAEV,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAKlC,OAAqB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAW5D,OAAO,EAEL,sBAAsB,EACtB,oBAAoB,EAErB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,MAAM,qBAAqB,GAAG,cAAc,EAAE,CAAC;AAarD,KAAK,aAAa,GAAG;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IAGX,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,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;IAEjC,wCAAwC;IACxC,YAAY,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,QAAQ,EACR,cAA+C,EAC/C,MAAM,EACN,YAAoC,EACpC,cAAiC,EACjC,mBAAsC,EACtC,OAAwB,EACxB,SAA4B,EAC5B,YAAoC,GACrC,EAAE,oBAAoB,GAAG,GAAG,CAAC,OAAO,CAoQpC;yBA/Qe,eAAe;;;;;;;;;;;;;;;;;;;;;;;;AA4R/B,eAAe,eAAe,CAAC"}
@@ -11,11 +11,10 @@ import { useDispatch, useSelector } from 'react-redux';
11
11
  import PanelManager from "./PanelManager.js";
12
12
  import PanelErrorBoundary from "./PanelErrorBoundary.js";
13
13
  import LayoutUtils from "./layout/LayoutUtils.js";
14
- import { dehydrate as dehydrateDefault, hydrate as hydrateDefault } from "./DashboardUtils.js";
14
+ import { canHaveRef, dehydrate as dehydrateDefault, hydrate as hydrateDefault } from "./DashboardUtils.js";
15
15
  import PanelEvent from "./PanelEvent.js";
16
16
  import { GLPropTypes, useListener } from "./layout/index.js";
17
17
  import { getDashboardData, updateDashboardData } from "./redux/index.js";
18
- import { isWrappedComponent } from "./DashboardPlugin.js";
19
18
  import DashboardPanelWrapper from "./DashboardPanelWrapper.js";
20
19
  import { jsx as _jsx } from "react/jsx-runtime";
21
20
  import { Fragment as _Fragment } from "react/jsx-runtime";
@@ -57,6 +56,7 @@ export function DashboardLayout(_ref) {
57
56
  var hydrateMap = useMemo(() => new Map(), []);
58
57
  var dehydrateMap = useMemo(() => new Map(), []);
59
58
  var registerComponent = useCallback(function (name, componentType) {
59
+ var _componentType$displa;
60
60
  var componentHydrate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : hydrate;
61
61
  var componentDehydrate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : dehydrate;
62
62
  log.debug2('registerComponent', name, componentType, componentHydrate, componentDehydrate);
@@ -65,14 +65,12 @@ export function DashboardLayout(_ref) {
65
65
  var CType = componentType;
66
66
  var PanelWrapperType = panelWrapper;
67
67
 
68
- /*
69
- Checking for class components will let us silence the React warning
70
- about assigning refs to function components not using forwardRef.
71
- The ref is used to detect changes to class component state so we
72
- can track changes to panelState. We should opt for more explicit
73
- state changes in the future and in functional components.
74
- */
75
- var isClassComponent = isWrappedComponent(CType) && CType.WrappedComponent.prototype != null && CType.WrappedComponent.prototype.isReactComponent != null || CType.prototype != null && CType.prototype.isReactComponent != null;
68
+ /**
69
+ * The ref is used to detect changes to class component state so we
70
+ * can track changes to panelState. We should opt for more explicit
71
+ * state changes in the future and in functional components.
72
+ */
73
+ var hasRef = canHaveRef(CType);
76
74
 
77
75
  // Props supplied by GoldenLayout
78
76
  var {
@@ -83,7 +81,7 @@ export function DashboardLayout(_ref) {
83
81
  glContainer: glContainer,
84
82
  glEventHub: glEventHub,
85
83
  children: /*#__PURE__*/_jsx(PanelWrapperType, _objectSpread(_objectSpread({}, props), {}, {
86
- children: isClassComponent ?
84
+ children: hasRef ?
87
85
  /*#__PURE__*/
88
86
  // eslint-disable-next-line react/jsx-props-no-spreading
89
87
  _jsx(CType, _objectSpread(_objectSpread({}, props), {}, {
@@ -95,6 +93,7 @@ export function DashboardLayout(_ref) {
95
93
  }))
96
94
  });
97
95
  }
96
+ wrappedComponent.displayName = "DashboardWrapper(".concat((_componentType$displa = componentType.displayName) !== null && _componentType$displa !== void 0 ? _componentType$displa : name, ")");
98
97
  var cleanup = layout.registerComponent(name, /*#__PURE__*/React.forwardRef(wrappedComponent));
99
98
  hydrateMap.set(name, componentHydrate);
100
99
  dehydrateMap.set(name, componentDehydrate);
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardLayout.js","names":["React","useCallback","useEffect","useMemo","useState","PropTypes","Log","usePrevious","useDispatch","useSelector","PanelManager","PanelErrorBoundary","LayoutUtils","dehydrate","dehydrateDefault","hydrate","hydrateDefault","PanelEvent","GLPropTypes","useListener","getDashboardData","updateDashboardData","isWrappedComponent","DashboardPanelWrapper","log","module","EMPTY_OBJECT","Object","freeze","DEFAULT_LAYOUT_CONFIG","DEFAULT_CALLBACK","undefined","FALLBACK_CALLBACK","props","DashboardLayout","id","children","emptyDashboard","layout","layoutConfig","onLayoutChange","onLayoutInitialized","panelWrapper","dispatch","data","state","isDashboardEmpty","setIsDashboardEmpty","isItemDragging","setIsItemDragging","lastConfig","setLastConfig","initialClosedPanels","closed","isDashboardInitialized","setIsDashboardInitialized","layoutChildren","setLayoutChildren","getReactChildren","hydrateMap","Map","dehydrateMap","registerComponent","name","componentType","componentHydrate","componentDehydrate","debug2","wrappedComponent","ref","CType","PanelWrapperType","isClassComponent","WrappedComponent","prototype","isReactComponent","glContainer","glEventHub","cleanup","forwardRef","set","hydrateComponent","get","dehydrateComponent","config","panelManager","openedMap","handleLayoutStateChanged","glConfig","toConfig","contentConfig","content","dehydratedLayoutConfig","dehydrateLayoutConfig","hasChanged","isEqual","debug","root","contentItems","length","handleLayoutItemPickedUp","component","componentId","getIdFromContainer","eventHub","emit","DRAGGING","handleLayoutItemDropped","DROPPED","handleComponentCreated","item","element","cssComponent","replace","toLowerCase","cssClass","addClass","handleReactChildrenChange","TITLE_CHANGED","previousLayoutConfig","loadNewConfig","hydrateLayoutConfig","remove","i","addChild","Children","map","child","cloneElement","propTypes","string","isRequired","node","shape","Layout","arrayOf","func"],"sources":["../src/DashboardLayout.tsx"],"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 from '@deephaven/golden-layout';\nimport type {\n Container,\n ItemConfigType,\n ReactComponentConfig,\n} from '@deephaven/golden-layout';\nimport Log from '@deephaven/log';\nimport { usePrevious } from '@deephaven/react-hooks';\nimport { RootState } from '@deephaven/redux';\nimport { useDispatch, useSelector } 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';\nimport {\n isWrappedComponent,\n PanelComponentType,\n PanelDehydrateFunction,\n PanelHydrateFunction,\n PanelProps,\n} from './DashboardPlugin';\nimport DashboardPanelWrapper from './DashboardPanelWrapper';\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 = (): void => 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): unknown => props;\n\ntype DashboardData = {\n closed?: ClosedPanels;\n};\n\ninterface DashboardLayoutProps {\n id: string;\n\n // Default hydrate/dehydration functions\n hydrate?: PanelHydrateFunction;\n dehydrate?: PanelDehydrateFunction;\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 /** Component to wrap each panel with */\n panelWrapper?: ComponentType;\n}\n\n/**\n * DashboardLayout component. Handles hydrating, dehydrating components, listening for dragging panels.\n */\nexport function 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 hydrate = hydrateDefault,\n dehydrate = dehydrateDefault,\n panelWrapper = DashboardPanelWrapper,\n}: DashboardLayoutProps): JSX.Element {\n const dispatch = useDispatch();\n const data =\n useSelector<RootState>(state => getDashboardData(state, id)) ??\n 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<ReactComponentConfig[] | undefined>(\n (data as DashboardData)?.closed ?? []\n );\n const [isDashboardInitialized, setIsDashboardInitialized] = useState(false);\n const [layoutChildren, setLayoutChildren] = useState(\n layout.getReactChildren()\n );\n\n const hydrateMap = useMemo(() => new Map(), []);\n const dehydrateMap = useMemo(() => new Map(), []);\n const registerComponent = useCallback(\n (\n name: string,\n componentType: PanelComponentType,\n componentHydrate = hydrate,\n componentDehydrate = dehydrate\n ) => {\n log.debug2(\n 'registerComponent',\n name,\n componentType,\n componentHydrate,\n componentDehydrate\n );\n\n function wrappedComponent(\n props: PanelProps,\n ref: React.Ref<unknown>\n ): JSX.Element {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const CType = componentType as any;\n const PanelWrapperType = panelWrapper;\n\n /*\n Checking for class components will let us silence the React warning\n about assigning refs to function components not using forwardRef.\n The ref is used to detect changes to class component state so we\n can track changes to panelState. We should opt for more explicit\n state changes in the future and in functional components.\n */\n const isClassComponent =\n (isWrappedComponent(CType) &&\n CType.WrappedComponent.prototype != null &&\n CType.WrappedComponent.prototype.isReactComponent != null) ||\n (CType.prototype != null && CType.prototype.isReactComponent != null);\n\n // Props supplied by GoldenLayout\n const { glContainer, glEventHub } = props;\n return (\n <PanelErrorBoundary glContainer={glContainer} glEventHub={glEventHub}>\n {/* eslint-disable-next-line react/jsx-props-no-spreading */}\n <PanelWrapperType {...props}>\n {isClassComponent ? (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <CType {...props} ref={ref} />\n ) : (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <CType {...props} />\n )}\n </PanelWrapperType>\n </PanelErrorBoundary>\n );\n }\n\n const cleanup = layout.registerComponent(\n name,\n React.forwardRef(wrappedComponent)\n );\n hydrateMap.set(name, componentHydrate);\n dehydrateMap.set(name, componentDehydrate);\n return cleanup;\n },\n [hydrate, dehydrate, hydrateMap, dehydrateMap, layout, panelWrapper]\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 setLayoutChildren(layout.getReactChildren());\n }\n }, [\n dehydrateComponent,\n isDashboardInitialized,\n isItemDragging,\n lastConfig,\n layout,\n onLayoutChange,\n onLayoutInitialized,\n ]);\n\n const handleLayoutItemPickedUp = useCallback(\n (component: Container) => {\n const componentId = LayoutUtils.getIdFromContainer(component);\n layout.eventHub.emit(PanelEvent.DRAGGING, componentId);\n setIsItemDragging(true);\n },\n [layout.eventHub]\n );\n\n const handleLayoutItemDropped = useCallback(\n (component: Container) => {\n const componentId = LayoutUtils.getIdFromContainer(component);\n layout.eventHub.emit(PanelEvent.DROPPED, componentId);\n setIsItemDragging(false);\n },\n [layout.eventHub]\n );\n\n const handleComponentCreated = useCallback(item => {\n log.debug2('handleComponentCreated', item);\n\n if (\n item == null ||\n item.config == null ||\n item.config.component == null ||\n item.element == null\n ) {\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 const handleReactChildrenChange = useCallback(() => {\n setLayoutChildren(layout.getReactChildren());\n }, [layout]);\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 useListener(layout, 'reactChildrenChanged', handleReactChildrenChange);\n\n const previousLayoutConfig = usePrevious(layoutConfig);\n useEffect(\n function loadNewConfig() {\n if (\n previousLayoutConfig !== layoutConfig &&\n layoutConfig !== lastConfig\n ) {\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 [\n hydrateComponent,\n layout,\n layoutConfig,\n lastConfig,\n panelManager,\n previousLayoutConfig,\n ]\n );\n\n return (\n <>\n {isDashboardEmpty && emptyDashboard}\n {layoutChildren}\n {React.Children.map(children, child =>\n child != null\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"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardLayout.js","names":["React","useCallback","useEffect","useMemo","useState","PropTypes","Log","usePrevious","useDispatch","useSelector","PanelManager","PanelErrorBoundary","LayoutUtils","canHaveRef","dehydrate","dehydrateDefault","hydrate","hydrateDefault","PanelEvent","GLPropTypes","useListener","getDashboardData","updateDashboardData","DashboardPanelWrapper","log","module","EMPTY_OBJECT","Object","freeze","DEFAULT_LAYOUT_CONFIG","DEFAULT_CALLBACK","undefined","FALLBACK_CALLBACK","props","DashboardLayout","id","children","emptyDashboard","layout","layoutConfig","onLayoutChange","onLayoutInitialized","panelWrapper","dispatch","data","state","isDashboardEmpty","setIsDashboardEmpty","isItemDragging","setIsItemDragging","lastConfig","setLastConfig","initialClosedPanels","closed","isDashboardInitialized","setIsDashboardInitialized","layoutChildren","setLayoutChildren","getReactChildren","hydrateMap","Map","dehydrateMap","registerComponent","name","componentType","componentHydrate","componentDehydrate","debug2","wrappedComponent","ref","CType","PanelWrapperType","hasRef","glContainer","glEventHub","displayName","cleanup","forwardRef","set","hydrateComponent","get","dehydrateComponent","config","panelManager","openedMap","handleLayoutStateChanged","glConfig","toConfig","contentConfig","content","dehydratedLayoutConfig","dehydrateLayoutConfig","hasChanged","isEqual","debug","root","contentItems","length","handleLayoutItemPickedUp","component","componentId","getIdFromContainer","eventHub","emit","DRAGGING","handleLayoutItemDropped","DROPPED","handleComponentCreated","item","element","cssComponent","replace","toLowerCase","cssClass","addClass","handleReactChildrenChange","TITLE_CHANGED","previousLayoutConfig","loadNewConfig","hydrateLayoutConfig","remove","i","addChild","Children","map","child","cloneElement","propTypes","string","isRequired","node","shape","Layout","arrayOf","func"],"sources":["../src/DashboardLayout.tsx"],"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 from '@deephaven/golden-layout';\nimport type {\n Container,\n ItemConfigType,\n ReactComponentConfig,\n} from '@deephaven/golden-layout';\nimport Log from '@deephaven/log';\nimport { usePrevious } from '@deephaven/react-hooks';\nimport { RootState } from '@deephaven/redux';\nimport { useDispatch, useSelector } from 'react-redux';\nimport PanelManager, { ClosedPanels } from './PanelManager';\nimport PanelErrorBoundary from './PanelErrorBoundary';\nimport LayoutUtils from './layout/LayoutUtils';\nimport {\n canHaveRef,\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';\nimport {\n PanelComponentType,\n PanelDehydrateFunction,\n PanelHydrateFunction,\n PanelProps,\n} from './DashboardPlugin';\nimport DashboardPanelWrapper from './DashboardPanelWrapper';\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 = (): void => 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): unknown => props;\n\ntype DashboardData = {\n closed?: ClosedPanels;\n};\n\ninterface DashboardLayoutProps {\n id: string;\n\n // Default hydrate/dehydration functions\n hydrate?: PanelHydrateFunction;\n dehydrate?: PanelDehydrateFunction;\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 /** Component to wrap each panel with */\n panelWrapper?: ComponentType;\n}\n\n/**\n * DashboardLayout component. Handles hydrating, dehydrating components, listening for dragging panels.\n */\nexport function 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 hydrate = hydrateDefault,\n dehydrate = dehydrateDefault,\n panelWrapper = DashboardPanelWrapper,\n}: DashboardLayoutProps): JSX.Element {\n const dispatch = useDispatch();\n const data =\n useSelector<RootState>(state => getDashboardData(state, id)) ??\n 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<ReactComponentConfig[] | undefined>(\n (data as DashboardData)?.closed ?? []\n );\n const [isDashboardInitialized, setIsDashboardInitialized] = useState(false);\n const [layoutChildren, setLayoutChildren] = useState(\n layout.getReactChildren()\n );\n\n const hydrateMap = useMemo(() => new Map(), []);\n const dehydrateMap = useMemo(() => new Map(), []);\n const registerComponent = useCallback(\n (\n name: string,\n componentType: PanelComponentType,\n componentHydrate = hydrate,\n componentDehydrate = dehydrate\n ) => {\n log.debug2(\n 'registerComponent',\n name,\n componentType,\n componentHydrate,\n componentDehydrate\n );\n\n function wrappedComponent(\n props: PanelProps,\n ref: React.Ref<unknown>\n ): JSX.Element {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const CType = componentType as any;\n const PanelWrapperType = panelWrapper;\n\n /**\n * The ref is used to detect changes to class component state so we\n * can track changes to panelState. We should opt for more explicit\n * state changes in the future and in functional components.\n */\n const hasRef = canHaveRef(CType);\n\n // Props supplied by GoldenLayout\n const { glContainer, glEventHub } = props;\n return (\n <PanelErrorBoundary glContainer={glContainer} glEventHub={glEventHub}>\n {/* eslint-disable-next-line react/jsx-props-no-spreading */}\n <PanelWrapperType {...props}>\n {hasRef ? (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <CType {...props} ref={ref} />\n ) : (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <CType {...props} />\n )}\n </PanelWrapperType>\n </PanelErrorBoundary>\n );\n }\n\n wrappedComponent.displayName = `DashboardWrapper(${\n componentType.displayName ?? name\n })`;\n\n const cleanup = layout.registerComponent(\n name,\n React.forwardRef(wrappedComponent)\n );\n hydrateMap.set(name, componentHydrate);\n dehydrateMap.set(name, componentDehydrate);\n return cleanup;\n },\n [hydrate, dehydrate, hydrateMap, dehydrateMap, layout, panelWrapper]\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 setLayoutChildren(layout.getReactChildren());\n }\n }, [\n dehydrateComponent,\n isDashboardInitialized,\n isItemDragging,\n lastConfig,\n layout,\n onLayoutChange,\n onLayoutInitialized,\n ]);\n\n const handleLayoutItemPickedUp = useCallback(\n (component: Container) => {\n const componentId = LayoutUtils.getIdFromContainer(component);\n layout.eventHub.emit(PanelEvent.DRAGGING, componentId);\n setIsItemDragging(true);\n },\n [layout.eventHub]\n );\n\n const handleLayoutItemDropped = useCallback(\n (component: Container) => {\n const componentId = LayoutUtils.getIdFromContainer(component);\n layout.eventHub.emit(PanelEvent.DROPPED, componentId);\n setIsItemDragging(false);\n },\n [layout.eventHub]\n );\n\n const handleComponentCreated = useCallback(item => {\n log.debug2('handleComponentCreated', item);\n\n if (\n item == null ||\n item.config == null ||\n item.config.component == null ||\n item.element == null\n ) {\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 const handleReactChildrenChange = useCallback(() => {\n setLayoutChildren(layout.getReactChildren());\n }, [layout]);\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 useListener(layout, 'reactChildrenChanged', handleReactChildrenChange);\n\n const previousLayoutConfig = usePrevious(layoutConfig);\n useEffect(\n function loadNewConfig() {\n if (\n previousLayoutConfig !== layoutConfig &&\n layoutConfig !== lastConfig\n ) {\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 [\n hydrateComponent,\n layout,\n layoutConfig,\n lastConfig,\n panelManager,\n previousLayoutConfig,\n ]\n );\n\n return (\n <>\n {isDashboardEmpty && emptyDashboard}\n {layoutChildren}\n {React.Children.map(children, child =>\n child != null\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"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { DehydratedDashboardPanelProps, PanelConfig } from './DashboardPlugin';
1
+ import { DehydratedDashboardPanelProps, PanelComponentType, PanelConfig } from './DashboardPlugin';
2
2
  /**
3
3
  * Dehydrate an existing panel to allow it to be serialized/saved.
4
4
  * Just takes what's in the panels `metadata` in the props and `panelState` in
@@ -15,6 +15,13 @@ export declare function dehydrate(config: PanelConfig): PanelConfig | null;
15
15
  * @returns The hydrated panel props
16
16
  */
17
17
  export declare function hydrate<T extends DehydratedDashboardPanelProps>(props: T, localDashboardId?: string): T;
18
+ /**
19
+ * Checks if a panel component can take a ref. Helps silence react dev errors
20
+ * if a ref is passed to a functional component without forwardRef.
21
+ * @param component The panel component to check if it can take a ref
22
+ * @returns Wheter the component can take a ref or not
23
+ */
24
+ export declare function canHaveRef(component: PanelComponentType): boolean;
18
25
  declare const _default: {
19
26
  dehydrate: typeof dehydrate;
20
27
  hydrate: typeof hydrate;
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardUtils.d.ts","sourceRoot":"","sources":["../src/DashboardUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE/E;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAqBjE;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,6BAA6B,EAC7D,KAAK,EAAE,CAAC,EACR,gBAAgB,SAAK,GACpB,CAAC,CAMH;;;;;AAED,wBAGE"}
1
+ {"version":3,"file":"DashboardUtils.d.ts","sourceRoot":"","sources":["../src/DashboardUtils.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,6BAA6B,EAE7B,kBAAkB,EAClB,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAE3B;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAqBjE;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,6BAA6B,EAC7D,KAAK,EAAE,CAAC,EACR,gBAAgB,SAAK,GACpB,CAAC,CAMH;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,kBAAkB,GAAG,OAAO,CAejE;;;;;AAED,wBAGE"}
@@ -3,6 +3,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
3
3
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4
4
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
5
5
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
6
+ import { ForwardRef } from 'react-is';
7
+ import { isWrappedComponent } from "./DashboardPlugin.js";
6
8
  /**
7
9
  * Dehydrate an existing panel to allow it to be serialized/saved.
8
10
  * Just takes what's in the panels `metadata` in the props and `panelState` in
@@ -55,6 +57,19 @@ export function hydrate(props) {
55
57
  localDashboardId
56
58
  });
57
59
  }
60
+
61
+ /**
62
+ * Checks if a panel component can take a ref. Helps silence react dev errors
63
+ * if a ref is passed to a functional component without forwardRef.
64
+ * @param component The panel component to check if it can take a ref
65
+ * @returns Wheter the component can take a ref or not
66
+ */
67
+ export function canHaveRef(component) {
68
+ // Might be a redux connect wrapped component
69
+ var isClassComponent = isWrappedComponent(component) && component.WrappedComponent.prototype != null && component.WrappedComponent.prototype.isReactComponent != null || component.prototype != null && component.prototype.isReactComponent != null;
70
+ var isForwardRef = !isWrappedComponent(component) && '$$typeof' in component && component.$$typeof === ForwardRef;
71
+ return isClassComponent || isForwardRef;
72
+ }
58
73
  export default {
59
74
  dehydrate,
60
75
  hydrate
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardUtils.js","names":["dehydrate","config","props","componentState","metadata","panelState","newProps","type","hydrate","localDashboardId"],"sources":["../src/DashboardUtils.ts"],"sourcesContent":["import { DehydratedDashboardPanelProps, PanelConfig } from './DashboardPlugin';\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 != null) {\n newProps.metadata = metadata;\n }\n if (panelState != null) {\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<T extends DehydratedDashboardPanelProps>(\n props: T,\n localDashboardId = ''\n): T {\n return {\n metadata: {},\n ...props,\n localDashboardId,\n };\n}\n\nexport default {\n dehydrate,\n hydrate,\n};\n"],"mappings":";;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,SAAS,CAACC,MAAmB,EAAsB;EACjE,IAAM;IAAEC,KAAK;IAAEC;EAAe,CAAC,GAAGF,MAAM;EACxC,IAAM;IAAEG;EAAS,CAAC,GAAGF,KAAK;EAC1B,IAAI;IAAEG,UAAU,GAAG;EAAK,CAAC,GAAGH,KAAK;EACjC,IAAIC,cAAc,EAAE;IAClB,CAAC;MAAEE;IAAW,CAAC,GAAGF,cAAc;EAClC;EACA,IAAMG,QAAiC,GAAG,CAAC,CAAC;EAC5C,IAAIF,QAAQ,IAAI,IAAI,EAAE;IACpBE,QAAQ,CAACF,QAAQ,GAAGA,QAAQ;EAC9B;EACA,IAAIC,UAAU,IAAI,IAAI,EAAE;IACtBC,QAAQ,CAACD,UAAU,GAAGA,UAAU;EAClC;EAEA,uCACKJ,MAAM;IACTE,cAAc,EAAE,IAAI;IACpBD,KAAK,EAAEI,QAAQ;IACfC,IAAI,EAAE;EAAiB;AAE3B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,OAAO,CACrBN,KAAQ,EAEL;EAAA,IADHO,gBAAgB,uEAAG,EAAE;EAErB;IACEL,QAAQ,EAAE,CAAC;EAAC,GACTF,KAAK;IACRO;EAAgB;AAEpB;AAEA,eAAe;EACbT,SAAS;EACTQ;AACF,CAAC"}
1
+ {"version":3,"file":"DashboardUtils.js","names":["ForwardRef","isWrappedComponent","dehydrate","config","props","componentState","metadata","panelState","newProps","type","hydrate","localDashboardId","canHaveRef","component","isClassComponent","WrappedComponent","prototype","isReactComponent","isForwardRef","$$typeof"],"sources":["../src/DashboardUtils.tsx"],"sourcesContent":["import { ForwardRef } from 'react-is';\nimport {\n DehydratedDashboardPanelProps,\n isWrappedComponent,\n PanelComponentType,\n PanelConfig,\n} from './DashboardPlugin';\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 != null) {\n newProps.metadata = metadata;\n }\n if (panelState != null) {\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<T extends DehydratedDashboardPanelProps>(\n props: T,\n localDashboardId = ''\n): T {\n return {\n metadata: {},\n ...props,\n localDashboardId,\n };\n}\n\n/**\n * Checks if a panel component can take a ref. Helps silence react dev errors\n * if a ref is passed to a functional component without forwardRef.\n * @param component The panel component to check if it can take a ref\n * @returns Wheter the component can take a ref or not\n */\nexport function canHaveRef(component: PanelComponentType): boolean {\n // Might be a redux connect wrapped component\n const isClassComponent =\n (isWrappedComponent(component) &&\n component.WrappedComponent.prototype != null &&\n component.WrappedComponent.prototype.isReactComponent != null) ||\n (component.prototype != null &&\n component.prototype.isReactComponent != null);\n\n const isForwardRef =\n !isWrappedComponent(component) &&\n '$$typeof' in component &&\n component.$$typeof === ForwardRef;\n\n return isClassComponent || isForwardRef;\n}\n\nexport default {\n dehydrate,\n hydrate,\n};\n"],"mappings":";;;;;AAAA,SAASA,UAAU,QAAQ,UAAU;AAAC,SAGpCC,kBAAkB;AAKpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,SAAS,CAACC,MAAmB,EAAsB;EACjE,IAAM;IAAEC,KAAK;IAAEC;EAAe,CAAC,GAAGF,MAAM;EACxC,IAAM;IAAEG;EAAS,CAAC,GAAGF,KAAK;EAC1B,IAAI;IAAEG,UAAU,GAAG;EAAK,CAAC,GAAGH,KAAK;EACjC,IAAIC,cAAc,EAAE;IAClB,CAAC;MAAEE;IAAW,CAAC,GAAGF,cAAc;EAClC;EACA,IAAMG,QAAiC,GAAG,CAAC,CAAC;EAC5C,IAAIF,QAAQ,IAAI,IAAI,EAAE;IACpBE,QAAQ,CAACF,QAAQ,GAAGA,QAAQ;EAC9B;EACA,IAAIC,UAAU,IAAI,IAAI,EAAE;IACtBC,QAAQ,CAACD,UAAU,GAAGA,UAAU;EAClC;EAEA,uCACKJ,MAAM;IACTE,cAAc,EAAE,IAAI;IACpBD,KAAK,EAAEI,QAAQ;IACfC,IAAI,EAAE;EAAiB;AAE3B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,OAAO,CACrBN,KAAQ,EAEL;EAAA,IADHO,gBAAgB,uEAAG,EAAE;EAErB;IACEL,QAAQ,EAAE,CAAC;EAAC,GACTF,KAAK;IACRO;EAAgB;AAEpB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAU,CAACC,SAA6B,EAAW;EACjE;EACA,IAAMC,gBAAgB,GACnBb,kBAAkB,CAACY,SAAS,CAAC,IAC5BA,SAAS,CAACE,gBAAgB,CAACC,SAAS,IAAI,IAAI,IAC5CH,SAAS,CAACE,gBAAgB,CAACC,SAAS,CAACC,gBAAgB,IAAI,IAAI,IAC9DJ,SAAS,CAACG,SAAS,IAAI,IAAI,IAC1BH,SAAS,CAACG,SAAS,CAACC,gBAAgB,IAAI,IAAK;EAEjD,IAAMC,YAAY,GAChB,CAACjB,kBAAkB,CAACY,SAAS,CAAC,IAC9B,UAAU,IAAIA,SAAS,IACvBA,SAAS,CAACM,QAAQ,KAAKnB,UAAU;EAEnC,OAAOc,gBAAgB,IAAII,YAAY;AACzC;AAEA,eAAe;EACbhB,SAAS;EACTQ;AACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deephaven/dashboard",
3
- "version": "0.50.1-beta.2+876a6acd",
3
+ "version": "0.50.1-beta.3+94cc82c3",
4
4
  "description": "Deephaven Dashboard",
5
5
  "author": "Deephaven Data Labs LLC",
6
6
  "license": "Apache-2.0",
@@ -22,13 +22,13 @@
22
22
  "build:sass": "sass --embed-sources --load-path=../../node_modules ./src:./dist"
23
23
  },
24
24
  "dependencies": {
25
- "@deephaven/components": "^0.50.1-beta.2+876a6acd",
26
- "@deephaven/golden-layout": "^0.50.1-beta.2+876a6acd",
27
- "@deephaven/jsapi-bootstrap": "^0.50.1-beta.2+876a6acd",
28
- "@deephaven/log": "^0.50.1-beta.2+876a6acd",
29
- "@deephaven/react-hooks": "^0.50.1-beta.2+876a6acd",
30
- "@deephaven/redux": "^0.50.1-beta.2+876a6acd",
31
- "@deephaven/utils": "^0.50.1-beta.2+876a6acd",
25
+ "@deephaven/components": "^0.50.1-beta.3+94cc82c3",
26
+ "@deephaven/golden-layout": "^0.50.1-beta.3+94cc82c3",
27
+ "@deephaven/jsapi-bootstrap": "^0.50.1-beta.3+94cc82c3",
28
+ "@deephaven/log": "^0.50.1-beta.3+94cc82c3",
29
+ "@deephaven/react-hooks": "^0.50.1-beta.3+94cc82c3",
30
+ "@deephaven/redux": "^0.50.1-beta.3+94cc82c3",
31
+ "@deephaven/utils": "^0.50.1-beta.3+94cc82c3",
32
32
  "deep-equal": "^2.0.5",
33
33
  "lodash.ismatch": "^4.1.1",
34
34
  "lodash.throttle": "^4.1.1",
@@ -38,10 +38,11 @@
38
38
  "peerDependencies": {
39
39
  "react": "^17.0.0",
40
40
  "react-dom": "^17.0.0",
41
+ "react-is": "^17.0.0",
41
42
  "react-redux": "^7.2.4"
42
43
  },
43
44
  "devDependencies": {
44
- "@deephaven/mocks": "^0.50.1-beta.2+876a6acd",
45
+ "@deephaven/mocks": "^0.50.1-beta.3+94cc82c3",
45
46
  "@types/lodash.ismatch": "^4.4.0"
46
47
  },
47
48
  "files": [
@@ -50,5 +51,5 @@
50
51
  "publishConfig": {
51
52
  "access": "public"
52
53
  },
53
- "gitHead": "876a6acd00d239f3ac7df21e27db74a16e4fd1b7"
54
+ "gitHead": "94cc82c379103326669d477ae96ec253041f2967"
54
55
  }