PanelModel: Use shouldMigrate when migrating (#108998)

This commit is contained in:
Adela Almasan
2025-08-06 21:21:36 +00:00
committed by GitHub
parent c066254e67
commit 62a1f6c0b8
3 changed files with 60 additions and 6 deletions
@@ -3,6 +3,7 @@ import { ComponentClass, ComponentType } from 'react';
import { FieldConfigOptionsRegistry } from '../field/FieldConfigOptionsRegistry';
import { StandardEditorContext } from '../field/standardFieldConfigEditorRegistry';
import { PanelModel } from '../types/dashboard';
import { FieldConfigProperty, FieldConfigSource } from '../types/fieldOverrides';
import {
PanelPluginMeta,
@@ -113,7 +114,7 @@ export class PanelPlugin<
panel: ComponentType<PanelProps<TOptions>> | null;
editor?: ComponentClass<PanelEditorProps<TOptions>>;
onPanelMigration?: PanelMigrationHandler<TOptions>;
shouldMigrate?: (panel: ComponentType<PanelProps<TOptions>> | null) => boolean;
shouldMigrate?: (panel: PanelModel) => boolean;
onPanelTypeChanged?: PanelTypeChangedHandler<TOptions>;
noPadding?: boolean;
dataSupport: PanelPluginDataSupport = {
@@ -208,10 +209,7 @@ export class PanelPlugin<
*
* This is a good place to support any changes to the options model
*/
setMigrationHandler(
handler: PanelMigrationHandler<TOptions>,
shouldMigrate?: (panel: ComponentType<PanelProps<TOptions>> | null) => boolean
) {
setMigrationHandler(handler: PanelMigrationHandler<TOptions>, shouldMigrate?: (panel: PanelModel) => boolean) {
this.onPanelMigration = handler;
this.shouldMigrate = shouldMigrate;
return this;
@@ -146,12 +146,16 @@ describe('PanelModel', () => {
describe('migrations', () => {
let initialMigrator: PanelMigrationHandler<(typeof model)['options']> | undefined = undefined;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let initialShouldMigrate: ((panel: any) => boolean) | undefined = undefined;
beforeEach(() => {
initialMigrator = tablePlugin.onPanelMigration;
initialShouldMigrate = tablePlugin.shouldMigrate;
});
afterEach(() => {
tablePlugin.onPanelMigration = initialMigrator;
tablePlugin.shouldMigrate = initialShouldMigrate;
});
it('should run sync migrations', async () => {
@@ -179,6 +183,58 @@ describe('PanelModel', () => {
await model.pluginLoaded(tablePlugin);
expect(model.options).toMatchObject({ valueToMigrate: 'new-version' });
});
it('should run migration when shouldMigrate=true and same version', async () => {
model.options.valueToMigrate = 'old-legacy';
model.pluginVersion = '1.0.0';
tablePlugin.meta.info.version = '1.0.0';
tablePlugin.onPanelMigration = (p) => ({ ...p.options, valueToMigrate: 'migrated-by-shouldMigrate' });
tablePlugin.shouldMigrate = () => true;
await model.pluginLoaded(tablePlugin);
expect(model.options).toMatchObject({ valueToMigrate: 'migrated-by-shouldMigrate' });
});
it('should run migration when shouldMigrate=false and versions are different', async () => {
model.options.valueToMigrate = 'old-legacy';
model.pluginVersion = '1.0.0';
tablePlugin.meta.info.version = '2.0.0';
tablePlugin.onPanelMigration = (p) => ({ ...p.options, valueToMigrate: 'migrated-by-version' });
tablePlugin.shouldMigrate = () => false;
await model.pluginLoaded(tablePlugin);
expect(model.options).toMatchObject({ valueToMigrate: 'migrated-by-version' });
});
it('should fallback to version comparison when shouldMigrate is false', async () => {
model.options.valueToMigrate = 'old-legacy';
model.pluginVersion = '1.0.0';
tablePlugin.meta.info.version = '1.0.0';
tablePlugin.onPanelMigration = (p) => ({ ...p.options, valueToMigrate: 'should-not-migrate' });
tablePlugin.shouldMigrate = () => false;
await model.pluginLoaded(tablePlugin);
expect(model.options).toMatchObject({ valueToMigrate: 'old-legacy' });
});
it('should fallback to version comparison when shouldMigrate is not defined', async () => {
model.options.valueToMigrate = 'old-legacy';
model.pluginVersion = '1.0.0';
tablePlugin.meta.info.version = '2.0.0';
tablePlugin.onPanelMigration = (p) => ({ ...p.options, valueToMigrate: 'migrated-by-version' });
tablePlugin.shouldMigrate = undefined;
await model.pluginLoaded(tablePlugin);
expect(model.options).toMatchObject({ valueToMigrate: 'migrated-by-version' });
});
});
it('should apply defaults', () => {
@@ -458,7 +458,7 @@ export class PanelModel implements DataConfigSource, IPanelModel {
}
if (plugin.onPanelMigration) {
if (version !== this.pluginVersion) {
if (version !== this.pluginVersion || plugin.shouldMigrate?.(this)) {
const newPanelOptions = plugin.onPanelMigration(this);
this.options = await newPanelOptions;
this.pluginVersion = version;