@grafana/scenes 0.0.19 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +20 -10
  2. package/dist/esm/components/EmbeddedScene.js +10 -9
  3. package/dist/esm/components/EmbeddedScene.js.map +1 -1
  4. package/dist/esm/components/SceneApp/SceneApp.js +3 -145
  5. package/dist/esm/components/SceneApp/SceneApp.js.map +1 -1
  6. package/dist/esm/components/SceneApp/SceneAppPage.js +151 -0
  7. package/dist/esm/components/SceneApp/SceneAppPage.js.map +1 -0
  8. package/dist/esm/components/SceneByFrameRepeater.js +8 -8
  9. package/dist/esm/components/SceneByFrameRepeater.js.map +1 -1
  10. package/dist/esm/components/SceneReactObject.js +34 -0
  11. package/dist/esm/components/SceneReactObject.js.map +1 -0
  12. package/dist/esm/components/SceneRefreshPicker.js +8 -9
  13. package/dist/esm/components/SceneRefreshPicker.js.map +1 -1
  14. package/dist/esm/components/VizPanel/VizPanel.js.map +1 -1
  15. package/dist/esm/components/VizPanel/VizPanelMenu.js +42 -0
  16. package/dist/esm/components/VizPanel/VizPanelMenu.js.map +1 -0
  17. package/dist/esm/components/VizPanel/VizPanelRenderer.js +11 -3
  18. package/dist/esm/components/VizPanel/VizPanelRenderer.js.map +1 -1
  19. package/dist/esm/components/layout/SceneFlexLayout.js +2 -1
  20. package/dist/esm/components/layout/SceneFlexLayout.js.map +1 -1
  21. package/dist/esm/core/SceneObjectBase.js +21 -9
  22. package/dist/esm/core/SceneObjectBase.js.map +1 -1
  23. package/dist/esm/core/types.js.map +1 -1
  24. package/dist/esm/index.js +4 -1
  25. package/dist/esm/index.js.map +1 -1
  26. package/dist/esm/querying/SceneDataTransformer.js +10 -9
  27. package/dist/esm/querying/SceneDataTransformer.js.map +1 -1
  28. package/dist/esm/querying/SceneQueryRunner.js +34 -18
  29. package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
  30. package/dist/esm/variables/interpolation/formatRegistry.js.map +1 -1
  31. package/dist/esm/variables/sets/SceneVariableSet.js +29 -29
  32. package/dist/esm/variables/sets/SceneVariableSet.js.map +1 -1
  33. package/dist/esm/variables/variants/query/QueryVariable.js +10 -12
  34. package/dist/esm/variables/variants/query/QueryVariable.js.map +1 -1
  35. package/dist/index.d.ts +112 -43
  36. package/dist/index.js +472 -366
  37. package/dist/index.js.map +1 -1
  38. package/package.json +21 -25
@@ -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} from '@grafana/data';\nimport { config, getPluginImportUtils } from '@grafana/runtime';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { DeepPartial, SceneLayoutChildState } from '../../core/types';\n\nimport { VizPanelRenderer } from './VizPanelRenderer';\nimport { VariableDependencyConfig } from '../../variables/VariableDependencyConfig';\nimport { CustomFormatterFn } from '../../variables/interpolation/sceneInterpolator';\n\nexport interface VizPanelState<TOptions = {}, TFieldConfig = {}> extends SceneLayoutChildState {\n title: string;\n description?: string;\n pluginId: string;\n options: DeepPartial<TOptions>;\n fieldConfig: FieldConfigSource<DeepPartial<TFieldConfig>>;\n pluginVersion?: string;\n displayMode?: 'default' | 'transparent';\n hoverHeader?: boolean;\n // internal state\n pluginLoadError?: string;\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\n public constructor(state: Partial<VizPanelState<TOptions, TFieldConfig>>) {\n super({\n options: {},\n fieldConfig: { defaults: {}, overrides: [] },\n title: 'Title',\n pluginId: 'timeseries',\n ...state,\n });\n }\n\n public activate() {\n super.activate();\n const { getPanelPluginFromCache, importPanelPlugin } = getPluginImportUtils();\n const plugin = getPanelPluginFromCache(this.state.pluginId);\n\n if (plugin) {\n this.pluginLoaded(plugin);\n } else {\n importPanelPlugin(this.state.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, pluginId, pluginVersion } = this.state;\n\n const panel: PanelModel = { title, options, fieldConfig, id: 1, type: pluginId, pluginVersion: pluginVersion };\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 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 | CustomFormatterFn) => {\n return sceneGraph.interpolate(this, value, scoped, format);\n }) as InterpolateFunction;\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} from '@grafana/data';\nimport { config, getPluginImportUtils } from '@grafana/runtime';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { DeepPartial, SceneLayoutChildState } from '../../core/types';\n\nimport { VizPanelRenderer } from './VizPanelRenderer';\nimport { VizPanelMenu } from './VizPanelMenu';\nimport { VariableDependencyConfig } from '../../variables/VariableDependencyConfig';\nimport { CustomFormatterFn } from '../../variables/interpolation/sceneInterpolator';\n\nexport interface VizPanelState<TOptions = {}, TFieldConfig = {}> extends SceneLayoutChildState {\n title: string;\n description?: string;\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 // internal state\n pluginLoadError?: string;\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\n public constructor(state: Partial<VizPanelState<TOptions, TFieldConfig>>) {\n super({\n options: {},\n fieldConfig: { defaults: {}, overrides: [] },\n title: 'Title',\n pluginId: 'timeseries',\n ...state,\n });\n }\n\n public activate() {\n super.activate();\n const { getPanelPluginFromCache, importPanelPlugin } = getPluginImportUtils();\n const plugin = getPanelPluginFromCache(this.state.pluginId);\n\n if (plugin) {\n this.pluginLoaded(plugin);\n } else {\n importPanelPlugin(this.state.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, pluginId, pluginVersion } = this.state;\n\n const panel: PanelModel = { title, options, fieldConfig, id: 1, type: pluginId, pluginVersion: pluginVersion };\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 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 | CustomFormatterFn) => {\n return sceneGraph.interpolate(this, value, scoped, format);\n }) as InterpolateFunction;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import { Menu } from '@grafana/ui';
3
+ import { SceneObjectBase } from '../../core/SceneObjectBase.js';
4
+
5
+ class VizPanelMenu extends SceneObjectBase {
6
+ addItem(item) {
7
+ this.setState({
8
+ items: this.state.items ? [...this.state.items, item] : [item]
9
+ });
10
+ }
11
+ setItems(items) {
12
+ this.setState({
13
+ items
14
+ });
15
+ }
16
+ }
17
+ VizPanelMenu.Component = VizPanelMenuRenderer;
18
+ function VizPanelMenuRenderer({ model }) {
19
+ const { items } = model.useState();
20
+ const renderItems = (items2) => {
21
+ return items2.map(
22
+ (item) => item.type === "divider" ? /* @__PURE__ */ React.createElement(Menu.Divider, {
23
+ key: item.text
24
+ }) : /* @__PURE__ */ React.createElement(Menu.Item, {
25
+ key: item.text,
26
+ label: item.text,
27
+ icon: item.iconClassName,
28
+ childItems: item.subMenu ? renderItems(item.subMenu) : void 0,
29
+ url: item.href,
30
+ onClick: item.onClick,
31
+ shortcut: item.shortcut
32
+ })
33
+ );
34
+ };
35
+ if (!items) {
36
+ return null;
37
+ }
38
+ return /* @__PURE__ */ React.createElement(Menu, null, renderItems(items));
39
+ }
40
+
41
+ export { VizPanelMenu };
42
+ //# sourceMappingURL=VizPanelMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VizPanelMenu.js","sources":["../../../../src/components/VizPanel/VizPanelMenu.tsx"],"sourcesContent":["import React from 'react';\nimport { PanelMenuItem } from '@grafana/data';\nimport { Menu } from '@grafana/ui';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObjectStatePlain } from '../../core/types';\n\ninterface VizPanelMenuState extends SceneObjectStatePlain {\n items?: PanelMenuItem[];\n}\n\nexport class VizPanelMenu extends SceneObjectBase<VizPanelMenuState> {\n static Component = VizPanelMenuRenderer;\n\n // Allows adding menu items dynamically\n public addItem(item: PanelMenuItem) {\n this.setState({\n items: this.state.items ? [...this.state.items, item] : [item],\n });\n }\n\n // Allows replacing all menu items\n public setItems(items: PanelMenuItem[]) {\n this.setState({\n items,\n });\n }\n}\n\nfunction VizPanelMenuRenderer({ model }: SceneComponentProps<VizPanelMenu>) {\n const { items } = model.useState();\n\n const renderItems = (items: PanelMenuItem[]) => {\n return items.map((item) =>\n item.type === 'divider' ? (\n <Menu.Divider key={item.text} />\n ) : (\n <Menu.Item\n key={item.text}\n label={item.text}\n icon={item.iconClassName}\n childItems={item.subMenu ? renderItems(item.subMenu) : undefined}\n url={item.href}\n onClick={item.onClick}\n shortcut={item.shortcut}\n />\n )\n );\n };\n if (!items) {\n return null;\n }\n\n return <Menu>{renderItems(items)}</Menu>;\n}\n"],"names":["items"],"mappings":";;;;AAUO,MAAM,qBAAqB,eAAmC,CAAA;AAAA,EAI5D,QAAQ,IAAqB,EAAA;AAClC,IAAA,IAAA,CAAK,QAAS,CAAA;AAAA,MACZ,KAAO,EAAA,IAAA,CAAK,KAAM,CAAA,KAAA,GAAQ,CAAC,GAAG,IAAK,CAAA,KAAA,CAAM,KAAO,EAAA,IAAI,CAAI,GAAA,CAAC,IAAI,CAAA;AAAA,KAC9D,CAAA,CAAA;AAAA,GACH;AAAA,EAGO,SAAS,KAAwB,EAAA;AACtC,IAAA,IAAA,CAAK,QAAS,CAAA;AAAA,MACZ,KAAA;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAA;AAhBa,YAAA,CACJ,SAAY,GAAA,oBAAA,CAAA;AAiBrB,SAAS,oBAAA,CAAqB,EAAE,KAAA,EAA4C,EAAA;AAC1E,EAAA,MAAM,EAAE,KAAA,EAAU,GAAA,KAAA,CAAM,QAAS,EAAA,CAAA;AAEjC,EAAM,MAAA,WAAA,GAAc,CAACA,MAA2B,KAAA;AAC9C,IAAA,OAAOA,MAAM,CAAA,GAAA;AAAA,MAAI,CAAC,IAChB,KAAA,IAAA,CAAK,SAAS,SACZ,mBAAA,KAAA,CAAA,aAAA,CAAC,KAAK,OAAL,EAAA;AAAA,QAAa,KAAK,IAAK,CAAA,IAAA;AAAA,OAAM,CAAA,mBAE7B,KAAA,CAAA,aAAA,CAAA,IAAA,CAAK,IAAL,EAAA;AAAA,QACC,KAAK,IAAK,CAAA,IAAA;AAAA,QACV,OAAO,IAAK,CAAA,IAAA;AAAA,QACZ,MAAM,IAAK,CAAA,aAAA;AAAA,QACX,YAAY,IAAK,CAAA,OAAA,GAAU,WAAY,CAAA,IAAA,CAAK,OAAO,CAAI,GAAA,KAAA,CAAA;AAAA,QACvD,KAAK,IAAK,CAAA,IAAA;AAAA,QACV,SAAS,IAAK,CAAA,OAAA;AAAA,QACd,UAAU,IAAK,CAAA,QAAA;AAAA,OACjB,CAAA;AAAA,KAEJ,CAAA;AAAA,GACF,CAAA;AACA,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAM,WAAY,CAAA,KAAK,CAAE,CAAA,CAAA;AACnC;;;;"}
@@ -18,17 +18,18 @@ function VizPanelRenderer({ model }) {
18
18
  $data,
19
19
  placement,
20
20
  displayMode,
21
- hoverHeader
21
+ hoverHeader,
22
+ menu
22
23
  } = model.useState();
23
24
  const [ref, { width, height }] = useMeasure();
24
25
  const plugin = model.getPlugin();
25
- const { data } = sceneGraph.getData(model).useState();
26
26
  const parentLayout = sceneGraph.getLayout(model);
27
27
  const isDraggable = parentLayout.isDraggable() && ((_a = placement == null ? void 0 : placement.isDraggable) != null ? _a : true);
28
28
  const dragClass = isDraggable && parentLayout.getDragClass ? parentLayout.getDragClass() : "";
29
29
  const dragClassCancel = isDraggable && parentLayout.getDragClassCancel ? parentLayout.getDragClassCancel() : "";
30
30
  const titleInterpolated = model.interpolate(title, void 0, "text");
31
31
  const timeZone = sceneGraph.getTimeRange(model).state.timeZone;
32
+ const { data } = sceneGraph.getData(model).useState();
32
33
  const dataWithOverrides = useFieldOverrides(plugin, fieldConfig, data, timeZone, theme, model.interpolate);
33
34
  if (pluginLoadError) {
34
35
  return /* @__PURE__ */ React.createElement("div", null, "Failed to load plugin: ", pluginLoadError);
@@ -49,6 +50,12 @@ function VizPanelRenderer({ model }) {
49
50
  model: model.state.$timeRange
50
51
  }));
51
52
  }
53
+ let panelMenu;
54
+ if (menu) {
55
+ panelMenu = /* @__PURE__ */ React.createElement(menu.Component, {
56
+ model: menu
57
+ });
58
+ }
52
59
  return /* @__PURE__ */ React.createElement("div", {
53
60
  ref,
54
61
  style: { position: "absolute", width: "100%", height: "100%" }
@@ -63,7 +70,8 @@ function VizPanelRenderer({ model }) {
63
70
  hoverHeader,
64
71
  titleItems,
65
72
  dragClass,
66
- dragClassCancel
73
+ dragClassCancel,
74
+ menu: panelMenu
67
75
  }, (innerWidth, innerHeight) => /* @__PURE__ */ React.createElement(React.Fragment, null, !dataWithOverrides && /* @__PURE__ */ React.createElement("div", null, "No data..."), dataWithOverrides && /* @__PURE__ */ React.createElement(ErrorBoundaryAlert, {
68
76
  dependencies: [plugin, data]
69
77
  }, /* @__PURE__ */ React.createElement(PluginContextProvider, {
@@ -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 { PluginContextProvider, useFieldOverrides } from '@grafana/data';\nimport { getAppEvents } from '@grafana/runtime';\nimport { PanelChrome, ErrorBoundaryAlert, useTheme2 } from '@grafana/ui';\n\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { SceneComponentProps } from '../../core/types';\n\nimport { VizPanel } from './VizPanel';\n\nexport function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {\n const theme = useTheme2();\n const {\n title,\n description,\n options,\n fieldConfig,\n pluginId,\n pluginLoadError,\n $data,\n placement,\n displayMode,\n hoverHeader,\n } = model.useState();\n const [ref, { width, height }] = useMeasure();\n const plugin = model.getPlugin();\n const { data } = sceneGraph.getData(model).useState();\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() && (placement?.isDraggable ?? true);\n const dragClass = isDraggable && parentLayout.getDragClass ? parentLayout.getDragClass() : '';\n const dragClassCancel = isDraggable && parentLayout.getDragClassCancel ? parentLayout.getDragClassCancel() : '';\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).state.timeZone;\n const dataWithOverrides = useFieldOverrides(plugin, fieldConfig, data, timeZone, theme, model.interpolate);\n\n if (pluginLoadError) {\n return <div>Failed to load plugin: {pluginLoadError}</div>;\n }\n\n if (!plugin || !plugin.hasPluginId(pluginId)) {\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 return (\n <div ref={ref as RefCallback<HTMLDivElement>} style={{ position: 'absolute', width: '100%', height: '100%' }}>\n <PanelChrome\n title={titleInterpolated}\n description={description ? () => model.interpolate(description) : ''}\n loadingState={dataWithOverrides?.state}\n statusMessage={dataWithOverrides?.error ? dataWithOverrides.error.message : ''}\n width={width}\n height={height}\n displayMode={displayMode}\n hoverHeader={hoverHeader}\n titleItems={titleItems}\n dragClass={dragClass}\n dragClassCancel={dragClassCancel}\n >\n {(innerWidth, innerHeight) => (\n <>\n {!dataWithOverrides && <div>No data...</div>}\n {dataWithOverrides && (\n <ErrorBoundaryAlert dependencies={[plugin, data]}>\n <PluginContextProvider meta={plugin.meta}>\n <PanelComponent\n id={1}\n data={dataWithOverrides}\n title={title}\n timeRange={dataWithOverrides.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 </PluginContextProvider>\n </ErrorBoundaryAlert>\n )}\n </>\n )}\n </PanelChrome>\n </div>\n );\n}\n\nVizPanelRenderer.displayName = 'ScenePanelRenderer';\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 { PluginContextProvider, useFieldOverrides } from '@grafana/data';\nimport { getAppEvents } from '@grafana/runtime';\nimport { PanelChrome, ErrorBoundaryAlert, useTheme2 } from '@grafana/ui';\n\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { SceneComponentProps } from '../../core/types';\n\nimport { VizPanel } from './VizPanel';\n\nexport function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {\n const theme = useTheme2();\n const {\n title,\n description,\n options,\n fieldConfig,\n pluginId,\n pluginLoadError,\n $data,\n placement,\n displayMode,\n hoverHeader,\n menu,\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() && (placement?.isDraggable ?? true);\n const dragClass = isDraggable && parentLayout.getDragClass ? parentLayout.getDragClass() : '';\n const dragClassCancel = isDraggable && parentLayout.getDragClassCancel ? parentLayout.getDragClassCancel() : '';\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).state.timeZone;\n\n // Subscribe to data and apply field overrides\n const { data } = sceneGraph.getData(model).useState();\n const dataWithOverrides = useFieldOverrides(plugin, fieldConfig, data, timeZone, theme, model.interpolate);\n\n if (pluginLoadError) {\n return <div>Failed to load plugin: {pluginLoadError}</div>;\n }\n\n if (!plugin || !plugin.hasPluginId(pluginId)) {\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 return (\n <div ref={ref as RefCallback<HTMLDivElement>} style={{ position: 'absolute', width: '100%', height: '100%' }}>\n <PanelChrome\n title={titleInterpolated}\n description={description ? () => model.interpolate(description) : ''}\n loadingState={dataWithOverrides?.state}\n statusMessage={dataWithOverrides?.error ? dataWithOverrides.error.message : ''}\n width={width}\n height={height}\n displayMode={displayMode}\n hoverHeader={hoverHeader}\n titleItems={titleItems}\n dragClass={dragClass}\n dragClassCancel={dragClassCancel}\n menu={panelMenu}\n >\n {(innerWidth, innerHeight) => (\n <>\n {!dataWithOverrides && <div>No data...</div>}\n {dataWithOverrides && (\n <ErrorBoundaryAlert dependencies={[plugin, data]}>\n <PluginContextProvider meta={plugin.meta}>\n <PanelComponent\n id={1}\n data={dataWithOverrides}\n title={title}\n timeRange={dataWithOverrides.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 </PluginContextProvider>\n </ErrorBoundaryAlert>\n )}\n </>\n )}\n </PanelChrome>\n </div>\n );\n}\n\nVizPanelRenderer.displayName = 'ScenePanelRenderer';\n"],"names":[],"mappings":"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"}
@@ -22,7 +22,8 @@ function FlexLayoutRenderer({ model, isEditing }) {
22
22
  display: "flex",
23
23
  gap: "8px",
24
24
  flexWrap: wrap,
25
- alignContent: "baseline"
25
+ alignContent: "baseline",
26
+ minHeight: 0
26
27
  };
27
28
  return /* @__PURE__ */ React.createElement("div", {
28
29
  style
@@ -1 +1 @@
1
- {"version":3,"file":"SceneFlexLayout.js","sources":["../../../../src/components/layout/SceneFlexLayout.tsx"],"sourcesContent":["import React, { CSSProperties } from 'react';\n\nimport { Field, RadioButtonGroup } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport {\n SceneComponentProps,\n SceneLayoutChild,\n SceneLayoutState,\n SceneLayoutChildOptions,\n SceneLayout,\n} from '../../core/types';\n\nexport type FlexLayoutDirection = 'column' | 'row';\n\ninterface SceneFlexLayoutState extends SceneLayoutState {\n direction?: FlexLayoutDirection;\n wrap?: CSSProperties['flexWrap'];\n}\n\nexport class SceneFlexLayout extends SceneObjectBase<SceneFlexLayoutState> implements SceneLayout {\n public static Component = FlexLayoutRenderer;\n public static Editor = FlexLayoutEditor;\n\n public toggleDirection() {\n this.setState({\n direction: this.state.direction === 'row' ? 'column' : 'row',\n });\n }\n\n public isDraggable(): boolean {\n return false;\n }\n}\n\nfunction FlexLayoutRenderer({ model, isEditing }: SceneComponentProps<SceneFlexLayout>) {\n const { direction = 'row', children, wrap } = model.useState();\n\n const style: CSSProperties = {\n flexGrow: 1,\n flexDirection: direction,\n display: 'flex',\n gap: '8px',\n flexWrap: wrap,\n alignContent: 'baseline',\n };\n\n return (\n <div style={style}>\n {children.map((item) => (\n <FlexLayoutChildComponent key={item.state.key} item={item} direction={direction} isEditing={isEditing} />\n ))}\n </div>\n );\n}\n\nfunction FlexLayoutChildComponent({\n item,\n direction,\n isEditing,\n}: {\n item: SceneLayoutChild;\n direction: FlexLayoutDirection;\n isEditing?: boolean;\n}) {\n const { placement } = item.useState();\n\n return (\n <div style={getItemStyles(direction, placement)}>\n <item.Component model={item} isEditing={isEditing} />\n </div>\n );\n}\n\nfunction getItemStyles(direction: FlexLayoutDirection, layout: SceneLayoutChildOptions = {}) {\n const { xSizing = 'fill', ySizing = 'fill' } = layout;\n\n const style: CSSProperties = {\n display: 'flex',\n flexDirection: direction,\n minWidth: layout.minWidth,\n minHeight: layout.minHeight,\n position: 'relative',\n };\n\n if (direction === 'column') {\n if (layout.height) {\n style.height = layout.height;\n } else {\n style.flexGrow = ySizing === 'fill' ? 1 : 0;\n }\n\n if (layout.width) {\n style.width = layout.width;\n } else {\n style.alignSelf = xSizing === 'fill' ? 'stretch' : 'flex-start';\n }\n } else {\n if (layout.height) {\n style.height = layout.height;\n } else {\n style.alignSelf = ySizing === 'fill' ? 'stretch' : 'flex-start';\n }\n\n if (layout.width) {\n style.width = layout.width;\n } else {\n style.flexGrow = xSizing === 'fill' ? 1 : 0;\n }\n }\n\n return style;\n}\n\nfunction FlexLayoutEditor({ model }: SceneComponentProps<SceneFlexLayout>) {\n const { direction = 'row' } = model.useState();\n const options = [\n { icon: 'arrow-right', value: 'row' },\n { icon: 'arrow-down', value: 'column' },\n ];\n\n return (\n <Field label=\"Direction\">\n <RadioButtonGroup\n options={options}\n value={direction}\n onChange={(value) => model.setState({ direction: value as FlexLayoutDirection })}\n />\n </Field>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SceneFlexLayout.js","sources":["../../../../src/components/layout/SceneFlexLayout.tsx"],"sourcesContent":["import React, { CSSProperties } from 'react';\n\nimport { Field, RadioButtonGroup } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport {\n SceneComponentProps,\n SceneLayoutChild,\n SceneLayoutState,\n SceneLayoutChildOptions,\n SceneLayout,\n} from '../../core/types';\n\nexport type FlexLayoutDirection = 'column' | 'row';\n\ninterface SceneFlexLayoutState extends SceneLayoutState {\n direction?: FlexLayoutDirection;\n wrap?: CSSProperties['flexWrap'];\n}\n\nexport class SceneFlexLayout extends SceneObjectBase<SceneFlexLayoutState> implements SceneLayout {\n public static Component = FlexLayoutRenderer;\n public static Editor = FlexLayoutEditor;\n\n public toggleDirection() {\n this.setState({\n direction: this.state.direction === 'row' ? 'column' : 'row',\n });\n }\n\n public isDraggable(): boolean {\n return false;\n }\n}\n\nfunction FlexLayoutRenderer({ model, isEditing }: SceneComponentProps<SceneFlexLayout>) {\n const { direction = 'row', children, wrap } = model.useState();\n const style: CSSProperties = {\n flexGrow: 1,\n flexDirection: direction,\n display: 'flex',\n gap: '8px',\n flexWrap: wrap,\n alignContent: 'baseline',\n minHeight: 0,\n };\n\n return (\n <div style={style}>\n {children.map((item) => (\n <FlexLayoutChildComponent key={item.state.key} item={item} direction={direction} isEditing={isEditing} />\n ))}\n </div>\n );\n}\n\nfunction FlexLayoutChildComponent({\n item,\n direction,\n isEditing,\n}: {\n item: SceneLayoutChild;\n direction: FlexLayoutDirection;\n isEditing?: boolean;\n}) {\n const { placement } = item.useState();\n\n return (\n <div style={getItemStyles(direction, placement)}>\n <item.Component model={item} isEditing={isEditing} />\n </div>\n );\n}\n\nfunction getItemStyles(direction: FlexLayoutDirection, layout: SceneLayoutChildOptions = {}) {\n const { xSizing = 'fill', ySizing = 'fill' } = layout;\n\n const style: CSSProperties = {\n display: 'flex',\n flexDirection: direction,\n minWidth: layout.minWidth,\n minHeight: layout.minHeight,\n position: 'relative',\n };\n\n if (direction === 'column') {\n if (layout.height) {\n style.height = layout.height;\n } else {\n style.flexGrow = ySizing === 'fill' ? 1 : 0;\n }\n\n if (layout.width) {\n style.width = layout.width;\n } else {\n style.alignSelf = xSizing === 'fill' ? 'stretch' : 'flex-start';\n }\n } else {\n if (layout.height) {\n style.height = layout.height;\n } else {\n style.alignSelf = ySizing === 'fill' ? 'stretch' : 'flex-start';\n }\n\n if (layout.width) {\n style.width = layout.width;\n } else {\n style.flexGrow = xSizing === 'fill' ? 1 : 0;\n }\n }\n\n return style;\n}\n\nfunction FlexLayoutEditor({ model }: SceneComponentProps<SceneFlexLayout>) {\n const { direction = 'row' } = model.useState();\n const options = [\n { icon: 'arrow-right', value: 'row' },\n { icon: 'arrow-down', value: 'column' },\n ];\n\n return (\n <Field label=\"Direction\">\n <RadioButtonGroup\n options={options}\n value={direction}\n onChange={(value) => model.setState({ direction: value as FlexLayoutDirection })}\n />\n </Field>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { useEffect } from 'react';
2
- import { Subject, Subscription } from 'rxjs';
2
+ import { Subscription } from 'rxjs';
3
3
  import { v4 } from 'uuid';
4
4
  import { EventBusSrv } from '@grafana/data';
5
5
  import { useForceUpdate } from '@grafana/ui';
@@ -26,14 +26,14 @@ var __spreadValues = (a, b) => {
26
26
  class SceneObjectBase {
27
27
  constructor(state) {
28
28
  this._isActive = false;
29
- this._subject = new Subject();
30
29
  this._events = new EventBusSrv();
30
+ this._activationHandlers = [];
31
+ this._deactivationHandlers = [];
31
32
  this._subs = new Subscription();
32
33
  if (!state.key) {
33
34
  state.key = v4();
34
35
  }
35
36
  this._state = Object.freeze(state);
36
- this._subject.next(state);
37
37
  this.setParent();
38
38
  }
39
39
  get state() {
@@ -61,8 +61,12 @@ class SceneObjectBase {
61
61
  setParent() {
62
62
  forEachSceneObjectInState(this._state, (child) => child._parent = this);
63
63
  }
64
- subscribeToState(observerOrNext) {
65
- return this._subject.subscribe(observerOrNext);
64
+ subscribeToState(handler) {
65
+ return this._events.subscribe(SceneObjectStateChangedEvent, (event) => {
66
+ if (event.payload.changedObject === this) {
67
+ handler(event.payload.newState, event.payload.prevState);
68
+ }
69
+ });
66
70
  }
67
71
  subscribeToEvent(eventType, handler) {
68
72
  return this._events.subscribe(eventType, handler);
@@ -72,7 +76,6 @@ class SceneObjectBase {
72
76
  const newState = __spreadValues(__spreadValues({}, this._state), update);
73
77
  this._state = Object.freeze(newState);
74
78
  this.setParent();
75
- this._subject.next(newState);
76
79
  this.publishEvent(
77
80
  new SceneObjectStateChangedEvent({
78
81
  prevState,
@@ -104,6 +107,12 @@ class SceneObjectBase {
104
107
  if ($data && !$data.isActive) {
105
108
  $data.activate();
106
109
  }
110
+ this._activationHandlers.forEach((handler) => {
111
+ const result = handler();
112
+ if (result) {
113
+ this._deactivationHandlers.push(result);
114
+ }
115
+ });
107
116
  }
108
117
  deactivate() {
109
118
  this._isActive = false;
@@ -117,11 +126,11 @@ class SceneObjectBase {
117
126
  if ($variables && $variables.isActive) {
118
127
  $variables.deactivate();
119
128
  }
129
+ this._deactivationHandlers.forEach((handler) => handler());
130
+ this._deactivationHandlers = [];
120
131
  this._events.removeAllListeners();
121
132
  this._subs.unsubscribe();
122
133
  this._subs = new Subscription();
123
- this._subject.complete();
124
- this._subject = new Subject();
125
134
  }
126
135
  useState() {
127
136
  return useSceneObjectState(this);
@@ -132,11 +141,14 @@ class SceneObjectBase {
132
141
  clone(withState) {
133
142
  return cloneSceneObject(this, withState);
134
143
  }
144
+ addActivationHandler(handler) {
145
+ this._activationHandlers.push(handler);
146
+ }
135
147
  }
136
148
  function useSceneObjectState(model) {
137
149
  const forceUpdate = useForceUpdate();
138
150
  useEffect(() => {
139
- const s = model.subscribeToState({ next: forceUpdate });
151
+ const s = model.subscribeToState(forceUpdate);
140
152
  return () => s.unsubscribe();
141
153
  }, [model, forceUpdate]);
142
154
  return model.state;
@@ -1 +1 @@
1
- {"version":3,"file":"SceneObjectBase.js","sources":["../../../src/core/SceneObjectBase.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { Observer, Subject, Subscription, SubscriptionLike, Unsubscribable } from 'rxjs';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BusEvent, BusEventHandler, BusEventType, EventBusSrv } from '@grafana/data';\nimport { SceneObject, SceneComponent, SceneObjectState, SceneObjectUrlSyncHandler } from './types';\nimport { useForceUpdate } from '@grafana/ui';\n\nimport { SceneComponentWrapper } from './SceneComponentWrapper';\nimport { SceneObjectStateChangedEvent } from './events';\nimport { cloneSceneObject, forEachSceneObjectInState } from './utils';\nimport { SceneVariableDependencyConfigLike } from '../variables/types';\n\nexport abstract class SceneObjectBase<TState extends SceneObjectState = SceneObjectState>\n implements SceneObject<TState>\n{\n private _isActive = false;\n private _subject = new Subject<TState>();\n private _state: TState;\n private _events = new EventBusSrv();\n\n protected _parent?: SceneObject;\n protected _subs = new Subscription();\n\n protected _variableDependency: SceneVariableDependencyConfigLike | undefined;\n protected _urlSync: SceneObjectUrlSyncHandler<TState> | undefined;\n\n public constructor(state: TState) {\n if (!state.key) {\n state.key = uuidv4();\n }\n\n this._state = Object.freeze(state);\n this._subject.next(state);\n this.setParent();\n }\n\n /** Current state */\n public get state(): TState {\n return this._state;\n }\n\n /** True if currently being active (ie displayed for visual objects) */\n public get isActive(): boolean {\n return this._isActive;\n }\n\n /** Returns the parent, undefined for root object */\n public get parent(): SceneObject | undefined {\n return this._parent;\n }\n\n /** Returns variable dependency config */\n public get variableDependency(): SceneVariableDependencyConfigLike | undefined {\n return this._variableDependency;\n }\n\n /** Returns url sync config */\n public get urlSync(): SceneObjectUrlSyncHandler<TState> | undefined {\n return this._urlSync;\n }\n\n /**\n * Used in render functions when rendering a SceneObject.\n * Wraps the component in an EditWrapper that handles edit mode\n */\n public get Component(): SceneComponent<this> {\n return SceneComponentWrapper;\n }\n\n /**\n * Temporary solution, should be replaced by declarative options\n */\n public get Editor(): SceneComponent<this> {\n return ((this as any).constructor['Editor'] ?? (() => null)) as SceneComponent<this>;\n }\n\n private setParent() {\n forEachSceneObjectInState(this._state, (child) => (child._parent = this));\n }\n\n /**\n * Subscribe to the scene state subject\n **/\n public subscribeToState(observerOrNext?: Partial<Observer<TState>>): SubscriptionLike {\n return this._subject.subscribe(observerOrNext);\n }\n\n /**\n * Subscribe to the scene event\n **/\n public subscribeToEvent<T extends BusEvent>(eventType: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable {\n return this._events.subscribe(eventType, handler);\n }\n\n public setState(update: Partial<TState>) {\n const prevState = this._state;\n const newState: TState = {\n ...this._state,\n ...update,\n };\n\n this._state = Object.freeze(newState);\n\n this.setParent();\n this._subject.next(newState);\n\n // Bubble state change event. This is event is subscribed to by UrlSyncManager and UndoManager\n this.publishEvent(\n new SceneObjectStateChangedEvent({\n prevState,\n newState,\n partialUpdate: update,\n changedObject: this,\n }),\n true\n );\n }\n /*\n * Publish an event and optionally bubble it up the scene\n **/\n public publishEvent(event: BusEvent, bubble?: boolean) {\n this._events.publish(event);\n\n if (bubble && this.parent) {\n this.parent.publishEvent(event, bubble);\n }\n }\n\n public getRoot(): SceneObject {\n return !this._parent ? this : this._parent.getRoot();\n }\n\n /**\n * Called by the SceneComponentWrapper when the react component is mounted\n */\n public activate() {\n this._isActive = true;\n\n const { $data, $variables, $timeRange } = this.state;\n\n if ($timeRange && !$timeRange.isActive) {\n $timeRange.activate();\n }\n\n if ($variables && !$variables.isActive) {\n $variables.activate();\n }\n\n if ($data && !$data.isActive) {\n $data.activate();\n }\n }\n\n /**\n * Called by the SceneComponentWrapper when the react component is unmounted\n */\n public deactivate(): void {\n this._isActive = false;\n\n const { $data, $variables, $timeRange } = this.state;\n\n if ($timeRange && $timeRange.isActive) {\n $timeRange.deactivate();\n }\n\n if ($data && $data.isActive) {\n $data.deactivate();\n }\n\n if ($variables && $variables.isActive) {\n $variables.deactivate();\n }\n\n // Clear subscriptions and listeners\n this._events.removeAllListeners();\n this._subs.unsubscribe();\n this._subs = new Subscription();\n\n this._subject.complete();\n this._subject = new Subject<TState>();\n }\n\n /**\n * Utility hook to get and subscribe to state\n */\n public useState() {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useSceneObjectState(this);\n }\n\n /** Force a re-render, should only be needed when variable values change */\n public forceRender(): void {\n this.setState({});\n }\n\n /**\n * Will create new SceneObject with shallow-cloned state, but all state items of type SceneObject are deep cloned\n */\n public clone(withState?: Partial<TState>): this {\n return cloneSceneObject(this, withState);\n }\n}\n\n/**\n * This hook is always returning model.state instead of a useState that remembers the last state emitted on the subject\n * The reason for this is so that if the model instance change this function will always return the latest state.\n */\nfunction useSceneObjectState<TState extends SceneObjectState>(model: SceneObjectBase<TState>): TState {\n const forceUpdate = useForceUpdate();\n\n useEffect(() => {\n const s = model.subscribeToState({ next: forceUpdate });\n return () => s.unsubscribe();\n }, [model, forceUpdate]);\n\n return model.state;\n}\n"],"names":["uuidv4"],"mappings":"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"}
1
+ {"version":3,"file":"SceneObjectBase.js","sources":["../../../src/core/SceneObjectBase.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { Subscription, Unsubscribable } from 'rxjs';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BusEvent, BusEventHandler, BusEventType, EventBusSrv } from '@grafana/data';\nimport {\n SceneObject,\n SceneComponent,\n SceneObjectState,\n SceneObjectUrlSyncHandler,\n SceneStateChangedHandler,\n SceneActivationHandler,\n SceneDeactivationHandler,\n} from './types';\nimport { useForceUpdate } from '@grafana/ui';\n\nimport { SceneComponentWrapper } from './SceneComponentWrapper';\nimport { SceneObjectStateChangedEvent } from './events';\nimport { cloneSceneObject, forEachSceneObjectInState } from './utils';\nimport { SceneVariableDependencyConfigLike } from '../variables/types';\n\nexport abstract class SceneObjectBase<TState extends SceneObjectState = SceneObjectState>\n implements SceneObject<TState>\n{\n private _isActive = false;\n private _state: TState;\n private _events = new EventBusSrv();\n private _activationHandlers: SceneActivationHandler[] = [];\n private _deactivationHandlers: SceneDeactivationHandler[] = [];\n\n protected _parent?: SceneObject;\n protected _subs = new Subscription();\n\n protected _variableDependency: SceneVariableDependencyConfigLike | undefined;\n protected _urlSync: SceneObjectUrlSyncHandler<TState> | undefined;\n\n public constructor(state: TState) {\n if (!state.key) {\n state.key = uuidv4();\n }\n\n this._state = Object.freeze(state);\n this.setParent();\n }\n\n /** Current state */\n public get state(): TState {\n return this._state;\n }\n\n /** True if currently being active (ie displayed for visual objects) */\n public get isActive(): boolean {\n return this._isActive;\n }\n\n /** Returns the parent, undefined for root object */\n public get parent(): SceneObject | undefined {\n return this._parent;\n }\n\n /** Returns variable dependency config */\n public get variableDependency(): SceneVariableDependencyConfigLike | undefined {\n return this._variableDependency;\n }\n\n /** Returns url sync config */\n public get urlSync(): SceneObjectUrlSyncHandler<TState> | undefined {\n return this._urlSync;\n }\n\n /**\n * Used in render functions when rendering a SceneObject.\n * Wraps the component in an EditWrapper that handles edit mode\n */\n public get Component(): SceneComponent<this> {\n return SceneComponentWrapper;\n }\n\n /**\n * Temporary solution, should be replaced by declarative options\n */\n public get Editor(): SceneComponent<this> {\n return ((this as any).constructor['Editor'] ?? (() => null)) as SceneComponent<this>;\n }\n\n private setParent() {\n forEachSceneObjectInState(this._state, (child) => (child._parent = this));\n }\n\n /**\n * Subscribe to the scene state subject\n **/\n public subscribeToState(handler: SceneStateChangedHandler<TState>): Unsubscribable {\n return this._events.subscribe(SceneObjectStateChangedEvent, (event) => {\n if (event.payload.changedObject === this) {\n handler(event.payload.newState as TState, event.payload.prevState as TState);\n }\n });\n }\n\n /**\n * Subscribe to the scene event\n **/\n public subscribeToEvent<T extends BusEvent>(eventType: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable {\n return this._events.subscribe(eventType, handler);\n }\n\n public setState(update: Partial<TState>) {\n const prevState = this._state;\n const newState: TState = {\n ...this._state,\n ...update,\n };\n\n this._state = Object.freeze(newState);\n\n this.setParent();\n\n // Bubble state change event. This is event is subscribed to by UrlSyncManager and UndoManager\n this.publishEvent(\n new SceneObjectStateChangedEvent({\n prevState,\n newState,\n partialUpdate: update,\n changedObject: this,\n }),\n true\n );\n }\n /*\n * Publish an event and optionally bubble it up the scene\n **/\n public publishEvent(event: BusEvent, bubble?: boolean) {\n this._events.publish(event);\n\n if (bubble && this.parent) {\n this.parent.publishEvent(event, bubble);\n }\n }\n\n public getRoot(): SceneObject {\n return !this._parent ? this : this._parent.getRoot();\n }\n\n /**\n * Called by the SceneComponentWrapper when the react component is mounted.\n * Don't override this, instead use addActivationHandler\n */\n public activate() {\n this._isActive = true;\n\n const { $data, $variables, $timeRange } = this.state;\n\n if ($timeRange && !$timeRange.isActive) {\n $timeRange.activate();\n }\n\n if ($variables && !$variables.isActive) {\n $variables.activate();\n }\n\n if ($data && !$data.isActive) {\n $data.activate();\n }\n\n this._activationHandlers.forEach((handler) => {\n const result = handler();\n if (result) {\n this._deactivationHandlers.push(result);\n }\n });\n }\n\n /**\n * Called by the SceneComponentWrapper when the react component is unmounted.\n * Don't override this, instead use addActivationHandler. The activation handler can return a deactivation handler.\n */\n public deactivate(): void {\n this._isActive = false;\n\n const { $data, $variables, $timeRange } = this.state;\n\n if ($timeRange && $timeRange.isActive) {\n $timeRange.deactivate();\n }\n\n if ($data && $data.isActive) {\n $data.deactivate();\n }\n\n if ($variables && $variables.isActive) {\n $variables.deactivate();\n }\n\n this._deactivationHandlers.forEach((handler) => handler());\n this._deactivationHandlers = [];\n\n // Clear subscriptions and listeners\n this._events.removeAllListeners();\n this._subs.unsubscribe();\n this._subs = new Subscription();\n }\n\n /**\n * Utility hook to get and subscribe to state\n */\n public useState() {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useSceneObjectState(this);\n }\n\n /** Force a re-render, should only be needed when variable values change */\n public forceRender(): void {\n this.setState({});\n }\n\n /**\n * Will create new SceneObject with shallow-cloned state, but all state items of type SceneObject are deep cloned\n */\n public clone(withState?: Partial<TState>): this {\n return cloneSceneObject(this, withState);\n }\n\n /**\n * Allows external code to register code that is executed on activate and deactivate. This allow you\n * to wire up scene objects that need to respond to state changes in other objects from the outside.\n **/\n public addActivationHandler(handler: SceneActivationHandler) {\n this._activationHandlers.push(handler);\n }\n}\n\n/**\n * This hook is always returning model.state instead of a useState that remembers the last state emitted on the subject\n * The reason for this is so that if the model instance change this function will always return the latest state.\n */\nfunction useSceneObjectState<TState extends SceneObjectState>(model: SceneObjectBase<TState>): TState {\n const forceUpdate = useForceUpdate();\n\n useEffect(() => {\n const s = model.subscribeToState(forceUpdate);\n return () => s.unsubscribe();\n }, [model, forceUpdate]);\n\n return model.state;\n}\n"],"names":["uuidv4"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../../src/core/types.ts"],"sourcesContent":["import React from 'react';\nimport { MonoTypeOperatorFunction, Observer, SubscriptionLike, Unsubscribable } from 'rxjs';\n\nimport {\n BusEvent,\n BusEventHandler,\n BusEventType,\n DataFrame,\n DataTransformContext,\n PanelData,\n TimeRange,\n TimeZone,\n} from '@grafana/data';\n\nimport { SceneVariableDependencyConfigLike, SceneVariables } from '../variables/types';\n\nexport interface SceneObjectStatePlain {\n key?: string;\n $timeRange?: SceneTimeRangeLike;\n $data?: SceneDataProvider;\n $editor?: SceneEditor;\n $variables?: SceneVariables;\n}\n\nexport interface SceneLayoutChildState extends SceneObjectStatePlain {\n placement?: SceneLayoutChildOptions;\n}\n\nexport type SceneObjectState = SceneObjectStatePlain | SceneLayoutState | SceneLayoutChildState;\n\nexport interface SceneLayoutChildOptions {\n width?: number | string;\n height?: number | string;\n xSizing?: 'fill' | 'content';\n ySizing?: 'fill' | 'content';\n x?: number;\n y?: number;\n minWidth?: number | string;\n minHeight?: number | string;\n isDraggable?: boolean;\n isResizable?: boolean;\n}\n\nexport interface SceneComponentProps<T> {\n model: T;\n isEditing?: boolean;\n}\n\nexport type SceneComponent<TModel> = React.FunctionComponent<SceneComponentProps<TModel>>;\n\nexport interface SceneDataState extends SceneObjectStatePlain {\n data?: PanelData;\n}\n\nexport interface SceneObject<TState extends SceneObjectState = SceneObjectState> {\n /** The current state */\n readonly state: TState;\n\n /** True when there is a React component mounted for this Object */\n readonly isActive: boolean;\n\n /** SceneObject parent */\n readonly parent?: SceneObject;\n\n /** This abtractions declares what variables the scene object depends on and how to handle when they change value. **/\n readonly variableDependency?: SceneVariableDependencyConfigLike;\n\n /** This abstraction declares URL sync dependencies of a scene object. **/\n readonly urlSync?: SceneObjectUrlSyncHandler<TState>;\n\n /** Subscribe to state changes */\n subscribeToState(observer?: Partial<Observer<TState>>): SubscriptionLike;\n\n /** Subscribe to a scene event */\n subscribeToEvent<T extends BusEvent>(typeFilter: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable;\n\n /** Publish an event and optionally bubble it up the scene */\n publishEvent(event: BusEvent, bubble?: boolean): void;\n\n /** Utility hook that wraps useObservable. Used by React components to subscribes to state changes */\n useState(): TState;\n\n /** How to modify state */\n setState(state: Partial<TState>): void;\n\n /** Called when the Component is mounted. A place to register event listeners add subscribe to state changes */\n activate(): void;\n\n /** Called when component unmounts. Unsubscribe and closes all subscriptions */\n deactivate(): void;\n\n /** Get the scene root */\n getRoot(): SceneObject;\n\n /** Returns a deep clone this object and all its children */\n clone(state?: Partial<TState>): this;\n\n /** A React component to use for rendering the object */\n Component(props: SceneComponentProps<SceneObject<TState>>): React.ReactElement | null;\n\n /** To be replaced by declarative method */\n Editor(props: SceneComponentProps<SceneObject<TState>>): React.ReactElement | null;\n\n /** Force a re-render, should only be needed when variable values change */\n forceRender(): void;\n}\n\nexport type SceneLayoutChild = SceneObject<SceneLayoutChildState | SceneLayoutState>;\n\nexport interface SceneLayoutState extends SceneLayoutChildState {\n children: SceneLayoutChild[];\n}\n\nexport interface SceneLayout<T extends SceneLayoutState = SceneLayoutState> extends SceneObject<T> {\n isDraggable(): boolean;\n getDragClass?(): string;\n getDragClassCancel?(): string;\n}\n\nexport interface SceneEditorState extends SceneObjectStatePlain {\n hoverObject?: SceneObjectRef;\n selectedObject?: SceneObjectRef;\n}\n\nexport interface SceneEditor extends SceneObject<SceneEditorState> {\n onMouseEnterObject(model: SceneObject): void;\n onMouseLeaveObject(model: SceneObject): void;\n onSelectObject(model: SceneObject): void;\n getEditComponentWrapper(): React.ComponentType<SceneComponentEditWrapperProps>;\n}\n\ninterface SceneComponentEditWrapperProps {\n editor: SceneEditor;\n model: SceneObject;\n children: React.ReactNode;\n}\n\nexport interface SceneTimeRangeState extends SceneObjectStatePlain {\n from: string;\n to: string;\n timeZone: TimeZone;\n fiscalYearStartMonth?: number;\n value: TimeRange;\n}\n\nexport interface SceneTimeRangeLike extends SceneObject<SceneTimeRangeState> {\n onTimeRangeChange(timeRange: TimeRange): void;\n onRefresh(): void;\n}\n\nexport interface SceneObjectRef {\n ref: SceneObject;\n}\n\nexport function isSceneObject(obj: any): obj is SceneObject {\n return obj.useState !== undefined;\n}\n\nexport interface SceneObjectWithUrlSync<TState> extends SceneObject {\n getUrlState(state: TState): SceneObjectUrlValues;\n updateFromUrl(values: SceneObjectUrlValues): void;\n}\n\nexport interface SceneObjectUrlSyncHandler<TState> {\n getKeys(): string[];\n getUrlState(state: TState): SceneObjectUrlValues;\n updateFromUrl(values: SceneObjectUrlValues): void;\n}\n\nexport type SceneObjectUrlValue = string | string[] | undefined | null;\nexport type SceneObjectUrlValues = Record<string, SceneObjectUrlValue>;\n\nexport type CustomTransformOperator = (context: DataTransformContext) => MonoTypeOperatorFunction<DataFrame[]>;\n\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];\n};\n\nexport interface SceneDataProvider extends SceneObject<SceneDataState> {\n setContainerWidth?: (width: number) => void;\n}\n"],"names":[],"mappings":"AA0JO,SAAS,cAAc,GAA8B,EAAA;AAC1D,EAAA,OAAO,IAAI,QAAa,KAAA,KAAA,CAAA,CAAA;AAC1B;;;;"}
1
+ {"version":3,"file":"types.js","sources":["../../../src/core/types.ts"],"sourcesContent":["import React from 'react';\nimport { MonoTypeOperatorFunction, Unsubscribable } from 'rxjs';\n\nimport {\n BusEvent,\n BusEventHandler,\n BusEventType,\n DataFrame,\n DataTransformContext,\n PanelData,\n TimeRange,\n TimeZone,\n} from '@grafana/data';\n\nimport { SceneVariableDependencyConfigLike, SceneVariables } from '../variables/types';\n\nexport interface SceneObjectStatePlain {\n key?: string;\n $timeRange?: SceneTimeRangeLike;\n $data?: SceneDataProvider;\n $editor?: SceneEditor;\n $variables?: SceneVariables;\n}\n\nexport interface SceneLayoutChildState extends SceneObjectStatePlain {\n placement?: SceneLayoutChildOptions;\n}\n\nexport type SceneObjectState = SceneObjectStatePlain | SceneLayoutState | SceneLayoutChildState;\n\nexport interface SceneLayoutChildOptions {\n width?: number | string;\n height?: number | string;\n xSizing?: 'fill' | 'content';\n ySizing?: 'fill' | 'content';\n x?: number;\n y?: number;\n minWidth?: number | string;\n minHeight?: number | string;\n isDraggable?: boolean;\n isResizable?: boolean;\n}\n\nexport interface SceneComponentProps<T> {\n model: T;\n isEditing?: boolean;\n}\n\nexport type SceneComponent<TModel> = React.FunctionComponent<SceneComponentProps<TModel>>;\n\nexport interface SceneDataState extends SceneObjectStatePlain {\n data?: PanelData;\n}\n\nexport interface SceneObject<TState extends SceneObjectState = SceneObjectState> {\n /** The current state */\n readonly state: TState;\n\n /** True when there is a React component mounted for this Object */\n readonly isActive: boolean;\n\n /** SceneObject parent */\n readonly parent?: SceneObject;\n\n /** This abtractions declares what variables the scene object depends on and how to handle when they change value. **/\n readonly variableDependency?: SceneVariableDependencyConfigLike;\n\n /** This abstraction declares URL sync dependencies of a scene object. **/\n readonly urlSync?: SceneObjectUrlSyncHandler<TState>;\n\n /** Subscribe to state changes */\n subscribeToState(handler: SceneStateChangedHandler<TState>): Unsubscribable;\n\n /** Subscribe to a scene event */\n subscribeToEvent<T extends BusEvent>(typeFilter: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable;\n\n /** Publish an event and optionally bubble it up the scene */\n publishEvent(event: BusEvent, bubble?: boolean): void;\n\n /** Utility hook that wraps useObservable. Used by React components to subscribes to state changes */\n useState(): TState;\n\n /** How to modify state */\n setState(state: Partial<TState>): void;\n\n /**\n * Called when the Component is mounted. This will also activate any $data, $variables or $timeRange scene object on this level.\n * Don't override this in your custom SceneObjects, instead use addActivationHandler from the constructor. The activation handler can return a deactivation handler.\n **/\n activate(): void;\n\n /** Called when component unmounts. This will also deactivate any $data, $variables or $timeRange scene object on this level.\n * Don't override this in your custom SceneObjects, instead use addActivationHandler from the constructor. The activation handler can return a deactivation handler.\n */\n deactivate(): void;\n\n /** Get the scene root */\n getRoot(): SceneObject;\n\n /** Returns a deep clone this object and all its children */\n clone(state?: Partial<TState>): this;\n\n /** A React component to use for rendering the object */\n Component(props: SceneComponentProps<SceneObject<TState>>): React.ReactElement | null;\n\n /** To be replaced by declarative method */\n Editor(props: SceneComponentProps<SceneObject<TState>>): React.ReactElement | null;\n\n /** Force a re-render, should only be needed when variable values change */\n forceRender(): void;\n\n /**\n * Allows external code to register code that is executed on activate and deactivate. This allow you\n * to wire up scene objects that need to respond to state changes in other objects from the outside.\n **/\n addActivationHandler(handler: SceneActivationHandler): void;\n}\n\nexport type SceneActivationHandler = () => SceneDeactivationHandler | void;\nexport type SceneDeactivationHandler = () => void;\n\nexport type SceneLayoutChild = SceneObject<SceneLayoutChildState | SceneLayoutState>;\n\nexport interface SceneLayoutState extends SceneLayoutChildState {\n children: SceneLayoutChild[];\n}\n\nexport interface SceneLayout<T extends SceneLayoutState = SceneLayoutState> extends SceneObject<T> {\n isDraggable(): boolean;\n getDragClass?(): string;\n getDragClassCancel?(): string;\n}\n\nexport interface SceneEditorState extends SceneObjectStatePlain {\n hoverObject?: SceneObjectRef;\n selectedObject?: SceneObjectRef;\n}\n\nexport interface SceneEditor extends SceneObject<SceneEditorState> {\n onMouseEnterObject(model: SceneObject): void;\n onMouseLeaveObject(model: SceneObject): void;\n onSelectObject(model: SceneObject): void;\n getEditComponentWrapper(): React.ComponentType<SceneComponentEditWrapperProps>;\n}\n\ninterface SceneComponentEditWrapperProps {\n editor: SceneEditor;\n model: SceneObject;\n children: React.ReactNode;\n}\n\nexport interface SceneTimeRangeState extends SceneObjectStatePlain {\n from: string;\n to: string;\n timeZone: TimeZone;\n fiscalYearStartMonth?: number;\n value: TimeRange;\n}\n\nexport interface SceneTimeRangeLike extends SceneObject<SceneTimeRangeState> {\n onTimeRangeChange(timeRange: TimeRange): void;\n onRefresh(): void;\n}\n\nexport interface SceneObjectRef {\n ref: SceneObject;\n}\n\nexport function isSceneObject(obj: any): obj is SceneObject {\n return obj.useState !== undefined;\n}\n\nexport interface SceneObjectWithUrlSync<TState> extends SceneObject {\n getUrlState(state: TState): SceneObjectUrlValues;\n updateFromUrl(values: SceneObjectUrlValues): void;\n}\n\nexport interface SceneObjectUrlSyncHandler<TState> {\n getKeys(): string[];\n getUrlState(state: TState): SceneObjectUrlValues;\n updateFromUrl(values: SceneObjectUrlValues): void;\n}\n\nexport type SceneObjectUrlValue = string | string[] | undefined | null;\nexport type SceneObjectUrlValues = Record<string, SceneObjectUrlValue>;\n\nexport type CustomTransformOperator = (context: DataTransformContext) => MonoTypeOperatorFunction<DataFrame[]>;\nexport type SceneStateChangedHandler<TState> = (newState: TState, prevState: TState) => void;\n\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];\n};\n\nexport interface SceneDataProvider extends SceneObject<SceneDataState> {\n setContainerWidth?: (width: number) => void;\n}\n"],"names":[],"mappings":"AAwKO,SAAS,cAAc,GAA8B,EAAA;AAC1D,EAAA,OAAO,IAAI,QAAa,KAAA,KAAA,CAAA,CAAA;AAC1B;;;;"}
package/dist/esm/index.js CHANGED
@@ -22,6 +22,7 @@ export { UrlSyncManager } from './services/UrlSyncManager.js';
22
22
  export { SceneObjectUrlSyncConfig } from './services/SceneObjectUrlSyncConfig.js';
23
23
  export { EmbeddedScene } from './components/EmbeddedScene.js';
24
24
  export { VizPanel } from './components/VizPanel/VizPanel.js';
25
+ export { VizPanelMenu } from './components/VizPanel/VizPanelMenu.js';
25
26
  export { NestedScene } from './components/NestedScene.js';
26
27
  export { SceneCanvasText } from './components/SceneCanvasText.js';
27
28
  export { SceneToolbarButton, SceneToolbarInput } from './components/SceneToolbarButton.js';
@@ -32,5 +33,7 @@ export { SceneControlsSpacer } from './components/SceneControlsSpacer.js';
32
33
  export { SceneFlexLayout } from './components/layout/SceneFlexLayout.js';
33
34
  export { SceneGridLayout } from './components/layout/SceneGridLayout.js';
34
35
  export { SceneGridRow } from './components/layout/SceneGridRow.js';
35
- export { SceneApp, SceneAppPage } from './components/SceneApp/SceneApp.js';
36
+ export { SceneApp } from './components/SceneApp/SceneApp.js';
37
+ export { SceneAppPage } from './components/SceneApp/SceneAppPage.js';
38
+ export { SceneReactObject } from './components/SceneReactObject.js';
36
39
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -24,8 +24,8 @@ var __spreadValues = (a, b) => {
24
24
  };
25
25
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
26
26
  class SceneDataTransformer extends SceneObjectBase {
27
- constructor() {
28
- super(...arguments);
27
+ constructor(state) {
28
+ super(state);
29
29
  this._variableDependency = new VariableDependencyConfig(
30
30
  this,
31
31
  {
@@ -33,18 +33,19 @@ class SceneDataTransformer extends SceneObjectBase {
33
33
  onReferencedVariableValueChanged: () => this.reprocessTransformations()
34
34
  }
35
35
  );
36
+ this.addActivationHandler(() => this.activationHandler());
36
37
  }
37
- activate() {
38
- super.activate();
38
+ activationHandler() {
39
39
  const sourceData = this.getSourceData();
40
- this._subs.add(
41
- sourceData.subscribeToState({
42
- next: (state) => this.transform(state.data)
43
- })
44
- );
40
+ this._subs.add(sourceData.subscribeToState((state) => this.transform(state.data)));
45
41
  if (sourceData.state.data) {
46
42
  this.transform(sourceData.state.data);
47
43
  }
44
+ return () => {
45
+ if (this._transformSub) {
46
+ this._transformSub.unsubscribe();
47
+ }
48
+ };
48
49
  }
49
50
  getSourceData() {
50
51
  if (this.state.$data) {
@@ -1 +1 @@
1
- {"version":3,"file":"SceneDataTransformer.js","sources":["../../../src/querying/SceneDataTransformer.ts"],"sourcesContent":["import { DataTransformerConfig, PanelData, transformDataFrame } from '@grafana/data';\nimport { map, Unsubscribable } from 'rxjs';\nimport { SceneDataNodeState } from '../core/SceneDataNode';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { CustomTransformOperator, SceneDataProvider } from '../core/types';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\n\nexport interface SceneDataTransformerState extends SceneDataNodeState {\n /**\n * Array of standard transformation configs and custom transform operators\n */\n transformations: Array<DataTransformerConfig | CustomTransformOperator>;\n}\n\n/**\n * You can use this as a $data object. It can either transform an inner $data DataProvider or if that is not set it will\n * subscribe to a DataProvider higher up in the scene graph and transform its data.\n *\n * The transformations array supports custom (runtime defined) transformation as well as declarative core transformations.\n * You can manually re-process the transformations by calling reprocessTransformations(). This is useful if you have\n * transformations that depend on other scene object states.\n */\nexport class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerState> implements SceneDataProvider {\n protected _variableDependency: VariableDependencyConfig<SceneDataTransformerState> = new VariableDependencyConfig(\n this,\n {\n statePaths: ['transformations'],\n onReferencedVariableValueChanged: () => this.reprocessTransformations(),\n }\n );\n\n private _transformSub?: Unsubscribable;\n\n public activate(): void {\n super.activate();\n\n const sourceData = this.getSourceData();\n\n this._subs.add(\n sourceData.subscribeToState({\n next: (state) => this.transform(state.data),\n })\n );\n\n if (sourceData.state.data) {\n this.transform(sourceData.state.data);\n }\n }\n\n private getSourceData(): SceneDataProvider {\n if (this.state.$data) {\n return this.state.$data;\n }\n\n if (!this.parent || !this.parent.parent) {\n throw new Error('SceneDataTransformer must either have $data set on it or have a parent.parent with $data');\n }\n\n return sceneGraph.getData(this.parent.parent);\n }\n\n public setContainerWidth(width: number) {\n if (this.state.$data && this.state.$data.setContainerWidth) {\n this.state.$data.setContainerWidth(width);\n }\n }\n\n public reprocessTransformations() {\n this.transform(this.getSourceData().state.data);\n }\n\n private transform(data: PanelData | undefined) {\n const transformations = this.state.transformations || [];\n\n if (transformations.length === 0 || !data) {\n this.setState({ data });\n return;\n }\n\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(this, value, data.request?.scopedVars);\n },\n };\n\n this._transformSub = transformDataFrame(transformations, data.series, ctx)\n .pipe(map((series) => ({ ...data, series })))\n .subscribe((data) => this.setState({ data }));\n }\n}\n"],"names":["data"],"mappings":"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"}
1
+ {"version":3,"file":"SceneDataTransformer.js","sources":["../../../src/querying/SceneDataTransformer.ts"],"sourcesContent":["import { DataTransformerConfig, PanelData, transformDataFrame } from '@grafana/data';\nimport { map, Unsubscribable } from 'rxjs';\nimport { SceneDataNodeState } from '../core/SceneDataNode';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { CustomTransformOperator, SceneDataProvider } from '../core/types';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\n\nexport interface SceneDataTransformerState extends SceneDataNodeState {\n /**\n * Array of standard transformation configs and custom transform operators\n */\n transformations: Array<DataTransformerConfig | CustomTransformOperator>;\n}\n\n/**\n * You can use this as a $data object. It can either transform an inner $data DataProvider or if that is not set it will\n * subscribe to a DataProvider higher up in the scene graph and transform its data.\n *\n * The transformations array supports custom (runtime defined) transformation as well as declarative core transformations.\n * You can manually re-process the transformations by calling reprocessTransformations(). This is useful if you have\n * transformations that depend on other scene object states.\n */\nexport class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerState> implements SceneDataProvider {\n private _transformSub?: Unsubscribable;\n\n /**\n * Scan transformations for variable usage and re-process transforms when a variable values change\n */\n protected _variableDependency: VariableDependencyConfig<SceneDataTransformerState> = new VariableDependencyConfig(\n this,\n {\n statePaths: ['transformations'],\n onReferencedVariableValueChanged: () => this.reprocessTransformations(),\n }\n );\n\n public constructor(state: SceneDataTransformerState) {\n super(state);\n\n this.addActivationHandler(() => this.activationHandler());\n }\n\n private activationHandler() {\n const sourceData = this.getSourceData();\n\n this._subs.add(sourceData.subscribeToState((state) => this.transform(state.data)));\n\n if (sourceData.state.data) {\n this.transform(sourceData.state.data);\n }\n\n return () => {\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n };\n }\n\n private getSourceData(): SceneDataProvider {\n if (this.state.$data) {\n return this.state.$data;\n }\n\n if (!this.parent || !this.parent.parent) {\n throw new Error('SceneDataTransformer must either have $data set on it or have a parent.parent with $data');\n }\n\n return sceneGraph.getData(this.parent.parent);\n }\n\n public setContainerWidth(width: number) {\n if (this.state.$data && this.state.$data.setContainerWidth) {\n this.state.$data.setContainerWidth(width);\n }\n }\n\n public reprocessTransformations() {\n this.transform(this.getSourceData().state.data);\n }\n\n private transform(data: PanelData | undefined) {\n const transformations = this.state.transformations || [];\n\n if (transformations.length === 0 || !data) {\n this.setState({ data });\n return;\n }\n\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(this, value, data.request?.scopedVars);\n },\n };\n\n this._transformSub = transformDataFrame(transformations, data.series, ctx)\n .pipe(map((series) => ({ ...data, series })))\n .subscribe((data) => this.setState({ data }));\n }\n}\n"],"names":["data"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { cloneDeep } from 'lodash';
2
2
  import 'rxjs';
3
+ import { LoadingState } from '@grafana/schema';
3
4
  import { preProcessPanelData, CoreApp, rangeUtil } from '@grafana/data';
4
5
  import { getRunRequest } from '@grafana/runtime';
5
6
  import { SceneObjectBase } from '../core/SceneObjectBase.js';
@@ -11,34 +12,32 @@ import { VariableValueRecorder } from '../variables/VariableValueRecorder.js';
11
12
 
12
13
  let counter = 100;
13
14
  function getNextRequestId() {
14
- return "QS" + counter++;
15
+ return "SQR" + counter++;
15
16
  }
16
17
  class SceneQueryRunner extends SceneObjectBase {
17
- constructor() {
18
- super(...arguments);
18
+ constructor(initialState) {
19
+ super(initialState);
19
20
  this._variableValueRecorder = new VariableValueRecorder();
20
21
  this._variableDependency = new VariableDependencyConfig(this, {
21
22
  statePaths: ["queries", "datasource"],
22
23
  onVariableUpdatesCompleted: (variables, dependencyChanged) => this.onVariableUpdatesCompleted(variables, dependencyChanged)
23
24
  });
25
+ this._onActivate = () => {
26
+ const timeRange = sceneGraph.getTimeRange(this);
27
+ this._subs.add(
28
+ timeRange.subscribeToState((timeRange2) => {
29
+ this.runWithTimeRange(timeRange2.value);
30
+ })
31
+ );
32
+ if (this.shouldRunQueriesOnActivate()) {
33
+ this.runQueries();
34
+ }
35
+ };
24
36
  this.onDataReceived = (data) => {
25
37
  const preProcessedData = preProcessPanelData(data, this.state.data);
26
38
  this.setState({ data: preProcessedData });
27
39
  };
28
- }
29
- activate() {
30
- super.activate();
31
- const timeRange = sceneGraph.getTimeRange(this);
32
- this._subs.add(
33
- timeRange.subscribeToState({
34
- next: (timeRange2) => {
35
- this.runWithTimeRange(timeRange2.value);
36
- }
37
- })
38
- );
39
- if (this.shouldRunQueriesOnActivate()) {
40
- this.runQueries();
41
- }
40
+ this.addActivationHandler(this._onActivate);
42
41
  }
43
42
  onVariableUpdatesCompleted(_variablesThatHaveChanged, dependencyChanged) {
44
43
  if (this.state.isWaitingForVariables && this.shouldRunQueriesOnActivate()) {
@@ -98,6 +97,7 @@ class SceneQueryRunner extends SceneObjectBase {
98
97
  return (_b = (_a = this.state.maxDataPoints) != null ? _a : this._containerWidth) != null ? _b : 500;
99
98
  }
100
99
  async runWithTimeRange(timeRange) {
100
+ var _a;
101
101
  if (sceneGraph.hasVariableDependencyInLoadingState(this)) {
102
102
  writeSceneLog("SceneQueryRunner", "Variable dependency is in loading state, skipping query execution");
103
103
  this.setState({ isWaitingForVariables: true });
@@ -106,10 +106,17 @@ class SceneQueryRunner extends SceneObjectBase {
106
106
  if (this.state.isWaitingForVariables) {
107
107
  this.setState({ isWaitingForVariables: false });
108
108
  }
109
- const { datasource, minInterval, queries } = this.state;
109
+ const { minInterval, queries } = this.state;
110
110
  const sceneObjectScopedVar = {
111
111
  __sceneObject: { text: "__sceneObject", value: this }
112
112
  };
113
+ if (!(queries == null ? void 0 : queries.length)) {
114
+ this.onDataReceived({
115
+ state: LoadingState.Done,
116
+ series: [],
117
+ timeRange
118
+ });
119
+ }
113
120
  const request = {
114
121
  app: CoreApp.Dashboard,
115
122
  requestId: getNextRequestId(),
@@ -125,6 +132,7 @@ class SceneQueryRunner extends SceneObjectBase {
125
132
  startTime: Date.now()
126
133
  };
127
134
  try {
135
+ const datasource = (_a = this.state.datasource) != null ? _a : findFirstDatasource(request.targets);
128
136
  const ds = await getDataSource(datasource, request.scopedVars);
129
137
  request.targets = request.targets.map((query) => {
130
138
  if (!query.datasource) {
@@ -148,6 +156,14 @@ class SceneQueryRunner extends SceneObjectBase {
148
156
  }
149
157
  }
150
158
  }
159
+ function findFirstDatasource(targets) {
160
+ for (const t of targets) {
161
+ if (t.datasource != null) {
162
+ return t.datasource;
163
+ }
164
+ }
165
+ return void 0;
166
+ }
151
167
 
152
168
  export { SceneQueryRunner, getNextRequestId };
153
169
  //# sourceMappingURL=SceneQueryRunner.js.map