Skip to content

Commit 3858612

Browse files
authored
Merge pull request #80 from grafana/missing-props-sent-custom-formatter
Variables: Missing variable props sent to custom variable formatters
2 parents fbb2594 + 4bd7de1 commit 3858612

File tree

8 files changed

+52
-18
lines changed

8 files changed

+52
-18
lines changed

packages/scenes/src/components/VizPanel/VizPanel.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { DeepPartial, SceneLayoutChildState } from '../../core/types';
1616
import { VizPanelRenderer } from './VizPanelRenderer';
1717
import { VizPanelMenu } from './VizPanelMenu';
1818
import { VariableDependencyConfig } from '../../variables/VariableDependencyConfig';
19-
import { CustomFormatterFn } from '../../variables/interpolation/sceneInterpolator';
19+
import { VariableCustomFormatterFn } from '../../variables/types';
2020

2121
export interface VizPanelState<TOptions = {}, TFieldConfig = {}> extends SceneLayoutChildState {
2222
title: string;
@@ -125,7 +125,7 @@ export class VizPanel<TOptions = {}, TFieldConfig = {}> extends SceneObjectBase<
125125
this.setState({ fieldConfig });
126126
};
127127

128-
public interpolate = ((value: string, scoped?: ScopedVars, format?: string | CustomFormatterFn) => {
128+
public interpolate = ((value: string, scoped?: ScopedVars, format?: string | VariableCustomFormatterFn) => {
129129
return sceneGraph.interpolate(this, value, scoped, format);
130130
}) as InterpolateFunction;
131131
}

packages/scenes/src/core/sceneGraph.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ScopedVars } from '@grafana/data';
22
import { DefaultTimeRange, EmptyDataNode, EmptyVariableSet } from '../variables/interpolation/defaults';
33

4-
import { CustomFormatterFn, sceneInterpolator } from '../variables/interpolation/sceneInterpolator';
5-
import { SceneVariables } from '../variables/types';
4+
import { sceneInterpolator } from '../variables/interpolation/sceneInterpolator';
5+
import { VariableCustomFormatterFn, SceneVariables } from '../variables/types';
66

77
import { SceneDataState, SceneEditor, SceneLayout, SceneObject, SceneTimeRangeLike } from './types';
88
import { lookupVariable } from '../variables/lookupVariable';
@@ -92,7 +92,7 @@ export function interpolate(
9292
sceneObject: SceneObject,
9393
value: string | undefined | null,
9494
scopedVars?: ScopedVars,
95-
format?: string | CustomFormatterFn
95+
format?: string | VariableCustomFormatterFn
9696
): string {
9797
if (value === '' || value == null) {
9898
return '';

packages/scenes/src/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export { SceneDataTransformer } from './querying/SceneDataTransformer';
1111
export * from './variables/types';
1212
export { VariableDependencyConfig } from './variables/VariableDependencyConfig';
1313
export { formatRegistry, FormatRegistryID, type FormatVariable } from './variables/interpolation/formatRegistry';
14-
export { type CustomFormatterFn } from './variables/interpolation/sceneInterpolator';
1514
export { VariableValueSelectors } from './variables/components/VariableValueSelectors';
1615
export { SceneVariableSet } from './variables/sets/SceneVariableSet';
1716
export { ConstantVariable } from './variables/variants/ConstantVariable';

packages/scenes/src/variables/interpolation/formatRegistry.ts

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ export interface FormatVariable {
1919
state: {
2020
name: string;
2121
type: VariableType | string;
22+
isMulti?: boolean;
23+
includeAll?: boolean;
2224
};
2325

2426
getValue(fieldPath?: string): VariableValue | undefined | null;

packages/scenes/src/variables/interpolation/sceneInterpolator.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,25 @@ describe('sceneInterpolator', () => {
167167
const scopedVars = { __data: { value: { name: 'Main org' }, text: '' } };
168168
expect(sceneInterpolator(scene, '${__data.name}', scopedVars)).toBe('Main org');
169169
});
170+
171+
it('Can use custom formatter', () => {
172+
const scene = new TestScene({
173+
$variables: new SceneVariableSet({
174+
variables: [
175+
new TestVariable({
176+
name: 'cluster',
177+
value: ['1', '2'],
178+
text: ['hello', 'world'],
179+
isMulti: true,
180+
includeAll: true,
181+
}),
182+
],
183+
}),
184+
});
185+
186+
const formatter = jest.fn().mockReturnValue('custom');
187+
188+
expect(sceneInterpolator(scene, '$cluster', undefined, formatter)).toBe('custom');
189+
expect(formatter.mock.calls[0][1]).toEqual({ name: 'cluster', type: 'custom', multi: true, includeAll: true });
190+
});
170191
});

packages/scenes/src/variables/interpolation/sceneInterpolator.ts

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
import { ScopedVars } from '@grafana/data';
2-
import { VariableModel, VariableType } from '@grafana/schema';
2+
import { VariableType } from '@grafana/schema';
33

44
import { SceneObject } from '../../core/types';
5-
import { VariableValue } from '../types';
5+
import { VariableCustomFormatterFn, VariableValue } from '../types';
66

77
import { getSceneVariableForScopedVar } from './ScopedVarsVariable';
88
import { formatRegistry, FormatRegistryID, FormatVariable } from './formatRegistry';
99
import { VARIABLE_REGEX } from '../constants';
1010
import { lookupVariable } from '../lookupVariable';
1111

12-
export type CustomFormatterFn = (
13-
value: unknown,
14-
legacyVariableModel: Partial<VariableModel>,
15-
legacyDefaultFormatter?: CustomFormatterFn
16-
) => string;
17-
1812
/**
1913
* This function will try to parse and replace any variable expression found in the target string. The sceneObject will be used as the source of variables. It will
2014
* use the scene graph and walk up the parent tree until it finds the closest variable.
@@ -26,7 +20,7 @@ export function sceneInterpolator(
2620
sceneObject: SceneObject,
2721
target: string | undefined | null,
2822
scopedVars?: ScopedVars,
29-
format?: string | CustomFormatterFn
23+
format?: string | VariableCustomFormatterFn
3024
): string {
3125
if (!target) {
3226
return target ?? '';
@@ -56,7 +50,7 @@ export function sceneInterpolator(
5650
function formatValue(
5751
variable: FormatVariable,
5852
value: VariableValue | undefined | null,
59-
formatNameOrFn?: string | CustomFormatterFn
53+
formatNameOrFn?: string | VariableCustomFormatterFn
6054
): string {
6155
if (value === null || value === undefined) {
6256
return '';
@@ -81,6 +75,8 @@ function formatValue(
8175
return formatNameOrFn(value, {
8276
name: variable.state.name,
8377
type: variable.state.type as VariableType,
78+
multi: variable.state.isMulti,
79+
includeAll: variable.state.includeAll,
8480
});
8581
}
8682

packages/scenes/src/variables/types.ts

+16
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,19 @@ export interface SceneVariableDependencyConfigLike {
8585
**/
8686
variableUpdatesCompleted(changedVariables: Set<SceneVariable>): void;
8787
}
88+
89+
/**
90+
* Used in CustomFormatterFn
91+
*/
92+
export interface CustomFormatterVariable {
93+
name: string;
94+
type: VariableType;
95+
multi?: boolean;
96+
includeAll?: boolean;
97+
}
98+
99+
export type VariableCustomFormatterFn = (
100+
value: unknown,
101+
legacyVariableModel: Partial<CustomFormatterVariable>,
102+
legacyDefaultFormatter?: VariableCustomFormatterFn
103+
) => string;

packages/scenes/src/variables/variants/DataSourceVariable.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { lastValueFrom } from 'rxjs';
33
import { DataSourceInstanceSettings, ScopedVars, PluginType } from '@grafana/data';
44

55
import { SceneObject } from '../../core/types';
6-
import { CustomFormatterFn } from '../interpolation/sceneInterpolator';
76

87
import { DataSourceVariable } from './DataSourceVariable';
8+
import { VariableCustomFormatterFn } from '../types';
99

1010
function getDataSource(name: string, type: string, isDefault = false): DataSourceInstanceSettings {
1111
return {
@@ -58,7 +58,7 @@ jest.mock('../../core/sceneGraph', () => {
5858
sceneObject: SceneObject,
5959
value: string | undefined | null,
6060
scopedVars?: ScopedVars,
61-
format?: string | CustomFormatterFn
61+
format?: string | VariableCustomFormatterFn
6262
) => {
6363
return value?.replace('$variable-1', 'slow');
6464
},

0 commit comments

Comments
 (0)