3
0
mirror of https://github.com/grafana/grafana.git synced 2025-02-25 18:55:37 -06:00

New Editor: Add ValuePicker for overrides selection ()

This commit is contained in:
Dominik Prokop 2020-02-09 18:47:48 +01:00 committed by GitHub
parent bedc708dfa
commit 58639ee53e
5 changed files with 106 additions and 35 deletions
packages/grafana-ui/src/components

View File

@ -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>
);

View File

@ -16,7 +16,7 @@ export default {
decorators: [withCenteredStory, withHorizontallyCenteredStory],
};
const generateOptions = () => {
export const generateOptions = () => {
const values = [
'Sharilyn Markowitz',
'Naomi Striplin',

View File

@ -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>
);
};

View File

@ -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);
}}
/>
)}
</>
);
}

View File

@ -134,3 +134,4 @@ export {
// Next-gen forms
export { default as Forms } from './Forms';
export { ValuePicker } from './ValuePicker/ValuePicker';