Remove repeating responsibility from LibraryVizPanel (#84879)

* Remove repeating responsibility from LibraryVizPanel

* Improvements
This commit is contained in:
Dominik Prokop 2024-04-10 17:46:42 +02:00 committed by GitHub
parent 615fa73f23
commit 483dc02b68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 24 deletions

View File

@ -1,5 +1,6 @@
import { css } from '@emotion/css';
import React, { useMemo } from 'react';
import { Unsubscribable } from 'rxjs';
import { config } from '@grafana/runtime';
import {
@ -39,6 +40,7 @@ interface DashboardGridItemState extends SceneGridItemStateLike {
export type RepeatDirection = 'v' | 'h';
export class DashboardGridItem extends SceneObjectBase<DashboardGridItemState> implements SceneGridItemLike {
private _libPanelSubscription: Unsubscribable | undefined;
protected _variableDependency = new VariableDependencyConfig(this, {
variableNames: this.state.variableName ? [this.state.variableName] : [],
onVariableUpdateCompleted: this._onVariableUpdateCompleted.bind(this),
@ -55,6 +57,46 @@ export class DashboardGridItem extends SceneObjectBase<DashboardGridItemState> i
this._subs.add(this.subscribeToState((newState, prevState) => this._handleGridResize(newState, prevState)));
this._performRepeat();
}
// Subscriptions that handles body updates, i.e. VizPanel -> LibraryVizPanel, AddLibPanelWidget -> LibraryVizPanel
this._subs.add(
this.subscribeToState((newState, prevState) => {
if (newState.body !== prevState.body) {
if (newState.body instanceof LibraryVizPanel) {
this.setupLibraryPanelChangeSubscription(newState.body);
}
}
})
);
// Initial setup of the lbrary panel subscription. Lib panels are lazy laded, so only then we can subscribe to the repeat config changes
if (this.state.body instanceof LibraryVizPanel) {
this.setupLibraryPanelChangeSubscription(this.state.body);
}
return () => {
this._libPanelSubscription?.unsubscribe();
this._libPanelSubscription = undefined;
};
}
private setupLibraryPanelChangeSubscription(panel: LibraryVizPanel) {
if (this._libPanelSubscription) {
this._libPanelSubscription.unsubscribe();
this._libPanelSubscription = undefined;
}
this._libPanelSubscription = panel.subscribeToState((newState) => {
if (newState._loadedPanel?.model.repeat) {
this._variableDependency.setVariableNames([newState._loadedPanel.model.repeat]);
this.setState({
variableName: newState._loadedPanel.model.repeat,
repeatDirection: newState._loadedPanel.model.repeatDirection,
maxPerRow: newState._loadedPanel.model.maxPerRow,
});
this._performRepeat();
}
});
}
private _onVariableUpdateCompleted(): void {

View File

@ -2,7 +2,6 @@ import React from 'react';
import {
SceneComponentProps,
SceneGridLayout,
SceneObjectBase,
SceneObjectState,
VizPanel,
@ -78,29 +77,6 @@ export class LibraryVizPanel extends SceneObjectBase<LibraryVizPanelState> {
};
const panel = new VizPanel(vizPanelState);
const gridItem = this.parent;
if (libPanelModel.repeat && gridItem instanceof DashboardGridItem && gridItem.parent instanceof SceneGridLayout) {
this._parent = undefined;
const repeater = new DashboardGridItem({
key: gridItem.state.key,
x: gridItem.state.x,
y: gridItem.state.y,
width: libPanelModel.repeatDirection === 'h' ? 24 : gridItem.state.width,
height: gridItem.state.height,
itemHeight: gridItem.state.height,
body: this,
variableName: libPanelModel.repeat,
repeatedPanels: [],
repeatDirection: libPanelModel.repeatDirection === 'h' ? 'h' : 'v',
maxPerRow: libPanelModel.maxPerRow,
});
gridItem.parent.setState({
children: gridItem.parent.state.children.map((child) =>
child.state.key === gridItem.state.key ? repeater : child
),
});
}
this.setState({ panel, _loadedPanel: libPanel, isLoaded: true, name: libPanel.name });
}