mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
New Editor: Add ValuePicker for overrides selection (#22048)
This commit is contained in:
parent
bedc708dfa
commit
58639ee53e
packages/grafana-ui/src/components
@ -11,6 +11,7 @@ import { standardFieldConfigEditorRegistry } from './standardFieldConfigEditorRe
|
||||
import Forms from '../Forms';
|
||||
import { fieldMatchersUI } from '../MatchersUI/fieldMatchersUI';
|
||||
import { ControlledCollapse } from '../Collapse/Collapse';
|
||||
import { ValuePicker } from '../ValuePicker/ValuePicker';
|
||||
|
||||
interface Props {
|
||||
config: FieldConfigSource;
|
||||
@ -116,6 +117,9 @@ export class FieldConfigEditor extends React.PureComponent<Props> {
|
||||
|
||||
renderOverrides() {
|
||||
const { config, data, custom } = this.props;
|
||||
if (config.overrides.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let configPropertiesOptions = standardFieldConfigEditorRegistry.list().map(i => ({
|
||||
label: i.name,
|
||||
@ -136,11 +140,11 @@ export class FieldConfigEditor extends React.PureComponent<Props> {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{config.overrides.map((o, i) => {
|
||||
const matcherUi = fieldMatchersUI.get(o.matcher.id);
|
||||
return (
|
||||
<div key={`${o.matcher.id}/${i}`}>
|
||||
<div key={`${o.matcher.id}/${i}`} style={{ border: `2px solid red`, marginBottom: '10px' }}>
|
||||
<Forms.Field label={matcherUi.name} description={matcherUi.description}>
|
||||
<>
|
||||
<matcherUi.component
|
||||
@ -149,49 +153,50 @@ export class FieldConfigEditor extends React.PureComponent<Props> {
|
||||
options={o.matcher.options}
|
||||
onChange={option => this.onMatcherConfigChange(i, option)}
|
||||
/>
|
||||
<Forms.ButtonSelect
|
||||
icon="plus"
|
||||
placeholder="Set config property"
|
||||
options={configPropertiesOptions}
|
||||
onChange={o => {
|
||||
this.onDynamicConfigValueAdd(i, o.value!, o.custom);
|
||||
}}
|
||||
/>
|
||||
|
||||
{o.properties.map((p, j) => {
|
||||
const reg = p.custom ? custom : standardFieldConfigEditorRegistry;
|
||||
const item = reg?.get(p.prop);
|
||||
if (!item) {
|
||||
return <div>Unknown property: {p.prop}</div>;
|
||||
}
|
||||
return (
|
||||
<Forms.Field label={item.name} description={item.description}>
|
||||
<item.override
|
||||
value={p.value}
|
||||
onChange={value => {
|
||||
this.onDynamicConfigValueChange(i, j, value);
|
||||
}}
|
||||
item={item}
|
||||
context={{} as any}
|
||||
/>
|
||||
</Forms.Field>
|
||||
);
|
||||
})}
|
||||
<div style={{ border: `2px solid blue`, marginBottom: '5px' }}>
|
||||
{o.properties.map((p, j) => {
|
||||
const reg = p.custom ? custom : standardFieldConfigEditorRegistry;
|
||||
const item = reg?.getIfExists(p.prop);
|
||||
if (!item) {
|
||||
return <div>Unknown property: {p.prop}</div>;
|
||||
}
|
||||
return (
|
||||
<Forms.Field label={item.name} description={item.description}>
|
||||
<item.override
|
||||
value={p.value}
|
||||
onChange={value => {
|
||||
this.onDynamicConfigValueChange(i, j, value);
|
||||
}}
|
||||
item={item}
|
||||
context={{} as any}
|
||||
/>
|
||||
</Forms.Field>
|
||||
);
|
||||
})}
|
||||
<ValuePicker
|
||||
icon="plus"
|
||||
label="Set config property"
|
||||
options={configPropertiesOptions}
|
||||
onChange={o => {
|
||||
this.onDynamicConfigValueAdd(i, o.value!, o.custom);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
</Forms.Field>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderAddOverride = () => {
|
||||
return (
|
||||
<Forms.ButtonSelect
|
||||
<ValuePicker
|
||||
icon="plus"
|
||||
placeholder={'Add override'}
|
||||
value={{ label: 'Add override' }}
|
||||
label="Add override"
|
||||
options={fieldMatchersUI.list().map(i => ({ label: i.name, value: i.id, description: i.description }))}
|
||||
onChange={value => {
|
||||
const { onChange, config } = this.props;
|
||||
@ -223,8 +228,8 @@ export class FieldConfigEditor extends React.PureComponent<Props> {
|
||||
)}
|
||||
|
||||
<ControlledCollapse label="Field Overrides" collapsible>
|
||||
{this.renderAddOverride()}
|
||||
{this.renderOverrides()}
|
||||
{this.renderAddOverride()}
|
||||
</ControlledCollapse>
|
||||
</div>
|
||||
);
|
||||
|
@ -16,7 +16,7 @@ export default {
|
||||
decorators: [withCenteredStory, withHorizontallyCenteredStory],
|
||||
};
|
||||
|
||||
const generateOptions = () => {
|
||||
export const generateOptions = () => {
|
||||
const values = [
|
||||
'Sharilyn Markowitz',
|
||||
'Naomi Striplin',
|
||||
|
@ -0,0 +1,22 @@
|
||||
import { text } from '@storybook/addon-knobs';
|
||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
import { ValuePicker } from './ValuePicker';
|
||||
import React from 'react';
|
||||
import { generateOptions } from '../Forms/Select/Select.story';
|
||||
|
||||
export default {
|
||||
title: 'General/ValuePicker',
|
||||
component: ValuePicker,
|
||||
decorators: [withCenteredStory],
|
||||
};
|
||||
|
||||
const options = generateOptions();
|
||||
|
||||
export const simple = () => {
|
||||
const label = text('Label', 'Pick an option');
|
||||
return (
|
||||
<div style={{ width: '200px' }}>
|
||||
<ValuePicker options={options} label={label} onChange={v => console.log(v)} />
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,43 @@
|
||||
import React, { useState } from 'react';
|
||||
import { IconType } from '../Icon/types';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Button } from '../Forms/Button';
|
||||
import { Select } from '../Forms/Select/Select';
|
||||
|
||||
interface ValuePickerProps<T> {
|
||||
/** Label to display on the picker button */
|
||||
label: string;
|
||||
/** Icon to display on the picker button */
|
||||
icon?: IconType;
|
||||
/** ValuePicker options */
|
||||
options: Array<SelectableValue<T>>;
|
||||
onChange: (value: SelectableValue<T>) => void;
|
||||
}
|
||||
|
||||
export function ValuePicker<T>({ label, icon, options, onChange }: ValuePickerProps<T>) {
|
||||
const [isPicking, setIsPicking] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isPicking && (
|
||||
<Button icon={`fa fa-${icon || 'plus'}`} onClick={() => setIsPicking(true)}>
|
||||
{label}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{isPicking && (
|
||||
<Select
|
||||
placeholder={label}
|
||||
options={options}
|
||||
isOpen
|
||||
onCloseMenu={() => setIsPicking(false)}
|
||||
autoFocus={true}
|
||||
onChange={value => {
|
||||
setIsPicking(false);
|
||||
onChange(value);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
@ -134,3 +134,4 @@ export {
|
||||
|
||||
// Next-gen forms
|
||||
export { default as Forms } from './Forms';
|
||||
export { ValuePicker } from './ValuePicker/ValuePicker';
|
||||
|
Loading…
Reference in New Issue
Block a user