Update scenes to 0.2 (#65676)

* Update scenes to latest

* Replace FormatRegistryID with VariableFormatID

* Remove scene demos that were moved to scenes repo, fix the remaining demos

* Fix grafana Monitoring app

* DashboardsLoader migration

* Fix test
This commit is contained in:
Dominik Prokop 2023-03-31 09:59:06 +02:00 committed by GitHub
parent e0ef79f5cc
commit bbf74b941b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 665 additions and 942 deletions

View File

@ -267,7 +267,7 @@
"@grafana/lezer-logql": "0.1.2", "@grafana/lezer-logql": "0.1.2",
"@grafana/monaco-logql": "^0.0.7", "@grafana/monaco-logql": "^0.0.7",
"@grafana/runtime": "workspace:*", "@grafana/runtime": "workspace:*",
"@grafana/scenes": "^0.0.28", "@grafana/scenes": "^0.2.0",
"@grafana/schema": "workspace:*", "@grafana/schema": "workspace:*",
"@grafana/ui": "workspace:*", "@grafana/ui": "workspace:*",
"@kusto/monaco-kusto": "5.3.6", "@kusto/monaco-kusto": "5.3.6",

View File

@ -20,7 +20,7 @@ import {
VariableSuggestionsScope, VariableSuggestionsScope,
} from '@grafana/data'; } from '@grafana/data';
import { getTemplateSrv } from '@grafana/runtime'; import { getTemplateSrv } from '@grafana/runtime';
import { FormatRegistryID } from '@grafana/scenes'; import { VariableFormatID } from '@grafana/schema';
import { getConfig } from 'app/core/config'; import { getConfig } from 'app/core/config';
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
@ -305,7 +305,7 @@ export class LinkSrv implements LinkService {
}; };
if (replaceVariables) { if (replaceVariables) {
info.href = replaceVariables(info.href, undefined, FormatRegistryID.percentEncode); info.href = replaceVariables(info.href, undefined, VariableFormatID.PercentEncode);
info.title = replaceVariables(link.title); info.title = replaceVariables(link.title);
} }

View File

@ -9,6 +9,7 @@ import {
SceneRouteMatch, SceneRouteMatch,
EmbeddedScene, EmbeddedScene,
SceneAppPageLike, SceneAppPageLike,
SceneFlexItem,
} from '@grafana/scenes'; } from '@grafana/scenes';
import { usePageNav } from 'app/core/components/Page/usePageNav'; import { usePageNav } from 'app/core/components/Page/usePageNav';
import { PluginPageContext, PluginPageContextType } from 'app/features/plugins/components/PluginPageContext'; import { PluginPageContext, PluginPageContextType } from 'app/features/plugins/components/PluginPageContext';
@ -131,9 +132,11 @@ export function getSecondLevelDrilldown(
return new EmbeddedScene({ return new EmbeddedScene({
body: new SceneFlexLayout({ body: new SceneFlexLayout({
children: [ children: [
new SceneCanvasText({ new SceneFlexItem({
body: new SceneCanvasText({
text: 'Drilldown: ' + secondLevel, text: 'Drilldown: ' + secondLevel,
}), }),
}),
], ],
}), }),
}); });

View File

@ -15,6 +15,7 @@ import {
SceneControlsSpacer, SceneControlsSpacer,
SceneDataTransformer, SceneDataTransformer,
SceneRefreshPicker, SceneRefreshPicker,
SceneFlexItem,
} from '@grafana/scenes'; } from '@grafana/scenes';
import { PromQuery } from 'app/plugins/datasource/prometheus/types'; import { PromQuery } from 'app/plugins/datasource/prometheus/types';
@ -142,18 +143,20 @@ export function getHttpHandlerListScene(): EmbeddedScene {
children: [], children: [],
}), }),
getLayoutChild: (data, frame, frameIndex) => { getLayoutChild: (data, frame, frameIndex) => {
return new SceneFlexLayout({ return new SceneFlexItem({
key: `panel-${frameIndex}`, key: `panel-${frameIndex}`,
direction: 'row', minHeight: 200,
placement: { minHeight: 200 },
$data: new SceneDataNode({ $data: new SceneDataNode({
data: { data: {
...data, ...data,
series: [frame], series: [frame],
}, },
}), }),
body: new SceneFlexLayout({
direction: 'row',
children: [ children: [
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
// titleLink: { // titleLink: {
// path: `/scenes/grafana-monitoring/handlers/${encodeURIComponent(frame.fields[1].labels.handler)}`, // path: `/scenes/grafana-monitoring/handlers/${encodeURIComponent(frame.fields[1].labels.handler)}`,
@ -164,8 +167,11 @@ export function getHttpHandlerListScene(): EmbeddedScene {
legend: { displayMode: 'hidden' }, legend: { displayMode: 'hidden' },
}, },
}), }),
new VizPanel({ }),
placement: { width: 200 },
new SceneFlexItem({
width: 200,
body: new VizPanel({
title: 'Last', title: 'Last',
pluginId: 'stat', pluginId: 'stat',
fieldConfig: { fieldConfig: {
@ -192,13 +198,15 @@ export function getHttpHandlerListScene(): EmbeddedScene {
textMode: 'value', textMode: 'value',
}, },
}), }),
}),
], ],
}),
}); });
}, },
}); });
const layout = new SceneFlexLayout({ const layout = new SceneFlexLayout({
children: [httpHandlersTable], children: [new SceneFlexItem({ body: httpHandlersTable })],
}); });
const sceneToggle = new SceneRadioToggle({ const sceneToggle = new SceneRadioToggle({
@ -209,7 +217,7 @@ export function getHttpHandlerListScene(): EmbeddedScene {
value: 'table', value: 'table',
onChange: (value) => { onChange: (value) => {
if (value === 'table') { if (value === 'table') {
layout.setState({ children: [httpHandlersTable] }); layout.setState({ children: [new SceneFlexItem({ body: httpHandlersTable })] });
} else { } else {
layout.setState({ children: [graphsScene] }); layout.setState({ children: [graphsScene] });
} }
@ -257,21 +265,24 @@ export function getHandlerDetailsScene(handler: string): EmbeddedScene {
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'column', direction: 'column',
children: [ children: [
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
$data: reqDurationTimeSeries, $data: reqDurationTimeSeries,
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Request duration avg (ms)', title: 'Request duration avg (ms)',
placement: {},
//displayMode: 'transparent', //displayMode: 'transparent',
options: {}, options: {},
}), }),
new VizPanel({ }),
new SceneFlexItem({
body: new VizPanel({
$data: reqCountTimeSeries, $data: reqCountTimeSeries,
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Request count/s', title: 'Request count/s',
//displayMode: 'transparent', //displayMode: 'transparent',
options: {}, options: {},
}), }),
}),
], ],
}), }),
}); });
@ -322,16 +333,28 @@ export function getOverviewScene(): EmbeddedScene {
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'column', direction: 'column',
children: [ children: [
new SceneFlexLayout({ new SceneFlexItem({
placement: { height: 150 }, height: 150,
body: new SceneFlexLayout({
children: [ children: [
getInstantStatPanel('grafana_stat_totals_dashboard', 'Dashboards'), new SceneFlexItem({
getInstantStatPanel('grafana_stat_total_users', 'Users'), body: getInstantStatPanel('grafana_stat_totals_dashboard', 'Dashboards'),
getInstantStatPanel('sum(grafana_stat_totals_datasource)', 'Data sources'), }),
getInstantStatPanel('grafana_stat_total_service_account_tokens', 'Service account tokens'), new SceneFlexItem({
body: getInstantStatPanel('grafana_stat_total_users', 'Users'),
}),
new SceneFlexItem({
body: getInstantStatPanel('sum(grafana_stat_totals_datasource)', 'Data sources'),
}),
new SceneFlexItem({
body: getInstantStatPanel('grafana_stat_total_service_account_tokens', 'Service account tokens'),
}),
], ],
}), }),
new VizPanel({ }),
new SceneFlexItem({
body: new VizPanel({
$data: new SceneQueryRunner({ $data: new SceneQueryRunner({
datasource: { uid: 'gdev-prometheus' }, datasource: { uid: 'gdev-prometheus' },
queries: [ queries: [
@ -364,7 +387,9 @@ export function getOverviewScene(): EmbeddedScene {
overrides: [], overrides: [],
}, },
}), }),
new VizPanel({ }),
new SceneFlexItem({
body: new VizPanel({
$data: new SceneQueryRunner({ $data: new SceneQueryRunner({
datasource: { uid: 'gdev-prometheus' }, datasource: { uid: 'gdev-prometheus' },
queries: [ queries: [
@ -396,6 +421,7 @@ export function getOverviewScene(): EmbeddedScene {
overrides: [], overrides: [],
}, },
}), }),
}),
], ],
}), }),
}); });
@ -455,7 +481,8 @@ export function getHandlerLogsScene(handler: string): EmbeddedScene {
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'column', direction: 'column',
children: [ children: [
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
pluginId: 'text', pluginId: 'text',
title: '', title: '',
options: { options: {
@ -466,7 +493,9 @@ export function getHandlerLogsScene(handler: string): EmbeddedScene {
`, `,
}, },
}), }),
new VizPanel({ }),
new SceneFlexItem({
body: new VizPanel({
$data: logsQuery, $data: logsQuery,
pluginId: 'logs', pluginId: 'logs',
title: '', title: '',
@ -481,6 +510,7 @@ export function getHandlerLogsScene(handler: string): EmbeddedScene {
sortOrder: 'Descending', sortOrder: 'Descending',
}, },
}), }),
}),
], ],
}), }),
}); });
@ -513,7 +543,8 @@ export function getOverviewLogsScene(): EmbeddedScene {
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'column', direction: 'column',
children: [ children: [
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
$data: logsQuery, $data: logsQuery,
pluginId: 'logs', pluginId: 'logs',
title: '', title: '',
@ -528,6 +559,7 @@ export function getOverviewLogsScene(): EmbeddedScene {
sortOrder: 'Descending', sortOrder: 'Descending',
}, },
}), }),
}),
], ],
}), }),
}); });

View File

@ -3,6 +3,7 @@ import {
DataSourceVariable, DataSourceVariable,
QueryVariable, QueryVariable,
SceneDataTransformer, SceneDataTransformer,
SceneGridItem,
SceneGridLayout, SceneGridLayout,
SceneGridRow, SceneGridRow,
SceneQueryRunner, SceneQueryRunner,
@ -169,10 +170,10 @@ describe('DashboardLoader', () => {
const rowScene = body.state.children[0] as SceneGridRow; const rowScene = body.state.children[0] as SceneGridRow;
expect(rowScene).toBeInstanceOf(SceneGridRow); expect(rowScene).toBeInstanceOf(SceneGridRow);
expect(rowScene.state.title).toEqual(row.title); expect(rowScene.state.title).toEqual(row.title);
expect(rowScene.state.placement?.y).toEqual(row.gridPos!.y); expect(rowScene.state.y).toEqual(row.gridPos!.y);
expect(rowScene.state.isCollapsed).toEqual(row.collapsed); expect(rowScene.state.isCollapsed).toEqual(row.collapsed);
expect(rowScene.state.children).toHaveLength(1); expect(rowScene.state.children).toHaveLength(1);
expect(rowScene.state.children[0]).toBeInstanceOf(VizPanel); expect(rowScene.state.children[0]).toBeInstanceOf(SceneGridItem);
}); });
it('should create panels within expanded row', () => { it('should create panels within expanded row', () => {
@ -233,18 +234,18 @@ describe('DashboardLoader', () => {
expect(body.state.children).toHaveLength(3); expect(body.state.children).toHaveLength(3);
expect(body).toBeInstanceOf(SceneGridLayout); expect(body).toBeInstanceOf(SceneGridLayout);
// Panel out of row // Panel out of row
expect(body.state.children[0]).toBeInstanceOf(VizPanel); expect(body.state.children[0]).toBeInstanceOf(SceneGridItem);
const panelOutOfRowVizPanel = body.state.children[0] as VizPanel; const panelOutOfRowVizPanel = body.state.children[0] as SceneGridItem;
expect(panelOutOfRowVizPanel.state.title).toBe(panelOutOfRow.title); expect((panelOutOfRowVizPanel.state.body as VizPanel)?.state.title).toBe(panelOutOfRow.title);
// Row with panel // Row with panel
expect(body.state.children[1]).toBeInstanceOf(SceneGridRow); expect(body.state.children[1]).toBeInstanceOf(SceneGridRow);
const rowWithPanelsScene = body.state.children[1] as SceneGridRow; const rowWithPanelsScene = body.state.children[1] as SceneGridRow;
expect(rowWithPanelsScene.state.title).toBe(rowWithPanel.title); expect(rowWithPanelsScene.state.title).toBe(rowWithPanel.title);
expect(rowWithPanelsScene.state.children).toHaveLength(1); expect(rowWithPanelsScene.state.children).toHaveLength(1);
// Panel within row // Panel within row
expect(rowWithPanelsScene.state.children[0]).toBeInstanceOf(VizPanel); expect(rowWithPanelsScene.state.children[0]).toBeInstanceOf(SceneGridItem);
const panelInRowVizPanel = rowWithPanelsScene.state.children[0] as VizPanel; const panelInRowVizPanel = rowWithPanelsScene.state.children[0] as SceneGridItem;
expect(panelInRowVizPanel.state.title).toBe(panelInRow.title); expect((panelInRowVizPanel.state.body as VizPanel).state.title).toBe(panelInRow.title);
// Empty row // Empty row
expect(body.state.children[2]).toBeInstanceOf(SceneGridRow); expect(body.state.children[2]).toBeInstanceOf(SceneGridRow);
const emptyRowScene = body.state.children[2] as SceneGridRow; const emptyRowScene = body.state.children[2] as SceneGridRow;
@ -295,22 +296,23 @@ describe('DashboardLoader', () => {
], ],
}; };
const vizPanelSceneObject = createVizPanelFromPanelModel(new PanelModel(panel)); const vizPanelSceneObject = createVizPanelFromPanelModel(new PanelModel(panel));
const vizPanelItelf = vizPanelSceneObject.state.body as VizPanel;
expect(vizPanelSceneObject.state.title).toBe('test'); expect(vizPanelItelf?.state.title).toBe('test');
expect(vizPanelSceneObject.state.pluginId).toBe('test-plugin'); expect(vizPanelItelf?.state.pluginId).toBe('test-plugin');
expect(vizPanelSceneObject.state.placement).toEqual({ x: 0, y: 0, width: 12, height: 8 }); expect(vizPanelSceneObject.state.x).toEqual(0);
expect(vizPanelSceneObject.state.options).toEqual(panel.options); expect(vizPanelSceneObject.state.y).toEqual(0);
expect(vizPanelSceneObject.state.fieldConfig).toEqual(panel.fieldConfig); expect(vizPanelSceneObject.state.width).toEqual(12);
expect(vizPanelSceneObject.state.pluginVersion).toBe('1.0.0'); expect(vizPanelSceneObject.state.height).toEqual(8);
expect(vizPanelItelf?.state.options).toEqual(panel.options);
expect(vizPanelItelf?.state.fieldConfig).toEqual(panel.fieldConfig);
expect(vizPanelItelf?.state.pluginVersion).toBe('1.0.0');
expect( expect(
((vizPanelSceneObject.state.$data as SceneDataTransformer)?.state.$data as SceneQueryRunner).state.queries ((vizPanelItelf.state.$data as SceneDataTransformer)?.state.$data as SceneQueryRunner).state.queries
).toEqual(panel.targets); ).toEqual(panel.targets);
expect( expect(
((vizPanelSceneObject.state.$data as SceneDataTransformer)?.state.$data as SceneQueryRunner).state.maxDataPoints ((vizPanelItelf.state.$data as SceneDataTransformer)?.state.$data as SceneQueryRunner).state.maxDataPoints
).toEqual(100); ).toEqual(100);
expect((vizPanelSceneObject.state.$data as SceneDataTransformer)?.state.transformations).toEqual( expect((vizPanelItelf.state.$data as SceneDataTransformer)?.state.transformations).toEqual(panel.transformations);
panel.transformations
);
}); });
it('should initalize the VizPanel without title and transparent true', () => { it('should initalize the VizPanel without title and transparent true', () => {
@ -323,8 +325,8 @@ describe('DashboardLoader', () => {
const vizPanelSceneObject = createVizPanelFromPanelModel(new PanelModel(panel)); const vizPanelSceneObject = createVizPanelFromPanelModel(new PanelModel(panel));
expect(vizPanelSceneObject.state.displayMode).toEqual('transparent'); expect((vizPanelSceneObject.state.body as VizPanel)?.state.displayMode).toEqual('transparent');
expect(vizPanelSceneObject.state.hoverHeader).toEqual(true); expect((vizPanelSceneObject.state.body as VizPanel)?.state.hoverHeader).toEqual(true);
}); });
}); });
@ -586,7 +588,7 @@ describe('DashboardLoader', () => {
hide: 2, hide: 2,
label: 'constant', label: 'constant',
name: 'constant', name: 'constant',
skipUrlSync: false, skipUrlSync: true,
type: 'constant', type: 'constant',
value: 'test', value: 'test',
}); });

View File

@ -11,7 +11,6 @@ import {
SceneGridLayout, SceneGridLayout,
SceneGridRow, SceneGridRow,
SceneTimeRange, SceneTimeRange,
SceneObject,
SceneQueryRunner, SceneQueryRunner,
SceneVariableSet, SceneVariableSet,
VariableValueSelectors, VariableValueSelectors,
@ -21,6 +20,7 @@ import {
QueryVariable, QueryVariable,
ConstantVariable, ConstantVariable,
SceneDataTransformer, SceneDataTransformer,
SceneGridItem,
} from '@grafana/scenes'; } from '@grafana/scenes';
import { StateManagerBase } from 'app/core/services/StateManagerBase'; import { StateManagerBase } from 'app/core/services/StateManagerBase';
import { dashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv'; import { dashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv';
@ -81,14 +81,14 @@ export class DashboardLoader extends StateManagerBase<DashboardLoaderState> {
} }
} }
export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneObject[] { export function createSceneObjectsForPanels(oldPanels: PanelModel[]): Array<SceneGridItem | SceneGridRow> {
// collects all panels and rows // collects all panels and rows
const panels: SceneObject[] = []; const panels: Array<SceneGridItem | SceneGridRow> = [];
// indicates expanded row that's currently processed // indicates expanded row that's currently processed
let currentRow: PanelModel | null = null; let currentRow: PanelModel | null = null;
// collects panels in the currently processed, expanded row // collects panels in the currently processed, expanded row
let currentRowPanels: SceneObject[] = []; let currentRowPanels: SceneGridItem[] = [];
for (const panel of oldPanels) { for (const panel of oldPanels) {
if (panel.type === 'row') { if (panel.type === 'row') {
@ -99,9 +99,7 @@ export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneObjec
new SceneGridRow({ new SceneGridRow({
title: panel.title, title: panel.title,
isCollapsed: true, isCollapsed: true,
placement: {
y: panel.gridPos.y, y: panel.gridPos.y,
},
children: panel.panels ? panel.panels.map(createVizPanelFromPanelModel) : [], children: panel.panels ? panel.panels.map(createVizPanelFromPanelModel) : [],
}) })
); );
@ -116,9 +114,7 @@ export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneObjec
panels.push( panels.push(
new SceneGridRow({ new SceneGridRow({
title: currentRow!.title, title: currentRow!.title,
placement: {
y: currentRow.gridPos.y, y: currentRow.gridPos.y,
},
children: currentRowPanels, children: currentRowPanels,
}) })
); );
@ -144,9 +140,7 @@ export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneObjec
panels.push( panels.push(
new SceneGridRow({ new SceneGridRow({
title: currentRow!.title, title: currentRow!.title,
placement: {
y: currentRow.gridPos.y, y: currentRow.gridPos.y,
},
children: currentRowPanels, children: currentRowPanels,
}) })
); );
@ -263,15 +257,16 @@ export function createVizPanelFromPanelModel(panel: PanelModel) {
maxDataPoints: panel.maxDataPoints ?? undefined, maxDataPoints: panel.maxDataPoints ?? undefined,
}); });
return new VizPanel({ return new SceneGridItem({
title: panel.title,
pluginId: panel.type,
placement: {
x: panel.gridPos.x, x: panel.gridPos.x,
y: panel.gridPos.y, y: panel.gridPos.y,
width: panel.gridPos.w, width: panel.gridPos.w,
height: panel.gridPos.h, height: panel.gridPos.h,
}, isDraggable: true,
isResizable: true,
body: new VizPanel({
title: panel.title,
pluginId: panel.type,
options: panel.options ?? {}, options: panel.options ?? {},
fieldConfig: panel.fieldConfig, fieldConfig: panel.fieldConfig,
pluginVersion: panel.pluginVersion, pluginVersion: panel.pluginVersion,
@ -284,6 +279,7 @@ export function createVizPanelFromPanelModel(panel: PanelModel) {
transformations: panel.transformations, transformations: panel.transformations,
}) })
: queryRunner, : queryRunner,
}),
}); });
} }

View File

@ -1,187 +0,0 @@
import { getFrameDisplayName } from '@grafana/data';
import {
SceneFlexLayout,
SceneTimeRange,
SceneTimePicker,
SceneByFrameRepeater,
VizPanel,
SceneCanvasText,
SceneToolbarInput,
SceneDataNode,
} from '@grafana/scenes';
import { TestDataQueryType } from 'app/plugins/datasource/testdata/dataquery.gen';
import { panelBuilders } from '../builders/panelBuilders';
import { DashboardScene } from '../dashboard/DashboardScene';
import { getQueryRunnerWithRandomWalkQuery } from './queries';
export function getFlexLayoutTest(): DashboardScene {
return new DashboardScene({
title: 'Flex layout test',
body: new SceneFlexLayout({
direction: 'row',
children: [
panelBuilders.newGraph({
placement: { minWidth: '70%' },
title: 'Dynamic height and width',
$data: getQueryRunnerWithRandomWalkQuery({}, { maxDataPointsFromWidth: true }),
}),
new SceneFlexLayout({
direction: 'column',
children: [
panelBuilders.newGraph({
title: 'Fill height',
options: {},
fieldConfig: {
defaults: {
custom: {
fillOpacity: 20,
},
},
overrides: [],
},
}),
panelBuilders.newGraph({
title: 'Fill height',
}),
new SceneCanvasText({
placement: { ySizing: 'content' },
text: 'Size to content',
fontSize: 20,
align: 'center',
}),
panelBuilders.newGraph({
title: 'Fixed height',
placement: { height: 300 },
}),
],
}),
],
}),
$timeRange: new SceneTimeRange(),
$data: getQueryRunnerWithRandomWalkQuery(),
actions: [new SceneTimePicker({})],
});
}
export function getScenePanelRepeaterTest(): DashboardScene {
const queryRunner = getQueryRunnerWithRandomWalkQuery({
seriesCount: 2,
alias: '__server_names',
scenarioId: TestDataQueryType.RandomWalk,
});
return new DashboardScene({
title: 'Panel repeater test',
body: new SceneByFrameRepeater({
body: new SceneFlexLayout({
direction: 'column',
children: [],
}),
getLayoutChild: (data, frame, frameIndex) => {
return new SceneFlexLayout({
key: `panel-${frameIndex}`,
$data: new SceneDataNode({
data: {
...data,
series: [frame],
},
}),
direction: 'row',
placement: { minHeight: 200 },
children: [
new VizPanel({
pluginId: 'timeseries',
title: getFrameDisplayName(frame),
options: {
legend: { displayMode: 'hidden' },
},
}),
new VizPanel({
placement: { width: 300 },
pluginId: 'stat',
fieldConfig: { defaults: { displayName: 'Last' }, overrides: [] },
options: {
graphMode: 'none',
},
}),
],
});
},
}),
$timeRange: new SceneTimeRange(),
$data: queryRunner,
actions: [
new SceneToolbarInput({
value: '2',
onChange: (newValue) => {
queryRunner.setState({
queries: [
{
...queryRunner.state.queries[0],
seriesCount: newValue,
},
],
});
queryRunner.runQueries();
},
}),
new SceneTimePicker({}),
],
});
}
export function getRepeaterSceneWithFlexWrap(): DashboardScene {
const queryRunner = getQueryRunnerWithRandomWalkQuery({
seriesCount: 10,
alias: '__server_names',
scenarioId: TestDataQueryType.RandomWalk,
});
return new DashboardScene({
title: 'Flex layout with wrap test',
body: new SceneByFrameRepeater({
body: new SceneFlexLayout({
direction: 'row',
wrap: 'wrap',
children: [],
}),
getLayoutChild: (data, frame, frameIndex) => {
return new VizPanel({
pluginId: 'timeseries',
title: getFrameDisplayName(frame),
$data: new SceneDataNode({
data: {
...data,
series: [frame],
},
}),
placement: { height: 300, minWidth: 400 },
options: {
legend: { displayMode: 'hidden' },
},
});
},
}),
$timeRange: new SceneTimeRange(),
$data: queryRunner,
actions: [
new SceneToolbarInput({
value: '10',
onChange: (newValue) => {
queryRunner.setState({
queries: [
{
...queryRunner.state.queries[0],
seriesCount: newValue,
},
],
});
queryRunner.runQueries();
},
}),
new SceneTimePicker({}),
],
});
}

View File

@ -1,53 +0,0 @@
import { VizPanel, SceneTimePicker, SceneFlexLayout, SceneGridLayout, SceneTimeRange } from '@grafana/scenes';
import { DashboardScene } from '../dashboard/DashboardScene';
import { getQueryRunnerWithRandomWalkQuery } from './queries';
export function getGridLayoutTest(): DashboardScene {
return new DashboardScene({
title: 'Grid layout test',
body: new SceneGridLayout({
children: [
new VizPanel({
pluginId: 'timeseries',
title: 'Draggable and resizable',
placement: {
x: 0,
y: 0,
width: 12,
height: 10,
isResizable: true,
isDraggable: true,
},
}),
new VizPanel({
pluginId: 'timeseries',
title: 'No drag and no resize',
placement: { x: 12, y: 0, width: 12, height: 10, isResizable: false, isDraggable: false },
}),
new SceneFlexLayout({
direction: 'column',
placement: { x: 6, y: 11, width: 12, height: 10, isDraggable: true, isResizable: true },
children: [
new VizPanel({
placement: { ySizing: 'fill' },
pluginId: 'timeseries',
title: 'Child of flex layout',
}),
new VizPanel({
placement: { ySizing: 'fill' },
pluginId: 'timeseries',
title: 'Child of flex layout',
}),
],
}),
],
}),
$timeRange: new SceneTimeRange(),
$data: getQueryRunnerWithRandomWalkQuery(),
actions: [new SceneTimePicker({})],
});
}

View File

@ -1,4 +1,11 @@
import { VizPanel, SceneGridRow, SceneTimePicker, SceneGridLayout, SceneTimeRange } from '@grafana/scenes'; import {
VizPanel,
SceneGridRow,
SceneTimePicker,
SceneGridLayout,
SceneTimeRange,
SceneGridItem,
} from '@grafana/scenes';
import { TestDataQueryType } from 'app/plugins/datasource/testdata/dataquery.gen'; import { TestDataQueryType } from 'app/plugins/datasource/testdata/dataquery.gen';
import { DashboardScene } from '../dashboard/DashboardScene'; import { DashboardScene } from '../dashboard/DashboardScene';
@ -22,36 +29,49 @@ export function getGridWithMultipleTimeRanges(): DashboardScene {
title: 'Row A - has its own query, last year time range', title: 'Row A - has its own query, last year time range',
key: 'Row A', key: 'Row A',
isCollapsed: true, isCollapsed: true,
placement: { y: 0 }, y: 0,
children: [ children: [
new VizPanel({ new SceneGridItem({
x: 0,
y: 1,
width: 12,
height: 5,
isResizable: true,
isDraggable: true,
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Row A Child1', title: 'Row A Child1',
key: 'Row A Child1', key: 'Row A Child1',
placement: { x: 0, y: 1, width: 12, height: 5, isResizable: true, isDraggable: true },
}), }),
new VizPanel({ }),
new SceneGridItem({
x: 0,
y: 5,
width: 6,
height: 5,
isResizable: true,
isDraggable: true,
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Row A Child2', title: 'Row A Child2',
key: 'Row A Child2', key: 'Row A Child2',
placement: { x: 0, y: 5, width: 6, height: 5, isResizable: true, isDraggable: true }, }),
}), }),
], ],
}), }),
new SceneGridItem({
new VizPanel({
$data: getQueryRunnerWithRandomWalkQuery(),
pluginId: 'timeseries',
title: 'Outsider, has its own query',
key: 'Outsider-own-query',
placement: {
x: 0, x: 0,
y: 12, y: 12,
width: 6, width: 6,
height: 10, height: 10,
isResizable: true, isResizable: true,
isDraggable: true, isDraggable: true,
}, body: new VizPanel({
$data: getQueryRunnerWithRandomWalkQuery(),
pluginId: 'timeseries',
title: 'Outsider, has its own query',
key: 'Outsider-own-query',
}),
}), }),
], ],
}), }),

View File

@ -1,4 +1,12 @@
import { VizPanel, SceneTimePicker, SceneFlexLayout, SceneGridLayout, SceneTimeRange } from '@grafana/scenes'; import {
VizPanel,
SceneTimePicker,
SceneFlexLayout,
SceneGridLayout,
SceneTimeRange,
SceneGridItem,
SceneFlexItem,
} from '@grafana/scenes';
import { DashboardScene } from '../dashboard/DashboardScene'; import { DashboardScene } from '../dashboard/DashboardScene';
@ -9,80 +17,120 @@ export function getMultipleGridLayoutTest(): DashboardScene {
title: 'Multiple grid layouts test', title: 'Multiple grid layouts test',
body: new SceneFlexLayout({ body: new SceneFlexLayout({
children: [ children: [
new SceneGridLayout({ new SceneFlexItem({
body: new SceneGridLayout({
children: [ children: [
new VizPanel({ new SceneGridItem({
placement: {
x: 0, x: 0,
y: 0, y: 0,
width: 12, width: 12,
height: 10, height: 10,
isDraggable: true, isDraggable: true,
isResizable: true, isResizable: true,
}, body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Dragabble and resizable', title: 'Dragabble and resizable',
}), }),
new VizPanel({ }),
placement: { x: 12, y: 0, width: 12, height: 10, isResizable: false, isDraggable: true }, new SceneGridItem({
x: 12,
y: 0,
width: 12,
height: 10,
isResizable: false,
isDraggable: true,
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Draggable only', title: 'Draggable only',
}), }),
new SceneFlexLayout({ }),
placement: { x: 6, y: 11, width: 12, height: 10, isResizable: false, isDraggable: true }, new SceneGridItem({
x: 6,
y: 11,
width: 12,
height: 10,
isResizable: false,
isDraggable: true,
body: new SceneFlexLayout({
direction: 'column', direction: 'column',
children: [ children: [
new VizPanel({ new SceneFlexItem({
placement: { ySizing: 'fill' }, ySizing: 'fill',
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Fill height',
}), }),
new VizPanel({ }),
placement: { ySizing: 'fill' }, new SceneFlexItem({
ySizing: 'fill',
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Fill height',
}), }),
],
}), }),
], ],
}), }),
}),
new SceneGridLayout({ ],
}),
}),
new SceneFlexItem({
body: new SceneGridLayout({
children: [ children: [
new VizPanel({ new SceneGridItem({
placement: {
x: 0, x: 0,
y: 0, y: 0,
width: 12, width: 12,
height: 10, height: 10,
isDraggable: true, isDraggable: true,
}, isResizable: true,
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Dragabble and resizable',
}), }),
new VizPanel({ }),
placement: { x: 12, y: 0, width: 12, height: 10, isResizable: false, isDraggable: true }, new SceneGridItem({
x: 12,
y: 0,
width: 12,
height: 10,
isResizable: false,
isDraggable: true,
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Draggable only',
}), }),
new SceneFlexLayout({ }),
placement: { x: 6, y: 11, width: 12, height: 10 }, new SceneGridItem({
x: 6,
y: 11,
width: 12,
height: 10,
isResizable: false,
isDraggable: true,
body: new SceneFlexLayout({
direction: 'column', direction: 'column',
children: [ children: [
new VizPanel({ new SceneFlexItem({
placement: { ySizing: 'fill', isDraggable: true }, ySizing: 'fill',
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Fill height',
}), }),
new VizPanel({ }),
placement: { ySizing: 'fill', isDraggable: true }, new SceneFlexItem({
ySizing: 'fill',
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Fill height',
}), }),
],
}), }),
], ],
}), }),
}),
],
}),
}),
], ],
}), }),
$timeRange: new SceneTimeRange(), $timeRange: new SceneTimeRange(),

View File

@ -1,4 +1,11 @@
import { VizPanel, SceneGridRow, SceneTimePicker, SceneGridLayout, SceneTimeRange } from '@grafana/scenes'; import {
VizPanel,
SceneGridRow,
SceneTimePicker,
SceneGridLayout,
SceneTimeRange,
SceneGridItem,
} from '@grafana/scenes';
import { TestDataQueryType } from 'app/plugins/datasource/testdata/dataquery.gen'; import { TestDataQueryType } from 'app/plugins/datasource/testdata/dataquery.gen';
import { DashboardScene } from '../dashboard/DashboardScene'; import { DashboardScene } from '../dashboard/DashboardScene';
@ -16,19 +23,33 @@ export function getGridWithMultipleData(): DashboardScene {
title: 'Row A - has its own query', title: 'Row A - has its own query',
key: 'Row A', key: 'Row A',
isCollapsed: true, isCollapsed: true,
placement: { y: 0 }, y: 0,
children: [ children: [
new VizPanel({ new SceneGridItem({
x: 0,
y: 1,
width: 12,
height: 5,
isResizable: true,
isDraggable: true,
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Row A Child1', title: 'Row A Child1',
key: 'Row A Child1', key: 'Row A Child1',
placement: { x: 0, y: 1, width: 12, height: 5, isResizable: true, isDraggable: true },
}), }),
new VizPanel({ }),
new SceneGridItem({
x: 0,
y: 5,
width: 6,
height: 5,
isResizable: true,
isDraggable: true,
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Row A Child2', title: 'Row A Child2',
key: 'Row A Child2', key: 'Row A Child2',
placement: { x: 0, y: 5, width: 6, height: 5, isResizable: true, isDraggable: true }, }),
}), }),
], ],
}), }),
@ -36,49 +57,63 @@ export function getGridWithMultipleData(): DashboardScene {
title: 'Row B - uses global query', title: 'Row B - uses global query',
key: 'Row B', key: 'Row B',
isCollapsed: true, isCollapsed: true,
placement: { y: 1 }, y: 1,
children: [ children: [
new VizPanel({ new SceneGridItem({
x: 0,
y: 2,
width: 12,
height: 5,
isResizable: false,
isDraggable: true,
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Row B Child1', title: 'Row B Child1',
key: 'Row B Child1', key: 'Row B Child1',
placement: { x: 0, y: 2, width: 12, height: 5, isResizable: false, isDraggable: true },
}), }),
new VizPanel({ }),
new SceneGridItem({
x: 0,
y: 7,
width: 6,
height: 5,
isResizable: false,
isDraggable: true,
body: new VizPanel({
$data: getQueryRunnerWithRandomWalkQuery({ seriesCount: 10 }), $data: getQueryRunnerWithRandomWalkQuery({ seriesCount: 10 }),
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Row B Child2 with data', title: 'Row B Child2 with data',
key: 'Row B Child2', key: 'Row B Child2',
placement: { x: 0, y: 7, width: 6, height: 5, isResizable: false, isDraggable: true }, }),
}), }),
], ],
}), }),
new VizPanel({ new SceneGridItem({
$data: getQueryRunnerWithRandomWalkQuery({ seriesCount: 10 }),
pluginId: 'timeseries',
title: 'Outsider, has its own query',
key: 'Outsider-own-query',
placement: {
x: 0, x: 0,
y: 12, y: 12,
width: 6, width: 6,
height: 10, height: 10,
isResizable: true, isResizable: true,
isDraggable: true, isDraggable: true,
}, body: new VizPanel({
}), $data: getQueryRunnerWithRandomWalkQuery({ seriesCount: 10 }),
new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Outsider, uses global query', title: 'Outsider, has its own query',
key: 'Outsider-global-query', key: 'Outsider-own-query',
placement: { }),
}),
new SceneGridItem({
x: 6, x: 6,
y: 12, y: 12,
width: 12, width: 12,
height: 10, height: 10,
isResizable: true, isResizable: true,
isDraggable: true, isDraggable: true,
}, body: new VizPanel({
pluginId: 'timeseries',
title: 'Outsider, uses global query',
key: 'Outsider-global-query',
}),
}), }),
], ],
}), }),

View File

@ -1,71 +0,0 @@
import { VizPanel, SceneGridLayout, SceneGridRow, SceneTimePicker, SceneTimeRange } from '@grafana/scenes';
import { DashboardScene } from '../dashboard/DashboardScene';
import { getQueryRunnerWithRandomWalkQuery } from './queries';
export function getGridWithRowLayoutTest(): DashboardScene {
return new DashboardScene({
title: 'Grid with row layout test',
body: new SceneGridLayout({
children: [
new SceneGridRow({
title: 'Row A',
key: 'Row A',
isCollapsed: true,
placement: { y: 0 },
children: [
new VizPanel({
pluginId: 'timeseries',
title: 'Row A Child1',
key: 'Row A Child1',
placement: { x: 0, y: 1, width: 12, height: 5, isResizable: true, isDraggable: true },
}),
new VizPanel({
pluginId: 'timeseries',
title: 'Row A Child2',
key: 'Row A Child2',
placement: { x: 0, y: 5, width: 6, height: 5, isResizable: true, isDraggable: true },
}),
],
}),
new SceneGridRow({
title: 'Row B',
key: 'Row B',
isCollapsed: true,
placement: { y: 1 },
children: [
new VizPanel({
pluginId: 'timeseries',
title: 'Row B Child1',
key: 'Row B Child1',
placement: { x: 0, y: 2, width: 12, height: 5, isResizable: false, isDraggable: true },
}),
new VizPanel({
pluginId: 'timeseries',
title: 'Row B Child2',
key: 'Row B Child2',
placement: { x: 0, y: 7, width: 6, height: 5, isResizable: false, isDraggable: true },
}),
],
}),
new VizPanel({
pluginId: 'timeseries',
title: 'Outsider',
key: 'Outsider',
placement: {
x: 2,
y: 12,
width: 12,
height: 10,
isResizable: true,
isDraggable: true,
},
}),
],
}),
$timeRange: new SceneTimeRange(),
$data: getQueryRunnerWithRandomWalkQuery(),
actions: [new SceneTimePicker({})],
});
}

View File

@ -1,91 +0,0 @@
import {
VizPanel,
SceneGridRow,
SceneTimePicker,
SceneFlexLayout,
SceneGridLayout,
SceneTimeRange,
} from '@grafana/scenes';
import { DashboardScene } from '../dashboard/DashboardScene';
import { getQueryRunnerWithRandomWalkQuery } from './queries';
export function getGridWithRowsTest(): DashboardScene {
const panel = new VizPanel({
pluginId: 'timeseries',
title: 'Fill height',
});
const row1 = new SceneGridRow({
title: 'Collapsible/draggable row with flex layout',
placement: { x: 0, y: 0, height: 10 },
children: [
new SceneFlexLayout({
direction: 'row',
children: [
new VizPanel({
pluginId: 'timeseries',
title: 'Fill height',
}),
new VizPanel({
pluginId: 'timeseries',
title: 'Fill height',
}),
new VizPanel({
pluginId: 'timeseries',
title: 'Fill height',
}),
],
}),
],
});
const cell1 = new VizPanel({
placement: {
x: 0,
y: 10,
width: 12,
height: 20,
},
pluginId: 'timeseries',
title: 'Cell 1',
});
const cell2 = new VizPanel({
placement: { x: 12, y: 20, width: 12, height: 10, isResizable: false, isDraggable: false },
pluginId: 'timeseries',
title: 'No resize/no drag',
});
const row2 = new SceneGridRow({
placement: { x: 12, y: 10, height: 10, width: 12 },
title: 'Row with a nested flex layout',
children: [
new SceneFlexLayout({
children: [
new SceneFlexLayout({
direction: 'column',
children: [panel, panel],
}),
new SceneFlexLayout({
direction: 'column',
children: [panel, panel],
}),
],
}),
],
});
const scene = new DashboardScene({
title: 'Grid rows test',
body: new SceneGridLayout({
children: [cell1, cell2, row1, row2],
}),
$timeRange: new SceneTimeRange(),
$data: getQueryRunnerWithRandomWalkQuery(),
actions: [new SceneTimePicker({})],
});
return scene;
}

View File

@ -1,12 +1,8 @@
import { DashboardScene } from '../dashboard/DashboardScene'; import { DashboardScene } from '../dashboard/DashboardScene';
import { getFlexLayoutTest, getRepeaterSceneWithFlexWrap, getScenePanelRepeaterTest } from './demo';
import { getGridLayoutTest } from './grid';
import { getGridWithMultipleTimeRanges } from './gridMultiTimeRange'; import { getGridWithMultipleTimeRanges } from './gridMultiTimeRange';
import { getMultipleGridLayoutTest } from './gridMultiple'; import { getMultipleGridLayoutTest } from './gridMultiple';
import { getGridWithMultipleData } from './gridWithMultipleData'; import { getGridWithMultipleData } from './gridWithMultipleData';
import { getGridWithRowLayoutTest } from './gridWithRow';
import { getNestedScene } from './nested';
import { getQueryVariableDemo } from './queryVariableDemo'; import { getQueryVariableDemo } from './queryVariableDemo';
import { getSceneWithRows } from './sceneWithRows'; import { getSceneWithRows } from './sceneWithRows';
import { getTransformationsDemo } from './transformations'; import { getTransformationsDemo } from './transformations';
@ -18,13 +14,7 @@ interface SceneDef {
} }
export function getScenes(): SceneDef[] { export function getScenes(): SceneDef[] {
return [ return [
{ title: 'Flex layout test', getScene: getFlexLayoutTest },
{ title: 'Panel repeater test', getScene: getScenePanelRepeaterTest },
{ title: 'Panel repeater test flex wrap', getScene: getRepeaterSceneWithFlexWrap },
{ title: 'Nested Scene demo', getScene: getNestedScene },
{ title: 'Scene with rows', getScene: getSceneWithRows }, { title: 'Scene with rows', getScene: getSceneWithRows },
{ title: 'Grid layout test', getScene: getGridLayoutTest },
{ title: 'Grid with row layout test', getScene: getGridWithRowLayoutTest },
{ title: 'Grid with rows and different queries', getScene: getGridWithMultipleData }, { title: 'Grid with rows and different queries', getScene: getGridWithMultipleData },
{ title: 'Grid with rows and different queries and time ranges', getScene: getGridWithMultipleTimeRanges }, { title: 'Grid with rows and different queries and time ranges', getScene: getGridWithMultipleTimeRanges },
{ title: 'Multiple grid layouts test', getScene: getMultipleGridLayoutTest }, { title: 'Multiple grid layouts test', getScene: getMultipleGridLayoutTest },

View File

@ -1,48 +0,0 @@
import { VizPanel, NestedScene, SceneTimePicker, SceneFlexLayout, SceneTimeRange } from '@grafana/scenes';
import { DashboardScene } from '../dashboard/DashboardScene';
import { getQueryRunnerWithRandomWalkQuery } from './queries';
export function getNestedScene(): DashboardScene {
return new DashboardScene({
title: 'Nested Scene demo',
body: new SceneFlexLayout({
direction: 'column',
children: [
new VizPanel({
key: '3',
pluginId: 'timeseries',
title: 'Panel 3',
}),
getInnerScene('Inner scene'),
],
}),
$timeRange: new SceneTimeRange(),
$data: getQueryRunnerWithRandomWalkQuery(),
actions: [new SceneTimePicker({})],
});
}
export function getInnerScene(title: string) {
const scene = new NestedScene({
title: title,
canRemove: true,
canCollapse: true,
body: new SceneFlexLayout({
direction: 'row',
children: [
new VizPanel({
key: '3',
pluginId: 'timeseries',
title: 'Data',
}),
],
}),
$timeRange: new SceneTimeRange(),
$data: getQueryRunnerWithRandomWalkQuery(),
actions: [new SceneTimePicker({})],
});
return scene;
}

View File

@ -9,6 +9,7 @@ import {
CustomVariable, CustomVariable,
DataSourceVariable, DataSourceVariable,
QueryVariable, QueryVariable,
SceneFlexItem,
} from '@grafana/scenes'; } from '@grafana/scenes';
import { DashboardScene } from '../dashboard/DashboardScene'; import { DashboardScene } from '../dashboard/DashboardScene';
@ -49,15 +50,13 @@ export function getQueryVariableDemo(): DashboardScene {
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'row', direction: 'row',
children: [ children: [
new SceneFlexLayout({ new SceneFlexItem({
children: [ width: '40%',
new SceneCanvasText({ body: new SceneCanvasText({
placement: { width: '40%' },
text: 'metric: ${metric}', text: 'metric: ${metric}',
fontSize: 20, fontSize: 20,
align: 'center', align: 'center',
}), }),
],
}), }),
], ],
}), }),

View File

@ -1,4 +1,11 @@
import { VizPanel, NestedScene, SceneTimePicker, SceneFlexLayout, SceneTimeRange } from '@grafana/scenes'; import {
VizPanel,
NestedScene,
SceneTimePicker,
SceneFlexLayout,
SceneTimeRange,
SceneFlexItem,
} from '@grafana/scenes';
import { DashboardScene } from '../dashboard/DashboardScene'; import { DashboardScene } from '../dashboard/DashboardScene';
@ -13,36 +20,43 @@ export function getSceneWithRows(): DashboardScene {
new NestedScene({ new NestedScene({
title: 'Overview', title: 'Overview',
canCollapse: true, canCollapse: true,
// size: { ySizing: 'content', xSizing: 'fill' },
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'row', direction: 'row',
children: [ children: [
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Fill height',
}), }),
new VizPanel({ }),
new SceneFlexItem({
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Fill height',
}), }),
}),
], ],
}), }),
}), }),
new NestedScene({ new NestedScene({
title: 'More server details', title: 'More server details',
// size: { ySizing: 'content', xSizing: 'fill' },
canCollapse: true, canCollapse: true,
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'row', direction: 'row',
children: [ children: [
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Fill height',
}), }),
new VizPanel({ }),
new SceneFlexItem({
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Fill height', title: 'Fill height',
}), }),
}),
], ],
}), }),
}), }),

View File

@ -1,4 +1,11 @@
import { SceneTimePicker, SceneFlexLayout, VizPanel, SceneDataTransformer, SceneTimeRange } from '@grafana/scenes'; import {
SceneTimePicker,
SceneFlexLayout,
VizPanel,
SceneDataTransformer,
SceneTimeRange,
SceneFlexItem,
} from '@grafana/scenes';
import { DashboardScene } from '../dashboard/DashboardScene'; import { DashboardScene } from '../dashboard/DashboardScene';
@ -10,17 +17,22 @@ export function getTransformationsDemo(): DashboardScene {
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'row', direction: 'row',
children: [ children: [
new SceneFlexLayout({ new SceneFlexItem({
body: new SceneFlexLayout({
direction: 'column', direction: 'column',
children: [ children: [
new SceneFlexLayout({ new SceneFlexItem({
body: new SceneFlexLayout({
direction: 'row', direction: 'row',
children: [ children: [
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'Source data (global query', title: 'Source data (global query',
}), }),
new VizPanel({ }),
new SceneFlexItem({
body: new VizPanel({
pluginId: 'stat', pluginId: 'stat',
title: 'Transformed data', title: 'Transformed data',
$data: new SceneDataTransformer({ $data: new SceneDataTransformer({
@ -34,10 +46,12 @@ export function getTransformationsDemo(): DashboardScene {
], ],
}), }),
}), }),
}),
], ],
}), }),
}),
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
$data: new SceneDataTransformer({ $data: new SceneDataTransformer({
$data: getQueryRunnerWithRandomWalkQuery(), $data: getQueryRunnerWithRandomWalkQuery(),
transformations: [ transformations: [
@ -53,8 +67,10 @@ export function getTransformationsDemo(): DashboardScene {
pluginId: 'stat', pluginId: 'stat',
title: 'Query with predefined transformations', title: 'Query with predefined transformations',
}), }),
}),
], ],
}), }),
}),
], ],
}), }),
$timeRange: new SceneTimeRange(), $timeRange: new SceneTimeRange(),

View File

@ -11,6 +11,7 @@ import {
TestVariable, TestVariable,
NestedScene, NestedScene,
TextBoxVariable, TextBoxVariable,
SceneFlexItem,
} from '@grafana/scenes'; } from '@grafana/scenes';
import { DashboardScene } from '../dashboard/DashboardScene'; import { DashboardScene } from '../dashboard/DashboardScene';
@ -65,49 +66,63 @@ export function getVariablesDemo(): DashboardScene {
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'row', direction: 'row',
children: [ children: [
new SceneFlexLayout({ new SceneFlexItem({
body: new SceneFlexLayout({
direction: 'column', direction: 'column',
children: [ children: [
new SceneFlexLayout({ new SceneFlexItem({
body: new SceneFlexLayout({
children: [ children: [
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'handler: $handler', title: 'handler: $handler',
$data: getQueryRunnerWithRandomWalkQuery({ $data: getQueryRunnerWithRandomWalkQuery({
alias: 'handler: $handler', alias: 'handler: $handler',
}), }),
}), }),
new SceneCanvasText({ }),
new SceneFlexItem({
body: new SceneCanvasText({
text: 'Text: ${textbox}', text: 'Text: ${textbox}',
fontSize: 20, fontSize: 20,
align: 'center', align: 'center',
}), }),
new SceneCanvasText({ }),
placement: { width: '40%' }, new SceneFlexItem({
width: '40%',
body: new SceneCanvasText({
text: 'server: ${server} pod:${pod}', text: 'server: ${server} pod:${pod}',
fontSize: 20, fontSize: 20,
align: 'center', align: 'center',
}), }),
}),
], ],
}), }),
new NestedScene({ }),
new SceneFlexItem({
body: new NestedScene({
title: 'Collapsable inner scene', title: 'Collapsable inner scene',
canCollapse: true, canCollapse: true,
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'row', direction: 'row',
children: [ children: [
new VizPanel({ new SceneFlexItem({
body: new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'handler: $handler', title: 'handler: $handler',
$data: getQueryRunnerWithRandomWalkQuery({ $data: getQueryRunnerWithRandomWalkQuery({
alias: 'handler: $handler', alias: 'handler: $handler',
}), }),
}), }),
}),
], ],
}), }),
}), }),
}),
], ],
}), }),
}),
], ],
}), }),
$timeRange: new SceneTimeRange(), $timeRange: new SceneTimeRange(),
@ -158,22 +173,22 @@ export function getVariablesDemoWithAll(): DashboardScene {
body: new SceneFlexLayout({ body: new SceneFlexLayout({
direction: 'row', direction: 'row',
children: [ children: [
new SceneFlexLayout({ new SceneFlexItem({
children: [ body: new VizPanel({
new VizPanel({
pluginId: 'timeseries', pluginId: 'timeseries',
title: 'handler: $handler', title: 'handler: $handler',
$data: getQueryRunnerWithRandomWalkQuery({ $data: getQueryRunnerWithRandomWalkQuery({
alias: 'handler: $handler', alias: 'handler: $handler',
}), }),
}), }),
new SceneCanvasText({ }),
placement: { width: '40%' }, new SceneFlexItem({
width: '40%',
body: new SceneCanvasText({
text: 'server: ${server} pod:${pod}', text: 'server: ${server} pod:${pod}',
fontSize: 20, fontSize: 20,
align: 'center', align: 'center',
}), }),
],
}), }),
], ],
}), }),

View File

@ -1,4 +1,5 @@
import { formatRegistry, FormatRegistryID } from '@grafana/scenes'; import { formatRegistry } from '@grafana/scenes';
import { VariableFormatID } from '@grafana/schema';
import { isAdHoc } from '../variables/guard'; import { isAdHoc } from '../variables/guard';
@ -12,7 +13,7 @@ export function formatVariableValue(value: any, format?: any, variable?: any, te
return ''; return '';
} }
if (isAdHoc(variable) && format !== FormatRegistryID.queryParam) { if (isAdHoc(variable) && format !== VariableFormatID.QueryParam) {
return ''; return '';
} }
@ -26,7 +27,7 @@ export function formatVariableValue(value: any, format?: any, variable?: any, te
} }
if (!format) { if (!format) {
format = FormatRegistryID.glob; format = VariableFormatID.Glob;
} }
// some formats have arguments that come after ':' character // some formats have arguments that come after ':' character
@ -42,7 +43,7 @@ export function formatVariableValue(value: any, format?: any, variable?: any, te
if (!formatItem) { if (!formatItem) {
console.error(`Variable format ${format} not found. Using glob format as fallback.`); console.error(`Variable format ${format} not found. Using glob format as fallback.`);
formatItem = formatRegistry.get(FormatRegistryID.glob); formatItem = formatRegistry.get(VariableFormatID.Glob);
} }
const formatVariable = getVariableWrapper(variable, value, text ?? value); const formatVariable = getVariableWrapper(variable, value, text ?? value);

View File

@ -1,6 +1,7 @@
import { dateTime, TimeRange } from '@grafana/data'; import { dateTime, TimeRange } from '@grafana/data';
import { setDataSourceSrv, VariableInterpolation } from '@grafana/runtime'; import { setDataSourceSrv, VariableInterpolation } from '@grafana/runtime';
import { FormatRegistryID, TestVariable } from '@grafana/scenes'; import { TestVariable } from '@grafana/scenes';
import { VariableFormatID } from '@grafana/schema';
import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput'; import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput';
import { initTemplateSrv } from '../../../test/helpers/initTemplateSrv'; import { initTemplateSrv } from '../../../test/helpers/initTemplateSrv';
@ -697,9 +698,9 @@ describe('templateSrv', () => {
}); });
it(`should not be handled by any registry items except for queryparam`, () => { it(`should not be handled by any registry items except for queryparam`, () => {
const registryItems = Object.values(FormatRegistryID); const registryItems = Object.values(VariableFormatID);
for (const registryItem of registryItems) { for (const registryItem of registryItems) {
if (registryItem === FormatRegistryID.queryParam) { if (registryItem === VariableFormatID.QueryParam) {
continue; continue;
} }

View File

@ -15,7 +15,8 @@ import {
TemplateSrv as BaseTemplateSrv, TemplateSrv as BaseTemplateSrv,
VariableInterpolation, VariableInterpolation,
} from '@grafana/runtime'; } from '@grafana/runtime';
import { sceneGraph, FormatRegistryID, VariableCustomFormatterFn } from '@grafana/scenes'; import { sceneGraph, VariableCustomFormatterFn } from '@grafana/scenes';
import { VariableFormatID } from '@grafana/schema';
import { variableAdapters } from '../variables/adapters'; import { variableAdapters } from '../variables/adapters';
import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../variables/constants'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../variables/constants';
@ -290,7 +291,7 @@ export class TemplateSrv implements BaseTemplateSrv {
return match; return match;
} }
if (format === FormatRegistryID.queryParam || isAdHoc(variable)) { if (format === VariableFormatID.QueryParam || isAdHoc(variable)) {
const value = variableAdapters.get(variable.type).getValueForUrl(variable); const value = variableAdapters.get(variable.type).getValueForUrl(variable);
const text = isAdHoc(variable) ? variable.id : variable.current.text; const text = isAdHoc(variable) ? variable.id : variable.current.text;
@ -309,7 +310,7 @@ export class TemplateSrv implements BaseTemplateSrv {
value = this.getAllValue(variable); value = this.getAllValue(variable);
text = ALL_VARIABLE_TEXT; text = ALL_VARIABLE_TEXT;
// skip formatting of custom all values unless format set to text or percentencode // skip formatting of custom all values unless format set to text or percentencode
if (variable.allValue && format !== FormatRegistryID.text && format !== FormatRegistryID.percentEncode) { if (variable.allValue && format !== VariableFormatID.Text && format !== VariableFormatID.PercentEncode) {
return this.replace(value); return this.replace(value);
} }
} }

View File

@ -1,6 +1,6 @@
import { ScopedVars } from '@grafana/data'; import { ScopedVars } from '@grafana/data';
import { TemplateSrv } from '@grafana/runtime'; import { TemplateSrv } from '@grafana/runtime';
import { FormatRegistryID } from '@grafana/scenes'; import { VariableFormatID } from '@grafana/schema';
import { applyQueryDefaults } from 'app/features/plugins/sql/defaults'; import { applyQueryDefaults } from 'app/features/plugins/sql/defaults';
import { SQLQuery, SqlQueryModel } from 'app/features/plugins/sql/types'; import { SQLQuery, SqlQueryModel } from 'app/features/plugins/sql/types';
@ -16,7 +16,7 @@ export class PostgresQueryModel implements SqlQueryModel {
} }
interpolate() { interpolate() {
return this.templateSrv?.replace(this.target.rawSql, this.scopedVars, FormatRegistryID.sqlString) || ''; return this.templateSrv?.replace(this.target.rawSql, this.scopedVars, VariableFormatID.SQLString) || '';
} }
quoteLiteral(value: string) { quoteLiteral(value: string) {

View File

@ -3326,9 +3326,9 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"@grafana/scenes@npm:^0.0.28": "@grafana/scenes@npm:^0.2.0":
version: 0.0.28 version: 0.2.0
resolution: "@grafana/scenes@npm:0.0.28" resolution: "@grafana/scenes@npm:0.2.0"
dependencies: dependencies:
"@grafana/e2e-selectors": ^9.4.3 "@grafana/e2e-selectors": ^9.4.3
"@grafana/experimental": 1.0.1 "@grafana/experimental": 1.0.1
@ -3336,7 +3336,7 @@ __metadata:
react-use: 17.4.0 react-use: 17.4.0
react-virtualized-auto-sizer: 1.0.7 react-virtualized-auto-sizer: 1.0.7
uuid: ^9.0.0 uuid: ^9.0.0
checksum: 0cfcfda325f42c1aee571e32411514954d5a14ac7b40102f33c1c52bd39e65766c3081e634de303379dccd363f78ed4ce022ac71a4d6b7ab3658f18ac81163e7 checksum: a04fe353eec8f048de7c51079e7f7bef461b372c3c086d5ff3be46fc0e70a21e907272f0ed05a41633847a3736c5e65e441ffa20b2c18eedea813decf3eef636
languageName: node languageName: node
linkType: hard linkType: hard
@ -20110,7 +20110,7 @@ __metadata:
"@grafana/lezer-logql": 0.1.2 "@grafana/lezer-logql": 0.1.2
"@grafana/monaco-logql": ^0.0.7 "@grafana/monaco-logql": ^0.0.7
"@grafana/runtime": "workspace:*" "@grafana/runtime": "workspace:*"
"@grafana/scenes": ^0.0.28 "@grafana/scenes": ^0.2.0
"@grafana/schema": "workspace:*" "@grafana/schema": "workspace:*"
"@grafana/toolkit": "workspace:*" "@grafana/toolkit": "workspace:*"
"@grafana/tsconfig": ^1.2.0-rc1 "@grafana/tsconfig": ^1.2.0-rc1