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) { for (const behavior of child.state.$behaviors) {
if (behavior instanceof RowRepeaterBehavior) { if (behavior instanceof RowRepeaterBehavior) {
if (behavior.isWaitingForVariables || (behavior.state.variableName === variable.state.name && hasChanged)) { 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 { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks';
import { setPluginImportUtils } from '@grafana/runtime'; import { setPluginImportUtils } from '@grafana/runtime';
import { import {
@ -144,6 +145,26 @@ describe('RowRepeaterBehavior', () => {
expect(gridStateUpdates.length).toBe(1); 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', () => { describe('Should not repeat row', () => {
@ -251,6 +272,7 @@ interface SceneOptions {
maxPerRow?: number; maxPerRow?: number;
itemHeight?: number; itemHeight?: number;
repeatDirection?: RepeatDirection; repeatDirection?: RepeatDirection;
variableRefresh?: VariableRefresh;
} }
function buildScene( function buildScene(
@ -334,6 +356,7 @@ function buildScene(
isMulti: true, isMulti: true,
includeAll: true, includeAll: true,
delayMs: options.variableQueryTime, delayMs: options.variableQueryTime,
refresh: options.variableRefresh,
optionsToReturn: variableOptions ?? [ optionsToReturn: variableOptions ?? [
{ label: 'A', value: 'A1' }, { label: 'A', value: 'A1' },
{ label: 'B', value: 'B1' }, { label: 'B', value: 'B1' },

View File

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