@grafana/scenes 6.20.3--canary.1151.15712722900.0 → 6.21.0--canary.1146.15674574987.0
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 +0 -41
- package/dist/esm/behaviors/SceneRenderProfiler.js.map +1 -1
- package/dist/esm/components/NestedScene.js +2 -3
- package/dist/esm/components/NestedScene.js.map +1 -1
- package/dist/esm/components/SceneApp/SceneAppPage.js +3 -4
- package/dist/esm/components/SceneApp/SceneAppPage.js.map +1 -1
- package/dist/esm/components/SceneCanvasText.js +2 -3
- package/dist/esm/components/SceneCanvasText.js.map +1 -1
- package/dist/esm/components/SceneDebugger/SceneDebugger.js +1 -10
- package/dist/esm/components/SceneDebugger/SceneDebugger.js.map +1 -1
- package/dist/esm/components/SceneRefreshPicker.js.map +1 -1
- package/dist/esm/components/SceneTimeRangeCompare.js +2 -6
- package/dist/esm/components/SceneTimeRangeCompare.js.map +1 -1
- package/dist/esm/components/VizPanel/VizPanel.js +1 -2
- package/dist/esm/components/VizPanel/VizPanel.js.map +1 -1
- package/dist/esm/components/VizPanel/VizPanelExploreButton.js +1 -2
- package/dist/esm/components/VizPanel/VizPanelExploreButton.js.map +1 -1
- package/dist/esm/components/VizPanel/VizPanelRenderer.js +2 -3
- package/dist/esm/components/VizPanel/VizPanelRenderer.js.map +1 -1
- package/dist/esm/components/VizPanel/VizPanelSeriesLimit.js +2 -19
- package/dist/esm/components/VizPanel/VizPanelSeriesLimit.js.map +1 -1
- package/dist/esm/components/layout/grid/SceneGridRow.js +1 -2
- package/dist/esm/components/layout/grid/SceneGridRow.js.map +1 -1
- package/dist/esm/components/layout/split/Splitter.js +1 -2
- package/dist/esm/components/layout/split/Splitter.js.map +1 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/ControlsLabel.js +1 -11
- package/dist/esm/utils/ControlsLabel.js.map +1 -1
- package/dist/esm/utils/LoadingIndicator.js +1 -2
- package/dist/esm/utils/LoadingIndicator.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFilterBuilder.js +2 -3
- package/dist/esm/variables/adhoc/AdHocFilterBuilder.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js +5 -20
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFilterPill.js +3 -25
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFilterPill.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js +2 -11
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/DropdownItem.js +4 -5
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/DropdownItem.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/MultiValuePill.js +1 -8
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/MultiValuePill.js.map +1 -1
- package/dist/esm/variables/adhoc/getAdHocFiltersFromScopes.js +1 -3
- package/dist/esm/variables/adhoc/getAdHocFiltersFromScopes.js.map +1 -1
- package/dist/esm/variables/components/VariableValueInput.js +1 -2
- package/dist/esm/variables/components/VariableValueInput.js.map +1 -1
- package/dist/esm/variables/components/VariableValueSelect.js +1 -2
- package/dist/esm/variables/components/VariableValueSelect.js.map +1 -1
- package/dist/esm/variables/groupby/DefaultGroupByCustomIndicatorContainer.js +3 -10
- package/dist/esm/variables/groupby/DefaultGroupByCustomIndicatorContainer.js.map +1 -1
- package/dist/esm/variables/groupby/GroupByVariable.js +4 -17
- package/dist/esm/variables/groupby/GroupByVariable.js.map +1 -1
- package/dist/esm/variables/interpolation/formatRegistry.js +12 -49
- package/dist/esm/variables/interpolation/formatRegistry.js.map +1 -1
- package/dist/esm/variables/variants/DataSourceVariable.js +1 -5
- package/dist/esm/variables/variants/DataSourceVariable.js.map +1 -1
- package/dist/esm/variables/variants/IntervalVariable.js +1 -2
- package/dist/esm/variables/variants/IntervalVariable.js.map +1 -1
- package/dist/esm/variables/variants/TestVariable.js +1 -2
- package/dist/esm/variables/variants/TestVariable.js.map +1 -1
- package/dist/index.d.ts +2 -9
- package/dist/index.js +62 -228
- package/dist/index.js.map +1 -1
- package/package.json +13 -22
- package/dist/esm/locales/en-US/grafana-scenes.json.js +0 -151
- package/dist/esm/locales/en-US/grafana-scenes.json.js.map +0 -1
- package/dist/esm/utils/loadResources.js +0 -23
- package/dist/esm/utils/loadResources.js.map +0 -1
- package/dist/grafana-scenes-DCHONTnD.js +0 -153
- package/dist/grafana-scenes-DCHONTnD.js.map +0 -1
package/CHANGELOG.md
CHANGED
@@ -1,44 +1,3 @@
|
|
1
|
-
# v6.20.2 (Mon Jun 16 2025)
|
2
|
-
|
3
|
-
#### 🐛 Bug Fix
|
4
|
-
|
5
|
-
- AdHocFiltersVariable: Fix scopes crashing when scope filters are undefined [#1153](https://github.com/grafana/scenes/pull/1153) ([@mdvictor](https://github.com/mdvictor))
|
6
|
-
|
7
|
-
#### Authors: 1
|
8
|
-
|
9
|
-
- Victor Marin ([@mdvictor](https://github.com/mdvictor))
|
10
|
-
|
11
|
-
---
|
12
|
-
|
13
|
-
# v6.20.1 (Mon Jun 16 2025)
|
14
|
-
|
15
|
-
#### 🐛 Bug Fix
|
16
|
-
|
17
|
-
- GroupBy: Fix edge cases on default values on dashboard load [#1146](https://github.com/grafana/scenes/pull/1146) ([@mdvictor](https://github.com/mdvictor))
|
18
|
-
|
19
|
-
#### Authors: 1
|
20
|
-
|
21
|
-
- Victor Marin ([@mdvictor](https://github.com/mdvictor))
|
22
|
-
|
23
|
-
---
|
24
|
-
|
25
|
-
# v6.20.0 (Mon Jun 16 2025)
|
26
|
-
|
27
|
-
#### 🚀 Enhancement
|
28
|
-
|
29
|
-
- AdHocVariable: Refactor origin filters [#1132](https://github.com/grafana/scenes/pull/1132) ([@mdvictor](https://github.com/mdvictor))
|
30
|
-
|
31
|
-
#### 🐛 Bug Fix
|
32
|
-
|
33
|
-
- VariableDependencyConfig: Simplify bits and pieces [#1145](https://github.com/grafana/scenes/pull/1145) ([@kaydelaney](https://github.com/kaydelaney))
|
34
|
-
|
35
|
-
#### Authors: 2
|
36
|
-
|
37
|
-
- kay delaney ([@kaydelaney](https://github.com/kaydelaney))
|
38
|
-
- Victor Marin ([@mdvictor](https://github.com/mdvictor))
|
39
|
-
|
40
|
-
---
|
41
|
-
|
42
1
|
# v6.19.0 (Thu Jun 12 2025)
|
43
2
|
|
44
3
|
#### 🚀 Enhancement
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writeSceneLog } from '../utils/writeSceneLog';\nimport { SceneQueryControllerLike } from './types';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst SPAN_THRESHOLD = 30; // Frames longer than this will be considered slow\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n // Profile origin, i.e. scene refresh picker\n origin: string;\n crumbs: string[];\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Will keep measured lengths trailing frames\n #recordedTrailingSpans: number[] = [];\n\n lastFrameTime = 0;\n\n public constructor(private queryController: SceneQueryControllerLike) {}\n\n public startProfile(name: string) {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n\n writeSceneLog(this.constructor.name, 'New profile: Stopped recording frames');\n }\n\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n writeSceneLog(this.constructor.name, 'Profile started:', this.#profileInProgress, this.#profileStartTs);\n }\n\n private recordProfileTail(measurementStartTime: number, profileStartTs: number) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTime, measurementStartTime, profileStartTs)\n );\n }\n\n private measureTrailingFrames = (measurementStartTs: number, lastFrameTime: number, profileStartTs: number) => {\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - lastFrameTime;\n this.#recordedTrailingSpans.push(frameLength);\n\n if (currentFrameTime - measurementStartTs! < POST_STORM_WINDOW) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTs, currentFrameTime, profileStartTs)\n );\n } else {\n const slowFrames = processRecordedSpans(this.#recordedTrailingSpans);\n const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);\n\n writeSceneLog(\n this.constructor.name,\n 'Profile tail recorded, slow frames duration:',\n slowFramesTime,\n slowFrames,\n this.#profileInProgress\n );\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n writeSceneLog(\n this.constructor.name,\n 'Stoped recording, total measured time (network included):',\n profileDuration + slowFramesTime\n );\n this.#trailAnimationFrameId = null;\n\n // performance.measure('DashboardInteraction tail', {\n // start: measurementStartTs,\n // end: measurementStartTs + n,\n // });\n\n const profileEndTs = profileStartTs + profileDuration + slowFramesTime;\n\n performance.measure('DashboardInteraction', {\n start: profileStartTs,\n end: profileEndTs,\n });\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.queryController.state.onProfileComplete) {\n this.queryController.state.onProfileComplete({\n origin: this.#profileInProgress!.origin,\n crumbs: this.#profileInProgress!.crumbs,\n duration: profileDuration + slowFramesTime,\n networkDuration,\n // @ts-ignore\n jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,\n // @ts-ignore\n usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,\n // @ts-ignore\n totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0,\n });\n }\n // @ts-ignore\n if (window.__runs) {\n // @ts-ignore\n window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n } else {\n // @ts-ignore\n window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n }\n }\n };\n\n public tryCompletingProfile() {\n writeSceneLog(this.constructor.name, 'Trying to complete profile', this.#profileInProgress);\n\n if (this.queryController.runningQueriesCount() === 0 && this.#profileInProgress) {\n writeSceneLog(this.constructor.name, 'All queries completed, stopping profile');\n this.recordProfileTail(performance.now(), this.#profileStartTs!);\n }\n }\n\n public isTailRecording() {\n return Boolean(this.#trailAnimationFrameId);\n }\n public cancelTailRecording() {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n writeSceneLog(this.constructor.name, 'Cancelled recording frames, new profile started');\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n this.#profileInProgress.crumbs.push(crumb);\n }\n }\n}\n\nexport function processRecordedSpans(spans: number[]) {\n // identify last span in spans that's bigger than SPAN_THRESHOLD\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > SPAN_THRESHOLD) {\n return spans.slice(0, i + 1);\n }\n }\n return [spans[0]];\n}\n\nfunction captureNetwork(startTs: number, endTs: number) {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n performance.clearResourceTimings();\n const networkEntries = entries.filter((entry) => entry.startTime >= startTs && entry.startTime <= endTs);\n for (const entry of networkEntries) {\n performance.measure('Network entry ' + entry.name, {\n start: entry.startTime,\n end: entry.responseEnd,\n });\n }\n\n return calculateNetworkTime(networkEntries);\n}\n\n// Will calculate total time spent on Network\nexport function calculateNetworkTime(requests: PerformanceResourceTiming[]): number {\n if (requests.length === 0) {\n return 0;\n }\n\n // Step 1: Sort the requests by startTs\n requests.sort((a, b) => a.startTime - b.startTime);\n\n // Step 2: Initialize variables\n let totalNetworkTime = 0;\n let currentStart = requests[0].startTime;\n let currentEnd = requests[0].responseEnd;\n\n // Step 3: Iterate through the sorted list and merge overlapping intervals\n for (let i = 1; i < requests.length; i++) {\n if (requests[i].startTime <= currentEnd) {\n // Overlapping intervals, merge them\n currentEnd = Math.max(currentEnd, requests[i].responseEnd);\n } else {\n // Non-overlapping interval, add the duration to total time\n totalNetworkTime += currentEnd - currentStart;\n\n // Update current interval\n currentStart = requests[i].startTime;\n currentEnd = requests[i].responseEnd;\n }\n }\n\n // Step 4: Add the last interval\n totalNetworkTime += currentEnd - currentStart;\n\n return totalNetworkTime;\n}\n"],"names":[],"mappings":"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"}
|
1
|
+
{"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writeSceneLog } from '../utils/writeSceneLog';\nimport { SceneQueryControllerLike } from './types';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst SPAN_THRESHOLD = 30; // Frames longer than this will be considered slow\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n // Profile origin, i.e. scene refresh picker\n origin: string;\n crumbs: string[];\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Will keep measured lengths trailing frames\n #recordedTrailingSpans: number[] = [];\n\n lastFrameTime: number = 0;\n\n public constructor(private queryController: SceneQueryControllerLike) {}\n\n public startProfile(name: string) {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n\n writeSceneLog(this.constructor.name, 'New profile: Stopped recording frames');\n }\n\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n writeSceneLog(this.constructor.name, 'Profile started:', this.#profileInProgress, this.#profileStartTs);\n }\n\n private recordProfileTail(measurementStartTime: number, profileStartTs: number) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTime, measurementStartTime, profileStartTs)\n );\n }\n\n private measureTrailingFrames = (measurementStartTs: number, lastFrameTime: number, profileStartTs: number) => {\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - lastFrameTime;\n this.#recordedTrailingSpans.push(frameLength);\n\n if (currentFrameTime - measurementStartTs! < POST_STORM_WINDOW) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTs, currentFrameTime, profileStartTs)\n );\n } else {\n const slowFrames = processRecordedSpans(this.#recordedTrailingSpans);\n const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);\n\n writeSceneLog(\n this.constructor.name,\n 'Profile tail recorded, slow frames duration:',\n slowFramesTime,\n slowFrames,\n this.#profileInProgress\n );\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n writeSceneLog(\n this.constructor.name,\n 'Stoped recording, total measured time (network included):',\n profileDuration + slowFramesTime\n );\n this.#trailAnimationFrameId = null;\n\n // performance.measure('DashboardInteraction tail', {\n // start: measurementStartTs,\n // end: measurementStartTs + n,\n // });\n\n const profileEndTs = profileStartTs + profileDuration + slowFramesTime;\n\n performance.measure('DashboardInteraction', {\n start: profileStartTs,\n end: profileEndTs,\n });\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.queryController.state.onProfileComplete) {\n this.queryController.state.onProfileComplete({\n origin: this.#profileInProgress!.origin,\n crumbs: this.#profileInProgress!.crumbs,\n duration: profileDuration + slowFramesTime,\n networkDuration,\n // @ts-ignore\n jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,\n // @ts-ignore\n usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,\n // @ts-ignore\n totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0,\n });\n }\n // @ts-ignore\n if (window.__runs) {\n // @ts-ignore\n window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n } else {\n // @ts-ignore\n window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n }\n }\n };\n\n public tryCompletingProfile() {\n writeSceneLog(this.constructor.name, 'Trying to complete profile', this.#profileInProgress);\n\n if (this.queryController.runningQueriesCount() === 0 && this.#profileInProgress) {\n writeSceneLog(this.constructor.name, 'All queries completed, stopping profile');\n this.recordProfileTail(performance.now(), this.#profileStartTs!);\n }\n }\n\n public isTailRecording() {\n return Boolean(this.#trailAnimationFrameId);\n }\n public cancelTailRecording() {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n writeSceneLog(this.constructor.name, 'Cancelled recording frames, new profile started');\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n this.#profileInProgress.crumbs.push(crumb);\n }\n }\n}\n\nexport function processRecordedSpans(spans: number[]) {\n // identify last span in spans that's bigger than SPAN_THRESHOLD\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > SPAN_THRESHOLD) {\n return spans.slice(0, i + 1);\n }\n }\n return [spans[0]];\n}\n\nfunction captureNetwork(startTs: number, endTs: number) {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n performance.clearResourceTimings();\n const networkEntries = entries.filter((entry) => entry.startTime >= startTs && entry.startTime <= endTs);\n for (const entry of networkEntries) {\n performance.measure('Network entry ' + entry.name, {\n start: entry.startTime,\n end: entry.responseEnd,\n });\n }\n\n return calculateNetworkTime(networkEntries);\n}\n\n// Will calculate total time spent on Network\nexport function calculateNetworkTime(requests: PerformanceResourceTiming[]): number {\n if (requests.length === 0) {\n return 0;\n }\n\n // Step 1: Sort the requests by startTs\n requests.sort((a, b) => a.startTime - b.startTime);\n\n // Step 2: Initialize variables\n let totalNetworkTime = 0;\n let currentStart = requests[0].startTime;\n let currentEnd = requests[0].responseEnd;\n\n // Step 3: Iterate through the sorted list and merge overlapping intervals\n for (let i = 1; i < requests.length; i++) {\n if (requests[i].startTime <= currentEnd) {\n // Overlapping intervals, merge them\n currentEnd = Math.max(currentEnd, requests[i].responseEnd);\n } else {\n // Non-overlapping interval, add the duration to total time\n totalNetworkTime += currentEnd - currentStart;\n\n // Update current interval\n currentStart = requests[i].startTime;\n currentEnd = requests[i].responseEnd;\n }\n }\n\n // Step 4: Add the last interval\n totalNetworkTime += currentEnd - currentStart;\n\n return totalNetworkTime;\n}\n"],"names":[],"mappings":"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"}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { t } from '@grafana/i18n';
|
2
1
|
import { css, cx } from '@emotion/css';
|
3
2
|
import React from 'react';
|
4
3
|
import { useStyles2, ToolbarButton, Icon } from '@grafana/ui';
|
@@ -40,7 +39,7 @@ function NestedSceneRenderer({ model }) {
|
|
40
39
|
variant: "default",
|
41
40
|
onClick: model.onRemove,
|
42
41
|
key: "remove-button",
|
43
|
-
"aria-label":
|
42
|
+
"aria-label": "Remove scene"
|
44
43
|
}
|
45
44
|
)
|
46
45
|
);
|
@@ -50,7 +49,7 @@ function NestedSceneRenderer({ model }) {
|
|
50
49
|
{
|
51
50
|
onClick: model.onToggle,
|
52
51
|
className: gridRow.rowTitleButton,
|
53
|
-
"aria-label": isCollapsed ?
|
52
|
+
"aria-label": isCollapsed ? "Expand scene" : "Collapse scene"
|
54
53
|
},
|
55
54
|
canCollapse && /* @__PURE__ */ React.createElement(Icon, { name: isCollapsed ? "angle-right" : "angle-down" }),
|
56
55
|
/* @__PURE__ */ React.createElement("span", { className: gridRow.rowTitle, role: "heading" }, sceneGraph.interpolate(model, title, void 0, "text"))
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"NestedScene.js","sources":["../../../src/components/NestedScene.tsx"],"sourcesContent":["import {
|
1
|
+
{"version":3,"file":"NestedScene.js","sources":["../../../src/components/NestedScene.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport React from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Icon, ToolbarButton, useStyles2 } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { SceneObject, SceneComponentProps, SceneLayout, SceneObjectState } from '../core/types';\nimport { getSceneGridRowStyles } from './layout/grid/SceneGridRow';\nimport { sceneGraph } from '../core/sceneGraph';\n\ninterface NestedSceneState extends SceneObjectState {\n title: string;\n isCollapsed?: boolean;\n canCollapse?: boolean;\n canRemove?: boolean;\n body: SceneLayout;\n controls?: SceneObject[];\n}\n\n/**\n * @internal\n * POC status, don't use this yet\n */\nexport class NestedScene extends SceneObjectBase<NestedSceneState> {\n public static Component = NestedSceneRenderer;\n\n public onToggle = () => {\n this.setState({\n isCollapsed: !this.state.isCollapsed,\n });\n };\n\n /** Removes itself from its parent's children array */\n public onRemove = () => {\n const parent = this.parent!;\n\n if (isSceneLayoutItem(parent)) {\n parent.setState({\n body: undefined,\n });\n }\n };\n}\n\nexport function NestedSceneRenderer({ model }: SceneComponentProps<NestedScene>) {\n const { title, isCollapsed, canCollapse, canRemove, body, controls } = model.useState();\n const gridRow = useStyles2(getSceneGridRowStyles);\n const styles = useStyles2(getStyles);\n\n const toolbarControls = (controls ?? []).map((action) => <action.Component key={action.state.key} model={action} />);\n\n if (canRemove) {\n toolbarControls.push(\n <ToolbarButton\n icon=\"times\"\n variant={'default'}\n onClick={model.onRemove}\n key=\"remove-button\"\n aria-label=\"Remove scene\"\n />\n );\n }\n\n return (\n <div className={styles.wrapper}>\n <div className={cx(styles.row, isCollapsed && styles.rowCollapsed)}>\n <button\n onClick={model.onToggle}\n className={gridRow.rowTitleButton}\n aria-label={isCollapsed ? 'Expand scene' : 'Collapse scene'}\n >\n {canCollapse && <Icon name={isCollapsed ? 'angle-right' : 'angle-down'} />}\n <span className={gridRow.rowTitle} role=\"heading\">\n {sceneGraph.interpolate(model, title, undefined, 'text')}\n </span>\n </button>\n <div className={styles.actions}>{toolbarControls}</div>\n </div>\n {!isCollapsed && <body.Component model={body} />}\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n wrapper: css({\n display: 'flex',\n flexDirection: 'column',\n flexGrow: 1,\n gap: theme.spacing(1),\n }),\n row: css({\n width: '100%',\n display: 'flex',\n justifyContent: 'space-between',\n gap: theme.spacing(1),\n }),\n rowCollapsed: css({\n borderBottom: `1px solid ${theme.colors.border.weak}`,\n paddingBottom: theme.spacing(1),\n }),\n actions: css({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n justifyContent: 'flex-end',\n flexGrow: 1,\n }),\n});\n\nfunction isSceneLayoutItem(x: SceneObject): x is SceneObject<SceneObjectState & { body: SceneObject | undefined }> {\n return 'body' in x.state;\n}\n"],"names":[],"mappings":"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"}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { t, Trans } from '@grafana/i18n';
|
2
1
|
import React from 'react';
|
3
2
|
import { Route, Routes } from 'react-router-dom';
|
4
3
|
import { SceneObjectBase } from '../../core/SceneObjectBase.js';
|
@@ -115,8 +114,8 @@ function getFallbackRoute(page) {
|
|
115
114
|
function getDefaultFallbackPage() {
|
116
115
|
return new SceneAppPage({
|
117
116
|
url: "",
|
118
|
-
title:
|
119
|
-
subTitle:
|
117
|
+
title: "Not found",
|
118
|
+
subTitle: "The url did not match any page",
|
120
119
|
routePath: "*",
|
121
120
|
getScene: () => {
|
122
121
|
return new EmbeddedScene({
|
@@ -126,7 +125,7 @@ function getDefaultFallbackPage() {
|
|
126
125
|
new SceneFlexItem({
|
127
126
|
body: new SceneReactObject({
|
128
127
|
component: () => {
|
129
|
-
return /* @__PURE__ */ React.createElement("div", { "data-testid": "default-fallback-content" },
|
128
|
+
return /* @__PURE__ */ React.createElement("div", { "data-testid": "default-fallback-content" }, "If you found your way here using a link then there might be a bug in this application.");
|
130
129
|
}
|
131
130
|
})
|
132
131
|
})
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SceneAppPage.js","sources":["../../../../src/components/SceneApp/SceneAppPage.tsx"],"sourcesContent":["import
|
1
|
+
{"version":3,"file":"SceneAppPage.js","sources":["../../../../src/components/SceneApp/SceneAppPage.tsx"],"sourcesContent":["import React from 'react';\nimport { Route, Routes } from 'react-router-dom';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneComponentProps, SceneObject, isDataRequestEnricher } from '../../core/types';\nimport { EmbeddedScene } from '../EmbeddedScene';\nimport { SceneFlexItem, SceneFlexLayout } from '../layout/SceneFlexLayout';\nimport { SceneReactObject } from '../SceneReactObject';\nimport { SceneAppDrilldownViewRender, SceneAppPageView } from './SceneAppPageView';\nimport { SceneAppDrilldownView, SceneAppPageLike, SceneAppPageState, SceneRouteMatch } from './types';\n\n/**\n * Responsible for page's drilldown & tabs routing\n */\nexport class SceneAppPage extends SceneObjectBase<SceneAppPageState> implements SceneAppPageLike {\n public static Component = SceneAppPageRenderer;\n private _sceneCache = new Map<string, EmbeddedScene>();\n private _drilldownCache = new Map<string, SceneAppPageLike>();\n\n public initializeScene(scene: EmbeddedScene) {\n this.setState({ initializedScene: scene });\n }\n\n public getScene(routeMatch: SceneRouteMatch): EmbeddedScene {\n let scene = this._sceneCache.get(routeMatch.url);\n\n if (scene) {\n return scene;\n }\n\n if (!this.state.getScene) {\n throw new Error('Missing getScene on SceneAppPage ' + this.state.title);\n }\n\n scene = this.state.getScene(routeMatch);\n this._sceneCache.set(routeMatch.url, scene);\n\n return scene;\n }\n\n public getDrilldownPage(drilldown: SceneAppDrilldownView, routeMatch: SceneRouteMatch<{}>): SceneAppPageLike {\n let page = this._drilldownCache.get(routeMatch!.url);\n if (page) {\n return page;\n }\n\n page = drilldown.getPage(routeMatch, this);\n this._drilldownCache.set(routeMatch!.url, page);\n\n return page;\n }\n\n public enrichDataRequest(source: SceneObject) {\n if (this.state.getParentPage) {\n return this.state.getParentPage().enrichDataRequest(source);\n }\n\n if (!this.parent) {\n return null;\n }\n\n const root = this.getRoot();\n\n if (isDataRequestEnricher(root)) {\n return root.enrichDataRequest(source);\n }\n\n return null;\n }\n}\nfunction SceneAppPageRenderer({ model }: SceneComponentProps<SceneAppPage>) {\n const { tabs, drilldowns } = model.useState();\n const routes: React.ReactNode[] = [];\n\n routes.push(getFallbackRoute(model));\n\n if (tabs && tabs.length > 0) {\n for (let tabIndex = 0; tabIndex < tabs.length; tabIndex++) {\n const tab = tabs[tabIndex];\n\n // Add first tab as a default route, this makes it possible for the first tab to render with the url of the parent page\n if (tabIndex === 0) {\n routes.push(<Route key={model.state.routePath} path=\"\" element={<tab.Component model={tab} />}></Route>);\n }\n\n routes.push(\n <Route key={tab.state.url} path={tab.state.routePath} element={<tab.Component model={tab} />}></Route>\n );\n\n if (tab.state.drilldowns) {\n for (const drilldown of tab.state.drilldowns) {\n routes.push(\n <Route\n key={drilldown.routePath}\n path={drilldown.routePath}\n element={<SceneAppDrilldownViewRender drilldown={drilldown} parent={tab} />}\n ></Route>\n );\n }\n }\n }\n }\n\n if (drilldowns) {\n for (const drilldown of drilldowns) {\n routes.push(\n <Route\n key={drilldown.routePath}\n path={drilldown.routePath}\n Component={() => <SceneAppDrilldownViewRender drilldown={drilldown} parent={model} />}\n ></Route>\n );\n }\n }\n\n if (!tabs) {\n routes.push(<Route key=\"home route\" path=\"/\" element={<SceneAppPageView page={model} />}></Route>);\n }\n\n return <Routes>{routes}</Routes>;\n}\n\nfunction getFallbackRoute(page: SceneAppPage) {\n return (\n <Route\n key={'fallback route'}\n path=\"*\"\n element={<SceneAppPageView page={page.state.getFallbackPage?.() ?? getDefaultFallbackPage()} />}\n ></Route>\n );\n}\n\nfunction getDefaultFallbackPage() {\n return new SceneAppPage({\n url: '',\n title: 'Not found',\n subTitle: 'The url did not match any page',\n routePath: '*',\n getScene: () => {\n return new EmbeddedScene({\n body: new SceneFlexLayout({\n direction: 'column',\n children: [\n new SceneFlexItem({\n body: new SceneReactObject({\n component: () => {\n return (\n <div data-testid=\"default-fallback-content\">\n If you found your way here using a link then there might be a bug in this application.\n </div>\n );\n },\n }),\n }),\n ],\n }),\n });\n },\n });\n}\n"],"names":[],"mappings":"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"}
|
@@ -11,8 +11,7 @@ class SceneCanvasText extends SceneObjectBase {
|
|
11
11
|
this._variableDependency = new VariableDependencyConfig(this, { statePaths: ["text"] });
|
12
12
|
}
|
13
13
|
}
|
14
|
-
SceneCanvasText.Component =
|
15
|
-
function SceneCanvasTextRenderer({ model }) {
|
14
|
+
SceneCanvasText.Component = ({ model }) => {
|
16
15
|
const { text, fontSize = 20, align = "left", key, spacing } = model.useState();
|
17
16
|
const theme = useTheme2();
|
18
17
|
const style = css({
|
@@ -24,7 +23,7 @@ function SceneCanvasTextRenderer({ model }) {
|
|
24
23
|
justifyContent: align
|
25
24
|
});
|
26
25
|
return /* @__PURE__ */ React.createElement("div", { className: style, "data-testid": key }, sceneGraph.interpolate(model, text));
|
27
|
-
}
|
26
|
+
};
|
28
27
|
|
29
28
|
export { SceneCanvasText };
|
30
29
|
//# sourceMappingURL=SceneCanvasText.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SceneCanvasText.js","sources":["../../../src/components/SceneCanvasText.tsx"],"sourcesContent":["import React from 'react';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneComponentProps, SceneObjectState } from '../core/types';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\nimport { useTheme2 } from '@grafana/ui';\nimport { css } from '@emotion/css';\n\nexport interface SceneCanvasTextState extends SceneObjectState {\n text: string;\n fontSize?: number;\n align?: 'left' | 'center' | 'right';\n spacing?: number;\n}\n\n/**\n * Not a really useful component, just an example of how to create one\n * @internal\n */\nexport class SceneCanvasText extends SceneObjectBase<SceneCanvasTextState> {\n protected _variableDependency = new VariableDependencyConfig(this, { statePaths: ['text'] });\n\n public static Component =
|
1
|
+
{"version":3,"file":"SceneCanvasText.js","sources":["../../../src/components/SceneCanvasText.tsx"],"sourcesContent":["import React from 'react';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneComponentProps, SceneObjectState } from '../core/types';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\nimport { useTheme2 } from '@grafana/ui';\nimport { css } from '@emotion/css';\n\nexport interface SceneCanvasTextState extends SceneObjectState {\n text: string;\n fontSize?: number;\n align?: 'left' | 'center' | 'right';\n spacing?: number;\n}\n\n/**\n * Not a really useful component, just an example of how to create one\n * @internal\n */\nexport class SceneCanvasText extends SceneObjectBase<SceneCanvasTextState> {\n protected _variableDependency = new VariableDependencyConfig(this, { statePaths: ['text'] });\n\n public static Component = ({ model }: SceneComponentProps<SceneCanvasText>) => {\n const { text, fontSize = 20, align = 'left', key, spacing } = model.useState();\n const theme = useTheme2();\n\n const style = css({\n fontSize: fontSize,\n display: 'flex',\n flexGrow: 1,\n alignItems: 'center',\n padding: spacing ? theme.spacing(spacing, 0) : undefined,\n justifyContent: align,\n });\n\n return (\n <div className={style} data-testid={key}>\n {sceneGraph.interpolate(model, text)}\n </div>\n );\n };\n}\n"],"names":[],"mappings":";;;;;;;AAoBO,MAAM,wBAAwB,eAAsC,CAAA;AAAA,EAApE,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AACL,IAAU,IAAA,CAAA,mBAAA,GAAsB,IAAI,wBAAyB,CAAA,IAAA,EAAM,EAAE,UAAY,EAAA,CAAC,MAAM,CAAA,EAAG,CAAA;AAAA;AAqB7F;AAtBa,eAAA,CAGG,SAAY,GAAA,CAAC,EAAE,KAAA,EAAkD,KAAA;AAC7E,EAAM,MAAA,EAAE,IAAM,EAAA,QAAA,GAAW,EAAI,EAAA,KAAA,GAAQ,QAAQ,GAAK,EAAA,OAAA,EAAY,GAAA,KAAA,CAAM,QAAS,EAAA;AAC7E,EAAA,MAAM,QAAQ,SAAU,EAAA;AAExB,EAAA,MAAM,QAAQ,GAAI,CAAA;AAAA,IAChB,QAAA;AAAA,IACA,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,CAAA;AAAA,IACV,UAAY,EAAA,QAAA;AAAA,IACZ,SAAS,OAAU,GAAA,KAAA,CAAM,OAAQ,CAAA,OAAA,EAAS,CAAC,CAAI,GAAA,MAAA;AAAA,IAC/C,cAAgB,EAAA;AAAA,GACjB,CAAA;AAED,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,KAAO,EAAA,aAAA,EAAa,OACjC,UAAW,CAAA,WAAA,CAAY,KAAO,EAAA,IAAI,CACrC,CAAA;AAEJ,CAAA;;;;"}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { t, Trans } from '@grafana/i18n';
|
2
1
|
import { css } from '@emotion/css';
|
3
2
|
import { useStyles2, ToolbarButton, Drawer, CustomScrollbar } from '@grafana/ui';
|
4
3
|
import React, { useState } from 'react';
|
@@ -9,15 +8,7 @@ function SceneDebugger({ scene }) {
|
|
9
8
|
const styles = useStyles2(getStyles);
|
10
9
|
const [isOpen, setIsOpen] = useState(false);
|
11
10
|
const [selectedObject, setSelectedObject] = useState();
|
12
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ToolbarButton, { variant: "canvas", icon: "bug", onClick: () => setIsOpen(true) }), isOpen && /* @__PURE__ */ React.createElement(
|
13
|
-
Drawer,
|
14
|
-
{
|
15
|
-
title: t("grafana-scenes.components.scene-debugger.title-scene-debugger", "Scene debugger"),
|
16
|
-
onClose: () => setIsOpen(false),
|
17
|
-
size: "lg"
|
18
|
-
},
|
19
|
-
/* @__PURE__ */ React.createElement("div", { className: styles.panes }, /* @__PURE__ */ React.createElement("div", { className: styles.pane1 }, /* @__PURE__ */ React.createElement("div", { className: styles.paneHeading }, /* @__PURE__ */ React.createElement(Trans, { i18nKey: "grafana-scenes.components.scene-debugger.scene-graph" }, "Scene graph")), /* @__PURE__ */ React.createElement(CustomScrollbar, { autoHeightMin: "100%" }, /* @__PURE__ */ React.createElement("div", { className: styles.treeWrapper }, /* @__PURE__ */ React.createElement(DebugTreeNode, { node: scene, selectedObject, onSelect: setSelectedObject })))), /* @__PURE__ */ React.createElement("div", { className: styles.pane2 }, /* @__PURE__ */ React.createElement("div", { className: styles.paneHeading }, /* @__PURE__ */ React.createElement(Trans, { i18nKey: "grafana-scenes.components.scene-debugger.object-details" }, "Object details")), selectedObject && /* @__PURE__ */ React.createElement(DebugDetails, { node: selectedObject })))
|
20
|
-
));
|
11
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ToolbarButton, { variant: "canvas", icon: "bug", onClick: () => setIsOpen(true) }), isOpen && /* @__PURE__ */ React.createElement(Drawer, { title: "Scene debugger", onClose: () => setIsOpen(false), size: "lg" }, /* @__PURE__ */ React.createElement("div", { className: styles.panes }, /* @__PURE__ */ React.createElement("div", { className: styles.pane1 }, /* @__PURE__ */ React.createElement("div", { className: styles.paneHeading }, "Scene graph"), /* @__PURE__ */ React.createElement(CustomScrollbar, { autoHeightMin: "100%" }, /* @__PURE__ */ React.createElement("div", { className: styles.treeWrapper }, /* @__PURE__ */ React.createElement(DebugTreeNode, { node: scene, selectedObject, onSelect: setSelectedObject })))), /* @__PURE__ */ React.createElement("div", { className: styles.pane2 }, /* @__PURE__ */ React.createElement("div", { className: styles.paneHeading }, "Object details"), selectedObject && /* @__PURE__ */ React.createElement(DebugDetails, { node: selectedObject })))));
|
21
12
|
}
|
22
13
|
function getStyles(theme) {
|
23
14
|
return {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SceneDebugger.js","sources":["../../../../src/components/SceneDebugger/SceneDebugger.tsx"],"sourcesContent":["import {
|
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\n/**\n * @internal\n * Please don't use from plugins directly.\n * This is already exposed via SceneAppPage and the ?scene-debugger query parameter.\n *\n * This is only exported so that core dashboards can use it.\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 +1 @@
|
|
1
|
-
{"version":3,"file":"SceneRefreshPicker.js","sources":["../../../src/components/SceneRefreshPicker.tsx"],"sourcesContent":["import React from 'react';\nimport { Unsubscribable } from 'rxjs';\nimport { rangeUtil } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { RefreshPicker } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneComponentProps, SceneObject, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\n\nexport const DEFAULT_INTERVALS = ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'];\n\nexport interface SceneRefreshPickerState extends SceneObjectState {\n /**\n * Refresh interval, e.g. 5s, 1m, 2h\n */\n refresh: string;\n autoEnabled?: boolean;\n autoMinInterval?: string;\n autoValue?: string;\n /**\n * List of allowed refresh intervals, e.g. ['5s', '1m']\n */\n intervals?: string[];\n isOnCanvas?: boolean;\n primary?: boolean;\n withText?: boolean;\n /**\n * Overrides the default minRefreshInterval from the grafana config. Can be set to \"0s\" to remove the minimum refresh interval.\n */\n minRefreshInterval?: string;\n}\n\nexport class SceneRefreshPicker extends SceneObjectBase<SceneRefreshPickerState> {\n public static Component = SceneRefreshPickerRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['refresh'] });\n private _intervalTimer: ReturnType<typeof setInterval> | undefined;\n private _autoTimeRangeListener: Unsubscribable | undefined;\n private _autoRefreshBlocked = false;\n\n public constructor(state: Partial<SceneRefreshPickerState>) {\n const filterDissalowedIntervals = (i: string) => {\n const minInterval = state.minRefreshInterval ?? config.minRefreshInterval;\n try {\n return minInterval ? rangeUtil.intervalToMs(i) >= rangeUtil.intervalToMs(minInterval) : true;\n } catch (e) {\n // Unable to parse interval\n return false;\n }\n };\n\n super({\n refresh: '',\n ...state,\n autoValue: undefined,\n autoEnabled: state.autoEnabled ?? true,\n autoMinInterval: state.autoMinInterval ?? config.minRefreshInterval,\n intervals: (state.intervals ?? DEFAULT_INTERVALS).filter(filterDissalowedIntervals),\n });\n\n this.addActivationHandler(() => {\n this.setupIntervalTimer();\n\n const onVisibilityChange = () => {\n if (this._autoRefreshBlocked && document.visibilityState === 'visible') {\n this._autoRefreshBlocked = false;\n this.onRefresh();\n }\n };\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n return () => {\n if (this._intervalTimer) {\n clearInterval(this._intervalTimer);\n }\n\n document.removeEventListener('visibilitychange', onVisibilityChange);\n this._autoTimeRangeListener?.unsubscribe();\n };\n });\n }\n\n public onRefresh = () => {\n const queryController = sceneGraph.getQueryController(this);\n\n queryController?.startProfile('SceneRefreshPicker');\n\n if (queryController?.state.isRunning) {\n queryController.cancelAll();\n return;\n }\n\n const timeRange = sceneGraph.getTimeRange(this);\n\n if (this._intervalTimer) {\n clearInterval(this._intervalTimer);\n }\n\n timeRange.onRefresh();\n this.setupIntervalTimer();\n };\n\n public onIntervalChanged = (interval: string) => {\n this.setState({ refresh: interval });\n this.setupIntervalTimer();\n };\n\n public getUrlState() {\n let refresh: string | undefined = this.state.refresh;\n\n if (typeof refresh !== 'string' || refresh.length === 0) {\n refresh = undefined;\n }\n\n return { refresh };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n const { intervals } = this.state;\n let refresh = values.refresh;\n\n if (typeof refresh === 'string' && isIntervalString(refresh)) {\n if (intervals?.includes(refresh)) {\n this.setState({ refresh });\n } else {\n this.setState({\n // Default to the first refresh interval if the interval from the URL is not allowed, just like in the old architecture.\n refresh: intervals ? intervals[0] : undefined,\n });\n }\n }\n }\n\n private setupAutoTimeRangeListener = () => {\n // If the time range has changed, we need to recalculate the auto interval but prevent unnecessary processing\n return sceneGraph.getTimeRange(this).subscribeToState((newState, prevState) => {\n if (newState.from !== prevState.from || newState.to !== prevState.to) {\n this.setupIntervalTimer();\n }\n });\n };\n\n private calculateAutoRefreshInterval = () => {\n const timeRange = sceneGraph.getTimeRange(this);\n const resolution = window?.innerWidth ?? 2000;\n return rangeUtil.calculateInterval(timeRange.state.value, resolution, this.state.autoMinInterval);\n };\n\n private isTabVisible() {\n return document.visibilityState === undefined || document.visibilityState === 'visible';\n }\n\n private setupIntervalTimer = () => {\n const timeRange = sceneGraph.getTimeRange(this);\n const { refresh, intervals } = this.state;\n\n if (this._intervalTimer || refresh === '') {\n clearInterval(this._intervalTimer);\n }\n\n if (refresh === '') {\n return;\n }\n\n // If the provided interval is not allowed\n if (refresh !== RefreshPicker.autoOption.value && intervals && !intervals.includes(refresh)) {\n return;\n }\n\n let intervalMs: number;\n\n // Unsubscribe from previous listener no matter what\n this._autoTimeRangeListener?.unsubscribe();\n\n if (refresh === RefreshPicker.autoOption.value) {\n const autoRefreshInterval = this.calculateAutoRefreshInterval();\n\n intervalMs = autoRefreshInterval.intervalMs;\n\n this._autoTimeRangeListener = this.setupAutoTimeRangeListener();\n\n if (autoRefreshInterval.interval !== this.state.autoValue) {\n this.setState({ autoValue: autoRefreshInterval.interval });\n }\n } else {\n intervalMs = rangeUtil.intervalToMs(refresh);\n }\n\n this._intervalTimer = setInterval(() => {\n if (this.isTabVisible()) {\n const queryController = sceneGraph.getQueryController(this);\n queryController?.startProfile('SceneRefreshPicker');\n timeRange.onRefresh();\n } else {\n this._autoRefreshBlocked = true;\n }\n }, intervalMs);\n };\n}\n\nexport function SceneRefreshPickerRenderer({ model }: SceneComponentProps<SceneRefreshPicker>) {\n const { refresh, intervals, autoEnabled, autoValue, isOnCanvas, primary, withText } = model.useState();\n const isRunning = useQueryControllerState(model);\n\n let text = refresh === RefreshPicker.autoOption?.value ? autoValue : withText ? 'Refresh' : undefined;\n let tooltip: string | undefined;\n let width: string | undefined;\n\n if (isRunning) {\n tooltip = 'Cancel all queries';\n\n if (withText) {\n text = 'Cancel';\n }\n }\n\n if (withText) {\n width = '96px';\n }\n\n return (\n <RefreshPicker\n showAutoInterval={autoEnabled}\n value={refresh}\n intervals={intervals}\n tooltip={tooltip}\n width={width}\n text={text}\n onRefresh={() => {\n model.onRefresh();\n }}\n primary={primary}\n onIntervalChanged={model.onIntervalChanged}\n isLoading={isRunning}\n isOnCanvas={isOnCanvas ?? true}\n />\n );\n}\n\nfunction useQueryControllerState(model: SceneObject): boolean {\n const queryController = sceneGraph.getQueryController(model);\n if (!queryController) {\n return false;\n }\n\n return queryController.useState().isRunning;\n}\n\nfunction isIntervalString(str: string): boolean {\n try {\n const res = rangeUtil.describeInterval(str);\n return res.count > 0;\n } catch {\n return false;\n }\n}\n"],"names":["_a"],"mappings":";;;;;;;;AAWa,MAAA,iBAAA,GAAoB,CAAC,IAAA,EAAM,KAAO,EAAA,KAAA,EAAO,IAAM,EAAA,IAAA,EAAM,KAAO,EAAA,KAAA,EAAO,IAAM,EAAA,IAAA,EAAM,IAAI;AAuBzF,MAAM,2BAA2B,eAAyC,CAAA;AAAA,EAOxE,YAAY,KAAyC,EAAA;AAzC9D,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA0CI,IAAM,MAAA,yBAAA,GAA4B,CAAC,CAAc,KAAA;AA1CrD,MAAAA,IAAAA,GAAAA;AA2CM,MAAA,MAAM,eAAcA,GAAA,GAAA,KAAA,CAAM,kBAAN,KAAA,IAAA,GAAAA,MAA4B,MAAO,CAAA,kBAAA;AACvD,MAAI,IAAA;AACF,QAAO,OAAA,WAAA,GAAc,UAAU,YAAa,CAAA,CAAC,KAAK,SAAU,CAAA,YAAA,CAAa,WAAW,CAAI,GAAA,IAAA;AAAA,eACjF,CAAG,EAAA;AAEV,QAAO,OAAA,KAAA;AAAA;AACT,KACF;AAEA,IAAM,KAAA,CAAA;AAAA,MACJ,OAAS,EAAA,EAAA;AAAA,MACT,GAAG,KAAA;AAAA,MACH,SAAW,EAAA,MAAA;AAAA,MACX,WAAA,EAAA,CAAa,EAAM,GAAA,KAAA,CAAA,WAAA,KAAN,IAAqB,GAAA,EAAA,GAAA,IAAA;AAAA,MAClC,eAAiB,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,eAAN,KAAA,IAAA,GAAA,EAAA,GAAyB,MAAO,CAAA,kBAAA;AAAA,MACjD,aAAY,EAAM,GAAA,KAAA,CAAA,SAAA,KAAN,IAAmB,GAAA,EAAA,GAAA,iBAAA,EAAmB,OAAO,yBAAyB;AAAA,KACnF,CAAA;AAvBH,IAAU,IAAA,CAAA,QAAA,GAAW,IAAI,wBAAyB,CAAA,IAAA,EAAM,EAAE,IAAM,EAAA,CAAC,SAAS,CAAA,EAAG,CAAA;AAG7E,IAAA,IAAA,CAAQ,mBAAsB,GAAA,KAAA;AA6C9B,IAAA,IAAA,CAAO,YAAY,MAAM;AACvB,MAAM,MAAA,eAAA,GAAkB,UAAW,CAAA,kBAAA,CAAmB,IAAI,CAAA;AAE1D,MAAA,eAAA,IAAA,IAAA,GAAA,MAAA,GAAA,eAAA,CAAiB,YAAa,CAAA,oBAAA,CAAA;AAE9B,MAAI,IAAA,eAAA,IAAA,IAAA,GAAA,MAAA,GAAA,eAAA,CAAiB,MAAM,SAAW,EAAA;AACpC,QAAA,eAAA,CAAgB,SAAU,EAAA;AAC1B,QAAA;AAAA;AAGF,MAAM,MAAA,SAAA,GAAY,UAAW,CAAA,YAAA,CAAa,IAAI,CAAA;AAE9C,MAAA,IAAI,KAAK,cAAgB,EAAA;AACvB,QAAA,aAAA,CAAc,KAAK,cAAc,CAAA;AAAA;AAGnC,MAAA,SAAA,CAAU,SAAU,EAAA;AACpB,MAAA,IAAA,CAAK,kBAAmB,EAAA;AAAA,KAC1B;AAEA,IAAO,IAAA,CAAA,iBAAA,GAAoB,CAAC,QAAqB,KAAA;AAC/C,MAAA,IAAA,CAAK,QAAS,CAAA,EAAE,OAAS,EAAA,QAAA,EAAU,CAAA;AACnC,MAAA,IAAA,CAAK,kBAAmB,EAAA;AAAA,KAC1B;AA4BA,IAAA,IAAA,CAAQ,6BAA6B,MAAM;AAEzC,MAAA,OAAO,WAAW,YAAa,CAAA,IAAI,EAAE,gBAAiB,CAAA,CAAC,UAAU,SAAc,KAAA;AAC7E,QAAA,IAAI,SAAS,IAAS,KAAA,SAAA,CAAU,QAAQ,QAAS,CAAA,EAAA,KAAO,UAAU,EAAI,EAAA;AACpE,UAAA,IAAA,CAAK,kBAAmB,EAAA;AAAA;AAC1B,OACD,CAAA;AAAA,KACH;AAEA,IAAA,IAAA,CAAQ,+BAA+B,MAAM;AAhJ/C,MAAA,IAAA,EAAA;AAiJI,MAAM,MAAA,SAAA,GAAY,UAAW,CAAA,YAAA,CAAa,IAAI,CAAA;AAC9C,MAAM,MAAA,UAAA,GAAA,CAAa,EAAQ,GAAA,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAA,UAAA,KAAR,IAAsB,GAAA,EAAA,GAAA,GAAA;AACzC,MAAO,OAAA,SAAA,CAAU,kBAAkB,SAAU,CAAA,KAAA,CAAM,OAAO,UAAY,EAAA,IAAA,CAAK,MAAM,eAAe,CAAA;AAAA,KAClG;AAMA,IAAA,IAAA,CAAQ,qBAAqB,MAAM;AA1JrC,MAAA,IAAA,EAAA;AA2JI,MAAM,MAAA,SAAA,GAAY,UAAW,CAAA,YAAA,CAAa,IAAI,CAAA;AAC9C,MAAA,MAAM,EAAE,OAAA,EAAS,SAAU,EAAA,GAAI,IAAK,CAAA,KAAA;AAEpC,MAAI,IAAA,IAAA,CAAK,cAAkB,IAAA,OAAA,KAAY,EAAI,EAAA;AACzC,QAAA,aAAA,CAAc,KAAK,cAAc,CAAA;AAAA;AAGnC,MAAA,IAAI,YAAY,EAAI,EAAA;AAClB,QAAA;AAAA;AAIF,MAAI,IAAA,OAAA,KAAY,cAAc,UAAW,CAAA,KAAA,IAAS,aAAa,CAAC,SAAA,CAAU,QAAS,CAAA,OAAO,CAAG,EAAA;AAC3F,QAAA;AAAA;AAGF,MAAI,IAAA,UAAA;AAGJ,MAAA,CAAA,EAAA,GAAA,IAAA,CAAK,2BAAL,IAA6B,GAAA,MAAA,GAAA,EAAA,CAAA,WAAA,EAAA;AAE7B,MAAI,IAAA,OAAA,KAAY,aAAc,CAAA,UAAA,CAAW,KAAO,EAAA;AAC9C,QAAM,MAAA,mBAAA,GAAsB,KAAK,4BAA6B,EAAA;AAE9D,QAAA,UAAA,GAAa,mBAAoB,CAAA,UAAA;AAEjC,QAAK,IAAA,CAAA,sBAAA,GAAyB,KAAK,0BAA2B,EAAA;AAE9D,QAAA,IAAI,mBAAoB,CAAA,QAAA,KAAa,IAAK,CAAA,KAAA,CAAM,SAAW,EAAA;AACzD,UAAA,IAAA,CAAK,QAAS,CAAA,EAAE,SAAW,EAAA,mBAAA,CAAoB,UAAU,CAAA;AAAA;AAC3D,OACK,MAAA;AACL,QAAa,UAAA,GAAA,SAAA,CAAU,aAAa,OAAO,CAAA;AAAA;AAG7C,MAAK,IAAA,CAAA,cAAA,GAAiB,YAAY,MAAM;AACtC,QAAI,IAAA,IAAA,CAAK,cAAgB,EAAA;AACvB,UAAM,MAAA,eAAA,GAAkB,UAAW,CAAA,kBAAA,CAAmB,IAAI,CAAA;AAC1D,UAAA,eAAA,IAAA,IAAA,GAAA,MAAA,GAAA,eAAA,CAAiB,YAAa,CAAA,oBAAA,CAAA;AAC9B,UAAA,SAAA,CAAU,SAAU,EAAA;AAAA,SACf,MAAA;AACL,UAAA,IAAA,CAAK,mBAAsB,GAAA,IAAA;AAAA;AAC7B,SACC,UAAU,CAAA;AAAA,KACf;AA1IE,IAAA,IAAA,CAAK,qBAAqB,MAAM;AAC9B,MAAA,IAAA,CAAK,kBAAmB,EAAA;AAExB,MAAA,MAAM,qBAAqB,MAAM;AAC/B,QAAA,IAAI,IAAK,CAAA,mBAAA,IAAuB,QAAS,CAAA,eAAA,KAAoB,SAAW,EAAA;AACtE,UAAA,IAAA,CAAK,mBAAsB,GAAA,KAAA;AAC3B,UAAA,IAAA,CAAK,SAAU,EAAA;AAAA;AACjB,OACF;AAEA,MAAS,QAAA,CAAA,gBAAA,CAAiB,oBAAoB,kBAAkB,CAAA;AAEhE,MAAA,OAAO,MAAM;AAzEnB,QAAAA,IAAAA,GAAAA;AA0EQ,QAAA,IAAI,KAAK,cAAgB,EAAA;AACvB,UAAA,aAAA,CAAc,KAAK,cAAc,CAAA;AAAA;AAGnC,QAAS,QAAA,CAAA,mBAAA,CAAoB,oBAAoB,kBAAkB,CAAA;AACnE,QAAA,CAAAA,GAAA,GAAA,IAAA,CAAK,sBAAL,KAAA,IAAA,GAAA,MAAA,GAAAA,GAA6B,CAAA,WAAA,EAAA;AAAA,OAC/B;AAAA,KACD,CAAA;AAAA;AACH,EA2BO,WAAc,GAAA;AACnB,IAAI,IAAA,OAAA,GAA8B,KAAK,KAAM,CAAA,OAAA;AAE7C,IAAA,IAAI,OAAO,OAAA,KAAY,QAAY,IAAA,OAAA,CAAQ,WAAW,CAAG,EAAA;AACvD,MAAU,OAAA,GAAA,MAAA;AAAA;AAGZ,IAAA,OAAO,EAAE,OAAQ,EAAA;AAAA;AACnB,EAEO,cAAc,MAA8B,EAAA;AACjD,IAAM,MAAA,EAAE,SAAU,EAAA,GAAI,IAAK,CAAA,KAAA;AAC3B,IAAA,IAAI,UAAU,MAAO,CAAA,OAAA;AAErB,IAAA,IAAI,OAAO,OAAA,KAAY,QAAY,IAAA,gBAAA,CAAiB,OAAO,CAAG,EAAA;AAC5D,MAAI,IAAA,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,SAAS,OAAU,CAAA,EAAA;AAChC,QAAK,IAAA,CAAA,QAAA,CAAS,EAAE,OAAA,EAAS,CAAA;AAAA,OACpB,MAAA;AACL,QAAA,IAAA,CAAK,QAAS,CAAA;AAAA;AAAA,UAEZ,OAAS,EAAA,SAAA,GAAY,SAAU,CAAA,CAAC,CAAI,GAAA;AAAA,SACrC,CAAA;AAAA;AACH;AACF;AACF,EAiBQ,YAAe,GAAA;AACrB,IAAA,OAAO,QAAS,CAAA,eAAA,KAAoB,MAAa,IAAA,QAAA,CAAS,eAAoB,KAAA,SAAA;AAAA;AAiDlF;AAtKa,kBAAA,CACG,SAAY,GAAA,0BAAA;AAuKZ,SAAA,0BAAA,CAA2B,EAAE,KAAA,EAAkD,EAAA;AA1M/F,EAAA,IAAA,EAAA;AA2ME,EAAM,MAAA,EAAE,OAAS,EAAA,SAAA,EAAW,WAAa,EAAA,SAAA,EAAW,YAAY,OAAS,EAAA,QAAA,EAAa,GAAA,KAAA,CAAM,QAAS,EAAA;AACrG,EAAM,MAAA,SAAA,GAAY,wBAAwB,KAAK,CAAA;AAE/C,EAAI,IAAA,IAAA,GAAO,cAAY,EAAc,GAAA,aAAA,CAAA,UAAA,KAAd,mBAA0B,KAAQ,CAAA,GAAA,SAAA,GAAY,WAAW,SAAY,GAAA,MAAA;AAC5F,EAAI,IAAA,OAAA;AACJ,EAAI,IAAA,KAAA;AAEJ,EAAA,IAAI,SAAW,EAAA;AACb,IAAU,OAAA,GAAA,oBAAA;AAEV,IAAA,IAAI,QAAU,EAAA;AACZ,MAAO,IAAA,GAAA,QAAA;AAAA;AACT;AAGF,EAAA,IAAI,QAAU,EAAA;AACZ,IAAQ,KAAA,GAAA,MAAA;AAAA;AAGV,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,gBAAkB,EAAA,WAAA;AAAA,MAClB,KAAO,EAAA,OAAA;AAAA,MACP,SAAA;AAAA,MACA,OAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,WAAW,MAAM;AACf,QAAA,KAAA,CAAM,SAAU,EAAA;AAAA,OAClB;AAAA,MACA,OAAA;AAAA,MACA,mBAAmB,KAAM,CAAA,iBAAA;AAAA,MACzB,SAAW,EAAA,SAAA;AAAA,MACX,YAAY,UAAc,IAAA,IAAA,GAAA,UAAA,GAAA;AAAA;AAAA,GAC5B;AAEJ;AAEA,SAAS,wBAAwB,KAA6B,EAAA;AAC5D,EAAM,MAAA,eAAA,GAAkB,UAAW,CAAA,kBAAA,CAAmB,KAAK,CAAA;AAC3D,EAAA,IAAI,CAAC,eAAiB,EAAA;AACpB,IAAO,OAAA,KAAA;AAAA;AAGT,EAAO,OAAA,eAAA,CAAgB,UAAW,CAAA,SAAA;AACpC;AAEA,SAAS,iBAAiB,GAAsB,EAAA;AAC9C,EAAI,IAAA;AACF,IAAM,MAAA,GAAA,GAAM,SAAU,CAAA,gBAAA,CAAiB,GAAG,CAAA;AAC1C,IAAA,OAAO,IAAI,KAAQ,GAAA,CAAA;AAAA,GACb,CAAA,OAAA,CAAA,EAAA;AACN,IAAO,OAAA,KAAA;AAAA;AAEX;;;;"}
|
1
|
+
{"version":3,"file":"SceneRefreshPicker.js","sources":["../../../src/components/SceneRefreshPicker.tsx"],"sourcesContent":["import React from 'react';\nimport { Unsubscribable } from 'rxjs';\nimport { rangeUtil } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { RefreshPicker } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneComponentProps, SceneObject, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\n\nexport const DEFAULT_INTERVALS = ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'];\n\nexport interface SceneRefreshPickerState extends SceneObjectState {\n /**\n * Refresh interval, e.g. 5s, 1m, 2h\n */\n refresh: string;\n autoEnabled?: boolean;\n autoMinInterval?: string;\n autoValue?: string;\n /**\n * List of allowed refresh intervals, e.g. ['5s', '1m']\n */\n intervals?: string[];\n isOnCanvas?: boolean;\n primary?: boolean;\n withText?: boolean;\n /**\n * Overrides the default minRefreshInterval from the grafana config. Can be set to \"0s\" to remove the minimum refresh interval.\n */\n minRefreshInterval?: string;\n}\n\nexport class SceneRefreshPicker extends SceneObjectBase<SceneRefreshPickerState> {\n public static Component = SceneRefreshPickerRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['refresh'] });\n private _intervalTimer: ReturnType<typeof setInterval> | undefined;\n private _autoTimeRangeListener: Unsubscribable | undefined;\n private _autoRefreshBlocked: boolean = false;\n\n public constructor(state: Partial<SceneRefreshPickerState>) {\n const filterDissalowedIntervals = (i: string) => {\n const minInterval = state.minRefreshInterval ?? config.minRefreshInterval;\n try {\n return minInterval ? rangeUtil.intervalToMs(i) >= rangeUtil.intervalToMs(minInterval) : true;\n } catch (e) {\n // Unable to parse interval\n return false;\n }\n };\n\n super({\n refresh: '',\n ...state,\n autoValue: undefined,\n autoEnabled: state.autoEnabled ?? true,\n autoMinInterval: state.autoMinInterval ?? config.minRefreshInterval,\n intervals: (state.intervals ?? DEFAULT_INTERVALS).filter(filterDissalowedIntervals),\n });\n\n this.addActivationHandler(() => {\n this.setupIntervalTimer();\n\n const onVisibilityChange = () => {\n if (this._autoRefreshBlocked && document.visibilityState === 'visible') {\n this._autoRefreshBlocked = false;\n this.onRefresh();\n }\n };\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n return () => {\n if (this._intervalTimer) {\n clearInterval(this._intervalTimer);\n }\n\n document.removeEventListener('visibilitychange', onVisibilityChange);\n this._autoTimeRangeListener?.unsubscribe();\n };\n });\n }\n\n public onRefresh = () => {\n const queryController = sceneGraph.getQueryController(this);\n\n queryController?.startProfile('SceneRefreshPicker');\n\n if (queryController?.state.isRunning) {\n queryController.cancelAll();\n return;\n }\n\n const timeRange = sceneGraph.getTimeRange(this);\n\n if (this._intervalTimer) {\n clearInterval(this._intervalTimer);\n }\n\n timeRange.onRefresh();\n this.setupIntervalTimer();\n };\n\n public onIntervalChanged = (interval: string) => {\n this.setState({ refresh: interval });\n this.setupIntervalTimer();\n };\n\n public getUrlState() {\n let refresh: string | undefined = this.state.refresh;\n\n if (typeof refresh !== 'string' || refresh.length === 0) {\n refresh = undefined;\n }\n\n return { refresh };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n const { intervals } = this.state;\n let refresh = values.refresh;\n\n if (typeof refresh === 'string' && isIntervalString(refresh)) {\n if (intervals?.includes(refresh)) {\n this.setState({ refresh });\n } else {\n this.setState({\n // Default to the first refresh interval if the interval from the URL is not allowed, just like in the old architecture.\n refresh: intervals ? intervals[0] : undefined,\n });\n }\n }\n }\n\n private setupAutoTimeRangeListener = () => {\n // If the time range has changed, we need to recalculate the auto interval but prevent unnecessary processing\n return sceneGraph.getTimeRange(this).subscribeToState((newState, prevState) => {\n if (newState.from !== prevState.from || newState.to !== prevState.to) {\n this.setupIntervalTimer();\n }\n });\n };\n\n private calculateAutoRefreshInterval = () => {\n const timeRange = sceneGraph.getTimeRange(this);\n const resolution = window?.innerWidth ?? 2000;\n return rangeUtil.calculateInterval(timeRange.state.value, resolution, this.state.autoMinInterval);\n };\n\n private isTabVisible() {\n return document.visibilityState === undefined || document.visibilityState === 'visible';\n }\n\n private setupIntervalTimer = () => {\n const timeRange = sceneGraph.getTimeRange(this);\n const { refresh, intervals } = this.state;\n\n if (this._intervalTimer || refresh === '') {\n clearInterval(this._intervalTimer);\n }\n\n if (refresh === '') {\n return;\n }\n\n // If the provided interval is not allowed\n if (refresh !== RefreshPicker.autoOption.value && intervals && !intervals.includes(refresh)) {\n return;\n }\n\n let intervalMs: number;\n\n // Unsubscribe from previous listener no matter what\n this._autoTimeRangeListener?.unsubscribe();\n\n if (refresh === RefreshPicker.autoOption.value) {\n const autoRefreshInterval = this.calculateAutoRefreshInterval();\n\n intervalMs = autoRefreshInterval.intervalMs;\n\n this._autoTimeRangeListener = this.setupAutoTimeRangeListener();\n\n if (autoRefreshInterval.interval !== this.state.autoValue) {\n this.setState({ autoValue: autoRefreshInterval.interval });\n }\n } else {\n intervalMs = rangeUtil.intervalToMs(refresh);\n }\n\n this._intervalTimer = setInterval(() => {\n if (this.isTabVisible()) {\n const queryController = sceneGraph.getQueryController(this);\n queryController?.startProfile('SceneRefreshPicker');\n timeRange.onRefresh();\n } else {\n this._autoRefreshBlocked = true;\n }\n }, intervalMs);\n };\n}\n\nexport function SceneRefreshPickerRenderer({ model }: SceneComponentProps<SceneRefreshPicker>) {\n const { refresh, intervals, autoEnabled, autoValue, isOnCanvas, primary, withText } = model.useState();\n const isRunning = useQueryControllerState(model);\n\n let text = refresh === RefreshPicker.autoOption?.value ? autoValue : withText ? 'Refresh' : undefined;\n let tooltip: string | undefined;\n let width: string | undefined;\n\n if (isRunning) {\n tooltip = 'Cancel all queries';\n\n if (withText) {\n text = 'Cancel';\n }\n }\n\n if (withText) {\n width = '96px';\n }\n\n return (\n <RefreshPicker\n showAutoInterval={autoEnabled}\n value={refresh}\n intervals={intervals}\n tooltip={tooltip}\n width={width}\n text={text}\n onRefresh={() => {\n model.onRefresh();\n }}\n primary={primary}\n onIntervalChanged={model.onIntervalChanged}\n isLoading={isRunning}\n isOnCanvas={isOnCanvas ?? true}\n />\n );\n}\n\nfunction useQueryControllerState(model: SceneObject): boolean {\n const queryController = sceneGraph.getQueryController(model);\n if (!queryController) {\n return false;\n }\n\n return queryController.useState().isRunning;\n}\n\nfunction isIntervalString(str: string): boolean {\n try {\n const res = rangeUtil.describeInterval(str);\n return res.count > 0;\n } catch {\n return false;\n }\n}\n"],"names":["_a"],"mappings":"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"}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { t, Trans } from '@grafana/i18n';
|
2
1
|
import { rangeUtil, dateTime, FieldType } from '@grafana/data';
|
3
2
|
import { config } from '@grafana/runtime';
|
4
3
|
import { useStyles2, ButtonGroup, ToolbarButton, Checkbox, ButtonSelect } from '@grafana/ui';
|
@@ -190,10 +189,7 @@ function SceneTimeRangeCompareRenderer({ model }) {
|
|
190
189
|
ToolbarButton,
|
191
190
|
{
|
192
191
|
variant: "canvas",
|
193
|
-
tooltip:
|
194
|
-
"grafana-scenes.components.scene-time-range-compare-renderer.button-tooltip",
|
195
|
-
"Enable time frame comparison"
|
196
|
-
),
|
192
|
+
tooltip: "Enable time frame comparison",
|
197
193
|
onClick: (e) => {
|
198
194
|
e.stopPropagation();
|
199
195
|
e.preventDefault();
|
@@ -201,7 +197,7 @@ function SceneTimeRangeCompareRenderer({ model }) {
|
|
201
197
|
}
|
202
198
|
},
|
203
199
|
/* @__PURE__ */ React.createElement(Checkbox, { label: " ", value: enabled, onClick }),
|
204
|
-
|
200
|
+
"Comparison"
|
205
201
|
), enabled ? /* @__PURE__ */ React.createElement(
|
206
202
|
ButtonSelect,
|
207
203
|
{
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SceneTimeRangeCompare.js","sources":["../../../src/components/SceneTimeRangeCompare.tsx"],"sourcesContent":["import { t, Trans } from '@grafana/i18n';\nimport { DataQueryRequest, DateTime, dateTime, FieldType, GrafanaTheme2, rangeUtil, TimeRange } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { ButtonGroup, ButtonSelect, Checkbox, ToolbarButton, useStyles2 } from '@grafana/ui';\nimport React from 'react';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { SceneComponentProps, SceneDataQuery, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { DataQueryExtended } from '../querying/SceneQueryRunner';\nimport { ExtraQueryDescriptor, ExtraQueryDataProcessor, ExtraQueryProvider } from '../querying/ExtraQueryProvider';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\nimport { getCompareSeriesRefId } from '../utils/getCompareSeriesRefId';\nimport { parseUrlParam } from '../utils/parseUrlParam';\nimport { css } from '@emotion/css';\nimport { of } from 'rxjs';\n\ninterface SceneTimeRangeCompareState extends SceneObjectState {\n compareWith?: string;\n compareOptions: Array<{ label: string; value: string }>;\n}\n\nconst PREVIOUS_PERIOD_VALUE = '__previousPeriod';\nconst NO_PERIOD_VALUE = '__noPeriod';\n\nexport const PREVIOUS_PERIOD_COMPARE_OPTION = {\n label: 'Previous period',\n value: PREVIOUS_PERIOD_VALUE,\n};\n\nexport const NO_COMPARE_OPTION = {\n label: 'No comparison',\n value: NO_PERIOD_VALUE,\n};\n\nexport const DEFAULT_COMPARE_OPTIONS = [\n { label: 'Day before', value: '24h' },\n { label: 'Week before', value: '1w' },\n { label: 'Month before', value: '1M' },\n];\n\nexport class SceneTimeRangeCompare\n extends SceneObjectBase<SceneTimeRangeCompareState>\n implements ExtraQueryProvider<SceneTimeRangeCompareState>\n{\n static Component = SceneTimeRangeCompareRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['compareWith'] });\n\n public constructor(state: Partial<SceneTimeRangeCompareState>) {\n super({ compareOptions: DEFAULT_COMPARE_OPTIONS, ...state });\n this.addActivationHandler(this._onActivate);\n }\n\n private _onActivate = () => {\n const sceneTimeRange = sceneGraph.getTimeRange(this);\n this.setState({ compareOptions: this.getCompareOptions(sceneTimeRange.state.value) });\n\n this._subs.add(\n sceneTimeRange.subscribeToState((timeRange) => {\n const compareOptions = this.getCompareOptions(timeRange.value);\n const stateUpdate: Partial<SceneTimeRangeCompareState> = { compareOptions };\n\n // if current compareWith is not applicable to the new time range, set it to previous period comparison\n if (Boolean(this.state.compareWith) && !compareOptions.find(({ value }) => value === this.state.compareWith)) {\n stateUpdate.compareWith = PREVIOUS_PERIOD_VALUE;\n }\n\n this.setState(stateUpdate);\n })\n );\n };\n\n public getCompareOptions = (timeRange: TimeRange) => {\n const diffDays = Math.ceil(timeRange.to.diff(timeRange.from));\n\n const matchIndex = DEFAULT_COMPARE_OPTIONS.findIndex(({ value }) => {\n const intervalInMs = rangeUtil.intervalToMs(value);\n return intervalInMs >= diffDays;\n });\n\n return [\n NO_COMPARE_OPTION,\n PREVIOUS_PERIOD_COMPARE_OPTION,\n ...DEFAULT_COMPARE_OPTIONS.slice(matchIndex).map(({ label, value }) => ({ label, value })),\n ];\n };\n\n public onCompareWithChanged = (compareWith: string) => {\n if (compareWith === NO_PERIOD_VALUE) {\n this.onClearCompare();\n } else {\n this.setState({ compareWith });\n }\n };\n\n public onClearCompare = () => {\n this.setState({ compareWith: undefined });\n };\n\n // Get a time shifted request to compare with the primary request.\n public getExtraQueries(request: DataQueryRequest): ExtraQueryDescriptor[] {\n const extraQueries: ExtraQueryDescriptor[] = [];\n const compareRange = this.getCompareTimeRange(request.range);\n if (!compareRange) {\n return extraQueries;\n }\n\n const targets = request.targets.filter((query: DataQueryExtended) => query.timeRangeCompare !== false);\n if (targets.length) {\n extraQueries.push({\n req: {\n ...request,\n targets,\n range: compareRange,\n },\n processor: timeShiftAlignmentProcessor,\n });\n }\n return extraQueries;\n }\n\n // The query runner should rerun the comparison query if the compareWith value has changed and there are queries that haven't opted out of TWC\n public shouldRerun(\n prev: SceneTimeRangeCompareState,\n next: SceneTimeRangeCompareState,\n queries: SceneDataQuery[]\n ): boolean {\n return (\n prev.compareWith !== next.compareWith && queries.find((query) => query.timeRangeCompare !== false) !== undefined\n );\n }\n\n public getCompareTimeRange(timeRange: TimeRange): TimeRange | undefined {\n let compareFrom: DateTime;\n let compareTo: DateTime;\n\n if (this.state.compareWith) {\n if (this.state.compareWith === PREVIOUS_PERIOD_VALUE) {\n const diffMs = timeRange.to.diff(timeRange.from);\n compareFrom = dateTime(timeRange.from!).subtract(diffMs);\n compareTo = dateTime(timeRange.to!).subtract(diffMs);\n } else {\n compareFrom = dateTime(timeRange.from!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n compareTo = dateTime(timeRange.to!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n }\n return {\n from: compareFrom,\n to: compareTo,\n raw: {\n from: compareFrom,\n to: compareTo,\n },\n };\n }\n\n return undefined;\n }\n\n public getUrlState(): SceneObjectUrlValues {\n return {\n compareWith: this.state.compareWith,\n };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n if (!values.compareWith) {\n return;\n }\n\n const compareWith = parseUrlParam(values.compareWith);\n\n if (compareWith) {\n const compareOptions = this.getCompareOptions(sceneGraph.getTimeRange(this).state.value);\n\n if (compareOptions.find(({ value }) => value === compareWith)) {\n this.setState({\n compareWith,\n });\n } else {\n this.setState({\n compareWith: '__previousPeriod',\n });\n }\n }\n }\n}\n\n// Processor function for use with time shifted comparison series.\n// This aligns the secondary series with the primary and adds custom\n// metadata and config to the secondary series' fields so that it is\n// rendered appropriately.\nconst timeShiftAlignmentProcessor: ExtraQueryDataProcessor = (primary, secondary) => {\n const diff = secondary.timeRange.from.diff(primary.timeRange.from);\n secondary.series.forEach((series) => {\n series.refId = getCompareSeriesRefId(series.refId || '');\n series.meta = {\n ...series.meta,\n // @ts-ignore Remove when https://github.com/grafana/grafana/pull/71129 is released\n timeCompare: {\n diffMs: diff,\n isTimeShiftQuery: true,\n },\n };\n series.fields.forEach((field) => {\n // Align compare series time stamps with reference series\n if (field.type === FieldType.time) {\n field.values = field.values.map((v) => {\n return diff < 0 ? v - diff : v + diff;\n });\n }\n\n field.config = {\n ...field.config,\n color: {\n mode: 'fixed',\n fixedColor: config.theme.palette.gray60,\n },\n };\n return field;\n });\n });\n return of(secondary);\n};\n\nfunction SceneTimeRangeCompareRenderer({ model }: SceneComponentProps<SceneTimeRangeCompare>) {\n const styles = useStyles2(getStyles);\n const { compareWith, compareOptions } = model.useState();\n\n const [previousCompare, setPreviousCompare] = React.useState(compareWith);\n const previousValue = compareOptions.find(({ value }) => value === previousCompare) ?? PREVIOUS_PERIOD_COMPARE_OPTION;\n\n const value = compareOptions.find(({ value }) => value === compareWith);\n const enabled = Boolean(value);\n\n const onClick = () => {\n if (enabled) {\n setPreviousCompare(compareWith);\n model.onClearCompare();\n } else if (!enabled) {\n model.onCompareWithChanged(previousValue.value);\n }\n };\n\n return (\n <ButtonGroup>\n <ToolbarButton\n variant=\"canvas\"\n tooltip={t(\n 'grafana-scenes.components.scene-time-range-compare-renderer.button-tooltip',\n 'Enable time frame comparison'\n )}\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onClick();\n }}\n >\n <Checkbox label=\" \" value={enabled} onClick={onClick} />\n <Trans i18nKey=\"grafana-scenes.components.scene-time-range-compare-renderer.button-label\">Comparison</Trans>\n </ToolbarButton>\n\n {enabled ? (\n <ButtonSelect\n variant=\"canvas\"\n value={value}\n options={compareOptions}\n onChange={(v) => {\n model.onCompareWithChanged(v.value!);\n }}\n />\n ) : (\n <ToolbarButton className={styles.previewButton} disabled variant=\"canvas\" isOpen={false}>\n {previousValue.label}\n </ToolbarButton>\n )}\n </ButtonGroup>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n previewButton: css({\n '&:disabled': {\n border: `1px solid ${theme.colors.secondary.border}`,\n color: theme.colors.text.disabled,\n opacity: 1,\n },\n }),\n };\n}\n"],"names":["value"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"SceneTimeRangeCompare.js","sources":["../../../src/components/SceneTimeRangeCompare.tsx"],"sourcesContent":["import { DataQueryRequest, DateTime, dateTime, FieldType, GrafanaTheme2, rangeUtil, TimeRange } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { ButtonGroup, ButtonSelect, Checkbox, ToolbarButton, useStyles2 } from '@grafana/ui';\nimport React from 'react';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { SceneComponentProps, SceneDataQuery, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { DataQueryExtended } from '../querying/SceneQueryRunner';\nimport { ExtraQueryDescriptor, ExtraQueryDataProcessor, ExtraQueryProvider } from '../querying/ExtraQueryProvider';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\nimport { getCompareSeriesRefId } from '../utils/getCompareSeriesRefId';\nimport { parseUrlParam } from '../utils/parseUrlParam';\nimport { css } from '@emotion/css';\nimport { of } from 'rxjs';\n\ninterface SceneTimeRangeCompareState extends SceneObjectState {\n compareWith?: string;\n compareOptions: Array<{ label: string; value: string }>;\n}\n\nconst PREVIOUS_PERIOD_VALUE = '__previousPeriod';\nconst NO_PERIOD_VALUE = '__noPeriod';\n\nexport const PREVIOUS_PERIOD_COMPARE_OPTION = {\n label: 'Previous period',\n value: PREVIOUS_PERIOD_VALUE,\n};\n\nexport const NO_COMPARE_OPTION = {\n label: 'No comparison',\n value: NO_PERIOD_VALUE,\n};\n\nexport const DEFAULT_COMPARE_OPTIONS = [\n { label: 'Day before', value: '24h' },\n { label: 'Week before', value: '1w' },\n { label: 'Month before', value: '1M' },\n];\n\nexport class SceneTimeRangeCompare\n extends SceneObjectBase<SceneTimeRangeCompareState>\n implements ExtraQueryProvider<SceneTimeRangeCompareState>\n{\n static Component = SceneTimeRangeCompareRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['compareWith'] });\n\n public constructor(state: Partial<SceneTimeRangeCompareState>) {\n super({ compareOptions: DEFAULT_COMPARE_OPTIONS, ...state });\n this.addActivationHandler(this._onActivate);\n }\n\n private _onActivate = () => {\n const sceneTimeRange = sceneGraph.getTimeRange(this);\n this.setState({ compareOptions: this.getCompareOptions(sceneTimeRange.state.value) });\n\n this._subs.add(\n sceneTimeRange.subscribeToState((timeRange) => {\n const compareOptions = this.getCompareOptions(timeRange.value);\n const stateUpdate: Partial<SceneTimeRangeCompareState> = { compareOptions };\n\n // if current compareWith is not applicable to the new time range, set it to previous period comparison\n if (Boolean(this.state.compareWith) && !compareOptions.find(({ value }) => value === this.state.compareWith)) {\n stateUpdate.compareWith = PREVIOUS_PERIOD_VALUE;\n }\n\n this.setState(stateUpdate);\n })\n );\n };\n\n public getCompareOptions = (timeRange: TimeRange) => {\n const diffDays = Math.ceil(timeRange.to.diff(timeRange.from));\n\n const matchIndex = DEFAULT_COMPARE_OPTIONS.findIndex(({ value }) => {\n const intervalInMs = rangeUtil.intervalToMs(value);\n return intervalInMs >= diffDays;\n });\n\n return [\n NO_COMPARE_OPTION,\n PREVIOUS_PERIOD_COMPARE_OPTION,\n ...DEFAULT_COMPARE_OPTIONS.slice(matchIndex).map(({ label, value }) => ({ label, value })),\n ];\n };\n\n public onCompareWithChanged = (compareWith: string) => {\n if (compareWith === NO_PERIOD_VALUE) {\n this.onClearCompare();\n } else {\n this.setState({ compareWith });\n }\n };\n\n public onClearCompare = () => {\n this.setState({ compareWith: undefined });\n };\n\n // Get a time shifted request to compare with the primary request.\n public getExtraQueries(request: DataQueryRequest): ExtraQueryDescriptor[] {\n const extraQueries: ExtraQueryDescriptor[] = [];\n const compareRange = this.getCompareTimeRange(request.range);\n if (!compareRange) {\n return extraQueries;\n }\n\n const targets = request.targets.filter((query: DataQueryExtended) => query.timeRangeCompare !== false);\n if (targets.length) {\n extraQueries.push({\n req: {\n ...request,\n targets,\n range: compareRange,\n },\n processor: timeShiftAlignmentProcessor,\n });\n }\n return extraQueries;\n }\n\n // The query runner should rerun the comparison query if the compareWith value has changed and there are queries that haven't opted out of TWC\n public shouldRerun(\n prev: SceneTimeRangeCompareState,\n next: SceneTimeRangeCompareState,\n queries: SceneDataQuery[]\n ): boolean {\n return (\n prev.compareWith !== next.compareWith && queries.find((query) => query.timeRangeCompare !== false) !== undefined\n );\n }\n\n public getCompareTimeRange(timeRange: TimeRange): TimeRange | undefined {\n let compareFrom: DateTime;\n let compareTo: DateTime;\n\n if (this.state.compareWith) {\n if (this.state.compareWith === PREVIOUS_PERIOD_VALUE) {\n const diffMs = timeRange.to.diff(timeRange.from);\n compareFrom = dateTime(timeRange.from!).subtract(diffMs);\n compareTo = dateTime(timeRange.to!).subtract(diffMs);\n } else {\n compareFrom = dateTime(timeRange.from!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n compareTo = dateTime(timeRange.to!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n }\n return {\n from: compareFrom,\n to: compareTo,\n raw: {\n from: compareFrom,\n to: compareTo,\n },\n };\n }\n\n return undefined;\n }\n\n public getUrlState(): SceneObjectUrlValues {\n return {\n compareWith: this.state.compareWith,\n };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n if (!values.compareWith) {\n return;\n }\n\n const compareWith = parseUrlParam(values.compareWith);\n\n if (compareWith) {\n const compareOptions = this.getCompareOptions(sceneGraph.getTimeRange(this).state.value);\n\n if (compareOptions.find(({ value }) => value === compareWith)) {\n this.setState({\n compareWith,\n });\n } else {\n this.setState({\n compareWith: '__previousPeriod',\n });\n }\n }\n }\n}\n\n// Processor function for use with time shifted comparison series.\n// This aligns the secondary series with the primary and adds custom\n// metadata and config to the secondary series' fields so that it is\n// rendered appropriately.\nconst timeShiftAlignmentProcessor: ExtraQueryDataProcessor = (primary, secondary) => {\n const diff = secondary.timeRange.from.diff(primary.timeRange.from);\n secondary.series.forEach((series) => {\n series.refId = getCompareSeriesRefId(series.refId || '');\n series.meta = {\n ...series.meta,\n // @ts-ignore Remove when https://github.com/grafana/grafana/pull/71129 is released\n timeCompare: {\n diffMs: diff,\n isTimeShiftQuery: true,\n },\n };\n series.fields.forEach((field) => {\n // Align compare series time stamps with reference series\n if (field.type === FieldType.time) {\n field.values = field.values.map((v) => {\n return diff < 0 ? v - diff : v + diff;\n });\n }\n\n field.config = {\n ...field.config,\n color: {\n mode: 'fixed',\n fixedColor: config.theme.palette.gray60,\n },\n };\n return field;\n });\n });\n return of(secondary);\n};\n\nfunction SceneTimeRangeCompareRenderer({ model }: SceneComponentProps<SceneTimeRangeCompare>) {\n const styles = useStyles2(getStyles);\n const { compareWith, compareOptions } = model.useState();\n\n const [previousCompare, setPreviousCompare] = React.useState(compareWith);\n const previousValue = compareOptions.find(({ value }) => value === previousCompare) ?? PREVIOUS_PERIOD_COMPARE_OPTION;\n\n const value = compareOptions.find(({ value }) => value === compareWith);\n const enabled = Boolean(value);\n\n const onClick = () => {\n if (enabled) {\n setPreviousCompare(compareWith);\n model.onClearCompare();\n } else if (!enabled) {\n model.onCompareWithChanged(previousValue.value);\n }\n };\n\n return (\n <ButtonGroup>\n <ToolbarButton\n variant=\"canvas\"\n tooltip=\"Enable time frame comparison\"\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onClick();\n }}\n >\n <Checkbox label=\" \" value={enabled} onClick={onClick} />\n Comparison\n </ToolbarButton>\n\n {enabled ? (\n <ButtonSelect\n variant=\"canvas\"\n value={value}\n options={compareOptions}\n onChange={(v) => {\n model.onCompareWithChanged(v.value!);\n }}\n />\n ) : (\n <ToolbarButton className={styles.previewButton} disabled variant=\"canvas\" isOpen={false}>\n {previousValue.label}\n </ToolbarButton>\n )}\n </ButtonGroup>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n previewButton: css({\n '&:disabled': {\n border: `1px solid ${theme.colors.secondary.border}`,\n color: theme.colors.text.disabled,\n opacity: 1,\n },\n }),\n };\n}\n"],"names":["value"],"mappings":";;;;;;;;;;;;AAoBA,MAAM,qBAAwB,GAAA,kBAAA;AAC9B,MAAM,eAAkB,GAAA,YAAA;AAEjB,MAAM,8BAAiC,GAAA;AAAA,EAC5C,KAAO,EAAA,iBAAA;AAAA,EACP,KAAO,EAAA;AACT;AAEO,MAAM,iBAAoB,GAAA;AAAA,EAC/B,KAAO,EAAA,eAAA;AAAA,EACP,KAAO,EAAA;AACT;AAEO,MAAM,uBAA0B,GAAA;AAAA,EACrC,EAAE,KAAA,EAAO,YAAc,EAAA,KAAA,EAAO,KAAM,EAAA;AAAA,EACpC,EAAE,KAAA,EAAO,aAAe,EAAA,KAAA,EAAO,IAAK,EAAA;AAAA,EACpC,EAAE,KAAA,EAAO,cAAgB,EAAA,KAAA,EAAO,IAAK;AACvC;AAEO,MAAM,8BACH,eAEV,CAAA;AAAA,EAIS,YAAY,KAA4C,EAAA;AAC7D,IAAA,KAAA,CAAM,EAAE,cAAA,EAAgB,uBAAyB,EAAA,GAAG,OAAO,CAAA;AAH7D,IAAU,IAAA,CAAA,QAAA,GAAW,IAAI,wBAAyB,CAAA,IAAA,EAAM,EAAE,IAAM,EAAA,CAAC,aAAa,CAAA,EAAG,CAAA;AAOjF,IAAA,IAAA,CAAQ,cAAc,MAAM;AAC1B,MAAM,MAAA,cAAA,GAAiB,UAAW,CAAA,YAAA,CAAa,IAAI,CAAA;AACnD,MAAK,IAAA,CAAA,QAAA,CAAS,EAAE,cAAgB,EAAA,IAAA,CAAK,kBAAkB,cAAe,CAAA,KAAA,CAAM,KAAK,CAAA,EAAG,CAAA;AAEpF,MAAA,IAAA,CAAK,KAAM,CAAA,GAAA;AAAA,QACT,cAAA,CAAe,gBAAiB,CAAA,CAAC,SAAc,KAAA;AAC7C,UAAA,MAAM,cAAiB,GAAA,IAAA,CAAK,iBAAkB,CAAA,SAAA,CAAU,KAAK,CAAA;AAC7D,UAAM,MAAA,WAAA,GAAmD,EAAE,cAAe,EAAA;AAG1E,UAAA,IAAI,QAAQ,IAAK,CAAA,KAAA,CAAM,WAAW,CAAA,IAAK,CAAC,cAAe,CAAA,IAAA,CAAK,CAAC,EAAE,OAAY,KAAA,KAAA,KAAU,IAAK,CAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AAC5G,YAAA,WAAA,CAAY,WAAc,GAAA,qBAAA;AAAA;AAG5B,UAAA,IAAA,CAAK,SAAS,WAAW,CAAA;AAAA,SAC1B;AAAA,OACH;AAAA,KACF;AAEA,IAAO,IAAA,CAAA,iBAAA,GAAoB,CAAC,SAAyB,KAAA;AACnD,MAAM,MAAA,QAAA,GAAW,KAAK,IAAK,CAAA,SAAA,CAAU,GAAG,IAAK,CAAA,SAAA,CAAU,IAAI,CAAC,CAAA;AAE5D,MAAA,MAAM,aAAa,uBAAwB,CAAA,SAAA,CAAU,CAAC,EAAE,OAAY,KAAA;AAClE,QAAM,MAAA,YAAA,GAAe,SAAU,CAAA,YAAA,CAAa,KAAK,CAAA;AACjD,QAAA,OAAO,YAAgB,IAAA,QAAA;AAAA,OACxB,CAAA;AAED,MAAO,OAAA;AAAA,QACL,iBAAA;AAAA,QACA,8BAAA;AAAA,QACA,GAAG,uBAAA,CAAwB,KAAM,CAAA,UAAU,EAAE,GAAI,CAAA,CAAC,EAAE,KAAA,EAAO,KAAM,EAAA,MAAO,EAAE,KAAA,EAAO,OAAQ,CAAA;AAAA,OAC3F;AAAA,KACF;AAEA,IAAO,IAAA,CAAA,oBAAA,GAAuB,CAAC,WAAwB,KAAA;AACrD,MAAA,IAAI,gBAAgB,eAAiB,EAAA;AACnC,QAAA,IAAA,CAAK,cAAe,EAAA;AAAA,OACf,MAAA;AACL,QAAK,IAAA,CAAA,QAAA,CAAS,EAAE,WAAA,EAAa,CAAA;AAAA;AAC/B,KACF;AAEA,IAAA,IAAA,CAAO,iBAAiB,MAAM;AAC5B,MAAA,IAAA,CAAK,QAAS,CAAA,EAAE,WAAa,EAAA,MAAA,EAAW,CAAA;AAAA,KAC1C;AA/CE,IAAK,IAAA,CAAA,oBAAA,CAAqB,KAAK,WAAW,CAAA;AAAA;AAC5C;AAAA,EAiDO,gBAAgB,OAAmD,EAAA;AACxE,IAAA,MAAM,eAAuC,EAAC;AAC9C,IAAA,MAAM,YAAe,GAAA,IAAA,CAAK,mBAAoB,CAAA,OAAA,CAAQ,KAAK,CAAA;AAC3D,IAAA,IAAI,CAAC,YAAc,EAAA;AACjB,MAAO,OAAA,YAAA;AAAA;AAGT,IAAM,MAAA,OAAA,GAAU,QAAQ,OAAQ,CAAA,MAAA,CAAO,CAAC,KAA6B,KAAA,KAAA,CAAM,qBAAqB,KAAK,CAAA;AACrG,IAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,MAAA,YAAA,CAAa,IAAK,CAAA;AAAA,QAChB,GAAK,EAAA;AAAA,UACH,GAAG,OAAA;AAAA,UACH,OAAA;AAAA,UACA,KAAO,EAAA;AAAA,SACT;AAAA,QACA,SAAW,EAAA;AAAA,OACZ,CAAA;AAAA;AAEH,IAAO,OAAA,YAAA;AAAA;AACT;AAAA,EAGO,WAAA,CACL,IACA,EAAA,IAAA,EACA,OACS,EAAA;AACT,IACE,OAAA,IAAA,CAAK,WAAgB,KAAA,IAAA,CAAK,WAAe,IAAA,OAAA,CAAQ,IAAK,CAAA,CAAC,KAAU,KAAA,KAAA,CAAM,gBAAqB,KAAA,KAAK,CAAM,KAAA,MAAA;AAAA;AAE3G,EAEO,oBAAoB,SAA6C,EAAA;AACtE,IAAI,IAAA,WAAA;AACJ,IAAI,IAAA,SAAA;AAEJ,IAAI,IAAA,IAAA,CAAK,MAAM,WAAa,EAAA;AAC1B,MAAI,IAAA,IAAA,CAAK,KAAM,CAAA,WAAA,KAAgB,qBAAuB,EAAA;AACpD,QAAA,MAAM,MAAS,GAAA,SAAA,CAAU,EAAG,CAAA,IAAA,CAAK,UAAU,IAAI,CAAA;AAC/C,QAAA,WAAA,GAAc,QAAS,CAAA,SAAA,CAAU,IAAK,CAAA,CAAE,SAAS,MAAM,CAAA;AACvD,QAAA,SAAA,GAAY,QAAS,CAAA,SAAA,CAAU,EAAG,CAAA,CAAE,SAAS,MAAM,CAAA;AAAA,OAC9C,MAAA;AACL,QAAc,WAAA,GAAA,QAAA,CAAS,SAAU,CAAA,IAAK,CAAE,CAAA,QAAA,CAAS,UAAU,YAAa,CAAA,IAAA,CAAK,KAAM,CAAA,WAAW,CAAC,CAAA;AAC/F,QAAY,SAAA,GAAA,QAAA,CAAS,SAAU,CAAA,EAAG,CAAE,CAAA,QAAA,CAAS,UAAU,YAAa,CAAA,IAAA,CAAK,KAAM,CAAA,WAAW,CAAC,CAAA;AAAA;AAE7F,MAAO,OAAA;AAAA,QACL,IAAM,EAAA,WAAA;AAAA,QACN,EAAI,EAAA,SAAA;AAAA,QACJ,GAAK,EAAA;AAAA,UACH,IAAM,EAAA,WAAA;AAAA,UACN,EAAI,EAAA;AAAA;AACN,OACF;AAAA;AAGF,IAAO,OAAA,MAAA;AAAA;AACT,EAEO,WAAoC,GAAA;AACzC,IAAO,OAAA;AAAA,MACL,WAAA,EAAa,KAAK,KAAM,CAAA;AAAA,KAC1B;AAAA;AACF,EAEO,cAAc,MAA8B,EAAA;AACjD,IAAI,IAAA,CAAC,OAAO,WAAa,EAAA;AACvB,MAAA;AAAA;AAGF,IAAM,MAAA,WAAA,GAAc,aAAc,CAAA,MAAA,CAAO,WAAW,CAAA;AAEpD,IAAA,IAAI,WAAa,EAAA;AACf,MAAM,MAAA,cAAA,GAAiB,KAAK,iBAAkB,CAAA,UAAA,CAAW,aAAa,IAAI,CAAA,CAAE,MAAM,KAAK,CAAA;AAEvF,MAAI,IAAA,cAAA,CAAe,KAAK,CAAC,EAAE,OAAY,KAAA,KAAA,KAAU,WAAW,CAAG,EAAA;AAC7D,QAAA,IAAA,CAAK,QAAS,CAAA;AAAA,UACZ;AAAA,SACD,CAAA;AAAA,OACI,MAAA;AACL,QAAA,IAAA,CAAK,QAAS,CAAA;AAAA,UACZ,WAAa,EAAA;AAAA,SACd,CAAA;AAAA;AACH;AACF;AAEJ;AAhJa,qBAAA,CAIJ,SAAY,GAAA,6BAAA;AAkJrB,MAAM,2BAAA,GAAuD,CAAC,OAAA,EAAS,SAAc,KAAA;AACnF,EAAA,MAAM,OAAO,SAAU,CAAA,SAAA,CAAU,KAAK,IAAK,CAAA,OAAA,CAAQ,UAAU,IAAI,CAAA;AACjE,EAAU,SAAA,CAAA,MAAA,CAAO,OAAQ,CAAA,CAAC,MAAW,KAAA;AACnC,IAAA,MAAA,CAAO,KAAQ,GAAA,qBAAA,CAAsB,MAAO,CAAA,KAAA,IAAS,EAAE,CAAA;AACvD,IAAA,MAAA,CAAO,IAAO,GAAA;AAAA,MACZ,GAAG,MAAO,CAAA,IAAA;AAAA;AAAA,MAEV,WAAa,EAAA;AAAA,QACX,MAAQ,EAAA,IAAA;AAAA,QACR,gBAAkB,EAAA;AAAA;AACpB,KACF;AACA,IAAO,MAAA,CAAA,MAAA,CAAO,OAAQ,CAAA,CAAC,KAAU,KAAA;AAE/B,MAAI,IAAA,KAAA,CAAM,IAAS,KAAA,SAAA,CAAU,IAAM,EAAA;AACjC,QAAA,KAAA,CAAM,MAAS,GAAA,KAAA,CAAM,MAAO,CAAA,GAAA,CAAI,CAAC,CAAM,KAAA;AACrC,UAAA,OAAO,IAAO,GAAA,CAAA,GAAI,CAAI,GAAA,IAAA,GAAO,CAAI,GAAA,IAAA;AAAA,SAClC,CAAA;AAAA;AAGH,MAAA,KAAA,CAAM,MAAS,GAAA;AAAA,QACb,GAAG,KAAM,CAAA,MAAA;AAAA,QACT,KAAO,EAAA;AAAA,UACL,IAAM,EAAA,OAAA;AAAA,UACN,UAAA,EAAY,MAAO,CAAA,KAAA,CAAM,OAAQ,CAAA;AAAA;AACnC,OACF;AACA,MAAO,OAAA,KAAA;AAAA,KACR,CAAA;AAAA,GACF,CAAA;AACD,EAAA,OAAO,GAAG,SAAS,CAAA;AACrB,CAAA;AAEA,SAAS,6BAAA,CAA8B,EAAE,KAAA,EAAqD,EAAA;AA9N9F,EAAA,IAAA,EAAA;AA+NE,EAAM,MAAA,MAAA,GAAS,WAAW,SAAS,CAAA;AACnC,EAAA,MAAM,EAAE,WAAA,EAAa,cAAe,EAAA,GAAI,MAAM,QAAS,EAAA;AAEvD,EAAA,MAAM,CAAC,eAAiB,EAAA,kBAAkB,CAAI,GAAA,KAAA,CAAM,SAAS,WAAW,CAAA;AACxE,EAAM,MAAA,aAAA,GAAA,CAAgB,EAAe,GAAA,cAAA,CAAA,IAAA,CAAK,CAAC,EAAE,KAAAA,EAAAA,MAAAA,EAAYA,KAAAA,MAAAA,KAAU,eAAe,CAAA,KAA5D,IAAiE,GAAA,EAAA,GAAA,8BAAA;AAEvF,EAAM,MAAA,KAAA,GAAQ,eAAe,IAAK,CAAA,CAAC,EAAE,KAAAA,EAAAA,MAAAA,EAAYA,KAAAA,MAAAA,KAAU,WAAW,CAAA;AACtE,EAAM,MAAA,OAAA,GAAU,QAAQ,KAAK,CAAA;AAE7B,EAAA,MAAM,UAAU,MAAM;AACpB,IAAA,IAAI,OAAS,EAAA;AACX,MAAA,kBAAA,CAAmB,WAAW,CAAA;AAC9B,MAAA,KAAA,CAAM,cAAe,EAAA;AAAA,KACvB,MAAA,IAAW,CAAC,OAAS,EAAA;AACnB,MAAM,KAAA,CAAA,oBAAA,CAAqB,cAAc,KAAK,CAAA;AAAA;AAChD,GACF;AAEA,EAAA,2CACG,WACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,QAAA;AAAA,MACR,OAAQ,EAAA,8BAAA;AAAA,MACR,OAAA,EAAS,CAAC,CAAM,KAAA;AACd,QAAA,CAAA,CAAE,eAAgB,EAAA;AAClB,QAAA,CAAA,CAAE,cAAe,EAAA;AACjB,QAAQ,OAAA,EAAA;AAAA;AACV,KAAA;AAAA,wCAEC,QAAS,EAAA,EAAA,KAAA,EAAM,GAAI,EAAA,KAAA,EAAO,SAAS,OAAkB,EAAA,CAAA;AAAA,IAAE;AAAA,KAIzD,OACC,mBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,QAAA;AAAA,MACR,KAAA;AAAA,MACA,OAAS,EAAA,cAAA;AAAA,MACT,QAAA,EAAU,CAAC,CAAM,KAAA;AACf,QAAM,KAAA,CAAA,oBAAA,CAAqB,EAAE,KAAM,CAAA;AAAA;AACrC;AAAA,GAGF,mBAAA,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,EAAA,SAAA,EAAW,OAAO,aAAe,EAAA,QAAA,EAAQ,IAAC,EAAA,OAAA,EAAQ,QAAS,EAAA,MAAA,EAAQ,KAC/E,EAAA,EAAA,aAAA,CAAc,KACjB,CAEJ,CAAA;AAEJ;AAEA,SAAS,UAAU,KAAsB,EAAA;AACvC,EAAO,OAAA;AAAA,IACL,eAAe,GAAI,CAAA;AAAA,MACjB,YAAc,EAAA;AAAA,QACZ,MAAQ,EAAA,CAAA,UAAA,EAAa,KAAM,CAAA,MAAA,CAAO,UAAU,MAAM,CAAA,CAAA;AAAA,QAClD,KAAA,EAAO,KAAM,CAAA,MAAA,CAAO,IAAK,CAAA,QAAA;AAAA,QACzB,OAAS,EAAA;AAAA;AACX,KACD;AAAA,GACH;AACF;;;;"}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { t } from '@grafana/i18n';
|
2
1
|
import { toUtc, getPanelOptionsWithDefaults, renderMarkdown, applyFieldOverrides, compareArrayValues, compareDataFrameStructures, CoreApp, DashboardCursorSync, PanelPlugin, PluginType } from '@grafana/data';
|
3
2
|
import { getPluginImportUtils, config, getAppEvents } from '@grafana/runtime';
|
4
3
|
import { SceneObjectBase } from '../../core/SceneObjectBase.js';
|
@@ -22,7 +21,7 @@ class VizPanel extends SceneObjectBase {
|
|
22
21
|
super({
|
23
22
|
options: {},
|
24
23
|
fieldConfig: { defaults: {}, overrides: [] },
|
25
|
-
title:
|
24
|
+
title: "Title",
|
26
25
|
pluginId: "timeseries",
|
27
26
|
_renderCounter: 0,
|
28
27
|
...state
|