grafana/public/app/features/scenes/components/VizPanel/VizPanelRenderer.tsx
Dominik Prokop 831e7697ae
grafana/data: Move useFieldOverrides from core (#60817)
* grafana/data: Move useFieldOverrides from core

* Update packages/grafana-data/src/field/fieldOverrides.ts

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>

* Review

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
2023-01-02 02:27:48 -08:00

102 lines
3.9 KiB
TypeScript

import React, { RefCallback, useMemo } from 'react';
import { useMeasure } from 'react-use';
import { PluginContextProvider, useFieldOverrides } from '@grafana/data';
import { getTemplateSrv } from '@grafana/runtime';
import { PanelChrome, ErrorBoundaryAlert, useTheme2 } from '@grafana/ui';
import { appEvents } from 'app/core/core';
import { sceneGraph } from '../../core/sceneGraph';
import { SceneComponentProps } from '../../core/types';
import { SceneQueryRunner } from '../../querying/SceneQueryRunner';
import { CustomFormatterFn } from '../../variables/interpolation/sceneInterpolator';
import { SceneDragHandle } from '../SceneDragHandle';
import { VizPanel } from './VizPanel';
export function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {
const { title, options, fieldConfig, pluginId, pluginLoadError, $data, placement } = model.useState();
const theme = useTheme2();
const replace = useMemo(() => getTemplateSrv().replace, []);
const [ref, { width, height }] = useMeasure();
const plugin = model.getPlugin();
const { data } = sceneGraph.getData(model).useState();
const parentLayout = sceneGraph.getLayout(model);
// TODO: this should probably be parentLayout.isDraggingEnabled() ? placement?.isDraggable : false
// The current logic is not correct, just because parent layout itself is not draggable does not mean children are not
const isDraggable = parentLayout.state.placement?.isDraggable ? placement?.isDraggable : false;
const dragHandle = <SceneDragHandle layoutKey={parentLayout.state.key!} />;
const titleInterpolated = sceneGraph.interpolate(model, title);
// Not sure we need to subscribe to this state
const timeZone = sceneGraph.getTimeRange(model).state.timeZone;
const dataWithOverrides = useFieldOverrides(plugin, fieldConfig, data, timeZone, theme, replace);
if (pluginLoadError) {
return <div>Failed to load plugin: {pluginLoadError}</div>;
}
if (!plugin || !plugin.hasPluginId(pluginId)) {
return <div>Loading plugin panel...</div>;
}
if (!plugin.panel) {
return <div>Panel plugin has no panel component</div>;
}
const PanelComponent = plugin.panel;
// Query runner needs to with for auto maxDataPoints
if ($data instanceof SceneQueryRunner) {
$data.setContainerWidth(width);
}
return (
<div ref={ref as RefCallback<HTMLDivElement>} style={{ position: 'absolute', width: '100%', height: '100%' }}>
<PanelChrome
title={titleInterpolated}
width={width}
height={height}
leftItems={isDraggable ? [dragHandle] : undefined}
>
{(innerWidth, innerHeight) => (
<>
{!dataWithOverrides && <div>No data...</div>}
{dataWithOverrides && (
<ErrorBoundaryAlert dependencies={[plugin, data]}>
<PluginContextProvider meta={plugin.meta}>
<PanelComponent
id={1}
data={dataWithOverrides}
title={title}
timeRange={dataWithOverrides.timeRange}
timeZone={timeZone}
options={options}
fieldConfig={fieldConfig}
transparent={false}
width={innerWidth}
height={innerHeight}
renderCounter={0}
replaceVariables={(str, scopedVars, format) =>
sceneGraph.interpolate(model, str, scopedVars, format as string | CustomFormatterFn | undefined)
}
onOptionsChange={model.onOptionsChange}
onFieldConfigChange={model.onFieldConfigChange}
onChangeTimeRange={model.onChangeTimeRange}
eventBus={appEvents}
/>
</PluginContextProvider>
</ErrorBoundaryAlert>
)}
</>
)}
</PanelChrome>
</div>
);
}
VizPanelRenderer.displayName = 'ScenePanelRenderer';