From b2ad23f6e9f7c46aba34adda2d8d202870b02461 Mon Sep 17 00:00:00 2001 From: Sergej-Vlasov <37613182+Sergej-Vlasov@users.noreply.github.com> Date: Tue, 13 Jan 2026 15:54:40 +0000 Subject: [PATCH] [release-11.6.10] InspectJsonTab: Force render the layout after change to reflect new gridPos (#116110) * InspectJsonTab: Force render the layout after change to reflect new gridPos (#115688) force render the layout after inspect panel change to account for gridPos change (cherry picked from commit 0a0f92e85ea6d319c8e7501e435672608e3e3884) * fix merge conflicts --- .../inspect/InspectJsonTab.test.tsx | 47 ++++++++++++++++++- .../inspect/InspectJsonTab.tsx | 7 +++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/public/app/features/dashboard-scene/inspect/InspectJsonTab.test.tsx b/public/app/features/dashboard-scene/inspect/InspectJsonTab.test.tsx index 582e0855008..d3fb7d807fb 100644 --- a/public/app/features/dashboard-scene/inspect/InspectJsonTab.test.tsx +++ b/public/app/features/dashboard-scene/inspect/InspectJsonTab.test.tsx @@ -12,7 +12,7 @@ import { } from '@grafana/data'; import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks'; import { setPluginImportUtils, setRunRequest } from '@grafana/runtime'; -import { SceneCanvasText, SceneDataTransformer, SceneQueryRunner, VizPanel } from '@grafana/scenes'; +import { SceneCanvasText, SceneDataTransformer, SceneGridLayout, SceneQueryRunner, VizPanel } from '@grafana/scenes'; import * as libpanels from 'app/features/library-panels/state/api'; import { getStandardTransformers } from 'app/features/transformers/standardTransformers'; @@ -170,6 +170,51 @@ describe('InspectJsonTab', () => { expect(tab.state.onClose).toHaveBeenCalled(); }); + + it('Can update gridPos and forces layout re-render', async () => { + const { tab, panel, scene } = await buildTestScene(); + + // Get the layout manager and spy on the grid's forceRender + const layoutManager = scene.state.body as DefaultGridLayoutManager; + const grid = layoutManager.state.grid as SceneGridLayout; + const forceRenderSpy = jest.spyOn(grid, 'forceRender'); + + const originalGridItem = panel.parent as DashboardGridItem; + expect(originalGridItem.state.x).toBe(0); + expect(originalGridItem.state.y).toBe(0); + expect(originalGridItem.state.width).toBe(8); + expect(originalGridItem.state.height).toBe(10); + + tab.onCodeEditorBlur(`{ + "id": 12, + "type": "table", + "title": "Panel A", + "gridPos": { + "x": 5, + "y": 10, + "w": 12, + "h": 8 + }, + "options": {}, + "fieldConfig": {}, + "transformations": [], + "transparent": false + }`); + + tab.onApplyChange(); + + const panel2 = findVizPanelByKey(scene, panel.state.key)!; + const gridItem = panel2.parent as DashboardGridItem; + + // Verify all gridPos properties are updated + expect(gridItem.state.x).toBe(5); + expect(gridItem.state.y).toBe(10); + expect(gridItem.state.width).toBe(12); + expect(gridItem.state.height).toBe(8); + + // Verify forceRender was called on the layout to apply position changes + expect(forceRenderSpy).toHaveBeenCalled(); + }); }); function buildTestPanel() { diff --git a/public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx b/public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx index ff7798b2c7c..230136e1c2f 100644 --- a/public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx +++ b/public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx @@ -8,6 +8,7 @@ import { SceneDataTransformer, sceneGraph, SceneGridItemStateLike, + SceneGridLayout, SceneObjectBase, SceneObjectRef, SceneObjectState, @@ -125,6 +126,12 @@ export class InspectJsonTab extends SceneObjectBase { panel.parent.setState(newState); + // Force the grid layout to re-render with the new positions + const layout = sceneGraph.getLayout(panel); + if (layout instanceof SceneGridLayout) { + layout.forceRender(); + } + //Report relevant updates reportPanelInspectInteraction(InspectTab.JSON, 'apply', { panel_type_changed: panel.state.pluginId !== panelModel.type,