mirror of
https://github.com/grafana/grafana.git
synced 2025-01-24 07:17:08 -06:00
Field config: Add support for paths in default field config setup (#27570)
* Add support for paths in default field config setup * Typecheck fix
This commit is contained in:
parent
e350e1fff6
commit
e04e3e7d46
@ -1,13 +1,13 @@
|
||||
import React, { useCallback, ReactNode } from 'react';
|
||||
import React, { ReactNode, useCallback } from 'react';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import {
|
||||
DataFrame,
|
||||
DocsId,
|
||||
FieldConfigPropertyItem,
|
||||
FieldConfigSource,
|
||||
PanelPlugin,
|
||||
SelectableValue,
|
||||
VariableSuggestionsScope,
|
||||
DocsId,
|
||||
} from '@grafana/data';
|
||||
import { Container, Counter, FeatureInfoBox, Field, fieldMatchersUI, Label, useTheme, ValuePicker } from '@grafana/ui';
|
||||
import { getDataLinksVariableSuggestions } from '../../../panel/panellinks/link_srv';
|
||||
@ -17,6 +17,7 @@ import { OptionsGroup } from './OptionsGroup';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { css } from 'emotion';
|
||||
import { getDocsLink } from 'app/core/utils/docsLinks';
|
||||
import { updateDefaultFieldConfigValue } from './utils';
|
||||
|
||||
interface Props {
|
||||
plugin: PanelPlugin;
|
||||
@ -32,6 +33,7 @@ interface Props {
|
||||
export const OverrideFieldConfigEditor: React.FC<Props> = props => {
|
||||
const theme = useTheme();
|
||||
const { config } = props;
|
||||
|
||||
const onOverrideChange = (index: number, override: any) => {
|
||||
const { config } = props;
|
||||
let overrides = cloneDeep(config.overrides);
|
||||
@ -128,32 +130,9 @@ export const OverrideFieldConfigEditor: React.FC<Props> = props => {
|
||||
};
|
||||
|
||||
export const DefaultFieldConfigEditor: React.FC<Props> = ({ data, onChange, config, plugin }) => {
|
||||
const setDefaultValue = useCallback(
|
||||
const onDefaultValueChange = useCallback(
|
||||
(name: string, value: any, isCustom: boolean | undefined) => {
|
||||
const defaults = { ...config.defaults };
|
||||
const remove = value === undefined || value === null || '';
|
||||
|
||||
if (isCustom) {
|
||||
if (defaults.custom) {
|
||||
if (remove) {
|
||||
defaults.custom = { ...defaults.custom };
|
||||
delete defaults.custom[name];
|
||||
} else {
|
||||
defaults.custom = { ...defaults.custom, [name]: value };
|
||||
}
|
||||
} else if (!remove) {
|
||||
defaults.custom = { [name]: value };
|
||||
}
|
||||
} else if (remove) {
|
||||
delete (defaults as any)[name];
|
||||
} else {
|
||||
(defaults as any)[name] = value;
|
||||
}
|
||||
|
||||
onChange({
|
||||
...config,
|
||||
defaults,
|
||||
});
|
||||
onChange(updateDefaultFieldConfigValue(config, name, value, isCustom));
|
||||
},
|
||||
[config, onChange]
|
||||
);
|
||||
@ -187,7 +166,7 @@ export const DefaultFieldConfigEditor: React.FC<Props> = ({ data, onChange, conf
|
||||
<item.editor
|
||||
item={item}
|
||||
value={value}
|
||||
onChange={v => setDefaultValue(item.path, v, item.isCustom)}
|
||||
onChange={v => onDefaultValueChange(item.path, v, item.isCustom)}
|
||||
context={{
|
||||
data,
|
||||
getSuggestions: (scope?: VariableSuggestionsScope) => getDataLinksVariableSuggestions(data, scope),
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { FieldConfig, PanelPlugin, standardFieldConfigEditorRegistry } from '@grafana/data';
|
||||
import { supportsDataQuery } from './utils';
|
||||
import { FieldConfig, FieldConfigSource, PanelPlugin, standardFieldConfigEditorRegistry } from '@grafana/data';
|
||||
import { supportsDataQuery, updateDefaultFieldConfigValue } from './utils';
|
||||
|
||||
describe('standardFieldConfigEditorRegistry', () => {
|
||||
const dummyConfig: FieldConfig = {
|
||||
@ -50,3 +50,39 @@ describe('supportsDataQuery', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateDefaultFieldConfigValue', () => {
|
||||
it.each`
|
||||
property | isCustom | newValue | expected
|
||||
${'a'} | ${false} | ${2} | ${{ a: 2, b: { c: 'nested default' }, custom: { d: 1, e: { f: 'nested custom' } } }}
|
||||
${'b.c'} | ${false} | ${'nested default updated'} | ${{ a: 1, b: { c: 'nested default updated' }, custom: { d: 1, e: { f: 'nested custom' } } }}
|
||||
${'a'} | ${false} | ${undefined} | ${{ b: { c: 'nested default' }, custom: { d: 1, e: { f: 'nested custom' } } }}
|
||||
${'b'} | ${false} | ${undefined} | ${{ a: 1, custom: { d: 1, e: { f: 'nested custom' } } }}
|
||||
${'b.c'} | ${false} | ${undefined} | ${{ a: 1, b: {}, custom: { d: 1, e: { f: 'nested custom' } } }}
|
||||
${'d'} | ${true} | ${2} | ${{ a: 1, b: { c: 'nested default' }, custom: { d: 2, e: { f: 'nested custom' } } }}
|
||||
${'e.f'} | ${true} | ${'nested custom updated'} | ${{ a: 1, b: { c: 'nested default' }, custom: { d: 1, e: { f: 'nested custom updated' } } }}
|
||||
${'d'} | ${true} | ${undefined} | ${{ a: 1, b: { c: 'nested default' }, custom: { e: { f: 'nested custom' } } }}
|
||||
${'e'} | ${true} | ${undefined} | ${{ a: 1, b: { c: 'nested default' }, custom: { d: 1 } }}
|
||||
${'e.f'} | ${true} | ${undefined} | ${{ a: 1, b: { c: 'nested default' }, custom: { d: 1, e: {} } }}
|
||||
`(
|
||||
'when updating property:$property (is custom: $isCustom) with $newValue',
|
||||
({ property, isCustom, newValue, expected }) => {
|
||||
const config = {
|
||||
defaults: {
|
||||
a: 1,
|
||||
b: {
|
||||
c: 'nested default',
|
||||
},
|
||||
custom: {
|
||||
d: 1,
|
||||
e: { f: 'nested custom' },
|
||||
},
|
||||
},
|
||||
overrides: [],
|
||||
};
|
||||
expect(updateDefaultFieldConfigValue(config as FieldConfigSource, property, newValue, isCustom).defaults).toEqual(
|
||||
expected
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { CSSProperties } from 'react';
|
||||
import { set as lodashSet, omit } from 'lodash';
|
||||
import { FieldConfigSource, PanelPlugin } from '@grafana/data';
|
||||
import { PanelModel } from '../../state/PanelModel';
|
||||
import { DisplayMode } from './types';
|
||||
import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT } from 'app/core/constants';
|
||||
import { PanelPlugin } from '@grafana/data';
|
||||
|
||||
export function calculatePanelSize(mode: DisplayMode, width: number, height: number, panel: PanelModel): CSSProperties {
|
||||
if (mode === DisplayMode.Fill) {
|
||||
@ -29,3 +30,34 @@ export function calculatePanelSize(mode: DisplayMode, width: number, height: num
|
||||
export function supportsDataQuery(plugin: PanelPlugin | undefined): boolean {
|
||||
return plugin?.meta.skipDataQuery === false;
|
||||
}
|
||||
|
||||
export const updateDefaultFieldConfigValue = (
|
||||
config: FieldConfigSource,
|
||||
name: string,
|
||||
value: any,
|
||||
isCustom?: boolean
|
||||
) => {
|
||||
let defaults = { ...config.defaults };
|
||||
const remove = value === undefined || value === null || '';
|
||||
|
||||
if (isCustom) {
|
||||
if (defaults.custom) {
|
||||
if (remove) {
|
||||
defaults.custom = omit(defaults.custom, name);
|
||||
} else {
|
||||
defaults.custom = lodashSet({ ...defaults.custom }, name, value);
|
||||
}
|
||||
} else if (!remove) {
|
||||
defaults.custom = lodashSet({ ...defaults.custom }, name, value);
|
||||
}
|
||||
} else if (remove) {
|
||||
defaults = omit(defaults, name);
|
||||
} else {
|
||||
defaults = lodashSet({ ...defaults }, name, value);
|
||||
}
|
||||
|
||||
return {
|
||||
...config,
|
||||
defaults,
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user