Re-enable rule line-between-class-members (#10862)
This commit is contained in:
parent
91b8c8afc9
commit
e28f3d6220
|
|
@ -84,7 +84,6 @@ module.exports = {
|
||||||
'jsx-a11y/anchor-is-valid': 0, // disabled temporarily
|
'jsx-a11y/anchor-is-valid': 0, // disabled temporarily
|
||||||
'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
|
'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
|
||||||
'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
|
'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
|
||||||
'lines-between-class-members': 0, // disabled temporarily
|
|
||||||
'new-cap': 0,
|
'new-cap': 0,
|
||||||
'no-bitwise': 0,
|
'no-bitwise': 0,
|
||||||
'no-continue': 0,
|
'no-continue': 0,
|
||||||
|
|
@ -197,7 +196,6 @@ module.exports = {
|
||||||
'jsx-a11y/anchor-is-valid': 0, // disabled temporarily
|
'jsx-a11y/anchor-is-valid': 0, // disabled temporarily
|
||||||
'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
|
'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
|
||||||
'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
|
'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
|
||||||
'lines-between-class-members': 0, // disabled temporarily
|
|
||||||
'new-cap': 0,
|
'new-cap': 0,
|
||||||
'no-bitwise': 0,
|
'no-bitwise': 0,
|
||||||
'no-continue': 0,
|
'no-continue': 0,
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
this.renderTableBody = this.renderTableBody.bind(this);
|
this.renderTableBody = this.renderTableBody.bind(this);
|
||||||
this.changeCollection = this.changeCollection.bind(this);
|
this.changeCollection = this.changeCollection.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps: CRUDCollectionProps) {
|
UNSAFE_componentWillReceiveProps(nextProps: CRUDCollectionProps) {
|
||||||
if (nextProps.collection !== this.props.collection) {
|
if (nextProps.collection !== this.props.collection) {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
|
@ -85,6 +86,7 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onCellChange(id: number, col: string, val: boolean) {
|
onCellChange(id: number, col: string, val: boolean) {
|
||||||
this.changeCollection({
|
this.changeCollection({
|
||||||
...this.state.collection,
|
...this.state.collection,
|
||||||
|
|
@ -94,6 +96,7 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onAddItem() {
|
onAddItem() {
|
||||||
if (this.props.itemGenerator) {
|
if (this.props.itemGenerator) {
|
||||||
let newItem = this.props.itemGenerator();
|
let newItem = this.props.itemGenerator();
|
||||||
|
|
@ -106,12 +109,14 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onFieldsetChange(item: any) {
|
onFieldsetChange(item: any) {
|
||||||
this.changeCollection({
|
this.changeCollection({
|
||||||
...this.state.collection,
|
...this.state.collection,
|
||||||
[item.id]: item,
|
[item.id]: item,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getLabel(col: any) {
|
getLabel(col: any) {
|
||||||
const { columnLabels } = this.props;
|
const { columnLabels } = this.props;
|
||||||
let label = columnLabels && columnLabels[col] ? columnLabels[col] : col;
|
let label = columnLabels && columnLabels[col] ? columnLabels[col] : col;
|
||||||
|
|
@ -121,17 +126,20 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
}
|
}
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
changeCollection(collection: any) {
|
changeCollection(collection: any) {
|
||||||
this.setState({ collection });
|
this.setState({ collection });
|
||||||
if (this.props.onChange) {
|
if (this.props.onChange) {
|
||||||
this.props.onChange(Object.keys(collection).map(k => collection[k]));
|
this.props.onChange(Object.keys(collection).map(k => collection[k]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteItem(id: number) {
|
deleteItem(id: number) {
|
||||||
const newColl = { ...this.state.collection };
|
const newColl = { ...this.state.collection };
|
||||||
delete newColl[id];
|
delete newColl[id];
|
||||||
this.changeCollection(newColl);
|
this.changeCollection(newColl);
|
||||||
}
|
}
|
||||||
|
|
||||||
effectiveTableColumns() {
|
effectiveTableColumns() {
|
||||||
const { tableColumns, allowDeletes, expandFieldset } = this.props;
|
const { tableColumns, allowDeletes, expandFieldset } = this.props;
|
||||||
const cols = allowDeletes
|
const cols = allowDeletes
|
||||||
|
|
@ -139,6 +147,7 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
: tableColumns;
|
: tableColumns;
|
||||||
return expandFieldset ? ['__expand'].concat(cols) : cols;
|
return expandFieldset ? ['__expand'].concat(cols) : cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleExpand(id: any) {
|
toggleExpand(id: any) {
|
||||||
this.onCellChange(id, '__expanded', false);
|
this.onCellChange(id, '__expanded', false);
|
||||||
this.setState({
|
this.setState({
|
||||||
|
|
@ -148,6 +157,7 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHeaderRow() {
|
renderHeaderRow() {
|
||||||
const cols = this.effectiveTableColumns();
|
const cols = this.effectiveTableColumns();
|
||||||
const {
|
const {
|
||||||
|
|
@ -178,6 +188,7 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
</thead>
|
</thead>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderExpandableSection(item: any) {
|
renderExpandableSection(item: any) {
|
||||||
const propsGenerator = () => ({ item, onChange: this.onFieldsetChange });
|
const propsGenerator = () => ({ item, onChange: this.onFieldsetChange });
|
||||||
return recurseReactClone(
|
return recurseReactClone(
|
||||||
|
|
@ -186,12 +197,14 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
propsGenerator,
|
propsGenerator,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCell(record: any, col: any) {
|
renderCell(record: any, col: any) {
|
||||||
const renderer = this.props.itemRenderers && this.props.itemRenderers[col];
|
const renderer = this.props.itemRenderers && this.props.itemRenderers[col];
|
||||||
const val = record[col];
|
const val = record[col];
|
||||||
const onChange = this.onCellChange.bind(this, record.id, col);
|
const onChange = this.onCellChange.bind(this, record.id, col);
|
||||||
return renderer ? renderer(val, onChange, this.getLabel(col), record) : val;
|
return renderer ? renderer(val, onChange, this.getLabel(col), record) : val;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderItem(record: any) {
|
renderItem(record: any) {
|
||||||
const {
|
const {
|
||||||
allowAddItem,
|
allowAddItem,
|
||||||
|
|
@ -258,6 +271,7 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
}
|
}
|
||||||
return trs;
|
return trs;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEmptyCell() {
|
renderEmptyCell() {
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -265,6 +279,7 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTableBody() {
|
renderTableBody() {
|
||||||
const data = Object.keys(this.state.collection).map(
|
const data = Object.keys(this.state.collection).map(
|
||||||
k => this.state.collection[k],
|
k => this.state.collection[k],
|
||||||
|
|
@ -274,6 +289,7 @@ export default class CRUDCollection extends React.PureComponent<
|
||||||
: this.renderEmptyCell();
|
: this.renderEmptyCell();
|
||||||
return <tbody>{content}</tbody>;
|
return <tbody>{content}</tbody>;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="CRUD">
|
<div className="CRUD">
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,11 @@ export default class Field extends React.PureComponent {
|
||||||
super(props);
|
super(props);
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(newValue) {
|
onChange(newValue) {
|
||||||
this.props.onChange(this.props.fieldKey, newValue);
|
this.props.onChange(this.props.fieldKey, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
compact,
|
compact,
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,14 @@ export default class Fieldset extends React.PureComponent {
|
||||||
super(props);
|
super(props);
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(fieldKey, val) {
|
onChange(fieldKey, val) {
|
||||||
return this.props.onChange({
|
return this.props.onChange({
|
||||||
...this.props.item,
|
...this.props.item,
|
||||||
[fieldKey]: val,
|
[fieldKey]: val,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { title } = this.props;
|
const { title } = this.props;
|
||||||
const propExtender = field => ({
|
const propExtender = field => ({
|
||||||
|
|
|
||||||
|
|
@ -83,11 +83,13 @@ class AceEditorWrapper extends React.PureComponent<Props, State> {
|
||||||
};
|
};
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// Making sure no text is selected from previous mount
|
// Making sure no text is selected from previous mount
|
||||||
this.props.actions.queryEditorSetSelectedText(this.props.queryEditor, null);
|
this.props.actions.queryEditorSetSelectedText(this.props.queryEditor, null);
|
||||||
this.setAutoCompleter(this.props);
|
this.setAutoCompleter(this.props);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps: Props) {
|
UNSAFE_componentWillReceiveProps(nextProps: Props) {
|
||||||
if (
|
if (
|
||||||
!areArraysShallowEqual(this.props.tables, nextProps.tables) ||
|
!areArraysShallowEqual(this.props.tables, nextProps.tables) ||
|
||||||
|
|
@ -103,12 +105,15 @@ class AceEditorWrapper extends React.PureComponent<Props, State> {
|
||||||
this.setState({ sql: nextProps.sql });
|
this.setState({ sql: nextProps.sql });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onBlur() {
|
onBlur() {
|
||||||
this.props.onBlur(this.state.sql);
|
this.props.onBlur(this.state.sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAltEnter() {
|
onAltEnter() {
|
||||||
this.props.onBlur(this.state.sql);
|
this.props.onBlur(this.state.sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
onEditorLoad(editor: any) {
|
onEditorLoad(editor: any) {
|
||||||
editor.commands.addCommand({
|
editor.commands.addCommand({
|
||||||
name: 'runQuery',
|
name: 'runQuery',
|
||||||
|
|
@ -140,10 +145,12 @@ class AceEditorWrapper extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(text: string) {
|
onChange(text: string) {
|
||||||
this.setState({ sql: text });
|
this.setState({ sql: text });
|
||||||
this.props.onChange(text);
|
this.props.onChange(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCompletions(
|
getCompletions(
|
||||||
aceEditor: any,
|
aceEditor: any,
|
||||||
session: any,
|
session: any,
|
||||||
|
|
@ -180,6 +187,7 @@ class AceEditorWrapper extends React.PureComponent<Props, State> {
|
||||||
});
|
});
|
||||||
callback(null, words);
|
callback(null, words);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAutoCompleter(props: Props) {
|
setAutoCompleter(props: Props) {
|
||||||
// Loading schema, table and column names as auto-completable words
|
// Loading schema, table and column names as auto-completable words
|
||||||
const schemas = props.schemas || [];
|
const schemas = props.schemas || [];
|
||||||
|
|
@ -236,6 +244,7 @@ class AceEditorWrapper extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getAceAnnotations() {
|
getAceAnnotations() {
|
||||||
const { validationResult } = this.props.queryEditor;
|
const { validationResult } = this.props.queryEditor;
|
||||||
const resultIsReady = validationResult && validationResult.completed;
|
const resultIsReady = validationResult && validationResult.completed;
|
||||||
|
|
@ -250,6 +259,7 @@ class AceEditorWrapper extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<AceEditor
|
<AceEditor
|
||||||
|
|
|
||||||
|
|
@ -48,12 +48,14 @@ class App extends React.PureComponent {
|
||||||
{ trailing: false },
|
{ trailing: false },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
/* eslint-disable react/no-did-mount-set-state */
|
/* eslint-disable react/no-did-mount-set-state */
|
||||||
this.setState({ contentHeight: this.getHeight() });
|
this.setState({ contentHeight: this.getHeight() });
|
||||||
window.addEventListener('hashchange', this.onHashChanged.bind(this));
|
window.addEventListener('hashchange', this.onHashChanged.bind(this));
|
||||||
window.addEventListener('resize', this.handleResize.bind(this));
|
window.addEventListener('resize', this.handleResize.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
if (
|
if (
|
||||||
this.props.localStorageUsageInKilobytes >=
|
this.props.localStorageUsageInKilobytes >=
|
||||||
|
|
@ -64,13 +66,16 @@ class App extends React.PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
window.removeEventListener('hashchange', this.onHashChanged.bind(this));
|
window.removeEventListener('hashchange', this.onHashChanged.bind(this));
|
||||||
window.removeEventListener('resize', this.handleResize.bind(this));
|
window.removeEventListener('resize', this.handleResize.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
onHashChanged() {
|
onHashChanged() {
|
||||||
this.setState({ hash: window.location.hash });
|
this.setState({ hash: window.location.hash });
|
||||||
}
|
}
|
||||||
|
|
||||||
getHeight() {
|
getHeight() {
|
||||||
const warningEl = $('#navbar-warning');
|
const warningEl = $('#navbar-warning');
|
||||||
const tabsEl = $('.nav-tabs');
|
const tabsEl = $('.nav-tabs');
|
||||||
|
|
@ -96,6 +101,7 @@ class App extends React.PureComponent {
|
||||||
alertHeight
|
alertHeight
|
||||||
}px`;
|
}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
showLocalStorageUsageWarning(currentUsage) {
|
showLocalStorageUsageWarning(currentUsage) {
|
||||||
this.props.actions.addDangerToast(
|
this.props.actions.addDangerToast(
|
||||||
t(
|
t(
|
||||||
|
|
@ -109,9 +115,11 @@ class App extends React.PureComponent {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleResize() {
|
handleResize() {
|
||||||
this.setState({ contentHeight: this.getHeight() });
|
this.setState({ contentHeight: this.getHeight() });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let content;
|
let content;
|
||||||
if (this.state.hash) {
|
if (this.state.hash) {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ class ExploreCtasResultsButton extends React.PureComponent {
|
||||||
this.visualize = this.visualize.bind(this);
|
this.visualize = this.visualize.bind(this);
|
||||||
this.onClick = this.onClick.bind(this);
|
this.onClick = this.onClick.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClick() {
|
onClick() {
|
||||||
this.visualize();
|
this.visualize();
|
||||||
}
|
}
|
||||||
|
|
@ -59,6 +60,7 @@ class ExploreCtasResultsButton extends React.PureComponent {
|
||||||
templateParams: this.props.templateParams,
|
templateParams: this.props.templateParams,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
visualize() {
|
visualize() {
|
||||||
this.props.actions
|
this.props.actions
|
||||||
.createCtasDatasource(this.buildVizOptions())
|
.createCtasDatasource(this.buildVizOptions())
|
||||||
|
|
@ -85,6 +87,7 @@ class ExploreCtasResultsButton extends React.PureComponent {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ class ExploreResultsButton extends React.PureComponent {
|
||||||
this,
|
this,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClick() {
|
onClick() {
|
||||||
const { timeout } = this.props;
|
const { timeout } = this.props;
|
||||||
const msg = this.renderInvalidColumnMessage();
|
const msg = this.renderInvalidColumnMessage();
|
||||||
|
|
@ -85,6 +86,7 @@ class ExploreResultsButton extends React.PureComponent {
|
||||||
this.visualize();
|
this.visualize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getColumns() {
|
getColumns() {
|
||||||
const { props } = this;
|
const { props } = this;
|
||||||
if (
|
if (
|
||||||
|
|
@ -96,11 +98,13 @@ class ExploreResultsButton extends React.PureComponent {
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
getQueryDuration() {
|
getQueryDuration() {
|
||||||
return moment
|
return moment
|
||||||
.duration(this.props.query.endDttm - this.props.query.startDttm)
|
.duration(this.props.query.endDttm - this.props.query.startDttm)
|
||||||
.asSeconds();
|
.asSeconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
getInvalidColumns() {
|
getInvalidColumns() {
|
||||||
const re1 = /__\d+$/; // duplicate column name pattern
|
const re1 = /__\d+$/; // duplicate column name pattern
|
||||||
const re2 = /^__timestamp/i; // reserved temporal column alias
|
const re2 = /^__timestamp/i; // reserved temporal column alias
|
||||||
|
|
@ -109,6 +113,7 @@ class ExploreResultsButton extends React.PureComponent {
|
||||||
.map(col => col.name)
|
.map(col => col.name)
|
||||||
.filter(col => re1.test(col) || re2.test(col));
|
.filter(col => re1.test(col) || re2.test(col));
|
||||||
}
|
}
|
||||||
|
|
||||||
datasourceName() {
|
datasourceName() {
|
||||||
const { query } = this.props;
|
const { query } = this.props;
|
||||||
const uniqueId = shortid.generate();
|
const uniqueId = shortid.generate();
|
||||||
|
|
@ -119,6 +124,7 @@ class ExploreResultsButton extends React.PureComponent {
|
||||||
}
|
}
|
||||||
return datasourceName;
|
return datasourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildVizOptions() {
|
buildVizOptions() {
|
||||||
const { schema, sql, dbId, templateParams } = this.props.query;
|
const { schema, sql, dbId, templateParams } = this.props.query;
|
||||||
return {
|
return {
|
||||||
|
|
@ -130,6 +136,7 @@ class ExploreResultsButton extends React.PureComponent {
|
||||||
columns: this.getColumns(),
|
columns: this.getColumns(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
visualize() {
|
visualize() {
|
||||||
this.props.actions
|
this.props.actions
|
||||||
.createDatasource(this.buildVizOptions())
|
.createDatasource(this.buildVizOptions())
|
||||||
|
|
@ -158,6 +165,7 @@ class ExploreResultsButton extends React.PureComponent {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTimeoutWarning() {
|
renderTimeoutWarning() {
|
||||||
return (
|
return (
|
||||||
<Alert bsStyle="warning">
|
<Alert bsStyle="warning">
|
||||||
|
|
@ -181,6 +189,7 @@ class ExploreResultsButton extends React.PureComponent {
|
||||||
</Alert>
|
</Alert>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderInvalidColumnMessage() {
|
renderInvalidColumnMessage() {
|
||||||
const invalidColumns = this.getInvalidColumns();
|
const invalidColumns = this.getInvalidColumns();
|
||||||
if (invalidColumns.length === 0) {
|
if (invalidColumns.length === 0) {
|
||||||
|
|
@ -200,6 +209,7 @@ class ExploreResultsButton extends React.PureComponent {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const allowsSubquery =
|
const allowsSubquery =
|
||||||
this.props.database && this.props.database.allows_subquery;
|
this.props.database && this.props.database.allows_subquery;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ class HighlightedSql extends React.Component {
|
||||||
modalBody: null,
|
modalBody: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
shrinkSql() {
|
shrinkSql() {
|
||||||
const ssql = this.props.sql || '';
|
const ssql = this.props.sql || '';
|
||||||
let lines = ssql.split('\n');
|
let lines = ssql.split('\n');
|
||||||
|
|
@ -66,6 +67,7 @@ class HighlightedSql extends React.Component {
|
||||||
})
|
})
|
||||||
.join('\n');
|
.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerNode() {
|
triggerNode() {
|
||||||
const shownSql = this.props.shrink
|
const shownSql = this.props.shrink
|
||||||
? this.shrinkSql(this.props.sql)
|
? this.shrinkSql(this.props.sql)
|
||||||
|
|
@ -76,6 +78,7 @@ class HighlightedSql extends React.Component {
|
||||||
</SyntaxHighlighter>
|
</SyntaxHighlighter>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
generateModal() {
|
generateModal() {
|
||||||
let rawSql;
|
let rawSql;
|
||||||
if (this.props.rawSql && this.props.rawSql !== this.props.sql) {
|
if (this.props.rawSql && this.props.rawSql !== this.props.sql) {
|
||||||
|
|
@ -100,6 +103,7 @@ class HighlightedSql extends React.Component {
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<ModalTrigger
|
<ModalTrigger
|
||||||
|
|
|
||||||
|
|
@ -36,17 +36,21 @@ class QueryAutoRefresh extends React.PureComponent {
|
||||||
offline: props.offline,
|
offline: props.offline,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillMount() {
|
UNSAFE_componentWillMount() {
|
||||||
this.startTimer();
|
this.startTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
if (prevProps.offline !== this.state.offline) {
|
if (prevProps.offline !== this.state.offline) {
|
||||||
this.props.actions.setUserOffline(this.state.offline);
|
this.props.actions.setUserOffline(this.state.offline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.stopTimer();
|
this.stopTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldCheckForQueries() {
|
shouldCheckForQueries() {
|
||||||
// if there are started or running queries, this method should return true
|
// if there are started or running queries, this method should return true
|
||||||
const { queries } = this.props;
|
const { queries } = this.props;
|
||||||
|
|
@ -58,15 +62,18 @@ class QueryAutoRefresh extends React.PureComponent {
|
||||||
q => isQueryRunning(q) && now - q.startDttm < MAX_QUERY_AGE_TO_POLL,
|
q => isQueryRunning(q) && now - q.startDttm < MAX_QUERY_AGE_TO_POLL,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
startTimer() {
|
startTimer() {
|
||||||
if (!this.timer) {
|
if (!this.timer) {
|
||||||
this.timer = setInterval(this.stopwatch.bind(this), QUERY_UPDATE_FREQ);
|
this.timer = setInterval(this.stopwatch.bind(this), QUERY_UPDATE_FREQ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stopTimer() {
|
stopTimer() {
|
||||||
clearInterval(this.timer);
|
clearInterval(this.timer);
|
||||||
this.timer = null;
|
this.timer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
stopwatch() {
|
stopwatch() {
|
||||||
// only poll /superset/queries/ if there are started or running queries
|
// only poll /superset/queries/ if there are started or running queries
|
||||||
if (this.shouldCheckForQueries()) {
|
if (this.shouldCheckForQueries()) {
|
||||||
|
|
@ -89,6 +96,7 @@ class QueryAutoRefresh extends React.PureComponent {
|
||||||
this.setState({ offline: false });
|
this.setState({ offline: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,15 +60,19 @@ class QueryTable extends React.PureComponent {
|
||||||
openQueryInNewTab(query) {
|
openQueryInNewTab(query) {
|
||||||
this.props.actions.cloneQueryToNewTab(query, true);
|
this.props.actions.cloneQueryToNewTab(query, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
openAsyncResults(query, displayLimit) {
|
openAsyncResults(query, displayLimit) {
|
||||||
this.props.actions.fetchQueryResults(query, displayLimit);
|
this.props.actions.fetchQueryResults(query, displayLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearQueryResults(query) {
|
clearQueryResults(query) {
|
||||||
this.props.actions.clearQueryResults(query);
|
this.props.actions.clearQueryResults(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeQuery(query) {
|
removeQuery(query) {
|
||||||
this.props.actions.removeQuery(query);
|
this.props.actions.removeQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const data = this.props.queries
|
const data = this.props.queries
|
||||||
.map(query => {
|
.map(query => {
|
||||||
|
|
|
||||||
|
|
@ -86,10 +86,12 @@ export default class ResultSet extends React.PureComponent<
|
||||||
this,
|
this,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// only do this the first time the component is rendered/mounted
|
// only do this the first time the component is rendered/mounted
|
||||||
this.reRunQueryIfSessionTimeoutErrorOnMount();
|
this.reRunQueryIfSessionTimeoutErrorOnMount();
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps: ResultSetProps) {
|
UNSAFE_componentWillReceiveProps(nextProps: ResultSetProps) {
|
||||||
// when new results comes in, save them locally and clear in store
|
// when new results comes in, save them locally and clear in store
|
||||||
if (
|
if (
|
||||||
|
|
@ -110,9 +112,11 @@ export default class ResultSet extends React.PureComponent<
|
||||||
this.fetchResults(nextProps.query);
|
this.fetchResults(nextProps.query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clearQueryResults(query: Query) {
|
clearQueryResults(query: Query) {
|
||||||
this.props.actions.clearQueryResults(query);
|
this.props.actions.clearQueryResults(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
popSelectStar(tempSchema: string | null, tempTable: string) {
|
popSelectStar(tempSchema: string | null, tempTable: string) {
|
||||||
const qe = {
|
const qe = {
|
||||||
id: shortid.generate(),
|
id: shortid.generate(),
|
||||||
|
|
@ -123,20 +127,25 @@ export default class ResultSet extends React.PureComponent<
|
||||||
};
|
};
|
||||||
this.props.actions.addQueryEditor(qe);
|
this.props.actions.addQueryEditor(qe);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleExploreResultsButton() {
|
toggleExploreResultsButton() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showExploreResultsButton: !this.state.showExploreResultsButton,
|
showExploreResultsButton: !this.state.showExploreResultsButton,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changeSearch(event: React.ChangeEvent<HTMLInputElement>) {
|
changeSearch(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
this.setState({ searchText: event.target.value });
|
this.setState({ searchText: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchResults(query: Query) {
|
fetchResults(query: Query) {
|
||||||
this.props.actions.fetchQueryResults(query, this.props.displayLimit);
|
this.props.actions.fetchQueryResults(query, this.props.displayLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
reFetchQueryResults(query: Query) {
|
reFetchQueryResults(query: Query) {
|
||||||
this.props.actions.reFetchQueryResults(query);
|
this.props.actions.reFetchQueryResults(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
reRunQueryIfSessionTimeoutErrorOnMount() {
|
reRunQueryIfSessionTimeoutErrorOnMount() {
|
||||||
const { query } = this.props;
|
const { query } = this.props;
|
||||||
if (
|
if (
|
||||||
|
|
@ -146,6 +155,7 @@ export default class ResultSet extends React.PureComponent<
|
||||||
this.props.actions.runQuery(query, true);
|
this.props.actions.runQuery(query, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderControls() {
|
renderControls() {
|
||||||
if (this.props.search || this.props.visualize || this.props.csv) {
|
if (this.props.search || this.props.visualize || this.props.csv) {
|
||||||
let { data } = this.props.query.results;
|
let { data } = this.props.query.results;
|
||||||
|
|
@ -198,6 +208,7 @@ export default class ResultSet extends React.PureComponent<
|
||||||
}
|
}
|
||||||
return <div className="noControls" />;
|
return <div className="noControls" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { query } = this.props;
|
const { query } = this.props;
|
||||||
const height = Math.max(
|
const height = Math.max(
|
||||||
|
|
|
||||||
|
|
@ -55,23 +55,29 @@ class SaveQuery extends React.PureComponent {
|
||||||
this.onLabelChange = this.onLabelChange.bind(this);
|
this.onLabelChange = this.onLabelChange.bind(this);
|
||||||
this.onDescriptionChange = this.onDescriptionChange.bind(this);
|
this.onDescriptionChange = this.onDescriptionChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSave() {
|
onSave() {
|
||||||
this.props.onSave(this.queryPayload());
|
this.props.onSave(this.queryPayload());
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdate() {
|
onUpdate() {
|
||||||
this.props.onUpdate(this.queryPayload());
|
this.props.onUpdate(this.queryPayload());
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
onCancel() {
|
onCancel() {
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
onLabelChange(e) {
|
onLabelChange(e) {
|
||||||
this.setState({ label: e.target.value });
|
this.setState({ label: e.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
onDescriptionChange(e) {
|
onDescriptionChange(e) {
|
||||||
this.setState({ description: e.target.value });
|
this.setState({ description: e.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
queryPayload() {
|
queryPayload() {
|
||||||
return {
|
return {
|
||||||
...this.props.query,
|
...this.props.query,
|
||||||
|
|
@ -79,12 +85,15 @@ class SaveQuery extends React.PureComponent {
|
||||||
description: this.state.description,
|
description: this.state.description,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
if (this.saveModal) this.saveModal.close();
|
if (this.saveModal) this.saveModal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSave() {
|
toggleSave() {
|
||||||
this.setState({ showSave: !this.state.showSave });
|
this.setState({ showSave: !this.state.showSave });
|
||||||
}
|
}
|
||||||
|
|
||||||
renderModalBody() {
|
renderModalBody() {
|
||||||
const isSaved = !!this.props.query.remoteId;
|
const isSaved = !!this.props.query.remoteId;
|
||||||
return (
|
return (
|
||||||
|
|
@ -157,6 +166,7 @@ class SaveQuery extends React.PureComponent {
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<span className="SaveQuery">
|
<span className="SaveQuery">
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ class ScheduleQueryButton extends React.PureComponent {
|
||||||
this.onLabelChange = this.onLabelChange.bind(this);
|
this.onLabelChange = this.onLabelChange.bind(this);
|
||||||
this.onDescriptionChange = this.onDescriptionChange.bind(this);
|
this.onDescriptionChange = this.onDescriptionChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSchedule({ formData }) {
|
onSchedule({ formData }) {
|
||||||
const query = {
|
const query = {
|
||||||
label: this.state.label,
|
label: this.state.label,
|
||||||
|
|
@ -118,18 +119,23 @@ class ScheduleQueryButton extends React.PureComponent {
|
||||||
this.props.onSchedule(query);
|
this.props.onSchedule(query);
|
||||||
this.saveModal.close();
|
this.saveModal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
onCancel() {
|
onCancel() {
|
||||||
this.saveModal.close();
|
this.saveModal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
onLabelChange(e) {
|
onLabelChange(e) {
|
||||||
this.setState({ label: e.target.value });
|
this.setState({ label: e.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
onDescriptionChange(e) {
|
onDescriptionChange(e) {
|
||||||
this.setState({ description: e.target.value });
|
this.setState({ description: e.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSchedule() {
|
toggleSchedule() {
|
||||||
this.setState({ showSchedule: !this.state.showSchedule });
|
this.setState({ showSchedule: !this.state.showSchedule });
|
||||||
}
|
}
|
||||||
|
|
||||||
renderModalBody() {
|
renderModalBody() {
|
||||||
return (
|
return (
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
|
|
@ -181,6 +187,7 @@ class ScheduleQueryButton extends React.PureComponent {
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<span className="ScheduleQueryButton">
|
<span className="ScheduleQueryButton">
|
||||||
|
|
|
||||||
|
|
@ -68,19 +68,23 @@ export class SouthPane extends React.PureComponent {
|
||||||
this.getSouthPaneHeight = this.getSouthPaneHeight.bind(this);
|
this.getSouthPaneHeight = this.getSouthPaneHeight.bind(this);
|
||||||
this.switchTab = this.switchTab.bind(this);
|
this.switchTab = this.switchTab.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps() {
|
UNSAFE_componentWillReceiveProps() {
|
||||||
// south pane expands the entire height of the tab content on mount
|
// south pane expands the entire height of the tab content on mount
|
||||||
this.setState({ height: this.getSouthPaneHeight() });
|
this.setState({ height: this.getSouthPaneHeight() });
|
||||||
}
|
}
|
||||||
|
|
||||||
// One layer of abstraction for easy spying in unit tests
|
// One layer of abstraction for easy spying in unit tests
|
||||||
getSouthPaneHeight() {
|
getSouthPaneHeight() {
|
||||||
return this.southPaneRef.current
|
return this.southPaneRef.current
|
||||||
? this.southPaneRef.current.clientHeight
|
? this.southPaneRef.current.clientHeight
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switchTab(id) {
|
switchTab(id) {
|
||||||
this.props.actions.setActiveSouthPaneTab(id);
|
this.props.actions.setActiveSouthPaneTab(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.offline) {
|
if (this.props.offline) {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ class SqlEditor extends React.PureComponent {
|
||||||
WINDOW_RESIZE_THROTTLE_MS,
|
WINDOW_RESIZE_THROTTLE_MS,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillMount() {
|
UNSAFE_componentWillMount() {
|
||||||
if (this.state.autorun) {
|
if (this.state.autorun) {
|
||||||
this.setState({ autorun: false });
|
this.setState({ autorun: false });
|
||||||
|
|
@ -135,6 +136,7 @@ class SqlEditor extends React.PureComponent {
|
||||||
this.startQuery();
|
this.startQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// We need to measure the height of the sql editor post render to figure the height of
|
// We need to measure the height of the sql editor post render to figure the height of
|
||||||
// the south pane so it gets rendered properly
|
// the south pane so it gets rendered properly
|
||||||
|
|
@ -143,14 +145,17 @@ class SqlEditor extends React.PureComponent {
|
||||||
|
|
||||||
window.addEventListener('resize', this.handleWindowResize);
|
window.addEventListener('resize', this.handleWindowResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
window.removeEventListener('resize', this.handleWindowResize);
|
window.removeEventListener('resize', this.handleWindowResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
onResizeStart() {
|
onResizeStart() {
|
||||||
// Set the heights on the ace editor and the ace content area after drag starts
|
// Set the heights on the ace editor and the ace content area after drag starts
|
||||||
// to smooth out the visual transition to the new heights when drag ends
|
// to smooth out the visual transition to the new heights when drag ends
|
||||||
document.getElementsByClassName('ace_content')[0].style.height = '100%';
|
document.getElementsByClassName('ace_content')[0].style.height = '100%';
|
||||||
}
|
}
|
||||||
|
|
||||||
onResizeEnd([northPercent, southPercent]) {
|
onResizeEnd([northPercent, southPercent]) {
|
||||||
this.setState({ northPercent, southPercent });
|
this.setState({ northPercent, southPercent });
|
||||||
|
|
||||||
|
|
@ -162,6 +167,7 @@ class SqlEditor extends React.PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSqlChanged(sql) {
|
onSqlChanged(sql) {
|
||||||
this.setState({ sql });
|
this.setState({ sql });
|
||||||
this.setQueryEditorSqlWithDebounce(sql);
|
this.setQueryEditorSqlWithDebounce(sql);
|
||||||
|
|
@ -171,12 +177,14 @@ class SqlEditor extends React.PureComponent {
|
||||||
this.requestValidation();
|
this.requestValidation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// One layer of abstraction for easy spying in unit tests
|
// One layer of abstraction for easy spying in unit tests
|
||||||
getSqlEditorHeight() {
|
getSqlEditorHeight() {
|
||||||
return this.sqlEditorRef.current
|
return this.sqlEditorRef.current
|
||||||
? this.sqlEditorRef.current.clientHeight - SQL_EDITOR_PADDING * 2
|
? this.sqlEditorRef.current.clientHeight - SQL_EDITOR_PADDING * 2
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the heights for the ace editor and the south pane as an object
|
// Return the heights for the ace editor and the south pane as an object
|
||||||
// given the height of the sql editor, north pane percent and south pane percent.
|
// given the height of the sql editor, north pane percent and south pane percent.
|
||||||
getAceEditorAndSouthPaneHeights(height, northPercent, southPercent) {
|
getAceEditorAndSouthPaneHeights(height, northPercent, southPercent) {
|
||||||
|
|
@ -190,6 +198,7 @@ class SqlEditor extends React.PureComponent {
|
||||||
(SQL_EDITOR_GUTTER_HEIGHT / 2 + SQL_EDITOR_GUTTER_MARGIN),
|
(SQL_EDITOR_GUTTER_HEIGHT / 2 + SQL_EDITOR_GUTTER_MARGIN),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getHotkeyConfig() {
|
getHotkeyConfig() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
@ -224,15 +233,18 @@ class SqlEditor extends React.PureComponent {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
setQueryEditorSql(sql) {
|
setQueryEditorSql(sql) {
|
||||||
this.props.actions.queryEditorSetSql(this.props.queryEditor, sql);
|
this.props.actions.queryEditorSetSql(this.props.queryEditor, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
setQueryLimit(queryLimit) {
|
setQueryLimit(queryLimit) {
|
||||||
this.props.actions.queryEditorSetQueryLimit(
|
this.props.actions.queryEditorSetQueryLimit(
|
||||||
this.props.queryEditor,
|
this.props.queryEditor,
|
||||||
queryLimit,
|
queryLimit,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getQueryCostEstimate() {
|
getQueryCostEstimate() {
|
||||||
if (this.props.database) {
|
if (this.props.database) {
|
||||||
const qe = this.props.queryEditor;
|
const qe = this.props.queryEditor;
|
||||||
|
|
@ -246,12 +258,15 @@ class SqlEditor extends React.PureComponent {
|
||||||
this.props.actions.estimateQueryCost(query);
|
this.props.actions.estimateQueryCost(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleToggleAutocompleteEnabled = () => {
|
handleToggleAutocompleteEnabled = () => {
|
||||||
this.setState({ autocompleteEnabled: !this.state.autocompleteEnabled });
|
this.setState({ autocompleteEnabled: !this.state.autocompleteEnabled });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleWindowResize() {
|
handleWindowResize() {
|
||||||
this.setState({ height: this.getSqlEditorHeight() });
|
this.setState({ height: this.getSqlEditorHeight() });
|
||||||
}
|
}
|
||||||
|
|
||||||
elementStyle(dimension, elementSize, gutterSize) {
|
elementStyle(dimension, elementSize, gutterSize) {
|
||||||
return {
|
return {
|
||||||
[dimension]: `calc(${elementSize}% - ${
|
[dimension]: `calc(${elementSize}% - ${
|
||||||
|
|
@ -259,6 +274,7 @@ class SqlEditor extends React.PureComponent {
|
||||||
}px)`,
|
}px)`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
requestValidation() {
|
requestValidation() {
|
||||||
if (this.props.database) {
|
if (this.props.database) {
|
||||||
const qe = this.props.queryEditor;
|
const qe = this.props.queryEditor;
|
||||||
|
|
@ -272,6 +288,7 @@ class SqlEditor extends React.PureComponent {
|
||||||
this.props.actions.validateQuery(query);
|
this.props.actions.validateQuery(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canValidateQuery() {
|
canValidateQuery() {
|
||||||
// Check whether or not we can validate the current query based on whether
|
// Check whether or not we can validate the current query based on whether
|
||||||
// or not the backend has a validator configured for it.
|
// or not the backend has a validator configured for it.
|
||||||
|
|
@ -281,11 +298,13 @@ class SqlEditor extends React.PureComponent {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
runQuery() {
|
runQuery() {
|
||||||
if (this.props.database) {
|
if (this.props.database) {
|
||||||
this.startQuery();
|
this.startQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
startQuery(ctas = false, ctas_method = CtasEnum.TABLE) {
|
startQuery(ctas = false, ctas_method = CtasEnum.TABLE) {
|
||||||
const qe = this.props.queryEditor;
|
const qe = this.props.queryEditor;
|
||||||
const query = {
|
const query = {
|
||||||
|
|
@ -307,6 +326,7 @@ class SqlEditor extends React.PureComponent {
|
||||||
this.props.actions.runQuery(query);
|
this.props.actions.runQuery(query);
|
||||||
this.props.actions.setActiveSouthPaneTab('Results');
|
this.props.actions.setActiveSouthPaneTab('Results');
|
||||||
}
|
}
|
||||||
|
|
||||||
stopQuery() {
|
stopQuery() {
|
||||||
if (
|
if (
|
||||||
this.props.latestQuery &&
|
this.props.latestQuery &&
|
||||||
|
|
@ -315,15 +335,19 @@ class SqlEditor extends React.PureComponent {
|
||||||
this.props.actions.postStopQuery(this.props.latestQuery);
|
this.props.actions.postStopQuery(this.props.latestQuery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createTableAs() {
|
createTableAs() {
|
||||||
this.startQuery(true, CtasEnum.TABLE);
|
this.startQuery(true, CtasEnum.TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
createViewAs() {
|
createViewAs() {
|
||||||
this.startQuery(true, CtasEnum.VIEW);
|
this.startQuery(true, CtasEnum.VIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctasChanged(event) {
|
ctasChanged(event) {
|
||||||
this.setState({ ctas: event.target.value });
|
this.setState({ ctas: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
queryPane() {
|
queryPane() {
|
||||||
const hotkeys = this.getHotkeyConfig();
|
const hotkeys = this.getHotkeyConfig();
|
||||||
const {
|
const {
|
||||||
|
|
@ -376,6 +400,7 @@ class SqlEditor extends React.PureComponent {
|
||||||
</Split>
|
</Split>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEditorBottomBar(hotkeys) {
|
renderEditorBottomBar(hotkeys) {
|
||||||
let ctasControls;
|
let ctasControls;
|
||||||
if (
|
if (
|
||||||
|
|
@ -560,6 +585,7 @@ class SqlEditor extends React.PureComponent {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div ref={this.sqlEditorRef} className="SqlEditor">
|
<div ref={this.sqlEditorRef} className="SqlEditor">
|
||||||
|
|
|
||||||
|
|
@ -50,27 +50,33 @@ export default class SqlEditorLeftBar extends React.PureComponent {
|
||||||
this.getDbList = this.getDbList.bind(this);
|
this.getDbList = this.getDbList.bind(this);
|
||||||
this.onTableChange = this.onTableChange.bind(this);
|
this.onTableChange = this.onTableChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSchemaChange(schema) {
|
onSchemaChange(schema) {
|
||||||
this.props.actions.queryEditorSetSchema(this.props.queryEditor, schema);
|
this.props.actions.queryEditorSetSchema(this.props.queryEditor, schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSchemasLoad(schemas) {
|
onSchemasLoad(schemas) {
|
||||||
this.props.actions.queryEditorSetSchemaOptions(
|
this.props.actions.queryEditorSetSchemaOptions(
|
||||||
this.props.queryEditor,
|
this.props.queryEditor,
|
||||||
schemas,
|
schemas,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onTablesLoad(tables) {
|
onTablesLoad(tables) {
|
||||||
this.props.actions.queryEditorSetTableOptions(
|
this.props.actions.queryEditorSetTableOptions(
|
||||||
this.props.queryEditor,
|
this.props.queryEditor,
|
||||||
tables,
|
tables,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDbChange(db) {
|
onDbChange(db) {
|
||||||
this.props.actions.queryEditorSetDb(this.props.queryEditor, db.id);
|
this.props.actions.queryEditorSetDb(this.props.queryEditor, db.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
onTableChange(tableName, schemaName) {
|
onTableChange(tableName, schemaName) {
|
||||||
this.props.actions.addTable(this.props.queryEditor, tableName, schemaName);
|
this.props.actions.addTable(this.props.queryEditor, tableName, schemaName);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDbList(dbs) {
|
getDbList(dbs) {
|
||||||
this.props.actions.setDatabases(dbs);
|
this.props.actions.setDatabases(dbs);
|
||||||
}
|
}
|
||||||
|
|
@ -92,6 +98,7 @@ export default class SqlEditorLeftBar extends React.PureComponent {
|
||||||
resetState() {
|
resetState() {
|
||||||
this.props.actions.resetState();
|
this.props.actions.resetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
changeTable(tableOpt) {
|
changeTable(tableOpt) {
|
||||||
if (!tableOpt) {
|
if (!tableOpt) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -105,6 +112,7 @@ export default class SqlEditorLeftBar extends React.PureComponent {
|
||||||
closePopover(ref) {
|
closePopover(ref) {
|
||||||
this.refs[ref].hide();
|
this.refs[ref].hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const shouldShowReset = window.location.search === '?reset=1';
|
const shouldShowReset = window.location.search === '?reset=1';
|
||||||
const tableMetaDataHeight = this.props.height - 130; // 130 is the height of the selects above
|
const tableMetaDataHeight = this.props.height - 130; // 130 is the height of the selects above
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||||
);
|
);
|
||||||
this.duplicateQueryEditor = this.duplicateQueryEditor.bind(this);
|
this.duplicateQueryEditor = this.duplicateQueryEditor.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// migrate query editor and associated tables state to server
|
// migrate query editor and associated tables state to server
|
||||||
if (isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)) {
|
if (isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)) {
|
||||||
|
|
@ -168,6 +169,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||||
const nextActiveQeId =
|
const nextActiveQeId =
|
||||||
nextProps.tabHistory[nextProps.tabHistory.length - 1];
|
nextProps.tabHistory[nextProps.tabHistory.length - 1];
|
||||||
|
|
@ -201,11 +203,13 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||||
this.setState({ dataPreviewQueries });
|
this.setState({ dataPreviewQueries });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
popNewTab() {
|
popNewTab() {
|
||||||
queryCount += 1;
|
queryCount += 1;
|
||||||
// Clean the url in browser history
|
// Clean the url in browser history
|
||||||
window.history.replaceState({}, document.title, this.state.sqlLabUrl);
|
window.history.replaceState({}, document.title, this.state.sqlLabUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
renameTab(qe) {
|
renameTab(qe) {
|
||||||
/* eslint no-alert: 0 */
|
/* eslint no-alert: 0 */
|
||||||
const newTitle = prompt(t('Enter a new title for the tab'));
|
const newTitle = prompt(t('Enter a new title for the tab'));
|
||||||
|
|
@ -213,6 +217,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||||
this.props.actions.queryEditorSetTitle(qe, newTitle);
|
this.props.actions.queryEditorSetTitle(qe, newTitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
activeQueryEditor() {
|
activeQueryEditor() {
|
||||||
if (this.props.tabHistory.length === 0) {
|
if (this.props.tabHistory.length === 0) {
|
||||||
return this.props.queryEditors[0];
|
return this.props.queryEditors[0];
|
||||||
|
|
@ -220,6 +225,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||||
const qeid = this.props.tabHistory[this.props.tabHistory.length - 1];
|
const qeid = this.props.tabHistory[this.props.tabHistory.length - 1];
|
||||||
return this.props.queryEditors.find(qe => qe.id === qeid) || null;
|
return this.props.queryEditors.find(qe => qe.id === qeid) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
newQueryEditor() {
|
newQueryEditor() {
|
||||||
queryCount += 1;
|
queryCount += 1;
|
||||||
const activeQueryEditor = this.activeQueryEditor();
|
const activeQueryEditor = this.activeQueryEditor();
|
||||||
|
|
@ -244,6 +250,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||||
};
|
};
|
||||||
this.props.actions.addQueryEditor(qe);
|
this.props.actions.addQueryEditor(qe);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSelect(key) {
|
handleSelect(key) {
|
||||||
if (key === 'add_tab') {
|
if (key === 'add_tab') {
|
||||||
this.newQueryEditor();
|
this.newQueryEditor();
|
||||||
|
|
@ -258,20 +265,25 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeQueryEditor(qe) {
|
removeQueryEditor(qe) {
|
||||||
this.props.actions.removeQueryEditor(qe);
|
this.props.actions.removeQueryEditor(qe);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAllOtherQueryEditors(cqe) {
|
removeAllOtherQueryEditors(cqe) {
|
||||||
this.props.queryEditors.forEach(
|
this.props.queryEditors.forEach(
|
||||||
qe => qe !== cqe && this.removeQueryEditor(qe),
|
qe => qe !== cqe && this.removeQueryEditor(qe),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
duplicateQueryEditor(qe) {
|
duplicateQueryEditor(qe) {
|
||||||
this.props.actions.cloneQueryToNewTab(qe, false);
|
this.props.actions.cloneQueryToNewTab(qe, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleLeftBar() {
|
toggleLeftBar() {
|
||||||
this.setState({ hideLeftBar: !this.state.hideLeftBar });
|
this.setState({ hideLeftBar: !this.state.hideLeftBar });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const editors = this.props.queryEditors.map((qe, i) => {
|
const editors = this.props.queryEditors.map((qe, i) => {
|
||||||
const isSelected =
|
const isSelected =
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ class TableElement extends React.PureComponent {
|
||||||
this.setState({ expanded: false });
|
this.setState({ expanded: false });
|
||||||
this.props.actions.removeDataPreview(this.props.table);
|
this.props.actions.removeDataPreview(this.props.table);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSortColumns() {
|
toggleSortColumns() {
|
||||||
this.setState({ sortColumns: !this.state.sortColumns });
|
this.setState({ sortColumns: !this.state.sortColumns });
|
||||||
}
|
}
|
||||||
|
|
@ -127,6 +128,7 @@ class TableElement extends React.PureComponent {
|
||||||
}
|
}
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderControls() {
|
renderControls() {
|
||||||
let keyLink;
|
let keyLink;
|
||||||
const { table } = this.props;
|
const { table } = this.props;
|
||||||
|
|
@ -190,6 +192,7 @@ class TableElement extends React.PureComponent {
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHeader() {
|
renderHeader() {
|
||||||
const { table } = this.props;
|
const { table } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|
@ -228,6 +231,7 @@ class TableElement extends React.PureComponent {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderBody() {
|
renderBody() {
|
||||||
const { table } = this.props;
|
const { table } = this.props;
|
||||||
let cols;
|
let cols;
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,11 @@ export default class TemplateParamsEditor extends React.Component {
|
||||||
};
|
};
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.onChange(this.state.codeText);
|
this.onChange(this.state.codeText);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(value) {
|
onChange(value) {
|
||||||
const codeText = value;
|
const codeText = value;
|
||||||
let isValid;
|
let isValid;
|
||||||
|
|
@ -75,6 +77,7 @@ export default class TemplateParamsEditor extends React.Component {
|
||||||
this.props.onChange(newValue);
|
this.props.onChange(newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDoc() {
|
renderDoc() {
|
||||||
return (
|
return (
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -96,6 +99,7 @@ export default class TemplateParamsEditor extends React.Component {
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderModalBody() {
|
renderModalBody() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -115,6 +119,7 @@ export default class TemplateParamsEditor extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const paramCount = this.state.parsedJSON
|
const paramCount = this.state.parsedJSON
|
||||||
? Object.keys(this.state.parsedJSON).length
|
? Object.keys(this.state.parsedJSON).length
|
||||||
|
|
|
||||||
|
|
@ -124,10 +124,15 @@ export default class FilterableTable extends PureComponent<
|
||||||
};
|
};
|
||||||
|
|
||||||
list: List<Datum>;
|
list: List<Datum>;
|
||||||
|
|
||||||
complexColumns: Record<string, boolean>;
|
complexColumns: Record<string, boolean>;
|
||||||
|
|
||||||
widthsForColumnsByKey: Record<string, number>;
|
widthsForColumnsByKey: Record<string, number>;
|
||||||
|
|
||||||
totalTableWidth: number;
|
totalTableWidth: number;
|
||||||
|
|
||||||
totalTableHeight: number;
|
totalTableHeight: number;
|
||||||
|
|
||||||
container: React.RefObject<HTMLDivElement>;
|
container: React.RefObject<HTMLDivElement>;
|
||||||
|
|
||||||
constructor(props: FilterableTableProps) {
|
constructor(props: FilterableTableProps) {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ class FlashProvider extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return this.props.children;
|
return this.props.children;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ export default class Hotkeys extends React.PureComponent {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPopover() {
|
renderPopover() {
|
||||||
const { header, hotkeys } = this.props;
|
const { header, hotkeys } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|
@ -70,6 +71,7 @@ export default class Hotkeys extends React.PureComponent {
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<OverlayTrigger
|
<OverlayTrigger
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ export default class ModalTrigger extends React.Component {
|
||||||
this.props.beforeOpen();
|
this.props.beforeOpen();
|
||||||
this.setState(() => ({ showModal: true }));
|
this.setState(() => ({ showModal: true }));
|
||||||
}
|
}
|
||||||
|
|
||||||
renderModal() {
|
renderModal() {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
|
|
||||||
|
|
@ -124,9 +124,13 @@ const PaginationList = styled.ul`
|
||||||
|
|
||||||
export default class Pagination extends PureComponent<PaginationProps> {
|
export default class Pagination extends PureComponent<PaginationProps> {
|
||||||
static Next = Next;
|
static Next = Next;
|
||||||
|
|
||||||
static Prev = Prev;
|
static Prev = Prev;
|
||||||
|
|
||||||
static Item = Item;
|
static Item = Item;
|
||||||
|
|
||||||
static Ellipsis = Ellipsis;
|
static Ellipsis = Ellipsis;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <PaginationList> {this.props.children}</PaginationList>;
|
return <PaginationList> {this.props.children}</PaginationList>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ class BuilderComponentPane extends React.PureComponent {
|
||||||
</Tabs>
|
</Tabs>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { topOffset } = this.props;
|
const { topOffset } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ class ColorSchemeControlWrapper extends React.PureComponent {
|
||||||
this.choices = this.categoricalSchemeRegistry.keys().map(s => [s, s]);
|
this.choices = this.categoricalSchemeRegistry.keys().map(s => [s, s]);
|
||||||
this.schemes = this.categoricalSchemeRegistry.getMap();
|
this.schemes = this.categoricalSchemeRegistry.getMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
setHover(hovered) {
|
setHover(hovered) {
|
||||||
this.setState({ hovered });
|
this.setState({ hovered });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ class PropertiesModal extends React.PureComponent {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.fetchDashboardDetails();
|
this.fetchDashboardDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
onColorSchemeChange(value) {
|
onColorSchemeChange(value) {
|
||||||
this.updateFormState('colorScheme', value);
|
this.updateFormState('colorScheme', value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -280,6 +280,7 @@ export class DatasourceEditor extends React.PureComponent {
|
||||||
};
|
};
|
||||||
this.props.onChange(datasource, this.state.errors);
|
this.props.onChange(datasource, this.state.errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDatasourceChange(datasource) {
|
onDatasourceChange(datasource) {
|
||||||
this.setState({ datasource }, this.validateAndChange);
|
this.setState({ datasource }, this.validateAndChange);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,12 +68,15 @@ export default class Control extends React.PureComponent {
|
||||||
this.onMouseEnter = this.setHover.bind(this, true);
|
this.onMouseEnter = this.setHover.bind(this, true);
|
||||||
this.onMouseLeave = this.setHover.bind(this, false);
|
this.onMouseLeave = this.setHover.bind(this, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(value, errors) {
|
onChange(value, errors) {
|
||||||
this.props.actions.setControlValue(this.props.name, value, errors);
|
this.props.actions.setControlValue(this.props.name, value, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
setHover(hovered) {
|
setHover(hovered) {
|
||||||
this.setState({ hovered });
|
this.setState({ hovered });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { type, hidden } = this.props;
|
const { type, hidden } = this.props;
|
||||||
if (!type) return null;
|
if (!type) return null;
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ export default class ControlHeader extends React.Component {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.props.label) {
|
if (!this.props.label) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,11 @@ export default class ControlPanelSection extends React.Component {
|
||||||
this.state = { expanded: this.props.startExpanded };
|
this.state = { expanded: this.props.startExpanded };
|
||||||
this.toggleExpand = this.toggleExpand.bind(this);
|
this.toggleExpand = this.toggleExpand.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleExpand() {
|
toggleExpand() {
|
||||||
this.setState({ expanded: !this.state.expanded });
|
this.setState({ expanded: !this.state.expanded });
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHeader() {
|
renderHeader() {
|
||||||
const { label, description, hasErrors } = this.props;
|
const { label, description, hasErrors } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ export class DisplayQueryButton extends React.PureComponent {
|
||||||
this.openPropertiesModal = this.openPropertiesModal.bind(this);
|
this.openPropertiesModal = this.openPropertiesModal.bind(this);
|
||||||
this.closePropertiesModal = this.closePropertiesModal.bind(this);
|
this.closePropertiesModal = this.closePropertiesModal.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeOpen(resultType) {
|
beforeOpen(resultType) {
|
||||||
this.setState({ isLoading: true });
|
this.setState({ isLoading: true });
|
||||||
|
|
||||||
|
|
@ -118,18 +119,23 @@ export class DisplayQueryButton extends React.PureComponent {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changeFilterText(event) {
|
changeFilterText(event) {
|
||||||
this.setState({ filterText: event.target.value });
|
this.setState({ filterText: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
redirectSQLLab() {
|
redirectSQLLab() {
|
||||||
this.props.onOpenInEditor(this.props.latestQueryFormData);
|
this.props.onOpenInEditor(this.props.latestQueryFormData);
|
||||||
}
|
}
|
||||||
|
|
||||||
openPropertiesModal() {
|
openPropertiesModal() {
|
||||||
this.setState({ isPropertiesModalOpen: true });
|
this.setState({ isPropertiesModalOpen: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
closePropertiesModal() {
|
closePropertiesModal() {
|
||||||
this.setState({ isPropertiesModalOpen: false });
|
this.setState({ isPropertiesModalOpen: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
renderQueryModalBody() {
|
renderQueryModalBody() {
|
||||||
if (this.state.isLoading) {
|
if (this.state.isLoading) {
|
||||||
return <Loading />;
|
return <Loading />;
|
||||||
|
|
@ -157,6 +163,7 @@ export class DisplayQueryButton extends React.PureComponent {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderResultsModalBody() {
|
renderResultsModalBody() {
|
||||||
if (this.state.isLoading) {
|
if (this.state.isLoading) {
|
||||||
return <Loading />;
|
return <Loading />;
|
||||||
|
|
@ -172,6 +179,7 @@ export class DisplayQueryButton extends React.PureComponent {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDataTable(data) {
|
renderDataTable(data) {
|
||||||
return (
|
return (
|
||||||
<div style={{ overflow: 'auto' }}>
|
<div style={{ overflow: 'auto' }}>
|
||||||
|
|
@ -213,6 +221,7 @@ export class DisplayQueryButton extends React.PureComponent {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSamplesModalBody() {
|
renderSamplesModalBody() {
|
||||||
if (this.state.isLoading) {
|
if (this.state.isLoading) {
|
||||||
return <Loading />;
|
return <Loading />;
|
||||||
|
|
@ -225,6 +234,7 @@ export class DisplayQueryButton extends React.PureComponent {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { animation, chartHeight, slice } = this.props;
|
const { animation, chartHeight, slice } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,7 @@ export default class EmbedCodeButton extends React.Component {
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<OverlayTrigger
|
<OverlayTrigger
|
||||||
|
|
|
||||||
|
|
@ -283,12 +283,14 @@ class ExploreViewContainer extends React.Component {
|
||||||
toggleModal() {
|
toggleModal() {
|
||||||
this.setState({ showModal: !this.state.showModal });
|
this.setState({ showModal: !this.state.showModal });
|
||||||
}
|
}
|
||||||
|
|
||||||
hasErrors() {
|
hasErrors() {
|
||||||
const ctrls = this.props.controls;
|
const ctrls = this.props.controls;
|
||||||
return Object.keys(ctrls).some(
|
return Object.keys(ctrls).some(
|
||||||
k => ctrls[k].validationErrors && ctrls[k].validationErrors.length > 0,
|
k => ctrls[k].validationErrors && ctrls[k].validationErrors.length > 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderErrorMessage() {
|
renderErrorMessage() {
|
||||||
// Returns an error message as a node if any errors are in the store
|
// Returns an error message as a node if any errors are in the store
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
|
@ -311,6 +313,7 @@ class ExploreViewContainer extends React.Component {
|
||||||
}
|
}
|
||||||
return errorMessage;
|
return errorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderChartContainer() {
|
renderChartContainer() {
|
||||||
return (
|
return (
|
||||||
<ExploreChartPanel
|
<ExploreChartPanel
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ class SaveModal extends React.Component {
|
||||||
this.onDashboardSelectChange = this.onDashboardSelectChange.bind(this);
|
this.onDashboardSelectChange = this.onDashboardSelectChange.bind(this);
|
||||||
this.onSliceNameChange = this.onSliceNameChange.bind(this);
|
this.onSliceNameChange = this.onSliceNameChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.actions.fetchDashboards(this.props.userId).then(() => {
|
this.props.actions.fetchDashboards(this.props.userId).then(() => {
|
||||||
const dashboardIds = this.props.dashboards.map(
|
const dashboardIds = this.props.dashboards.map(
|
||||||
|
|
@ -72,18 +73,22 @@ class SaveModal extends React.Component {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onSliceNameChange(event) {
|
onSliceNameChange(event) {
|
||||||
this.setState({ newSliceName: event.target.value });
|
this.setState({ newSliceName: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
onDashboardSelectChange(event) {
|
onDashboardSelectChange(event) {
|
||||||
const newDashboardName = event ? event.label : null;
|
const newDashboardName = event ? event.label : null;
|
||||||
const saveToDashboardId =
|
const saveToDashboardId =
|
||||||
event && typeof event.value === 'number' ? event.value : null;
|
event && typeof event.value === 'number' ? event.value : null;
|
||||||
this.setState({ saveToDashboardId, newDashboardName });
|
this.setState({ saveToDashboardId, newDashboardName });
|
||||||
}
|
}
|
||||||
|
|
||||||
changeAction(action) {
|
changeAction(action) {
|
||||||
this.setState({ action });
|
this.setState({ action });
|
||||||
}
|
}
|
||||||
|
|
||||||
saveOrOverwrite(gotodash) {
|
saveOrOverwrite(gotodash) {
|
||||||
this.setState({ alert: null });
|
this.setState({ alert: null });
|
||||||
this.props.actions.removeSaveModalAlert();
|
this.props.actions.removeSaveModalAlert();
|
||||||
|
|
@ -117,12 +122,14 @@ class SaveModal extends React.Component {
|
||||||
});
|
});
|
||||||
this.props.onHide();
|
this.props.onHide();
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAlert() {
|
removeAlert() {
|
||||||
if (this.props.alert) {
|
if (this.props.alert) {
|
||||||
this.props.actions.removeSaveModalAlert();
|
this.props.actions.removeSaveModalAlert();
|
||||||
}
|
}
|
||||||
this.setState({ alert: null });
|
this.setState({ alert: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Modal show onHide={this.props.onHide}>
|
<Modal show onHide={this.props.onHide}>
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ export default class BoundsControl extends React.Component {
|
||||||
this.onMinChange = this.onMinChange.bind(this);
|
this.onMinChange = this.onMinChange.bind(this);
|
||||||
this.onMaxChange = this.onMaxChange.bind(this);
|
this.onMaxChange = this.onMaxChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMinChange(event) {
|
onMinChange(event) {
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
|
|
@ -53,6 +54,7 @@ export default class BoundsControl extends React.Component {
|
||||||
this.onChange,
|
this.onChange,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMaxChange(event) {
|
onMaxChange(event) {
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
|
|
@ -61,6 +63,7 @@ export default class BoundsControl extends React.Component {
|
||||||
this.onChange,
|
this.onChange,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange() {
|
onChange() {
|
||||||
const mm = this.state.minMax;
|
const mm = this.state.minMax;
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
|
@ -76,6 +79,7 @@ export default class BoundsControl extends React.Component {
|
||||||
this.props.onChange([null, null], errors);
|
this.props.onChange([null, null], errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ export default class CheckboxControl extends React.Component {
|
||||||
onChange() {
|
onChange() {
|
||||||
this.props.onChange(!this.props.value);
|
this.props.onChange(!this.props.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCheckbox() {
|
renderCheckbox() {
|
||||||
return (
|
return (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|
@ -47,6 +48,7 @@ export default class CheckboxControl extends React.Component {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.label) {
|
if (this.props.label) {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -68,19 +68,24 @@ export default class CollectionControl extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
this.onAdd = this.onAdd.bind(this);
|
this.onAdd = this.onAdd.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(i, value) {
|
onChange(i, value) {
|
||||||
Object.assign(this.props.value[i], value);
|
Object.assign(this.props.value[i], value);
|
||||||
this.props.onChange(this.props.value);
|
this.props.onChange(this.props.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd() {
|
onAdd() {
|
||||||
this.props.onChange(this.props.value.concat([this.props.itemGenerator()]));
|
this.props.onChange(this.props.value.concat([this.props.itemGenerator()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
onSortEnd({ oldIndex, newIndex }) {
|
onSortEnd({ oldIndex, newIndex }) {
|
||||||
this.props.onChange(arrayMove(this.props.value, oldIndex, newIndex));
|
this.props.onChange(arrayMove(this.props.value, oldIndex, newIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
removeItem(i) {
|
removeItem(i) {
|
||||||
this.props.onChange(this.props.value.filter((o, ix) => i !== ix));
|
this.props.onChange(this.props.value.filter((o, ix) => i !== ix));
|
||||||
}
|
}
|
||||||
|
|
||||||
renderList() {
|
renderList() {
|
||||||
if (this.props.value.length === 0) {
|
if (this.props.value.length === 0) {
|
||||||
return <div className="text-muted">{this.props.placeholder}</div>;
|
return <div className="text-muted">{this.props.placeholder}</div>;
|
||||||
|
|
@ -126,6 +131,7 @@ export default class CollectionControl extends React.Component {
|
||||||
</SortableListGroup>
|
</SortableListGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="CollectionControl">
|
<div className="CollectionControl">
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,11 @@ export default class ColorPickerControl extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(col) {
|
onChange(col) {
|
||||||
this.props.onChange(col.rgb);
|
this.props.onChange(col.rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPopover() {
|
renderPopover() {
|
||||||
const presetColors = getCategoricalSchemeRegistry()
|
const presetColors = getCategoricalSchemeRegistry()
|
||||||
.get()
|
.get()
|
||||||
|
|
@ -86,6 +88,7 @@ export default class ColorPickerControl extends React.Component {
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const c = this.props.value || { r: 0, g: 0, b: 0, a: 0 };
|
const c = this.props.value || { r: 0, g: 0, b: 0, a: 0 };
|
||||||
const colStyle = {
|
const colStyle = {
|
||||||
|
|
|
||||||
|
|
@ -238,11 +238,13 @@ class DateFilterControl extends React.Component {
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
document.removeEventListener('click', this.handleClick);
|
document.removeEventListener('click', this.handleClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnter(event) {
|
onEnter(event) {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCustomRange(key, value) {
|
setCustomRange(key, value) {
|
||||||
const updatedState = { ...this.state, [key]: value };
|
const updatedState = { ...this.state, [key]: value };
|
||||||
const combinedValue = [
|
const combinedValue = [
|
||||||
|
|
@ -252,6 +254,7 @@ class DateFilterControl extends React.Component {
|
||||||
].join(' ');
|
].join(' ');
|
||||||
this.setState(getStateFromCustomRange(combinedValue));
|
this.setState(getStateFromCustomRange(combinedValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
setCustomStartEnd(key, value) {
|
setCustomStartEnd(key, value) {
|
||||||
const closeCalendar =
|
const closeCalendar =
|
||||||
(key === 'since' && this.state.sinceViewMode === 'days') ||
|
(key === 'since' && this.state.sinceViewMode === 'days') ||
|
||||||
|
|
@ -265,9 +268,11 @@ class DateFilterControl extends React.Component {
|
||||||
untilViewMode: closeCalendar ? 'days' : this.state.untilViewMode,
|
untilViewMode: closeCalendar ? 'days' : this.state.untilViewMode,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setTypeCustomRange() {
|
setTypeCustomRange() {
|
||||||
this.setState({ type: TYPES.CUSTOM_RANGE });
|
this.setState({ type: TYPES.CUSTOM_RANGE });
|
||||||
}
|
}
|
||||||
|
|
||||||
setTypeCustomStartEnd() {
|
setTypeCustomStartEnd() {
|
||||||
this.setState({ type: TYPES.CUSTOM_START_END });
|
this.setState({ type: TYPES.CUSTOM_START_END });
|
||||||
}
|
}
|
||||||
|
|
@ -325,18 +330,21 @@ class DateFilterControl extends React.Component {
|
||||||
this.refs.trigger.hide();
|
this.refs.trigger.hide();
|
||||||
this.setState({ showSinceCalendar: false, showUntilCalendar: false });
|
this.setState({ showSinceCalendar: false, showUntilCalendar: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
isValidSince(date) {
|
isValidSince(date) {
|
||||||
return (
|
return (
|
||||||
!isValidMoment(this.state.until) ||
|
!isValidMoment(this.state.until) ||
|
||||||
date <= moment(this.state.until, MOMENT_FORMAT)
|
date <= moment(this.state.until, MOMENT_FORMAT)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
isValidUntil(date) {
|
isValidUntil(date) {
|
||||||
return (
|
return (
|
||||||
!isValidMoment(this.state.since) ||
|
!isValidMoment(this.state.since) ||
|
||||||
date >= moment(this.state.since, MOMENT_FORMAT)
|
date >= moment(this.state.since, MOMENT_FORMAT)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCalendar(key) {
|
toggleCalendar(key) {
|
||||||
const nextState = {};
|
const nextState = {};
|
||||||
if (key === 'showSinceCalendar') {
|
if (key === 'showSinceCalendar') {
|
||||||
|
|
@ -352,6 +360,7 @@ class DateFilterControl extends React.Component {
|
||||||
}
|
}
|
||||||
this.setState(nextState);
|
this.setState(nextState);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderInput(props, key) {
|
renderInput(props, key) {
|
||||||
return (
|
return (
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
|
|
@ -372,6 +381,7 @@ class DateFilterControl extends React.Component {
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPopover() {
|
renderPopover() {
|
||||||
const grainOptions = TIME_GRAIN_OPTIONS.map(grain => (
|
const grainOptions = TIME_GRAIN_OPTIONS.map(grain => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|
@ -575,6 +585,7 @@ class DateFilterControl extends React.Component {
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const timeRange = this.props.value || defaultProps.value;
|
const timeRange = this.props.value || defaultProps.value;
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -95,9 +95,11 @@ export default class FilterBoxItemControl extends React.Component {
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
this.onControlChange = this.onControlChange.bind(this);
|
this.onControlChange = this.onControlChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange() {
|
onChange() {
|
||||||
this.props.onChange(this.state);
|
this.props.onChange(this.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
onControlChange(attr, value) {
|
onControlChange(attr, value) {
|
||||||
let typedValue = value;
|
let typedValue = value;
|
||||||
const { column: selectedColumnName, multiple } = this.state;
|
const { column: selectedColumnName, multiple } = this.state;
|
||||||
|
|
@ -122,10 +124,13 @@ export default class FilterBoxItemControl extends React.Component {
|
||||||
}
|
}
|
||||||
this.setState({ [attr]: typedValue }, this.onChange);
|
this.setState({ [attr]: typedValue }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
setType() {}
|
setType() {}
|
||||||
|
|
||||||
textSummary() {
|
textSummary() {
|
||||||
return this.state.column || 'N/A';
|
return this.state.column || 'N/A';
|
||||||
}
|
}
|
||||||
|
|
||||||
renderForm() {
|
renderForm() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -257,6 +262,7 @@ export default class FilterBoxItemControl extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPopover() {
|
renderPopover() {
|
||||||
return (
|
return (
|
||||||
<Popover id="ts-col-popo" title={t('Filter Configuration')}>
|
<Popover id="ts-col-popo" title={t('Filter Configuration')}>
|
||||||
|
|
@ -264,6 +270,7 @@ export default class FilterBoxItemControl extends React.Component {
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ export default class FixedOrMetricControl extends React.Component {
|
||||||
metricValue: type === controlTypes.metric ? value : null,
|
metricValue: type === controlTypes.metric ? value : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange() {
|
onChange() {
|
||||||
this.props.onChange({
|
this.props.onChange({
|
||||||
type: this.state.type,
|
type: this.state.type,
|
||||||
|
|
@ -75,12 +76,15 @@ export default class FixedOrMetricControl extends React.Component {
|
||||||
: this.state.metricValue,
|
: this.state.metricValue,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setType(type) {
|
setType(type) {
|
||||||
this.setState({ type }, this.onChange);
|
this.setState({ type }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
setFixedValue(fixedValue) {
|
setFixedValue(fixedValue) {
|
||||||
this.setState({ fixedValue }, this.onChange);
|
this.setState({ fixedValue }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
setMetric(metricValue) {
|
setMetric(metricValue) {
|
||||||
this.setState({ metricValue }, this.onChange);
|
this.setState({ metricValue }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,9 +70,11 @@ export default class SpatialControl extends React.Component {
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
this.renderReverseCheckbox = this.renderReverseCheckbox.bind(this);
|
this.renderReverseCheckbox = this.renderReverseCheckbox.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.onChange();
|
this.onChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange() {
|
onChange() {
|
||||||
const { type } = this.state;
|
const { type } = this.state;
|
||||||
const value = { type };
|
const value = { type };
|
||||||
|
|
@ -101,18 +103,22 @@ export default class SpatialControl extends React.Component {
|
||||||
this.setState({ value, errors });
|
this.setState({ value, errors });
|
||||||
this.props.onChange(value, errors);
|
this.props.onChange(value, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
setType(type) {
|
setType(type) {
|
||||||
this.setState({ type }, this.onChange);
|
this.setState({ type }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
this.refs.trigger.hide();
|
this.refs.trigger.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCheckbox() {
|
toggleCheckbox() {
|
||||||
this.setState(
|
this.setState(
|
||||||
{ reverseCheckbox: !this.state.reverseCheckbox },
|
{ reverseCheckbox: !this.state.reverseCheckbox },
|
||||||
this.onChange,
|
this.onChange,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLabelContent() {
|
renderLabelContent() {
|
||||||
if (this.state.errors.length > 0) {
|
if (this.state.errors.length > 0) {
|
||||||
return 'N/A';
|
return 'N/A';
|
||||||
|
|
@ -128,6 +134,7 @@ export default class SpatialControl extends React.Component {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSelect(name, type) {
|
renderSelect(name, type) {
|
||||||
return (
|
return (
|
||||||
<SelectControl
|
<SelectControl
|
||||||
|
|
@ -144,6 +151,7 @@ export default class SpatialControl extends React.Component {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderReverseCheckbox() {
|
renderReverseCheckbox() {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
|
|
@ -155,6 +163,7 @@ export default class SpatialControl extends React.Component {
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPopover() {
|
renderPopover() {
|
||||||
return (
|
return (
|
||||||
<Popover id="filter-popover">
|
<Popover id="filter-popover">
|
||||||
|
|
@ -219,6 +228,7 @@ export default class SpatialControl extends React.Component {
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -68,9 +68,11 @@ export default class TextAreaControl extends React.Component {
|
||||||
onControlChange(event) {
|
onControlChange(event) {
|
||||||
this.props.onChange(event.target.value);
|
this.props.onChange(event.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAceChange(value) {
|
onAceChange(value) {
|
||||||
this.props.onChange(value);
|
this.props.onChange(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEditor(inModal = false) {
|
renderEditor(inModal = false) {
|
||||||
const value = this.props.value || '';
|
const value = this.props.value || '';
|
||||||
if (this.props.language) {
|
if (this.props.language) {
|
||||||
|
|
@ -103,6 +105,7 @@ export default class TextAreaControl extends React.Component {
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderModalBody() {
|
renderModalBody() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -111,6 +114,7 @@ export default class TextAreaControl extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const controlHeader = <ControlHeader {...this.props} />;
|
const controlHeader = <ControlHeader {...this.props} />;
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ export default class TextControl extends React.Component<TextControlProps> {
|
||||||
super(props);
|
super(props);
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(event: any) {
|
onChange(event: any) {
|
||||||
let { value } = event.target;
|
let { value } = event.target;
|
||||||
|
|
||||||
|
|
@ -59,6 +60,7 @@ export default class TextControl extends React.Component<TextControlProps> {
|
||||||
}
|
}
|
||||||
this.props.onChange(value, errors);
|
this.props.onChange(value, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { value: rawValue } = this.props;
|
const { value: rawValue } = this.props;
|
||||||
const value =
|
const value =
|
||||||
|
|
|
||||||
|
|
@ -102,29 +102,39 @@ export default class TimeSeriesColumnControl extends React.Component {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange() {
|
onChange() {
|
||||||
this.props.onChange(this.state);
|
this.props.onChange(this.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectChange(attr, opt) {
|
onSelectChange(attr, opt) {
|
||||||
this.setState({ [attr]: opt.value }, this.onChange);
|
this.setState({ [attr]: opt.value }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextInputChange(attr, event) {
|
onTextInputChange(attr, event) {
|
||||||
this.setState({ [attr]: event.target.value }, this.onChange);
|
this.setState({ [attr]: event.target.value }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
onCheckboxChange(attr, value) {
|
onCheckboxChange(attr, value) {
|
||||||
this.setState({ [attr]: value }, this.onChange);
|
this.setState({ [attr]: value }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
onBoundsChange(bounds) {
|
onBoundsChange(bounds) {
|
||||||
this.setState({ bounds }, this.onChange);
|
this.setState({ bounds }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
onYAxisBoundsChange(yAxisBounds) {
|
onYAxisBoundsChange(yAxisBounds) {
|
||||||
this.setState({ yAxisBounds }, this.onChange);
|
this.setState({ yAxisBounds }, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
setType() {}
|
setType() {}
|
||||||
|
|
||||||
textSummary() {
|
textSummary() {
|
||||||
return `${this.state.label}`;
|
return `${this.state.label}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
edit() {}
|
edit() {}
|
||||||
|
|
||||||
formRow(label, tooltip, ttLabel, control) {
|
formRow(label, tooltip, ttLabel, control) {
|
||||||
return (
|
return (
|
||||||
<Row style={{ marginTop: '5px' }}>
|
<Row style={{ marginTop: '5px' }}>
|
||||||
|
|
@ -140,6 +150,7 @@ export default class TimeSeriesColumnControl extends React.Component {
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPopover() {
|
renderPopover() {
|
||||||
return (
|
return (
|
||||||
<Popover id="ts-col-popo" title="Column Configuration">
|
<Popover id="ts-col-popo" title="Column Configuration">
|
||||||
|
|
@ -297,6 +308,7 @@ export default class TimeSeriesColumnControl extends React.Component {
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,14 @@ export default class ViewportControl extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(ctrl, value) {
|
onChange(ctrl, value) {
|
||||||
this.props.onChange({
|
this.props.onChange({
|
||||||
...this.props.value,
|
...this.props.value,
|
||||||
[ctrl]: value,
|
[ctrl]: value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTextControl(ctrl) {
|
renderTextControl(ctrl) {
|
||||||
return (
|
return (
|
||||||
<div key={ctrl}>
|
<div key={ctrl}>
|
||||||
|
|
@ -78,6 +80,7 @@ export default class ViewportControl extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPopover() {
|
renderPopover() {
|
||||||
return (
|
return (
|
||||||
<Popover id={`filter-popover-${this.props.name}`} title="Viewport">
|
<Popover id={`filter-popover-${this.props.name}`} title="Viewport">
|
||||||
|
|
@ -85,6 +88,7 @@ export default class ViewportControl extends React.Component {
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLabel() {
|
renderLabel() {
|
||||||
if (this.props.value.longitude && this.props.value.latitude) {
|
if (this.props.value.longitude && this.props.value.latitude) {
|
||||||
return `${decimal2sexagesimal(
|
return `${decimal2sexagesimal(
|
||||||
|
|
@ -93,6 +97,7 @@ export default class ViewportControl extends React.Component {
|
||||||
}
|
}
|
||||||
return 'N/A';
|
return 'N/A';
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ class CreatedContent extends React.PureComponent<CreatedContentProps> {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDashboardTable() {
|
renderDashboardTable() {
|
||||||
const mutator = (data: Dashboard[]) =>
|
const mutator = (data: Dashboard[]) =>
|
||||||
data.map(dash => ({
|
data.map(dash => ({
|
||||||
|
|
@ -65,6 +66,7 @@ class CreatedContent extends React.PureComponent<CreatedContentProps> {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ export default class Favorites extends React.PureComponent<FavoritesProps> {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDashboardTable() {
|
renderDashboardTable() {
|
||||||
const mutator = (data: Dashboard[]) =>
|
const mutator = (data: Dashboard[]) =>
|
||||||
data.map(dash => ({
|
data.map(dash => ({
|
||||||
|
|
@ -66,6 +67,7 @@ export default class Favorites extends React.PureComponent<FavoritesProps> {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,12 @@ class DebouncedMessageQueue {
|
||||||
this.trigger = debounce(this.trigger.bind(this), this.delayThrehold);
|
this.trigger = debounce(this.trigger.bind(this), this.delayThrehold);
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
append(eventData) {
|
append(eventData) {
|
||||||
this.queue.push(eventData);
|
this.queue.push(eventData);
|
||||||
this.trigger();
|
this.trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger() {
|
trigger() {
|
||||||
if (this.queue.length > 0) {
|
if (this.queue.length > 0) {
|
||||||
const events = this.queue.splice(0, this.sizeThreshold);
|
const events = this.queue.splice(0, this.sizeThreshold);
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const onTextChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
const onTextChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
const target = event.target;
|
const { target } = event;
|
||||||
const data = {
|
const data = {
|
||||||
database_name: db ? db.database_name : '',
|
database_name: db ? db.database_name : '',
|
||||||
sqlalchemy_uri: db ? db.sqlalchemy_uri : '',
|
sqlalchemy_uri: db ? db.sqlalchemy_uri : '',
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,7 @@ class FilterBox extends React.Component {
|
||||||
this.props.onChange(selectedValues, false);
|
this.props.onChange(selectedValues, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changeFilter(filter, options) {
|
changeFilter(filter, options) {
|
||||||
const fltr = TIME_FILTER_MAP[filter] || filter;
|
const fltr = TIME_FILTER_MAP[filter] || filter;
|
||||||
let vals = null;
|
let vals = null;
|
||||||
|
|
@ -320,6 +321,7 @@ class FilterBox extends React.Component {
|
||||||
}
|
}
|
||||||
return datasourceFilters;
|
return datasourceFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSelect(filterConfig) {
|
renderSelect(filterConfig) {
|
||||||
const { filtersChoices } = this.props;
|
const { filtersChoices } = this.props;
|
||||||
const { selectedValues } = this.state;
|
const { selectedValues } = this.state;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue