mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
ad6cd55301
commit
a214fbd7cf
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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' },
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user