mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'master' into react-query-editor
This commit is contained in:
@@ -11,6 +11,7 @@ interface Props {
|
||||
hideTracksWhenNotNeeded?: boolean;
|
||||
scrollTop?: number;
|
||||
setScrollTop: (value: React.MouseEvent<HTMLElement>) => void;
|
||||
autoHeightMin?: number | string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,6 +27,7 @@ export class CustomScrollbar extends PureComponent<Props> {
|
||||
hideTracksWhenNotNeeded: false,
|
||||
scrollTop: 0,
|
||||
setScrollTop: () => {},
|
||||
autoHeightMin: '0'
|
||||
};
|
||||
|
||||
private ref: React.RefObject<Scrollbars>;
|
||||
@@ -65,7 +67,6 @@ export class CustomScrollbar extends PureComponent<Props> {
|
||||
autoHeight={true}
|
||||
// These autoHeightMin & autoHeightMax options affect firefox and chrome differently.
|
||||
// Before these where set to inhert but that caused problems with cut of legends in firefox
|
||||
autoHeightMin={'0'}
|
||||
autoHeightMax={autoMaxHeight}
|
||||
renderTrackHorizontal={props => <div {...props} className="track-horizontal" />}
|
||||
renderTrackVertical={props => <div {...props} className="track-vertical" />}
|
||||
|
||||
@@ -7,7 +7,7 @@ exports[`CustomScrollbar renders correctly 1`] = `
|
||||
Object {
|
||||
"height": "auto",
|
||||
"maxHeight": "100%",
|
||||
"minHeight": "0",
|
||||
"minHeight": 0,
|
||||
"overflow": "hidden",
|
||||
"position": "relative",
|
||||
"width": "100%",
|
||||
@@ -24,7 +24,7 @@ exports[`CustomScrollbar renders correctly 1`] = `
|
||||
"marginBottom": 0,
|
||||
"marginRight": 0,
|
||||
"maxHeight": "calc(100% + 0px)",
|
||||
"minHeight": "calc(0 + 0px)",
|
||||
"minHeight": 0,
|
||||
"overflow": "scroll",
|
||||
"position": "relative",
|
||||
"right": undefined,
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { FormField, Props } from './FormField';
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
label: 'Test',
|
||||
labelWidth: 11,
|
||||
value: 10,
|
||||
onChange: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
return shallow(<FormField {...props} />);
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
it('should render component', () => {
|
||||
const wrapper = setup();
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
25
packages/grafana-ui/src/components/FormField/FormField.tsx
Normal file
25
packages/grafana-ui/src/components/FormField/FormField.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React, { InputHTMLAttributes, FunctionComponent } from 'react';
|
||||
import { FormLabel } from '..';
|
||||
|
||||
export interface Props extends InputHTMLAttributes<HTMLInputElement> {
|
||||
label: string;
|
||||
labelWidth?: number;
|
||||
inputWidth?: number;
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
labelWidth: 6,
|
||||
inputWidth: 12,
|
||||
};
|
||||
|
||||
const FormField: FunctionComponent<Props> = ({ label, labelWidth, inputWidth, ...inputProps }) => {
|
||||
return (
|
||||
<div className="form-field">
|
||||
<FormLabel width={labelWidth}>{label}</FormLabel>
|
||||
<input type="text" className={`gf-form-input width-${inputWidth}`} {...inputProps} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
FormField.defaultProps = defaultProps;
|
||||
export { FormField };
|
||||
12
packages/grafana-ui/src/components/FormField/_FormField.scss
Normal file
12
packages/grafana-ui/src/components/FormField/_FormField.scss
Normal file
@@ -0,0 +1,12 @@
|
||||
.form-field {
|
||||
margin-bottom: $gf-form-margin;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
|
||||
&--grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render should render component 1`] = `
|
||||
<div
|
||||
className="form-field"
|
||||
>
|
||||
<Component
|
||||
width={11}
|
||||
>
|
||||
Test
|
||||
</Component>
|
||||
<input
|
||||
className="gf-form-input width-12"
|
||||
onChange={[MockFunction]}
|
||||
type="text"
|
||||
value={10}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
42
packages/grafana-ui/src/components/FormLabel/FormLabel.tsx
Normal file
42
packages/grafana-ui/src/components/FormLabel/FormLabel.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import React, { FunctionComponent, ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Tooltip } from '..';
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
htmlFor?: string;
|
||||
isFocused?: boolean;
|
||||
isInvalid?: boolean;
|
||||
tooltip?: string;
|
||||
width?: number;
|
||||
}
|
||||
|
||||
export const FormLabel: FunctionComponent<Props> = ({
|
||||
children,
|
||||
isFocused,
|
||||
isInvalid,
|
||||
className,
|
||||
htmlFor,
|
||||
tooltip,
|
||||
width,
|
||||
...rest
|
||||
}) => {
|
||||
const classes = classNames(`gf-form-label width-${width ? width : '10'}`, className, {
|
||||
'gf-form-label--is-focused': isFocused,
|
||||
'gf-form-label--is-invalid': isInvalid,
|
||||
});
|
||||
|
||||
return (
|
||||
<label className={classes} {...rest} htmlFor={htmlFor}>
|
||||
{children}
|
||||
{tooltip && (
|
||||
<Tooltip placement="auto" content={tooltip}>
|
||||
<div className="gf-form-help-icon--right-normal">
|
||||
<i className="gicon gicon-question gicon--has-hover" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
</label>
|
||||
);
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
import React, { SFC, ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
htmlFor?: string;
|
||||
className?: string;
|
||||
isFocused?: boolean;
|
||||
isInvalid?: boolean;
|
||||
}
|
||||
|
||||
export const GfFormLabel: SFC<Props> = ({ children, isFocused, isInvalid, className, htmlFor, ...rest }) => {
|
||||
const classes = classNames('gf-form-label', className, {
|
||||
'gf-form-label--is-focused': isFocused,
|
||||
'gf-form-label--is-invalid': isInvalid,
|
||||
});
|
||||
|
||||
return (
|
||||
<label className={classes} {...rest} htmlFor={htmlFor}>
|
||||
{children}
|
||||
</label>
|
||||
);
|
||||
};
|
||||
@@ -6,7 +6,7 @@
|
||||
}
|
||||
|
||||
.panel-options-group__header {
|
||||
padding: 4px 20px;
|
||||
padding: 4px 8px;
|
||||
font-size: 1.1rem;
|
||||
background: $panel-options-group-header-bg;
|
||||
position: relative;
|
||||
|
||||
@@ -16,7 +16,7 @@ import SelectOptionGroup from './SelectOptionGroup';
|
||||
import IndicatorsContainer from './IndicatorsContainer';
|
||||
import NoOptionsMessage from './NoOptionsMessage';
|
||||
import resetSelectStyles from './resetSelectStyles';
|
||||
import { CustomScrollbar } from '@grafana/ui';
|
||||
import { CustomScrollbar } from '..';
|
||||
|
||||
export interface SelectOptionItem {
|
||||
label?: string;
|
||||
|
||||
@@ -102,6 +102,7 @@ $select-input-bg-disabled: $input-bg-disabled;
|
||||
.gf-form-select-box__value-container {
|
||||
display: table-cell;
|
||||
padding: 6px 10px;
|
||||
vertical-align: middle;
|
||||
> div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.thresholds-row:first-child > .thresholds-row-color-indicator {
|
||||
border-top-left-radius: $border-radius;
|
||||
border-top-right-radius: $border-radius;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.thresholds-row:last-child > .thresholds-row-color-indicator {
|
||||
border-bottom-left-radius: $border-radius;
|
||||
border-bottom-right-radius: $border-radius;
|
||||
@@ -33,7 +39,7 @@
|
||||
}
|
||||
|
||||
.thresholds-row-color-indicator {
|
||||
width: 20px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.thresholds-row-input {
|
||||
@@ -45,18 +51,6 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: row;
|
||||
height: 42px;
|
||||
}
|
||||
|
||||
.thresholds-row-input-inner > div {
|
||||
border-left: 1px solid $input-label-border-color;
|
||||
border-top: 1px solid $input-label-border-color;
|
||||
border-bottom: 1px solid $input-label-border-color;
|
||||
}
|
||||
|
||||
.thresholds-row-input-inner > *:nth-child(2) {
|
||||
border-top-left-radius: $border-radius;
|
||||
border-bottom-left-radius: $border-radius;
|
||||
}
|
||||
|
||||
.thresholds-row-input-inner > *:last-child {
|
||||
@@ -74,9 +68,11 @@
|
||||
}
|
||||
|
||||
.thresholds-row-input-inner-value > input {
|
||||
height: 100%;
|
||||
padding: 8px 10px;
|
||||
height: $gf-form-input-height;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
width: 150px;
|
||||
border-top: 1px solid $input-label-border-color;
|
||||
border-bottom: 1px solid $input-label-border-color;
|
||||
}
|
||||
|
||||
.thresholds-row-input-inner-color {
|
||||
@@ -85,6 +81,7 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: $input-bg;
|
||||
border: 1px solid $input-label-border-color;
|
||||
}
|
||||
|
||||
.thresholds-row-input-inner-color-colorpicker {
|
||||
@@ -99,8 +96,10 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 42px;
|
||||
height: $gf-form-input-height;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
width: 42px;
|
||||
background-color: $input-label-border-color;
|
||||
background-color: $input-label-bg;
|
||||
border: 1px solid $input-label-border-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
import React, { ChangeEvent, PureComponent } from 'react';
|
||||
|
||||
import { MappingType, ValueMapping } from '../../types';
|
||||
import { FormField, FormLabel, Select } from '..';
|
||||
|
||||
export interface Props {
|
||||
valueMapping: ValueMapping;
|
||||
updateValueMapping: (valueMapping: ValueMapping) => void;
|
||||
removeValueMapping: () => void;
|
||||
}
|
||||
|
||||
interface State {
|
||||
from?: string;
|
||||
id: number;
|
||||
operator: string;
|
||||
text: string;
|
||||
to?: string;
|
||||
type: MappingType;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
const mappingOptions = [
|
||||
{ value: MappingType.ValueToText, label: 'Value' },
|
||||
{ value: MappingType.RangeToText, label: 'Range' },
|
||||
];
|
||||
|
||||
export default class MappingRow extends PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.state = { ...props.valueMapping };
|
||||
}
|
||||
|
||||
onMappingValueChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({ value: event.target.value });
|
||||
};
|
||||
|
||||
onMappingFromChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({ from: event.target.value });
|
||||
};
|
||||
|
||||
onMappingToChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({ to: event.target.value });
|
||||
};
|
||||
|
||||
onMappingTextChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({ text: event.target.value });
|
||||
};
|
||||
|
||||
onMappingTypeChange = (mappingType: MappingType) => {
|
||||
this.setState({ type: mappingType });
|
||||
};
|
||||
|
||||
updateMapping = () => {
|
||||
this.props.updateValueMapping({ ...this.state } as ValueMapping);
|
||||
};
|
||||
|
||||
renderRow() {
|
||||
const { from, text, to, type, value } = this.state;
|
||||
|
||||
if (type === MappingType.RangeToText) {
|
||||
return (
|
||||
<>
|
||||
<FormField
|
||||
label="From"
|
||||
labelWidth={4}
|
||||
inputWidth={8}
|
||||
onBlur={this.updateMapping}
|
||||
onChange={this.onMappingFromChange}
|
||||
value={from}
|
||||
/>
|
||||
<FormField
|
||||
label="To"
|
||||
labelWidth={4}
|
||||
inputWidth={8}
|
||||
onBlur={this.updateMapping}
|
||||
onChange={this.onMappingToChange}
|
||||
value={to}
|
||||
/>
|
||||
<div className="gf-form gf-form--grow">
|
||||
<FormLabel width={4}>Text</FormLabel>
|
||||
<input
|
||||
className="gf-form-input"
|
||||
onBlur={this.updateMapping}
|
||||
value={text}
|
||||
onChange={this.onMappingTextChange}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormField
|
||||
label="Value"
|
||||
labelWidth={4}
|
||||
onBlur={this.updateMapping}
|
||||
onChange={this.onMappingValueChange}
|
||||
value={value}
|
||||
inputWidth={8}
|
||||
/>
|
||||
<div className="gf-form gf-form--grow">
|
||||
<FormLabel width={4}>Text</FormLabel>
|
||||
<input
|
||||
className="gf-form-input"
|
||||
onBlur={this.updateMapping}
|
||||
value={text}
|
||||
onChange={this.onMappingTextChange}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { type } = this.state;
|
||||
|
||||
return (
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<FormLabel width={5}>Type</FormLabel>
|
||||
<Select
|
||||
placeholder="Choose type"
|
||||
isSearchable={false}
|
||||
options={mappingOptions}
|
||||
value={mappingOptions.find(o => o.value === type)}
|
||||
onChange={type => this.onMappingTypeChange(type.value)}
|
||||
width={7}
|
||||
/>
|
||||
</div>
|
||||
{this.renderRow()}
|
||||
<div className="gf-form">
|
||||
<button onClick={this.props.removeValueMapping} className="gf-form-label gf-form-label--btn">
|
||||
<i className="fa fa-times" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { ValueMappingsEditor, Props } from './ValueMappingsEditor';
|
||||
import { MappingType } from '../../types/panel';
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
onChange: jest.fn(),
|
||||
valueMappings: [
|
||||
{ id: 1, operator: '', type: MappingType.ValueToText, value: '20', text: 'Ok' },
|
||||
{ id: 2, operator: '', type: MappingType.RangeToText, from: '21', to: '30', text: 'Meh' },
|
||||
],
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
|
||||
const wrapper = shallow(<ValueMappingsEditor {...props} />);
|
||||
|
||||
const instance = wrapper.instance() as ValueMappingsEditor;
|
||||
|
||||
return {
|
||||
instance,
|
||||
wrapper,
|
||||
};
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
it('should render component', () => {
|
||||
const { wrapper } = setup();
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('On remove mapping', () => {
|
||||
it('Should remove mapping with id 0', () => {
|
||||
const { instance } = setup();
|
||||
|
||||
instance.onRemoveMapping(1);
|
||||
|
||||
expect(instance.state.valueMappings).toEqual([
|
||||
{ id: 2, operator: '', type: MappingType.RangeToText, from: '21', to: '30', text: 'Meh' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should remove mapping with id 1', () => {
|
||||
const { instance } = setup();
|
||||
|
||||
instance.onRemoveMapping(2);
|
||||
|
||||
expect(instance.state.valueMappings).toEqual([
|
||||
{ id: 1, operator: '', type: MappingType.ValueToText, value: '20', text: 'Ok' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Next id to add', () => {
|
||||
it('should be 4', () => {
|
||||
const { instance } = setup();
|
||||
|
||||
instance.addMapping();
|
||||
|
||||
expect(instance.state.nextIdToAdd).toEqual(4);
|
||||
});
|
||||
|
||||
it('should default to 1', () => {
|
||||
const { instance } = setup({ valueMappings: [] });
|
||||
|
||||
expect(instance.state.nextIdToAdd).toEqual(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,105 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import MappingRow from './MappingRow';
|
||||
import { MappingType, ValueMapping } from '../../types/panel';
|
||||
import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup';
|
||||
|
||||
export interface Props {
|
||||
valueMappings: ValueMapping[];
|
||||
onChange: (valueMappings: ValueMapping[]) => void;
|
||||
}
|
||||
|
||||
interface State {
|
||||
valueMappings: ValueMapping[];
|
||||
nextIdToAdd: number;
|
||||
}
|
||||
|
||||
export class ValueMappingsEditor extends PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
const mappings = props.valueMappings;
|
||||
|
||||
this.state = {
|
||||
valueMappings: mappings,
|
||||
nextIdToAdd: mappings.length > 0 ? this.getMaxIdFromValueMappings(mappings) : 1,
|
||||
};
|
||||
}
|
||||
|
||||
getMaxIdFromValueMappings(mappings: ValueMapping[]) {
|
||||
return Math.max.apply(null, mappings.map(mapping => mapping.id).map(m => m)) + 1;
|
||||
}
|
||||
|
||||
addMapping = () =>
|
||||
this.setState(prevState => ({
|
||||
valueMappings: [
|
||||
...prevState.valueMappings,
|
||||
{
|
||||
id: prevState.nextIdToAdd,
|
||||
operator: '',
|
||||
value: '',
|
||||
text: '',
|
||||
type: MappingType.ValueToText,
|
||||
from: '',
|
||||
to: '',
|
||||
},
|
||||
],
|
||||
nextIdToAdd: prevState.nextIdToAdd + 1,
|
||||
}));
|
||||
|
||||
onRemoveMapping = (id: number) => {
|
||||
this.setState(
|
||||
prevState => ({
|
||||
valueMappings: prevState.valueMappings.filter(m => {
|
||||
return m.id !== id;
|
||||
}),
|
||||
}),
|
||||
() => {
|
||||
this.props.onChange(this.state.valueMappings);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
updateGauge = (mapping: ValueMapping) => {
|
||||
this.setState(
|
||||
prevState => ({
|
||||
valueMappings: prevState.valueMappings.map(m => {
|
||||
if (m.id === mapping.id) {
|
||||
return { ...mapping };
|
||||
}
|
||||
|
||||
return m;
|
||||
}),
|
||||
}),
|
||||
() => {
|
||||
this.props.onChange(this.state.valueMappings);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { valueMappings } = this.state;
|
||||
|
||||
return (
|
||||
<PanelOptionsGroup title="Value Mappings">
|
||||
<div>
|
||||
{valueMappings.length > 0 &&
|
||||
valueMappings.map((valueMapping, index) => (
|
||||
<MappingRow
|
||||
key={`${valueMapping.text}-${index}`}
|
||||
valueMapping={valueMapping}
|
||||
updateValueMapping={this.updateGauge}
|
||||
removeValueMapping={() => this.onRemoveMapping(valueMapping.id)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="add-mapping-row" onClick={this.addMapping}>
|
||||
<div className="add-mapping-row-icon">
|
||||
<i className="fa fa-plus" />
|
||||
</div>
|
||||
<div className="add-mapping-row-label">Add mapping</div>
|
||||
</div>
|
||||
</PanelOptionsGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
.mapping-row {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.add-mapping-row {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
height: 37px;
|
||||
cursor: pointer;
|
||||
border-radius: $border-radius;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.add-mapping-row-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
background-color: $green;
|
||||
}
|
||||
|
||||
.add-mapping-row-label {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
padding: 5px 8px;
|
||||
background-color: $input-label-bg;
|
||||
width: calc(100% - 36px);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render should render component 1`] = `
|
||||
<Component
|
||||
title="Value Mappings"
|
||||
>
|
||||
<div>
|
||||
<MappingRow
|
||||
key="Ok-0"
|
||||
removeValueMapping={[Function]}
|
||||
updateValueMapping={[Function]}
|
||||
valueMapping={
|
||||
Object {
|
||||
"id": 1,
|
||||
"operator": "",
|
||||
"text": "Ok",
|
||||
"type": 1,
|
||||
"value": "20",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<MappingRow
|
||||
key="Meh-1"
|
||||
removeValueMapping={[Function]}
|
||||
updateValueMapping={[Function]}
|
||||
valueMapping={
|
||||
Object {
|
||||
"from": "21",
|
||||
"id": 2,
|
||||
"operator": "",
|
||||
"text": "Meh",
|
||||
"to": "30",
|
||||
"type": 2,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="add-mapping-row"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<div
|
||||
className="add-mapping-row-icon"
|
||||
>
|
||||
<i
|
||||
className="fa fa-plus"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="add-mapping-row-label"
|
||||
>
|
||||
Add mapping
|
||||
</div>
|
||||
</div>
|
||||
</Component>
|
||||
`;
|
||||
@@ -6,3 +6,5 @@
|
||||
@import 'PanelOptionsGroup/PanelOptionsGroup';
|
||||
@import 'PanelOptionsGrid/PanelOptionsGrid';
|
||||
@import 'ColorPicker/ColorPicker';
|
||||
@import 'ValueMappingsEditor/ValueMappingsEditor';
|
||||
@import "FormField/FormField";
|
||||
|
||||
@@ -9,12 +9,16 @@ export { IndicatorsContainer } from './Select/IndicatorsContainer';
|
||||
export { NoOptionsMessage } from './Select/NoOptionsMessage';
|
||||
export { default as resetSelectStyles } from './Select/resetSelectStyles';
|
||||
|
||||
// Forms
|
||||
export { FormLabel } from './FormLabel/FormLabel';
|
||||
export { FormField } from './FormField/FormField';
|
||||
|
||||
export { LoadingPlaceholder } from './LoadingPlaceholder/LoadingPlaceholder';
|
||||
export { ColorPicker } from './ColorPicker/ColorPicker';
|
||||
export { SeriesColorPickerPopover } from './ColorPicker/SeriesColorPickerPopover';
|
||||
export { SeriesColorPicker } from './ColorPicker/SeriesColorPicker';
|
||||
export { ThresholdsEditor } from './ThresholdsEditor/ThresholdsEditor';
|
||||
export { GfFormLabel } from './GfFormLabel/GfFormLabel';
|
||||
export { Graph } from './Graph/Graph';
|
||||
export { PanelOptionsGroup } from './PanelOptionsGroup/PanelOptionsGroup';
|
||||
export { PanelOptionsGrid } from './PanelOptionsGrid/PanelOptionsGrid';
|
||||
export { ValueMappingsEditor } from './ValueMappingsEditor/ValueMappingsEditor';
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { RangeMap, Threshold, ValueMap } from './panel';
|
||||
|
||||
export interface GaugeOptions {
|
||||
baseColor: string;
|
||||
decimals: number;
|
||||
mappings: Array<RangeMap | ValueMap>;
|
||||
maxValue: number;
|
||||
minValue: number;
|
||||
prefix: string;
|
||||
showThresholdLabels: boolean;
|
||||
showThresholdMarkers: boolean;
|
||||
stat: string;
|
||||
suffix: string;
|
||||
thresholds: Threshold[];
|
||||
unit: string;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
export * from './series';
|
||||
export * from './time';
|
||||
export * from './panel';
|
||||
export * from './gauge';
|
||||
|
||||
@@ -56,6 +56,8 @@ interface BaseMap {
|
||||
type: MappingType;
|
||||
}
|
||||
|
||||
export type ValueMapping = ValueMap | RangeMap;
|
||||
|
||||
export interface ValueMap extends BaseMap {
|
||||
value: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user