Commit 19e82400 by Dominik Prokop Committed by GitHub

Refactor: Make SelectOptionItem a generic type to enable select value typing (#16718)

* Make SelectOptionItem a generic type to enable select value typing
* TS ignores added because of optional value on Select items (it's no longer any)
parent f4a8240d
...@@ -33,15 +33,16 @@ export class RefreshPicker extends PureComponent<Props> { ...@@ -33,15 +33,16 @@ export class RefreshPicker extends PureComponent<Props> {
return false; return false;
}; };
intervalsToOptions = (intervals: string[] = defaultIntervals): SelectOptionItem[] => { intervalsToOptions = (intervals: string[] = defaultIntervals): Array<SelectOptionItem<string>> => {
const options = intervals.map(interval => ({ label: interval, value: interval })); const options = intervals.map(interval => ({ label: interval, value: interval }));
options.unshift(offOption); options.unshift(offOption);
return options; return options;
}; };
onChangeSelect = (item: SelectOptionItem) => { onChangeSelect = (item: SelectOptionItem<string>) => {
const { onIntervalChanged } = this.props; const { onIntervalChanged } = this.props;
if (onIntervalChanged) { if (onIntervalChanged) {
// @ts-ignore
onIntervalChanged(item.value); onIntervalChanged(item.value);
} }
}; };
......
...@@ -12,9 +12,9 @@ const ButtonSelectStories = storiesOf('UI/Select/ButtonSelect', module); ...@@ -12,9 +12,9 @@ const ButtonSelectStories = storiesOf('UI/Select/ButtonSelect', module);
ButtonSelectStories.addDecorator(withCenteredStory).addDecorator(withKnobs); ButtonSelectStories.addDecorator(withCenteredStory).addDecorator(withKnobs);
ButtonSelectStories.add('default', () => { ButtonSelectStories.add('default', () => {
const intialState: SelectOptionItem = { label: 'A label', value: 'A value' }; const intialState: SelectOptionItem<string> = { label: 'A label', value: 'A value' };
const value = object<SelectOptionItem>('Selected Value:', intialState); const value = object<SelectOptionItem<string>>('Selected Value:', intialState);
const options = object<SelectOptionItem[]>('Options:', [ const options = object<Array<SelectOptionItem<string>>>('Options:', [
intialState, intialState,
{ label: 'Another label', value: 'Another value' }, { label: 'Another label', value: 'Another value' },
]); ]);
......
...@@ -27,23 +27,23 @@ const ButtonComponent = (buttonProps: ButtonComponentProps) => (props: any) => { ...@@ -27,23 +27,23 @@ const ButtonComponent = (buttonProps: ButtonComponentProps) => (props: any) => {
); );
}; };
export interface Props { export interface Props<T> {
className: string | undefined; className: string | undefined;
options: SelectOptionItem[]; options: Array<SelectOptionItem<T>>;
value: SelectOptionItem; value: SelectOptionItem<T>;
label?: string; label?: string;
iconClass?: string; iconClass?: string;
components?: any; components?: any;
maxMenuHeight?: number; maxMenuHeight?: number;
onChange: (item: SelectOptionItem) => void; onChange: (item: SelectOptionItem<T>) => void;
tooltipContent?: PopperContent<any>; tooltipContent?: PopperContent<any>;
isMenuOpen?: boolean; isMenuOpen?: boolean;
onOpenMenu?: () => void; onOpenMenu?: () => void;
onCloseMenu?: () => void; onCloseMenu?: () => void;
} }
export class ButtonSelect extends PureComponent<Props> { export class ButtonSelect<T> extends PureComponent<Props<T>> {
onChange = (item: SelectOptionItem) => { onChange = (item: SelectOptionItem<T>) => {
const { onChange } = this.props; const { onChange } = this.props;
onChange(item); onChange(item);
}; };
......
...@@ -20,22 +20,22 @@ import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; ...@@ -20,22 +20,22 @@ import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar';
import { PopperContent } from '@grafana/ui/src/components/Tooltip/PopperController'; import { PopperContent } from '@grafana/ui/src/components/Tooltip/PopperController';
import { Tooltip } from '@grafana/ui'; import { Tooltip } from '@grafana/ui';
export interface SelectOptionItem { export interface SelectOptionItem<T> {
label?: string; label?: string;
value?: any; value?: T;
imgUrl?: string; imgUrl?: string;
description?: string; description?: string;
[key: string]: any; [key: string]: any;
} }
export interface CommonProps { export interface CommonProps<T> {
defaultValue?: any; defaultValue?: any;
getOptionLabel?: (item: SelectOptionItem) => string; getOptionLabel?: (item: SelectOptionItem<T>) => string;
getOptionValue?: (item: SelectOptionItem) => string; getOptionValue?: (item: SelectOptionItem<T>) => string;
onChange: (item: SelectOptionItem) => {} | void; onChange: (item: SelectOptionItem<T>) => {} | void;
placeholder?: string; placeholder?: string;
width?: number; width?: number;
value?: SelectOptionItem; value?: SelectOptionItem<T>;
className?: string; className?: string;
isDisabled?: boolean; isDisabled?: boolean;
isSearchable?: boolean; isSearchable?: boolean;
...@@ -55,13 +55,13 @@ export interface CommonProps { ...@@ -55,13 +55,13 @@ export interface CommonProps {
onCloseMenu?: () => void; onCloseMenu?: () => void;
} }
export interface SelectProps { export interface SelectProps<T> {
options: SelectOptionItem[]; options: Array<SelectOptionItem<T>>;
} }
interface AsyncProps { interface AsyncProps<T> {
defaultOptions: boolean; defaultOptions: boolean;
loadOptions: (query: string) => Promise<SelectOptionItem[]>; loadOptions: (query: string) => Promise<Array<SelectOptionItem<T>>>;
loadingMessage?: () => string; loadingMessage?: () => string;
} }
...@@ -95,7 +95,7 @@ export const MenuList = (props: any) => { ...@@ -95,7 +95,7 @@ export const MenuList = (props: any) => {
); );
}; };
export class Select extends PureComponent<CommonProps & SelectProps> { export class Select<T> extends PureComponent<CommonProps<T> & SelectProps<T>> {
static defaultProps = { static defaultProps = {
width: null, width: null,
className: '', className: '',
...@@ -201,7 +201,7 @@ export class Select extends PureComponent<CommonProps & SelectProps> { ...@@ -201,7 +201,7 @@ export class Select extends PureComponent<CommonProps & SelectProps> {
} }
} }
export class AsyncSelect extends PureComponent<CommonProps & AsyncProps> { export class AsyncSelect<T> extends PureComponent<CommonProps<T> & AsyncProps<T>> {
static defaultProps = { static defaultProps = {
width: null, width: null,
className: '', className: '',
......
...@@ -18,39 +18,40 @@ import { SingleStatValueOptions } from './shared'; ...@@ -18,39 +18,40 @@ import { SingleStatValueOptions } from './shared';
const labelWidth = 6; const labelWidth = 6;
export interface Props { export interface Props {
options: SingleStatValueOptions; value: SingleStatValueOptions;
onChange: (valueOptions: SingleStatValueOptions) => void; onChange: (valueOptions: SingleStatValueOptions) => void;
} }
export class SingleStatValueEditor extends PureComponent<Props> { export class SingleStatValueEditor extends PureComponent<Props> {
onUnitChange = (unit: SelectOptionItem) => this.props.onChange({ ...this.props.options, unit: unit.value }); // @ts-ignore
onUnitChange = (unit: SelectOptionItem<string>) => this.props.onChange({ ...this.props.value, unit: unit.value });
onStatsChange = (stats: string[]) => { onStatsChange = (stats: string[]) => {
const stat = stats[0] || StatID.mean; const stat = stats[0] || StatID.mean;
this.props.onChange({ ...this.props.options, stat }); this.props.onChange({ ...this.props.value, stat });
}; };
onDecimalChange = (event: ChangeEvent<HTMLInputElement>) => { onDecimalChange = (event: ChangeEvent<HTMLInputElement>) => {
if (!isNaN(parseInt(event.target.value, 10))) { if (!isNaN(parseInt(event.target.value, 10))) {
this.props.onChange({ this.props.onChange({
...this.props.options, ...this.props.value,
decimals: parseInt(event.target.value, 10), decimals: parseInt(event.target.value, 10),
}); });
} else { } else {
this.props.onChange({ this.props.onChange({
...this.props.options, ...this.props.value,
decimals: null, decimals: null,
}); });
} }
}; };
onPrefixChange = (event: ChangeEvent<HTMLInputElement>) => onPrefixChange = (event: ChangeEvent<HTMLInputElement>) =>
this.props.onChange({ ...this.props.options, prefix: event.target.value }); this.props.onChange({ ...this.props.value, prefix: event.target.value });
onSuffixChange = (event: ChangeEvent<HTMLInputElement>) => onSuffixChange = (event: ChangeEvent<HTMLInputElement>) =>
this.props.onChange({ ...this.props.options, suffix: event.target.value }); this.props.onChange({ ...this.props.value, suffix: event.target.value });
render() { render() {
const { stat, unit, decimals, prefix, suffix } = this.props.options; const { stat, unit, decimals, prefix, suffix } = this.props.value;
let decimalsString = ''; let decimalsString = '';
if (decimals !== null && decimals !== undefined && Number.isFinite(decimals as number)) { if (decimals !== null && decimals !== undefined && Number.isFinite(decimals as number)) {
......
...@@ -54,12 +54,12 @@ export class StatsPicker extends PureComponent<Props> { ...@@ -54,12 +54,12 @@ export class StatsPicker extends PureComponent<Props> {
} }
}; };
onSelectionChange = (item: SelectOptionItem) => { onSelectionChange = (item: SelectOptionItem<string>) => {
const { onChange } = this.props; const { onChange } = this.props;
if (isArray(item)) { if (isArray(item)) {
onChange(item.map(v => v.value)); onChange(item.map(v => v.value));
} else { } else {
onChange([item.value]); onChange(item.value ? [item.value] : []);
} }
}; };
...@@ -73,7 +73,7 @@ export class StatsPicker extends PureComponent<Props> { ...@@ -73,7 +73,7 @@ export class StatsPicker extends PureComponent<Props> {
}; };
}); });
const value: SelectOptionItem[] = options.filter(option => stats.find(stat => option.value === stat)); const value: Array<SelectOptionItem<string>> = options.filter(option => stats.find(stat => option.value === stat));
return ( return (
<Select <Select
......
...@@ -231,8 +231,10 @@ export class TimePicker extends PureComponent<Props, State> { ...@@ -231,8 +231,10 @@ export class TimePicker extends PureComponent<Props, State> {
]; ];
}; };
onSelectChanged = (item: SelectOptionItem) => { onSelectChanged = (item: SelectOptionItem<TimeOption>) => {
const { isTimezoneUtc, onChange, timezone } = this.props; const { isTimezoneUtc, onChange, timezone } = this.props;
// @ts-ignore
onChange(mapTimeOptionToTimeRange(item.value, isTimezoneUtc, timezone)); onChange(mapTimeOptionToTimeRange(item.value, isTimezoneUtc, timezone));
}; };
...@@ -264,6 +266,7 @@ export class TimePicker extends PureComponent<Props, State> { ...@@ -264,6 +266,7 @@ export class TimePicker extends PureComponent<Props, State> {
const options = this.mapTimeOptionsToSelectOptionItems(selectTimeOptions); const options = this.mapTimeOptionsToSelectOptionItems(selectTimeOptions);
const rangeString = mapTimeRangeToRangeString(value); const rangeString = mapTimeRangeToRangeString(value);
const isAbsolute = moment.isMoment(value.raw.to); const isAbsolute = moment.isMoment(value.raw.to);
return ( return (
<div className="time-picker"> <div className="time-picker">
<div className="time-picker-buttons"> <div className="time-picker-buttons">
......
...@@ -126,6 +126,7 @@ export default class MappingRow extends PureComponent<Props, State> { ...@@ -126,6 +126,7 @@ export default class MappingRow extends PureComponent<Props, State> {
isSearchable={false} isSearchable={false}
options={mappingOptions} options={mappingOptions}
value={mappingOptions.find(o => o.value === type)} value={mappingOptions.find(o => o.value === type)}
// @ts-ignore
onChange={type => this.onMappingTypeChange(type.value)} onChange={type => this.onMappingTypeChange(type.value)}
width={7} width={7}
/> />
......
...@@ -43,7 +43,7 @@ export function stringToMs(str: string): number { ...@@ -43,7 +43,7 @@ export function stringToMs(str: string): number {
} }
} }
export function getIntervalFromString(strInterval: string): SelectOptionItem { export function getIntervalFromString(strInterval: string): SelectOptionItem<number> {
return { return {
label: strInterval, label: strInterval,
value: stringToMs(strInterval), value: stringToMs(strInterval),
......
...@@ -61,7 +61,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> { ...@@ -61,7 +61,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
this.setState({ teamId: team && !Array.isArray(team) ? team.id : 0 }); this.setState({ teamId: team && !Array.isArray(team) ? team.id : 0 });
}; };
onPermissionChanged = (permission: SelectOptionItem) => { onPermissionChanged = (permission: SelectOptionItem<PermissionLevel>) => {
this.setState({ permission: permission.value }); this.setState({ permission: permission.value });
}; };
......
...@@ -28,7 +28,7 @@ export class DataSourcePicker extends PureComponent<Props> { ...@@ -28,7 +28,7 @@ export class DataSourcePicker extends PureComponent<Props> {
super(props); super(props);
} }
onChange = (item: SelectOptionItem) => { onChange = (item: SelectOptionItem<string>) => {
const ds = this.props.datasources.find(ds => ds.name === item.value); const ds = this.props.datasources.find(ds => ds.name === item.value);
this.props.onChange(ds); this.props.onChange(ds);
}; };
......
...@@ -6,7 +6,7 @@ import { Variable } from 'app/types/templates'; ...@@ -6,7 +6,7 @@ import { Variable } from 'app/types/templates';
export interface Props { export interface Props {
onChange: (value: string) => void; onChange: (value: string) => void;
options: SelectOptionItem[]; options: Array<SelectOptionItem<string>>;
isSearchable: boolean; isSearchable: boolean;
value: string; value: string;
placeholder?: string; placeholder?: string;
...@@ -15,7 +15,7 @@ export interface Props { ...@@ -15,7 +15,7 @@ export interface Props {
} }
interface State { interface State {
options: any[]; options: Array<SelectOptionItem<string>>;
} }
export class MetricSelect extends React.Component<Props, State> { export class MetricSelect extends React.Component<Props, State> {
......
...@@ -80,7 +80,7 @@ describe('Functions', () => { ...@@ -80,7 +80,7 @@ describe('Functions', () => {
}; };
const { instance } = setup({ member }); const { instance } = setup({ member });
const permission = TeamPermissionLevel.Admin; const permission = TeamPermissionLevel.Admin;
const item: SelectOptionItem = { value: permission }; const item: SelectOptionItem<TeamPermissionLevel> = { value: permission };
const expectedTeamMemeber = { ...member, permission }; const expectedTeamMemeber = { ...member, permission };
instance.onPermissionChange(item, member); instance.onPermissionChange(item, member);
......
...@@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; ...@@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { DeleteButton, Select, SelectOptionItem } from '@grafana/ui'; import { DeleteButton, Select, SelectOptionItem } from '@grafana/ui';
import { TeamMember, teamsPermissionLevels } from 'app/types'; import { TeamMember, teamsPermissionLevels, TeamPermissionLevel } from 'app/types';
import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle'; import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle';
import { updateTeamMember, removeTeamMember } from './state/actions'; import { updateTeamMember, removeTeamMember } from './state/actions';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
...@@ -27,7 +27,7 @@ export class TeamMemberRow extends PureComponent<Props> { ...@@ -27,7 +27,7 @@ export class TeamMemberRow extends PureComponent<Props> {
this.props.removeTeamMember(member.userId); this.props.removeTeamMember(member.userId);
} }
onPermissionChange = (item: SelectOptionItem, member: TeamMember) => { onPermissionChange = (item: SelectOptionItem<TeamPermissionLevel>, member: TeamMember) => {
const permission = item.value; const permission = item.value;
const updatedTeamMember = { ...member, permission }; const updatedTeamMember = { ...member, permission };
......
...@@ -29,7 +29,7 @@ export class InputQueryEditor extends PureComponent<Props, State> { ...@@ -29,7 +29,7 @@ export class InputQueryEditor extends PureComponent<Props, State> {
this.setState({ text }); this.setState({ text });
} }
onSourceChange = (item: SelectOptionItem) => { onSourceChange = (item: SelectOptionItem<string>) => {
const { datasource, query, onChange, onRunQuery } = this.props; const { datasource, query, onChange, onRunQuery } = this.props;
let data: SeriesData[] | undefined = undefined; let data: SeriesData[] | undefined = undefined;
if (item.value === 'panel') { if (item.value === 'panel') {
......
...@@ -8,7 +8,7 @@ import { SelectOptionItem } from '@grafana/ui'; ...@@ -8,7 +8,7 @@ import { SelectOptionItem } from '@grafana/ui';
export interface Props { export interface Props {
onChange: (perSeriesAligner) => void; onChange: (perSeriesAligner) => void;
templateSrv: TemplateSrv; templateSrv: TemplateSrv;
alignOptions: SelectOptionItem[]; alignOptions: Array<SelectOptionItem<string>>;
perSeriesAligner: string; perSeriesAligner: string;
} }
......
...@@ -25,7 +25,7 @@ export interface Props { ...@@ -25,7 +25,7 @@ export interface Props {
} }
interface State extends StackdriverQuery { interface State extends StackdriverQuery {
alignOptions: SelectOptionItem[]; alignOptions: Array<SelectOptionItem<string>>;
lastQuery: string; lastQuery: string;
lastQueryError: string; lastQueryError: string;
[key: string]: any; [key: string]: any;
......
...@@ -40,7 +40,7 @@ export class QueryEditor extends PureComponent<Props> { ...@@ -40,7 +40,7 @@ export class QueryEditor extends PureComponent<Props> {
this.setState({ scenarioList: scenarioList, current: current }); this.setState({ scenarioList: scenarioList, current: current });
} }
onScenarioChange = (item: SelectOptionItem) => { onScenarioChange = (item: SelectOptionItem<string>) => {
this.props.onChange({ this.props.onChange({
...this.props.query, ...this.props.query,
scenarioId: item.value, scenarioId: item.value,
......
...@@ -46,7 +46,7 @@ export class BarGaugePanelEditor extends PureComponent<PanelEditorProps<BarGauge ...@@ -46,7 +46,7 @@ export class BarGaugePanelEditor extends PureComponent<PanelEditorProps<BarGauge
return ( return (
<> <>
<PanelOptionsGrid> <PanelOptionsGrid>
<SingleStatValueEditor onChange={this.onValueOptionsChanged} options={options.valueOptions} /> <SingleStatValueEditor onChange={this.onValueOptionsChanged} value={options.valueOptions} />
<PanelOptionsGroup title="Gauge"> <PanelOptionsGroup title="Gauge">
<FormField label="Min value" labelWidth={8} onChange={this.onMinValueChange} value={options.minValue} /> <FormField label="Min value" labelWidth={8} onChange={this.onMinValueChange} value={options.minValue} />
<FormField label="Max value" labelWidth={8} onChange={this.onMaxValueChange} value={options.maxValue} /> <FormField label="Max value" labelWidth={8} onChange={this.onMaxValueChange} value={options.maxValue} />
......
...@@ -6,13 +6,13 @@ export interface BarGaugeOptions extends SingleStatBaseOptions { ...@@ -6,13 +6,13 @@ export interface BarGaugeOptions extends SingleStatBaseOptions {
displayMode: 'basic' | 'lcd' | 'gradient'; displayMode: 'basic' | 'lcd' | 'gradient';
} }
export const displayModes: SelectOptionItem[] = [ export const displayModes: Array<SelectOptionItem<string>> = [
{ value: 'gradient', label: 'Gradient' }, { value: 'gradient', label: 'Gradient' },
{ value: 'lcd', label: 'Retro LCD' }, { value: 'lcd', label: 'Retro LCD' },
{ value: 'basic', label: 'Basic' }, { value: 'basic', label: 'Basic' },
]; ];
export const orientationOptions: SelectOptionItem[] = [ export const orientationOptions: Array<SelectOptionItem<VizOrientation>> = [
{ value: VizOrientation.Horizontal, label: 'Horizontal' }, { value: VizOrientation.Horizontal, label: 'Horizontal' },
{ value: VizOrientation.Vertical, label: 'Vertical' }, { value: VizOrientation.Vertical, label: 'Vertical' },
]; ];
......
...@@ -39,7 +39,7 @@ export class GaugePanelEditor extends PureComponent<PanelEditorProps<GaugeOption ...@@ -39,7 +39,7 @@ export class GaugePanelEditor extends PureComponent<PanelEditorProps<GaugeOption
return ( return (
<> <>
<PanelOptionsGrid> <PanelOptionsGrid>
<SingleStatValueEditor onChange={this.onValueOptionsChanged} options={options.valueOptions} /> <SingleStatValueEditor onChange={this.onValueOptionsChanged} value={options.valueOptions} />
<GaugeOptionsBox onOptionsChange={onOptionsChange} options={options} /> <GaugeOptionsBox onOptionsChange={onOptionsChange} options={options} />
<ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={options.thresholds} /> <ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={options.thresholds} />
</PanelOptionsGrid> </PanelOptionsGrid>
......
...@@ -30,7 +30,7 @@ export class PieChartPanelEditor extends PureComponent<PanelEditorProps<PieChart ...@@ -30,7 +30,7 @@ export class PieChartPanelEditor extends PureComponent<PanelEditorProps<PieChart
return ( return (
<> <>
<PanelOptionsGrid> <PanelOptionsGrid>
<SingleStatValueEditor onChange={this.onValueOptionsChanged} options={options.valueOptions} /> <SingleStatValueEditor onChange={this.onValueOptionsChanged} value={options.valueOptions} />
<PieChartOptionsBox onOptionsChange={onOptionsChange} options={options} /> <PieChartOptionsBox onOptionsChange={onOptionsChange} options={options} />
</PanelOptionsGrid> </PanelOptionsGrid>
......
...@@ -20,11 +20,13 @@ const fontSizeOptions = percents.map(v => { ...@@ -20,11 +20,13 @@ const fontSizeOptions = percents.map(v => {
}); });
export class FontSizeEditor extends PureComponent<Props> { export class FontSizeEditor extends PureComponent<Props> {
setPrefixFontSize = (v: SelectOptionItem) => this.props.onChange({ ...this.props.options, prefixFontSize: v.value }); setPrefixFontSize = (v: SelectOptionItem<string>) =>
this.props.onChange({ ...this.props.options, prefixFontSize: v.value });
setValueFontSize = (v: SelectOptionItem) => this.props.onChange({ ...this.props.options, valueFontSize: v.value }); setValueFontSize = (v: SelectOptionItem<string>) =>
this.props.onChange({ ...this.props.options, valueFontSize: v.value });
setPostfixFontSize = (v: SelectOptionItem) => setPostfixFontSize = (v: SelectOptionItem<string>) =>
this.props.onChange({ ...this.props.options, postfixFontSize: v.value }); this.props.onChange({ ...this.props.options, postfixFontSize: v.value });
render() { render() {
......
...@@ -47,7 +47,7 @@ export class SingleStatEditor extends PureComponent<PanelEditorProps<SingleStatO ...@@ -47,7 +47,7 @@ export class SingleStatEditor extends PureComponent<PanelEditorProps<SingleStatO
return ( return (
<> <>
<PanelOptionsGrid> <PanelOptionsGrid>
<SingleStatValueEditor onChange={this.onValueOptionsChanged} options={options.valueOptions} /> <SingleStatValueEditor onChange={this.onValueOptionsChanged} value={options.valueOptions} />
<FontSizeEditor options={options} onChange={this.props.onOptionsChange} /> <FontSizeEditor options={options} onChange={this.props.onOptionsChange} />
<ColoringEditor options={options} onChange={this.props.onOptionsChange} /> <ColoringEditor options={options} onChange={this.props.onOptionsChange} />
<SparklineEditor options={options.sparkline} onChange={this.onSparklineChanged} /> <SparklineEditor options={options.sparkline} onChange={this.onSparklineChanged} />
......
...@@ -5,16 +5,17 @@ import React, { PureComponent, ChangeEvent } from 'react'; ...@@ -5,16 +5,17 @@ import React, { PureComponent, ChangeEvent } from 'react';
import { PanelEditorProps, PanelOptionsGroup, Select, SelectOptionItem } from '@grafana/ui'; import { PanelEditorProps, PanelOptionsGroup, Select, SelectOptionItem } from '@grafana/ui';
// Types // Types
import { TextOptions } from './types'; import { TextOptions, TextMode } from './types';
export class TextPanelEditor extends PureComponent<PanelEditorProps<TextOptions>> { export class TextPanelEditor extends PureComponent<PanelEditorProps<TextOptions>> {
modes: SelectOptionItem[] = [ modes: Array<SelectOptionItem<TextMode>> = [
{ value: 'markdown', label: 'Markdown' }, { value: 'markdown', label: 'Markdown' },
{ value: 'text', label: 'Text' }, { value: 'text', label: 'Text' },
{ value: 'html', label: 'HTML' }, { value: 'html', label: 'HTML' },
]; ];
onModeChange = (item: SelectOptionItem) => this.props.onOptionsChange({ ...this.props.options, mode: item.value }); onModeChange = (item: SelectOptionItem<TextMode>) =>
this.props.onOptionsChange({ ...this.props.options, mode: item.value });
onContentChange = (evt: ChangeEvent<HTMLTextAreaElement>) => { onContentChange = (evt: ChangeEvent<HTMLTextAreaElement>) => {
this.props.onOptionsChange({ ...this.props.options, content: (event.target as any).value }); this.props.onOptionsChange({ ...this.props.options, content: (event.target as any).value });
......
export type TextMode = 'html' | 'markdown' | 'text';
export interface TextOptions { export interface TextOptions {
mode: 'html' | 'markdown' | 'text'; mode: TextMode;
content: string; content: string;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment