@grafana/scenes 0.24.0 → 0.24.1

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ # v0.24.1 (Fri Aug 18 2023)
2
+
3
+ #### 🐛 Bug Fix
4
+
5
+ - SceneObject: Warn if parent is already set to another SceneObject [#284](https://github.com/grafana/scenes/pull/284) ([@torkelo](https://github.com/torkelo))
6
+ - VizPanel: Handle plugin not found scenario correctly [#287](https://github.com/grafana/scenes/pull/287) ([@dprokop](https://github.com/dprokop))
7
+ - VariableValueSelectors: Don't wrap labels [#285](https://github.com/grafana/scenes/pull/285) ([@dprokop](https://github.com/dprokop))
8
+ - SceneDebugger: Scene graph explore & state viewer [#262](https://github.com/grafana/scenes/pull/262) ([@torkelo](https://github.com/torkelo))
9
+
10
+ #### Authors: 2
11
+
12
+ - Dominik Prokop ([@dprokop](https://github.com/dprokop))
13
+ - Torkel Ödegaard ([@torkelo](https://github.com/torkelo))
14
+
15
+ ---
16
+
1
17
  # v0.24.0 (Fri Aug 04 2023)
2
18
 
3
19
  #### 🚀 Enhancement
@@ -1,12 +1,13 @@
1
1
  import { PluginPage } from '@grafana/runtime';
2
2
  import React, { useState, useLayoutEffect } from 'react';
3
+ import { SceneDebugger } from '../SceneDebugger/SceneDebugger.js';
3
4
  import { SceneAppPage } from './SceneAppPage.js';
4
5
  import { useAppQueryParams, getUrlWithAppState, renderSceneComponentWithRouteProps } from './utils.js';
5
6
 
6
7
  function SceneAppPageView({ page, routeProps }) {
7
8
  const containerPage = getParentPageIfTab(page);
8
9
  const containerState = containerPage.useState();
9
- useAppQueryParams();
10
+ const params = useAppQueryParams();
10
11
  const scene = page.getScene(routeProps.match);
11
12
  const [initialized, setInitialized] = useState(false);
12
13
  useLayoutEffect(() => {
@@ -39,13 +40,19 @@ function SceneAppPageView({ page, routeProps }) {
39
40
  };
40
41
  });
41
42
  }
42
- let pageActions = void 0;
43
+ let pageActions = [];
43
44
  if (containerState.controls) {
44
45
  pageActions = containerState.controls.map((control) => /* @__PURE__ */ React.createElement(control.Component, {
45
46
  model: control,
46
47
  key: control.state.key
47
48
  }));
48
49
  }
50
+ if (params["scene-debugger"]) {
51
+ pageActions.push(/* @__PURE__ */ React.createElement(SceneDebugger, {
52
+ scene: containerPage,
53
+ key: "scene-debugger"
54
+ }));
55
+ }
49
56
  return /* @__PURE__ */ React.createElement(PluginPage, {
50
57
  pageNav,
51
58
  actions: pageActions,
@@ -1 +1 @@
1
- {"version":3,"file":"SceneAppPageView.js","sources":["../../../../src/components/SceneApp/SceneAppPageView.tsx"],"sourcesContent":["import { NavModelItem, UrlQueryMap } from '@grafana/data';\nimport { PluginPage } from '@grafana/runtime';\nimport React, { useLayoutEffect, useState } from 'react';\n\nimport { RouteComponentProps } from 'react-router-dom';\nimport { SceneObject } from '../../core/types';\nimport { SceneAppPage } from './SceneAppPage';\nimport { SceneAppDrilldownView, SceneAppPageLike } from './types';\nimport { getUrlWithAppState, renderSceneComponentWithRouteProps, useAppQueryParams } from './utils';\n\nexport interface Props {\n page: SceneAppPageLike;\n // activeTab?: SceneAppPageLike;\n routeProps: RouteComponentProps;\n}\n\nexport function SceneAppPageView({ page, routeProps }: Props) {\n const containerPage = getParentPageIfTab(page);\n const containerState = containerPage.useState();\n const params = useAppQueryParams();\n const scene = page.getScene(routeProps.match);\n const [initialized, setInitialized] = useState(false);\n\n useLayoutEffect(() => {\n // Before rendering scene components, we are making sure the URL sync is enabled for.\n if (!initialized) {\n containerPage.initializeScene(scene);\n setInitialized(true);\n }\n }, [initialized, scene, containerPage]);\n\n if (!initialized) {\n return null;\n }\n\n const pageNav: NavModelItem = {\n text: containerState.title,\n img: containerState.titleImg,\n icon: containerState.titleIcon,\n url: getUrlWithAppState(containerState.url, containerState.preserveUrlKeys),\n hideFromBreadcrumbs: containerState.hideFromBreadcrumbs,\n parentItem: getParentBreadcrumbs(\n containerState.getParentPage ? containerState.getParentPage() : containerPage.parent,\n params\n ),\n };\n\n if (containerState.tabs) {\n pageNav.children = containerState.tabs.map((tab) => {\n return {\n text: tab.state.title,\n icon: tab.state.titleIcon,\n tabSuffix: tab.state.tabSuffix,\n active: page === tab,\n url: getUrlWithAppState(tab.state.url, tab.state.preserveUrlKeys),\n parentItem: pageNav,\n };\n });\n }\n\n let pageActions: React.ReactNode = undefined;\n if (containerState.controls) {\n pageActions = containerState.controls.map((control) => (\n <control.Component model={control} key={control.state.key} />\n ));\n }\n\n return (\n <PluginPage\n pageNav={pageNav}\n actions={pageActions}\n renderTitle={containerState.renderTitle}\n subTitle={containerState.subTitle}\n >\n <scene.Component model={scene} />\n </PluginPage>\n );\n}\n\n/**\n * For pages that are \"tabs\" this will return the parent page\n */\nfunction getParentPageIfTab(page: SceneAppPageLike) {\n if (page.parent instanceof SceneAppPage) {\n return page.parent;\n }\n\n return page;\n}\n\nfunction getParentBreadcrumbs(parent: SceneObject | undefined, params: UrlQueryMap): NavModelItem | undefined {\n if (parent instanceof SceneAppPage) {\n return {\n text: parent.state.title,\n url: getUrlWithAppState(parent.state.url, parent.state.preserveUrlKeys),\n hideFromBreadcrumbs: parent.state.hideFromBreadcrumbs,\n parentItem: getParentBreadcrumbs(\n parent.state.getParentPage ? parent.state.getParentPage() : parent.parent,\n params\n ),\n };\n }\n\n return undefined;\n}\n\nexport interface SceneAppDrilldownViewRenderProps {\n drilldown: SceneAppDrilldownView;\n parent: SceneAppPageLike;\n routeProps: RouteComponentProps;\n}\n\nexport function SceneAppDrilldownViewRender({ drilldown, parent, routeProps }: SceneAppDrilldownViewRenderProps) {\n return renderSceneComponentWithRouteProps(parent.getDrilldownPage(drilldown, routeProps.match), routeProps);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SceneAppPageView.js","sources":["../../../../src/components/SceneApp/SceneAppPageView.tsx"],"sourcesContent":["import { NavModelItem, UrlQueryMap } from '@grafana/data';\nimport { PluginPage } from '@grafana/runtime';\nimport React, { useLayoutEffect, useState } from 'react';\n\nimport { RouteComponentProps } from 'react-router-dom';\nimport { SceneObject } from '../../core/types';\nimport { SceneDebugger } from '../SceneDebugger/SceneDebugger';\nimport { SceneAppPage } from './SceneAppPage';\nimport { SceneAppDrilldownView, SceneAppPageLike } from './types';\nimport { getUrlWithAppState, renderSceneComponentWithRouteProps, useAppQueryParams } from './utils';\n\nexport interface Props {\n page: SceneAppPageLike;\n // activeTab?: SceneAppPageLike;\n routeProps: RouteComponentProps;\n}\n\nexport function SceneAppPageView({ page, routeProps }: Props) {\n const containerPage = getParentPageIfTab(page);\n const containerState = containerPage.useState();\n const params = useAppQueryParams();\n const scene = page.getScene(routeProps.match);\n const [initialized, setInitialized] = useState(false);\n\n useLayoutEffect(() => {\n // Before rendering scene components, we are making sure the URL sync is enabled for.\n if (!initialized) {\n containerPage.initializeScene(scene);\n setInitialized(true);\n }\n }, [initialized, scene, containerPage]);\n\n if (!initialized) {\n return null;\n }\n\n const pageNav: NavModelItem = {\n text: containerState.title,\n img: containerState.titleImg,\n icon: containerState.titleIcon,\n url: getUrlWithAppState(containerState.url, containerState.preserveUrlKeys),\n hideFromBreadcrumbs: containerState.hideFromBreadcrumbs,\n parentItem: getParentBreadcrumbs(\n containerState.getParentPage ? containerState.getParentPage() : containerPage.parent,\n params\n ),\n };\n\n if (containerState.tabs) {\n pageNav.children = containerState.tabs.map((tab) => {\n return {\n text: tab.state.title,\n icon: tab.state.titleIcon,\n tabSuffix: tab.state.tabSuffix,\n active: page === tab,\n url: getUrlWithAppState(tab.state.url, tab.state.preserveUrlKeys),\n parentItem: pageNav,\n };\n });\n }\n\n let pageActions: React.ReactNode[] = [];\n if (containerState.controls) {\n pageActions = containerState.controls.map((control) => (\n <control.Component model={control} key={control.state.key} />\n ));\n }\n\n if (params['scene-debugger']) {\n pageActions.push(<SceneDebugger scene={containerPage} key={'scene-debugger'} />);\n }\n\n return (\n <PluginPage\n pageNav={pageNav}\n actions={pageActions}\n renderTitle={containerState.renderTitle}\n subTitle={containerState.subTitle}\n >\n <scene.Component model={scene} />\n </PluginPage>\n );\n}\n\n/**\n * For pages that are \"tabs\" this will return the parent page\n */\nfunction getParentPageIfTab(page: SceneAppPageLike) {\n if (page.parent instanceof SceneAppPage) {\n return page.parent;\n }\n\n return page;\n}\n\nfunction getParentBreadcrumbs(parent: SceneObject | undefined, params: UrlQueryMap): NavModelItem | undefined {\n if (parent instanceof SceneAppPage) {\n return {\n text: parent.state.title,\n url: getUrlWithAppState(parent.state.url, parent.state.preserveUrlKeys),\n hideFromBreadcrumbs: parent.state.hideFromBreadcrumbs,\n parentItem: getParentBreadcrumbs(\n parent.state.getParentPage ? parent.state.getParentPage() : parent.parent,\n params\n ),\n };\n }\n\n return undefined;\n}\n\nexport interface SceneAppDrilldownViewRenderProps {\n drilldown: SceneAppDrilldownView;\n parent: SceneAppPageLike;\n routeProps: RouteComponentProps;\n}\n\nexport function SceneAppDrilldownViewRender({ drilldown, parent, routeProps }: SceneAppDrilldownViewRenderProps) {\n return renderSceneComponentWithRouteProps(parent.getDrilldownPage(drilldown, routeProps.match), routeProps);\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { css } from '@emotion/css';
2
+ import { useStyles2, JSONFormatter, Input } from '@grafana/ui';
3
+ import { isPlainObject, isArray } from 'lodash';
4
+ import React from 'react';
5
+ import { isSceneObject } from '../../core/types.js';
6
+
7
+ function DebugDetails({ node }) {
8
+ const state = node.useState();
9
+ const styles = useStyles2(getStyles);
10
+ return /* @__PURE__ */ React.createElement("div", {
11
+ className: styles.container
12
+ }, Object.keys(state).map((key) => /* @__PURE__ */ React.createElement("div", {
13
+ className: styles.row,
14
+ key
15
+ }, /* @__PURE__ */ React.createElement("div", {
16
+ className: styles.keyName
17
+ }, key), /* @__PURE__ */ React.createElement("div", {
18
+ className: styles.value
19
+ }, renderValue(key, state[key], node)))));
20
+ }
21
+ function renderValue(key, value, node) {
22
+ if (value === null) {
23
+ return "null";
24
+ }
25
+ switch (typeof value) {
26
+ case "number":
27
+ return /* @__PURE__ */ React.createElement(Input, {
28
+ type: "number",
29
+ defaultValue: value,
30
+ onBlur: (evt) => node.setState({ [key]: evt.currentTarget.valueAsNumber })
31
+ });
32
+ case "string":
33
+ return /* @__PURE__ */ React.createElement(Input, {
34
+ type: "text",
35
+ defaultValue: value,
36
+ onBlur: (evt) => node.setState({ [key]: evt.currentTarget.value })
37
+ });
38
+ case "object":
39
+ if (isSceneObject(value)) {
40
+ return value.constructor.name;
41
+ }
42
+ if (isPlainObject(value) || isArray(value)) {
43
+ return /* @__PURE__ */ React.createElement(JSONFormatter, {
44
+ json: value,
45
+ open: 0
46
+ });
47
+ }
48
+ return String(value);
49
+ default:
50
+ return typeof value;
51
+ }
52
+ }
53
+ function getStyles(theme) {
54
+ return {
55
+ container: css({
56
+ flexGrow: 1,
57
+ display: "flex",
58
+ gap: theme.spacing(0.5),
59
+ flexDirection: "column"
60
+ }),
61
+ row: css({
62
+ display: "flex",
63
+ gap: theme.spacing(2)
64
+ }),
65
+ keyName: css({
66
+ display: "flex",
67
+ flexGrow: "0",
68
+ width: 120,
69
+ alignItems: "center",
70
+ height: theme.spacing(theme.components.height.md)
71
+ }),
72
+ value: css({
73
+ flexGrow: 1,
74
+ minHeight: theme.spacing(theme.components.height.md),
75
+ display: "flex",
76
+ alignItems: "center"
77
+ })
78
+ };
79
+ }
80
+
81
+ export { DebugDetails };
82
+ //# sourceMappingURL=DebugDetails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DebugDetails.js","sources":["../../../../src/components/SceneDebugger/DebugDetails.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Input, JSONFormatter, useStyles2 } from '@grafana/ui';\nimport { isArray, isPlainObject } from 'lodash';\nimport React from 'react';\nimport { isSceneObject, SceneObject } from '../../core/types';\n\nexport interface Props {\n node: SceneObject;\n}\n\nexport function DebugDetails({ node }: Props) {\n const state = node.useState();\n const styles = useStyles2(getStyles);\n\n return (\n <div className={styles.container}>\n {Object.keys(state).map((key) => (\n <div className={styles.row} key={key}>\n <div className={styles.keyName}>{key}</div>\n <div className={styles.value}>{renderValue(key, (state as any)[key], node)}</div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction renderValue(key: string, value: any, node: SceneObject) {\n if (value === null) {\n return 'null';\n }\n\n switch (typeof value) {\n case 'number':\n return (\n <Input\n type=\"number\"\n defaultValue={value}\n onBlur={(evt) => node.setState({ [key]: evt.currentTarget.valueAsNumber })}\n />\n );\n case 'string':\n return (\n <Input type=\"text\" defaultValue={value} onBlur={(evt) => node.setState({ [key]: evt.currentTarget.value })} />\n );\n case 'object':\n if (isSceneObject(value)) {\n return value.constructor.name;\n }\n if (isPlainObject(value) || isArray(value)) {\n return <JSONFormatter json={value} open={0} />;\n }\n return String(value);\n default:\n return typeof value;\n }\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n container: css({\n flexGrow: 1,\n display: 'flex',\n gap: theme.spacing(0.5),\n flexDirection: 'column',\n }),\n row: css({\n display: 'flex',\n gap: theme.spacing(2),\n }),\n keyName: css({\n display: 'flex',\n flexGrow: '0',\n width: 120,\n alignItems: 'center',\n height: theme.spacing(theme.components.height.md),\n }),\n value: css({\n flexGrow: 1,\n minHeight: theme.spacing(theme.components.height.md),\n display: 'flex',\n alignItems: 'center',\n }),\n };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import { cx, css } from '@emotion/css';
2
+ import { useStyles2 } from '@grafana/ui';
3
+ import React from 'react';
4
+
5
+ function DebugTreeNode({ node, selectedObject, onSelect }) {
6
+ const styles = useStyles2(getStyles);
7
+ const children = [];
8
+ const isSelected = node === selectedObject;
9
+ node.forEachChild((child) => {
10
+ children.push(
11
+ /* @__PURE__ */ React.createElement(DebugTreeNode, {
12
+ node: child,
13
+ key: child.state.key,
14
+ selectedObject,
15
+ onSelect
16
+ })
17
+ );
18
+ });
19
+ return /* @__PURE__ */ React.createElement("div", {
20
+ className: styles.container
21
+ }, /* @__PURE__ */ React.createElement("div", {
22
+ className: cx(styles.name, isSelected && styles.selected),
23
+ onClick: () => onSelect(node)
24
+ }, node.constructor.name), /* @__PURE__ */ React.createElement("div", {
25
+ className: styles.children
26
+ }, children));
27
+ }
28
+ function getStyles(theme) {
29
+ return {
30
+ container: css({
31
+ flexGrow: 1,
32
+ display: "flex",
33
+ gap: theme.spacing(0.5),
34
+ flexDirection: "column"
35
+ }),
36
+ name: css({
37
+ flexGrow: 1,
38
+ display: "flex",
39
+ gap: theme.spacing(1),
40
+ fontSize: theme.typography.bodySmall.fontSize,
41
+ cursor: "pointer",
42
+ padding: theme.spacing(0, 1),
43
+ borderRadius: theme.shape.borderRadius(2),
44
+ position: "relative",
45
+ "&:hover": {
46
+ background: theme.colors.background.secondary
47
+ }
48
+ }),
49
+ selected: css({
50
+ "&::before": {
51
+ display: "block",
52
+ content: "' '",
53
+ position: "absolute",
54
+ left: 0,
55
+ width: 4,
56
+ bottom: 2,
57
+ top: 2,
58
+ borderRadius: theme.shape.radius.default,
59
+ backgroundImage: theme.colors.gradients.brandVertical
60
+ }
61
+ }),
62
+ children: css({
63
+ flexGrow: 1,
64
+ display: "flex",
65
+ flexDirection: "column",
66
+ paddingLeft: theme.spacing(1)
67
+ })
68
+ };
69
+ }
70
+
71
+ export { DebugTreeNode };
72
+ //# sourceMappingURL=DebugTreeNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DebugTreeNode.js","sources":["../../../../src/components/SceneDebugger/DebugTreeNode.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { useStyles2 } from '@grafana/ui';\nimport React, { ReactNode } from 'react';\nimport { SceneObject } from '../../core/types';\n\nexport interface Props {\n node: SceneObject;\n selectedObject?: SceneObject;\n onSelect: (node: SceneObject) => void;\n}\n\nexport function DebugTreeNode({ node, selectedObject, onSelect }: Props) {\n const styles = useStyles2(getStyles);\n const children: ReactNode[] = [];\n const isSelected = node === selectedObject;\n\n node.forEachChild((child) => {\n children.push(\n <DebugTreeNode node={child} key={child.state.key} selectedObject={selectedObject} onSelect={onSelect} />\n );\n });\n\n return (\n <div className={styles.container}>\n <div className={cx(styles.name, isSelected && styles.selected)} onClick={() => onSelect(node)}>\n {node.constructor.name}\n </div>\n <div className={styles.children}>{children}</div>\n </div>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n container: css({\n flexGrow: 1,\n display: 'flex',\n gap: theme.spacing(0.5),\n flexDirection: 'column',\n }),\n name: css({\n flexGrow: 1,\n display: 'flex',\n gap: theme.spacing(1),\n fontSize: theme.typography.bodySmall.fontSize,\n cursor: 'pointer',\n padding: theme.spacing(0, 1),\n borderRadius: theme.shape.borderRadius(2),\n position: 'relative',\n '&:hover': {\n background: theme.colors.background.secondary,\n },\n }),\n selected: css({\n '&::before': {\n display: 'block',\n content: \"' '\",\n position: 'absolute',\n left: 0,\n width: 4,\n bottom: 2,\n top: 2,\n borderRadius: theme.shape.radius.default,\n backgroundImage: theme.colors.gradients.brandVertical,\n },\n }),\n children: css({\n flexGrow: 1,\n display: 'flex',\n flexDirection: 'column',\n paddingLeft: theme.spacing(1),\n }),\n };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { css } from '@emotion/css';
2
+ import { useStyles2, ToolbarButton, Drawer, CustomScrollbar } from '@grafana/ui';
3
+ import React, { useState } from 'react';
4
+ import { DebugDetails } from './DebugDetails.js';
5
+ import { DebugTreeNode } from './DebugTreeNode.js';
6
+
7
+ function SceneDebugger({ scene }) {
8
+ const styles = useStyles2(getStyles);
9
+ const [isOpen, setIsOpen] = useState(false);
10
+ const [selectedObject, setSelectedObject] = useState();
11
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ToolbarButton, {
12
+ variant: "canvas",
13
+ icon: "bug",
14
+ onClick: () => setIsOpen(true)
15
+ }), isOpen && /* @__PURE__ */ React.createElement(Drawer, {
16
+ title: "Scene debugger",
17
+ onClose: () => setIsOpen(false),
18
+ size: "lg"
19
+ }, /* @__PURE__ */ React.createElement("div", {
20
+ className: styles.panes
21
+ }, /* @__PURE__ */ React.createElement("div", {
22
+ className: styles.pane1
23
+ }, /* @__PURE__ */ React.createElement("div", {
24
+ className: styles.paneHeading
25
+ }, "Scene graph"), /* @__PURE__ */ React.createElement(CustomScrollbar, {
26
+ autoHeightMin: "100%"
27
+ }, /* @__PURE__ */ React.createElement("div", {
28
+ className: styles.treeWrapper
29
+ }, /* @__PURE__ */ React.createElement(DebugTreeNode, {
30
+ node: scene,
31
+ selectedObject,
32
+ onSelect: setSelectedObject
33
+ })))), /* @__PURE__ */ React.createElement("div", {
34
+ className: styles.pane2
35
+ }, /* @__PURE__ */ React.createElement("div", {
36
+ className: styles.paneHeading
37
+ }, "Object details"), selectedObject && /* @__PURE__ */ React.createElement(DebugDetails, {
38
+ node: selectedObject
39
+ })))));
40
+ }
41
+ function getStyles(theme) {
42
+ return {
43
+ panes: css({
44
+ flexGrow: 1,
45
+ display: "flex",
46
+ height: "100%",
47
+ flexDirection: "row",
48
+ marginTop: theme.spacing(-2)
49
+ }),
50
+ pane1: css({
51
+ flexGrow: 0,
52
+ display: "flex",
53
+ height: "100%",
54
+ flexDirection: "column",
55
+ borderRight: `1px solid ${theme.colors.border.weak}`
56
+ }),
57
+ pane2: css({
58
+ flexGrow: 1,
59
+ display: "flex",
60
+ minHeight: "100%",
61
+ flexDirection: "column",
62
+ paddingLeft: theme.spacing(2)
63
+ }),
64
+ treeWrapper: css({
65
+ paddingRight: theme.spacing(2),
66
+ height: "100%",
67
+ marginLeft: theme.spacing(-1)
68
+ }),
69
+ paneHeading: css({
70
+ padding: theme.spacing(1, 0),
71
+ fontWeight: theme.typography.fontWeightMedium
72
+ })
73
+ };
74
+ }
75
+
76
+ export { SceneDebugger };
77
+ //# sourceMappingURL=SceneDebugger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SceneDebugger.js","sources":["../../../../src/components/SceneDebugger/SceneDebugger.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { CustomScrollbar, Drawer, ToolbarButton, useStyles2 } from '@grafana/ui';\nimport React, { useState } from 'react';\n\nimport { SceneObject } from '../../core/types';\nimport { DebugDetails } from './DebugDetails';\nimport { DebugTreeNode } from './DebugTreeNode';\n\nexport interface Props {\n scene: SceneObject;\n}\n\nexport function SceneDebugger({ scene }: Props) {\n const styles = useStyles2(getStyles);\n const [isOpen, setIsOpen] = useState(false);\n const [selectedObject, setSelectedObject] = useState<SceneObject>();\n\n return (\n <>\n <ToolbarButton variant=\"canvas\" icon=\"bug\" onClick={() => setIsOpen(true)} />\n {isOpen && (\n <Drawer title=\"Scene debugger\" onClose={() => setIsOpen(false)} size=\"lg\">\n <div className={styles.panes}>\n <div className={styles.pane1}>\n <div className={styles.paneHeading}>Scene graph</div>\n <CustomScrollbar autoHeightMin={'100%'}>\n <div className={styles.treeWrapper}>\n <DebugTreeNode node={scene} selectedObject={selectedObject} onSelect={setSelectedObject} />\n </div>\n </CustomScrollbar>\n </div>\n <div className={styles.pane2}>\n <div className={styles.paneHeading}>Object details</div>\n {selectedObject && <DebugDetails node={selectedObject} />}\n </div>\n </div>\n </Drawer>\n )}\n </>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n panes: css({\n flexGrow: 1,\n display: 'flex',\n height: '100%',\n flexDirection: 'row',\n marginTop: theme.spacing(-2),\n }),\n pane1: css({\n flexGrow: 0,\n display: 'flex',\n height: '100%',\n flexDirection: 'column',\n borderRight: `1px solid ${theme.colors.border.weak}`,\n }),\n pane2: css({\n flexGrow: 1,\n display: 'flex',\n minHeight: '100%',\n flexDirection: 'column',\n paddingLeft: theme.spacing(2),\n }),\n treeWrapper: css({\n paddingRight: theme.spacing(2),\n height: '100%',\n marginLeft: theme.spacing(-1),\n }),\n paneHeading: css({\n padding: theme.spacing(1, 0),\n fontWeight: theme.typography.fontWeightMedium,\n }),\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { toUtc, getPanelOptionsWithDefaults, compareArrayValues, compareDataFrameStructures, applyFieldOverrides, CoreApp, DashboardCursorSync } from '@grafana/data';
1
+ import { toUtc, getPanelOptionsWithDefaults, compareArrayValues, compareDataFrameStructures, applyFieldOverrides, CoreApp, DashboardCursorSync, PanelPlugin, PluginType } from '@grafana/data';
2
2
  import { getPluginImportUtils, config, getAppEvents } from '@grafana/runtime';
3
3
  import { SceneObjectBase } from '../../core/SceneObjectBase.js';
4
4
  import { sceneGraph } from '../../core/sceneGraph/index.js';
@@ -117,9 +117,14 @@ class VizPanel extends SceneObjectBase {
117
117
  this._pluginLoaded(plugin);
118
118
  } else {
119
119
  const { importPanelPlugin } = getPluginImportUtils();
120
- importPanelPlugin(pluginId).then((result) => this._pluginLoaded(result)).catch((err) => {
120
+ try {
121
+ importPanelPlugin(pluginId).then((result) => {
122
+ return this._pluginLoaded(result);
123
+ });
124
+ } catch (err) {
125
+ this._pluginLoaded(getPanelPluginNotFound(pluginId));
121
126
  this.setState({ pluginLoadError: err.message });
122
- });
127
+ }
123
128
  }
124
129
  }
125
130
  _pluginLoaded(plugin) {
@@ -208,6 +213,32 @@ class VizPanel extends SceneObjectBase {
208
213
  }
209
214
  }
210
215
  VizPanel.Component = VizPanelRenderer;
216
+ function getPanelPluginNotFound(id, silent) {
217
+ const plugin = new PanelPlugin(() => null);
218
+ plugin.meta = {
219
+ id,
220
+ name: id,
221
+ sort: 100,
222
+ type: PluginType.panel,
223
+ module: "",
224
+ baseUrl: "",
225
+ info: {
226
+ author: {
227
+ name: ""
228
+ },
229
+ description: "",
230
+ links: [],
231
+ logos: {
232
+ large: "",
233
+ small: "public/img/grafana_icon.svg"
234
+ },
235
+ screenshots: [],
236
+ updated: "",
237
+ version: ""
238
+ }
239
+ };
240
+ return plugin;
241
+ }
211
242
 
212
243
  export { VizPanel };
213
244
  //# sourceMappingURL=VizPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VizPanel.js","sources":["../../../../src/components/VizPanel/VizPanel.tsx"],"sourcesContent":["import {\n AbsoluteTimeRange,\n FieldConfigSource,\n PanelModel,\n PanelPlugin,\n toUtc,\n getPanelOptionsWithDefaults,\n ScopedVars,\n InterpolateFunction,\n CoreApp,\n DashboardCursorSync,\n PanelData,\n compareArrayValues,\n compareDataFrameStructures,\n applyFieldOverrides,\n} from '@grafana/data';\nimport { PanelContext, SeriesVisibilityChangeMode, VizLegendOptions } from '@grafana/ui';\nimport { config, getAppEvents, getPluginImportUtils } from '@grafana/runtime';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { DeepPartial, SceneObject, SceneObjectState } from '../../core/types';\n\nimport { VizPanelRenderer } from './VizPanelRenderer';\nimport { VizPanelMenu } from './VizPanelMenu';\nimport { VariableDependencyConfig } from '../../variables/VariableDependencyConfig';\nimport { VariableCustomFormatterFn } from '../../variables/types';\nimport { seriesVisibilityConfigFactory } from './seriesVisibilityConfigFactory';\nimport { emptyPanelData } from '../../core/SceneDataNode';\nimport { changeSeriesColorConfigFactory } from './colorSeriesConfigFactory';\nimport { loadPanelPluginSync } from './registerRuntimePanelPlugin';\nimport { getCursorSyncScope } from '../../behaviors/CursorSync';\n\nexport interface VizPanelState<TOptions = {}, TFieldConfig = {}> extends SceneObjectState {\n title: string;\n description?: string;\n /**\n * This is usually a plugin id that references a core plugin or an external plugin. But this can also reference a\n * runtime registered PanelPlugin registered via function registerScenePanelPlugin.\n */\n pluginId: string;\n options: DeepPartial<TOptions>;\n fieldConfig: FieldConfigSource<DeepPartial<TFieldConfig>>;\n pluginVersion?: string;\n displayMode?: 'default' | 'transparent';\n hoverHeader?: boolean;\n menu?: VizPanelMenu;\n isDraggable?: boolean;\n isResizable?: boolean;\n headerActions?: React.ReactNode | SceneObject;\n // internal state\n pluginLoadError?: string;\n pluginInstanceState?: any;\n}\n\nexport class VizPanel<TOptions = {}, TFieldConfig = {}> extends SceneObjectBase<VizPanelState<TOptions, TFieldConfig>> {\n public static Component = VizPanelRenderer;\n\n protected _variableDependency = new VariableDependencyConfig(this, {\n statePaths: ['title', 'options', 'fieldConfig'],\n });\n\n // Not part of state as this is not serializable\n private _plugin?: PanelPlugin;\n private _panelContext?: PanelContext;\n private _prevData?: PanelData;\n private _dataWithFieldConfig?: PanelData;\n private _structureRev: number = 0;\n\n public constructor(state: Partial<VizPanelState<TOptions, TFieldConfig>>) {\n super({\n options: {} as TOptions,\n fieldConfig: { defaults: {}, overrides: [] },\n title: 'Title',\n pluginId: 'timeseries',\n ...state,\n });\n\n this.addActivationHandler(() => {\n this._onActivate();\n });\n }\n\n private _onActivate() {\n if (!this._plugin) {\n this._loadPlugin(this.state.pluginId);\n }\n\n this.buildPanelContext();\n }\n\n private _loadPlugin(pluginId: string) {\n const plugin = loadPanelPluginSync(pluginId);\n\n if (plugin) {\n this._pluginLoaded(plugin);\n } else {\n const { importPanelPlugin } = getPluginImportUtils();\n\n importPanelPlugin(pluginId)\n .then((result) => this._pluginLoaded(result))\n .catch((err: Error) => {\n this.setState({ pluginLoadError: err.message });\n });\n }\n }\n\n private _pluginLoaded(plugin: PanelPlugin) {\n const { options, fieldConfig, title, pluginVersion } = this.state;\n\n const panel: PanelModel = {\n title,\n options,\n fieldConfig,\n id: 1,\n type: plugin.meta.id,\n pluginVersion: pluginVersion,\n };\n\n const currentVersion = this._getPluginVersion(plugin);\n\n if (plugin.onPanelMigration) {\n if (currentVersion !== this.state.pluginVersion) {\n // These migration handlers also mutate panel.fieldConfig to migrate fieldConfig\n panel.options = plugin.onPanelMigration(panel);\n }\n }\n\n const withDefaults = getPanelOptionsWithDefaults({\n plugin,\n currentOptions: panel.options,\n currentFieldConfig: panel.fieldConfig,\n isAfterPluginChange: false,\n });\n\n this._plugin = plugin;\n\n this.setState({\n options: withDefaults.options,\n fieldConfig: withDefaults.fieldConfig,\n pluginVersion: currentVersion,\n });\n }\n\n private _getPluginVersion(plugin: PanelPlugin): string {\n return plugin && plugin.meta.info.version ? plugin.meta.info.version : config.buildInfo.version;\n }\n\n public getPlugin(): PanelPlugin | undefined {\n return this._plugin;\n }\n\n public getPanelContext(): PanelContext {\n if (!this._panelContext) {\n this.buildPanelContext();\n }\n\n return this._panelContext!;\n }\n\n public onChangeTimeRange = (timeRange: AbsoluteTimeRange) => {\n const sceneTimeRange = sceneGraph.getTimeRange(this);\n sceneTimeRange.onTimeRangeChange({\n raw: {\n from: toUtc(timeRange.from),\n to: toUtc(timeRange.to),\n },\n from: toUtc(timeRange.from),\n to: toUtc(timeRange.to),\n });\n };\n\n public onOptionsChange = (options: TOptions) => {\n this.setState({ options });\n };\n\n public onFieldConfigChange = (fieldConfig: FieldConfigSource<TFieldConfig>) => {\n this.setState({ fieldConfig });\n };\n\n public interpolate = ((value: string, scoped?: ScopedVars, format?: string | VariableCustomFormatterFn) => {\n return sceneGraph.interpolate(this, value, scoped, format);\n }) as InterpolateFunction;\n\n /**\n * Called from the react render path to apply the field config to the data provided by the data provider\n */\n public applyFieldConfig(rawData?: PanelData): PanelData {\n const plugin = this._plugin!;\n\n if (!plugin || plugin.meta.skipDataQuery || !rawData) {\n // TODO setup time range subscription instead\n return emptyPanelData;\n }\n\n const fieldConfigRegistry = plugin.fieldConfigRegistry;\n const prevFrames = this._prevData?.series;\n const newFrames = rawData?.series;\n\n if (\n rawData.structureRev == null &&\n newFrames &&\n prevFrames &&\n !compareArrayValues(newFrames, prevFrames, compareDataFrameStructures)\n ) {\n this._structureRev++;\n }\n\n this._dataWithFieldConfig = {\n ...rawData,\n structureRev: this._structureRev,\n series: applyFieldOverrides({\n data: newFrames,\n fieldConfig: this.state.fieldConfig,\n fieldConfigRegistry,\n replaceVariables: this.interpolate,\n theme: config.theme2,\n timeZone: rawData.request?.timezone,\n }),\n };\n\n return this._dataWithFieldConfig;\n }\n\n public onCancelQuery = () => {\n const data = sceneGraph.getData(this);\n data.cancelQuery?.();\n };\n\n /**\n * Panel context functions\n */\n private _onSeriesColorChange = (label: string, color: string) => {\n this.onFieldConfigChange(changeSeriesColorConfigFactory(label, color, this.state.fieldConfig));\n };\n\n private _onSeriesVisibilityChange = (label: string, mode: SeriesVisibilityChangeMode) => {\n if (!this._dataWithFieldConfig) {\n return;\n }\n\n this.onFieldConfigChange(\n seriesVisibilityConfigFactory(label, mode, this.state.fieldConfig, this._dataWithFieldConfig.series)\n );\n };\n\n private _onInstanceStateChange = (state: any) => {\n this.setState({ pluginInstanceState: state });\n };\n\n private _onToggleLegendSort = (sortKey: string) => {\n const legendOptions: VizLegendOptions = (this.state.options as any).legend;\n\n // We don't want to do anything when legend options are not available\n if (!legendOptions) {\n return;\n }\n\n let sortDesc = legendOptions.sortDesc;\n let sortBy = legendOptions.sortBy;\n if (sortKey !== sortBy) {\n sortDesc = undefined;\n }\n\n // if already sort ascending, disable sorting\n if (sortDesc === false) {\n sortBy = undefined;\n sortDesc = undefined;\n } else {\n sortDesc = !sortDesc;\n sortBy = sortKey;\n }\n\n this.onOptionsChange({\n ...this.state.options,\n legend: { ...legendOptions, sortBy, sortDesc },\n } as TOptions);\n };\n\n private buildPanelContext() {\n const sync = getCursorSyncScope(this);\n\n this._panelContext = {\n // @ts-ignore Waits for core release\n eventsScope: sync ? sync.getEventsScope() : '__global_',\n eventBus: sync ? sync.getEventsBus(this) : getAppEvents(),\n app: CoreApp.Unknown, // TODO,\n sync: () => {\n if (sync) {\n return sync.state.sync;\n }\n return DashboardCursorSync.Off;\n }, // TODO\n onSeriesColorChange: this._onSeriesColorChange,\n onToggleSeriesVisibility: this._onSeriesVisibilityChange,\n onToggleLegendSort: this._onToggleLegendSort,\n onInstanceStateChange: this._onInstanceStateChange,\n // onAnnotationCreate: this.onAnnotationCreate,\n // onAnnotationUpdate: this.onAnnotationUpdate,\n // onAnnotationDelete: this.onAnnotationDelete,\n // canAddAnnotations: props.dashboard.canAddAnnotations.bind(props.dashboard),\n // canEditAnnotations: props.dashboard.canEditAnnotations.bind(props.dashboard),\n // canDeleteAnnotations: props.dashboard.canDeleteAnnotations.bind(props.dashboard),\n };\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VizPanel.js","sources":["../../../../src/components/VizPanel/VizPanel.tsx"],"sourcesContent":["import {\n AbsoluteTimeRange,\n FieldConfigSource,\n PanelModel,\n PanelPlugin,\n toUtc,\n getPanelOptionsWithDefaults,\n ScopedVars,\n InterpolateFunction,\n CoreApp,\n DashboardCursorSync,\n PanelData,\n compareArrayValues,\n compareDataFrameStructures,\n applyFieldOverrides,\n PluginType,\n} from '@grafana/data';\nimport { PanelContext, SeriesVisibilityChangeMode, VizLegendOptions } from '@grafana/ui';\nimport { config, getAppEvents, getPluginImportUtils } from '@grafana/runtime';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { DeepPartial, SceneObject, SceneObjectState } from '../../core/types';\n\nimport { VizPanelRenderer } from './VizPanelRenderer';\nimport { VizPanelMenu } from './VizPanelMenu';\nimport { VariableDependencyConfig } from '../../variables/VariableDependencyConfig';\nimport { VariableCustomFormatterFn } from '../../variables/types';\nimport { seriesVisibilityConfigFactory } from './seriesVisibilityConfigFactory';\nimport { emptyPanelData } from '../../core/SceneDataNode';\nimport { changeSeriesColorConfigFactory } from './colorSeriesConfigFactory';\nimport { loadPanelPluginSync } from './registerRuntimePanelPlugin';\nimport { getCursorSyncScope } from '../../behaviors/CursorSync';\n\nexport interface VizPanelState<TOptions = {}, TFieldConfig = {}> extends SceneObjectState {\n title: string;\n description?: string;\n /**\n * This is usually a plugin id that references a core plugin or an external plugin. But this can also reference a\n * runtime registered PanelPlugin registered via function registerScenePanelPlugin.\n */\n pluginId: string;\n options: DeepPartial<TOptions>;\n fieldConfig: FieldConfigSource<DeepPartial<TFieldConfig>>;\n pluginVersion?: string;\n displayMode?: 'default' | 'transparent';\n hoverHeader?: boolean;\n menu?: VizPanelMenu;\n isDraggable?: boolean;\n isResizable?: boolean;\n headerActions?: React.ReactNode | SceneObject;\n // internal state\n pluginLoadError?: string;\n pluginInstanceState?: any;\n}\n\nexport class VizPanel<TOptions = {}, TFieldConfig = {}> extends SceneObjectBase<VizPanelState<TOptions, TFieldConfig>> {\n public static Component = VizPanelRenderer;\n\n protected _variableDependency = new VariableDependencyConfig(this, {\n statePaths: ['title', 'options', 'fieldConfig'],\n });\n\n // Not part of state as this is not serializable\n private _plugin?: PanelPlugin;\n private _panelContext?: PanelContext;\n private _prevData?: PanelData;\n private _dataWithFieldConfig?: PanelData;\n private _structureRev: number = 0;\n\n public constructor(state: Partial<VizPanelState<TOptions, TFieldConfig>>) {\n super({\n options: {} as TOptions,\n fieldConfig: { defaults: {}, overrides: [] },\n title: 'Title',\n pluginId: 'timeseries',\n ...state,\n });\n\n this.addActivationHandler(() => {\n this._onActivate();\n });\n }\n\n private _onActivate() {\n if (!this._plugin) {\n this._loadPlugin(this.state.pluginId);\n }\n\n this.buildPanelContext();\n }\n\n private _loadPlugin(pluginId: string) {\n const plugin = loadPanelPluginSync(pluginId);\n\n if (plugin) {\n this._pluginLoaded(plugin);\n } else {\n const { importPanelPlugin } = getPluginImportUtils();\n\n try {\n importPanelPlugin(pluginId).then((result) => {\n return this._pluginLoaded(result);\n });\n } catch (err: unknown) {\n this._pluginLoaded(getPanelPluginNotFound(pluginId));\n this.setState({ pluginLoadError: (err as Error).message });\n }\n }\n }\n\n private _pluginLoaded(plugin: PanelPlugin) {\n const { options, fieldConfig, title, pluginVersion } = this.state;\n\n const panel: PanelModel = {\n title,\n options,\n fieldConfig,\n id: 1,\n type: plugin.meta.id,\n pluginVersion: pluginVersion,\n };\n\n const currentVersion = this._getPluginVersion(plugin);\n\n if (plugin.onPanelMigration) {\n if (currentVersion !== this.state.pluginVersion) {\n // These migration handlers also mutate panel.fieldConfig to migrate fieldConfig\n panel.options = plugin.onPanelMigration(panel);\n }\n }\n\n const withDefaults = getPanelOptionsWithDefaults({\n plugin,\n currentOptions: panel.options,\n currentFieldConfig: panel.fieldConfig,\n isAfterPluginChange: false,\n });\n\n this._plugin = plugin;\n\n this.setState({\n options: withDefaults.options,\n fieldConfig: withDefaults.fieldConfig,\n pluginVersion: currentVersion,\n });\n }\n\n private _getPluginVersion(plugin: PanelPlugin): string {\n return plugin && plugin.meta.info.version ? plugin.meta.info.version : config.buildInfo.version;\n }\n\n public getPlugin(): PanelPlugin | undefined {\n return this._plugin;\n }\n\n public getPanelContext(): PanelContext {\n if (!this._panelContext) {\n this.buildPanelContext();\n }\n\n return this._panelContext!;\n }\n\n public onChangeTimeRange = (timeRange: AbsoluteTimeRange) => {\n const sceneTimeRange = sceneGraph.getTimeRange(this);\n sceneTimeRange.onTimeRangeChange({\n raw: {\n from: toUtc(timeRange.from),\n to: toUtc(timeRange.to),\n },\n from: toUtc(timeRange.from),\n to: toUtc(timeRange.to),\n });\n };\n\n public onOptionsChange = (options: TOptions) => {\n this.setState({ options });\n };\n\n public onFieldConfigChange = (fieldConfig: FieldConfigSource<TFieldConfig>) => {\n this.setState({ fieldConfig });\n };\n\n public interpolate = ((value: string, scoped?: ScopedVars, format?: string | VariableCustomFormatterFn) => {\n return sceneGraph.interpolate(this, value, scoped, format);\n }) as InterpolateFunction;\n\n /**\n * Called from the react render path to apply the field config to the data provided by the data provider\n */\n public applyFieldConfig(rawData?: PanelData): PanelData {\n const plugin = this._plugin!;\n\n if (!plugin || plugin.meta.skipDataQuery || !rawData) {\n // TODO setup time range subscription instead\n return emptyPanelData;\n }\n\n const fieldConfigRegistry = plugin.fieldConfigRegistry;\n const prevFrames = this._prevData?.series;\n const newFrames = rawData?.series;\n\n if (\n rawData.structureRev == null &&\n newFrames &&\n prevFrames &&\n !compareArrayValues(newFrames, prevFrames, compareDataFrameStructures)\n ) {\n this._structureRev++;\n }\n\n this._dataWithFieldConfig = {\n ...rawData,\n structureRev: this._structureRev,\n series: applyFieldOverrides({\n data: newFrames,\n fieldConfig: this.state.fieldConfig,\n fieldConfigRegistry,\n replaceVariables: this.interpolate,\n theme: config.theme2,\n timeZone: rawData.request?.timezone,\n }),\n };\n\n return this._dataWithFieldConfig;\n }\n\n public onCancelQuery = () => {\n const data = sceneGraph.getData(this);\n data.cancelQuery?.();\n };\n\n /**\n * Panel context functions\n */\n private _onSeriesColorChange = (label: string, color: string) => {\n this.onFieldConfigChange(changeSeriesColorConfigFactory(label, color, this.state.fieldConfig));\n };\n\n private _onSeriesVisibilityChange = (label: string, mode: SeriesVisibilityChangeMode) => {\n if (!this._dataWithFieldConfig) {\n return;\n }\n\n this.onFieldConfigChange(\n seriesVisibilityConfigFactory(label, mode, this.state.fieldConfig, this._dataWithFieldConfig.series)\n );\n };\n\n private _onInstanceStateChange = (state: any) => {\n this.setState({ pluginInstanceState: state });\n };\n\n private _onToggleLegendSort = (sortKey: string) => {\n const legendOptions: VizLegendOptions = (this.state.options as any).legend;\n\n // We don't want to do anything when legend options are not available\n if (!legendOptions) {\n return;\n }\n\n let sortDesc = legendOptions.sortDesc;\n let sortBy = legendOptions.sortBy;\n if (sortKey !== sortBy) {\n sortDesc = undefined;\n }\n\n // if already sort ascending, disable sorting\n if (sortDesc === false) {\n sortBy = undefined;\n sortDesc = undefined;\n } else {\n sortDesc = !sortDesc;\n sortBy = sortKey;\n }\n\n this.onOptionsChange({\n ...this.state.options,\n legend: { ...legendOptions, sortBy, sortDesc },\n } as TOptions);\n };\n\n private buildPanelContext() {\n const sync = getCursorSyncScope(this);\n\n this._panelContext = {\n // @ts-ignore Waits for core release\n eventsScope: sync ? sync.getEventsScope() : '__global_',\n eventBus: sync ? sync.getEventsBus(this) : getAppEvents(),\n app: CoreApp.Unknown, // TODO,\n sync: () => {\n if (sync) {\n return sync.state.sync;\n }\n return DashboardCursorSync.Off;\n }, // TODO\n onSeriesColorChange: this._onSeriesColorChange,\n onToggleSeriesVisibility: this._onSeriesVisibilityChange,\n onToggleLegendSort: this._onToggleLegendSort,\n onInstanceStateChange: this._onInstanceStateChange,\n // onAnnotationCreate: this.onAnnotationCreate,\n // onAnnotationUpdate: this.onAnnotationUpdate,\n // onAnnotationDelete: this.onAnnotationDelete,\n // canAddAnnotations: props.dashboard.canAddAnnotations.bind(props.dashboard),\n // canEditAnnotations: props.dashboard.canEditAnnotations.bind(props.dashboard),\n // canDeleteAnnotations: props.dashboard.canDeleteAnnotations.bind(props.dashboard),\n };\n }\n}\n\nfunction getPanelPluginNotFound(id: string, silent?: boolean): PanelPlugin {\n const plugin = new PanelPlugin(() => null);\n\n plugin.meta = {\n id: id,\n name: id,\n sort: 100,\n type: PluginType.panel,\n module: '',\n baseUrl: '',\n info: {\n author: {\n name: '',\n },\n description: '',\n links: [],\n logos: {\n large: '',\n small: 'public/img/grafana_icon.svg',\n },\n screenshots: [],\n updated: '',\n version: '',\n },\n };\n return plugin;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDO,MAAM,iBAAmD,eAAuD,CAAA;AAAA,EAc9G,YAAY,KAAuD,EAAA;AACxE,IAAM,KAAA,CAAA,cAAA,CAAA;AAAA,MACJ,SAAS,EAAC;AAAA,MACV,aAAa,EAAE,QAAA,EAAU,EAAI,EAAA,SAAA,EAAW,EAAG,EAAA;AAAA,MAC3C,KAAO,EAAA,OAAA;AAAA,MACP,QAAU,EAAA,YAAA;AAAA,KAAA,EACP,KACJ,CAAA,CAAA,CAAA;AAlBH,IAAU,IAAA,CAAA,mBAAA,GAAsB,IAAI,wBAAA,CAAyB,IAAM,EAAA;AAAA,MACjE,UAAY,EAAA,CAAC,OAAS,EAAA,SAAA,EAAW,aAAa,CAAA;AAAA,KAC/C,CAAA,CAAA;AAOD,IAAA,IAAA,CAAQ,aAAwB,GAAA,CAAA,CAAA;AAgGhC,IAAO,IAAA,CAAA,iBAAA,GAAoB,CAAC,SAAiC,KAAA;AAC3D,MAAM,MAAA,cAAA,GAAiB,UAAW,CAAA,YAAA,CAAa,IAAI,CAAA,CAAA;AACnD,MAAA,cAAA,CAAe,iBAAkB,CAAA;AAAA,QAC/B,GAAK,EAAA;AAAA,UACH,IAAA,EAAM,KAAM,CAAA,SAAA,CAAU,IAAI,CAAA;AAAA,UAC1B,EAAA,EAAI,KAAM,CAAA,SAAA,CAAU,EAAE,CAAA;AAAA,SACxB;AAAA,QACA,IAAA,EAAM,KAAM,CAAA,SAAA,CAAU,IAAI,CAAA;AAAA,QAC1B,EAAA,EAAI,KAAM,CAAA,SAAA,CAAU,EAAE,CAAA;AAAA,OACvB,CAAA,CAAA;AAAA,KACH,CAAA;AAEA,IAAO,IAAA,CAAA,eAAA,GAAkB,CAAC,OAAsB,KAAA;AAC9C,MAAK,IAAA,CAAA,QAAA,CAAS,EAAE,OAAA,EAAS,CAAA,CAAA;AAAA,KAC3B,CAAA;AAEA,IAAO,IAAA,CAAA,mBAAA,GAAsB,CAAC,WAAiD,KAAA;AAC7E,MAAK,IAAA,CAAA,QAAA,CAAS,EAAE,WAAA,EAAa,CAAA,CAAA;AAAA,KAC/B,CAAA;AAEA,IAAA,IAAA,CAAO,WAAe,GAAA,CAAC,KAAe,EAAA,MAAA,EAAqB,MAAgD,KAAA;AACzG,MAAA,OAAO,UAAW,CAAA,WAAA,CAAY,IAAM,EAAA,KAAA,EAAO,QAAQ,MAAM,CAAA,CAAA;AAAA,KAC3D,CAAA;AA0CA,IAAA,IAAA,CAAO,gBAAgB,MAAM;AAnO/B,MAAA,IAAA,EAAA,CAAA;AAoOI,MAAM,MAAA,IAAA,GAAO,UAAW,CAAA,OAAA,CAAQ,IAAI,CAAA,CAAA;AACpC,MAAA,CAAA,EAAA,GAAA,IAAA,CAAK,WAAL,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAA,CAAA,IAAA,CAAA,CAAA;AAAA,KACF,CAAA;AAKA,IAAQ,IAAA,CAAA,oBAAA,GAAuB,CAAC,KAAA,EAAe,KAAkB,KAAA;AAC/D,MAAA,IAAA,CAAK,oBAAoB,8BAA+B,CAAA,KAAA,EAAO,OAAO,IAAK,CAAA,KAAA,CAAM,WAAW,CAAC,CAAA,CAAA;AAAA,KAC/F,CAAA;AAEA,IAAQ,IAAA,CAAA,yBAAA,GAA4B,CAAC,KAAA,EAAe,IAAqC,KAAA;AACvF,MAAI,IAAA,CAAC,KAAK,oBAAsB,EAAA;AAC9B,QAAA,OAAA;AAAA,OACF;AAEA,MAAK,IAAA,CAAA,mBAAA;AAAA,QACH,6BAAA,CAA8B,OAAO,IAAM,EAAA,IAAA,CAAK,MAAM,WAAa,EAAA,IAAA,CAAK,qBAAqB,MAAM,CAAA;AAAA,OACrG,CAAA;AAAA,KACF,CAAA;AAEA,IAAQ,IAAA,CAAA,sBAAA,GAAyB,CAAC,KAAe,KAAA;AAC/C,MAAA,IAAA,CAAK,QAAS,CAAA,EAAE,mBAAqB,EAAA,KAAA,EAAO,CAAA,CAAA;AAAA,KAC9C,CAAA;AAEA,IAAQ,IAAA,CAAA,mBAAA,GAAsB,CAAC,OAAoB,KAAA;AACjD,MAAM,MAAA,aAAA,GAAmC,IAAK,CAAA,KAAA,CAAM,OAAgB,CAAA,MAAA,CAAA;AAGpE,MAAA,IAAI,CAAC,aAAe,EAAA;AAClB,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,IAAI,WAAW,aAAc,CAAA,QAAA,CAAA;AAC7B,MAAA,IAAI,SAAS,aAAc,CAAA,MAAA,CAAA;AAC3B,MAAA,IAAI,YAAY,MAAQ,EAAA;AACtB,QAAW,QAAA,GAAA,KAAA,CAAA,CAAA;AAAA,OACb;AAGA,MAAA,IAAI,aAAa,KAAO,EAAA;AACtB,QAAS,MAAA,GAAA,KAAA,CAAA,CAAA;AACT,QAAW,QAAA,GAAA,KAAA,CAAA,CAAA;AAAA,OACN,MAAA;AACL,QAAA,QAAA,GAAW,CAAC,QAAA,CAAA;AACZ,QAAS,MAAA,GAAA,OAAA,CAAA;AAAA,OACX;AAEA,MAAA,IAAA,CAAK,eAAgB,CAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EAChB,IAAK,CAAA,KAAA,CAAM,OADK,CAAA,EAAA;AAAA,QAEnB,MAAQ,EAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EAAK,aAAL,CAAA,EAAA,EAAoB,QAAQ,QAAS,EAAA,CAAA;AAAA,OAClC,CAAA,CAAA,CAAA;AAAA,KACf,CAAA;AA1ME,IAAA,IAAA,CAAK,qBAAqB,MAAM;AAC9B,MAAA,IAAA,CAAK,WAAY,EAAA,CAAA;AAAA,KAClB,CAAA,CAAA;AAAA,GACH;AAAA,EAEQ,WAAc,GAAA;AACpB,IAAI,IAAA,CAAC,KAAK,OAAS,EAAA;AACjB,MAAK,IAAA,CAAA,WAAA,CAAY,IAAK,CAAA,KAAA,CAAM,QAAQ,CAAA,CAAA;AAAA,KACtC;AAEA,IAAA,IAAA,CAAK,iBAAkB,EAAA,CAAA;AAAA,GACzB;AAAA,EAEQ,YAAY,QAAkB,EAAA;AACpC,IAAM,MAAA,MAAA,GAAS,oBAAoB,QAAQ,CAAA,CAAA;AAE3C,IAAA,IAAI,MAAQ,EAAA;AACV,MAAA,IAAA,CAAK,cAAc,MAAM,CAAA,CAAA;AAAA,KACpB,MAAA;AACL,MAAM,MAAA,EAAE,iBAAkB,EAAA,GAAI,oBAAqB,EAAA,CAAA;AAEnD,MAAI,IAAA;AACF,QAAA,iBAAA,CAAkB,QAAQ,CAAA,CAAE,IAAK,CAAA,CAAC,MAAW,KAAA;AAC3C,UAAO,OAAA,IAAA,CAAK,cAAc,MAAM,CAAA,CAAA;AAAA,SACjC,CAAA,CAAA;AAAA,eACM,GAAP,EAAA;AACA,QAAK,IAAA,CAAA,aAAA,CAAc,sBAAuB,CAAA,QAAQ,CAAC,CAAA,CAAA;AACnD,QAAA,IAAA,CAAK,QAAS,CAAA,EAAE,eAAkB,EAAA,GAAA,CAAc,SAAS,CAAA,CAAA;AAAA,OAC3D;AAAA,KACF;AAAA,GACF;AAAA,EAEQ,cAAc,MAAqB,EAAA;AACzC,IAAA,MAAM,EAAE,OAAS,EAAA,WAAA,EAAa,KAAO,EAAA,aAAA,KAAkB,IAAK,CAAA,KAAA,CAAA;AAE5D,IAAA,MAAM,KAAoB,GAAA;AAAA,MACxB,KAAA;AAAA,MACA,OAAA;AAAA,MACA,WAAA;AAAA,MACA,EAAI,EAAA,CAAA;AAAA,MACJ,IAAA,EAAM,OAAO,IAAK,CAAA,EAAA;AAAA,MAClB,aAAA;AAAA,KACF,CAAA;AAEA,IAAM,MAAA,cAAA,GAAiB,IAAK,CAAA,iBAAA,CAAkB,MAAM,CAAA,CAAA;AAEpD,IAAA,IAAI,OAAO,gBAAkB,EAAA;AAC3B,MAAI,IAAA,cAAA,KAAmB,IAAK,CAAA,KAAA,CAAM,aAAe,EAAA;AAE/C,QAAM,KAAA,CAAA,OAAA,GAAU,MAAO,CAAA,gBAAA,CAAiB,KAAK,CAAA,CAAA;AAAA,OAC/C;AAAA,KACF;AAEA,IAAA,MAAM,eAAe,2BAA4B,CAAA;AAAA,MAC/C,MAAA;AAAA,MACA,gBAAgB,KAAM,CAAA,OAAA;AAAA,MACtB,oBAAoB,KAAM,CAAA,WAAA;AAAA,MAC1B,mBAAqB,EAAA,KAAA;AAAA,KACtB,CAAA,CAAA;AAED,IAAA,IAAA,CAAK,OAAU,GAAA,MAAA,CAAA;AAEf,IAAA,IAAA,CAAK,QAAS,CAAA;AAAA,MACZ,SAAS,YAAa,CAAA,OAAA;AAAA,MACtB,aAAa,YAAa,CAAA,WAAA;AAAA,MAC1B,aAAe,EAAA,cAAA;AAAA,KAChB,CAAA,CAAA;AAAA,GACH;AAAA,EAEQ,kBAAkB,MAA6B,EAAA;AACrD,IAAO,OAAA,MAAA,IAAU,MAAO,CAAA,IAAA,CAAK,IAAK,CAAA,OAAA,GAAU,OAAO,IAAK,CAAA,IAAA,CAAK,OAAU,GAAA,MAAA,CAAO,SAAU,CAAA,OAAA,CAAA;AAAA,GAC1F;AAAA,EAEO,SAAqC,GAAA;AAC1C,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GACd;AAAA,EAEO,eAAgC,GAAA;AACrC,IAAI,IAAA,CAAC,KAAK,aAAe,EAAA;AACvB,MAAA,IAAA,CAAK,iBAAkB,EAAA,CAAA;AAAA,KACzB;AAEA,IAAA,OAAO,IAAK,CAAA,aAAA,CAAA;AAAA,GACd;AAAA,EA6BO,iBAAiB,OAAgC,EAAA;AA9L1D,IAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AA+LI,IAAA,MAAM,SAAS,IAAK,CAAA,OAAA,CAAA;AAEpB,IAAA,IAAI,CAAC,MAAU,IAAA,MAAA,CAAO,IAAK,CAAA,aAAA,IAAiB,CAAC,OAAS,EAAA;AAEpD,MAAO,OAAA,cAAA,CAAA;AAAA,KACT;AAEA,IAAA,MAAM,sBAAsB,MAAO,CAAA,mBAAA,CAAA;AACnC,IAAM,MAAA,UAAA,GAAA,CAAa,EAAK,GAAA,IAAA,CAAA,SAAA,KAAL,IAAgB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,MAAA,CAAA;AACnC,IAAA,MAAM,YAAY,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,MAAA,CAAA;AAE3B,IACE,IAAA,OAAA,CAAQ,YAAgB,IAAA,IAAA,IACxB,SACA,IAAA,UAAA,IACA,CAAC,kBAAmB,CAAA,SAAA,EAAW,UAAY,EAAA,0BAA0B,CACrE,EAAA;AACA,MAAK,IAAA,CAAA,aAAA,EAAA,CAAA;AAAA,KACP;AAEA,IAAK,IAAA,CAAA,oBAAA,GAAuB,iCACvB,OADuB,CAAA,EAAA;AAAA,MAE1B,cAAc,IAAK,CAAA,aAAA;AAAA,MACnB,QAAQ,mBAAoB,CAAA;AAAA,QAC1B,IAAM,EAAA,SAAA;AAAA,QACN,WAAA,EAAa,KAAK,KAAM,CAAA,WAAA;AAAA,QACxB,mBAAA;AAAA,QACA,kBAAkB,IAAK,CAAA,WAAA;AAAA,QACvB,OAAO,MAAO,CAAA,MAAA;AAAA,QACd,QAAA,EAAA,CAAU,EAAQ,GAAA,OAAA,CAAA,OAAA,KAAR,IAAiB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,QAAA;AAAA,OAC5B,CAAA;AAAA,KACH,CAAA,CAAA;AAEA,IAAA,OAAO,IAAK,CAAA,oBAAA,CAAA;AAAA,GACd;AAAA,EAyDQ,iBAAoB,GAAA;AAC1B,IAAM,MAAA,IAAA,GAAO,mBAAmB,IAAI,CAAA,CAAA;AAEpC,IAAA,IAAA,CAAK,aAAgB,GAAA;AAAA,MAEnB,WAAa,EAAA,IAAA,GAAO,IAAK,CAAA,cAAA,EAAmB,GAAA,WAAA;AAAA,MAC5C,UAAU,IAAO,GAAA,IAAA,CAAK,YAAa,CAAA,IAAI,IAAI,YAAa,EAAA;AAAA,MACxD,KAAK,OAAQ,CAAA,OAAA;AAAA,MACb,MAAM,MAAM;AACV,QAAA,IAAI,IAAM,EAAA;AACR,UAAA,OAAO,KAAK,KAAM,CAAA,IAAA,CAAA;AAAA,SACpB;AACA,QAAA,OAAO,mBAAoB,CAAA,GAAA,CAAA;AAAA,OAC7B;AAAA,MACA,qBAAqB,IAAK,CAAA,oBAAA;AAAA,MAC1B,0BAA0B,IAAK,CAAA,yBAAA;AAAA,MAC/B,oBAAoB,IAAK,CAAA,mBAAA;AAAA,MACzB,uBAAuB,IAAK,CAAA,sBAAA;AAAA,KAO9B,CAAA;AAAA,GACF;AACF,CAAA;AA7Pa,QAAA,CACG,SAAY,GAAA,gBAAA,CAAA;AA8P5B,SAAS,sBAAA,CAAuB,IAAY,MAA+B,EAAA;AACzE,EAAA,MAAM,MAAS,GAAA,IAAI,WAAY,CAAA,MAAM,IAAI,CAAA,CAAA;AAEzC,EAAA,MAAA,CAAO,IAAO,GAAA;AAAA,IACZ,EAAA;AAAA,IACA,IAAM,EAAA,EAAA;AAAA,IACN,IAAM,EAAA,GAAA;AAAA,IACN,MAAM,UAAW,CAAA,KAAA;AAAA,IACjB,MAAQ,EAAA,EAAA;AAAA,IACR,OAAS,EAAA,EAAA;AAAA,IACT,IAAM,EAAA;AAAA,MACJ,MAAQ,EAAA;AAAA,QACN,IAAM,EAAA,EAAA;AAAA,OACR;AAAA,MACA,WAAa,EAAA,EAAA;AAAA,MACb,OAAO,EAAC;AAAA,MACR,KAAO,EAAA;AAAA,QACL,KAAO,EAAA,EAAA;AAAA,QACP,KAAO,EAAA,6BAAA;AAAA,OACT;AAAA,MACA,aAAa,EAAC;AAAA,MACd,OAAS,EAAA,EAAA;AAAA,MACT,OAAS,EAAA,EAAA;AAAA,KACX;AAAA,GACF,CAAA;AACA,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
@@ -57,9 +57,6 @@ function VizPanelRenderer({ model }) {
57
57
  const dataWithFieldConfig = model.applyFieldConfig(rawData.data);
58
58
  const titleInterpolated = model.interpolate(title, void 0, "text");
59
59
  const timeZone = sceneGraph.getTimeRange(model).getTimeZone();
60
- if (pluginLoadError) {
61
- return /* @__PURE__ */ React.createElement("div", null, "Failed to load plugin: ", pluginLoadError);
62
- }
63
60
  if (!plugin) {
64
61
  return /* @__PURE__ */ React.createElement("div", null, "Loading plugin panel...");
65
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"VizPanelRenderer.js","sources":["../../../../src/components/VizPanel/VizPanelRenderer.tsx"],"sourcesContent":["import React, { RefCallback } from 'react';\nimport { useMeasure } from 'react-use';\n\nimport { PanelData, PluginContextProvider } from '@grafana/data';\nimport { getAppEvents } from '@grafana/runtime';\nimport { PanelChrome, ErrorBoundaryAlert, PanelContextProvider } from '@grafana/ui';\n\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { isSceneObject, SceneComponentProps } from '../../core/types';\n\nimport { VizPanel } from './VizPanel';\n\nexport function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {\n const {\n title,\n description,\n options,\n fieldConfig,\n pluginLoadError,\n $data,\n displayMode,\n hoverHeader,\n menu,\n headerActions,\n ...state\n } = model.useState();\n const [ref, { width, height }] = useMeasure();\n const plugin = model.getPlugin();\n const parentLayout = sceneGraph.getLayout(model);\n\n // If parent has enabled dragging and we have not explicitly disabled it then dragging is enabled\n const isDraggable = parentLayout.isDraggable() && (state.isDraggable ?? true);\n const dragClass = isDraggable && parentLayout.getDragClass ? parentLayout.getDragClass() : '';\n const dragClassCancel = isDraggable && parentLayout.getDragClassCancel ? parentLayout.getDragClassCancel() : '';\n const dataObject = sceneGraph.getData(model);\n const rawData = dataObject.useState();\n const dataWithFieldConfig = model.applyFieldConfig(rawData.data!);\n\n // Interpolate title\n const titleInterpolated = model.interpolate(title, undefined, 'text');\n\n // Not sure we need to subscribe to this state\n const timeZone = sceneGraph.getTimeRange(model).getTimeZone();\n\n if (pluginLoadError) {\n return <div>Failed to load plugin: {pluginLoadError}</div>;\n }\n\n if (!plugin) {\n return <div>Loading plugin panel...</div>;\n }\n\n if (!plugin.panel) {\n return <div>Panel plugin has no panel component</div>;\n }\n\n const PanelComponent = plugin.panel;\n\n // If we have a query runner on our level inform it of the container width (used to set auto max data points)\n if ($data && $data.setContainerWidth) {\n $data.setContainerWidth(width);\n }\n\n const titleItems: React.ReactNode[] = [];\n\n // If we have local time range show that in panel header\n if (model.state.$timeRange) {\n titleItems.push(<model.state.$timeRange.Component model={model.state.$timeRange} />);\n }\n\n let panelMenu;\n if (menu) {\n panelMenu = <menu.Component model={menu} />;\n }\n\n let actionsElement: React.ReactNode | undefined;\n\n if (headerActions) {\n if (isSceneObject(headerActions)) {\n actionsElement = <headerActions.Component model={headerActions} />;\n } else {\n actionsElement = headerActions;\n }\n }\n\n // Data is always returned. For non-data panels, empty PanelData is returned.\n const data = dataWithFieldConfig!;\n const isReadyToRender = dataObject.isDataReadyToDisplay ? dataObject.isDataReadyToDisplay() : true;\n\n return (\n <div ref={ref as RefCallback<HTMLDivElement>} style={{ position: 'absolute', width: '100%', height: '100%' }}>\n {width > 0 && height > 0 && (\n <PanelChrome\n title={titleInterpolated}\n description={description ? () => model.interpolate(description) : ''}\n loadingState={data.state}\n statusMessage={getChromeStatusMessage(data, pluginLoadError)}\n width={width}\n height={height}\n displayMode={displayMode}\n hoverHeader={hoverHeader}\n titleItems={titleItems}\n dragClass={dragClass}\n actions={actionsElement}\n dragClassCancel={dragClassCancel}\n padding={plugin.noPadding ? 'none' : 'md'}\n menu={panelMenu}\n onCancelQuery={model.onCancelQuery}\n >\n {(innerWidth, innerHeight) => (\n <>\n <ErrorBoundaryAlert dependencies={[plugin, data]}>\n <PluginContextProvider meta={plugin.meta}>\n <PanelContextProvider value={model.getPanelContext()}>\n {isReadyToRender && (\n <PanelComponent\n id={1}\n data={data}\n title={title}\n timeRange={data.timeRange}\n timeZone={timeZone}\n options={options}\n fieldConfig={fieldConfig}\n transparent={false}\n width={innerWidth}\n height={innerHeight}\n renderCounter={0}\n replaceVariables={model.interpolate}\n onOptionsChange={model.onOptionsChange}\n onFieldConfigChange={model.onFieldConfigChange}\n onChangeTimeRange={model.onChangeTimeRange}\n eventBus={getAppEvents()}\n />\n )}\n </PanelContextProvider>\n </PluginContextProvider>\n </ErrorBoundaryAlert>\n </>\n )}\n </PanelChrome>\n )}\n </div>\n );\n}\n\nfunction getChromeStatusMessage(data: PanelData, pluginLoadingError: string | undefined) {\n if (pluginLoadingError) {\n return pluginLoadingError;\n }\n\n return data.error ? data.error.message : undefined;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VizPanelRenderer.js","sources":["../../../../src/components/VizPanel/VizPanelRenderer.tsx"],"sourcesContent":["import React, { RefCallback } from 'react';\nimport { useMeasure } from 'react-use';\n\nimport { PanelData, PluginContextProvider } from '@grafana/data';\nimport { getAppEvents } from '@grafana/runtime';\nimport { PanelChrome, ErrorBoundaryAlert, PanelContextProvider } from '@grafana/ui';\n\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { isSceneObject, SceneComponentProps } from '../../core/types';\n\nimport { VizPanel } from './VizPanel';\n\nexport function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {\n const {\n title,\n description,\n options,\n fieldConfig,\n pluginLoadError,\n $data,\n displayMode,\n hoverHeader,\n menu,\n headerActions,\n ...state\n } = model.useState();\n const [ref, { width, height }] = useMeasure();\n const plugin = model.getPlugin();\n const parentLayout = sceneGraph.getLayout(model);\n\n // If parent has enabled dragging and we have not explicitly disabled it then dragging is enabled\n const isDraggable = parentLayout.isDraggable() && (state.isDraggable ?? true);\n const dragClass = isDraggable && parentLayout.getDragClass ? parentLayout.getDragClass() : '';\n const dragClassCancel = isDraggable && parentLayout.getDragClassCancel ? parentLayout.getDragClassCancel() : '';\n const dataObject = sceneGraph.getData(model);\n const rawData = dataObject.useState();\n const dataWithFieldConfig = model.applyFieldConfig(rawData.data!);\n\n // Interpolate title\n const titleInterpolated = model.interpolate(title, undefined, 'text');\n\n // Not sure we need to subscribe to this state\n const timeZone = sceneGraph.getTimeRange(model).getTimeZone();\n\n if (!plugin) {\n return <div>Loading plugin panel...</div>;\n }\n\n if (!plugin.panel) {\n return <div>Panel plugin has no panel component</div>;\n }\n\n const PanelComponent = plugin.panel;\n\n // If we have a query runner on our level inform it of the container width (used to set auto max data points)\n if ($data && $data.setContainerWidth) {\n $data.setContainerWidth(width);\n }\n\n const titleItems: React.ReactNode[] = [];\n\n // If we have local time range show that in panel header\n if (model.state.$timeRange) {\n titleItems.push(<model.state.$timeRange.Component model={model.state.$timeRange} />);\n }\n\n let panelMenu;\n if (menu) {\n panelMenu = <menu.Component model={menu} />;\n }\n\n let actionsElement: React.ReactNode | undefined;\n\n if (headerActions) {\n if (isSceneObject(headerActions)) {\n actionsElement = <headerActions.Component model={headerActions} />;\n } else {\n actionsElement = headerActions;\n }\n }\n\n // Data is always returned. For non-data panels, empty PanelData is returned.\n const data = dataWithFieldConfig!;\n const isReadyToRender = dataObject.isDataReadyToDisplay ? dataObject.isDataReadyToDisplay() : true;\n\n return (\n <div ref={ref as RefCallback<HTMLDivElement>} style={{ position: 'absolute', width: '100%', height: '100%' }}>\n {width > 0 && height > 0 && (\n <PanelChrome\n title={titleInterpolated}\n description={description ? () => model.interpolate(description) : ''}\n loadingState={data.state}\n statusMessage={getChromeStatusMessage(data, pluginLoadError)}\n width={width}\n height={height}\n displayMode={displayMode}\n hoverHeader={hoverHeader}\n titleItems={titleItems}\n dragClass={dragClass}\n actions={actionsElement}\n dragClassCancel={dragClassCancel}\n padding={plugin.noPadding ? 'none' : 'md'}\n menu={panelMenu}\n onCancelQuery={model.onCancelQuery}\n >\n {(innerWidth, innerHeight) => (\n <>\n <ErrorBoundaryAlert dependencies={[plugin, data]}>\n <PluginContextProvider meta={plugin.meta}>\n <PanelContextProvider value={model.getPanelContext()}>\n {isReadyToRender && (\n <PanelComponent\n id={1}\n data={data}\n title={title}\n timeRange={data.timeRange}\n timeZone={timeZone}\n options={options}\n fieldConfig={fieldConfig}\n transparent={false}\n width={innerWidth}\n height={innerHeight}\n renderCounter={0}\n replaceVariables={model.interpolate}\n onOptionsChange={model.onOptionsChange}\n onFieldConfigChange={model.onFieldConfigChange}\n onChangeTimeRange={model.onChangeTimeRange}\n eventBus={getAppEvents()}\n />\n )}\n </PanelContextProvider>\n </PluginContextProvider>\n </ErrorBoundaryAlert>\n </>\n )}\n </PanelChrome>\n )}\n </div>\n );\n}\n\nfunction getChromeStatusMessage(data: PanelData, pluginLoadingError: string | undefined) {\n if (pluginLoadingError) {\n return pluginLoadingError;\n }\n\n return data.error ? data.error.message : undefined;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAYgB,SAAA,gBAAA,CAAiB,EAAE,KAAA,EAAwC,EAAA;AAZ3E,EAAA,IAAA,EAAA,CAAA;AAaE,EAYI,MAAA,EAAA,GAAA,KAAA,CAAM,UAXR,EAAA;AAAA,IAAA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAA;AAAA,IACA,eAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAA;AAAA,IACA,IAAA;AAAA,IACA,aAAA;AAAA,GAvBJ,GAyBM,EADC,EAAA,KAAA,GAAA,SAAA,CACD,EADC,EAAA;AAAA,IAVH,OAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA,aAAA;AAAA,IACA,iBAAA;AAAA,IACA,OAAA;AAAA,IACA,aAAA;AAAA,IACA,aAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA;AAAA,GAAA,CAAA,CAAA;AAGF,EAAA,MAAM,CAAC,GAAK,EAAA,EAAE,OAAO,MAAO,EAAC,IAAI,UAAW,EAAA,CAAA;AAC5C,EAAM,MAAA,MAAA,GAAS,MAAM,SAAU,EAAA,CAAA;AAC/B,EAAM,MAAA,YAAA,GAAe,UAAW,CAAA,SAAA,CAAU,KAAK,CAAA,CAAA;AAG/C,EAAA,MAAM,cAAc,YAAa,CAAA,WAAA,EAAkB,KAAA,CAAA,EAAA,GAAA,KAAA,CAAM,gBAAN,IAAqB,GAAA,EAAA,GAAA,IAAA,CAAA,CAAA;AACxE,EAAA,MAAM,YAAY,WAAe,IAAA,YAAA,CAAa,YAAe,GAAA,YAAA,CAAa,cAAiB,GAAA,EAAA,CAAA;AAC3F,EAAA,MAAM,kBAAkB,WAAe,IAAA,YAAA,CAAa,kBAAqB,GAAA,YAAA,CAAa,oBAAuB,GAAA,EAAA,CAAA;AAC7G,EAAM,MAAA,UAAA,GAAa,UAAW,CAAA,OAAA,CAAQ,KAAK,CAAA,CAAA;AAC3C,EAAM,MAAA,OAAA,GAAU,WAAW,QAAS,EAAA,CAAA;AACpC,EAAA,MAAM,mBAAsB,GAAA,KAAA,CAAM,gBAAiB,CAAA,OAAA,CAAQ,IAAK,CAAA,CAAA;AAGhE,EAAA,MAAM,iBAAoB,GAAA,KAAA,CAAM,WAAY,CAAA,KAAA,EAAO,QAAW,MAAM,CAAA,CAAA;AAGpE,EAAA,MAAM,QAAW,GAAA,UAAA,CAAW,YAAa,CAAA,KAAK,EAAE,WAAY,EAAA,CAAA;AAE5D,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,aAAI,yBAAuB,CAAA,CAAA;AAAA,GACrC;AAEA,EAAI,IAAA,CAAC,OAAO,KAAO,EAAA;AACjB,IAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,aAAI,qCAAmC,CAAA,CAAA;AAAA,GACjD;AAEA,EAAA,MAAM,iBAAiB,MAAO,CAAA,KAAA,CAAA;AAG9B,EAAI,IAAA,KAAA,IAAS,MAAM,iBAAmB,EAAA;AACpC,IAAA,KAAA,CAAM,kBAAkB,KAAK,CAAA,CAAA;AAAA,GAC/B;AAEA,EAAA,MAAM,aAAgC,EAAC,CAAA;AAGvC,EAAI,IAAA,KAAA,CAAM,MAAM,UAAY,EAAA;AAC1B,IAAA,UAAA,CAAW,IAAK,iBAAA,KAAA,CAAA,aAAA,CAAC,KAAM,CAAA,KAAA,CAAM,WAAW,SAAvB,EAAA;AAAA,MAAiC,KAAA,EAAO,MAAM,KAAM,CAAA,UAAA;AAAA,KAAY,CAAE,CAAA,CAAA;AAAA,GACrF;AAEA,EAAI,IAAA,SAAA,CAAA;AACJ,EAAA,IAAI,IAAM,EAAA;AACR,IAAY,SAAA,mBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,SAAL,EAAA;AAAA,MAAe,KAAO,EAAA,IAAA;AAAA,KAAM,CAAA,CAAA;AAAA,GAC3C;AAEA,EAAI,IAAA,cAAA,CAAA;AAEJ,EAAA,IAAI,aAAe,EAAA;AACjB,IAAI,IAAA,aAAA,CAAc,aAAa,CAAG,EAAA;AAChC,MAAiB,cAAA,mBAAA,KAAA,CAAA,aAAA,CAAC,cAAc,SAAd,EAAA;AAAA,QAAwB,KAAO,EAAA,aAAA;AAAA,OAAe,CAAA,CAAA;AAAA,KAC3D,MAAA;AACL,MAAiB,cAAA,GAAA,aAAA,CAAA;AAAA,KACnB;AAAA,GACF;AAGA,EAAA,MAAM,IAAO,GAAA,mBAAA,CAAA;AACb,EAAA,MAAM,eAAkB,GAAA,UAAA,CAAW,oBAAuB,GAAA,UAAA,CAAW,sBAAyB,GAAA,IAAA,CAAA;AAE9F,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,GAAA;AAAA,IAAyC,OAAO,EAAE,QAAA,EAAU,YAAY,KAAO,EAAA,MAAA,EAAQ,QAAQ,MAAO,EAAA;AAAA,GAAA,EACxG,KAAQ,GAAA,CAAA,IAAK,MAAS,GAAA,CAAA,oBACpB,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA;AAAA,IACC,KAAO,EAAA,iBAAA;AAAA,IACP,aAAa,WAAc,GAAA,MAAM,KAAM,CAAA,WAAA,CAAY,WAAW,CAAI,GAAA,EAAA;AAAA,IAClE,cAAc,IAAK,CAAA,KAAA;AAAA,IACnB,aAAA,EAAe,sBAAuB,CAAA,IAAA,EAAM,eAAe,CAAA;AAAA,IAC3D,KAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAS,EAAA,cAAA;AAAA,IACT,eAAA;AAAA,IACA,OAAA,EAAS,MAAO,CAAA,SAAA,GAAY,MAAS,GAAA,IAAA;AAAA,IACrC,IAAM,EAAA,SAAA;AAAA,IACN,eAAe,KAAM,CAAA,aAAA;AAAA,GAAA,EAEpB,CAAC,UAAA,EAAY,WACZ,qBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBACG,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA;AAAA,IAAmB,YAAA,EAAc,CAAC,MAAA,EAAQ,IAAI,CAAA;AAAA,GAAA,kBAC5C,KAAA,CAAA,aAAA,CAAA,qBAAA,EAAA;AAAA,IAAsB,MAAM,MAAO,CAAA,IAAA;AAAA,GAAA,kBACjC,KAAA,CAAA,aAAA,CAAA,oBAAA,EAAA;AAAA,IAAqB,KAAA,EAAO,MAAM,eAAgB,EAAA;AAAA,GAAA,EAChD,mCACE,KAAA,CAAA,aAAA,CAAA,cAAA,EAAA;AAAA,IACC,EAAI,EAAA,CAAA;AAAA,IACJ,IAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAW,IAAK,CAAA,SAAA;AAAA,IAChB,QAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAa,EAAA,KAAA;AAAA,IACb,KAAO,EAAA,UAAA;AAAA,IACP,MAAQ,EAAA,WAAA;AAAA,IACR,aAAe,EAAA,CAAA;AAAA,IACf,kBAAkB,KAAM,CAAA,WAAA;AAAA,IACxB,iBAAiB,KAAM,CAAA,eAAA;AAAA,IACvB,qBAAqB,KAAM,CAAA,mBAAA;AAAA,IAC3B,mBAAmB,KAAM,CAAA,iBAAA;AAAA,IACzB,UAAU,YAAa,EAAA;AAAA,GACzB,CAEJ,CACF,CACF,CACF,CAEJ,CAEJ,CAAA,CAAA;AAEJ,CAAA;AAEA,SAAS,sBAAA,CAAuB,MAAiB,kBAAwC,EAAA;AACvF,EAAA,IAAI,kBAAoB,EAAA;AACtB,IAAO,OAAA,kBAAA,CAAA;AAAA,GACT;AAEA,EAAA,OAAO,IAAK,CAAA,KAAA,GAAQ,IAAK,CAAA,KAAA,CAAM,OAAU,GAAA,KAAA,CAAA,CAAA;AAC3C;;;;"}
@@ -56,6 +56,13 @@ class SceneObjectBase {
56
56
  }
57
57
  _setParent() {
58
58
  this.forEachChild((child) => {
59
+ if (child._parent && child._parent !== this) {
60
+ console.warn(
61
+ "SceneObject already has a parent set that is different from the new parent. You cannot share the same SceneObject instance in multiple scenes or in multiple different places of the same scene graph. Use SceneObject.clone() to duplicate a SceneObject or store a state key reference and use sceneGraph.findObject to locate it.",
62
+ child,
63
+ this
64
+ );
65
+ }
59
66
  child._parent = this;
60
67
  });
61
68
  }