mirror of
https://github.com/apache/superset.git
synced 2024-09-17 11:09:47 -04:00
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:
parent
14647fc2ed
commit
9b4f5ad8e1
@ -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)}
|
||||||
/>
|
/>
|
||||||
|
@ -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}
|
||||||
|
@ -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: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -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 }),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -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') });
|
||||||
|
Loading…
Reference in New Issue
Block a user