Plugins: added the possibility to manage field config state outside of the panel renderer. (#38944)

This commit is contained in:
Marcus Andersson 2021-09-08 15:02:44 +02:00 committed by GitHub
parent 7f49ad4152
commit 3bb2ee9de6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 4 deletions

View File

@ -13,10 +13,11 @@ export interface PanelRendererProps<P extends object = any, F extends object = a
data: PanelData;
pluginId: string;
title: string;
fieldConfig?: FieldConfigSource<F>;
options?: P;
onOptionsChange?: (options: P) => void;
onChangeTimeRange?: (timeRange: AbsoluteTimeRange) => void;
fieldConfig?: FieldConfigSource<F>;
onFieldConfigChange?: (config: FieldConfigSource<F>) => void;
timeZone?: string;
width: number;
height: number;

View File

@ -1,4 +1,4 @@
import React, { useState, useMemo } from 'react';
import React, { useState, useMemo, useRef, useCallback } from 'react';
import { applyFieldOverrides, FieldConfigSource, getTimeZone, PanelData, PanelPlugin } from '@grafana/data';
import { PanelRendererProps } from '@grafana/runtime';
import { appEvents } from 'app/core/core';
@ -18,10 +18,9 @@ export function PanelRenderer<P extends object = any, F extends object = any>(pr
title,
onOptionsChange = () => {},
onChangeTimeRange = () => {},
fieldConfig: config = { defaults: {}, overrides: [] },
} = props;
const [fieldConfig, setFieldConfig] = useState<FieldConfigSource>(config);
const [fieldConfig, setFieldConfig] = useFieldConfigState(props);
const { value: plugin, error, loading } = useAsync(() => importPanelPlugin(pluginId), [pluginId]);
const optionsWithDefaults = useOptionDefaults(plugin, options, fieldConfig);
const dataWithOverrides = useFieldOverrides(plugin, optionsWithDefaults, data, timeZone);
@ -118,3 +117,35 @@ function useFieldOverrides(
function pluginIsLoading(loading: boolean, plugin: PanelPlugin<any, any> | undefined, pluginId: string) {
return loading || plugin?.meta.id !== pluginId;
}
function useFieldConfigState(props: PanelRendererProps): [FieldConfigSource, (config: FieldConfigSource) => void] {
const {
onFieldConfigChange,
fieldConfig = {
defaults: {},
overrides: [],
},
} = props;
// First render will detect if the PanelRenderer will manage the
// field config state internally or externally by the consuming
// component. This will also prevent the way of managing state to
// change during the components life cycle.
const isManagedInternally = useRef(() => !!onFieldConfigChange);
const [internalConfig, setInternalConfig] = useState(fieldConfig);
const setExternalConfig = useCallback(
(config: FieldConfigSource) => {
if (!onFieldConfigChange) {
return;
}
onFieldConfigChange(config);
},
[onFieldConfigChange]
);
if (isManagedInternally) {
return [internalConfig, setInternalConfig];
}
return [fieldConfig, setExternalConfig];
}