mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
NewPanelEditor: Options/FieldConfig API for defaults and common options selection (#23214)
* Add "some" typesafety to panel options/field config APIs * Allow selected common field config properties config, allow option defaults config via fluent API * Update packages/grafana-data/src/panel/PanelPlugin.ts Co-Authored-By: Ryan McKinley <ryantxu@gmail.com> * Add defaults support for custom field config * Enable defaults setting for standard and custom field configs * Remove setFieldConfigDefaults from PanelPlugin API and replace it with useStandardFieldConfig * Update API for standard field config defaults Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
parent
a92bcb78a5
commit
dcf6bbc14f
@ -67,6 +67,9 @@ export const stringOverrideProcessor = (
|
|||||||
context: FieldOverrideContext,
|
context: FieldOverrideContext,
|
||||||
settings?: StringFieldConfigSettings
|
settings?: StringFieldConfigSettings
|
||||||
) => {
|
) => {
|
||||||
|
if (value === null || value === undefined) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
if (settings && settings.expandTemplateVars && context.replaceVariables) {
|
if (settings && settings.expandTemplateVars && context.replaceVariables) {
|
||||||
return context.replaceVariables(value, context.field!.config.scopedVars);
|
return context.replaceVariables(value, context.field!.config.scopedVars);
|
||||||
}
|
}
|
||||||
|
@ -12,4 +12,4 @@ export * from './datetime';
|
|||||||
export * from './text';
|
export * from './text';
|
||||||
export * from './valueFormats';
|
export * from './valueFormats';
|
||||||
export * from './field';
|
export * from './field';
|
||||||
export { PanelPlugin } from './panel/PanelPlugin';
|
export { PanelPlugin, defaultStandardFieldConfigProperties } from './panel/PanelPlugin';
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { identityOverrideProcessor } from '../field';
|
import { identityOverrideProcessor, standardEditorsRegistry } from '../field';
|
||||||
import { PanelPlugin } from './PanelPlugin';
|
import { PanelPlugin, standardFieldConfigProperties } from './PanelPlugin';
|
||||||
|
import { StandardFieldConfigProperties } from '../types';
|
||||||
|
|
||||||
describe('PanelPlugin', () => {
|
describe('PanelPlugin', () => {
|
||||||
describe('declarative options', () => {
|
describe('declarative options', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
standardEditorsRegistry.setInit(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: 'number',
|
||||||
|
},
|
||||||
|
] as any;
|
||||||
|
});
|
||||||
|
});
|
||||||
test('field config UI API', () => {
|
test('field config UI API', () => {
|
||||||
const panel = new PanelPlugin(() => {
|
const panel = new PanelPlugin(() => {
|
||||||
return <div>Panel</div>;
|
return <div>Panel</div>;
|
||||||
@ -45,4 +55,190 @@ describe('PanelPlugin', () => {
|
|||||||
expect(panel.optionEditors!.list()).toHaveLength(1);
|
expect(panel.optionEditors!.list()).toHaveLength(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('default options', () => {
|
||||||
|
describe('panel options', () => {
|
||||||
|
test('default values', () => {
|
||||||
|
const panel = new PanelPlugin(() => {
|
||||||
|
return <div>Panel</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.setPanelOptions(builder => {
|
||||||
|
builder
|
||||||
|
.addNumberInput({
|
||||||
|
id: 'numericOption',
|
||||||
|
name: 'Option editor',
|
||||||
|
description: 'Option editor description',
|
||||||
|
defaultValue: 10,
|
||||||
|
})
|
||||||
|
.addNumberInput({
|
||||||
|
id: 'numericOptionNoDefault',
|
||||||
|
name: 'Option editor',
|
||||||
|
description: 'Option editor description',
|
||||||
|
})
|
||||||
|
.addCustomEditor({
|
||||||
|
id: 'customOption',
|
||||||
|
name: 'Option editor',
|
||||||
|
description: 'Option editor description',
|
||||||
|
editor: () => <div>Editor</div>,
|
||||||
|
settings: {},
|
||||||
|
defaultValue: { value: 'Custom default value' },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedDefaults = {
|
||||||
|
numericOption: 10,
|
||||||
|
customOption: { value: 'Custom default value' },
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(panel.defaults).toEqual(expectedDefaults);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('default values for nested paths', () => {
|
||||||
|
const panel = new PanelPlugin(() => {
|
||||||
|
return <div>Panel</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.setPanelOptions(builder => {
|
||||||
|
builder.addNumberInput({
|
||||||
|
id: 'numericOption.nested',
|
||||||
|
name: 'Option editor',
|
||||||
|
description: 'Option editor description',
|
||||||
|
defaultValue: 10,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedDefaults = {
|
||||||
|
numericOption: { nested: 10 },
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(panel.defaults).toEqual(expectedDefaults);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('field config options', () => {
|
||||||
|
test('default values', () => {
|
||||||
|
const panel = new PanelPlugin(() => {
|
||||||
|
return <div>Panel</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.setCustomFieldOptions(builder => {
|
||||||
|
builder
|
||||||
|
.addNumberInput({
|
||||||
|
id: 'numericOption',
|
||||||
|
name: 'Option editor',
|
||||||
|
description: 'Option editor description',
|
||||||
|
defaultValue: 10,
|
||||||
|
})
|
||||||
|
.addNumberInput({
|
||||||
|
id: 'numericOptionNoDefault',
|
||||||
|
name: 'Option editor',
|
||||||
|
description: 'Option editor description',
|
||||||
|
})
|
||||||
|
.addCustomEditor({
|
||||||
|
id: 'customOption',
|
||||||
|
name: 'Option editor',
|
||||||
|
description: 'Option editor description',
|
||||||
|
editor: () => <div>Editor</div>,
|
||||||
|
override: () => <div>Override editor</div>,
|
||||||
|
process: identityOverrideProcessor,
|
||||||
|
shouldApply: () => true,
|
||||||
|
settings: {},
|
||||||
|
defaultValue: { value: 'Custom default value' },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedDefaults = {
|
||||||
|
numericOption: 10,
|
||||||
|
customOption: { value: 'Custom default value' },
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(panel.fieldConfigDefaults.defaults.custom).toEqual(expectedDefaults);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('default values for nested paths', () => {
|
||||||
|
const panel = new PanelPlugin(() => {
|
||||||
|
return <div>Panel</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.setCustomFieldOptions(builder => {
|
||||||
|
builder.addNumberInput({
|
||||||
|
id: 'numericOption.nested',
|
||||||
|
name: 'Option editor',
|
||||||
|
description: 'Option editor description',
|
||||||
|
defaultValue: 10,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedDefaults = {
|
||||||
|
numericOption: { nested: 10 },
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(panel.fieldConfigDefaults.defaults.custom).toEqual(expectedDefaults);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('standard field config options', () => {
|
||||||
|
test('standard config', () => {
|
||||||
|
const panel = new PanelPlugin(() => {
|
||||||
|
return <div>Panel</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.useStandardFieldConfig();
|
||||||
|
expect(panel.standardFieldConfigProperties).toEqual(Array.from(standardFieldConfigProperties.keys()));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('selected standard config', () => {
|
||||||
|
const panel = new PanelPlugin(() => {
|
||||||
|
return <div>Panel</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.useStandardFieldConfig([StandardFieldConfigProperties.Min, StandardFieldConfigProperties.Thresholds]);
|
||||||
|
expect(panel.standardFieldConfigProperties).toEqual(['min', 'thresholds']);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('default values', () => {
|
||||||
|
test('setting default values', () => {
|
||||||
|
const panel = new PanelPlugin(() => {
|
||||||
|
return <div>Panel</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.useStandardFieldConfig([StandardFieldConfigProperties.Color, StandardFieldConfigProperties.Min], {
|
||||||
|
[StandardFieldConfigProperties.Color]: '#ff00ff',
|
||||||
|
[StandardFieldConfigProperties.Min]: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(panel.standardFieldConfigProperties).toEqual(['color', 'min']);
|
||||||
|
|
||||||
|
expect(panel.fieldConfigDefaults).toEqual({
|
||||||
|
defaults: {
|
||||||
|
min: 10,
|
||||||
|
color: '#ff00ff',
|
||||||
|
},
|
||||||
|
overrides: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore defaults that are not specified as availeble properties', () => {
|
||||||
|
const panel = new PanelPlugin(() => {
|
||||||
|
return <div>Panel</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.useStandardFieldConfig([StandardFieldConfigProperties.Color], {
|
||||||
|
[StandardFieldConfigProperties.Color]: '#ff00ff',
|
||||||
|
[StandardFieldConfigProperties.Min]: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(panel.standardFieldConfigProperties).toEqual(['color']);
|
||||||
|
|
||||||
|
expect(panel.fieldConfigDefaults).toEqual({
|
||||||
|
defaults: {
|
||||||
|
color: '#ff00ff',
|
||||||
|
},
|
||||||
|
overrides: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -8,26 +8,48 @@ import {
|
|||||||
PanelPluginMeta,
|
PanelPluginMeta,
|
||||||
PanelProps,
|
PanelProps,
|
||||||
PanelTypeChangedHandler,
|
PanelTypeChangedHandler,
|
||||||
|
StandardFieldConfigProperties,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { FieldConfigEditorBuilder, PanelOptionsEditorBuilder } from '../utils/OptionsUIBuilders';
|
import { FieldConfigEditorBuilder, PanelOptionsEditorBuilder } from '../utils/OptionsUIBuilders';
|
||||||
import { ComponentClass, ComponentType } from 'react';
|
import { ComponentClass, ComponentType } from 'react';
|
||||||
|
import set from 'lodash/set';
|
||||||
|
import { deprecationWarning } from '../utils';
|
||||||
|
|
||||||
export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta> {
|
export const defaultStandardFieldConfigProperties: StandardFieldConfigProperties[] = [
|
||||||
private customFieldConfigsUIBuilder = new FieldConfigEditorBuilder();
|
StandardFieldConfigProperties.Min,
|
||||||
private _customFieldConfigs?: FieldConfigEditorRegistry;
|
StandardFieldConfigProperties.Max,
|
||||||
private registerCustomFieldConfigs?: (builder: FieldConfigEditorBuilder) => void;
|
StandardFieldConfigProperties.Title,
|
||||||
|
StandardFieldConfigProperties.Unit,
|
||||||
|
StandardFieldConfigProperties.Decimals,
|
||||||
|
StandardFieldConfigProperties.NoValue,
|
||||||
|
StandardFieldConfigProperties.Color,
|
||||||
|
StandardFieldConfigProperties.Thresholds,
|
||||||
|
StandardFieldConfigProperties.Mappings,
|
||||||
|
StandardFieldConfigProperties.Links,
|
||||||
|
];
|
||||||
|
|
||||||
private optionsUIBuilder = new PanelOptionsEditorBuilder();
|
export const standardFieldConfigProperties = new Map(defaultStandardFieldConfigProperties.map(p => [p, undefined]));
|
||||||
private _optionEditors?: PanelOptionEditorsRegistry;
|
|
||||||
private registerOptionEditors?: (builder: PanelOptionsEditorBuilder) => void;
|
|
||||||
|
|
||||||
panel: ComponentType<PanelProps<TOptions>>;
|
export class PanelPlugin<TOptions = any, TFieldConfigOptions extends object = any> extends GrafanaPlugin<
|
||||||
editor?: ComponentClass<PanelEditorProps<TOptions>>;
|
PanelPluginMeta
|
||||||
defaults?: TOptions;
|
> {
|
||||||
fieldConfigDefaults?: FieldConfigSource = {
|
private _defaults?: TOptions;
|
||||||
|
private _standardFieldConfigProperties?: Map<StandardFieldConfigProperties, any>;
|
||||||
|
|
||||||
|
private _fieldConfigDefaults: FieldConfigSource<TFieldConfigOptions> = {
|
||||||
defaults: {},
|
defaults: {},
|
||||||
overrides: [],
|
overrides: [],
|
||||||
};
|
};
|
||||||
|
private _customFieldConfigs?: FieldConfigEditorRegistry;
|
||||||
|
private customFieldConfigsUIBuilder = new FieldConfigEditorBuilder<TFieldConfigOptions>();
|
||||||
|
private registerCustomFieldConfigs?: (builder: FieldConfigEditorBuilder<TFieldConfigOptions>) => void;
|
||||||
|
|
||||||
|
private _optionEditors?: PanelOptionEditorsRegistry;
|
||||||
|
private optionsUIBuilder = new PanelOptionsEditorBuilder<TOptions>();
|
||||||
|
private registerOptionEditors?: (builder: PanelOptionsEditorBuilder<TOptions>) => void;
|
||||||
|
|
||||||
|
panel: ComponentType<PanelProps<TOptions>>;
|
||||||
|
editor?: ComponentClass<PanelEditorProps<TOptions>>;
|
||||||
onPanelMigration?: PanelMigrationHandler<TOptions>;
|
onPanelMigration?: PanelMigrationHandler<TOptions>;
|
||||||
onPanelTypeChanged?: PanelTypeChangedHandler<TOptions>;
|
onPanelTypeChanged?: PanelTypeChangedHandler<TOptions>;
|
||||||
noPadding?: boolean;
|
noPadding?: boolean;
|
||||||
@ -42,6 +64,66 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
|||||||
this.panel = panel;
|
this.panel = panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get defaults() {
|
||||||
|
let result = this._defaults || {};
|
||||||
|
|
||||||
|
if (!this._defaults) {
|
||||||
|
const editors = this.optionEditors;
|
||||||
|
|
||||||
|
if (!editors || editors.list().length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const editor of editors.list()) {
|
||||||
|
set(result, editor.id, editor.defaultValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
get fieldConfigDefaults(): FieldConfigSource<TFieldConfigOptions> {
|
||||||
|
let customPropertiesDefaults = this._fieldConfigDefaults.defaults.custom;
|
||||||
|
|
||||||
|
if (!customPropertiesDefaults) {
|
||||||
|
customPropertiesDefaults = {} as TFieldConfigOptions;
|
||||||
|
}
|
||||||
|
const editors = this.customFieldConfigs;
|
||||||
|
|
||||||
|
if (editors && editors.list().length !== 0) {
|
||||||
|
for (const editor of editors.list()) {
|
||||||
|
set(customPropertiesDefaults, editor.id, editor.defaultValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
defaults: {
|
||||||
|
...(this._standardFieldConfigProperties ? Object.fromEntries(this._standardFieldConfigProperties) : {}),
|
||||||
|
custom:
|
||||||
|
Object.keys(customPropertiesDefaults).length > 0
|
||||||
|
? {
|
||||||
|
...customPropertiesDefaults,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
...this._fieldConfigDefaults.defaults,
|
||||||
|
},
|
||||||
|
// TODO: not sure yet what about overrides, if anything
|
||||||
|
overrides: this._fieldConfigDefaults.overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get standardFieldConfigProperties() {
|
||||||
|
return this._standardFieldConfigProperties ? Array.from(this._standardFieldConfigProperties.keys()) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated setDefaults is deprecated in favor of setPanelOptions
|
||||||
|
*/
|
||||||
|
setDefaults(defaults: TOptions) {
|
||||||
|
deprecationWarning('PanelPlugin', 'setDefaults', 'setPanelOptions');
|
||||||
|
this._defaults = defaults;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
get customFieldConfigs() {
|
get customFieldConfigs() {
|
||||||
if (!this._customFieldConfigs && this.registerCustomFieldConfigs) {
|
if (!this._customFieldConfigs && this.registerCustomFieldConfigs) {
|
||||||
this.registerCustomFieldConfigs(this.customFieldConfigsUIBuilder);
|
this.registerCustomFieldConfigs(this.customFieldConfigsUIBuilder);
|
||||||
@ -65,11 +147,6 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setDefaults(defaults: TOptions) {
|
|
||||||
this.defaults = defaults;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
setNoPadding() {
|
setNoPadding() {
|
||||||
this.noPadding = true;
|
this.noPadding = true;
|
||||||
return this;
|
return this;
|
||||||
@ -134,7 +211,7 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
|||||||
*
|
*
|
||||||
* @public
|
* @public
|
||||||
**/
|
**/
|
||||||
setCustomFieldOptions(builder: (builder: FieldConfigEditorBuilder) => void) {
|
setCustomFieldOptions(builder: (builder: FieldConfigEditorBuilder<TFieldConfigOptions>) => void) {
|
||||||
// builder is applied lazily when custom field configs are accessed
|
// builder is applied lazily when custom field configs are accessed
|
||||||
this.registerCustomFieldConfigs = builder;
|
this.registerCustomFieldConfigs = builder;
|
||||||
return this;
|
return this;
|
||||||
@ -170,22 +247,63 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
|||||||
*
|
*
|
||||||
* @public
|
* @public
|
||||||
**/
|
**/
|
||||||
setPanelOptions(builder: (builder: PanelOptionsEditorBuilder) => void) {
|
setPanelOptions(builder: (builder: PanelOptionsEditorBuilder<TOptions>) => void) {
|
||||||
// builder is applied lazily when options UI is created
|
// builder is applied lazily when options UI is created
|
||||||
this.registerOptionEditors = builder;
|
this.registerOptionEditors = builder;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables configuration of panel's default field config
|
* Allows specyfing which standard field config options panel should use and defining default values
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
*
|
||||||
|
* import { ShapePanel } from './ShapePanel';
|
||||||
|
*
|
||||||
|
* interface ShapePanelOptions {}
|
||||||
|
*
|
||||||
|
* // when plugin should use all standard options
|
||||||
|
* export const plugin = new PanelPlugin<ShapePanelOptions>(ShapePanel)
|
||||||
|
* .useStandardFieldConfig();
|
||||||
|
*
|
||||||
|
* // when plugin should only display specific standard options
|
||||||
|
* // note, that options will be displayed in the order they are provided
|
||||||
|
* export const plugin = new PanelPlugin<ShapePanelOptions>(ShapePanel)
|
||||||
|
* .useStandardFieldConfig([StandardFieldConfigProperties.Min, StandardFieldConfigProperties.Max, StandardFieldConfigProperties.Links]);
|
||||||
|
*
|
||||||
|
* // when standard option's default value needs to be provided
|
||||||
|
* export const plugin = new PanelPlugin<ShapePanelOptions>(ShapePanel)
|
||||||
|
* .useStandardFieldConfig([StandardFieldConfigProperties.Min, StandardFieldConfigProperties.Max], {
|
||||||
|
* [StandardFieldConfigProperties.Min]: 20,
|
||||||
|
* [StandardFieldConfigProperties.Max]: 100
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @public
|
||||||
*/
|
*/
|
||||||
setFieldConfigDefaults(defaultConfig: Partial<FieldConfigSource>) {
|
useStandardFieldConfig(
|
||||||
this.fieldConfigDefaults = {
|
properties?: StandardFieldConfigProperties[],
|
||||||
defaults: {},
|
defauls?: Partial<Record<StandardFieldConfigProperties, any>>
|
||||||
overrides: [],
|
) {
|
||||||
...defaultConfig,
|
if (!properties) {
|
||||||
};
|
this._standardFieldConfigProperties = standardFieldConfigProperties;
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
this._standardFieldConfigProperties = new Map(properties.map(p => [p, standardFieldConfigProperties.get(p)]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defauls) {
|
||||||
|
Object.keys(defauls).map(k => {
|
||||||
|
if (properties.indexOf(k as StandardFieldConfigProperties) > -1) {
|
||||||
|
this._standardFieldConfigProperties!.set(
|
||||||
|
k as StandardFieldConfigProperties,
|
||||||
|
defauls[k as StandardFieldConfigProperties]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,52 +5,59 @@ import { NumberFieldConfigSettings, SelectFieldConfigSettings, StringFieldConfig
|
|||||||
/**
|
/**
|
||||||
* Option editor registry item
|
* Option editor registry item
|
||||||
*/
|
*/
|
||||||
export interface OptionsEditorItem<TSettings, TEditorProps> extends RegistryItem {
|
export interface OptionsEditorItem<TOptions, TSettings, TEditorProps, TValue> extends RegistryItem {
|
||||||
|
id: (keyof TOptions & string) | string;
|
||||||
editor: ComponentType<TEditorProps>;
|
editor: ComponentType<TEditorProps>;
|
||||||
settings?: TSettings;
|
settings?: TSettings;
|
||||||
|
defaultValue?: TValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration of option editor registry item
|
* Configuration of option editor registry item
|
||||||
*/
|
*/
|
||||||
interface OptionEditorConfig<TSettings> {
|
interface OptionEditorConfig<TOptions, TSettings, TValue = any> {
|
||||||
id: string;
|
id: keyof TOptions & string;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
settings?: TSettings;
|
settings?: TSettings;
|
||||||
|
defaultValue?: TValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes an API for option editors UI builder
|
* Describes an API for option editors UI builder
|
||||||
*/
|
*/
|
||||||
export interface OptionsUIRegistryBuilderAPI<TEditorProps, T extends OptionsEditorItem<any, TEditorProps>> {
|
export interface OptionsUIRegistryBuilderAPI<
|
||||||
|
TOptions,
|
||||||
|
TEditorProps,
|
||||||
|
T extends OptionsEditorItem<TOptions, any, TEditorProps, any>
|
||||||
|
> {
|
||||||
addNumberInput?<TSettings extends NumberFieldConfigSettings = NumberFieldConfigSettings>(
|
addNumberInput?<TSettings extends NumberFieldConfigSettings = NumberFieldConfigSettings>(
|
||||||
config: OptionEditorConfig<TSettings>
|
config: OptionEditorConfig<TOptions, TSettings, number>
|
||||||
): this;
|
): this;
|
||||||
|
|
||||||
addTextInput?<TSettings extends StringFieldConfigSettings = StringFieldConfigSettings>(
|
addTextInput?<TSettings extends StringFieldConfigSettings = StringFieldConfigSettings>(
|
||||||
config: OptionEditorConfig<TSettings>
|
config: OptionEditorConfig<TOptions, TSettings, string>
|
||||||
): this;
|
): this;
|
||||||
|
|
||||||
addSelect?<TOption, TSettings extends SelectFieldConfigSettings<TOption>>(
|
addSelect?<TOption, TSettings extends SelectFieldConfigSettings<TOption>>(
|
||||||
config: OptionEditorConfig<TSettings>
|
config: OptionEditorConfig<TOptions, TSettings, TOption>
|
||||||
): this;
|
): this;
|
||||||
|
|
||||||
addRadio?<TOption, TSettings extends SelectFieldConfigSettings<TOption> = SelectFieldConfigSettings<TOption>>(
|
addRadio?<TOption, TSettings extends SelectFieldConfigSettings<TOption> = SelectFieldConfigSettings<TOption>>(
|
||||||
config: OptionEditorConfig<TSettings>
|
config: OptionEditorConfig<TOptions, TSettings, TOption>
|
||||||
): this;
|
): this;
|
||||||
|
|
||||||
addBooleanSwitch?<TSettings = any>(config: OptionEditorConfig<TSettings>): this;
|
addBooleanSwitch?<TSettings = any>(config: OptionEditorConfig<TOptions, TSettings, boolean>): this;
|
||||||
|
|
||||||
addUnitPicker?<TSettings = any>(config: OptionEditorConfig<TSettings>): this;
|
addUnitPicker?<TSettings = any>(config: OptionEditorConfig<TOptions, TSettings, string>): this;
|
||||||
|
|
||||||
addColorPicker?<TSettings = any>(config: OptionEditorConfig<TSettings>): this;
|
addColorPicker?<TSettings = any>(config: OptionEditorConfig<TOptions, TSettings, string>): this;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables custom editor definition
|
* Enables custom editor definition
|
||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
addCustomEditor<TSettings>(config: OptionsEditorItem<TSettings, TEditorProps>): this;
|
addCustomEditor<TSettings, TValue>(config: OptionsEditorItem<TOptions, TSettings, TEditorProps, TValue>): this;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns registry of option editors
|
* Returns registry of option editors
|
||||||
@ -58,11 +65,14 @@ export interface OptionsUIRegistryBuilderAPI<TEditorProps, T extends OptionsEdit
|
|||||||
getRegistry: () => Registry<T>;
|
getRegistry: () => Registry<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class OptionsUIRegistryBuilder<TEditorProps, T extends OptionsEditorItem<any, TEditorProps>>
|
export abstract class OptionsUIRegistryBuilder<
|
||||||
implements OptionsUIRegistryBuilderAPI<TEditorProps, T> {
|
TOptions,
|
||||||
|
TEditorProps,
|
||||||
|
T extends OptionsEditorItem<TOptions, any, TEditorProps, any>
|
||||||
|
> implements OptionsUIRegistryBuilderAPI<TOptions, TEditorProps, T> {
|
||||||
private properties: T[] = [];
|
private properties: T[] = [];
|
||||||
|
|
||||||
addCustomEditor<TValue>(config: T & OptionsEditorItem<TValue, TEditorProps>): this {
|
addCustomEditor<TSettings, TValue>(config: T & OptionsEditorItem<TOptions, TSettings, TEditorProps, TValue>): this {
|
||||||
this.properties.push(config);
|
this.properties.push(config);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ export enum FieldType {
|
|||||||
*
|
*
|
||||||
* Plugins may extend this with additional properties. Something like series overrides
|
* Plugins may extend this with additional properties. Something like series overrides
|
||||||
*/
|
*/
|
||||||
export interface FieldConfig {
|
export interface FieldConfig<TOptions extends object = any> {
|
||||||
title?: string; // The display value for this field. This supports template variables blank is auto
|
title?: string; // The display value for this field. This supports template variables blank is auto
|
||||||
filterable?: boolean;
|
filterable?: boolean;
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ export interface FieldConfig {
|
|||||||
noValue?: string;
|
noValue?: string;
|
||||||
|
|
||||||
// Panel Specific Values
|
// Panel Specific Values
|
||||||
custom?: Record<string, any>;
|
custom?: TOptions;
|
||||||
|
|
||||||
scopedVars?: ScopedVars;
|
scopedVars?: ScopedVars;
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ export interface ConfigOverrideRule {
|
|||||||
properties: DynamicConfigValue[];
|
properties: DynamicConfigValue[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FieldConfigSource {
|
export interface FieldConfigSource<TOptions extends object = any> {
|
||||||
// Defatuls applied to all numeric fields
|
// Defatuls applied to all numeric fields
|
||||||
defaults: FieldConfig;
|
defaults: FieldConfig<TOptions>;
|
||||||
|
|
||||||
// Rules to override individual values
|
// Rules to override individual values
|
||||||
overrides: ConfigOverrideRule[];
|
overrides: ConfigOverrideRule[];
|
||||||
@ -54,16 +54,17 @@ export interface FieldOverrideEditorProps<TValue, TSettings> extends Omit<Standa
|
|||||||
context: FieldOverrideContext;
|
context: FieldOverrideContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FieldConfigEditorConfig<TSettings = any> {
|
export interface FieldConfigEditorConfig<TOptions, TSettings = any, TValue = any> {
|
||||||
id: string;
|
id: (keyof TOptions & string) | string;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
settings?: TSettings;
|
settings?: TSettings;
|
||||||
shouldApply?: (field: Field) => boolean;
|
shouldApply?: (field: Field) => boolean;
|
||||||
|
defaultValue?: TValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FieldPropertyEditorItem<TValue = any, TSettings extends {} = any>
|
export interface FieldPropertyEditorItem<TOptions = any, TValue = any, TSettings extends {} = any>
|
||||||
extends OptionsEditorItem<TSettings, FieldConfigEditorProps<TValue, TSettings>> {
|
extends OptionsEditorItem<TOptions, TSettings, FieldConfigEditorProps<TValue, TSettings>, TValue> {
|
||||||
// An editor that can be filled in with context info (template variables etc)
|
// An editor that can be filled in with context info (template variables etc)
|
||||||
override: ComponentType<FieldOverrideEditorProps<TValue, TSettings>>;
|
override: ComponentType<FieldOverrideEditorProps<TValue, TSettings>>;
|
||||||
|
|
||||||
@ -86,3 +87,16 @@ export interface ApplyFieldOverrideOptions {
|
|||||||
standard?: FieldConfigEditorRegistry;
|
standard?: FieldConfigEditorRegistry;
|
||||||
custom?: FieldConfigEditorRegistry;
|
custom?: FieldConfigEditorRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum StandardFieldConfigProperties {
|
||||||
|
Unit = 'unit',
|
||||||
|
Min = 'min',
|
||||||
|
Max = 'max',
|
||||||
|
Decimals = 'decimals',
|
||||||
|
Title = 'title',
|
||||||
|
NoValue = 'noValue',
|
||||||
|
Thresholds = 'thresholds',
|
||||||
|
Mappings = 'mappings',
|
||||||
|
Links = 'links',
|
||||||
|
Color = 'color',
|
||||||
|
}
|
||||||
|
@ -115,14 +115,15 @@ export type PanelOptionEditorsRegistry = Registry<PanelOptionsEditorItem>;
|
|||||||
|
|
||||||
export interface PanelOptionsEditorProps<TValue> extends StandardEditorProps<TValue> {}
|
export interface PanelOptionsEditorProps<TValue> extends StandardEditorProps<TValue> {}
|
||||||
|
|
||||||
export interface PanelOptionsEditorItem<TValue = any, TSettings = any>
|
export interface PanelOptionsEditorItem<TOptions = any, TValue = any, TSettings = any>
|
||||||
extends OptionsEditorItem<TSettings, PanelOptionsEditorProps<TValue>> {}
|
extends OptionsEditorItem<TOptions, TSettings, PanelOptionsEditorProps<TValue>, TValue> {}
|
||||||
|
|
||||||
export interface PanelOptionsEditorConfig<TSettings = any> {
|
export interface PanelOptionsEditorConfig<TOptions, TSettings = any, TValue = any> {
|
||||||
id: string;
|
id: (keyof TOptions & string) | string;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
settings?: TSettings;
|
settings?: TSettings;
|
||||||
|
defaultValue?: TValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PanelMenuItem {
|
export interface PanelMenuItem {
|
||||||
|
@ -26,11 +26,12 @@ import {
|
|||||||
/**
|
/**
|
||||||
* Fluent API for declarative creation of field config option editors
|
* Fluent API for declarative creation of field config option editors
|
||||||
*/
|
*/
|
||||||
export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder<
|
export class FieldConfigEditorBuilder<TOptions> extends OptionsUIRegistryBuilder<
|
||||||
|
TOptions,
|
||||||
FieldConfigEditorProps<any, any>,
|
FieldConfigEditorProps<any, any>,
|
||||||
FieldPropertyEditorItem
|
FieldPropertyEditorItem<TOptions>
|
||||||
> {
|
> {
|
||||||
addNumberInput<TSettings>(config: FieldConfigEditorConfig<TSettings & NumberFieldConfigSettings>) {
|
addNumberInput<TSettings>(config: FieldConfigEditorConfig<TOptions, TSettings & NumberFieldConfigSettings, number>) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
override: standardEditorsRegistry.get('number').editor as any,
|
override: standardEditorsRegistry.get('number').editor as any,
|
||||||
@ -41,7 +42,7 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addTextInput<TSettings>(config: FieldConfigEditorConfig<TSettings & StringFieldConfigSettings>) {
|
addTextInput<TSettings>(config: FieldConfigEditorConfig<TOptions, TSettings & StringFieldConfigSettings, string>) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
override: standardEditorsRegistry.get('text').editor as any,
|
override: standardEditorsRegistry.get('text').editor as any,
|
||||||
@ -52,7 +53,9 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addSelect<TOption, TSettings = any>(config: FieldConfigEditorConfig<TSettings & SelectFieldConfigSettings<TOption>>) {
|
addSelect<TOption, TSettings extends SelectFieldConfigSettings<TOption>>(
|
||||||
|
config: FieldConfigEditorConfig<TOptions, TSettings, TOption>
|
||||||
|
) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
override: standardEditorsRegistry.get('select').editor as any,
|
override: standardEditorsRegistry.get('select').editor as any,
|
||||||
@ -64,7 +67,7 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addRadio<TOption, TSettings = any>(config: FieldConfigEditorConfig<TSettings & SelectFieldConfigSettings<TOption>>) {
|
addRadio<TOption, TSettings = any>(config: FieldConfigEditorConfig<TOptions, TSettings, TOption>) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
override: standardEditorsRegistry.get('radio').editor as any,
|
override: standardEditorsRegistry.get('radio').editor as any,
|
||||||
@ -76,7 +79,7 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addBooleanSwitch<TSettings = any>(config: FieldConfigEditorConfig<TSettings>) {
|
addBooleanSwitch<TSettings = any>(config: FieldConfigEditorConfig<TOptions, TSettings, boolean>) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('boolean').editor as any,
|
editor: standardEditorsRegistry.get('boolean').editor as any,
|
||||||
@ -87,7 +90,9 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addColorPicker<TSettings = any>(config: FieldConfigEditorConfig<TSettings & ColorFieldConfigSettings>) {
|
addColorPicker<TSettings = any>(
|
||||||
|
config: FieldConfigEditorConfig<TOptions, TSettings & ColorFieldConfigSettings, string>
|
||||||
|
) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('color').editor as any,
|
editor: standardEditorsRegistry.get('color').editor as any,
|
||||||
@ -98,7 +103,9 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addUnitPicker<TSettings = any>(config: FieldConfigEditorConfig<TSettings & UnitFieldConfigSettings>) {
|
addUnitPicker<TSettings = any>(
|
||||||
|
config: FieldConfigEditorConfig<TOptions, TSettings & UnitFieldConfigSettings, string>
|
||||||
|
) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('unit').editor as any,
|
editor: standardEditorsRegistry.get('unit').editor as any,
|
||||||
@ -113,43 +120,53 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder<
|
|||||||
/**
|
/**
|
||||||
* Fluent API for declarative creation of panel options
|
* Fluent API for declarative creation of panel options
|
||||||
*/
|
*/
|
||||||
export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilder<StandardEditorProps, PanelOptionsEditorItem> {
|
export class PanelOptionsEditorBuilder<TOptions> extends OptionsUIRegistryBuilder<
|
||||||
addNumberInput<TSettings>(config: PanelOptionsEditorConfig<TSettings & NumberFieldConfigSettings>) {
|
TOptions,
|
||||||
|
StandardEditorProps,
|
||||||
|
PanelOptionsEditorItem<TOptions>
|
||||||
|
> {
|
||||||
|
addNumberInput<TSettings>(config: PanelOptionsEditorConfig<TOptions, TSettings & NumberFieldConfigSettings, number>) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('number').editor as any,
|
editor: standardEditorsRegistry.get('number').editor as any,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addTextInput<TSettings>(config: PanelOptionsEditorConfig<TSettings & StringFieldConfigSettings>) {
|
addTextInput<TSettings>(config: PanelOptionsEditorConfig<TOptions, TSettings & StringFieldConfigSettings, string>) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('text').editor as any,
|
editor: standardEditorsRegistry.get('text').editor as any,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addSelect<TOption, TSettings>(config: PanelOptionsEditorConfig<TSettings & SelectFieldConfigSettings<TOption>>) {
|
addSelect<TOption, TSettings extends SelectFieldConfigSettings<TOption>>(
|
||||||
|
config: PanelOptionsEditorConfig<TOptions, TSettings, TOption>
|
||||||
|
) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('select').editor as any,
|
editor: standardEditorsRegistry.get('select').editor as any,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addRadio<TOption, TSettings>(config: PanelOptionsEditorConfig<TSettings & SelectFieldConfigSettings<TOption>>) {
|
addRadio<TOption, TSettings extends SelectFieldConfigSettings<TOption>>(
|
||||||
|
config: PanelOptionsEditorConfig<TOptions, TSettings, TOption>
|
||||||
|
) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('radio').editor as any,
|
editor: standardEditorsRegistry.get('radio').editor as any,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addBooleanSwitch<TSettings = any>(config: PanelOptionsEditorConfig<TSettings>) {
|
addBooleanSwitch<TSettings = any>(config: PanelOptionsEditorConfig<TOptions, TSettings, boolean>) {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('boolean').editor as any,
|
editor: standardEditorsRegistry.get('boolean').editor as any,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addColorPicker<TSettings = any>(config: PanelOptionsEditorConfig<TSettings & ColorFieldConfigSettings>): this {
|
addColorPicker<TSettings = any>(
|
||||||
|
config: PanelOptionsEditorConfig<TOptions, TSettings & ColorFieldConfigSettings, string>
|
||||||
|
): this {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('color').editor as any,
|
editor: standardEditorsRegistry.get('color').editor as any,
|
||||||
@ -157,7 +174,9 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilder<Standard
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addUnitPicker<TSettings = any>(config: PanelOptionsEditorConfig<TSettings & UnitFieldConfigSettings>): this {
|
addUnitPicker<TSettings = any>(
|
||||||
|
config: PanelOptionsEditorConfig<TOptions, TSettings & UnitFieldConfigSettings, string>
|
||||||
|
): this {
|
||||||
return this.addCustomEditor({
|
return this.addCustomEditor({
|
||||||
...config,
|
...config,
|
||||||
editor: standardEditorsRegistry.get('unit').editor as any,
|
editor: standardEditorsRegistry.get('unit').editor as any,
|
||||||
|
@ -6,7 +6,7 @@ const history: KeyValue<number> = {};
|
|||||||
export const deprecationWarning = (file: string, oldName: string, newName?: string) => {
|
export const deprecationWarning = (file: string, oldName: string, newName?: string) => {
|
||||||
let message = `[Deprecation warning] ${file}: ${oldName} is deprecated`;
|
let message = `[Deprecation warning] ${file}: ${oldName} is deprecated`;
|
||||||
if (newName) {
|
if (newName) {
|
||||||
message += `. Use ${newName} instead`;
|
message += `. Use ${newName} instead`;
|
||||||
}
|
}
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const last = history[message];
|
const last = history[message];
|
||||||
|
@ -5,6 +5,13 @@ import Forms from '../Forms';
|
|||||||
export const StringValueEditor: React.FC<FieldConfigEditorProps<string, StringFieldConfigSettings>> = ({
|
export const StringValueEditor: React.FC<FieldConfigEditorProps<string, StringFieldConfigSettings>> = ({
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
|
item,
|
||||||
}) => {
|
}) => {
|
||||||
return <Forms.Input value={value || ''} onChange={e => onChange(e.currentTarget.value)} />;
|
return (
|
||||||
|
<Forms.Input
|
||||||
|
placeholder={item.settings?.placeholder}
|
||||||
|
value={value || ''}
|
||||||
|
onChange={e => onChange(e.currentTarget.value)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,7 @@ import { StatsPickerEditor } from '../components/OptionsUI/stats';
|
|||||||
* Returns collection of common field config properties definitions
|
* Returns collection of common field config properties definitions
|
||||||
*/
|
*/
|
||||||
export const getStandardFieldConfigs = () => {
|
export const getStandardFieldConfigs = () => {
|
||||||
const title: FieldPropertyEditorItem<string, StringFieldConfigSettings> = {
|
const title: FieldPropertyEditorItem<any, string, StringFieldConfigSettings> = {
|
||||||
id: 'title',
|
id: 'title',
|
||||||
name: 'Title',
|
name: 'Title',
|
||||||
description: "Field's title",
|
description: "Field's title",
|
||||||
@ -38,13 +38,13 @@ export const getStandardFieldConfigs = () => {
|
|||||||
override: standardEditorsRegistry.get('text').editor as any,
|
override: standardEditorsRegistry.get('text').editor as any,
|
||||||
process: stringOverrideProcessor,
|
process: stringOverrideProcessor,
|
||||||
settings: {
|
settings: {
|
||||||
placeholder: 'auto',
|
placeholder: 'none',
|
||||||
expandTemplateVars: true,
|
expandTemplateVars: true,
|
||||||
},
|
},
|
||||||
shouldApply: field => field.type !== FieldType.time,
|
shouldApply: field => field.type !== FieldType.time,
|
||||||
};
|
};
|
||||||
|
|
||||||
const unit: FieldPropertyEditorItem<string, StringFieldConfigSettings> = {
|
const unit: FieldPropertyEditorItem<any, string, StringFieldConfigSettings> = {
|
||||||
id: 'unit',
|
id: 'unit',
|
||||||
name: 'Unit',
|
name: 'Unit',
|
||||||
description: 'Value units',
|
description: 'Value units',
|
||||||
@ -60,7 +60,7 @@ export const getStandardFieldConfigs = () => {
|
|||||||
shouldApply: field => field.type === FieldType.number,
|
shouldApply: field => field.type === FieldType.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
const min: FieldPropertyEditorItem<number, NumberFieldConfigSettings> = {
|
const min: FieldPropertyEditorItem<any, number, NumberFieldConfigSettings> = {
|
||||||
id: 'min',
|
id: 'min',
|
||||||
name: 'Min',
|
name: 'Min',
|
||||||
description: 'Minimum expected value',
|
description: 'Minimum expected value',
|
||||||
@ -75,7 +75,7 @@ export const getStandardFieldConfigs = () => {
|
|||||||
shouldApply: field => field.type === FieldType.number,
|
shouldApply: field => field.type === FieldType.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
const max: FieldPropertyEditorItem<number, NumberFieldConfigSettings> = {
|
const max: FieldPropertyEditorItem<any, number, NumberFieldConfigSettings> = {
|
||||||
id: 'max',
|
id: 'max',
|
||||||
name: 'Max',
|
name: 'Max',
|
||||||
description: 'Maximum expected value',
|
description: 'Maximum expected value',
|
||||||
@ -91,7 +91,7 @@ export const getStandardFieldConfigs = () => {
|
|||||||
shouldApply: field => field.type === FieldType.number,
|
shouldApply: field => field.type === FieldType.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
const decimals: FieldPropertyEditorItem<number, NumberFieldConfigSettings> = {
|
const decimals: FieldPropertyEditorItem<any, number, NumberFieldConfigSettings> = {
|
||||||
id: 'decimals',
|
id: 'decimals',
|
||||||
name: 'Decimals',
|
name: 'Decimals',
|
||||||
description: 'Number of decimal to be shown for a value',
|
description: 'Number of decimal to be shown for a value',
|
||||||
@ -110,7 +110,7 @@ export const getStandardFieldConfigs = () => {
|
|||||||
shouldApply: field => field.type === FieldType.number,
|
shouldApply: field => field.type === FieldType.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
const thresholds: FieldPropertyEditorItem<ThresholdsConfig, ThresholdsFieldConfigSettings> = {
|
const thresholds: FieldPropertyEditorItem<any, ThresholdsConfig, ThresholdsFieldConfigSettings> = {
|
||||||
id: 'thresholds',
|
id: 'thresholds',
|
||||||
name: 'Thresholds',
|
name: 'Thresholds',
|
||||||
description: 'Manage thresholds',
|
description: 'Manage thresholds',
|
||||||
@ -126,7 +126,7 @@ export const getStandardFieldConfigs = () => {
|
|||||||
shouldApply: field => field.type === FieldType.number,
|
shouldApply: field => field.type === FieldType.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mappings: FieldPropertyEditorItem<ValueMapping[], ValueMappingFieldConfigSettings> = {
|
const mappings: FieldPropertyEditorItem<any, ValueMapping[], ValueMappingFieldConfigSettings> = {
|
||||||
id: 'mappings',
|
id: 'mappings',
|
||||||
name: 'Value mappings',
|
name: 'Value mappings',
|
||||||
description: 'Manage value mappings',
|
description: 'Manage value mappings',
|
||||||
@ -141,7 +141,7 @@ export const getStandardFieldConfigs = () => {
|
|||||||
shouldApply: field => field.type === FieldType.number,
|
shouldApply: field => field.type === FieldType.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
const noValue: FieldPropertyEditorItem<string, StringFieldConfigSettings> = {
|
const noValue: FieldPropertyEditorItem<any, string, StringFieldConfigSettings> = {
|
||||||
id: 'noValue',
|
id: 'noValue',
|
||||||
name: 'No Value',
|
name: 'No Value',
|
||||||
description: 'What to show when there is no value',
|
description: 'What to show when there is no value',
|
||||||
@ -157,7 +157,7 @@ export const getStandardFieldConfigs = () => {
|
|||||||
shouldApply: () => true,
|
shouldApply: () => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const links: FieldPropertyEditorItem<DataLink[], StringFieldConfigSettings> = {
|
const links: FieldPropertyEditorItem<any, DataLink[], StringFieldConfigSettings> = {
|
||||||
id: 'links',
|
id: 'links',
|
||||||
name: 'DataLinks',
|
name: 'DataLinks',
|
||||||
description: 'Manage date links',
|
description: 'Manage date links',
|
||||||
@ -170,7 +170,7 @@ export const getStandardFieldConfigs = () => {
|
|||||||
shouldApply: () => true,
|
shouldApply: () => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const color: FieldPropertyEditorItem<string, StringFieldConfigSettings> = {
|
const color: FieldPropertyEditorItem<any, string, StringFieldConfigSettings> = {
|
||||||
id: 'color',
|
id: 'color',
|
||||||
name: 'Color',
|
name: 'Color',
|
||||||
description: 'Customise color',
|
description: 'Customise color',
|
||||||
@ -217,7 +217,7 @@ export const getStandardOptionEditors = () => {
|
|||||||
description: 'Allows option selection',
|
description: 'Allows option selection',
|
||||||
editor: props => (
|
editor: props => (
|
||||||
<Forms.Select
|
<Forms.Select
|
||||||
defaultValue={props.value}
|
value={props.value}
|
||||||
onChange={e => props.onChange(e.value)}
|
onChange={e => props.onChange(e.value)}
|
||||||
options={props.item.settings?.options}
|
options={props.item.settings?.options}
|
||||||
/>
|
/>
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
standardFieldConfigEditorRegistry,
|
standardFieldConfigEditorRegistry,
|
||||||
PanelPlugin,
|
PanelPlugin,
|
||||||
SelectableValue,
|
SelectableValue,
|
||||||
|
StandardFieldConfigProperties,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { Forms, fieldMatchersUI, ValuePicker, useTheme } from '@grafana/ui';
|
import { Forms, fieldMatchersUI, ValuePicker, useTheme } from '@grafana/ui';
|
||||||
import { getDataLinksVariableSuggestions } from '../../../panel/panellinks/link_srv';
|
import { getDataLinksVariableSuggestions } from '../../../panel/panellinks/link_srv';
|
||||||
@ -17,7 +18,7 @@ import { css } from 'emotion';
|
|||||||
interface Props {
|
interface Props {
|
||||||
plugin: PanelPlugin;
|
plugin: PanelPlugin;
|
||||||
config: FieldConfigSource;
|
config: FieldConfigSource;
|
||||||
include?: string[]; // Ordered list of which fields should be shown/included
|
include?: StandardFieldConfigProperties[]; // Ordered list of which fields should be shown/included
|
||||||
onChange: (config: FieldConfigSource) => void;
|
onChange: (config: FieldConfigSource) => void;
|
||||||
/* Helpful for IntelliSense */
|
/* Helpful for IntelliSense */
|
||||||
data: DataFrame[];
|
data: DataFrame[];
|
||||||
@ -67,12 +68,15 @@ export const OverrideFieldConfigEditor: React.FC<Props> = props => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let configPropertiesOptions = standardFieldConfigEditorRegistry.list().map(i => ({
|
let configPropertiesOptions = plugin.standardFieldConfigProperties.map(i => {
|
||||||
label: i.name,
|
const editor = standardFieldConfigEditorRegistry.get(i);
|
||||||
value: i.id,
|
return {
|
||||||
description: i.description,
|
label: editor.name,
|
||||||
custom: false,
|
value: editor.id,
|
||||||
}));
|
description: editor.description,
|
||||||
|
custom: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
if (customFieldConfigs) {
|
if (customFieldConfigs) {
|
||||||
configPropertiesOptions = configPropertiesOptions.concat(
|
configPropertiesOptions = configPropertiesOptions.concat(
|
||||||
@ -185,6 +189,9 @@ export const DefaultFieldConfigEditor: React.FC<Props> = ({ include, data, onCha
|
|||||||
);
|
);
|
||||||
|
|
||||||
const renderStandardConfigs = useCallback(() => {
|
const renderStandardConfigs = useCallback(() => {
|
||||||
|
if (include && include.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (include) {
|
if (include) {
|
||||||
return <>{include.map(f => renderEditor(standardFieldConfigEditorRegistry.get(f), false))}</>;
|
return <>{include.map(f => renderEditor(standardFieldConfigEditorRegistry.get(f), false))}</>;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ export const OptionsPaneContent: React.FC<{
|
|||||||
plugin={plugin}
|
plugin={plugin}
|
||||||
onChange={onFieldConfigsChange}
|
onChange={onFieldConfigsChange}
|
||||||
data={data.series}
|
data={data.series}
|
||||||
|
include={plugin.standardFieldConfigProperties}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { PanelModel } from './PanelModel';
|
import { PanelModel } from './PanelModel';
|
||||||
import { getPanelPlugin } from '../../plugins/__mocks__/pluginMocks';
|
import { getPanelPlugin } from '../../plugins/__mocks__/pluginMocks';
|
||||||
import { ConfigOverrideRule, PanelProps } from '@grafana/data';
|
import { PanelProps, StandardFieldConfigProperties } from '@grafana/data';
|
||||||
import { ComponentClass } from 'react';
|
import { ComponentClass } from 'react';
|
||||||
|
|
||||||
class TablePanelCtrl {}
|
class TablePanelCtrl {}
|
||||||
@ -70,13 +70,6 @@ describe('PanelModel', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
model = new PanelModel(modelJson);
|
model = new PanelModel(modelJson);
|
||||||
const overrideMock: ConfigOverrideRule = {
|
|
||||||
matcher: {
|
|
||||||
id: '2',
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
properties: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
const panelPlugin = getPanelPlugin(
|
const panelPlugin = getPanelPlugin(
|
||||||
{
|
{
|
||||||
@ -86,12 +79,9 @@ describe('PanelModel', () => {
|
|||||||
TablePanelCtrl // angular
|
TablePanelCtrl // angular
|
||||||
);
|
);
|
||||||
panelPlugin.setDefaults(defaultOptionsMock);
|
panelPlugin.setDefaults(defaultOptionsMock);
|
||||||
panelPlugin.setFieldConfigDefaults({
|
panelPlugin.useStandardFieldConfig([StandardFieldConfigProperties.Unit, StandardFieldConfigProperties.Decimals], {
|
||||||
defaults: {
|
[StandardFieldConfigProperties.Unit]: 'flop',
|
||||||
unit: 'flop',
|
[StandardFieldConfigProperties.Decimals]: 2,
|
||||||
decimals: 2,
|
|
||||||
},
|
|
||||||
overrides: [overrideMock],
|
|
||||||
});
|
});
|
||||||
model.pluginLoaded(panelPlugin);
|
model.pluginLoaded(panelPlugin);
|
||||||
});
|
});
|
||||||
@ -108,10 +98,6 @@ describe('PanelModel', () => {
|
|||||||
expect(model.getOptions().arrayWith2Values.length).toBe(1);
|
expect(model.getOptions().arrayWith2Values.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should merge override field config options', () => {
|
|
||||||
expect(model.getFieldOverrideOptions().fieldOptions.overrides.length).toBe(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should apply field config defaults', () => {
|
it('should apply field config defaults', () => {
|
||||||
// default unit is overriden by model
|
// default unit is overriden by model
|
||||||
expect(model.getFieldOverrideOptions().fieldOptions.defaults.unit).toBe('mpg');
|
expect(model.getFieldOverrideOptions().fieldOptions.defaults.unit).toBe('mpg');
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import { sharedSingleStatPanelChangedHandler } from '@grafana/ui';
|
import { sharedSingleStatPanelChangedHandler } from '@grafana/ui';
|
||||||
import { PanelPlugin } from '@grafana/data';
|
import { defaultStandardFieldConfigProperties, PanelPlugin } from '@grafana/data';
|
||||||
import { BarGaugePanel } from './BarGaugePanel';
|
import { BarGaugePanel } from './BarGaugePanel';
|
||||||
import { BarGaugeOptions, defaults } from './types';
|
import { BarGaugeOptions, defaults } from './types';
|
||||||
import { standardFieldConfig, addStandardDataReduceOptions } from '../stat/types';
|
import { standardFieldConfigDefaults, addStandardDataReduceOptions } from '../stat/types';
|
||||||
import { BarGaugePanelEditor } from './BarGaugePanelEditor';
|
import { BarGaugePanelEditor } from './BarGaugePanelEditor';
|
||||||
import { barGaugePanelMigrationHandler } from './BarGaugeMigrations';
|
import { barGaugePanelMigrationHandler } from './BarGaugeMigrations';
|
||||||
|
|
||||||
export const plugin = new PanelPlugin<BarGaugeOptions>(BarGaugePanel)
|
export const plugin = new PanelPlugin<BarGaugeOptions>(BarGaugePanel)
|
||||||
.setDefaults(defaults)
|
.setDefaults(defaults)
|
||||||
.setEditor(BarGaugePanelEditor)
|
.setEditor(BarGaugePanelEditor)
|
||||||
.setFieldConfigDefaults(standardFieldConfig)
|
|
||||||
.setPanelOptions(builder => {
|
.setPanelOptions(builder => {
|
||||||
addStandardDataReduceOptions(builder);
|
addStandardDataReduceOptions(builder);
|
||||||
|
|
||||||
@ -33,4 +32,5 @@ export const plugin = new PanelPlugin<BarGaugeOptions>(BarGaugePanel)
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.setPanelChangeHandler(sharedSingleStatPanelChangedHandler)
|
.setPanelChangeHandler(sharedSingleStatPanelChangedHandler)
|
||||||
.setMigrationHandler(barGaugePanelMigrationHandler);
|
.setMigrationHandler(barGaugePanelMigrationHandler)
|
||||||
|
.useStandardFieldConfig(defaultStandardFieldConfigProperties, standardFieldConfigDefaults);
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import { PanelPlugin } from '@grafana/data';
|
import { defaultStandardFieldConfigProperties, PanelPlugin } from '@grafana/data';
|
||||||
import { GaugePanelEditor } from './GaugePanelEditor';
|
import { GaugePanelEditor } from './GaugePanelEditor';
|
||||||
import { GaugePanel } from './GaugePanel';
|
import { GaugePanel } from './GaugePanel';
|
||||||
import { GaugeOptions, defaults } from './types';
|
import { GaugeOptions, defaults } from './types';
|
||||||
import { standardFieldConfig, addStandardDataReduceOptions } from '../stat/types';
|
import { standardFieldConfigDefaults, addStandardDataReduceOptions } from '../stat/types';
|
||||||
import { gaugePanelMigrationHandler, gaugePanelChangedHandler } from './GaugeMigrations';
|
import { gaugePanelMigrationHandler, gaugePanelChangedHandler } from './GaugeMigrations';
|
||||||
|
|
||||||
export const plugin = new PanelPlugin<GaugeOptions>(GaugePanel)
|
export const plugin = new PanelPlugin<GaugeOptions>(GaugePanel)
|
||||||
.setDefaults(defaults)
|
.setDefaults(defaults)
|
||||||
.setFieldConfigDefaults(standardFieldConfig)
|
|
||||||
.setEditor(GaugePanelEditor)
|
.setEditor(GaugePanelEditor)
|
||||||
.setPanelOptions(builder => {
|
.setPanelOptions(builder => {
|
||||||
addStandardDataReduceOptions(builder);
|
addStandardDataReduceOptions(builder);
|
||||||
@ -25,4 +24,5 @@ export const plugin = new PanelPlugin<GaugeOptions>(GaugePanel)
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.setPanelChangeHandler(gaugePanelChangedHandler)
|
.setPanelChangeHandler(gaugePanelChangedHandler)
|
||||||
.setMigrationHandler(gaugePanelMigrationHandler);
|
.setMigrationHandler(gaugePanelMigrationHandler)
|
||||||
|
.useStandardFieldConfig(defaultStandardFieldConfigProperties, standardFieldConfigDefaults);
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { PanelPlugin } from '@grafana/data';
|
import { defaultStandardFieldConfigProperties, PanelPlugin, StandardFieldConfigProperties } from '@grafana/data';
|
||||||
import { PieChartPanelEditor } from './PieChartPanelEditor';
|
import { PieChartPanelEditor } from './PieChartPanelEditor';
|
||||||
import { PieChartPanel } from './PieChartPanel';
|
import { PieChartPanel } from './PieChartPanel';
|
||||||
import { PieChartOptions, defaults } from './types';
|
import { PieChartOptions, defaults } from './types';
|
||||||
|
|
||||||
export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel)
|
export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel)
|
||||||
.setDefaults(defaults)
|
.setDefaults(defaults)
|
||||||
.setFieldConfigDefaults({ defaults: { unit: 'short' } })
|
.useStandardFieldConfig(defaultStandardFieldConfigProperties, {
|
||||||
|
[StandardFieldConfigProperties.Unit]: 'short',
|
||||||
|
})
|
||||||
.setEditor(PieChartPanelEditor);
|
.setEditor(PieChartPanelEditor);
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { sharedSingleStatMigrationHandler, sharedSingleStatPanelChangedHandler } from '@grafana/ui';
|
import { sharedSingleStatMigrationHandler, sharedSingleStatPanelChangedHandler } from '@grafana/ui';
|
||||||
import { PanelPlugin } from '@grafana/data';
|
import { defaultStandardFieldConfigProperties, PanelPlugin } from '@grafana/data';
|
||||||
import { StatPanelOptions, defaults, standardFieldConfig, addStandardDataReduceOptions } from './types';
|
import { StatPanelOptions, defaults, standardFieldConfigDefaults, addStandardDataReduceOptions } from './types';
|
||||||
import { StatPanel } from './StatPanel';
|
import { StatPanel } from './StatPanel';
|
||||||
import { StatPanelEditor } from './StatPanelEditor';
|
import { StatPanelEditor } from './StatPanelEditor';
|
||||||
|
|
||||||
export const plugin = new PanelPlugin<StatPanelOptions>(StatPanel)
|
export const plugin = new PanelPlugin<StatPanelOptions>(StatPanel)
|
||||||
.setDefaults(defaults)
|
.setDefaults(defaults)
|
||||||
.setFieldConfigDefaults(standardFieldConfig)
|
|
||||||
.setEditor(StatPanelEditor)
|
.setEditor(StatPanelEditor)
|
||||||
.setPanelOptions(builder => {
|
.setPanelOptions(builder => {
|
||||||
addStandardDataReduceOptions(builder);
|
addStandardDataReduceOptions(builder);
|
||||||
@ -48,4 +47,5 @@ export const plugin = new PanelPlugin<StatPanelOptions>(StatPanel)
|
|||||||
})
|
})
|
||||||
.setNoPadding()
|
.setNoPadding()
|
||||||
.setPanelChangeHandler(sharedSingleStatPanelChangedHandler)
|
.setPanelChangeHandler(sharedSingleStatPanelChangedHandler)
|
||||||
.setMigrationHandler(sharedSingleStatMigrationHandler);
|
.setMigrationHandler(sharedSingleStatMigrationHandler)
|
||||||
|
.useStandardFieldConfig(defaultStandardFieldConfigProperties, standardFieldConfigDefaults);
|
||||||
|
@ -4,9 +4,9 @@ import {
|
|||||||
ReducerID,
|
ReducerID,
|
||||||
ReduceDataOptions,
|
ReduceDataOptions,
|
||||||
SelectableValue,
|
SelectableValue,
|
||||||
FieldConfigSource,
|
|
||||||
ThresholdsMode,
|
ThresholdsMode,
|
||||||
standardEditorsRegistry,
|
standardEditorsRegistry,
|
||||||
|
StandardFieldConfigProperties,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { PanelOptionsEditorBuilder } from '@grafana/data/src/utils/OptionsUIBuilders';
|
import { PanelOptionsEditorBuilder } from '@grafana/data/src/utils/OptionsUIBuilders';
|
||||||
|
|
||||||
@ -37,21 +37,18 @@ export const commonValueOptionDefaults: ReduceDataOptions = {
|
|||||||
calcs: [ReducerID.mean],
|
calcs: [ReducerID.mean],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const standardFieldConfig: FieldConfigSource = {
|
export const standardFieldConfigDefaults: Partial<Record<StandardFieldConfigProperties, any>> = {
|
||||||
defaults: {
|
[StandardFieldConfigProperties.Thresholds]: {
|
||||||
thresholds: {
|
mode: ThresholdsMode.Absolute,
|
||||||
mode: ThresholdsMode.Absolute,
|
steps: [
|
||||||
steps: [
|
{ value: -Infinity, color: 'green' },
|
||||||
{ value: -Infinity, color: 'green' },
|
{ value: 80, color: 'red' }, // 80%
|
||||||
{ value: 80, color: 'red' }, // 80%
|
],
|
||||||
],
|
|
||||||
},
|
|
||||||
mappings: [],
|
|
||||||
},
|
},
|
||||||
overrides: [],
|
[StandardFieldConfigProperties.Mappings]: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export function addStandardDataReduceOptions(builder: PanelOptionsEditorBuilder) {
|
export function addStandardDataReduceOptions(builder: PanelOptionsEditorBuilder<StatPanelOptions>) {
|
||||||
builder.addRadio({
|
builder.addRadio({
|
||||||
id: 'reduceOptions.values',
|
id: 'reduceOptions.values',
|
||||||
name: 'Show',
|
name: 'Show',
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { PanelPlugin } from '@grafana/data';
|
import { PanelPlugin } from '@grafana/data';
|
||||||
import { TablePanel } from './TablePanel';
|
import { TablePanel } from './TablePanel';
|
||||||
import { Options, defaults } from './types';
|
import { CustomFieldConfig, defaults, Options } from './types';
|
||||||
|
|
||||||
export const plugin = new PanelPlugin<Options>(TablePanel)
|
export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
|
||||||
.setDefaults(defaults)
|
.setDefaults(defaults)
|
||||||
.setCustomFieldOptions(builder => {
|
.setCustomFieldOptions(builder => {
|
||||||
builder
|
builder
|
||||||
@ -15,6 +15,7 @@ export const plugin = new PanelPlugin<Options>(TablePanel)
|
|||||||
min: 20,
|
min: 20,
|
||||||
max: 300,
|
max: 300,
|
||||||
},
|
},
|
||||||
|
defaultValue: 1,
|
||||||
})
|
})
|
||||||
.addSelect({
|
.addSelect({
|
||||||
id: 'displayMode',
|
id: 'displayMode',
|
||||||
|
@ -2,6 +2,11 @@ export interface Options {
|
|||||||
showHeader: boolean;
|
showHeader: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CustomFieldConfig {
|
||||||
|
width: number;
|
||||||
|
displayMode: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const defaults: Options = {
|
export const defaults: Options = {
|
||||||
showHeader: true,
|
showHeader: true,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user