diff --git a/package.json b/package.json index 1481eea5a15..b319ce93e6d 100644 --- a/package.json +++ b/package.json @@ -267,7 +267,7 @@ "@grafana/lezer-logql": "0.1.2", "@grafana/monaco-logql": "^0.0.7", "@grafana/runtime": "workspace:*", - "@grafana/scenes": "^0.0.28", + "@grafana/scenes": "^0.2.0", "@grafana/schema": "workspace:*", "@grafana/ui": "workspace:*", "@kusto/monaco-kusto": "5.3.6", diff --git a/public/app/features/panel/panellinks/link_srv.ts b/public/app/features/panel/panellinks/link_srv.ts index ef576e2d4a3..1d2037e8a98 100644 --- a/public/app/features/panel/panellinks/link_srv.ts +++ b/public/app/features/panel/panellinks/link_srv.ts @@ -20,7 +20,7 @@ import { VariableSuggestionsScope, } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; -import { FormatRegistryID } from '@grafana/scenes'; +import { VariableFormatID } from '@grafana/schema'; import { getConfig } from 'app/core/config'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; @@ -305,7 +305,7 @@ export class LinkSrv implements LinkService { }; if (replaceVariables) { - info.href = replaceVariables(info.href, undefined, FormatRegistryID.percentEncode); + info.href = replaceVariables(info.href, undefined, VariableFormatID.PercentEncode); info.title = replaceVariables(link.title); } diff --git a/public/app/features/scenes/apps/GrafanaMonitoringApp.tsx b/public/app/features/scenes/apps/GrafanaMonitoringApp.tsx index e42b2cd068c..5a68485a863 100644 --- a/public/app/features/scenes/apps/GrafanaMonitoringApp.tsx +++ b/public/app/features/scenes/apps/GrafanaMonitoringApp.tsx @@ -9,6 +9,7 @@ import { SceneRouteMatch, EmbeddedScene, SceneAppPageLike, + SceneFlexItem, } from '@grafana/scenes'; import { usePageNav } from 'app/core/components/Page/usePageNav'; import { PluginPageContext, PluginPageContextType } from 'app/features/plugins/components/PluginPageContext'; @@ -131,8 +132,10 @@ export function getSecondLevelDrilldown( return new EmbeddedScene({ body: new SceneFlexLayout({ children: [ - new SceneCanvasText({ - text: 'Drilldown: ' + secondLevel, + new SceneFlexItem({ + body: new SceneCanvasText({ + text: 'Drilldown: ' + secondLevel, + }), }), ], }), diff --git a/public/app/features/scenes/apps/scenes.ts b/public/app/features/scenes/apps/scenes.ts index 40aafdc3280..95316b54c7f 100644 --- a/public/app/features/scenes/apps/scenes.ts +++ b/public/app/features/scenes/apps/scenes.ts @@ -15,6 +15,7 @@ import { SceneControlsSpacer, SceneDataTransformer, SceneRefreshPicker, + SceneFlexItem, } from '@grafana/scenes'; import { PromQuery } from 'app/plugins/datasource/prometheus/types'; @@ -142,63 +143,70 @@ export function getHttpHandlerListScene(): EmbeddedScene { children: [], }), getLayoutChild: (data, frame, frameIndex) => { - return new SceneFlexLayout({ + return new SceneFlexItem({ key: `panel-${frameIndex}`, - direction: 'row', - placement: { minHeight: 200 }, + minHeight: 200, $data: new SceneDataNode({ data: { ...data, series: [frame], }, }), - children: [ - new VizPanel({ - pluginId: 'timeseries', - // titleLink: { - // path: `/scenes/grafana-monitoring/handlers/${encodeURIComponent(frame.fields[1].labels.handler)}`, - // queryKeys: ['from', 'to', 'var-instance'], - // }, - title: getFrameDisplayName(frame), - options: { - legend: { displayMode: 'hidden' }, - }, - }), - new VizPanel({ - placement: { width: 200 }, - title: 'Last', - pluginId: 'stat', - fieldConfig: { - defaults: { - displayName: 'Last', - links: [ - { - title: 'Go to handler drilldown view', - url: ``, - onBuildUrl: () => { - const params = locationService.getSearchObject(); - return getLinkUrlWithAppUrlState( - '/scenes/grafana-monitoring/handlers/${__field.labels.handler:percentencode}', - params - ); - }, + body: new SceneFlexLayout({ + direction: 'row', + children: [ + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'timeseries', + // titleLink: { + // path: `/scenes/grafana-monitoring/handlers/${encodeURIComponent(frame.fields[1].labels.handler)}`, + // queryKeys: ['from', 'to', 'var-instance'], + // }, + title: getFrameDisplayName(frame), + options: { + legend: { displayMode: 'hidden' }, + }, + }), + }), + + new SceneFlexItem({ + width: 200, + body: new VizPanel({ + title: 'Last', + pluginId: 'stat', + fieldConfig: { + defaults: { + displayName: 'Last', + links: [ + { + title: 'Go to handler drilldown view', + url: ``, + onBuildUrl: () => { + const params = locationService.getSearchObject(); + return getLinkUrlWithAppUrlState( + '/scenes/grafana-monitoring/handlers/${__field.labels.handler:percentencode}', + params + ); + }, + }, + ], }, - ], - }, - overrides: [], - }, - options: { - graphMode: 'none', - textMode: 'value', - }, - }), - ], + overrides: [], + }, + options: { + graphMode: 'none', + textMode: 'value', + }, + }), + }), + ], + }), }); }, }); const layout = new SceneFlexLayout({ - children: [httpHandlersTable], + children: [new SceneFlexItem({ body: httpHandlersTable })], }); const sceneToggle = new SceneRadioToggle({ @@ -209,7 +217,7 @@ export function getHttpHandlerListScene(): EmbeddedScene { value: 'table', onChange: (value) => { if (value === 'table') { - layout.setState({ children: [httpHandlersTable] }); + layout.setState({ children: [new SceneFlexItem({ body: httpHandlersTable })] }); } else { layout.setState({ children: [graphsScene] }); } @@ -257,20 +265,23 @@ export function getHandlerDetailsScene(handler: string): EmbeddedScene { body: new SceneFlexLayout({ direction: 'column', children: [ - new VizPanel({ - $data: reqDurationTimeSeries, - pluginId: 'timeseries', - title: 'Request duration avg (ms)', - placement: {}, - //displayMode: 'transparent', - options: {}, + new SceneFlexItem({ + body: new VizPanel({ + $data: reqDurationTimeSeries, + pluginId: 'timeseries', + title: 'Request duration avg (ms)', + //displayMode: 'transparent', + options: {}, + }), }), - new VizPanel({ - $data: reqCountTimeSeries, - pluginId: 'timeseries', - title: 'Request count/s', - //displayMode: 'transparent', - options: {}, + new SceneFlexItem({ + body: new VizPanel({ + $data: reqCountTimeSeries, + pluginId: 'timeseries', + title: 'Request count/s', + //displayMode: 'transparent', + options: {}, + }), }), ], }), @@ -322,79 +333,94 @@ export function getOverviewScene(): EmbeddedScene { body: new SceneFlexLayout({ direction: 'column', children: [ - new SceneFlexLayout({ - placement: { height: 150 }, - children: [ - getInstantStatPanel('grafana_stat_totals_dashboard', 'Dashboards'), - getInstantStatPanel('grafana_stat_total_users', 'Users'), - getInstantStatPanel('sum(grafana_stat_totals_datasource)', 'Data sources'), - getInstantStatPanel('grafana_stat_total_service_account_tokens', 'Service account tokens'), - ], - }), - new VizPanel({ - $data: new SceneQueryRunner({ - datasource: { uid: 'gdev-prometheus' }, - queries: [ - { - refId: 'A', - expr: `sum(process_resident_memory_bytes{job="grafana", instance=~"$instance"})`, - range: true, - format: 'time_series', - maxDataPoints: 500, - }, + new SceneFlexItem({ + height: 150, + body: new SceneFlexLayout({ + children: [ + new SceneFlexItem({ + body: getInstantStatPanel('grafana_stat_totals_dashboard', 'Dashboards'), + }), + 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'), + }), ], }), - pluginId: 'timeseries', - title: 'Memory usage', - options: { - legend: { - showLegend: false, - }, - }, - fieldConfig: { - defaults: { - unit: 'bytes', - min: 0, - custom: { - lineWidth: 2, - fillOpacity: 6, - //gradientMode: 'opacity', - }, - }, - overrides: [], - }, }), - new VizPanel({ - $data: new SceneQueryRunner({ - datasource: { uid: 'gdev-prometheus' }, - queries: [ - { - refId: 'A', - expr: `sum(go_goroutines{job="grafana", instance=~"$instance"})`, - range: true, - format: 'time_series', - maxDataPoints: 500, + + new SceneFlexItem({ + body: new VizPanel({ + $data: new SceneQueryRunner({ + datasource: { uid: 'gdev-prometheus' }, + queries: [ + { + refId: 'A', + expr: `sum(process_resident_memory_bytes{job="grafana", instance=~"$instance"})`, + range: true, + format: 'time_series', + maxDataPoints: 500, + }, + ], + }), + pluginId: 'timeseries', + title: 'Memory usage', + options: { + legend: { + showLegend: false, }, - ], + }, + fieldConfig: { + defaults: { + unit: 'bytes', + min: 0, + custom: { + lineWidth: 2, + fillOpacity: 6, + //gradientMode: 'opacity', + }, + }, + overrides: [], + }, }), - pluginId: 'timeseries', - title: 'Go routines', - options: { - legend: { - showLegend: false, - }, - }, - fieldConfig: { - defaults: { - min: 0, - custom: { - lineWidth: 2, - fillOpacity: 6, - //gradientMode: 'opacity', + }), + new SceneFlexItem({ + body: new VizPanel({ + $data: new SceneQueryRunner({ + datasource: { uid: 'gdev-prometheus' }, + queries: [ + { + refId: 'A', + expr: `sum(go_goroutines{job="grafana", instance=~"$instance"})`, + range: true, + format: 'time_series', + maxDataPoints: 500, + }, + ], + }), + pluginId: 'timeseries', + title: 'Go routines', + options: { + legend: { + showLegend: false, }, }, - overrides: [], - }, + fieldConfig: { + defaults: { + min: 0, + custom: { + lineWidth: 2, + fillOpacity: 6, + //gradientMode: 'opacity', + }, + }, + overrides: [], + }, + }), }), ], }), @@ -455,31 +481,35 @@ export function getHandlerLogsScene(handler: string): EmbeddedScene { body: new SceneFlexLayout({ direction: 'column', children: [ - new VizPanel({ - pluginId: 'text', - title: '', - options: { - mode: 'markdown', - content: ` -[mupp](/scenes/grafana-monitoring/handlers/${encodeURIComponent(handler)}/logs/mupp) -[mapp](/scenes/grafana-monitoring/handlers/${encodeURIComponent(handler)}/logs/mapp) -`, - }, + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'text', + title: '', + options: { + mode: 'markdown', + content: ` + [mupp](/scenes/grafana-monitoring/handlers/${encodeURIComponent(handler)}/logs/mupp) + [mapp](/scenes/grafana-monitoring/handlers/${encodeURIComponent(handler)}/logs/mapp) + `, + }, + }), }), - new VizPanel({ - $data: logsQuery, - pluginId: 'logs', - title: '', - options: { - showTime: true, - showLabels: false, - showCommonLabels: false, - wrapLogMessage: true, - prettifyLogMessage: false, - enableLogDetails: true, - dedupStrategy: 'none', - sortOrder: 'Descending', - }, + new SceneFlexItem({ + body: new VizPanel({ + $data: logsQuery, + pluginId: 'logs', + title: '', + options: { + showTime: true, + showLabels: false, + showCommonLabels: false, + wrapLogMessage: true, + prettifyLogMessage: false, + enableLogDetails: true, + dedupStrategy: 'none', + sortOrder: 'Descending', + }, + }), }), ], }), @@ -513,20 +543,22 @@ export function getOverviewLogsScene(): EmbeddedScene { body: new SceneFlexLayout({ direction: 'column', children: [ - new VizPanel({ - $data: logsQuery, - pluginId: 'logs', - title: '', - options: { - showTime: true, - showLabels: false, - showCommonLabels: false, - wrapLogMessage: true, - prettifyLogMessage: false, - enableLogDetails: true, - dedupStrategy: 'none', - sortOrder: 'Descending', - }, + new SceneFlexItem({ + body: new VizPanel({ + $data: logsQuery, + pluginId: 'logs', + title: '', + options: { + showTime: true, + showLabels: false, + showCommonLabels: false, + wrapLogMessage: true, + prettifyLogMessage: false, + enableLogDetails: true, + dedupStrategy: 'none', + sortOrder: 'Descending', + }, + }), }), ], }), diff --git a/public/app/features/scenes/dashboard/DashboardsLoader.test.ts b/public/app/features/scenes/dashboard/DashboardsLoader.test.ts index ec9d368a740..9daacdd517c 100644 --- a/public/app/features/scenes/dashboard/DashboardsLoader.test.ts +++ b/public/app/features/scenes/dashboard/DashboardsLoader.test.ts @@ -3,6 +3,7 @@ import { DataSourceVariable, QueryVariable, SceneDataTransformer, + SceneGridItem, SceneGridLayout, SceneGridRow, SceneQueryRunner, @@ -169,10 +170,10 @@ describe('DashboardLoader', () => { const rowScene = body.state.children[0] as SceneGridRow; expect(rowScene).toBeInstanceOf(SceneGridRow); 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.children).toHaveLength(1); - expect(rowScene.state.children[0]).toBeInstanceOf(VizPanel); + expect(rowScene.state.children[0]).toBeInstanceOf(SceneGridItem); }); it('should create panels within expanded row', () => { @@ -233,18 +234,18 @@ describe('DashboardLoader', () => { expect(body.state.children).toHaveLength(3); expect(body).toBeInstanceOf(SceneGridLayout); // Panel out of row - expect(body.state.children[0]).toBeInstanceOf(VizPanel); - const panelOutOfRowVizPanel = body.state.children[0] as VizPanel; - expect(panelOutOfRowVizPanel.state.title).toBe(panelOutOfRow.title); + expect(body.state.children[0]).toBeInstanceOf(SceneGridItem); + const panelOutOfRowVizPanel = body.state.children[0] as SceneGridItem; + expect((panelOutOfRowVizPanel.state.body as VizPanel)?.state.title).toBe(panelOutOfRow.title); // Row with panel expect(body.state.children[1]).toBeInstanceOf(SceneGridRow); const rowWithPanelsScene = body.state.children[1] as SceneGridRow; expect(rowWithPanelsScene.state.title).toBe(rowWithPanel.title); expect(rowWithPanelsScene.state.children).toHaveLength(1); // Panel within row - expect(rowWithPanelsScene.state.children[0]).toBeInstanceOf(VizPanel); - const panelInRowVizPanel = rowWithPanelsScene.state.children[0] as VizPanel; - expect(panelInRowVizPanel.state.title).toBe(panelInRow.title); + expect(rowWithPanelsScene.state.children[0]).toBeInstanceOf(SceneGridItem); + const panelInRowVizPanel = rowWithPanelsScene.state.children[0] as SceneGridItem; + expect((panelInRowVizPanel.state.body as VizPanel).state.title).toBe(panelInRow.title); // Empty row expect(body.state.children[2]).toBeInstanceOf(SceneGridRow); const emptyRowScene = body.state.children[2] as SceneGridRow; @@ -295,22 +296,23 @@ describe('DashboardLoader', () => { ], }; const vizPanelSceneObject = createVizPanelFromPanelModel(new PanelModel(panel)); - - expect(vizPanelSceneObject.state.title).toBe('test'); - expect(vizPanelSceneObject.state.pluginId).toBe('test-plugin'); - expect(vizPanelSceneObject.state.placement).toEqual({ x: 0, y: 0, width: 12, height: 8 }); - expect(vizPanelSceneObject.state.options).toEqual(panel.options); - expect(vizPanelSceneObject.state.fieldConfig).toEqual(panel.fieldConfig); - expect(vizPanelSceneObject.state.pluginVersion).toBe('1.0.0'); + const vizPanelItelf = vizPanelSceneObject.state.body as VizPanel; + expect(vizPanelItelf?.state.title).toBe('test'); + expect(vizPanelItelf?.state.pluginId).toBe('test-plugin'); + expect(vizPanelSceneObject.state.x).toEqual(0); + expect(vizPanelSceneObject.state.y).toEqual(0); + expect(vizPanelSceneObject.state.width).toEqual(12); + 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( - ((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); 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); - expect((vizPanelSceneObject.state.$data as SceneDataTransformer)?.state.transformations).toEqual( - panel.transformations - ); + expect((vizPanelItelf.state.$data as SceneDataTransformer)?.state.transformations).toEqual(panel.transformations); }); it('should initalize the VizPanel without title and transparent true', () => { @@ -323,8 +325,8 @@ describe('DashboardLoader', () => { const vizPanelSceneObject = createVizPanelFromPanelModel(new PanelModel(panel)); - expect(vizPanelSceneObject.state.displayMode).toEqual('transparent'); - expect(vizPanelSceneObject.state.hoverHeader).toEqual(true); + expect((vizPanelSceneObject.state.body as VizPanel)?.state.displayMode).toEqual('transparent'); + expect((vizPanelSceneObject.state.body as VizPanel)?.state.hoverHeader).toEqual(true); }); }); @@ -586,7 +588,7 @@ describe('DashboardLoader', () => { hide: 2, label: 'constant', name: 'constant', - skipUrlSync: false, + skipUrlSync: true, type: 'constant', value: 'test', }); diff --git a/public/app/features/scenes/dashboard/DashboardsLoader.ts b/public/app/features/scenes/dashboard/DashboardsLoader.ts index 306a04cc7ef..663ee91d789 100644 --- a/public/app/features/scenes/dashboard/DashboardsLoader.ts +++ b/public/app/features/scenes/dashboard/DashboardsLoader.ts @@ -11,7 +11,6 @@ import { SceneGridLayout, SceneGridRow, SceneTimeRange, - SceneObject, SceneQueryRunner, SceneVariableSet, VariableValueSelectors, @@ -21,6 +20,7 @@ import { QueryVariable, ConstantVariable, SceneDataTransformer, + SceneGridItem, } from '@grafana/scenes'; import { StateManagerBase } from 'app/core/services/StateManagerBase'; import { dashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv'; @@ -81,14 +81,14 @@ export class DashboardLoader extends StateManagerBase { } } -export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneObject[] { +export function createSceneObjectsForPanels(oldPanels: PanelModel[]): Array { // collects all panels and rows - const panels: SceneObject[] = []; + const panels: Array = []; // indicates expanded row that's currently processed let currentRow: PanelModel | null = null; // collects panels in the currently processed, expanded row - let currentRowPanels: SceneObject[] = []; + let currentRowPanels: SceneGridItem[] = []; for (const panel of oldPanels) { if (panel.type === 'row') { @@ -99,9 +99,7 @@ export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneObjec new SceneGridRow({ title: panel.title, isCollapsed: true, - placement: { - y: panel.gridPos.y, - }, + y: panel.gridPos.y, children: panel.panels ? panel.panels.map(createVizPanelFromPanelModel) : [], }) ); @@ -116,9 +114,7 @@ export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneObjec panels.push( new SceneGridRow({ title: currentRow!.title, - placement: { - y: currentRow.gridPos.y, - }, + y: currentRow.gridPos.y, children: currentRowPanels, }) ); @@ -144,9 +140,7 @@ export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneObjec panels.push( new SceneGridRow({ title: currentRow!.title, - placement: { - y: currentRow.gridPos.y, - }, + y: currentRow.gridPos.y, children: currentRowPanels, }) ); @@ -263,27 +257,29 @@ export function createVizPanelFromPanelModel(panel: PanelModel) { maxDataPoints: panel.maxDataPoints ?? undefined, }); - return new VizPanel({ - title: panel.title, - pluginId: panel.type, - placement: { - x: panel.gridPos.x, - y: panel.gridPos.y, - width: panel.gridPos.w, - height: panel.gridPos.h, - }, - options: panel.options ?? {}, - fieldConfig: panel.fieldConfig, - pluginVersion: panel.pluginVersion, - displayMode: panel.transparent ? 'transparent' : undefined, - // To be replaced with it's own option persited option instead derived - hoverHeader: !panel.title && !panel.timeFrom && !panel.timeShift, - $data: panel.transformations?.length - ? new SceneDataTransformer({ - $data: queryRunner, - transformations: panel.transformations, - }) - : queryRunner, + return new SceneGridItem({ + x: panel.gridPos.x, + y: panel.gridPos.y, + width: panel.gridPos.w, + height: panel.gridPos.h, + isDraggable: true, + isResizable: true, + body: new VizPanel({ + title: panel.title, + pluginId: panel.type, + options: panel.options ?? {}, + fieldConfig: panel.fieldConfig, + pluginVersion: panel.pluginVersion, + displayMode: panel.transparent ? 'transparent' : undefined, + // To be replaced with it's own option persited option instead derived + hoverHeader: !panel.title && !panel.timeFrom && !panel.timeShift, + $data: panel.transformations?.length + ? new SceneDataTransformer({ + $data: queryRunner, + transformations: panel.transformations, + }) + : queryRunner, + }), }); } diff --git a/public/app/features/scenes/scenes/demo.tsx b/public/app/features/scenes/scenes/demo.tsx deleted file mode 100644 index 13ef5a0e647..00000000000 --- a/public/app/features/scenes/scenes/demo.tsx +++ /dev/null @@ -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({}), - ], - }); -} diff --git a/public/app/features/scenes/scenes/grid.tsx b/public/app/features/scenes/scenes/grid.tsx deleted file mode 100644 index 5dc2ecd576b..00000000000 --- a/public/app/features/scenes/scenes/grid.tsx +++ /dev/null @@ -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({})], - }); -} diff --git a/public/app/features/scenes/scenes/gridMultiTimeRange.tsx b/public/app/features/scenes/scenes/gridMultiTimeRange.tsx index 259cacde635..3969e858028 100644 --- a/public/app/features/scenes/scenes/gridMultiTimeRange.tsx +++ b/public/app/features/scenes/scenes/gridMultiTimeRange.tsx @@ -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 { DashboardScene } from '../dashboard/DashboardScene'; @@ -22,36 +29,49 @@ export function getGridWithMultipleTimeRanges(): DashboardScene { title: 'Row A - has its own query, last year time range', key: 'Row A', isCollapsed: true, - placement: { y: 0 }, + 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 SceneGridItem({ + x: 0, + y: 1, + width: 12, + height: 5, + isResizable: true, + isDraggable: true, + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Row A Child1', + key: 'Row A Child1', + }), }), - 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 SceneGridItem({ + x: 0, + y: 5, + width: 6, + height: 5, + isResizable: true, + isDraggable: true, + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Row A Child2', + key: 'Row A Child2', + }), }), ], }), - - new VizPanel({ - $data: getQueryRunnerWithRandomWalkQuery(), - pluginId: 'timeseries', - title: 'Outsider, has its own query', - key: 'Outsider-own-query', - placement: { - x: 0, - y: 12, - width: 6, - height: 10, - isResizable: true, - isDraggable: true, - }, + new SceneGridItem({ + x: 0, + y: 12, + width: 6, + height: 10, + isResizable: true, + isDraggable: true, + body: new VizPanel({ + $data: getQueryRunnerWithRandomWalkQuery(), + pluginId: 'timeseries', + title: 'Outsider, has its own query', + key: 'Outsider-own-query', + }), }), ], }), diff --git a/public/app/features/scenes/scenes/gridMultiple.tsx b/public/app/features/scenes/scenes/gridMultiple.tsx index 42ae6a51967..635b09c427f 100644 --- a/public/app/features/scenes/scenes/gridMultiple.tsx +++ b/public/app/features/scenes/scenes/gridMultiple.tsx @@ -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'; @@ -9,79 +17,119 @@ export function getMultipleGridLayoutTest(): DashboardScene { title: 'Multiple grid layouts test', body: new SceneFlexLayout({ children: [ - new SceneGridLayout({ - children: [ - new VizPanel({ - placement: { + new SceneFlexItem({ + body: new SceneGridLayout({ + children: [ + new SceneGridItem({ x: 0, y: 0, width: 12, height: 10, isDraggable: true, isResizable: true, - }, - pluginId: 'timeseries', - title: 'Dragabble and resizable', - }), - new VizPanel({ - placement: { x: 12, y: 0, width: 12, height: 10, isResizable: false, isDraggable: true }, - pluginId: 'timeseries', - title: 'Draggable only', - }), - new SceneFlexLayout({ - placement: { x: 6, y: 11, width: 12, height: 10, isResizable: false, isDraggable: true }, - direction: 'column', - children: [ - new VizPanel({ - placement: { ySizing: 'fill' }, + body: new VizPanel({ pluginId: 'timeseries', - title: 'Fill height', + title: 'Dragabble and resizable', }), - new VizPanel({ - placement: { ySizing: 'fill' }, + }), + new SceneGridItem({ + x: 12, + y: 0, + width: 12, + height: 10, + isResizable: false, + isDraggable: true, + body: new VizPanel({ pluginId: 'timeseries', - title: 'Fill height', + title: 'Draggable only', }), - ], - }), - ], + }), + new SceneGridItem({ + x: 6, + y: 11, + width: 12, + height: 10, + isResizable: false, + isDraggable: true, + body: new SceneFlexLayout({ + direction: 'column', + children: [ + new SceneFlexItem({ + ySizing: 'fill', + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Fill height', + }), + }), + new SceneFlexItem({ + ySizing: 'fill', + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Fill height', + }), + }), + ], + }), + }), + ], + }), }), - - new SceneGridLayout({ - children: [ - new VizPanel({ - placement: { + new SceneFlexItem({ + body: new SceneGridLayout({ + children: [ + new SceneGridItem({ x: 0, y: 0, width: 12, height: 10, isDraggable: true, - }, - pluginId: 'timeseries', - title: 'Fill height', - }), - new VizPanel({ - placement: { x: 12, y: 0, width: 12, height: 10, isResizable: false, isDraggable: true }, - pluginId: 'timeseries', - title: 'Fill height', - }), - new SceneFlexLayout({ - placement: { x: 6, y: 11, width: 12, height: 10 }, - direction: 'column', - children: [ - new VizPanel({ - placement: { ySizing: 'fill', isDraggable: true }, + isResizable: true, + body: new VizPanel({ pluginId: 'timeseries', - title: 'Fill height', + title: 'Dragabble and resizable', }), - new VizPanel({ - placement: { ySizing: 'fill', isDraggable: true }, + }), + new SceneGridItem({ + x: 12, + y: 0, + width: 12, + height: 10, + isResizable: false, + isDraggable: true, + body: new VizPanel({ pluginId: 'timeseries', - title: 'Fill height', + title: 'Draggable only', }), - ], - }), - ], + }), + new SceneGridItem({ + x: 6, + y: 11, + width: 12, + height: 10, + isResizable: false, + isDraggable: true, + body: new SceneFlexLayout({ + direction: 'column', + children: [ + new SceneFlexItem({ + ySizing: 'fill', + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Fill height', + }), + }), + new SceneFlexItem({ + ySizing: 'fill', + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Fill height', + }), + }), + ], + }), + }), + ], + }), }), ], }), diff --git a/public/app/features/scenes/scenes/gridWithMultipleData.tsx b/public/app/features/scenes/scenes/gridWithMultipleData.tsx index 8610bf00c95..90999900208 100644 --- a/public/app/features/scenes/scenes/gridWithMultipleData.tsx +++ b/public/app/features/scenes/scenes/gridWithMultipleData.tsx @@ -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 { DashboardScene } from '../dashboard/DashboardScene'; @@ -16,19 +23,33 @@ export function getGridWithMultipleData(): DashboardScene { title: 'Row A - has its own query', key: 'Row A', isCollapsed: true, - placement: { y: 0 }, + 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 SceneGridItem({ + x: 0, + y: 1, + width: 12, + height: 5, + isResizable: true, + isDraggable: true, + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Row A Child1', + key: 'Row A Child1', + }), }), - 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 SceneGridItem({ + x: 0, + y: 5, + width: 6, + height: 5, + isResizable: true, + isDraggable: true, + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Row A Child2', + key: 'Row A Child2', + }), }), ], }), @@ -36,49 +57,63 @@ export function getGridWithMultipleData(): DashboardScene { title: 'Row B - uses global query', key: 'Row B', isCollapsed: true, - placement: { y: 1 }, + 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 SceneGridItem({ + x: 0, + y: 2, + width: 12, + height: 5, + isResizable: false, + isDraggable: true, + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Row B Child1', + key: 'Row B Child1', + }), }), - new VizPanel({ - $data: getQueryRunnerWithRandomWalkQuery({ seriesCount: 10 }), - pluginId: 'timeseries', - title: 'Row B Child2 with data', - key: 'Row B Child2', - placement: { x: 0, y: 7, width: 6, height: 5, isResizable: false, isDraggable: true }, + new SceneGridItem({ + x: 0, + y: 7, + width: 6, + height: 5, + isResizable: false, + isDraggable: true, + body: new VizPanel({ + $data: getQueryRunnerWithRandomWalkQuery({ seriesCount: 10 }), + pluginId: 'timeseries', + title: 'Row B Child2 with data', + key: 'Row B Child2', + }), }), ], }), - new VizPanel({ - $data: getQueryRunnerWithRandomWalkQuery({ seriesCount: 10 }), - pluginId: 'timeseries', - title: 'Outsider, has its own query', - key: 'Outsider-own-query', - placement: { - x: 0, - y: 12, - width: 6, - height: 10, - isResizable: true, - isDraggable: true, - }, + new SceneGridItem({ + x: 0, + y: 12, + width: 6, + height: 10, + isResizable: true, + isDraggable: true, + body: new VizPanel({ + $data: getQueryRunnerWithRandomWalkQuery({ seriesCount: 10 }), + pluginId: 'timeseries', + title: 'Outsider, has its own query', + key: 'Outsider-own-query', + }), }), - new VizPanel({ - pluginId: 'timeseries', - title: 'Outsider, uses global query', - key: 'Outsider-global-query', - placement: { - x: 6, - y: 12, - width: 12, - height: 10, - isResizable: true, - isDraggable: true, - }, + new SceneGridItem({ + x: 6, + y: 12, + width: 12, + height: 10, + isResizable: true, + isDraggable: true, + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Outsider, uses global query', + key: 'Outsider-global-query', + }), }), ], }), diff --git a/public/app/features/scenes/scenes/gridWithRow.tsx b/public/app/features/scenes/scenes/gridWithRow.tsx deleted file mode 100644 index 31632781273..00000000000 --- a/public/app/features/scenes/scenes/gridWithRow.tsx +++ /dev/null @@ -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({})], - }); -} diff --git a/public/app/features/scenes/scenes/gridWithRows.tsx b/public/app/features/scenes/scenes/gridWithRows.tsx deleted file mode 100644 index ad1c871d35d..00000000000 --- a/public/app/features/scenes/scenes/gridWithRows.tsx +++ /dev/null @@ -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; -} diff --git a/public/app/features/scenes/scenes/index.tsx b/public/app/features/scenes/scenes/index.tsx index a255f7712e0..6915368b9ea 100644 --- a/public/app/features/scenes/scenes/index.tsx +++ b/public/app/features/scenes/scenes/index.tsx @@ -1,12 +1,8 @@ import { DashboardScene } from '../dashboard/DashboardScene'; -import { getFlexLayoutTest, getRepeaterSceneWithFlexWrap, getScenePanelRepeaterTest } from './demo'; -import { getGridLayoutTest } from './grid'; import { getGridWithMultipleTimeRanges } from './gridMultiTimeRange'; import { getMultipleGridLayoutTest } from './gridMultiple'; import { getGridWithMultipleData } from './gridWithMultipleData'; -import { getGridWithRowLayoutTest } from './gridWithRow'; -import { getNestedScene } from './nested'; import { getQueryVariableDemo } from './queryVariableDemo'; import { getSceneWithRows } from './sceneWithRows'; import { getTransformationsDemo } from './transformations'; @@ -18,13 +14,7 @@ interface SceneDef { } export function getScenes(): SceneDef[] { 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: '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 and time ranges', getScene: getGridWithMultipleTimeRanges }, { title: 'Multiple grid layouts test', getScene: getMultipleGridLayoutTest }, diff --git a/public/app/features/scenes/scenes/nested.tsx b/public/app/features/scenes/scenes/nested.tsx deleted file mode 100644 index 7ac0056e3e8..00000000000 --- a/public/app/features/scenes/scenes/nested.tsx +++ /dev/null @@ -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; -} diff --git a/public/app/features/scenes/scenes/queryVariableDemo.tsx b/public/app/features/scenes/scenes/queryVariableDemo.tsx index 903aec184b1..303dc3490fa 100644 --- a/public/app/features/scenes/scenes/queryVariableDemo.tsx +++ b/public/app/features/scenes/scenes/queryVariableDemo.tsx @@ -9,6 +9,7 @@ import { CustomVariable, DataSourceVariable, QueryVariable, + SceneFlexItem, } from '@grafana/scenes'; import { DashboardScene } from '../dashboard/DashboardScene'; @@ -49,15 +50,13 @@ export function getQueryVariableDemo(): DashboardScene { body: new SceneFlexLayout({ direction: 'row', children: [ - new SceneFlexLayout({ - children: [ - new SceneCanvasText({ - placement: { width: '40%' }, - text: 'metric: ${metric}', - fontSize: 20, - align: 'center', - }), - ], + new SceneFlexItem({ + width: '40%', + body: new SceneCanvasText({ + text: 'metric: ${metric}', + fontSize: 20, + align: 'center', + }), }), ], }), diff --git a/public/app/features/scenes/scenes/sceneWithRows.tsx b/public/app/features/scenes/scenes/sceneWithRows.tsx index 51e77fc822d..ef925e0da70 100644 --- a/public/app/features/scenes/scenes/sceneWithRows.tsx +++ b/public/app/features/scenes/scenes/sceneWithRows.tsx @@ -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'; @@ -13,35 +20,42 @@ export function getSceneWithRows(): DashboardScene { new NestedScene({ title: 'Overview', canCollapse: true, - // size: { ySizing: 'content', xSizing: 'fill' }, body: new SceneFlexLayout({ direction: 'row', children: [ - new VizPanel({ - pluginId: 'timeseries', - title: 'Fill height', + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Fill height', + }), }), - new VizPanel({ - pluginId: 'timeseries', - title: 'Fill height', + + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Fill height', + }), }), ], }), }), new NestedScene({ title: 'More server details', - // size: { ySizing: 'content', xSizing: 'fill' }, canCollapse: true, body: new SceneFlexLayout({ direction: 'row', children: [ - new VizPanel({ - pluginId: 'timeseries', - title: 'Fill height', + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Fill height', + }), }), - new VizPanel({ - pluginId: 'timeseries', - title: 'Fill height', + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Fill height', + }), }), ], }), diff --git a/public/app/features/scenes/scenes/transformations.tsx b/public/app/features/scenes/scenes/transformations.tsx index 2140e56f993..43b8878ff70 100644 --- a/public/app/features/scenes/scenes/transformations.tsx +++ b/public/app/features/scenes/scenes/transformations.tsx @@ -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'; @@ -10,50 +17,59 @@ export function getTransformationsDemo(): DashboardScene { body: new SceneFlexLayout({ direction: 'row', children: [ - new SceneFlexLayout({ - direction: 'column', - children: [ - new SceneFlexLayout({ - direction: 'row', - children: [ - new VizPanel({ - pluginId: 'timeseries', - title: 'Source data (global query', + new SceneFlexItem({ + body: new SceneFlexLayout({ + direction: 'column', + children: [ + new SceneFlexItem({ + body: new SceneFlexLayout({ + direction: 'row', + children: [ + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'timeseries', + title: 'Source data (global query', + }), + }), + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'stat', + title: 'Transformed data', + $data: new SceneDataTransformer({ + transformations: [ + { + id: 'reduce', + options: { + reducers: ['last', 'mean'], + }, + }, + ], + }), + }), + }), + ], }), - new VizPanel({ - pluginId: 'stat', - title: 'Transformed data', + }), + new SceneFlexItem({ + body: new VizPanel({ $data: new SceneDataTransformer({ + $data: getQueryRunnerWithRandomWalkQuery(), transformations: [ { id: 'reduce', options: { - reducers: ['last', 'mean'], + reducers: ['mean'], }, }, ], }), + + pluginId: 'stat', + title: 'Query with predefined transformations', }), - ], - }), - - new VizPanel({ - $data: new SceneDataTransformer({ - $data: getQueryRunnerWithRandomWalkQuery(), - transformations: [ - { - id: 'reduce', - options: { - reducers: ['mean'], - }, - }, - ], }), - - pluginId: 'stat', - title: 'Query with predefined transformations', - }), - ], + ], + }), }), ], }), diff --git a/public/app/features/scenes/scenes/variablesDemo.tsx b/public/app/features/scenes/scenes/variablesDemo.tsx index b492271eb2b..f1002e208e7 100644 --- a/public/app/features/scenes/scenes/variablesDemo.tsx +++ b/public/app/features/scenes/scenes/variablesDemo.tsx @@ -11,6 +11,7 @@ import { TestVariable, NestedScene, TextBoxVariable, + SceneFlexItem, } from '@grafana/scenes'; import { DashboardScene } from '../dashboard/DashboardScene'; @@ -65,48 +66,62 @@ export function getVariablesDemo(): DashboardScene { body: new SceneFlexLayout({ direction: 'row', children: [ - new SceneFlexLayout({ - direction: 'column', - children: [ - new SceneFlexLayout({ - children: [ - new VizPanel({ - pluginId: 'timeseries', - title: 'handler: $handler', - $data: getQueryRunnerWithRandomWalkQuery({ - alias: 'handler: $handler', - }), - }), - new SceneCanvasText({ - text: 'Text: ${textbox}', - fontSize: 20, - align: 'center', - }), - new SceneCanvasText({ - placement: { width: '40%' }, - text: 'server: ${server} pod:${pod}', - fontSize: 20, - align: 'center', - }), - ], - }), - new NestedScene({ - title: 'Collapsable inner scene', - canCollapse: true, - body: new SceneFlexLayout({ - direction: 'row', - children: [ - new VizPanel({ - pluginId: 'timeseries', - title: 'handler: $handler', - $data: getQueryRunnerWithRandomWalkQuery({ - alias: 'handler: $handler', + new SceneFlexItem({ + body: new SceneFlexLayout({ + direction: 'column', + children: [ + new SceneFlexItem({ + body: new SceneFlexLayout({ + children: [ + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'timeseries', + title: 'handler: $handler', + $data: getQueryRunnerWithRandomWalkQuery({ + alias: 'handler: $handler', + }), + }), }), - }), - ], + new SceneFlexItem({ + body: new SceneCanvasText({ + text: 'Text: ${textbox}', + fontSize: 20, + align: 'center', + }), + }), + new SceneFlexItem({ + width: '40%', + body: new SceneCanvasText({ + text: 'server: ${server} pod:${pod}', + fontSize: 20, + align: 'center', + }), + }), + ], + }), }), - }), - ], + new SceneFlexItem({ + body: new NestedScene({ + title: 'Collapsable inner scene', + canCollapse: true, + body: new SceneFlexLayout({ + direction: 'row', + children: [ + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'timeseries', + title: 'handler: $handler', + $data: getQueryRunnerWithRandomWalkQuery({ + alias: 'handler: $handler', + }), + }), + }), + ], + }), + }), + }), + ], + }), }), ], }), @@ -158,22 +173,22 @@ export function getVariablesDemoWithAll(): DashboardScene { body: new SceneFlexLayout({ direction: 'row', children: [ - new SceneFlexLayout({ - children: [ - new VizPanel({ - pluginId: 'timeseries', - title: 'handler: $handler', - $data: getQueryRunnerWithRandomWalkQuery({ - alias: 'handler: $handler', - }), + new SceneFlexItem({ + body: new VizPanel({ + pluginId: 'timeseries', + title: 'handler: $handler', + $data: getQueryRunnerWithRandomWalkQuery({ + alias: 'handler: $handler', }), - new SceneCanvasText({ - placement: { width: '40%' }, - text: 'server: ${server} pod:${pod}', - fontSize: 20, - align: 'center', - }), - ], + }), + }), + new SceneFlexItem({ + width: '40%', + body: new SceneCanvasText({ + text: 'server: ${server} pod:${pod}', + fontSize: 20, + align: 'center', + }), }), ], }), diff --git a/public/app/features/templating/formatVariableValue.ts b/public/app/features/templating/formatVariableValue.ts index 74a5bf3e1e0..eeab28bba48 100644 --- a/public/app/features/templating/formatVariableValue.ts +++ b/public/app/features/templating/formatVariableValue.ts @@ -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'; @@ -12,7 +13,7 @@ export function formatVariableValue(value: any, format?: any, variable?: any, te return ''; } - if (isAdHoc(variable) && format !== FormatRegistryID.queryParam) { + if (isAdHoc(variable) && format !== VariableFormatID.QueryParam) { return ''; } @@ -26,7 +27,7 @@ export function formatVariableValue(value: any, format?: any, variable?: any, te } if (!format) { - format = FormatRegistryID.glob; + format = VariableFormatID.Glob; } // some formats have arguments that come after ':' character @@ -42,7 +43,7 @@ export function formatVariableValue(value: any, format?: any, variable?: any, te if (!formatItem) { 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); diff --git a/public/app/features/templating/template_srv.test.ts b/public/app/features/templating/template_srv.test.ts index 11b80ff841a..413c2c11063 100644 --- a/public/app/features/templating/template_srv.test.ts +++ b/public/app/features/templating/template_srv.test.ts @@ -1,6 +1,7 @@ import { dateTime, TimeRange } from '@grafana/data'; 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 { initTemplateSrv } from '../../../test/helpers/initTemplateSrv'; @@ -697,9 +698,9 @@ describe('templateSrv', () => { }); 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) { - if (registryItem === FormatRegistryID.queryParam) { + if (registryItem === VariableFormatID.QueryParam) { continue; } diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts index bcca0087752..2b1445def8b 100644 --- a/public/app/features/templating/template_srv.ts +++ b/public/app/features/templating/template_srv.ts @@ -15,7 +15,8 @@ import { TemplateSrv as BaseTemplateSrv, VariableInterpolation, } 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 { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../variables/constants'; @@ -290,7 +291,7 @@ export class TemplateSrv implements BaseTemplateSrv { return match; } - if (format === FormatRegistryID.queryParam || isAdHoc(variable)) { + if (format === VariableFormatID.QueryParam || isAdHoc(variable)) { const value = variableAdapters.get(variable.type).getValueForUrl(variable); const text = isAdHoc(variable) ? variable.id : variable.current.text; @@ -309,7 +310,7 @@ export class TemplateSrv implements BaseTemplateSrv { value = this.getAllValue(variable); text = ALL_VARIABLE_TEXT; // 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); } } diff --git a/public/app/plugins/datasource/postgres/PostgresQueryModel.ts b/public/app/plugins/datasource/postgres/PostgresQueryModel.ts index f84c0389df1..aa3c47f0a78 100644 --- a/public/app/plugins/datasource/postgres/PostgresQueryModel.ts +++ b/public/app/plugins/datasource/postgres/PostgresQueryModel.ts @@ -1,6 +1,6 @@ import { ScopedVars } from '@grafana/data'; import { TemplateSrv } from '@grafana/runtime'; -import { FormatRegistryID } from '@grafana/scenes'; +import { VariableFormatID } from '@grafana/schema'; import { applyQueryDefaults } from 'app/features/plugins/sql/defaults'; import { SQLQuery, SqlQueryModel } from 'app/features/plugins/sql/types'; @@ -16,7 +16,7 @@ export class PostgresQueryModel implements SqlQueryModel { } 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) { diff --git a/yarn.lock b/yarn.lock index 935a8a65967..b49d85f229d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3326,9 +3326,9 @@ __metadata: languageName: unknown linkType: soft -"@grafana/scenes@npm:^0.0.28": - version: 0.0.28 - resolution: "@grafana/scenes@npm:0.0.28" +"@grafana/scenes@npm:^0.2.0": + version: 0.2.0 + resolution: "@grafana/scenes@npm:0.2.0" dependencies: "@grafana/e2e-selectors": ^9.4.3 "@grafana/experimental": 1.0.1 @@ -3336,7 +3336,7 @@ __metadata: react-use: 17.4.0 react-virtualized-auto-sizer: 1.0.7 uuid: ^9.0.0 - checksum: 0cfcfda325f42c1aee571e32411514954d5a14ac7b40102f33c1c52bd39e65766c3081e634de303379dccd363f78ed4ce022ac71a4d6b7ab3658f18ac81163e7 + checksum: a04fe353eec8f048de7c51079e7f7bef461b372c3c086d5ff3be46fc0e70a21e907272f0ed05a41633847a3736c5e65e441ffa20b2c18eedea813decf3eef636 languageName: node linkType: hard @@ -20110,7 +20110,7 @@ __metadata: "@grafana/lezer-logql": 0.1.2 "@grafana/monaco-logql": ^0.0.7 "@grafana/runtime": "workspace:*" - "@grafana/scenes": ^0.0.28 + "@grafana/scenes": ^0.2.0 "@grafana/schema": "workspace:*" "@grafana/toolkit": "workspace:*" "@grafana/tsconfig": ^1.2.0-rc1