Hi there!
So I have a curious problem. I am migrating an angular Datasource plugin to react, with this migration I also need to change the custom DataQuery Type.
In order to allow a seamless migration from dashboard JSONs that were created with the angular plugin (and the old DataQuery Type) I tried doing a mapping in a useEffect
in the QueryEditor
component.
So to “migrate” the old dashboard JSON I would then just import the JSON into a new dashboard that uses the react plugin version, go into edit mode of the panels, which would trigger the useEffect
with the mapping of the QueryEditor
.
This works correctly for Panels that have only 1 query. However with Panels with more than 1 query the props.onChange(migratedQuery)
method does not update the query.
Either I am missing some crucial step here that needs to be considered when working with panels with multiple queries (couldn’t find anything in the docs though) or this is some kind of bug in grafana. Does anybody have a hint or any experience with this? Is there another way to achieve this mapping/migration? Thanks!
Here some simplified example code for reference:
types.ts
OldDataQueryType {
filter: {operator: string, value: string}[],
resultFormat: 'table' | 'time_series'
}
NewDataQueryType {
filters: {operator: string, value: string | boolean | number | string[]}[]
}
function isOldDataQueryType(query: OldDataQueryType | NewDataQueryType): query is OldDataQueryType {
return (query as OldDataQueryType).resultFormat != null;
}
QueryEditor.tsx
export function QueryEditor(props: Props) {
useEffect(() => {
if (!isOldDataQueryType(props.query)) {
return;
}
const convertedFilters = props.query.filter.map((filter) => {
return {
operator: filter.operator,
value: convertFilterValueToProperType(
filter.value,
filter.operator,
),
};
});
const oldQuery: OldDataQueryType = { ...props.query };
delete oldQuery['resultFormat'];
// this mapping always works (checked with console.log),
// so there is no bug in the mapping logic itself
const newQuery: NewDataQueryType = {
...oldQuery,
filters: convertedFilters,
};
// problem lies here, with only 1 query the query change gets propagated upwards correctly,
// with more than 1 queries the changes get lost somewhere and
// don't get to the query() Method in the datasource.ts
props.onChange(newQuery);
props.onRunQuery();
}, [props.query]);
}