refactor: Replace usages of Popover from react-bootstrap with Antd (#11163)

* New popover component

* LimitControl

* Moar components migrated

* TimeSeriesColumnControl

* Hotkeys

* ColorPicker

* FilterBoxItemCOntrol

* AdhocFilterEditPopover

* AdhocMetric

* AnnotationLayerControl

* DateFilterControl

* Tests fix

* Fix linting issue

* Fix tests

* Bug fix

* Test fix

* Remove Antd global stylesheet

* Fix linting

* Fix test

* Fix test

* Fix test

* Fix test

* Fix test
This commit is contained in:
Kamil Gabryjelski
2020-10-20 05:42:33 +02:00
committed by GitHub
parent 4208ca76e0
commit 901a42b1df
39 changed files with 942 additions and 874 deletions

View File

@@ -26,7 +26,6 @@ import {
SupersetClient,
getCategoricalSchemeRegistry,
getChartMetadataRegistry,
ThemeProvider,
validateNonEmpty,
} from '@superset-ui/core';
@@ -67,7 +66,6 @@ const propTypes = {
timeColumn: PropTypes.string,
intervalEndColumn: PropTypes.string,
vizType: PropTypes.string,
theme: PropTypes.object,
error: PropTypes.string,
colorScheme: PropTypes.string,
@@ -666,7 +664,6 @@ export default class AnnotationLayer extends React.PureComponent {
render() {
const { isNew, name, annotationType, sourceType, show } = this.state;
const isValid = this.isValidForm();
const { theme } = this.props;
const metadata = getChartMetadataRegistry().get(this.props.vizType);
const supportedAnnotationTypes = metadata
? metadata.supportedAnnotationTypes.map(
@@ -676,7 +673,7 @@ export default class AnnotationLayer extends React.PureComponent {
const supportedSourceTypes = this.getSupportedSourceTypes(annotationType);
return (
<ThemeProvider theme={theme}>
<>
{this.props.error && (
<span style={{ color: 'red' }}>ERROR: {this.props.error}</span>
)}
@@ -750,7 +747,7 @@ export default class AnnotationLayer extends React.PureComponent {
</Button>
</div>
</div>
</ThemeProvider>
</>
);
}
}

View File

@@ -18,15 +18,11 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import {
OverlayTrigger,
Popover,
ListGroup,
ListGroupItem,
} from 'react-bootstrap';
import { ListGroup, ListGroupItem } from 'react-bootstrap';
import { connect } from 'react-redux';
import { t, withTheme } from '@superset-ui/core';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import Popover from 'src/common/components/Popover';
import AsyncEsmComponent from 'src/components/AsyncEsmComponent';
import { getChartKey } from 'src/explore/exploreUtils';
import { runAnnotationQuery } from 'src/chart/chartAction';
@@ -62,8 +58,10 @@ const defaultProps = {
class AnnotationLayerControl extends React.PureComponent {
constructor(props) {
super(props);
this.state = { popoverVisible: false };
this.addAnnotationLayer = this.addAnnotationLayer.bind(this);
this.removeAnnotationLayer = this.removeAnnotationLayer.bind(this);
this.handleVisibleChange = this.handleVisibleChange.bind(this);
}
componentDidMount() {
@@ -101,6 +99,12 @@ class AnnotationLayerControl extends React.PureComponent {
this.props.onChange(annotations);
}
handleVisibleChange(visible, popoverKey) {
this.setState(prevState => ({
popoverVisible: { ...prevState, [popoverKey]: visible },
}));
}
removeAnnotationLayer(annotation) {
const annotations = this.props.value
.slice()
@@ -108,18 +112,10 @@ class AnnotationLayerControl extends React.PureComponent {
this.props.onChange(annotations);
}
renderPopover(parent, annotation, error) {
renderPopover(parent, popoverKey, annotation, error) {
const id = !annotation ? '_new' : annotation.name;
const { theme } = this.props;
return (
<Popover
data-test="annotation-popover"
style={{ maxWidth: 'none' }}
title={
annotation ? t('Edit Annotation Layer') : t('Add Annotation Layer')
}
id={`annotation-pop-${id}`}
>
<div id={`annotation-pop-${id}`} data-test="popover-content">
<AnnotationLayer
{...annotation}
parent={this.refs[parent]}
@@ -128,10 +124,9 @@ class AnnotationLayerControl extends React.PureComponent {
vizType={this.props.vizType}
addAnnotationLayer={this.addAnnotationLayer}
removeAnnotationLayer={this.removeAnnotationLayer}
close={() => this.refs[parent].hide()}
theme={theme}
close={() => this.handleVisibleChange(false, popoverKey)}
/>
</Popover>
</div>
);
}
@@ -159,34 +154,41 @@ class AnnotationLayerControl extends React.PureComponent {
render() {
const annotations = this.props.value.map((anno, i) => (
<OverlayTrigger
<Popover
key={i}
trigger="click"
rootClose
ref={`overlay-${i}`}
placement="right"
overlay={this.renderPopover(
title={t('Edit Annotation Layer')}
content={this.renderPopover(
`overlay-${i}`,
i,
anno,
this.props.annotationError[anno.name],
)}
visible={this.state.popoverVisible[i]}
onVisibleChange={visible => this.handleVisibleChange(visible, i)}
>
<ListGroupItem>
<span>{anno.name}</span>
<span style={{ float: 'right' }}>{this.renderInfo(anno)}</span>
</ListGroupItem>
</OverlayTrigger>
</Popover>
));
const addLayerPopoverKey = 'add';
return (
<div>
<ListGroup>
{annotations}
<OverlayTrigger
<Popover
trigger="click"
rootClose
ref="overlay-new"
placement="right"
overlay={this.renderPopover('overlay-new')}
content={this.renderPopover('overlay-new', addLayerPopoverKey)}
title={t('Add Annotation Layer')}
visible={this.state.popoverVisible[addLayerPopoverKey]}
onVisibleChange={visible =>
this.handleVisibleChange(visible, addLayerPopoverKey)
}
>
<ListGroupItem>
<i
@@ -195,7 +197,7 @@ class AnnotationLayerControl extends React.PureComponent {
/>{' '}
&nbsp; {t('Add Annotation Layer')}
</ListGroupItem>
</OverlayTrigger>
</Popover>
</ListGroup>
</div>
);

View File

@@ -18,9 +18,9 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import { OverlayTrigger, Popover } from 'react-bootstrap';
import { SketchPicker } from 'react-color';
import { getCategoricalSchemeRegistry } from '@superset-ui/core';
import Popover from 'src/common/components/Popover';
import ControlHeader from '../ControlHeader';
const propTypes = {
@@ -79,13 +79,13 @@ export default class ColorPickerControl extends React.Component {
.get()
.colors.filter((s, i) => i < 7);
return (
<Popover id="filter-popover" className="color-popover">
<div id="filter-popover" className="color-popover">
<SketchPicker
color={this.props.value}
onChange={this.onChange}
presetColors={presetColors}
/>
</Popover>
</div>
);
}
@@ -98,19 +98,16 @@ export default class ColorPickerControl extends React.Component {
return (
<div>
<ControlHeader {...this.props} />
<OverlayTrigger
container={document.body}
<Popover
trigger="click"
rootClose
ref="trigger"
placement="right"
overlay={this.renderPopover()}
content={this.renderPopover()}
>
<div style={styles.swatch}>
<div style={styles.checkboard} />
<div style={colStyle} />
</div>
</OverlayTrigger>
</Popover>
</div>
);
}

View File

@@ -25,12 +25,12 @@ import {
InputGroup,
MenuItem,
OverlayTrigger,
Popover,
Radio,
Tab,
Tabs,
Tooltip,
} from 'react-bootstrap';
import Popover from 'src/common/components/Popover';
import Button from 'src/components/Button';
import Datetime from 'react-datetime';
import 'react-datetime/css/react-datetime.css';
@@ -206,6 +206,8 @@ class DateFilterControl extends React.Component {
showUntilCalendar: false,
sinceViewMode: 'days',
untilViewMode: 'days',
popoverVisible: false,
};
const { value } = props;
@@ -230,6 +232,7 @@ class DateFilterControl extends React.Component {
this.setTypeCustomStartEnd = this.setTypeCustomStartEnd.bind(this);
this.toggleCalendar = this.toggleCalendar.bind(this);
this.changeTab = this.changeTab.bind(this);
this.handleVisibleChange = this.handleVisibleChange.bind(this);
}
componentDidMount() {
@@ -328,8 +331,11 @@ class DateFilterControl extends React.Component {
}
this.props.onCloseDateFilterControl();
this.props.onChange(val);
this.refs.trigger.hide();
this.setState({ showSinceCalendar: false, showUntilCalendar: false });
this.setState({
showSinceCalendar: false,
showUntilCalendar: false,
popoverVisible: false,
});
}
isValidSince(date) {
@@ -362,6 +368,10 @@ class DateFilterControl extends React.Component {
this.setState(nextState);
}
handleVisibleChange(visible) {
this.setState({ popoverVisible: visible });
}
renderInput(props, key) {
return (
<FormGroup>
@@ -374,7 +384,7 @@ class DateFilterControl extends React.Component {
onClick={() => {}}
/>
<InputGroup.Button onClick={() => this.toggleCalendar(key)}>
<Button theme={this.props.theme}>
<Button>
<i className="fa fa-calendar" />
</Button>
</InputGroup.Button>
@@ -400,7 +410,7 @@ class DateFilterControl extends React.Component {
const timeRange = buildTimeRangeString(nextState.since, nextState.until);
return (
<Styles theme={this.props.theme} key={timeFrame}>
<Styles key={timeFrame}>
<OverlayTrigger
key={timeFrame}
placement="right"
@@ -424,168 +434,166 @@ class DateFilterControl extends React.Component {
);
});
return (
<Popover id="filter-popover" placement="top" positionTop={0}>
<div
style={DATE_FILTER_POPOVER_STYLE}
ref={ref => {
this.popoverContainer = ref;
}}
<div
id="filter-popover"
style={DATE_FILTER_POPOVER_STYLE}
ref={ref => {
this.popoverContainer = ref;
}}
>
<Tabs
defaultActiveKey={this.state.tab === TABS.DEFAULTS ? 1 : 2}
id="type"
className="time-filter-tabs"
onSelect={this.changeTab}
>
<Tabs
defaultActiveKey={this.state.tab === TABS.DEFAULTS ? 1 : 2}
id="type"
className="time-filter-tabs"
onSelect={this.changeTab}
>
<Tab eventKey={1} title="Defaults">
<FormGroup>{timeFrames}</FormGroup>
</Tab>
<Tab eventKey={2} title="Custom">
<FormGroup>
<PopoverSection
title="Relative to today"
isSelected={this.state.type === TYPES.CUSTOM_RANGE}
onSelect={this.setTypeCustomRange}
<Tab eventKey={1} title="Defaults">
<FormGroup>{timeFrames}</FormGroup>
</Tab>
<Tab eventKey={2} title="Custom">
<FormGroup>
<PopoverSection
title="Relative to today"
isSelected={this.state.type === TYPES.CUSTOM_RANGE}
onSelect={this.setTypeCustomRange}
>
<div
className="clearfix centered"
style={{ marginTop: '12px' }}
>
<div
className="clearfix centered"
style={{ marginTop: '12px' }}
style={{ width: '60px', marginTop: '-4px' }}
className="input-inline"
>
<div
style={{ width: '60px', marginTop: '-4px' }}
className="input-inline"
<DropdownButton
bsSize="small"
componentClass={InputGroup.Button}
id="input-dropdown-rel"
title={this.state.rel}
onFocus={this.setTypeCustomRange}
>
<DropdownButton
bsSize="small"
componentClass={InputGroup.Button}
id="input-dropdown-rel"
title={this.state.rel}
onFocus={this.setTypeCustomRange}
<MenuItem
onSelect={value => this.setCustomRange('rel', value)}
key={RELATIVE_TIME_OPTIONS.LAST}
eventKey={RELATIVE_TIME_OPTIONS.LAST}
active={this.state.rel === RELATIVE_TIME_OPTIONS.LAST}
>
<MenuItem
onSelect={value => this.setCustomRange('rel', value)}
key={RELATIVE_TIME_OPTIONS.LAST}
eventKey={RELATIVE_TIME_OPTIONS.LAST}
active={this.state.rel === RELATIVE_TIME_OPTIONS.LAST}
>
Last
</MenuItem>
<MenuItem
onSelect={value => this.setCustomRange('rel', value)}
key={RELATIVE_TIME_OPTIONS.NEXT}
eventKey={RELATIVE_TIME_OPTIONS.NEXT}
active={this.state.rel === RELATIVE_TIME_OPTIONS.NEXT}
>
Next
</MenuItem>
</DropdownButton>
</div>
<div
style={{ width: '60px', marginTop: '-4px' }}
className="input-inline m-l-5 m-r-3"
Last
</MenuItem>
<MenuItem
onSelect={value => this.setCustomRange('rel', value)}
key={RELATIVE_TIME_OPTIONS.NEXT}
eventKey={RELATIVE_TIME_OPTIONS.NEXT}
active={this.state.rel === RELATIVE_TIME_OPTIONS.NEXT}
>
Next
</MenuItem>
</DropdownButton>
</div>
<div
style={{ width: '60px', marginTop: '-4px' }}
className="input-inline m-l-5 m-r-3"
>
<FormControl
bsSize="small"
type="text"
onChange={event =>
this.setCustomRange('num', event.target.value)
}
onFocus={this.setTypeCustomRange}
onKeyPress={this.onEnter}
value={this.state.num}
style={{ height: '30px' }}
/>
</div>
<div
style={{ width: '90px', marginTop: '-4px' }}
className="input-inline"
>
<DropdownButton
bsSize="small"
componentClass={InputGroup.Button}
id="input-dropdown-grain"
title={this.state.grain}
onFocus={this.setTypeCustomRange}
>
<FormControl
bsSize="small"
type="text"
onChange={event =>
this.setCustomRange('num', event.target.value)
{grainOptions}
</DropdownButton>
</div>
</div>
</PopoverSection>
<PopoverSection
title="Start / end"
isSelected={this.state.type === TYPES.CUSTOM_START_END}
onSelect={this.setTypeCustomStartEnd}
info={FREEFORM_TOOLTIP}
>
<div
ref={ref => {
this.startEndSectionRef = ref;
}}
>
<InputGroup data-test="date-input-group">
<div style={{ margin: '5px 0' }}>
<Datetime
inputProps={{ 'data-test': 'date-from-input' }}
value={this.state.since}
defaultValue={this.state.since}
viewDate={this.state.since}
onChange={value =>
this.setCustomStartEnd('since', value)
}
isValidDate={this.isValidSince}
onClick={this.setTypeCustomStartEnd}
renderInput={props =>
this.renderInput(props, 'showSinceCalendar')
}
open={this.state.showSinceCalendar}
viewMode={this.state.sinceViewMode}
onViewModeChange={sinceViewMode =>
this.setState({ sinceViewMode })
}
onFocus={this.setTypeCustomRange}
onKeyPress={this.onEnter}
value={this.state.num}
style={{ height: '30px' }}
/>
</div>
<div
style={{ width: '90px', marginTop: '-4px' }}
className="input-inline"
>
<DropdownButton
bsSize="small"
componentClass={InputGroup.Button}
id="input-dropdown-grain"
title={this.state.grain}
onFocus={this.setTypeCustomRange}
>
{grainOptions}
</DropdownButton>
<div style={{ margin: '5px 0' }}>
<Datetime
inputProps={{ 'data-test': 'date-to-input' }}
value={this.state.until}
defaultValue={this.state.until}
viewDate={this.state.until}
onChange={value =>
this.setCustomStartEnd('until', value)
}
isValidDate={this.isValidUntil}
onClick={this.setTypeCustomStartEnd}
renderInput={props =>
this.renderInput(props, 'showUntilCalendar')
}
open={this.state.showUntilCalendar}
viewMode={this.state.untilViewMode}
onViewModeChange={untilViewMode =>
this.setState({ untilViewMode })
}
/>
</div>
</div>
</PopoverSection>
<PopoverSection
title="Start / end"
isSelected={this.state.type === TYPES.CUSTOM_START_END}
onSelect={this.setTypeCustomStartEnd}
info={FREEFORM_TOOLTIP}
>
<div
ref={ref => {
this.startEndSectionRef = ref;
}}
>
<InputGroup data-test="date-input-group">
<div style={{ margin: '5px 0' }}>
<Datetime
inputProps={{ 'data-test': 'date-from-input' }}
value={this.state.since}
defaultValue={this.state.since}
viewDate={this.state.since}
onChange={value =>
this.setCustomStartEnd('since', value)
}
isValidDate={this.isValidSince}
onClick={this.setTypeCustomStartEnd}
renderInput={props =>
this.renderInput(props, 'showSinceCalendar')
}
open={this.state.showSinceCalendar}
viewMode={this.state.sinceViewMode}
onViewModeChange={sinceViewMode =>
this.setState({ sinceViewMode })
}
/>
</div>
<div style={{ margin: '5px 0' }}>
<Datetime
inputProps={{ 'data-test': 'date-to-input' }}
value={this.state.until}
defaultValue={this.state.until}
viewDate={this.state.until}
onChange={value =>
this.setCustomStartEnd('until', value)
}
isValidDate={this.isValidUntil}
onClick={this.setTypeCustomStartEnd}
renderInput={props =>
this.renderInput(props, 'showUntilCalendar')
}
open={this.state.showUntilCalendar}
viewMode={this.state.untilViewMode}
onViewModeChange={untilViewMode =>
this.setState({ untilViewMode })
}
/>
</div>
</InputGroup>
</div>
</PopoverSection>
</FormGroup>
</Tab>
</Tabs>
<div className="clearfix">
<Button
data-test="date-ok-button"
buttonSize="small"
className="float-right ok"
buttonStyle="primary"
onClick={this.close}
theme={this.props.theme}
>
Ok
</Button>
</div>
</InputGroup>
</div>
</PopoverSection>
</FormGroup>
</Tab>
</Tabs>
<div className="clearfix">
<Button
data-test="date-ok-button"
buttonSize="small"
className="float-right ok"
buttonStyle="primary"
onClick={this.close}
>
Ok
</Button>
</div>
</Popover>
</div>
);
}
@@ -594,15 +602,13 @@ class DateFilterControl extends React.Component {
return (
<div>
<ControlHeader {...this.props} />
<OverlayTrigger
animation={this.props.animation}
container={document.body}
<Popover
trigger="click"
rootClose
ref="trigger"
placement="right"
overlay={this.renderPopover()}
content={this.renderPopover()}
onClick={this.handleClickTrigger}
visible={this.state.popoverVisible}
onVisibleChange={this.handleVisibleChange}
>
<Label
name="popover-trigger"
@@ -611,7 +617,7 @@ class DateFilterControl extends React.Component {
>
{formatTimeRange(timeRange, this.props.endpoints)}
</Label>
</OverlayTrigger>
</Popover>
</div>
);
}

View File

@@ -18,10 +18,10 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import { OverlayTrigger, Popover } from 'react-bootstrap';
import { t } from '@superset-ui/core';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import Popover from 'src/common/components/Popover';
import FormRow from '../../../components/FormRow';
import SelectControl from './SelectControl';
import CheckboxControl from './CheckboxControl';
@@ -81,7 +81,7 @@ export default class FilterBoxItemControl extends React.Component {
label,
defaultValue,
} = props;
const state = {
this.state = {
column,
metric,
label,
@@ -91,7 +91,6 @@ export default class FilterBoxItemControl extends React.Component {
searchAllOptions,
defaultValue,
};
this.state = state;
this.onChange = this.onChange.bind(this);
this.onControlChange = this.onControlChange.bind(this);
}
@@ -265,9 +264,9 @@ export default class FilterBoxItemControl extends React.Component {
renderPopover() {
return (
<Popover id="ts-col-popo" title={t('Filter Configuration')}>
<div style={STYLE_WIDTH}>{this.renderForm()}</div>
</Popover>
<div id="ts-col-popo" style={STYLE_WIDTH}>
{this.renderForm()}
</div>
);
}
@@ -275,20 +274,18 @@ export default class FilterBoxItemControl extends React.Component {
return (
<span>
{this.textSummary()}{' '}
<OverlayTrigger
container={document.body}
<Popover
trigger="click"
rootClose
ref="trigger"
placement="right"
overlay={this.renderPopover()}
content={this.renderPopover()}
title={t('Filter Configuration')}
>
<InfoTooltipWithTrigger
icon="edit"
className="text-primary"
label="edit-ts-column"
/>
</OverlayTrigger>
</Popover>
</span>
);
}

View File

@@ -18,13 +18,8 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import {
Row,
Col,
FormControl,
OverlayTrigger,
Popover,
} from 'react-bootstrap';
import { Row, Col, FormControl } from 'react-bootstrap';
import Popover from 'src/common/components/Popover';
import Select from 'src/components/Select';
import { t } from '@superset-ui/core';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
@@ -153,159 +148,157 @@ export default class TimeSeriesColumnControl extends React.Component {
renderPopover() {
return (
<Popover id="ts-col-popo" title="Column Configuration">
<div style={{ width: 300 }}>
{this.formRow(
'Label',
'The column header label',
<div id="ts-col-popo" style={{ width: 300 }}>
{this.formRow(
'Label',
'The column header label',
'time-lag',
<FormControl
value={this.state.label}
onChange={this.onTextInputChange.bind(this, 'label')}
bsSize="small"
placeholder="Label"
/>,
)}
{this.formRow(
'Tooltip',
'Column header tooltip',
'col-tooltip',
<FormControl
value={this.state.tooltip}
onChange={this.onTextInputChange.bind(this, 'tooltip')}
bsSize="small"
placeholder="Tooltip"
/>,
)}
{this.formRow(
'Type',
'Type of comparison, value difference or percentage',
'col-type',
<Select
value={this.state.colType}
clearable={false}
onChange={this.onSelectChange.bind(this, 'colType')}
options={colTypeOptions}
/>,
)}
<hr />
{this.state.colType === 'spark' &&
this.formRow(
'Width',
'Width of the sparkline',
'spark-width',
<FormControl
value={this.state.width}
onChange={this.onTextInputChange.bind(this, 'width')}
bsSize="small"
placeholder="Width"
/>,
)}
{this.state.colType === 'spark' &&
this.formRow(
'Height',
'Height of the sparkline',
'spark-width',
<FormControl
value={this.state.height}
onChange={this.onTextInputChange.bind(this, 'height')}
bsSize="small"
placeholder="height"
/>,
)}
{['time', 'avg'].indexOf(this.state.colType) >= 0 &&
this.formRow(
'Time Lag',
'Number of periods to compare against',
'time-lag',
<FormControl
value={this.state.label}
onChange={this.onTextInputChange.bind(this, 'label')}
value={this.state.timeLag}
onChange={this.onTextInputChange.bind(this, 'timeLag')}
bsSize="small"
placeholder="Label"
placeholder="Time Lag"
/>,
)}
{this.formRow(
'Tooltip',
'Column header tooltip',
'col-tooltip',
{['spark'].indexOf(this.state.colType) >= 0 &&
this.formRow(
'Time Ratio',
'Number of periods to ratio against',
'time-ratio',
<FormControl
value={this.state.tooltip}
onChange={this.onTextInputChange.bind(this, 'tooltip')}
value={this.state.timeRatio}
onChange={this.onTextInputChange.bind(this, 'timeRatio')}
bsSize="small"
placeholder="Tooltip"
placeholder="Time Ratio"
/>,
)}
{this.formRow(
{this.state.colType === 'time' &&
this.formRow(
'Type',
'Type of comparison, value difference or percentage',
'col-type',
'comp-type',
<Select
value={this.state.colType}
value={this.state.comparisonType}
clearable={false}
onChange={this.onSelectChange.bind(this, 'colType')}
options={colTypeOptions}
onChange={this.onSelectChange.bind(this, 'comparisonType')}
options={comparisonTypeOptions}
/>,
)}
<hr />
{this.state.colType === 'spark' &&
this.formRow(
'Width',
'Width of the sparkline',
'spark-width',
<FormControl
value={this.state.width}
onChange={this.onTextInputChange.bind(this, 'width')}
bsSize="small"
placeholder="Width"
/>,
)}
{this.state.colType === 'spark' &&
this.formRow(
'Height',
'Height of the sparkline',
'spark-width',
<FormControl
value={this.state.height}
onChange={this.onTextInputChange.bind(this, 'height')}
bsSize="small"
placeholder="height"
/>,
)}
{['time', 'avg'].indexOf(this.state.colType) >= 0 &&
this.formRow(
'Time Lag',
'Number of periods to compare against',
'time-lag',
<FormControl
value={this.state.timeLag}
onChange={this.onTextInputChange.bind(this, 'timeLag')}
bsSize="small"
placeholder="Time Lag"
/>,
)}
{['spark'].indexOf(this.state.colType) >= 0 &&
this.formRow(
'Time Ratio',
'Number of periods to ratio against',
'time-ratio',
<FormControl
value={this.state.timeRatio}
onChange={this.onTextInputChange.bind(this, 'timeRatio')}
bsSize="small"
placeholder="Time Ratio"
/>,
)}
{this.state.colType === 'time' &&
this.formRow(
'Type',
'Type of comparison, value difference or percentage',
'comp-type',
<Select
value={this.state.comparisonType}
clearable={false}
onChange={this.onSelectChange.bind(this, 'comparisonType')}
options={comparisonTypeOptions}
/>,
)}
{this.state.colType === 'spark' &&
this.formRow(
'Show Y-axis',
'Show Y-axis on the sparkline. Will display the manually set min/max if set or min/max values in the data otherwise.',
'show-y-axis-bounds',
<CheckboxControl
value={this.state.showYAxis}
onChange={this.onCheckboxChange.bind(this, 'showYAxis')}
/>,
)}
{this.state.colType === 'spark' &&
this.formRow(
'Y-axis bounds',
'Manually set min/max values for the y-axis.',
'y-axis-bounds',
<BoundsControl
value={this.state.yAxisBounds}
onChange={this.onYAxisBoundsChange.bind(this)}
/>,
)}
{this.state.colType !== 'spark' &&
this.formRow(
'Color bounds',
`Number bounds used for color encoding from red to blue.
{this.state.colType === 'spark' &&
this.formRow(
'Show Y-axis',
'Show Y-axis on the sparkline. Will display the manually set min/max if set or min/max values in the data otherwise.',
'show-y-axis-bounds',
<CheckboxControl
value={this.state.showYAxis}
onChange={this.onCheckboxChange.bind(this, 'showYAxis')}
/>,
)}
{this.state.colType === 'spark' &&
this.formRow(
'Y-axis bounds',
'Manually set min/max values for the y-axis.',
'y-axis-bounds',
<BoundsControl
value={this.state.yAxisBounds}
onChange={this.onYAxisBoundsChange.bind(this)}
/>,
)}
{this.state.colType !== 'spark' &&
this.formRow(
'Color bounds',
`Number bounds used for color encoding from red to blue.
Reverse the numbers for blue to red. To get pure red or blue,
you can enter either only min or max.`,
'bounds',
<BoundsControl
value={this.state.bounds}
onChange={this.onBoundsChange.bind(this)}
/>,
)}
{this.formRow(
'Number format',
'Optional d3 number format string',
'd3-format',
<FormControl
value={this.state.d3format}
onChange={this.onTextInputChange.bind(this, 'd3format')}
bsSize="small"
placeholder="Number format string"
'bounds',
<BoundsControl
value={this.state.bounds}
onChange={this.onBoundsChange.bind(this)}
/>,
)}
{this.state.colType === 'spark' &&
this.formRow(
'Date format',
'Optional d3 date format string',
'date-format',
<FormControl
value={this.state.dateFormat}
onChange={this.onTextInputChange.bind(this, 'dateFormat')}
bsSize="small"
placeholder="Date format string"
/>,
)}
</div>
</Popover>
{this.formRow(
'Number format',
'Optional d3 number format string',
'd3-format',
<FormControl
value={this.state.d3format}
onChange={this.onTextInputChange.bind(this, 'd3format')}
bsSize="small"
placeholder="Number format string"
/>,
)}
{this.state.colType === 'spark' &&
this.formRow(
'Date format',
'Optional d3 date format string',
'date-format',
<FormControl
value={this.state.dateFormat}
onChange={this.onTextInputChange.bind(this, 'dateFormat')}
bsSize="small"
placeholder="Date format string"
/>,
)}
</div>
);
}
@@ -313,13 +306,11 @@ export default class TimeSeriesColumnControl extends React.Component {
return (
<span>
{this.textSummary()}{' '}
<OverlayTrigger
container={document.body}
<Popover
trigger="click"
rootClose
ref="trigger"
placement="right"
overlay={this.renderPopover()}
content={this.renderPopover()}
title="Column Configuration"
>
<InfoTooltipWithTrigger
icon="edit"
@@ -327,7 +318,7 @@ export default class TimeSeriesColumnControl extends React.Component {
onClick={this.edit.bind(this)}
label="edit-ts-column"
/>
</OverlayTrigger>
</Popover>
</span>
);
}

View File

@@ -18,7 +18,7 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import { Popover, OverlayTrigger } from 'react-bootstrap';
import Popover from 'src/common/components/Popover';
import { decimal2sexagesimal } from 'geolib';
import Label from 'src/components/Label';
@@ -83,9 +83,9 @@ export default class ViewportControl extends React.Component {
renderPopover() {
return (
<Popover id={`filter-popover-${this.props.name}`} title="Viewport">
<div id={`filter-popover-${this.props.name}`}>
{PARAMS.map(ctrl => this.renderTextControl(ctrl))}
</Popover>
</div>
);
}
@@ -102,16 +102,15 @@ export default class ViewportControl extends React.Component {
return (
<div>
<ControlHeader {...this.props} />
<OverlayTrigger
<Popover
container={document.body}
trigger="click"
rootClose
ref="trigger"
placement="right"
overlay={this.renderPopover()}
content={this.renderPopover()}
title="Viewport"
>
<Label className="pointer">{this.renderLabel()}</Label>
</OverlayTrigger>
</Popover>
</div>
);
}