diff --git a/public/app/features/dashboard-scene/edit-pane/shared.ts b/public/app/features/dashboard-scene/edit-pane/shared.ts
index a53b35208b6..dac06f09cdd 100644
--- a/public/app/features/dashboard-scene/edit-pane/shared.ts
+++ b/public/app/features/dashboard-scene/edit-pane/shared.ts
@@ -1,11 +1,12 @@
import { useSessionStorage } from 'react-use';
import { BusEventWithPayload } from '@grafana/data';
-import { SceneGridRow, SceneObject, SceneVariableSet, VizPanel } from '@grafana/scenes';
+import { LocalValueVariable, SceneGridRow, SceneObject, SceneVariableSet, VizPanel } from '@grafana/scenes';
import { DashboardScene } from '../scene/DashboardScene';
import { SceneGridRowEditableElement } from '../scene/layout-default/SceneGridRowEditableElement';
import { EditableDashboardElement, isEditableDashboardElement } from '../scene/types/EditableDashboardElement';
+import { LocalVariableEditableElement } from '../settings/variables/LocalVariableEditableElement';
import { VariableEditableElement } from '../settings/variables/VariableEditableElement';
import { VariableSetEditableElement } from '../settings/variables/VariableSetEditableElement';
import { isSceneVariable } from '../settings/variables/utils';
@@ -42,6 +43,10 @@ export function getEditableElementFor(sceneObj: SceneObject | undefined): Editab
return new VariableSetEditableElement(sceneObj);
}
+ if (sceneObj instanceof LocalValueVariable) {
+ return new LocalVariableEditableElement(sceneObj);
+ }
+
if (isSceneVariable(sceneObj)) {
return new VariableEditableElement(sceneObj);
}
diff --git a/public/app/features/dashboard-scene/settings/variables/LocalVariableEditableElement.tsx b/public/app/features/dashboard-scene/settings/variables/LocalVariableEditableElement.tsx
new file mode 100644
index 00000000000..d5bb9103893
--- /dev/null
+++ b/public/app/features/dashboard-scene/settings/variables/LocalVariableEditableElement.tsx
@@ -0,0 +1,57 @@
+import { useMemo } from 'react';
+
+import { LocalValueVariable } from '@grafana/scenes';
+import { Box, Stack } from '@grafana/ui';
+import { t } from 'app/core/internationalization';
+import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
+import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
+
+import { EditableDashboardElement, EditableDashboardElementInfo } from '../../scene/types/EditableDashboardElement';
+
+export class LocalVariableEditableElement implements EditableDashboardElement {
+ public readonly isEditableDashboardElement = true;
+
+ public constructor(public variable: LocalValueVariable) {}
+
+ public getEditableElementInfo(): EditableDashboardElementInfo {
+ return {
+ typeName: t('dashboard.edit-pane.elements.local-variable', 'Local variable'),
+ icon: 'dollar-alt',
+ instanceName: ` $${this.variable.state.name} = ${this.variable.getValueText!()}`,
+ isHidden: true,
+ };
+ }
+
+ public useEditPaneOptions(): OptionsPaneCategoryDescriptor[] {
+ const variable = this.variable;
+
+ return useMemo(() => {
+ const category = new OptionsPaneCategoryDescriptor({
+ title: '',
+ id: 'local-variable-options',
+ });
+
+ category.addItem(
+ new OptionsPaneItemDescriptor({
+ title: '',
+ skipField: true,
+ render: () => {
+ return (
+
+
+
+ ${variable.state.name}
+ =
+ {variable.getValueText()}
+
+
+
+ );
+ },
+ })
+ );
+
+ return [category];
+ }, [variable]);
+ }
+}
diff --git a/public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx b/public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx
index b8d2ee6f281..213557fc8c4 100644
--- a/public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx
+++ b/public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx
@@ -2,8 +2,8 @@ import { FormEvent, useMemo, useState } from 'react';
import { VariableHide } from '@grafana/data';
import { locationService } from '@grafana/runtime';
-import { MultiValueVariable, SceneVariable, SceneVariableSet } from '@grafana/scenes';
-import { Input, TextArea, Button, Field, Box } from '@grafana/ui';
+import { LocalValueVariable, MultiValueVariable, SceneVariable, SceneVariableSet } from '@grafana/scenes';
+import { Input, TextArea, Button, Field, Box, Stack } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
@@ -24,6 +24,15 @@ export class VariableEditableElement implements EditableDashboardElement, BulkAc
public constructor(public variable: SceneVariable) {}
public getEditableElementInfo(): EditableDashboardElementInfo {
+ if (this.variable instanceof LocalValueVariable) {
+ return {
+ typeName: t('dashboard.edit-pane.elements.local-variable', 'Local variable'),
+ icon: 'dollar-alt',
+ instanceName: this.variable.state.name,
+ isHidden: true,
+ };
+ }
+
const variableEditorDef = getEditableVariableDefinition(this.variable.state.type);
return {
@@ -37,6 +46,10 @@ export class VariableEditableElement implements EditableDashboardElement, BulkAc
public useEditPaneOptions(isNewElement: boolean): OptionsPaneCategoryDescriptor[] {
const variable = this.variable;
+ if (variable instanceof LocalValueVariable) {
+ return useLocalVariableOptions(variable);
+ }
+
const basicOptions = useMemo(() => {
return new OptionsPaneCategoryDescriptor({ title: '', id: 'variable-options' })
.addItem(
@@ -220,3 +233,34 @@ function OpenOldVariableEditButton({ variable }: VariableInputProps) {
);
}
+
+function useLocalVariableOptions(variable: LocalValueVariable): OptionsPaneCategoryDescriptor[] {
+ return useMemo(() => {
+ const category = new OptionsPaneCategoryDescriptor({
+ title: '',
+ id: 'local-variable-options',
+ });
+
+ category.addItem(
+ new OptionsPaneItemDescriptor({
+ title: '',
+ skipField: true,
+ render: () => {
+ return (
+
+
+
+ ${variable.state.name}
+ =
+ {variable.getValueText()}
+
+
+
+ );
+ },
+ })
+ );
+
+ return [category];
+ }, [variable]);
+}
diff --git a/public/app/features/dashboard-scene/settings/variables/VariableSetEditableElement.tsx b/public/app/features/dashboard-scene/settings/variables/VariableSetEditableElement.tsx
index a1e4047901f..442f7c58b47 100644
--- a/public/app/features/dashboard-scene/settings/variables/VariableSetEditableElement.tsx
+++ b/public/app/features/dashboard-scene/settings/variables/VariableSetEditableElement.tsx
@@ -10,6 +10,7 @@ import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
import { NewObjectAddedToCanvasEvent } from '../../edit-pane/shared';
+import { DashboardScene } from '../../scene/DashboardScene';
import { EditableDashboardElement, EditableDashboardElementInfo } from '../../scene/types/EditableDashboardElement';
import { getDashboardSceneFor } from '../../utils/utils';
@@ -51,6 +52,7 @@ function VariableList({ set }: { set: SceneVariableSet }) {
const { variables } = set.useState();
const styles = useStyles2(getStyles);
const [isAdding, setIsAdding] = useToggle(false);
+ const canAdd = set.parent instanceof DashboardScene;
const onEditVariable = (variable: SceneVariable) => {
const { editPane } = getDashboardSceneFor(set).state;
@@ -83,11 +85,13 @@ function VariableList({ set }: { set: SceneVariableSet }) {
))}
-
-
-
+ {canAdd && (
+
+
+
+ )}
);
}
diff --git a/public/app/features/dashboard-scene/settings/variables/editors/SystemVariableEditor.tsx b/public/app/features/dashboard-scene/settings/variables/editors/SystemVariableEditor.tsx
new file mode 100644
index 00000000000..d7a55ae5dad
--- /dev/null
+++ b/public/app/features/dashboard-scene/settings/variables/editors/SystemVariableEditor.tsx
@@ -0,0 +1,28 @@
+import { SceneVariable, LocalValueVariable } from '@grafana/scenes';
+import { Stack } from '@grafana/ui';
+import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
+
+export function getSystemVariableOptions(variable: SceneVariable): OptionsPaneItemDescriptor[] {
+ if (!(variable instanceof LocalValueVariable)) {
+ return [];
+ }
+
+ return [
+ new OptionsPaneItemDescriptor({
+ title: '',
+ render: () => {
+ return (
+
+
+
+ ${variable.state.name}
+ =
+ ${variable.getValueText()}
+
+
+
+ );
+ },
+ }),
+ ];
+}
diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json
index 01564808222..f56e7ceb411 100644
--- a/public/locales/en-US/grafana.json
+++ b/public/locales/en-US/grafana.json
@@ -3173,6 +3173,7 @@
"edit-pane": {
"elements": {
"dashboard": "Dashboard",
+ "local-variable": "Local variable",
"multiple-elements": "Multiple elements",
"multiple-elements-delete-text": "Are you sure you want to delete these elements?",
"multiple-panels": "Multiple panels",