diff --git a/package.json b/package.json index 7d1a7357f73..f19661282a5 100644 --- a/package.json +++ b/package.json @@ -244,7 +244,7 @@ "@grafana/lezer-traceql": "0.0.4", "@grafana/monaco-logql": "^0.0.7", "@grafana/runtime": "workspace:*", - "@grafana/scenes": "0.24.2", + "@grafana/scenes": "^0.25.0", "@grafana/schema": "workspace:*", "@grafana/ui": "workspace:*", "@kusto/monaco-kusto": "^7.4.0", diff --git a/public/app/features/scenes/dashboard/DashboardScene.tsx b/public/app/features/scenes/dashboard/DashboardScene.tsx index 42154d1e0cc..e67047351c4 100644 --- a/public/app/features/scenes/dashboard/DashboardScene.tsx +++ b/public/app/features/scenes/dashboard/DashboardScene.tsx @@ -6,6 +6,7 @@ import { getUrlSyncManager, sceneGraph, SceneGridItem, + SceneGridLayout, SceneObject, SceneObjectBase, SceneObjectState, @@ -17,6 +18,7 @@ import { import appEvents from 'app/core/app_events'; import { DashboardSceneRenderer } from './DashboardSceneRenderer'; +import { forceRenderChildren } from './utils'; export interface DashboardSceneState extends SceneObjectState { title: string; @@ -75,12 +77,24 @@ export class DashboardScene extends SceneObjectBase { onEnterEditMode = () => { this.setState({ isEditing: true }); + + // Make grid draggable + if (this.state.body instanceof SceneGridLayout) { + this.state.body.setState({ isDraggable: true, isResizable: true }); + forceRenderChildren(this.state.body, true); + } }; onDiscard = () => { // TODO open confirm modal if dirty // TODO actually discard changes this.setState({ isEditing: false }); + + // Disable grid dragging + if (this.state.body instanceof SceneGridLayout) { + this.state.body.setState({ isDraggable: false, isResizable: false }); + forceRenderChildren(this.state.body, true); + } }; onCloseInspectDrawer = () => { diff --git a/public/app/features/scenes/dashboard/utils.ts b/public/app/features/scenes/dashboard/utils.ts index 418c793a3b0..5939892c0fb 100644 --- a/public/app/features/scenes/dashboard/utils.ts +++ b/public/app/features/scenes/dashboard/utils.ts @@ -24,3 +24,23 @@ export function activateFullSceneTree(scene: SceneObject): SceneDeactivationHand } }; } + +/** + * Force re-render children. This is useful in some edge case scenarios when + * children deep down the scene graph needs to be re-rendered when some parent state change. + * + * Example could be isEditing bool flag or a layout IsDraggable state flag. + * + * @param model The model whose children should be re-rendered. It does not force render this model, only the children. + * @param recursive if it should keep force rendering down to leaf nodess + */ +export function forceRenderChildren(model: SceneObject, recursive?: boolean) { + model.forEachChild((child) => { + if (!child.isActive) { + return; + } + + child.forceRender(); + forceRenderChildren(child, recursive); + }); +} diff --git a/yarn.lock b/yarn.lock index 141589bb1f7..6c0c75ae464 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3930,9 +3930,9 @@ __metadata: languageName: unknown linkType: soft -"@grafana/scenes@npm:0.24.2": - version: 0.24.2 - resolution: "@grafana/scenes@npm:0.24.2" +"@grafana/scenes@npm:^0.25.0": + version: 0.25.0 + resolution: "@grafana/scenes@npm:0.25.0" dependencies: "@grafana/e2e-selectors": 10.0.2 react-grid-layout: 1.3.4 @@ -3944,7 +3944,7 @@ __metadata: "@grafana/runtime": 10.0.3 "@grafana/schema": 10.0.3 "@grafana/ui": 10.0.3 - checksum: 26797a4c90ff3b6d2e80f3da1d3be9721a371d9d9569e443dad14c81eba8413ef3fff78ab85602f9bfe3e243d7555a834134ac0c1c8542c23b9cc572bd40ad0a + checksum: ab81d18bb65b0b5d612708fbd9351022141248b476009bdde01660cce1747bd0724fdf599842127f48feea49b31858dc64e45af2638d90fd3b09d59e350f79e4 languageName: node linkType: hard @@ -19249,7 +19249,7 @@ __metadata: "@grafana/lezer-traceql": 0.0.4 "@grafana/monaco-logql": ^0.0.7 "@grafana/runtime": "workspace:*" - "@grafana/scenes": 0.24.2 + "@grafana/scenes": ^0.25.0 "@grafana/schema": "workspace:*" "@grafana/toolkit": "workspace:*" "@grafana/tsconfig": ^1.3.0-rc1