Files
grafana/public/app/features/dashboard-scene/conditional-rendering/ConditionalRenderingVariable.tsx
Hugo Häggmark 2b8c74de2e i18n: removes useTranslate hook (#106556)
* i18n: removes useTranslate hook

* chore: fix duplicate imports

* chore: fix import sorting and hook dependencies
2025-06-12 11:03:52 +02:00

141 lines
4.6 KiB
TypeScript

import { useMemo } from 'react';
import { t } from '@grafana/i18n';
import { SceneComponentProps, sceneGraph, VariableDependencyConfig } from '@grafana/scenes';
import { ConditionalRenderingVariableKind } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen';
import { Box, Combobox, ComboboxOption, Input, Stack } from '@grafana/ui';
import { ConditionalRenderingBase, ConditionalRenderingBaseState } from './ConditionalRenderingBase';
import {
ConditionalRenderingSerializerRegistryItem,
VariableConditionValue,
VariableConditionValueOperator,
} from './types';
type ConditionalRenderingVariableState = ConditionalRenderingBaseState<VariableConditionValue>;
export class ConditionalRenderingVariable extends ConditionalRenderingBase<ConditionalRenderingVariableState> {
public static Component = ConditionalRenderingVariableRenderer;
public static serializer: ConditionalRenderingSerializerRegistryItem = {
id: 'ConditionalRenderingVariable',
name: 'Variable',
deserialize: this.deserialize,
};
public get title(): string {
return t('dashboard.conditional-rendering.conditions.variable.label', 'Template variable');
}
public get info(): string {
return t(
'dashboard.conditional-rendering.conditions.variable.info',
'Show or hide the {{type}} dynamically based on the variable value.',
{ type: this.getItemType() }
);
}
protected _variableDependency = new VariableDependencyConfig(this, {
onAnyVariableChanged: (v) => {
if (v.state.name === this.state.value.name) {
this.notifyChange();
}
},
});
public evaluate(): boolean {
if (!this.state.value.name) {
return true;
}
const variable = sceneGraph.getVariables(this).getByName(this.state.value.name);
if (!variable) {
return false;
}
const variableValue = variable.getValue() ?? '';
const hit = Array.isArray(variableValue)
? variableValue.includes(this.state.value.value)
: variableValue === this.state.value.value;
return this.state.value.operator === '!=' ? !hit : hit;
}
public serialize(): ConditionalRenderingVariableKind {
return {
kind: 'ConditionalRenderingVariable',
spec: {
variable: this.state.value.name,
operator: this.state.value.operator === '=' ? 'equals' : 'notEquals',
value: this.state.value.value,
},
};
}
public static deserialize(model: ConditionalRenderingVariableKind): ConditionalRenderingVariable {
return new ConditionalRenderingVariable({
value: {
name: model.spec.variable,
operator: model.spec.operator === 'equals' ? '=' : '!=',
value: model.spec.value,
},
});
}
public static createEmpty(name: string): ConditionalRenderingVariable {
return new ConditionalRenderingVariable({ value: { name, operator: '=', value: '' } });
}
}
function ConditionalRenderingVariableRenderer({ model }: SceneComponentProps<ConditionalRenderingVariable>) {
const { value } = model.useState();
const variables = useMemo(() => sceneGraph.getVariables(model), [model]);
const variableNames: Array<ComboboxOption<string>> = useMemo(
() => variables.state.variables.map((v) => ({ value: v.state.name, label: v.state.label ?? v.state.name })),
[variables.state.variables]
);
const operatorOptions: Array<ComboboxOption<VariableConditionValueOperator>> = useMemo(
() => [
{ value: '=', description: t('dashboard.conditional-rendering.conditions.variable.operator.equals', 'Equals') },
{
value: '!=',
description: t('dashboard.conditional-rendering.conditions.variable.operator.not-equals', 'Not equals'),
},
],
[]
);
return (
<Stack direction="column" gap={0.5}>
<Stack direction="row" gap={0.5} grow={1}>
<Box flex={1}>
<Combobox
placeholder={t('dashboard.conditional-rendering.conditions.variable.name', 'Name')}
options={variableNames}
value={value.name}
onChange={(option) => model.setStateAndNotify({ value: { ...value, name: option.value } })}
/>
</Box>
<Combobox
width="auto"
minWidth={10}
options={operatorOptions}
value={value.operator}
onChange={(option) => model.setStateAndNotify({ value: { ...value, operator: option.value } })}
/>
</Stack>
<Input
placeholder={t('dashboard.conditional-rendering.conditions.variable.value', 'Value')}
value={value.value}
onChange={(e) => model.setStateAndNotify({ value: { ...value, value: e.currentTarget.value } })}
/>
</Stack>
);
}