mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard: Fix repeats behavior for inspect, solo panel and repeated and empty panels (#100605)
This commit is contained in:
parent
b58b5b5768
commit
5315b4fd2d
@ -25,7 +25,7 @@ describe('Solo Route', () => {
|
|||||||
it('Can view solo repeated panel in scenes', () => {
|
it('Can view solo repeated panel in scenes', () => {
|
||||||
// open Panel Tests - Graph NG
|
// open Panel Tests - Graph NG
|
||||||
e2e.pages.SoloPanel.visit(
|
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');
|
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'
|
'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');
|
cy.contains('uplot-main-div').should('not.exist');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,7 @@ describe('Solo Route', () => {
|
|||||||
it('Can view solo repeated panel in scenes', () => {
|
it('Can view solo repeated panel in scenes', () => {
|
||||||
// open Panel Tests - Graph NG
|
// open Panel Tests - Graph NG
|
||||||
e2e.pages.SoloPanel.visit(
|
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');
|
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'
|
'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');
|
cy.contains('uplot-main-div').should('not.exist');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -275,8 +275,8 @@
|
|||||||
"@grafana/prometheus": "workspace:*",
|
"@grafana/prometheus": "workspace:*",
|
||||||
"@grafana/runtime": "workspace:*",
|
"@grafana/runtime": "workspace:*",
|
||||||
"@grafana/saga-icons": "workspace:*",
|
"@grafana/saga-icons": "workspace:*",
|
||||||
"@grafana/scenes": "6.0.1",
|
"@grafana/scenes": "6.0.2",
|
||||||
"@grafana/scenes-react": "6.0.1",
|
"@grafana/scenes-react": "6.0.2",
|
||||||
"@grafana/schema": "workspace:*",
|
"@grafana/schema": "workspace:*",
|
||||||
"@grafana/sql": "workspace:*",
|
"@grafana/sql": "workspace:*",
|
||||||
"@grafana/ui": "workspace:*",
|
"@grafana/ui": "workspace:*",
|
||||||
|
@ -22,7 +22,8 @@ import { DefaultGridLayoutManager } from './layout-default/DefaultGridLayoutMana
|
|||||||
import { DashboardRepeatsProcessedEvent } from './types/DashboardRepeatsProcessedEvent';
|
import { DashboardRepeatsProcessedEvent } from './types/DashboardRepeatsProcessedEvent';
|
||||||
|
|
||||||
export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
||||||
private _eventSub?: Unsubscribable;
|
private _viewEventSub?: Unsubscribable;
|
||||||
|
private _inspectEventSub?: Unsubscribable;
|
||||||
|
|
||||||
constructor(private _scene: DashboardScene) {}
|
constructor(private _scene: DashboardScene) {}
|
||||||
|
|
||||||
@ -78,6 +79,14 @@ export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
|||||||
if (typeof values.inspect === 'string') {
|
if (typeof values.inspect === 'string') {
|
||||||
let panel = findVizPanelByKey(this._scene, values.inspect);
|
let panel = findVizPanelByKey(this._scene, values.inspect);
|
||||||
if (!panel) {
|
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']);
|
appEvents.emit(AppEvents.alertError, ['Panel not found']);
|
||||||
locationService.partial({ inspect: null });
|
locationService.partial({ inspect: null });
|
||||||
return;
|
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) {
|
private _handleViewRepeatClone(viewPanel: string) {
|
||||||
if (!this._eventSub) {
|
if (!this._viewEventSub) {
|
||||||
this._eventSub = this._scene.subscribeToEvent(DashboardRepeatsProcessedEvent, () => {
|
this._viewEventSub = this._scene.subscribeToEvent(DashboardRepeatsProcessedEvent, () => {
|
||||||
const panel = findVizPanelByKey(this._scene, viewPanel);
|
const panel = findVizPanelByKey(this._scene, viewPanel);
|
||||||
if (panel) {
|
if (panel) {
|
||||||
this._eventSub?.unsubscribe();
|
this._viewEventSub?.unsubscribe();
|
||||||
this._scene.setState({ viewPanelScene: new ViewPanelScene({ panelRef: panel.getRef() }) });
|
this._scene.setState({ viewPanelScene: new ViewPanelScene({ panelRef: panel.getRef() }) });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -252,6 +252,14 @@ export class DefaultGridLayoutManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
public activateRepeaters() {
|
public activateRepeaters() {
|
||||||
|
if (!this.isActive) {
|
||||||
|
this.activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.state.grid.isActive) {
|
||||||
|
this.state.grid.activate();
|
||||||
|
}
|
||||||
|
|
||||||
this.state.grid.forEachChild((child) => {
|
this.state.grid.forEachChild((child) => {
|
||||||
if (child instanceof DashboardGridItem && !child.isActive) {
|
if (child instanceof DashboardGridItem && !child.isActive) {
|
||||||
child.activate();
|
child.activate();
|
||||||
|
@ -30,6 +30,8 @@ describe('clone', () => {
|
|||||||
expect(getOriginalKey('panel-clone-1')).toBe('panel');
|
expect(getOriginalKey('panel-clone-1')).toBe('panel');
|
||||||
expect(getOriginalKey('row-clone-1/panel-clone-2')).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('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 { DashboardGridItem } from '../scene/layout-default/DashboardGridItem';
|
||||||
import { DashboardLayoutManager, isDashboardLayoutManager } from '../scene/types/DashboardLayoutManager';
|
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_HEIGHT = 8;
|
||||||
export const NEW_PANEL_WIDTH = 12;
|
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 panel = sceneGraph.findObject(scene, (obj) => {
|
||||||
const objKey = obj.state.key!;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
22
yarn.lock
22
yarn.lock
@ -3814,11 +3814,11 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@grafana/scenes-react@npm:6.0.1":
|
"@grafana/scenes-react@npm:6.0.2":
|
||||||
version: 6.0.1
|
version: 6.0.2
|
||||||
resolution: "@grafana/scenes-react@npm:6.0.1"
|
resolution: "@grafana/scenes-react@npm:6.0.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@grafana/scenes": "npm:6.0.1"
|
"@grafana/scenes": "npm:6.0.2"
|
||||||
lru-cache: "npm:^10.2.2"
|
lru-cache: "npm:^10.2.2"
|
||||||
react-use: "npm:^17.4.0"
|
react-use: "npm:^17.4.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -3830,13 +3830,13 @@ __metadata:
|
|||||||
react: ^18.0.0
|
react: ^18.0.0
|
||||||
react-dom: ^18.0.0
|
react-dom: ^18.0.0
|
||||||
react-router-dom: ^6.28.0
|
react-router-dom: ^6.28.0
|
||||||
checksum: 10/e4ad83cc628f17232fe9c8d74f641c65e2e289c177ce88a6990d00f6bea4e1a091115e7b98200de7bcff14ace0fe20eb816141fe533fee7d2ad5f7f665404d2c
|
checksum: 10/9744e01f2ff912229e43cedfa41d626ccdfd034f5b9718b57c593bc90edadade960f76baf1d8ad19eed03709c17c62397df1871b89acc635172aa14f6a20e096
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@grafana/scenes@npm:6.0.1":
|
"@grafana/scenes@npm:6.0.2":
|
||||||
version: 6.0.1
|
version: 6.0.2
|
||||||
resolution: "@grafana/scenes@npm:6.0.1"
|
resolution: "@grafana/scenes@npm:6.0.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@floating-ui/react": "npm:^0.26.16"
|
"@floating-ui/react": "npm:^0.26.16"
|
||||||
"@leeoniya/ufuzzy": "npm:^1.0.16"
|
"@leeoniya/ufuzzy": "npm:^1.0.16"
|
||||||
@ -3854,7 +3854,7 @@ __metadata:
|
|||||||
react: ^18.0.0
|
react: ^18.0.0
|
||||||
react-dom: ^18.0.0
|
react-dom: ^18.0.0
|
||||||
react-router-dom: ^6.28.0
|
react-router-dom: ^6.28.0
|
||||||
checksum: 10/6862e57358ba2e63f139e7f3bb977b19945f67eb070aa2c85c073a55dc460d3ccfeecfee22aea92c660a7632ac997e6cd945f9466b64103436a221979e6e8fcb
|
checksum: 10/2584f296db6299ef0a09d51f5c267ebcf7e44bd17b4d6516e38d3220f8f1d7aebc63c5fc6523979c4ac4d3f555416ca573e85e03bd36eb33a11941a5b3497149
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -18151,8 +18151,8 @@ __metadata:
|
|||||||
"@grafana/prometheus": "workspace:*"
|
"@grafana/prometheus": "workspace:*"
|
||||||
"@grafana/runtime": "workspace:*"
|
"@grafana/runtime": "workspace:*"
|
||||||
"@grafana/saga-icons": "workspace:*"
|
"@grafana/saga-icons": "workspace:*"
|
||||||
"@grafana/scenes": "npm:6.0.1"
|
"@grafana/scenes": "npm:6.0.2"
|
||||||
"@grafana/scenes-react": "npm:6.0.1"
|
"@grafana/scenes-react": "npm:6.0.2"
|
||||||
"@grafana/schema": "workspace:*"
|
"@grafana/schema": "workspace:*"
|
||||||
"@grafana/sql": "workspace:*"
|
"@grafana/sql": "workspace:*"
|
||||||
"@grafana/tsconfig": "npm:^2.0.0"
|
"@grafana/tsconfig": "npm:^2.0.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user