Re-enable rule line-between-class-members (#10862)

This commit is contained in:
Kamil Gabryjelski 2020-09-15 00:41:32 +02:00 committed by GitHub
parent 91b8c8afc9
commit e28f3d6220
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 277 additions and 3 deletions

View File

@ -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,

View File

@ -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">

View File

@ -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,

View File

@ -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 => ({

View File

@ -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

View File

@ -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) {

View File

@ -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 (
<> <>

View File

@ -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;

View File

@ -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

View File

@ -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;
} }

View File

@ -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 => {

View File

@ -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(

View File

@ -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">

View File

@ -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">

View File

@ -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 (

View File

@ -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">

View File

@ -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

View File

@ -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 =

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -48,6 +48,7 @@ class FlashProvider extends React.PureComponent<Props> {
} }
}); });
} }
render() { render() {
return this.props.children; return this.props.children;
} }

View File

@ -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

View File

@ -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

View File

@ -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>;
} }

View File

@ -64,6 +64,7 @@ class BuilderComponentPane extends React.PureComponent {
</Tabs> </Tabs>
); );
} }
render() { render() {
const { topOffset } = this.props; const { topOffset } = this.props;
return ( return (

View File

@ -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 });
} }

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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;

View File

@ -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;

View File

@ -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 (

View File

@ -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 (

View File

@ -144,6 +144,7 @@ export default class EmbedCodeButton extends React.Component {
</Popover> </Popover>
); );
} }
render() { render() {
return ( return (
<OverlayTrigger <OverlayTrigger

View File

@ -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

View File

@ -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}>

View File

@ -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>

View File

@ -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 (

View File

@ -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">

View File

@ -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 = {

View File

@ -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 (

View File

@ -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>

View File

@ -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);
} }

View File

@ -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>

View File

@ -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 (

View File

@ -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 =

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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);

View File

@ -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 : '',

View File

@ -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;