Fix panels in rows stuck in loading (#93168)

* Fix panels in rows stuck in loading

* fix

* fix + tests

* force reperform in case All value is selected and actual options change

* bump scenes so tests pass

* redo yarn.lock

* redo yarn.lock
This commit is contained in:
Victor Marin 2024-09-13 17:51:12 +03:00 committed by GitHub
parent ad6cd55301
commit a214fbd7cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 5 deletions

View File

@ -935,7 +935,9 @@ export class DashboardVariableDependency implements SceneVariableDependencyConfi
for (const behavior of child.state.$behaviors) {
if (behavior instanceof RowRepeaterBehavior) {
if (behavior.isWaitingForVariables || (behavior.state.variableName === variable.state.name && hasChanged)) {
behavior.performRepeat();
behavior.performRepeat(true);
} else if (!behavior.isWaitingForVariables && behavior.state.variableName === variable.state.name) {
behavior.notifyRepeatedPanelsWaitingForVariables(variable);
}
}
}

View File

@ -1,3 +1,4 @@
import { VariableRefresh } from '@grafana/data';
import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks';
import { setPluginImportUtils } from '@grafana/runtime';
import {
@ -144,6 +145,26 @@ describe('RowRepeaterBehavior', () => {
expect(gridStateUpdates.length).toBe(1);
});
it('Should update panels on refresh if variables load on time range change', async () => {
const { scene, repeatBehavior } = buildScene({
variableQueryTime: 0,
variableRefresh: VariableRefresh.onTimeRangeChanged,
});
const notifyPanelsSpy = jest.spyOn(repeatBehavior, 'notifyRepeatedPanelsWaitingForVariables');
activateFullSceneTree(scene);
expect(notifyPanelsSpy).toHaveBeenCalledTimes(0);
scene.state.$timeRange?.onRefresh();
//make sure notifier is called
expect(notifyPanelsSpy).toHaveBeenCalledTimes(1);
notifyPanelsSpy.mockRestore();
});
});
describe('Should not repeat row', () => {
@ -251,6 +272,7 @@ interface SceneOptions {
maxPerRow?: number;
itemHeight?: number;
repeatDirection?: RepeatDirection;
variableRefresh?: VariableRefresh;
}
function buildScene(
@ -334,6 +356,7 @@ function buildScene(
isMulti: true,
includeAll: true,
delayMs: options.variableQueryTime,
refresh: options.variableRefresh,
optionsToReturn: variableOptions ?? [
{ label: 'A', value: 'A1' },
{ label: 'B', value: 'B1' },

View File

@ -9,13 +9,14 @@ import {
SceneGridRow,
SceneObjectBase,
SceneObjectState,
SceneVariable,
SceneVariableSet,
VariableDependencyConfig,
VariableValueSingle,
VizPanelMenu,
} from '@grafana/scenes';
import { getMultiVariableValues } from '../utils/utils';
import { getMultiVariableValues, getQueryRunnerFor } from '../utils/utils';
import { DashboardGridItem } from './DashboardGridItem';
import { repeatPanelMenuBehavior } from './PanelMenuBehavior';
@ -37,6 +38,7 @@ export class RowRepeaterBehavior extends SceneObjectBase<RowRepeaterBehaviorStat
public isWaitingForVariables = false;
private _prevRepeatValues?: VariableValueSingle[];
private _clonedRows?: SceneGridRow[];
public constructor(state: RowRepeaterBehaviorState) {
super(state);
@ -44,6 +46,23 @@ export class RowRepeaterBehavior extends SceneObjectBase<RowRepeaterBehaviorStat
this.addActivationHandler(() => this._activationHandler());
}
public notifyRepeatedPanelsWaitingForVariables(variable: SceneVariable) {
const allRows = [this._getRow(), ...(this._clonedRows ?? [])];
for (const row of allRows) {
for (const gridItem of row.state.children) {
if (!(gridItem instanceof DashboardGridItem)) {
continue;
}
const queryRunner = getQueryRunnerFor(gridItem.state.body);
if (queryRunner) {
queryRunner.variableDependency?.variableUpdateCompleted(variable, false);
}
}
}
}
private _activationHandler() {
this.performRepeat();
@ -143,7 +162,7 @@ export class RowRepeaterBehavior extends SceneObjectBase<RowRepeaterBehaviorStat
this._prevRepeatValues = values;
const rows: SceneGridRow[] = [];
this._clonedRows = [];
const rowContent = rowToRepeat.state.children;
const rowContentHeight = getRowContentHeight(rowContent);
@ -205,10 +224,10 @@ export class RowRepeaterBehavior extends SceneObjectBase<RowRepeaterBehaviorStat
rowContentHeight,
children
);
rows.push(rowClone);
this._clonedRows.push(rowClone);
}
updateLayout(layout, rows, maxYOfRows, rowToRepeat);
updateLayout(layout, this._clonedRows, maxYOfRows, rowToRepeat);
// Used from dashboard url sync
this.publishEvent(new DashboardRepeatsProcessedEvent({ source: this }), true);