Dashboard: Fixes outline for repeated rows (#104283)

* Dashboard: Fixes outline for repeated rows

* Update

* make i18n-extract

---------

Co-authored-by: oscarkilhed <oscar.kilhed@grafana.com>
This commit is contained in:
Torkel Ödegaard
2025-04-23 10:10:09 +01:00
committed by GitHub
co-authored by oscarkilhed
parent f932bf7f36
commit 85a0a47efc
6 changed files with 147 additions and 8 deletions
@@ -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);
}
@@ -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 (
<Box paddingBottom={1}>
<Stack>
<Stack>
<span>${variable.state.name}</span>
<span>=</span>
<span>{variable.getValueText()}</span>
</Stack>
</Stack>
</Box>
);
},
})
);
return [category];
}, [variable]);
}
}
@@ -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) {
</Box>
);
}
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 (
<Box paddingBottom={1}>
<Stack>
<Stack>
<span>${variable.state.name}</span>
<span>=</span>
<span>{variable.getValueText()}</span>
</Stack>
</Stack>
</Box>
);
},
})
);
return [category];
}, [variable]);
}
@@ -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 }) {
</Stack>
</div>
))}
<Box paddingBottom={1} display={'flex'}>
<Button fullWidth icon="plus" size="sm" variant="secondary" onClick={setIsAdding}>
<Trans i18nKey="dashboard.edit-pane.variables.add-variable">Add variable</Trans>
</Button>
</Box>
{canAdd && (
<Box paddingBottom={1} display={'flex'}>
<Button fullWidth icon="plus" size="sm" variant="secondary" onClick={setIsAdding}>
<Trans i18nKey="dashboard.edit-pane.variables.add-variable">Add variable</Trans>
</Button>
</Box>
)}
</Stack>
);
}
@@ -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 (
<Stack direction="column">
<Stack>
<Stack>
<span>${variable.state.name}</span>
<span>=</span>
<span>${variable.getValueText()}</span>
</Stack>
</Stack>
</Stack>
);
},
}),
];
}
+1
View File
@@ -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",