mirror of
https://github.com/grafana/grafana.git
synced 2025-02-15 01:53:33 -06:00
* VizWrapper to handle some state * alertingqueryrunner first edition * added so we always set name and uid when changing datasource. * wip. * wip * added support for canceling requests. * util for getting time ranges for expression queries * remove logs, store data in state * merge from run branch * incremental commit * viz working * added structure for marble testing. * paddings and move viz picker * less height for viz, less width on rows * change so the expression buttons doesnt submit form. * fixed run button. * replaced mocks with implementation that will set default query + expression. * merge with run queries * fixed so we set a datasource name for the default expression rule. * improving expression guard. * lots of styling fixes for viz * adding placeholder for relative time range. * fixed story. * added basic structure to handle open/close of time range picker. * removed section from TimeOptions since it isn't used any where. * adding mapper and tests * move relativetimepicker to its own dir * added some simple tests. * changed test. * use relativetimerangeinput * redo state management * refactored the tests. * replace timerange with relativetimerange * wip * wip * did some refactoring. * refactored time option formatting. * added proper formatting and display of time range. * add relative time description, slight refactor of height * fixed incorrect import. * added validator and changed formatting. * removed unused dep. * reverted back to internal function. * fixed display of relative time range picker. * fixed failing tests. * fixed parsing issue. * fixed position of time range picker. * some more refactorings. * fixed validation of really big values. * added another test. * restored the step2 check. * fixed merge issue. * Update packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> * reverted change. * fixed merge conflict. * fixed todo. * sort some paddings * replace theme with theme2 Co-authored-by: Peter Holmberg <peter.hlmbrg@gmail.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>
121 lines
3.5 KiB
TypeScript
121 lines
3.5 KiB
TypeScript
import React, { useState, useMemo } from 'react';
|
|
import { applyFieldOverrides, FieldConfigSource, getTimeZone, PanelData, PanelPlugin } from '@grafana/data';
|
|
import { PanelRendererProps } from '@grafana/runtime';
|
|
import { appEvents } from 'app/core/core';
|
|
import { useAsync } from 'react-use';
|
|
import { getPanelOptionsWithDefaults, OptionDefaults } from '../dashboard/state/getPanelOptionsWithDefaults';
|
|
import { importPanelPlugin } from '../plugins/plugin_loader';
|
|
import { useTheme2 } from '@grafana/ui';
|
|
|
|
export function PanelRenderer<P extends object = any, F extends object = any>(props: PanelRendererProps<P, F>) {
|
|
const {
|
|
pluginId,
|
|
data,
|
|
timeZone = getTimeZone(),
|
|
options = {},
|
|
width,
|
|
height,
|
|
title,
|
|
onOptionsChange = () => {},
|
|
onChangeTimeRange = () => {},
|
|
fieldConfig: config = { defaults: {}, overrides: [] },
|
|
} = props;
|
|
|
|
const [fieldConfig, setFieldConfig] = useState<FieldConfigSource>(config);
|
|
const { value: plugin, error, loading } = useAsync(() => importPanelPlugin(pluginId), [pluginId]);
|
|
const optionsWithDefaults = useOptionDefaults(plugin, options, fieldConfig);
|
|
const dataWithOverrides = useFieldOverrides(plugin, optionsWithDefaults, data, timeZone);
|
|
|
|
if (error) {
|
|
return <div>Failed to load plugin: {error.message}</div>;
|
|
}
|
|
|
|
if (pluginIsLoading(loading, plugin, pluginId)) {
|
|
return <div>Loading plugin panel...</div>;
|
|
}
|
|
|
|
if (!plugin || !plugin.panel) {
|
|
return <div>Seems like the plugin you are trying to load does not have a panel component.</div>;
|
|
}
|
|
|
|
if (!dataWithOverrides) {
|
|
return <div>No panel data</div>;
|
|
}
|
|
|
|
const PanelComponent = plugin.panel;
|
|
|
|
return (
|
|
<PanelComponent
|
|
id={1}
|
|
data={dataWithOverrides}
|
|
title={title}
|
|
timeRange={dataWithOverrides.timeRange}
|
|
timeZone={timeZone}
|
|
options={optionsWithDefaults!.options}
|
|
fieldConfig={fieldConfig}
|
|
transparent={false}
|
|
width={width}
|
|
height={height}
|
|
renderCounter={0}
|
|
replaceVariables={(str: string) => str}
|
|
onOptionsChange={onOptionsChange}
|
|
onFieldConfigChange={setFieldConfig}
|
|
onChangeTimeRange={onChangeTimeRange}
|
|
eventBus={appEvents}
|
|
/>
|
|
);
|
|
}
|
|
|
|
function useOptionDefaults<P extends object = any, F extends object = any>(
|
|
plugin: PanelPlugin | undefined,
|
|
options: P,
|
|
fieldConfig: FieldConfigSource<F>
|
|
): OptionDefaults | undefined {
|
|
return useMemo(() => {
|
|
if (!plugin) {
|
|
return;
|
|
}
|
|
|
|
return getPanelOptionsWithDefaults({
|
|
plugin,
|
|
currentOptions: options,
|
|
currentFieldConfig: fieldConfig,
|
|
isAfterPluginChange: false,
|
|
});
|
|
}, [plugin, fieldConfig, options]);
|
|
}
|
|
|
|
function useFieldOverrides(
|
|
plugin: PanelPlugin | undefined,
|
|
defaultOptions: OptionDefaults | undefined,
|
|
data: PanelData | undefined,
|
|
timeZone: string
|
|
): PanelData | undefined {
|
|
const fieldConfig = defaultOptions?.fieldConfig;
|
|
const series = data?.series;
|
|
const fieldConfigRegistry = plugin?.fieldConfigRegistry;
|
|
const theme = useTheme2();
|
|
|
|
return useMemo(() => {
|
|
if (!fieldConfigRegistry || !fieldConfig || !data) {
|
|
return;
|
|
}
|
|
|
|
return {
|
|
...data,
|
|
series: applyFieldOverrides({
|
|
data: series,
|
|
fieldConfig,
|
|
fieldConfigRegistry,
|
|
replaceVariables: (str: string) => str,
|
|
theme,
|
|
timeZone,
|
|
}),
|
|
};
|
|
}, [fieldConfigRegistry, fieldConfig, data, series, timeZone, theme]);
|
|
}
|
|
|
|
function pluginIsLoading(loading: boolean, plugin: PanelPlugin<any, any> | undefined, pluginId: string) {
|
|
return loading || plugin?.meta.id !== pluginId;
|
|
}
|