bugfix: improve 'Time Table' (#6959)

* [WiP] debugging and improving 'Time Table'

closes https://github.com/apache/incubator-superset/issues/6948

* Lint

* Remove passing down props from CollectionControl

* Declarative passthrough of props

* remove console.error
This commit is contained in:
Maxime Beauchemin 2019-04-11 23:36:48 -07:00 committed by GitHub
parent 14647fc2ed
commit 9b4f5ad8e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 32 deletions

View File

@ -44,6 +44,7 @@ const propTypes = {
isFloat: PropTypes.bool, isFloat: PropTypes.bool,
isInt: PropTypes.bool, isInt: PropTypes.bool,
controlName: PropTypes.string.isRequired, controlName: PropTypes.string.isRequired,
passthroughProps: PropTypes.arrayOf(PropTypes.string),
}; };
const defaultProps = { const defaultProps = {
@ -55,6 +56,7 @@ const defaultProps = {
keyAccessor: o => o.key, keyAccessor: o => o.key,
value: [], value: [],
addTooltip: 'Add an item', addTooltip: 'Add an item',
passthroughProps: [],
}; };
const SortableListGroupItem = SortableElement(ListGroupItem); const SortableListGroupItem = SortableElement(ListGroupItem);
const SortableListGroup = SortableContainer(ListGroup); const SortableListGroup = SortableContainer(ListGroup);
@ -84,6 +86,13 @@ export default class CollectionControl extends React.Component {
return <div className="text-muted">{this.props.placeholder}</div>; return <div className="text-muted">{this.props.placeholder}</div>;
} }
const Control = controlMap[this.props.controlName]; const Control = controlMap[this.props.controlName];
// Creating an object to pass the selected props to the children
const passthroughPropsObj = {};
this.props.passthroughProps.forEach((k) => {
passthroughPropsObj[k] = this.props[k];
});
return ( return (
<SortableListGroup <SortableListGroup
useDragHandle useDragHandle
@ -101,7 +110,7 @@ export default class CollectionControl extends React.Component {
</div> </div>
<div className="pull-left"> <div className="pull-left">
<Control <Control
{...this.props} {...passthroughPropsObj}
{...o} {...o}
onChange={this.onChange.bind(this, i)} onChange={this.onChange.bind(this, i)}
/> />

View File

@ -22,6 +22,7 @@ import {
Row, Col, FormControl, OverlayTrigger, Popover, Row, Col, FormControl, OverlayTrigger, Popover,
} from 'react-bootstrap'; } from 'react-bootstrap';
import Select from 'react-select'; import Select from 'react-select';
import { t } from '@superset-ui/translation';
import InfoTooltipWithTrigger from '../../../components/InfoTooltipWithTrigger'; import InfoTooltipWithTrigger from '../../../components/InfoTooltipWithTrigger';
import BoundsControl from './BoundsControl'; import BoundsControl from './BoundsControl';
@ -102,9 +103,9 @@ export default class TimeSeriesColumnControl extends React.Component {
<Popover id="ts-col-popo" title="Column Configuration"> <Popover id="ts-col-popo" title="Column Configuration">
<div style={{ width: 300 }}> <div style={{ width: 300 }}>
{this.formRow( {this.formRow(
'Label', t('Label'),
'The column header label', t('The column header label'),
'time-lag', 'row-label',
<FormControl <FormControl
value={this.state.label} value={this.state.label}
onChange={this.onTextInputChange.bind(this, 'label')} onChange={this.onTextInputChange.bind(this, 'label')}
@ -113,8 +114,8 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{this.formRow( {this.formRow(
'Tooltip', t('Tooltip'),
'Column header tooltip', t('Column header tooltip'),
'col-tooltip', 'col-tooltip',
<FormControl <FormControl
value={this.state.tooltip} value={this.state.tooltip}
@ -124,8 +125,8 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{this.formRow( {this.formRow(
'Type', t('Type'),
'Type of comparison, value difference or percentage', t('Type of comparison, value difference or percentage'),
'col-type', 'col-type',
<Select <Select
value={this.state.colType} value={this.state.colType}
@ -136,8 +137,8 @@ export default class TimeSeriesColumnControl extends React.Component {
)} )}
<hr /> <hr />
{this.state.colType === 'spark' && this.formRow( {this.state.colType === 'spark' && this.formRow(
'Width', t('Width'),
'Width of the sparkline', t('Width of the sparkline'),
'spark-width', 'spark-width',
<FormControl <FormControl
value={this.state.width} value={this.state.width}
@ -147,8 +148,8 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{this.state.colType === 'spark' && this.formRow( {this.state.colType === 'spark' && this.formRow(
'Height', t('Height'),
'Height of the sparkline', t('Height of the sparkline'),
'spark-width', 'spark-width',
<FormControl <FormControl
value={this.state.height} value={this.state.height}
@ -158,8 +159,8 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{['time', 'avg'].indexOf(this.state.colType) >= 0 && this.formRow( {['time', 'avg'].indexOf(this.state.colType) >= 0 && this.formRow(
'Time Lag', t('Time Lag'),
'Number of periods to compare against', t('Number of periods to compare against'),
'time-lag', 'time-lag',
<FormControl <FormControl
value={this.state.timeLag} value={this.state.timeLag}
@ -169,19 +170,19 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{['spark'].indexOf(this.state.colType) >= 0 && this.formRow( {['spark'].indexOf(this.state.colType) >= 0 && this.formRow(
'Time Ratio', t('Time Ratio'),
'Number of periods to ratio against', t('Number of periods to ratio against'),
'time-ratio', 'time-ratio',
<FormControl <FormControl
value={this.state.timeRatio} value={this.state.timeRatio}
onChange={this.onTextInputChange.bind(this, 'timeRatio')} onChange={this.onTextInputChange.bind(this, 'timeRatio')}
bsSize="small" bsSize="small"
placeholder="Time Lag" placeholder="Time Ratio"
/>, />,
)} )}
{this.state.colType === 'time' && this.formRow( {this.state.colType === 'time' && this.formRow(
'Type', t('Type'),
'Type of comparison, value difference or percentage', t('Type of comparison, value difference or percentage'),
'comp-type', 'comp-type',
<Select <Select
value={this.state.comparisonType} value={this.state.comparisonType}
@ -191,9 +192,9 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{this.state.colType === 'spark' && this.formRow( {this.state.colType === 'spark' && this.formRow(
'Show Y-axis', t('Show Y-axis'),
( t(
'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 on the sparkline. Will display the manually set min/max if set or min/max values in the data otherwise.',
), ),
'show-y-axis-bounds', 'show-y-axis-bounds',
<CheckboxControl <CheckboxControl
@ -202,9 +203,9 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{this.state.colType === 'spark' && this.formRow( {this.state.colType === 'spark' && this.formRow(
'Y-axis bounds', t('Y-axis bounds'),
( t(
'Manually set min/max values for the y-axis.' 'Manually set min/max values for the y-axis.',
), ),
'y-axis-bounds', 'y-axis-bounds',
<BoundsControl <BoundsControl
@ -213,11 +214,11 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{this.state.colType !== 'spark' && this.formRow( {this.state.colType !== 'spark' && this.formRow(
'Color bounds', t('Color bounds'),
( t(
`Number bounds used for color encoding from red to blue. `Number bounds used for color encoding from red to blue.
Reverse the numbers for blue to red. To get pure red or blue, Reverse the numbers for blue to red. To get pure red or blue,
you can enter either only min or max.` you can enter either only min or max.`,
), ),
'bounds', 'bounds',
<BoundsControl <BoundsControl
@ -226,8 +227,8 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{this.formRow( {this.formRow(
'Number format', t('Number format'),
'Optional d3 number format string', t('Optional d3 number format string'),
'd3-format', 'd3-format',
<FormControl <FormControl
value={this.state.d3format} value={this.state.d3format}
@ -237,8 +238,8 @@ export default class TimeSeriesColumnControl extends React.Component {
/>, />,
)} )}
{this.state.colType === 'spark' && this.formRow( {this.state.colType === 'spark' && this.formRow(
'Date format', t('Date format'),
'Optional d3 date format string', t('Optional d3 date format string'),
'date-format', 'date-format',
<FormControl <FormControl
value={this.state.dateFormat} value={this.state.dateFormat}

View File

@ -41,6 +41,7 @@ export default {
description: t( description: t(
"Templated link, it's possible to include {{ metric }} " + "Templated link, it's possible to include {{ metric }} " +
'or other values coming from the controls.'), 'or other values coming from the controls.'),
default: '',
}, },
}, },
}; };

View File

@ -2322,6 +2322,7 @@ export const controls = {
description: t('Filter configuration for the filter box'), description: t('Filter configuration for the filter box'),
validators: [], validators: [],
controlName: 'FilterBoxItemControl', controlName: 'FilterBoxItemControl',
passthroughProps: ['datasource'],
mapStateToProps: ({ datasource }) => ({ datasource }), mapStateToProps: ({ datasource }) => ({ datasource }),
}, },

View File

@ -50,6 +50,9 @@ export default function getClientErrorObject(response) {
resolve({ ...response, error: errorText }); resolve({ ...response, error: errorText });
}); });
}); });
} else if (typeof (response) === 'object' && Object.keys(response).length === 0) {
// Weird empty object that can get converted to string
resolve({ ...response, error: String(response) });
} else { } else {
// fall back to Response.statusText or generic error of we cannot read the response // fall back to Response.statusText or generic error of we cannot read the response
resolve({ ...response, error: response.statusText || t('An error occurred') }); resolve({ ...response, error: response.statusText || t('An error occurred') });