mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 18:30:41 -06:00
Scenes: Add support for panel overrides (#81470)
This commit is contained in:
parent
80afc8202d
commit
0f6380b76a
@ -3,8 +3,9 @@ import React, { useMemo, useState } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { SceneComponentProps, SceneObjectBase, SceneObjectState } from '@grafana/scenes';
|
||||
import { SceneComponentProps, SceneObjectBase, SceneObjectState, sceneGraph } from '@grafana/scenes';
|
||||
import { ButtonGroup, FilterInput, RadioButtonGroup, ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
import { getFieldOverrideCategories } from 'app/features/dashboard/components/PanelEditor/getFieldOverrideElements';
|
||||
import { getPanelFrameCategory2 } from 'app/features/dashboard/components/PanelEditor/getPanelFrameOptions';
|
||||
import { getVisualizationOptions2 } from 'app/features/dashboard/components/PanelEditor/getVisualizationOptions';
|
||||
import { getAllPanelPluginMeta } from 'app/features/panel/state/util';
|
||||
@ -26,9 +27,13 @@ export class PanelOptionsPane extends SceneObjectBase<PanelOptionsPaneState> {
|
||||
static Component = ({ model }: SceneComponentProps<PanelOptionsPane>) => {
|
||||
const { panelManager } = model;
|
||||
const { panel } = panelManager.state;
|
||||
const { pluginId, options } = panel.useState();
|
||||
const dataObject = sceneGraph.getData(panel);
|
||||
const rawData = dataObject.useState();
|
||||
const dataWithFieldConfig = panel.applyFieldConfig(rawData.data!);
|
||||
const { pluginId, options, fieldConfig } = panel.useState();
|
||||
const styles = useStyles2(getStyles);
|
||||
const [isVizPickerOpen, setVizPickerOpen] = useState(true);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const panelFrameOptions = useMemo(() => getPanelFrameCategory2(panel), [panel]);
|
||||
|
||||
const visualizationOptions = useMemo(() => {
|
||||
@ -44,9 +49,30 @@ export class PanelOptionsPane extends SceneObjectBase<PanelOptionsPaneState> {
|
||||
instanceState: panel.getPanelContext().instanceState!,
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [panel, options]);
|
||||
}, [panel, options, fieldConfig]);
|
||||
|
||||
const mainBoxElements = [panelFrameOptions.render(), ...(visualizationOptions?.map((v) => v.render()) ?? [])];
|
||||
const justOverrides = useMemo(
|
||||
() =>
|
||||
getFieldOverrideCategories(
|
||||
fieldConfig,
|
||||
panel.getPlugin()?.fieldConfigRegistry!,
|
||||
dataWithFieldConfig.series,
|
||||
searchQuery,
|
||||
(newConfig) => {
|
||||
panel.setState({
|
||||
fieldConfig: newConfig,
|
||||
});
|
||||
}
|
||||
),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[searchQuery, panel, fieldConfig]
|
||||
);
|
||||
|
||||
const mainBoxElements = [
|
||||
panelFrameOptions.render(),
|
||||
...(visualizationOptions?.map((v) => v.render()) ?? []),
|
||||
...justOverrides.map((v) => v.render()),
|
||||
];
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
@ -67,9 +93,9 @@ export class PanelOptionsPane extends SceneObjectBase<PanelOptionsPaneState> {
|
||||
<div className={styles.top}>
|
||||
<FilterInput
|
||||
className={styles.searchOptions}
|
||||
value={''}
|
||||
value={searchQuery}
|
||||
placeholder="Search options"
|
||||
onChange={() => {}}
|
||||
onChange={setSearchQuery}
|
||||
/>
|
||||
<RadioButtonGroup
|
||||
options={[
|
||||
|
@ -33,7 +33,14 @@ export const OptionsPaneOptions = (props: OptionPaneRenderProps) => {
|
||||
);
|
||||
|
||||
const justOverrides = useMemo(
|
||||
() => getFieldOverrideCategories(props, searchQuery),
|
||||
() =>
|
||||
getFieldOverrideCategories(
|
||||
props.panel.fieldConfig,
|
||||
props.plugin.fieldConfigRegistry,
|
||||
props.data?.series ?? [],
|
||||
searchQuery,
|
||||
props.onFieldConfigsChange
|
||||
),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[panel.configRev, props.data, props.instanceState, searchQuery]
|
||||
);
|
||||
|
@ -11,6 +11,8 @@ import {
|
||||
ConfigOverrideRule,
|
||||
GrafanaTheme2,
|
||||
fieldMatchers,
|
||||
FieldConfigSource,
|
||||
DataFrame,
|
||||
} from '@grafana/data';
|
||||
import { fieldMatchersUI, useStyles2, ValuePicker } from '@grafana/ui';
|
||||
import { getDataLinksVariableSuggestions } from 'app/features/panel/panellinks/link_srv';
|
||||
@ -19,31 +21,31 @@ import { DynamicConfigValueEditor } from './DynamicConfigValueEditor';
|
||||
import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor';
|
||||
import { OverrideCategoryTitle } from './OverrideCategoryTitle';
|
||||
import { OptionPaneRenderProps } from './types';
|
||||
|
||||
export function getFieldOverrideCategories(
|
||||
props: OptionPaneRenderProps,
|
||||
searchQuery: string
|
||||
fieldConfig: FieldConfigSource,
|
||||
registry: FieldConfigOptionsRegistry,
|
||||
data: DataFrame[],
|
||||
searchQuery: string,
|
||||
onFieldConfigsChange: (config: FieldConfigSource) => void
|
||||
): OptionsPaneCategoryDescriptor[] {
|
||||
const categories: OptionsPaneCategoryDescriptor[] = [];
|
||||
const currentFieldConfig = props.panel.fieldConfig;
|
||||
const registry = props.plugin.fieldConfigRegistry;
|
||||
const data = props.data?.series ?? [];
|
||||
const currentFieldConfig = fieldConfig;
|
||||
|
||||
if (registry.isEmpty()) {
|
||||
if (!registry || registry.isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const onOverrideChange = (index: number, override: ConfigOverrideRule) => {
|
||||
let overrides = cloneDeep(currentFieldConfig.overrides);
|
||||
overrides[index] = override;
|
||||
props.onFieldConfigsChange({ ...currentFieldConfig, overrides });
|
||||
onFieldConfigsChange({ ...currentFieldConfig, overrides });
|
||||
};
|
||||
|
||||
const onOverrideRemove = (overrideIndex: number) => {
|
||||
let overrides = cloneDeep(currentFieldConfig.overrides);
|
||||
overrides.splice(overrideIndex, 1);
|
||||
props.onFieldConfigsChange({ ...currentFieldConfig, overrides });
|
||||
onFieldConfigsChange({ ...currentFieldConfig, overrides });
|
||||
};
|
||||
|
||||
const onOverrideAdd = (value: SelectableValue<string>) => {
|
||||
@ -52,7 +54,7 @@ export function getFieldOverrideCategories(
|
||||
return;
|
||||
}
|
||||
|
||||
props.onFieldConfigsChange({
|
||||
onFieldConfigsChange({
|
||||
...currentFieldConfig,
|
||||
overrides: [
|
||||
...currentFieldConfig.overrides,
|
||||
@ -135,7 +137,7 @@ export function getFieldOverrideCategories(
|
||||
<matcherUi.component
|
||||
id={`${matcherUi.matcher.id}-${idx}`}
|
||||
matcher={matcherUi.matcher}
|
||||
data={props.data?.series ?? []}
|
||||
data={data ?? []}
|
||||
options={override.matcher.options}
|
||||
onChange={onMatcherConfigChange}
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user