Dashboard: Fix repeats behavior for inspect, solo panel and repeated and empty panels (#100605)

pull/100416/head
Bogdan Matei 3 months ago committed by GitHub
parent b58b5b5768
commit 5315b4fd2d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      e2e/old-arch/various-suite/solo-route.spec.ts
  2. 4
      e2e/various-suite/solo-route.spec.ts
  3. 4
      package.json
  4. 32
      public/app/features/dashboard-scene/scene/DashboardSceneUrlSync.ts
  5. 8
      public/app/features/dashboard-scene/scene/layout-default/DefaultGridLayoutManager.tsx
  6. 2
      public/app/features/dashboard-scene/utils/clone.test.ts
  7. 13
      public/app/features/dashboard-scene/utils/utils.ts
  8. 22
      yarn.lock

@ -25,7 +25,7 @@ describe('Solo Route', () => {
it('Can view solo repeated panel in scenes', () => {
// open Panel Tests - Graph NG
e2e.pages.SoloPanel.visit(
'templating-repeating-panels/templating-repeating-panels?orgId=1&from=1699934989607&to=1699956589607&panelId=panel-16-clone-0/grid-item-2/panel-2-clone-0&__feature.dashboardSceneSolo=true'
'templating-repeating-panels/templating-repeating-panels?orgId=1&from=1699934989607&to=1699956589607&panelId=panel-2-clone-0&__feature.dashboardSceneSolo=true'
);
e2e.components.Panels.Panel.title('server=A').should('exist');
@ -38,7 +38,7 @@ describe('Solo Route', () => {
'Repeating-rows-uid/repeating-rows?orgId=1&var-server=A&var-server=B&var-server=D&var-pod=1&var-pod=2&var-pod=3&panelId=panel-16-clone-1/grid-item-2/panel-2-clone-1&__feature.dashboardSceneSolo=true'
);
e2e.components.Panels.Panel.title('server = A, pod = Rob').should('exist');
e2e.components.Panels.Panel.title('server = B, pod = Rob').should('exist');
cy.contains('uplot-main-div').should('not.exist');
});
});

@ -25,7 +25,7 @@ describe('Solo Route', () => {
it('Can view solo repeated panel in scenes', () => {
// open Panel Tests - Graph NG
e2e.pages.SoloPanel.visit(
'templating-repeating-panels/templating-repeating-panels?orgId=1&from=1699934989607&to=1699956589607&panelId=panel-16-clone-0/grid-item-2/panel-2-clone-0&__feature.dashboardSceneSolo=true'
'templating-repeating-panels/templating-repeating-panels?orgId=1&from=1699934989607&to=1699956589607&panelId=panel-2-clone-0&__feature.dashboardSceneSolo=true'
);
e2e.components.Panels.Panel.title('server=A').should('exist');
@ -38,7 +38,7 @@ describe('Solo Route', () => {
'Repeating-rows-uid/repeating-rows?orgId=1&var-server=A&var-server=B&var-server=D&var-pod=1&var-pod=2&var-pod=3&panelId=panel-16-clone-1/grid-item-2/panel-2-clone-1&__feature.dashboardSceneSolo=true'
);
e2e.components.Panels.Panel.title('server = A, pod = Rob').should('exist');
e2e.components.Panels.Panel.title('server = B, pod = Rob').should('exist');
cy.contains('uplot-main-div').should('not.exist');
});
});

@ -275,8 +275,8 @@
"@grafana/prometheus": "workspace:*",
"@grafana/runtime": "workspace:*",
"@grafana/saga-icons": "workspace:*",
"@grafana/scenes": "6.0.1",
"@grafana/scenes-react": "6.0.1",
"@grafana/scenes": "6.0.2",
"@grafana/scenes-react": "6.0.2",
"@grafana/schema": "workspace:*",
"@grafana/sql": "workspace:*",
"@grafana/ui": "workspace:*",

@ -22,7 +22,8 @@ import { DefaultGridLayoutManager } from './layout-default/DefaultGridLayoutMana
import { DashboardRepeatsProcessedEvent } from './types/DashboardRepeatsProcessedEvent';
export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
private _eventSub?: Unsubscribable;
private _viewEventSub?: Unsubscribable;
private _inspectEventSub?: Unsubscribable;
constructor(private _scene: DashboardScene) {}
@ -78,6 +79,14 @@ export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
if (typeof values.inspect === 'string') {
let panel = findVizPanelByKey(this._scene, values.inspect);
if (!panel) {
// If we are trying to view a repeat clone that can't be found it might be that the repeats have not been processed yet
// Here we check if the key contains the clone key so we force the repeat processing
// It doesn't matter if the element or the ancestors are clones or not, just that the key contains the clone key
if (containsCloneKey(values.inspect)) {
this._handleInspectRepeatClone(values.inspect);
return;
}
appEvents.emit(AppEvents.alertError, ['Panel not found']);
locationService.partial({ inspect: null });
return;
@ -177,12 +186,27 @@ export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
}
}
private _handleInspectRepeatClone(inspect: string) {
if (!this._inspectEventSub) {
this._inspectEventSub = this._scene.subscribeToEvent(DashboardRepeatsProcessedEvent, () => {
const panel = findVizPanelByKey(this._scene, inspect);
if (panel) {
this._inspectEventSub?.unsubscribe();
this._scene.setState({
inspectPanelKey: inspect,
overlay: new PanelInspectDrawer({ panelRef: panel.getRef() }),
});
}
});
}
}
private _handleViewRepeatClone(viewPanel: string) {
if (!this._eventSub) {
this._eventSub = this._scene.subscribeToEvent(DashboardRepeatsProcessedEvent, () => {
if (!this._viewEventSub) {
this._viewEventSub = this._scene.subscribeToEvent(DashboardRepeatsProcessedEvent, () => {
const panel = findVizPanelByKey(this._scene, viewPanel);
if (panel) {
this._eventSub?.unsubscribe();
this._viewEventSub?.unsubscribe();
this._scene.setState({ viewPanelScene: new ViewPanelScene({ panelRef: panel.getRef() }) });
}
});

@ -252,6 +252,14 @@ export class DefaultGridLayoutManager
}
public activateRepeaters() {
if (!this.isActive) {
this.activate();
}
if (!this.state.grid.isActive) {
this.state.grid.activate();
}
this.state.grid.forEachChild((child) => {
if (child instanceof DashboardGridItem && !child.isActive) {
child.activate();

@ -30,6 +30,8 @@ describe('clone', () => {
expect(getOriginalKey('panel-clone-1')).toBe('panel');
expect(getOriginalKey('row-clone-1/panel-clone-2')).toBe('panel');
expect(getOriginalKey('tab-clone-0/row-clone-1/panel-clone-2')).toBe('panel');
expect(getOriginalKey('panel-2-clone-3')).toBe('panel-2');
expect(getOriginalKey('panel-2')).toBe('panel-2');
});
});

@ -21,7 +21,7 @@ import { panelMenuBehavior } from '../scene/PanelMenuBehavior';
import { DashboardGridItem } from '../scene/layout-default/DashboardGridItem';
import { DashboardLayoutManager, isDashboardLayoutManager } from '../scene/types/DashboardLayoutManager';
import { getLastKeyFromClone, getOriginalKey } from './clone';
import { getOriginalKey, isClonedKey } from './clone';
export const NEW_PANEL_HEIGHT = 8;
export const NEW_PANEL_WIDTH = 12;
@ -64,7 +64,16 @@ function findVizPanelInternal(scene: SceneObject, key: string | undefined): VizP
const panel = sceneGraph.findObject(scene, (obj) => {
const objKey = obj.state.key!;
if (objKey === key || getLastKeyFromClone(objKey) === getLastKeyFromClone(key) || getOriginalKey(objKey) === key) {
if (objKey === key) {
return true;
}
// It might be possible to have the keys changed in the meantime from `panel-2` to `panel-2-clone-0`
// We need to check this as well
const originalObjectKey = !isClonedKey(objKey) ? getOriginalKey(objKey) : objKey;
const originalKey = !isClonedKey(key) ? getOriginalKey(key) : key;
if (originalObjectKey === originalKey) {
return true;
}

@ -3814,11 +3814,11 @@ __metadata:
languageName: unknown
linkType: soft
"@grafana/scenes-react@npm:6.0.1":
version: 6.0.1
resolution: "@grafana/scenes-react@npm:6.0.1"
"@grafana/scenes-react@npm:6.0.2":
version: 6.0.2
resolution: "@grafana/scenes-react@npm:6.0.2"
dependencies:
"@grafana/scenes": "npm:6.0.1"
"@grafana/scenes": "npm:6.0.2"
lru-cache: "npm:^10.2.2"
react-use: "npm:^17.4.0"
peerDependencies:
@ -3830,13 +3830,13 @@ __metadata:
react: ^18.0.0
react-dom: ^18.0.0
react-router-dom: ^6.28.0
checksum: 10/e4ad83cc628f17232fe9c8d74f641c65e2e289c177ce88a6990d00f6bea4e1a091115e7b98200de7bcff14ace0fe20eb816141fe533fee7d2ad5f7f665404d2c
checksum: 10/9744e01f2ff912229e43cedfa41d626ccdfd034f5b9718b57c593bc90edadade960f76baf1d8ad19eed03709c17c62397df1871b89acc635172aa14f6a20e096
languageName: node
linkType: hard
"@grafana/scenes@npm:6.0.1":
version: 6.0.1
resolution: "@grafana/scenes@npm:6.0.1"
"@grafana/scenes@npm:6.0.2":
version: 6.0.2
resolution: "@grafana/scenes@npm:6.0.2"
dependencies:
"@floating-ui/react": "npm:^0.26.16"
"@leeoniya/ufuzzy": "npm:^1.0.16"
@ -3854,7 +3854,7 @@ __metadata:
react: ^18.0.0
react-dom: ^18.0.0
react-router-dom: ^6.28.0
checksum: 10/6862e57358ba2e63f139e7f3bb977b19945f67eb070aa2c85c073a55dc460d3ccfeecfee22aea92c660a7632ac997e6cd945f9466b64103436a221979e6e8fcb
checksum: 10/2584f296db6299ef0a09d51f5c267ebcf7e44bd17b4d6516e38d3220f8f1d7aebc63c5fc6523979c4ac4d3f555416ca573e85e03bd36eb33a11941a5b3497149
languageName: node
linkType: hard
@ -18151,8 +18151,8 @@ __metadata:
"@grafana/prometheus": "workspace:*"
"@grafana/runtime": "workspace:*"
"@grafana/saga-icons": "workspace:*"
"@grafana/scenes": "npm:6.0.1"
"@grafana/scenes-react": "npm:6.0.1"
"@grafana/scenes": "npm:6.0.2"
"@grafana/scenes-react": "npm:6.0.2"
"@grafana/schema": "workspace:*"
"@grafana/sql": "workspace:*"
"@grafana/tsconfig": "npm:^2.0.0"

Loading…
Cancel
Save