You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by cw...@apache.org on 2019/07/27 08:46:46 UTC
[incubator-druid] branch master updated: Web console: code quality
improvements (null tidy up) (#8162)
This is an automated email from the ASF dual-hosted git repository.
cwylie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-druid.git
The following commit(s) were added to refs/heads/master by this push:
new 8bd0f8c Web console: code quality improvements (null tidy up) (#8162)
8bd0f8c is described below
commit 8bd0f8c2ac65b1d0f1816721a044a53f3b271ee0
Author: Vadim Ogievetsky <va...@gmail.com>
AuthorDate: Sat Jul 27 01:46:37 2019 -0700
Web console: code quality improvements (null tidy up) (#8162)
* tidy up nulls
* standardize more on undefined
* updated licenses
* update snapshot
* do not do heavy handed rendering
* add placeholder to SQL view
* remove pointelss fragment
---
licenses.yaml | 20 ++++
licenses/bin/lodash.compact.MIT | 23 +++++
licenses/bin/lodash.escape.MIT | 47 +++++++++
web-console/package-lock.json | 26 ++++-
web-console/package.json | 4 +
.../bootstrap/react-table-custom-pagination.tsx | 2 +-
web-console/src/bootstrap/react-table-defaults.tsx | 2 +-
.../components/action-cell/action-cell.spec.tsx | 2 +-
.../src/components/action-cell/action-cell.tsx | 2 +-
.../src/components/action-icon/action-icon.tsx | 2 +-
.../components/array-input/array-input.spec.tsx | 2 +-
.../src/components/array-input/array-input.tsx | 9 +-
web-console/src/components/auto-form/auto-form.tsx | 4 +-
.../components/center-message/center-message.tsx | 2 +-
.../clearable-input/clearable-input.spec.tsx | 2 +-
.../components/clearable-input/clearable-input.tsx | 2 +-
.../src/components/external-link/external-link.tsx | 2 +-
.../src/components/header-bar/header-bar.tsx | 2 +-
.../src/components/json-collapse/json-collapse.tsx | 2 +-
.../src/components/json-input/json-input.tsx | 2 +-
web-console/src/components/loader/loader.tsx | 2 +-
.../src/components/menu-checkbox/menu-checkbox.tsx | 2 +-
.../components/refresh-button/refresh-button.tsx | 2 +-
.../components/rule-editor/rule-editor.spec.tsx | 4 +-
.../src/components/rule-editor/rule-editor.tsx | 2 +-
web-console/src/components/show-json/show-json.tsx | 2 +-
web-console/src/components/show-log/show-log.tsx | 4 +-
.../suggestible-input/suggestible-input.tsx | 2 +-
.../src/components/table-cell/table-cell.tsx | 2 +-
.../table-column-selector.tsx | 2 +-
.../src/components/timed-button/timed-button.tsx | 2 +-
.../view-control-bar/view-control-bar.tsx | 2 +-
web-console/src/console-application.tsx | 2 +-
.../src/dialogs/about-dialog/about-dialog.spec.tsx | 2 +-
.../src/dialogs/about-dialog/about-dialog.tsx | 2 +-
.../async-action-dialog.spec.tsx | 2 +-
.../async-action-dialog/async-action-dialog.tsx | 2 +-
.../compaction-dialog/compaction-dialog.spec.tsx | 6 +-
.../compaction-dialog/compaction-dialog.tsx | 7 +-
.../coordinator-dynamic-config-dialog.spec.tsx | 2 +-
.../coordinator-dynamic-config-dialog.tsx | 7 +-
.../lookup-edit-dialog/lookup-edit-dialog.spec.tsx | 6 +-
.../lookup-edit-dialog/lookup-edit-dialog.tsx | 4 +-
.../overload-dynamic-config-dialog.spec.tsx | 2 +-
.../overlord-dynamic-config-dialog.tsx | 7 +-
.../query-plan-dialog/query-plan-dialog.spec.tsx | 6 +-
.../query-plan-dialog/query-plan-dialog.tsx | 16 +--
.../retention-dialog/retention-dialog.spec.tsx | 6 +-
.../dialogs/retention-dialog/retention-dialog.tsx | 2 +-
.../segment-table-action-dialog.spec.tsx | 2 +-
.../segment-table-action-dialog.tsx | 4 +-
.../show-value-dialog/show-value-dialog.spec.tsx | 2 +-
.../show-value-dialog/show-value-dialog.tsx | 2 +-
.../dialogs/snitch-dialog/snitch-dialog.spec.tsx | 2 +-
.../src/dialogs/snitch-dialog/snitch-dialog.tsx | 9 +-
.../src/dialogs/spec-dialog/spec-dialog.spec.tsx | 2 +-
.../src/dialogs/spec-dialog/spec-dialog.tsx | 2 +-
.../supervisor-table-action-dialog.spec.tsx.snap | 24 ++---
.../supervisor-table-action-dialog.spec.tsx | 2 +-
.../supervisor-table-action-dialog.tsx | 26 ++---
.../table-action-dialog.spec.tsx | 2 +-
.../table-action-dialog/table-action-dialog.tsx | 2 +-
.../task-table-action-dialog.spec.tsx | 2 +-
.../task-table-action-dialog.tsx | 2 +-
web-console/src/utils/druid-query.ts | 14 ++-
web-console/src/utils/druid-type.ts | 2 +-
web-console/src/utils/general.tsx | 5 +-
web-console/src/utils/ingestion-spec.tsx | 81 ++++++++-------
web-console/src/utils/local-storage-keys.tsx | 6 +-
web-console/src/utils/query-manager.tsx | 14 ++-
web-console/src/utils/query-state.ts | 4 +-
web-console/src/utils/rune-decoder.tsx | 20 ++--
web-console/src/utils/sampler.ts | 8 +-
.../src/views/datasource-view/datasource-view.tsx | 47 ++++-----
.../__snapshots__/home-view.spec.tsx.snap | 14 +--
web-console/src/views/home-view/home-view.scss | 4 +-
web-console/src/views/home-view/home-view.tsx | 81 +++++++--------
.../filter-table/filter-table.spec.tsx | 4 +-
.../load-data-view/filter-table/filter-table.tsx | 2 +-
.../src/views/load-data-view/load-data-view.scss | 21 ++--
.../src/views/load-data-view/load-data-view.tsx | 115 ++++++++++-----------
.../parse-data-table/parse-data-table.spec.tsx | 4 +-
.../parse-data-table/parse-data-table.tsx | 2 +-
.../parse-time-table/parse-time-table.spec.tsx | 2 +-
.../parse-time-table/parse-time-table.tsx | 4 +-
.../schema-table/schema-table.spec.tsx | 2 +-
.../load-data-view/schema-table/schema-table.tsx | 14 +--
.../transform-table/transform-table.spec.tsx | 2 +-
.../transform-table/transform-table.tsx | 2 +-
.../__snapshots__/lookups-view.spec.tsx.snap | 2 +-
.../src/views/lookups-view/lookups-view.tsx | 30 +++---
.../__snapshots__/query-view.spec.tsx.snap | 4 -
.../query-view/column-tree/column-tree.spec.tsx | 2 +-
.../views/query-view/column-tree/column-tree.tsx | 25 +++--
.../query-extra-info/query-extra-info.spec.tsx | 3 +-
.../query-extra-info/query-extra-info.tsx | 6 +-
.../query-view/query-input/query-input.spec.tsx | 7 +-
.../views/query-view/query-input/query-input.tsx | 43 ++++----
.../query-view/query-output/query-output.spec.tsx | 2 +-
.../views/query-view/query-output/query-output.tsx | 6 +-
web-console/src/views/query-view/query-view.tsx | 52 ++++------
.../query-view/run-button/run-button.spec.tsx | 6 +-
.../src/views/query-view/run-button/run-button.tsx | 4 +-
.../src/views/segments-view/segments-view.tsx | 60 +++++------
.../src/views/servers-view/servers-view.tsx | 26 ++---
.../src/views/task-view/tasks-view.spec.tsx | 6 +-
web-console/src/views/task-view/tasks-view.tsx | 80 ++++++--------
web-console/tsconfig.json | 2 +-
108 files changed, 619 insertions(+), 574 deletions(-)
diff --git a/licenses.yaml b/licenses.yaml
index 2e16f5f..372af99 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -2645,6 +2645,16 @@ license_file_path: licenses/bin/js-tokens.MIT
---
+name: "lodash.compact"
+license_category: binary
+module: web-console
+license_name: MIT License
+copyright: John-David Dalton
+version: 3.0.1
+license_file_path: licenses/bin/lodash.compact.MIT
+
+---
+
name: "lodash.debounce"
license_category: binary
module: web-console
@@ -2655,6 +2665,16 @@ license_file_path: licenses/bin/lodash.debounce.MIT
---
+name: "lodash.escape"
+license_category: binary
+module: web-console
+license_name: MIT License
+copyright: John-David Dalton
+version: 4.0.1
+license_file_path: licenses/bin/lodash.escape.MIT
+
+---
+
name: "lodash.get"
license_category: binary
module: web-console
diff --git a/licenses/bin/lodash.compact.MIT b/licenses/bin/lodash.compact.MIT
new file mode 100644
index 0000000..bcbe13d
--- /dev/null
+++ b/licenses/bin/lodash.compact.MIT
@@ -0,0 +1,23 @@
+The MIT License (MIT)
+
+Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
+Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas,
+DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/licenses/bin/lodash.escape.MIT b/licenses/bin/lodash.escape.MIT
new file mode 100644
index 0000000..e0c69d5
--- /dev/null
+++ b/licenses/bin/lodash.escape.MIT
@@ -0,0 +1,47 @@
+Copyright jQuery Foundation and other contributors <https://jquery.org/>
+
+Based on Underscore.js, copyright Jeremy Ashkenas,
+DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/lodash/lodash
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code displayed within the prose of the
+documentation.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+Files located in the node_modules and vendor directories are externally
+maintained libraries used by this software which have their own
+licenses; we recommend you read them, as their terms may differ from the
+terms above.
diff --git a/web-console/package-lock.json b/web-console/package-lock.json
index e7fe51f..c9c5c60 100644
--- a/web-console/package-lock.json
+++ b/web-console/package-lock.json
@@ -1282,6 +1282,15 @@
"integrity": "sha512-0GJhzBdvsW2RUccNHOBkabI8HZVdOXmXbXhuKlDEd5Vv12P7oAVGfomGp3Ne21o5D/qu1WmthlNKFaoZJJeErA==",
"dev": true
},
+ "@types/lodash.compact": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/lodash.compact/-/lodash.compact-3.0.6.tgz",
+ "integrity": "sha512-0pDKTX4alTyxH85Y5Al4YzS8oriqBQykADW6zLAHkZwNBMPXFIhdE2ctg0Z2GVcZsABxo5CI/J3vmHrFkdQBfA==",
+ "dev": true,
+ "requires": {
+ "@types/lodash": "*"
+ }
+ },
"@types/lodash.debounce": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.6.tgz",
@@ -1291,6 +1300,15 @@
"@types/lodash": "*"
}
},
+ "@types/lodash.escape": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@types/lodash.escape/-/lodash.escape-4.0.6.tgz",
+ "integrity": "sha512-/CI97B3wf1R4oD4yotsGoX/5bobL/RC8olTQ16iunzdjufcdD8GyIvNDatg1IfzVKaFBZmxuY0+WQDpdaQHLzg==",
+ "dev": true,
+ "requires": {
+ "@types/lodash": "*"
+ }
+ },
"@types/memoize-one": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@types/memoize-one/-/memoize-one-4.1.1.tgz",
@@ -7469,6 +7487,11 @@
"integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
"dev": true
},
+ "lodash.compact": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.compact/-/lodash.compact-3.0.1.tgz",
+ "integrity": "sha1-VAzjg3dFl1gHRx4WtKK6IeclbKU="
+ },
"lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -7477,8 +7500,7 @@
"lodash.escape": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz",
- "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=",
- "dev": true
+ "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg="
},
"lodash.flattendeep": {
"version": "4.4.0",
diff --git a/web-console/package.json b/web-console/package.json
index 7dc5408..8d7fbd9 100644
--- a/web-console/package.json
+++ b/web-console/package.json
@@ -60,7 +60,9 @@
"file-saver": "^2.0.2",
"has-own-prop": "^2.0.0",
"hjson": "^3.1.2",
+ "lodash.compact": "^3.0.1",
"lodash.debounce": "^4.0.8",
+ "lodash.escape": "^4.0.1",
"memoize-one": "^5.0.5",
"numeral": "^2.0.6",
"react": "^16.8.6",
@@ -84,7 +86,9 @@
"@types/file-saver": "^2.0.1",
"@types/hjson": "^2.4.1",
"@types/jest": "^24.0.15",
+ "@types/lodash.compact": "^3.0.6",
"@types/lodash.debounce": "^4.0.6",
+ "@types/lodash.escape": "^4.0.6",
"@types/memoize-one": "^4.1.1",
"@types/node": "^12.6.2",
"@types/numeral": "^0.0.25",
diff --git a/web-console/src/bootstrap/react-table-custom-pagination.tsx b/web-console/src/bootstrap/react-table-custom-pagination.tsx
index 5be343df..f45357d 100644
--- a/web-console/src/bootstrap/react-table-custom-pagination.tsx
+++ b/web-console/src/bootstrap/react-table-custom-pagination.tsx
@@ -83,7 +83,7 @@ export class ReactTableCustomPagination extends React.PureComponent<
this.changePage(page === '' ? this.props.page : page);
};
- render() {
+ render(): JSX.Element {
const {
pages,
page,
diff --git a/web-console/src/bootstrap/react-table-defaults.tsx b/web-console/src/bootstrap/react-table-defaults.tsx
index f0d2b2f..67b4121 100644
--- a/web-console/src/bootstrap/react-table-defaults.tsx
+++ b/web-console/src/bootstrap/react-table-defaults.tsx
@@ -27,7 +27,7 @@ import { ReactTableCustomPagination } from './react-table-custom-pagination';
/* tslint:disable:max-classes-per-file */
class NoData extends React.PureComponent {
- render() {
+ render(): JSX.Element | null {
const { children } = this.props;
if (!children) return null;
return <div className="rt-noData">{children}</div>;
diff --git a/web-console/src/components/action-cell/action-cell.spec.tsx b/web-console/src/components/action-cell/action-cell.spec.tsx
index 4f18bf8..f37d1ce 100644
--- a/web-console/src/components/action-cell/action-cell.spec.tsx
+++ b/web-console/src/components/action-cell/action-cell.spec.tsx
@@ -23,7 +23,7 @@ import { ActionCell } from './action-cell';
describe('action cell', () => {
it('matches snapshot', () => {
- const actionCell = <ActionCell onDetail={() => null} actions={[]} />;
+ const actionCell = <ActionCell onDetail={() => {}} actions={[]} />;
const { container } = render(actionCell);
expect(container.firstChild).toMatchSnapshot();
});
diff --git a/web-console/src/components/action-cell/action-cell.tsx b/web-console/src/components/action-cell/action-cell.tsx
index 32c2fa2..248c5ea 100644
--- a/web-console/src/components/action-cell/action-cell.tsx
+++ b/web-console/src/components/action-cell/action-cell.tsx
@@ -39,7 +39,7 @@ export class ActionCell extends React.PureComponent<ActionCellProps> {
super(props, context);
}
- render() {
+ render(): JSX.Element {
const { onDetail, actions } = this.props;
const actionsMenu = actions ? basicActionsToMenu(actions) : null;
diff --git a/web-console/src/components/action-icon/action-icon.tsx b/web-console/src/components/action-icon/action-icon.tsx
index c3c7da2..d53192d 100644
--- a/web-console/src/components/action-icon/action-icon.tsx
+++ b/web-console/src/components/action-icon/action-icon.tsx
@@ -29,7 +29,7 @@ export interface ActionIconProps {
}
export class ActionIcon extends React.PureComponent<ActionIconProps> {
- render() {
+ render(): JSX.Element {
const { className, icon, onClick } = this.props;
return <Icon className={classNames('action-icon', className)} icon={icon} onClick={onClick} />;
diff --git a/web-console/src/components/array-input/array-input.spec.tsx b/web-console/src/components/array-input/array-input.spec.tsx
index 8263983..bc21147 100644
--- a/web-console/src/components/array-input/array-input.spec.tsx
+++ b/web-console/src/components/array-input/array-input.spec.tsx
@@ -28,7 +28,7 @@ describe('array input', () => {
values={['apple', 'banana', 'pear']}
className={'test'}
placeholder={'test'}
- onChange={() => null}
+ onChange={() => {}}
/>
);
diff --git a/web-console/src/components/array-input/array-input.tsx b/web-console/src/components/array-input/array-input.tsx
index 75aedb8..9d7a451 100644
--- a/web-console/src/components/array-input/array-input.tsx
+++ b/web-console/src/components/array-input/array-input.tsx
@@ -17,12 +17,13 @@
*/
import { TextArea } from '@blueprintjs/core';
+import compact from 'lodash.compact';
import React from 'react';
export interface ArrayInputProps {
className?: string;
values: string[];
- onChange: (newValues: string[]) => void;
+ onChange: (newValues: string[] | undefined) => void;
placeholder?: string;
large?: boolean;
disabled?: boolean;
@@ -39,8 +40,8 @@ export class ArrayInput extends React.PureComponent<ArrayInputProps, { stringVal
private handleChange = (e: any) => {
const { onChange } = this.props;
const stringValue = e.target.value;
- const newValues = stringValue.split(',').map((v: string) => v.trim());
- const newValuesFiltered = newValues.filter(Boolean);
+ const newValues: string[] = stringValue.split(',').map((v: string) => v.trim());
+ const newValuesFiltered = compact(newValues);
this.setState({
stringValue:
newValues.length === newValuesFiltered.length ? newValues.join(', ') : stringValue,
@@ -48,7 +49,7 @@ export class ArrayInput extends React.PureComponent<ArrayInputProps, { stringVal
if (onChange) onChange(stringValue === '' ? undefined : newValuesFiltered);
};
- render() {
+ render(): JSX.Element {
const { className, placeholder, large, disabled } = this.props;
const { stringValue } = this.state;
return (
diff --git a/web-console/src/components/auto-form/auto-form.tsx b/web-console/src/components/auto-form/auto-form.tsx
index e7db357..ab2f9c8 100644
--- a/web-console/src/components/auto-form/auto-form.tsx
+++ b/web-console/src/components/auto-form/auto-form.tsx
@@ -42,7 +42,7 @@ export interface Field<T> {
export interface AutoFormProps<T> {
fields: Field<T>[];
- model: T | null;
+ model: T | undefined;
onChange: (newModel: T) => void;
showCustom?: (model: T) => boolean;
updateJSONValidity?: (jsonValidity: boolean) => void;
@@ -283,7 +283,7 @@ export class AutoForm<T extends Record<string, any>> extends React.PureComponent
);
}
- render() {
+ render(): JSX.Element {
const { fields, model, showCustom } = this.props;
return (
<div className="auto-form">
diff --git a/web-console/src/components/center-message/center-message.tsx b/web-console/src/components/center-message/center-message.tsx
index b84e0cf..6e88141 100644
--- a/web-console/src/components/center-message/center-message.tsx
+++ b/web-console/src/components/center-message/center-message.tsx
@@ -23,7 +23,7 @@ import './center-message.scss';
export interface CenterMessageProps {}
export class CenterMessage extends React.PureComponent<CenterMessageProps> {
- render() {
+ render(): JSX.Element {
return (
<div className="center-message bp3-input">
<div className="center-message-inner">{this.props.children}</div>
diff --git a/web-console/src/components/clearable-input/clearable-input.spec.tsx b/web-console/src/components/clearable-input/clearable-input.spec.tsx
index 9a20b53..3bea931 100644
--- a/web-console/src/components/clearable-input/clearable-input.spec.tsx
+++ b/web-console/src/components/clearable-input/clearable-input.spec.tsx
@@ -28,7 +28,7 @@ describe('clearable-input', () => {
className={'testClassName'}
value={'testValue'}
placeholder={'testPlaceholder'}
- onChange={() => null}
+ onChange={() => {}}
>
<div>Hello World</div>
</ClearableInput>
diff --git a/web-console/src/components/clearable-input/clearable-input.tsx b/web-console/src/components/clearable-input/clearable-input.tsx
index 1376759..252bddc 100644
--- a/web-console/src/components/clearable-input/clearable-input.tsx
+++ b/web-console/src/components/clearable-input/clearable-input.tsx
@@ -29,7 +29,7 @@ export interface ClearableInputProps {
}
export class ClearableInput extends React.PureComponent<ClearableInputProps> {
- render() {
+ render(): JSX.Element {
const { className, value, onChange, placeholder } = this.props;
return (
diff --git a/web-console/src/components/external-link/external-link.tsx b/web-console/src/components/external-link/external-link.tsx
index f4ca4b0..32428b0 100644
--- a/web-console/src/components/external-link/external-link.tsx
+++ b/web-console/src/components/external-link/external-link.tsx
@@ -23,7 +23,7 @@ export interface ExternalLinkProps {
}
export class ExternalLink extends React.PureComponent<ExternalLinkProps> {
- render() {
+ render(): JSX.Element {
const { href, children } = this.props;
return (
diff --git a/web-console/src/components/header-bar/header-bar.tsx b/web-console/src/components/header-bar/header-bar.tsx
index 5d4bc15..45598dc 100644
--- a/web-console/src/components/header-bar/header-bar.tsx
+++ b/web-console/src/components/header-bar/header-bar.tsx
@@ -127,7 +127,7 @@ export class HeaderBar extends React.PureComponent<HeaderBarProps, HeaderBarStat
);
}
- render() {
+ render(): JSX.Element {
const { active, hideLegacy } = this.props;
const {
aboutDialogOpen,
diff --git a/web-console/src/components/json-collapse/json-collapse.tsx b/web-console/src/components/json-collapse/json-collapse.tsx
index 0441d78..0936392 100644
--- a/web-console/src/components/json-collapse/json-collapse.tsx
+++ b/web-console/src/components/json-collapse/json-collapse.tsx
@@ -36,7 +36,7 @@ export class JSONCollapse extends React.PureComponent<JSONCollapseProps, JSONCol
};
}
- render() {
+ render(): JSX.Element {
const { stringValue, buttonText } = this.props;
const { isOpen } = this.state;
const prettyValue = JSON.stringify(JSON.parse(stringValue), undefined, 2);
diff --git a/web-console/src/components/json-input/json-input.tsx b/web-console/src/components/json-input/json-input.tsx
index 0aff544..6ecea6b 100644
--- a/web-console/src/components/json-input/json-input.tsx
+++ b/web-console/src/components/json-input/json-input.tsx
@@ -58,7 +58,7 @@ export class JSONInput extends React.PureComponent<JSONInputProps, JSONInputStat
}
}
- render() {
+ render(): JSX.Element {
const { onChange, updateInputValidity, focus, width, height } = this.props;
const { stringValue } = this.state;
return (
diff --git a/web-console/src/components/loader/loader.tsx b/web-console/src/components/loader/loader.tsx
index 69d74be..ecf5b3c 100644
--- a/web-console/src/components/loader/loader.tsx
+++ b/web-console/src/components/loader/loader.tsx
@@ -28,7 +28,7 @@ export interface LoaderProps {
export interface LoaderState {}
export class Loader extends React.PureComponent<LoaderProps, LoaderState> {
- render() {
+ render(): JSX.Element | null {
const { loadingText, loading } = this.props;
if (!loading) return null;
diff --git a/web-console/src/components/menu-checkbox/menu-checkbox.tsx b/web-console/src/components/menu-checkbox/menu-checkbox.tsx
index 270d34f..be1812a 100644
--- a/web-console/src/components/menu-checkbox/menu-checkbox.tsx
+++ b/web-console/src/components/menu-checkbox/menu-checkbox.tsx
@@ -22,7 +22,7 @@ import React from 'react';
import './menu-checkbox.scss';
export class MenuCheckbox extends React.PureComponent<ICheckboxProps> {
- render() {
+ render(): JSX.Element {
return (
<li className="menu-checkbox">
<Checkbox {...this.props} />
diff --git a/web-console/src/components/refresh-button/refresh-button.tsx b/web-console/src/components/refresh-button/refresh-button.tsx
index ab945e3..9393e50 100644
--- a/web-console/src/components/refresh-button/refresh-button.tsx
+++ b/web-console/src/components/refresh-button/refresh-button.tsx
@@ -31,7 +31,7 @@ export class RefreshButton extends React.PureComponent<RefreshButtonProps> {
super(props, context);
}
- render() {
+ render(): JSX.Element {
const { onRefresh, localStorageKey } = this.props;
const intervals = [
{ label: '5 seconds', value: 5000 },
diff --git a/web-console/src/components/rule-editor/rule-editor.spec.tsx b/web-console/src/components/rule-editor/rule-editor.spec.tsx
index a3a1608..fc945a3 100644
--- a/web-console/src/components/rule-editor/rule-editor.spec.tsx
+++ b/web-console/src/components/rule-editor/rule-editor.spec.tsx
@@ -27,8 +27,8 @@ describe('rule editor', () => {
<RuleEditor
rule={{ type: 'loadForever' }}
tiers={['test', 'test', 'test']}
- onChange={() => null}
- onDelete={() => null}
+ onChange={() => {}}
+ onDelete={() => {}}
moveUp={null}
moveDown={null}
/>
diff --git a/web-console/src/components/rule-editor/rule-editor.tsx b/web-console/src/components/rule-editor/rule-editor.tsx
index f46a42f..6ff916a 100644
--- a/web-console/src/components/rule-editor/rule-editor.tsx
+++ b/web-console/src/components/rule-editor/rule-editor.tsx
@@ -239,7 +239,7 @@ export class RuleEditor extends React.PureComponent<RuleEditorProps, RuleEditorS
);
}
- render() {
+ render(): JSX.Element | null {
const { onChange, rule, onDelete, moveUp, moveDown } = this.props;
const { isOpen } = this.state;
diff --git a/web-console/src/components/show-json/show-json.tsx b/web-console/src/components/show-json/show-json.tsx
index 7b8e2cc..beace5e 100644
--- a/web-console/src/components/show-json/show-json.tsx
+++ b/web-console/src/components/show-json/show-json.tsx
@@ -64,7 +64,7 @@ export class ShowJson extends React.PureComponent<ShowJsonProps, ShowJsonState>
}
};
- render() {
+ render(): JSX.Element {
const { endpoint, downloadFilename } = this.props;
const { jsonValue } = this.state;
diff --git a/web-console/src/components/show-log/show-log.tsx b/web-console/src/components/show-log/show-log.tsx
index 8efd2b0..801de24 100644
--- a/web-console/src/components/show-log/show-log.tsx
+++ b/web-console/src/components/show-log/show-log.tsx
@@ -39,7 +39,7 @@ export interface ShowLogProps {
endpoint: string;
downloadFilename?: string;
tailOffset?: number;
- status: string | null;
+ status?: string;
}
export interface ShowLogState {
@@ -102,7 +102,7 @@ export class ShowLog extends React.PureComponent<ShowLogProps, ShowLogState> {
}
};
- render() {
+ render(): JSX.Element {
const { endpoint, downloadFilename, status } = this.props;
const { logValue } = this.state;
diff --git a/web-console/src/components/suggestible-input/suggestible-input.tsx b/web-console/src/components/suggestible-input/suggestible-input.tsx
index 47eb174..92e0e51 100644
--- a/web-console/src/components/suggestible-input/suggestible-input.tsx
+++ b/web-console/src/components/suggestible-input/suggestible-input.tsx
@@ -79,7 +79,7 @@ export class SuggestibleInput extends React.PureComponent<SuggestibleInputProps>
);
}
- render() {
+ render(): JSX.Element {
const { className, value, defaultValue, onValueChange, large, ...rest } = this.props;
const suggestionsMenu = this.renderSuggestionsMenu();
diff --git a/web-console/src/components/table-cell/table-cell.tsx b/web-console/src/components/table-cell/table-cell.tsx
index e4164fd..5a6b535 100644
--- a/web-console/src/components/table-cell/table-cell.tsx
+++ b/web-console/src/components/table-cell/table-cell.tsx
@@ -69,7 +69,7 @@ export class TableCell extends React.PureComponent<NullTableCellProps> {
};
}
- render() {
+ render(): React.ReactNode {
const { value, timestamp, unparseable } = this.props;
if (unparseable) {
return <span className="table-cell unparseable">error</span>;
diff --git a/web-console/src/components/table-column-selector/table-column-selector.tsx b/web-console/src/components/table-column-selector/table-column-selector.tsx
index 2876404..efcf380 100644
--- a/web-console/src/components/table-column-selector/table-column-selector.tsx
+++ b/web-console/src/components/table-column-selector/table-column-selector.tsx
@@ -41,7 +41,7 @@ export class TableColumnSelector extends React.PureComponent<
this.state = {};
}
- render() {
+ render(): JSX.Element {
const { columns, onChange, tableColumnsHidden } = this.props;
const checkboxes = (
<Menu className="table-column-selector-menu">
diff --git a/web-console/src/components/timed-button/timed-button.tsx b/web-console/src/components/timed-button/timed-button.tsx
index 7b5d957..3da95d2 100644
--- a/web-console/src/components/timed-button/timed-button.tsx
+++ b/web-console/src/components/timed-button/timed-button.tsx
@@ -92,7 +92,7 @@ export class TimedButton extends React.PureComponent<TimedButtonProps, TimedButt
this.continuousRefresh(selectedInterval);
};
- render() {
+ render(): JSX.Element {
const {
label,
intervals,
diff --git a/web-console/src/components/view-control-bar/view-control-bar.tsx b/web-console/src/components/view-control-bar/view-control-bar.tsx
index 461e3b8..4dae002 100644
--- a/web-console/src/components/view-control-bar/view-control-bar.tsx
+++ b/web-console/src/components/view-control-bar/view-control-bar.tsx
@@ -29,7 +29,7 @@ export class ViewControlBar extends React.PureComponent<ViewControlBarProps> {
super(props);
}
- render() {
+ render(): JSX.Element {
const { label, children } = this.props;
return (
diff --git a/web-console/src/console-application.tsx b/web-console/src/console-application.tsx
index 636c706..08f253a 100644
--- a/web-console/src/console-application.tsx
+++ b/web-console/src/console-application.tsx
@@ -284,7 +284,7 @@ export class ConsoleApplication extends React.PureComponent<
return this.wrapInViewContainer('lookups', <LookupsView />);
};
- render() {
+ render(): JSX.Element {
const { capabilitiesLoading } = this.state;
if (capabilitiesLoading) {
diff --git a/web-console/src/dialogs/about-dialog/about-dialog.spec.tsx b/web-console/src/dialogs/about-dialog/about-dialog.spec.tsx
index f11fd2b..69a5068 100644
--- a/web-console/src/dialogs/about-dialog/about-dialog.spec.tsx
+++ b/web-console/src/dialogs/about-dialog/about-dialog.spec.tsx
@@ -23,7 +23,7 @@ import { AboutDialog } from './about-dialog';
describe('about dialog', () => {
it('matches snapshot', () => {
- const aboutDialog = <AboutDialog onClose={() => null} />;
+ const aboutDialog = <AboutDialog onClose={() => {}} />;
render(aboutDialog);
expect(document.body.lastChild).toMatchSnapshot();
});
diff --git a/web-console/src/dialogs/about-dialog/about-dialog.tsx b/web-console/src/dialogs/about-dialog/about-dialog.tsx
index fe2ea9d..7bbb549 100644
--- a/web-console/src/dialogs/about-dialog/about-dialog.tsx
+++ b/web-console/src/dialogs/about-dialog/about-dialog.tsx
@@ -40,7 +40,7 @@ export class AboutDialog extends React.PureComponent<AboutDialogProps, AboutDial
this.state = {};
}
- render() {
+ render(): JSX.Element {
const { onClose } = this.props;
return (
diff --git a/web-console/src/dialogs/async-action-dialog/async-action-dialog.spec.tsx b/web-console/src/dialogs/async-action-dialog/async-action-dialog.spec.tsx
index b54d204..d09c793 100644
--- a/web-console/src/dialogs/async-action-dialog/async-action-dialog.spec.tsx
+++ b/web-console/src/dialogs/async-action-dialog/async-action-dialog.spec.tsx
@@ -28,7 +28,7 @@ describe('async action dialog', () => {
action={() => {
return Promise.resolve();
}}
- onClose={() => null}
+ onClose={() => {}}
confirmButtonText={'test'}
successText={'test'}
failText={'test'}
diff --git a/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx b/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx
index 9891d1c..f426df1 100644
--- a/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx
+++ b/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx
@@ -106,7 +106,7 @@ export class AsyncActionDialog extends React.PureComponent<
onClose();
};
- render() {
+ render(): JSX.Element {
const {
className,
icon,
diff --git a/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx b/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx
index ad3ef3c..44ae80b 100644
--- a/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx
+++ b/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx
@@ -25,9 +25,9 @@ describe('compaction dialog', () => {
it('matches snapshot', () => {
const compactionDialog = (
<CompactionDialog
- onClose={() => null}
- onSave={() => null}
- onDelete={() => null}
+ onClose={() => {}}
+ onSave={() => {}}
+ onDelete={() => {}}
datasource={'test'}
configData={'test'}
/>
diff --git a/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx b/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx
index f5d9508..46976a5 100644
--- a/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx
+++ b/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx
@@ -32,7 +32,7 @@ export interface CompactionDialogProps {
}
export interface CompactionDialogState {
- currentConfig: Record<string, any> | null;
+ currentConfig?: Record<string, any>;
allJSONValid: boolean;
}
@@ -43,7 +43,6 @@ export class CompactionDialog extends React.PureComponent<
constructor(props: CompactionDialogProps) {
super(props);
this.state = {
- currentConfig: null,
allJSONValid: true,
};
}
@@ -68,7 +67,7 @@ export class CompactionDialog extends React.PureComponent<
});
}
- render() {
+ render(): JSX.Element {
const { onClose, onSave, onDelete, datasource, configData } = this.props;
const { currentConfig, allJSONValid } = this.state;
return (
@@ -127,7 +126,7 @@ export class CompactionDialog extends React.PureComponent<
text="Submit"
intent={Intent.PRIMARY}
onClick={() => onSave(currentConfig)}
- disabled={currentConfig === null || !allJSONValid}
+ disabled={!currentConfig || !allJSONValid}
/>
</div>
</div>
diff --git a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.spec.tsx b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.spec.tsx
index ad48adb..3b865ea 100644
--- a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.spec.tsx
+++ b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.spec.tsx
@@ -23,7 +23,7 @@ import { CoordinatorDynamicConfigDialog } from './coordinator-dynamic-config-dia
describe('coordinator dynamic config', () => {
it('matches snapshot', () => {
- const coordinatorDynamicConfig = <CoordinatorDynamicConfigDialog onClose={() => null} />;
+ const coordinatorDynamicConfig = <CoordinatorDynamicConfigDialog onClose={() => {}} />;
render(coordinatorDynamicConfig);
expect(document.body.lastChild).toMatchSnapshot();
});
diff --git a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx
index 7d70487..18818ca 100644
--- a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx
+++ b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx
@@ -33,7 +33,7 @@ export interface CoordinatorDynamicConfigDialogProps {
}
export interface CoordinatorDynamicConfigDialogState {
- dynamicConfig: Record<string, any> | null;
+ dynamicConfig?: Record<string, any>;
historyRecords: any[];
}
@@ -46,7 +46,6 @@ export class CoordinatorDynamicConfigDialog extends React.PureComponent<
constructor(props: CoordinatorDynamicConfigDialogProps) {
super(props);
this.state = {
- dynamicConfig: null,
historyRecords: [],
};
@@ -70,7 +69,7 @@ export class CoordinatorDynamicConfigDialog extends React.PureComponent<
}
async getClusterConfig() {
- let config: Record<string, any> | null = null;
+ let config: Record<string, any> | undefined;
try {
const configResp = await axios.get('/druid/coordinator/v1/config');
config = configResp.data;
@@ -112,7 +111,7 @@ export class CoordinatorDynamicConfigDialog extends React.PureComponent<
onClose();
};
- render() {
+ render(): JSX.Element {
const { onClose } = this.props;
const { dynamicConfig, historyRecords } = this.state;
diff --git a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx
index 0171c9b..0793637 100644
--- a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx
+++ b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx
@@ -26,9 +26,9 @@ describe('lookup edit dialog', () => {
const lookupEditDialog = (
<LookupEditDialog
isOpen
- onClose={() => null}
- onSubmit={() => null}
- onChange={() => null}
+ onClose={() => {}}
+ onSubmit={() => {}}
+ onChange={() => {}}
lookupName={'test'}
lookupTier={'test'}
lookupVersion={'test'}
diff --git a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.tsx b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.tsx
index 180ec2b..4abd892 100644
--- a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.tsx
+++ b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.tsx
@@ -94,7 +94,7 @@ export class LookupEditDialog extends React.PureComponent<
}
}
- render() {
+ render(): JSX.Element {
const {
isOpen,
onClose,
@@ -143,7 +143,7 @@ export class LookupEditDialog extends React.PureComponent<
<AceEditor
className="lookup-edit-dialog-textarea"
- mode="sql"
+ mode="hjson"
theme="solarized_dark"
onChange={(e: any) => onChange('lookupEditSpec', e)}
fontSize={12}
diff --git a/web-console/src/dialogs/overlord-dynamic-config-dialog/overload-dynamic-config-dialog.spec.tsx b/web-console/src/dialogs/overlord-dynamic-config-dialog/overload-dynamic-config-dialog.spec.tsx
index 7b60cdb..5b84552 100644
--- a/web-console/src/dialogs/overlord-dynamic-config-dialog/overload-dynamic-config-dialog.spec.tsx
+++ b/web-console/src/dialogs/overlord-dynamic-config-dialog/overload-dynamic-config-dialog.spec.tsx
@@ -23,7 +23,7 @@ import { OverlordDynamicConfigDialog } from './overlord-dynamic-config-dialog';
describe('overload dynamic config', () => {
it('matches snapshot', () => {
- const lookupEditDialog = <OverlordDynamicConfigDialog onClose={() => null} />;
+ const lookupEditDialog = <OverlordDynamicConfigDialog onClose={() => {}} />;
render(lookupEditDialog);
expect(document.body.lastChild).toMatchSnapshot();
diff --git a/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx b/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx
index dcf9423..ad0ea17 100644
--- a/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx
+++ b/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx
@@ -33,7 +33,7 @@ export interface OverlordDynamicConfigDialogProps {
}
export interface OverlordDynamicConfigDialogState {
- dynamicConfig: Record<string, any> | null;
+ dynamicConfig?: Record<string, any>;
allJSONValid: boolean;
historyRecords: any[];
}
@@ -47,7 +47,6 @@ export class OverlordDynamicConfigDialog extends React.PureComponent<
constructor(props: OverlordDynamicConfigDialogProps) {
super(props);
this.state = {
- dynamicConfig: null,
allJSONValid: true,
historyRecords: [],
};
@@ -72,7 +71,7 @@ export class OverlordDynamicConfigDialog extends React.PureComponent<
}
async getConfig() {
- let config: Record<string, any> | null = null;
+ let config: Record<string, any> | undefined;
try {
const configResp = await axios.get('/druid/indexer/v1/worker');
config = configResp.data || {};
@@ -114,7 +113,7 @@ export class OverlordDynamicConfigDialog extends React.PureComponent<
onClose();
};
- render() {
+ render(): JSX.Element {
const { onClose } = this.props;
const { dynamicConfig, allJSONValid, historyRecords } = this.state;
diff --git a/web-console/src/dialogs/query-plan-dialog/query-plan-dialog.spec.tsx b/web-console/src/dialogs/query-plan-dialog/query-plan-dialog.spec.tsx
index 59cc19f..465436d 100644
--- a/web-console/src/dialogs/query-plan-dialog/query-plan-dialog.spec.tsx
+++ b/web-console/src/dialogs/query-plan-dialog/query-plan-dialog.spec.tsx
@@ -24,11 +24,7 @@ import { QueryPlanDialog } from './query-plan-dialog';
describe('query plan dialog', () => {
it('matches snapshot', () => {
const queryPlanDialog = (
- <QueryPlanDialog
- explainResult={'test'}
- explainError={{ name: 'test', message: 'test' }}
- onClose={() => null}
- />
+ <QueryPlanDialog explainResult={'test'} explainError={undefined} onClose={() => {}} />
);
render(queryPlanDialog);
expect(document.body.lastChild).toMatchSnapshot();
diff --git a/web-console/src/dialogs/query-plan-dialog/query-plan-dialog.tsx b/web-console/src/dialogs/query-plan-dialog/query-plan-dialog.tsx
index 8fa438b..94bcdf3 100644
--- a/web-console/src/dialogs/query-plan-dialog/query-plan-dialog.tsx
+++ b/web-console/src/dialogs/query-plan-dialog/query-plan-dialog.tsx
@@ -24,8 +24,8 @@ import { BasicQueryExplanation, SemiJoinQueryExplanation } from '../../utils';
import './query-plan-dialog.scss';
export interface QueryPlanDialogProps {
- explainResult: BasicQueryExplanation | SemiJoinQueryExplanation | string | null;
- explainError: Error | null;
+ explainResult?: BasicQueryExplanation | SemiJoinQueryExplanation | string;
+ explainError?: string;
onClose: () => void;
}
@@ -40,17 +40,17 @@ export class QueryPlanDialog extends React.PureComponent<
this.state = {};
}
- render() {
+ render(): JSX.Element {
const { explainResult, explainError, onClose } = this.props;
let content: JSX.Element;
if (explainError) {
- content = <div>{explainError.message}</div>;
- } else if (explainResult == null) {
+ content = <div>{explainError}</div>;
+ } else if (!explainResult) {
content = <div />;
} else if ((explainResult as BasicQueryExplanation).query) {
- let signature: JSX.Element | null = null;
+ let signature: JSX.Element | undefined;
if ((explainResult as BasicQueryExplanation).signature) {
const signatureContent = (explainResult as BasicQueryExplanation).signature || '';
signature = (
@@ -79,8 +79,8 @@ export class QueryPlanDialog extends React.PureComponent<
(explainResult as SemiJoinQueryExplanation).mainQuery &&
(explainResult as SemiJoinQueryExplanation).subQueryRight
) {
- let mainSignature: JSX.Element | null = null;
- let subSignature: JSX.Element | null = null;
+ let mainSignature: JSX.Element | undefined;
+ let subSignature: JSX.Element | undefined;
if ((explainResult as SemiJoinQueryExplanation).mainQuery.signature) {
const signatureContent =
(explainResult as SemiJoinQueryExplanation).mainQuery.signature || '';
diff --git a/web-console/src/dialogs/retention-dialog/retention-dialog.spec.tsx b/web-console/src/dialogs/retention-dialog/retention-dialog.spec.tsx
index cc8d0ae..2372b39 100644
--- a/web-console/src/dialogs/retention-dialog/retention-dialog.spec.tsx
+++ b/web-console/src/dialogs/retention-dialog/retention-dialog.spec.tsx
@@ -28,9 +28,9 @@ describe('retention dialog', () => {
datasource={'test'}
rules={[null]}
tiers={['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']}
- onEditDefaults={() => null}
- onCancel={() => null}
- onSave={() => null}
+ onEditDefaults={() => {}}
+ onCancel={() => {}}
+ onSave={() => {}}
/>
);
render(retentionDialog);
diff --git a/web-console/src/dialogs/retention-dialog/retention-dialog.tsx b/web-console/src/dialogs/retention-dialog/retention-dialog.tsx
index f75a3d1..790ff06 100644
--- a/web-console/src/dialogs/retention-dialog/retention-dialog.tsx
+++ b/web-console/src/dialogs/retention-dialog/retention-dialog.tsx
@@ -163,7 +163,7 @@ export class RetentionDialog extends React.PureComponent<
});
};
- render() {
+ render(): JSX.Element {
const { datasource, onCancel, onEditDefaults } = this.props;
const { currentRules, historyRecords } = this.state;
diff --git a/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.spec.tsx b/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.spec.tsx
index a722986..e51a732 100644
--- a/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.spec.tsx
+++ b/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.spec.tsx
@@ -28,7 +28,7 @@ describe('task table action dialog', () => {
dataSourceId="test"
segmentId="test"
actions={[{ title: 'test', onAction: () => null }]}
- onClose={() => null}
+ onClose={() => {}}
isOpen
/>
);
diff --git a/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.tsx b/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.tsx
index 3dbfef8..37f4702 100644
--- a/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.tsx
+++ b/web-console/src/dialogs/segments-table-action-dialog/segment-table-action-dialog.tsx
@@ -24,8 +24,8 @@ import { BasicAction, basicActionsToButtons } from '../../utils/basic-action';
import { SideButtonMetaData, TableActionDialog } from '../table-action-dialog/table-action-dialog';
interface SegmentTableActionDialogProps extends IDialogProps {
- segmentId: string | null;
- dataSourceId: string | null;
+ segmentId?: string;
+ dataSourceId?: string;
actions: BasicAction[];
onClose: () => void;
}
diff --git a/web-console/src/dialogs/show-value-dialog/show-value-dialog.spec.tsx b/web-console/src/dialogs/show-value-dialog/show-value-dialog.spec.tsx
index 8a43718..553cabb 100644
--- a/web-console/src/dialogs/show-value-dialog/show-value-dialog.spec.tsx
+++ b/web-console/src/dialogs/show-value-dialog/show-value-dialog.spec.tsx
@@ -25,7 +25,7 @@ describe('clipboard dialog', () => {
it('matches snapshot', () => {
const compactionDialog = (
<ShowValueDialog
- onClose={() => null}
+ onClose={() => {}}
str={
'Bot: Automatska zamjena teksta (-[[Administrativna podjela Meksika|Admin]] +[[Administrativna podjela Meksika|Admi]])'
}
diff --git a/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx b/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx
index 9aed8b0..60f4a2f 100644
--- a/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx
+++ b/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx
@@ -35,7 +35,7 @@ export class ShowValueDialog extends React.PureComponent<ShowValueDialogProps> {
this.state = {};
}
- render() {
+ render(): JSX.Element {
const { onClose, str } = this.props;
return (
diff --git a/web-console/src/dialogs/snitch-dialog/snitch-dialog.spec.tsx b/web-console/src/dialogs/snitch-dialog/snitch-dialog.spec.tsx
index fd5cbd6..1c73826 100644
--- a/web-console/src/dialogs/snitch-dialog/snitch-dialog.spec.tsx
+++ b/web-console/src/dialogs/snitch-dialog/snitch-dialog.spec.tsx
@@ -23,7 +23,7 @@ import { SnitchDialog } from './snitch-dialog';
describe('snitch dialog', () => {
it('matches snapshot', () => {
- const snitchDialog = <SnitchDialog onSave={() => null} isOpen />;
+ const snitchDialog = <SnitchDialog onSave={() => {}} isOpen />;
render(snitchDialog);
expect(document.body.lastChild).toMatchSnapshot();
});
diff --git a/web-console/src/dialogs/snitch-dialog/snitch-dialog.tsx b/web-console/src/dialogs/snitch-dialog/snitch-dialog.tsx
index 742ad55..fc8b4f4 100644
--- a/web-console/src/dialogs/snitch-dialog/snitch-dialog.tsx
+++ b/web-console/src/dialogs/snitch-dialog/snitch-dialog.tsx
@@ -116,9 +116,10 @@ export class SnitchDialog extends React.PureComponent<SnitchDialogProps, SnitchD
);
}
- renderHistoryDialog() {
+ renderHistoryDialog(): JSX.Element | null {
const { historyRecords } = this.props;
- if (!historyRecords) return;
+ if (!historyRecords) return null;
+
return (
<HistoryDialog {...this.props} className="history-dialog" historyRecords={historyRecords}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
@@ -150,7 +151,7 @@ export class SnitchDialog extends React.PureComponent<SnitchDialogProps, SnitchD
Back
</Button>
) : onReset ? (
- <Button onClick={this.reset} intent={'none' as any}>
+ <Button onClick={this.reset} intent={Intent.NONE}>
Reset
</Button>
) : null}
@@ -176,7 +177,7 @@ export class SnitchDialog extends React.PureComponent<SnitchDialogProps, SnitchD
);
}
- render() {
+ render(): JSX.Element | null {
const { children, saveDisabled } = this.props;
const { showFinalStep, showHistory } = this.state;
diff --git a/web-console/src/dialogs/spec-dialog/spec-dialog.spec.tsx b/web-console/src/dialogs/spec-dialog/spec-dialog.spec.tsx
index 7cb93fa..65d576d 100644
--- a/web-console/src/dialogs/spec-dialog/spec-dialog.spec.tsx
+++ b/web-console/src/dialogs/spec-dialog/spec-dialog.spec.tsx
@@ -23,7 +23,7 @@ import { SpecDialog } from './spec-dialog';
describe('spec dialog', () => {
it('matches snapshot', () => {
- const specDialog = <SpecDialog onSubmit={() => null} onClose={() => null} title={'test'} />;
+ const specDialog = <SpecDialog onSubmit={() => {}} onClose={() => {}} title={'test'} />;
render(specDialog);
expect(document.body.lastChild).toMatchSnapshot();
});
diff --git a/web-console/src/dialogs/spec-dialog/spec-dialog.tsx b/web-console/src/dialogs/spec-dialog/spec-dialog.tsx
index 5cee087..b1a14f8 100644
--- a/web-console/src/dialogs/spec-dialog/spec-dialog.tsx
+++ b/web-console/src/dialogs/spec-dialog/spec-dialog.tsx
@@ -58,7 +58,7 @@ export class SpecDialog extends React.PureComponent<SpecDialogProps, SpecDialogS
onClose();
}
- render() {
+ render(): JSX.Element {
const { onClose, title } = this.props;
const { spec } = this.state;
diff --git a/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap b/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap
index 84017de..1fd8ebf 100755
--- a/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap
@@ -92,20 +92,20 @@ exports[`supervisor table action dialog matches snapshot 1`] = `
type="button"
>
<span
- class="bp3-icon bp3-icon-align-left"
- icon="align-left"
+ class="bp3-icon bp3-icon-chart"
+ icon="chart"
>
<svg
- data-icon="align-left"
+ data-icon="chart"
height="20"
viewBox="0 0 20 20"
width="20"
>
<desc>
- align-left
+ chart
</desc>
<path
- d="M1 7h10c.55 0 1-.45 1-1s-.45-1-1-1H1c-.55 0-1 .45-1 1s.45 1 1 1zm0-4h18c.55 0 1-.45 1-1s-.45-1-1-1H1c-.55 0-1 .45-1 1s.45 1 1 1zm14 14H1c-.55 0-1 .45-1 1s.45 1 1 1h14c.55 0 1-.45 1-1s-.45-1-1-1zm4-8H1c-.55 0-1 .45-1 1s.45 1 1 1h18c.55 0 1-.45 1-1s-.45-1-1-1zM1 15h6c.55 0 1-.45 1-1s-.45-1-1-1H1c-.55 0-1 .45-1 1s.45 1 1 1z"
+ d="M7 11v8c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-8l-2 2-4-2zm-7 8c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-8l-6 3v5zM17 7l-3 3v9c0 .55.45 1 1 1h4c.55 0 1-.45 1-1V8.74c-.26.15-.58.26-1 .26-1.92 0-2-2-2-2zm2-6h-4c-.55 0-1 .45-1 1s.45 1 1 1h1.59L10.8 8.78 7.45 7.11v.01C7.31 7.05 7.16 7 7 7s-.31.05-.44.11V7.1l-6 3v.01c-.33.17-.56.5-.56.89 0 .55.45 1 1 1 .16 0 .31-.05.44-.11v.01L7 9.12l3.55 1.78v-.01c.14.06.29.11.45.11.28 0 .53-.11.71-.29L18 4.41V6c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.4 [...]
fill-rule="evenodd"
/>
</svg>
@@ -113,7 +113,7 @@ exports[`supervisor table action dialog matches snapshot 1`] = `
<span
class="bp3-button-text"
>
- Payload
+ Statistics
</span>
</button>
<button
@@ -121,20 +121,20 @@ exports[`supervisor table action dialog matches snapshot 1`] = `
type="button"
>
<span
- class="bp3-icon bp3-icon-chart"
- icon="chart"
+ class="bp3-icon bp3-icon-align-left"
+ icon="align-left"
>
<svg
- data-icon="chart"
+ data-icon="align-left"
height="20"
viewBox="0 0 20 20"
width="20"
>
<desc>
- chart
+ align-left
</desc>
<path
- d="M7 11v8c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-8l-2 2-4-2zm-7 8c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-8l-6 3v5zM17 7l-3 3v9c0 .55.45 1 1 1h4c.55 0 1-.45 1-1V8.74c-.26.15-.58.26-1 .26-1.92 0-2-2-2-2zm2-6h-4c-.55 0-1 .45-1 1s.45 1 1 1h1.59L10.8 8.78 7.45 7.11v.01C7.31 7.05 7.16 7 7 7s-.31.05-.44.11V7.1l-6 3v.01c-.33.17-.56.5-.56.89 0 .55.45 1 1 1 .16 0 .31-.05.44-.11v.01L7 9.12l3.55 1.78v-.01c.14.06.29.11.45.11.28 0 .53-.11.71-.29L18 4.41V6c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.4 [...]
+ d="M1 7h10c.55 0 1-.45 1-1s-.45-1-1-1H1c-.55 0-1 .45-1 1s.45 1 1 1zm0-4h18c.55 0 1-.45 1-1s-.45-1-1-1H1c-.55 0-1 .45-1 1s.45 1 1 1zm14 14H1c-.55 0-1 .45-1 1s.45 1 1 1h14c.55 0 1-.45 1-1s-.45-1-1-1zm4-8H1c-.55 0-1 .45-1 1s.45 1 1 1h18c.55 0 1-.45 1-1s-.45-1-1-1zM1 15h6c.55 0 1-.45 1-1s-.45-1-1-1H1c-.55 0-1 .45-1 1s.45 1 1 1z"
fill-rule="evenodd"
/>
</svg>
@@ -142,7 +142,7 @@ exports[`supervisor table action dialog matches snapshot 1`] = `
<span
class="bp3-button-text"
>
- Statistics
+ Payload
</span>
</button>
<button
diff --git a/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.spec.tsx b/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.spec.tsx
index 5fdb45b..18ef377 100644
--- a/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.spec.tsx
+++ b/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.spec.tsx
@@ -29,7 +29,7 @@ describe('supervisor table action dialog', () => {
<SupervisorTableActionDialog
supervisorId={'test'}
actions={[basicAction, basicAction, basicAction, basicAction]}
- onClose={() => null}
+ onClose={() => {}}
isOpen
/>
);
diff --git a/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx b/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx
index 49d6af4..84a10b0 100644
--- a/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx
+++ b/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx
@@ -31,7 +31,7 @@ interface SupervisorTableActionDialogProps extends IDialogProps {
}
interface SupervisorTableActionDialogState {
- activeTab: 'status' | 'payload' | 'stats' | 'history';
+ activeTab: 'status' | 'stats' | 'payload' | 'history';
}
export class SupervisorTableActionDialog extends React.PureComponent<
@@ -56,18 +56,18 @@ export class SupervisorTableActionDialog extends React.PureComponent<
onClick: () => this.setState({ activeTab: 'status' }),
},
{
- icon: 'align-left',
- text: 'Payload',
- active: activeTab === 'payload',
- onClick: () => this.setState({ activeTab: 'payload' }),
- },
- {
icon: 'chart',
text: 'Statistics',
active: activeTab === 'stats',
onClick: () => this.setState({ activeTab: 'stats' }),
},
{
+ icon: 'align-left',
+ text: 'Payload',
+ active: activeTab === 'payload',
+ onClick: () => this.setState({ activeTab: 'payload' }),
+ },
+ {
icon: 'history',
text: 'History',
active: activeTab === 'history',
@@ -90,18 +90,18 @@ export class SupervisorTableActionDialog extends React.PureComponent<
downloadFilename={`supervisor-status-${supervisorId}.json`}
/>
)}
- {activeTab === 'payload' && (
- <ShowJson
- endpoint={`/druid/indexer/v1/supervisor/${supervisorId}`}
- downloadFilename={`supervisor-payload-${supervisorId}.json`}
- />
- )}
{activeTab === 'stats' && (
<ShowJson
endpoint={`/druid/indexer/v1/supervisor/${supervisorId}/stats`}
downloadFilename={`supervisor-stats-${supervisorId}.json`}
/>
)}
+ {activeTab === 'payload' && (
+ <ShowJson
+ endpoint={`/druid/indexer/v1/supervisor/${supervisorId}`}
+ downloadFilename={`supervisor-payload-${supervisorId}.json`}
+ />
+ )}
{activeTab === 'history' && (
<ShowJson
endpoint={`/druid/indexer/v1/supervisor/${supervisorId}/history`}
diff --git a/web-console/src/dialogs/table-action-dialog/table-action-dialog.spec.tsx b/web-console/src/dialogs/table-action-dialog/table-action-dialog.spec.tsx
index 48eb547..5e5ff8b 100644
--- a/web-console/src/dialogs/table-action-dialog/table-action-dialog.spec.tsx
+++ b/web-console/src/dialogs/table-action-dialog/table-action-dialog.spec.tsx
@@ -26,7 +26,7 @@ describe('table action dialog', () => {
const tableActionDialog = (
<TableActionDialog
sideButtonMetadata={[{ icon: 'badge', text: 'test' }]}
- onClose={() => null}
+ onClose={() => {}}
isOpen
/>
);
diff --git a/web-console/src/dialogs/table-action-dialog/table-action-dialog.tsx b/web-console/src/dialogs/table-action-dialog/table-action-dialog.tsx
index b8cd596..1e9209e 100644
--- a/web-console/src/dialogs/table-action-dialog/table-action-dialog.tsx
+++ b/web-console/src/dialogs/table-action-dialog/table-action-dialog.tsx
@@ -40,7 +40,7 @@ export class TableActionDialog extends React.PureComponent<TableActionDialogProp
this.state = {};
}
- render() {
+ render(): JSX.Element {
const { sideButtonMetadata, isOpen, onClose, title, bottomButtons } = this.props;
return (
diff --git a/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.spec.tsx b/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.spec.tsx
index 54e730f..adaacd6 100644
--- a/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.spec.tsx
+++ b/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.spec.tsx
@@ -29,7 +29,7 @@ describe('task table action dialog', () => {
status={'RUNNING'}
taskId={'test'}
actions={[basicAction]}
- onClose={() => null}
+ onClose={() => {}}
isOpen
/>
);
diff --git a/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.tsx b/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.tsx
index c6c5540..be2faae 100644
--- a/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.tsx
+++ b/web-console/src/dialogs/task-table-action-dialog/task-table-action-dialog.tsx
@@ -28,7 +28,7 @@ interface TaskTableActionDialogProps extends IDialogProps {
taskId: string;
actions: BasicAction[];
onClose: () => void;
- status: string | null;
+ status?: string;
}
interface TaskTableActionDialogState {
diff --git a/web-console/src/utils/druid-query.ts b/web-console/src/utils/druid-query.ts
index 831d2a9..db22700 100644
--- a/web-console/src/utils/druid-query.ts
+++ b/web-console/src/utils/druid-query.ts
@@ -18,11 +18,12 @@
import axios from 'axios';
import { AxiosResponse } from 'axios';
+import compact from 'lodash.compact';
-export function parseHtmlError(htmlStr: string): string | null {
+export function parseHtmlError(htmlStr: string): string | undefined {
const startIndex = htmlStr.indexOf('</h3><pre>');
const endIndex = htmlStr.indexOf('\n\tat');
- if (startIndex === -1 || endIndex === -1) return null;
+ if (startIndex === -1 || endIndex === -1) return;
return htmlStr
.substring(startIndex + 10, endIndex)
@@ -36,9 +37,12 @@ export function getDruidErrorMessage(e: any) {
switch (typeof data) {
case 'object':
return (
- [data.error, data.errorMessage, data.errorClass, data.host ? `on host ${data.host}` : null]
- .filter(Boolean)
- .join(' / ') || e.message
+ compact([
+ data.error,
+ data.errorMessage,
+ data.errorClass,
+ data.host ? `on host ${data.host}` : undefined,
+ ]).join(' / ') || e.message
);
case 'string':
diff --git a/web-console/src/utils/druid-type.ts b/web-console/src/utils/druid-type.ts
index 955c8a2..b0540d3 100644
--- a/web-console/src/utils/druid-type.ts
+++ b/web-console/src/utils/druid-type.ts
@@ -42,7 +42,7 @@ export function getColumnTypeFromHeaderAndRows(
column: string,
): string {
return guessTypeFromSample(
- filterMap(headerAndRows.rows, (r: any) => (r.parsed ? r.parsed[column] : null)),
+ filterMap(headerAndRows.rows, (r: any) => (r.parsed ? r.parsed[column] : undefined)),
);
}
diff --git a/web-console/src/utils/general.tsx b/web-console/src/utils/general.tsx
index ef75edc..b504420 100644
--- a/web-console/src/utils/general.tsx
+++ b/web-console/src/utils/general.tsx
@@ -101,10 +101,7 @@ function getNeedleAndMode(input: string): NeedleAndMode {
}
export function booleanCustomTableFilter(filter: Filter, value: any): boolean {
- if (value === undefined) {
- return true;
- }
- if (value === null) return false;
+ if (value == null) return false;
const haystack = String(value).toLowerCase();
const needleAndMode: NeedleAndMode = getNeedleAndMode(filter.value.toLowerCase());
const needle = needleAndMode.needle;
diff --git a/web-console/src/utils/ingestion-spec.tsx b/web-console/src/utils/ingestion-spec.tsx
index f39ceaa..6caf518 100644
--- a/web-console/src/utils/ingestion-spec.tsx
+++ b/web-console/src/utils/ingestion-spec.tsx
@@ -133,7 +133,7 @@ export function getIngestionImage(ingestionType: IngestionComboTypeWithExtra): s
return ingestionType;
}
-export function getRequiredModule(ingestionType: IngestionComboTypeWithExtra): string | null {
+export function getRequiredModule(ingestionType: IngestionComboTypeWithExtra): string | undefined {
switch (ingestionType) {
case 'index:static-s3':
return 'druid-s3-extensions';
@@ -148,7 +148,7 @@ export function getRequiredModule(ingestionType: IngestionComboTypeWithExtra): s
return 'druid-kinesis-indexing-service';
default:
- return null;
+ return;
}
}
@@ -308,9 +308,9 @@ export function getParseSpecFormFields() {
return PARSE_SPEC_FORM_FIELDS;
}
-export function issueWithParser(parser: Parser | undefined): string | null {
+export function issueWithParser(parser: Parser | undefined): string | undefined {
if (!parser) return 'no parser';
- if (parser.type === 'map') return null;
+ if (parser.type === 'map') return;
const { parseSpec } = parser;
if (!parseSpec) return 'no parse spec';
@@ -324,7 +324,7 @@ export function issueWithParser(parser: Parser | undefined): string | null {
if (!parseSpec['function']) return "must have a 'function'";
break;
}
- return null;
+ return;
}
export function parseSpecHasFlatten(parseSpec: ParseSpec): boolean {
@@ -415,10 +415,12 @@ export function getTimestampSpecFormFields(timestampSpec: TimestampSpec) {
}
}
-export function issueWithTimestampSpec(timestampSpec: TimestampSpec | undefined): string | null {
+export function issueWithTimestampSpec(
+ timestampSpec: TimestampSpec | undefined,
+): string | undefined {
if (!timestampSpec) return 'no spec';
if (!timestampSpec.column && !timestampSpec.missingValue) return 'timestamp spec is blank';
- return null;
+ return;
}
export interface DimensionsSpec {
@@ -722,15 +724,13 @@ export function getIoConfigFormFields(ingestionComboType: IngestionComboType): F
type: 'string',
suggestions: ['local', 'http', 'static-s3', 'static-google-blobstore'],
info: (
- <>
- <p>
- Druid connects to raw data through{' '}
- <ExternalLink href="https://druid.apache.org/docs/latest/ingestion/firehose.html">
- firehoses
- </ExternalLink>
- . You can change your selected firehose here.
- </p>
- </>
+ <p>
+ Druid connects to raw data through{' '}
+ <ExternalLink href="https://druid.apache.org/docs/latest/ingestion/firehose.html">
+ firehoses
+ </ExternalLink>
+ . You can change your selected firehose here.
+ </p>
),
};
@@ -957,7 +957,7 @@ function nonEmptyArray(a: any) {
return Array.isArray(a) && Boolean(a.length);
}
-function issueWithFirehose(firehose: Firehose | undefined): string | null {
+function issueWithFirehose(firehose: Firehose | undefined): string | undefined {
if (!firehose) return 'does not exist';
if (!firehose.type) return 'missing a type';
switch (firehose.type) {
@@ -984,10 +984,10 @@ function issueWithFirehose(firehose: Firehose | undefined): string | null {
}
break;
}
- return null;
+ return;
}
-export function issueWithIoConfig(ioConfig: IoConfig | undefined): string | null {
+export function issueWithIoConfig(ioConfig: IoConfig | undefined): string | undefined {
if (!ioConfig) return 'does not exist';
if (!ioConfig.type) return 'missing a type';
switch (ioConfig.type) {
@@ -1007,7 +1007,7 @@ export function issueWithIoConfig(ioConfig: IoConfig | undefined): string | null
break;
}
- return null;
+ return;
}
export function getIoConfigTuningFormFields(
@@ -1296,13 +1296,14 @@ function filterIsFilename(filter: string): boolean {
return !/[*?]/.test(filter);
}
-function filenameFromPath(path: string): string | null {
+function filenameFromPath(path: string): string | undefined {
const m = path.match(/([^\/.]+)[^\/]*?\/?$/);
- return m ? m[1] : null;
+ if (!m) return;
+ return m[1];
}
-function basenameFromFilename(filename: string): string | null {
- return filename.split('.')[0] || null;
+function basenameFromFilename(filename: string): string | undefined {
+ return filename.split('.')[0];
}
export function fillDataSourceName(spec: IngestionSpec): IngestionSpec {
@@ -1313,12 +1314,12 @@ export function fillDataSourceName(spec: IngestionSpec): IngestionSpec {
return deepSet(spec, 'dataSchema.dataSource', possibleName);
}
-export function guessDataSourceName(ioConfig: IoConfig): string | null {
+export function guessDataSourceName(ioConfig: IoConfig): string | undefined {
switch (ioConfig.type) {
case 'index':
case 'index_parallel':
const firehose = ioConfig.firehose;
- if (!firehose) return null;
+ if (!firehose) return;
switch (firehose.type) {
case 'local':
@@ -1327,27 +1328,27 @@ export function guessDataSourceName(ioConfig: IoConfig): string | null {
} else if (firehose.baseDir) {
return filenameFromPath(firehose.baseDir);
} else {
- return null;
+ return;
}
case 'static-s3':
const s3Path = (firehose.uris || EMPTY_ARRAY)[0] || (firehose.prefixes || EMPTY_ARRAY)[0];
- return s3Path ? filenameFromPath(s3Path) : null;
+ return s3Path ? filenameFromPath(s3Path) : undefined;
case 'http':
- return Array.isArray(firehose.uris) ? filenameFromPath(firehose.uris[0]) : null;
+ return Array.isArray(firehose.uris) ? filenameFromPath(firehose.uris[0]) : undefined;
}
- return null;
+ return;
case 'kafka':
- return ioConfig.topic || null;
+ return ioConfig.topic;
case 'kinesis':
- return ioConfig.stream || null;
+ return ioConfig.stream;
default:
- return null;
+ return;
}
}
@@ -1830,9 +1831,9 @@ export function fillParser(spec: IngestionSpec, sampleData: string[]): Ingestion
return deepSet(spec, 'dataSchema.parser', { type: 'string', parseSpec });
}
-function guessParseSpec(sampleData: string[]): ParseSpec | null {
+function guessParseSpec(sampleData: string[]): ParseSpec | undefined {
const sampleDatum = sampleData[0];
- if (!sampleDatum) return null;
+ if (!sampleDatum) return;
if (sampleDatum.startsWith('{') && sampleDatum.endsWith('}')) {
return parseSpecFromFormat('json');
@@ -1867,7 +1868,7 @@ export type DruidFilter = Record<string, any>;
export interface DimensionFiltersWithRest {
dimensionFilters: DruidFilter[];
- restFilter: DruidFilter | null;
+ restFilter?: DruidFilter;
}
export function splitFilter(filter: DruidFilter | null): DimensionFiltersWithRest {
@@ -1887,16 +1888,18 @@ export function splitFilter(filter: DruidFilter | null): DimensionFiltersWithRes
? restFilters.length > 1
? { type: 'and', filters: restFilters }
: restFilters[0]
- : null,
+ : undefined,
};
}
-export function joinFilter(dimensionFiltersWithRest: DimensionFiltersWithRest): DruidFilter | null {
+export function joinFilter(
+ dimensionFiltersWithRest: DimensionFiltersWithRest,
+): DruidFilter | undefined {
const { dimensionFilters, restFilter } = dimensionFiltersWithRest;
let newFields = dimensionFilters || EMPTY_ARRAY;
if (restFilter && restFilter.type) newFields = newFields.concat([restFilter]);
- if (!newFields.length) return null;
+ if (!newFields.length) return;
if (newFields.length === 1) return newFields[0];
return { type: 'and', fields: newFields };
}
diff --git a/web-console/src/utils/local-storage-keys.tsx b/web-console/src/utils/local-storage-keys.tsx
index 1aa50b7..620dc0e 100644
--- a/web-console/src/utils/local-storage-keys.tsx
+++ b/web-console/src/utils/local-storage-keys.tsx
@@ -43,7 +43,7 @@ export function localStorageSet(key: LocalStorageKeys, value: string): void {
localStorage.setItem(key, value);
}
-export function localStorageGet(key: LocalStorageKeys): string | null {
- if (typeof localStorage === 'undefined') return null;
- return localStorage.getItem(key);
+export function localStorageGet(key: LocalStorageKeys): string | undefined {
+ if (typeof localStorage === 'undefined') return;
+ return localStorage.getItem(key) || undefined;
}
diff --git a/web-console/src/utils/query-manager.tsx b/web-console/src/utils/query-manager.tsx
index ecf78f1..d7f0acb 100644
--- a/web-console/src/utils/query-manager.tsx
+++ b/web-console/src/utils/query-manager.tsx
@@ -19,9 +19,9 @@
import debounce from 'lodash.debounce';
export interface QueryStateInt<R> {
- result: R | null;
+ result?: R;
loading: boolean;
- error: string | null;
+ error?: string;
}
export interface QueryManagerOptions<Q, R> {
@@ -44,9 +44,7 @@ export class QueryManager<Q, R> {
private lastIntermediateQuery: any;
private actuallyLoading = false;
private state: QueryStateInt<R> = {
- result: null,
loading: false,
- error: null,
};
private currentQueryId = 0;
@@ -91,14 +89,14 @@ export class QueryManager<Q, R> {
this.setState({
result,
loading: false,
- error: null,
+ error: undefined,
});
},
(e: Error) => {
if (this.currentQueryId !== myQueryId) return;
this.actuallyLoading = false;
this.setState({
- result: null,
+ result: undefined,
loading: false,
error: e.message,
});
@@ -110,9 +108,9 @@ export class QueryManager<Q, R> {
const currentActuallyLoading = this.actuallyLoading;
this.setState({
- result: null,
+ result: undefined,
loading: true,
- error: null,
+ error: undefined,
});
if (currentActuallyLoading) {
diff --git a/web-console/src/utils/query-state.ts b/web-console/src/utils/query-state.ts
index 8663ff0..60e09fa 100644
--- a/web-console/src/utils/query-state.ts
+++ b/web-console/src/utils/query-state.ts
@@ -22,8 +22,8 @@ export class QueryState<T> {
static INIT: QueryState<any> = new QueryState({});
public state: QueryStateState = 'init';
- public error?: string | null;
- public data?: T | null;
+ public error?: string;
+ public data?: T;
constructor(opts: { loading?: boolean; error?: string; data?: T }) {
if (opts.error) {
diff --git a/web-console/src/utils/rune-decoder.tsx b/web-console/src/utils/rune-decoder.tsx
index 77e9d06..2d82c0a 100644
--- a/web-console/src/utils/rune-decoder.tsx
+++ b/web-console/src/utils/rune-decoder.tsx
@@ -54,33 +54,29 @@ function processTimeseries(rune: any[]): HeaderRows {
}
function processArrayWithResultArray(rune: any[]): HeaderRows {
- return flatArrayToHeaderRows([].concat(...rune.map(r => r.result)));
+ return flatArrayToHeaderRows(rune.flatMap(r => r.result));
}
function processArrayWithEvent(rune: any[]): HeaderRows {
- return flatArrayToHeaderRows(rune.map((r: any) => r.event));
+ return flatArrayToHeaderRows(rune.map(r => r.event));
}
function processArrayWithResult(rune: any[]): HeaderRows {
- return flatArrayToHeaderRows(rune.map((r: any) => r.result));
+ return flatArrayToHeaderRows(rune.map(r => r.result));
}
function processSelect(rune: any[]): HeaderRows {
- return flatArrayToHeaderRows(
- [].concat(...rune.map(r => r.result.events.map((e: any) => e.event))),
- );
+ return flatArrayToHeaderRows(rune.flatMap(r => r.result.events.map((e: any) => e.event)));
}
function processScan(rune: any[]): HeaderRows {
const header = rune[0].columns;
- return flatArrayToHeaderRows([].concat(...rune.map(r => r.events)), header);
+ return flatArrayToHeaderRows(rune.flatMap(r => r.events), header);
}
function processSegmentMetadata(rune: any[]): HeaderRows {
- const flatArray = ([] as any).concat(
- ...rune.map(r =>
- Object.keys(r.columns).map(k => Object.assign({ id: r.id, column: k }, r.columns[k])),
- ),
+ const flatArray = rune.flatMap(r =>
+ Object.keys(r.columns).map(k => Object.assign({ id: r.id, column: k }, r.columns[k])),
);
return flatArrayToHeaderRows(flatArray);
}
@@ -131,7 +127,7 @@ export function decodeRune(runeQuery: any, runeResult: any[]): HeaderRows {
if (runeQuery.resultFormat === 'compactedList') {
return {
header: runeResult[0].columns,
- rows: [].concat(...runeResult.map(r => r.events)),
+ rows: runeResult.flatMap(r => r.events),
};
}
return processScan(runeResult);
diff --git a/web-console/src/utils/sampler.ts b/web-console/src/utils/sampler.ts
index 1009bb0..bb87bdd 100644
--- a/web-console/src/utils/sampler.ts
+++ b/web-console/src/utils/sampler.ts
@@ -19,7 +19,7 @@
import axios from 'axios';
import { getDruidErrorMessage } from './druid-query';
-import { alphanumericCompare, filterMap, sortWithPrefixSuffix } from './general';
+import { alphanumericCompare, sortWithPrefixSuffix } from './general';
import {
DimensionsSpec,
getEmptyTimestampSpec,
@@ -98,11 +98,7 @@ export function headerFromSampleResponse(
columnOrder?: string[],
): string[] {
let columns = sortWithPrefixSuffix(
- dedupe(
- [].concat(
- ...(filterMap(sampleResponse.data, s => (s.parsed ? Object.keys(s.parsed) : null)) as any),
- ),
- ).sort(),
+ dedupe(sampleResponse.data.flatMap(s => (s.parsed ? Object.keys(s.parsed) : []))).sort(),
columnOrder || ['__time'],
[],
alphanumericCompare,
diff --git a/web-console/src/views/datasource-view/datasource-view.tsx b/web-console/src/views/datasource-view/datasource-view.tsx
index 8297a71..6580af6 100644
--- a/web-console/src/views/datasource-view/datasource-view.tsx
+++ b/web-console/src/views/datasource-view/datasource-view.tsx
@@ -110,16 +110,16 @@ export interface DatasourcesViewState {
datasources: Datasource[] | null;
tiers: string[];
defaultRules: any[];
- datasourcesError: string | null;
+ datasourcesError?: string;
datasourcesFilter: Filter[];
showDisabled: boolean;
- retentionDialogOpenOn: { datasource: string; rules: any[] } | null;
- compactionDialogOpenOn: { datasource: string; configData: any } | null;
- dropDataDatasource: string | null;
- enableDatasource: string | null;
- killDatasource: string | null;
- dropReloadDatasource: string | null;
+ retentionDialogOpenOn?: { datasource: string; rules: any[] };
+ compactionDialogOpenOn?: { datasource: string; configData: any };
+ dropDataDatasource?: string;
+ enableDatasource?: string;
+ killDatasource?: string;
+ dropReloadDatasource?: string;
dropReloadAction: 'drop' | 'reload';
dropReloadInterval: string;
hiddenColumns: LocalStorageBackedArray<string>;
@@ -167,16 +167,9 @@ GROUP BY 1`;
datasources: null,
tiers: [],
defaultRules: [],
- datasourcesError: null,
datasourcesFilter: [],
showDisabled: false,
- retentionDialogOpenOn: null,
- compactionDialogOpenOn: null,
- dropDataDatasource: null,
- enableDatasource: null,
- killDatasource: null,
- dropReloadDatasource: null,
dropReloadAction: 'drop',
dropReloadInterval: '',
hiddenColumns: new LocalStorageBackedArray<string>(
@@ -253,7 +246,7 @@ GROUP BY 1`;
datasources: result ? result.datasources : null,
tiers: result ? result.tiers : [],
defaultRules: result ? result.defaultRules : [],
- datasourcesError: error,
+ datasourcesError: error || undefined,
});
},
});
@@ -286,7 +279,7 @@ GROUP BY 1`;
failText="Could not drop data"
intent={Intent.DANGER}
onClose={() => {
- this.setState({ dropDataDatasource: null });
+ this.setState({ dropDataDatasource: undefined });
}}
onSuccess={() => {
this.datasourceQueryManager.rerunLastQuery();
@@ -317,7 +310,7 @@ GROUP BY 1`;
failText="Could not enable datasource"
intent={Intent.PRIMARY}
onClose={() => {
- this.setState({ enableDatasource: null });
+ this.setState({ enableDatasource: undefined });
}}
onSuccess={() => {
this.datasourceQueryManager.rerunLastQuery();
@@ -353,7 +346,7 @@ GROUP BY 1`;
failText={`Could not ${isDrop ? 'drop' : 'reload'} data`}
intent={Intent.PRIMARY}
onClose={() => {
- this.setState({ dropReloadDatasource: null });
+ this.setState({ dropReloadDatasource: undefined });
}}
onSuccess={() => {
this.datasourceQueryManager.rerunLastQuery();
@@ -392,7 +385,7 @@ GROUP BY 1`;
failText="Could not submit kill task"
intent={Intent.DANGER}
onClose={() => {
- this.setState({ killDatasource: null });
+ this.setState({ killDatasource: undefined });
}}
onSuccess={() => {
this.datasourceQueryManager.rerunLastQuery();
@@ -433,7 +426,7 @@ GROUP BY 1`;
const { datasources, defaultRules } = this.state;
if (!datasources) return;
- this.setState({ retentionDialogOpenOn: null });
+ this.setState({ retentionDialogOpenOn: undefined });
setTimeout(() => {
this.setState({
retentionDialogOpenOn: {
@@ -445,10 +438,10 @@ GROUP BY 1`;
};
private saveCompaction = async (compactionConfig: any) => {
- if (compactionConfig === null) return;
+ if (!compactionConfig) return;
try {
await axios.post(`/druid/coordinator/v1/config/compaction`, compactionConfig);
- this.setState({ compactionDialogOpenOn: null });
+ this.setState({ compactionDialogOpenOn: undefined });
this.datasourceQueryManager.rerunLastQuery();
} catch (e) {
AppToaster.show({
@@ -460,7 +453,7 @@ GROUP BY 1`;
private deleteCompaction = async () => {
const { compactionDialogOpenOn } = this.state;
- if (compactionDialogOpenOn === null) return;
+ if (!compactionDialogOpenOn) return;
const datasource = compactionDialogOpenOn.datasource;
AppToaster.show({
message: `Are you sure you want to delete ${datasource}'s compaction?`,
@@ -470,7 +463,7 @@ GROUP BY 1`;
onClick: async () => {
try {
await axios.delete(`/druid/coordinator/v1/config/compaction/${datasource}`);
- this.setState({ compactionDialogOpenOn: null }, () =>
+ this.setState({ compactionDialogOpenOn: undefined }, () =>
this.datasourceQueryManager.rerunLastQuery(),
);
} catch (e) {
@@ -547,7 +540,7 @@ GROUP BY 1`;
rules={retentionDialogOpenOn.rules}
tiers={tiers}
onEditDefaults={this.editDefaultRules}
- onCancel={() => this.setState({ retentionDialogOpenOn: null })}
+ onCancel={() => this.setState({ retentionDialogOpenOn: undefined })}
onSave={this.saveRules}
/>
);
@@ -562,7 +555,7 @@ GROUP BY 1`;
<CompactionDialog
datasource={compactionDialogOpenOn.datasource}
configData={compactionDialogOpenOn.configData}
- onClose={() => this.setState({ compactionDialogOpenOn: null })}
+ onClose={() => this.setState({ compactionDialogOpenOn: undefined })}
onSave={this.saveCompaction}
onDelete={this.deleteCompaction}
/>
@@ -808,7 +801,7 @@ GROUP BY 1`;
);
}
- render() {
+ render(): JSX.Element {
const { goToQuery, noSqlMode } = this.props;
const { showDisabled, hiddenColumns } = this.state;
diff --git a/web-console/src/views/home-view/__snapshots__/home-view.spec.tsx.snap b/web-console/src/views/home-view/__snapshots__/home-view.spec.tsx.snap
index 739c15e..37b29d2 100644
--- a/web-console/src/views/home-view/__snapshots__/home-view.spec.tsx.snap
+++ b/web-console/src/views/home-view/__snapshots__/home-view.spec.tsx.snap
@@ -9,7 +9,7 @@ exports[`home view matches snapshot 1`] = `
target="_blank"
>
<Blueprint3.Card
- className="status-card"
+ className="home-view-card"
elevation={0}
interactive={true}
>
@@ -30,7 +30,7 @@ exports[`home view matches snapshot 1`] = `
href="#datasources"
>
<Blueprint3.Card
- className="status-card"
+ className="home-view-card"
elevation={0}
interactive={true}
>
@@ -51,7 +51,7 @@ exports[`home view matches snapshot 1`] = `
href="#segments"
>
<Blueprint3.Card
- className="status-card"
+ className="home-view-card"
elevation={0}
interactive={true}
>
@@ -72,7 +72,7 @@ exports[`home view matches snapshot 1`] = `
href="#tasks"
>
<Blueprint3.Card
- className="status-card"
+ className="home-view-card"
elevation={0}
interactive={true}
>
@@ -93,7 +93,7 @@ exports[`home view matches snapshot 1`] = `
href="#tasks"
>
<Blueprint3.Card
- className="status-card"
+ className="home-view-card"
elevation={0}
interactive={true}
>
@@ -114,7 +114,7 @@ exports[`home view matches snapshot 1`] = `
href="#servers"
>
<Blueprint3.Card
- className="status-card"
+ className="home-view-card"
elevation={0}
interactive={true}
>
@@ -135,7 +135,7 @@ exports[`home view matches snapshot 1`] = `
href="#lookups"
>
<Blueprint3.Card
- className="status-card"
+ className="home-view-card"
elevation={0}
interactive={true}
>
diff --git a/web-console/src/views/home-view/home-view.scss b/web-console/src/views/home-view/home-view.scss
index 077a5b9..c2f5bb1 100644
--- a/web-console/src/views/home-view/home-view.scss
+++ b/web-console/src/views/home-view/home-view.scss
@@ -28,7 +28,7 @@
color: inherit;
}
- .status-card {
- height: 160px;
+ .home-view-card {
+ height: 170px;
}
}
diff --git a/web-console/src/views/home-view/home-view.tsx b/web-console/src/views/home-view/home-view.tsx
index 6090fe7..38eff67 100644
--- a/web-console/src/views/home-view/home-view.tsx
+++ b/web-console/src/views/home-view/home-view.tsx
@@ -34,7 +34,7 @@ export interface CardOptions {
title: string;
loading?: boolean;
content: JSX.Element | string;
- error?: string | null;
+ error?: string;
}
export interface HomeViewProps {
@@ -42,28 +42,23 @@ export interface HomeViewProps {
}
export interface HomeViewState {
- statusLoading: boolean;
- status: any;
- statusError: string | null;
+ versionLoading: boolean;
+ version: string;
+ versionError?: string;
datasourceCountLoading: boolean;
datasourceCount: number;
- datasourceCountError: string | null;
+ datasourceCountError?: string;
segmentCountLoading: boolean;
segmentCount: number;
unavailableSegmentCount: number;
- segmentCountError: string | null;
+ segmentCountError?: string;
supervisorCountLoading: boolean;
runningSupervisorCount: number;
suspendedSupervisorCount: number;
- supervisorCountError: string | null;
-
- lookupsCountLoading: boolean;
- lookupsCount: number;
- lookupsCountError: string | null;
- lookupsUninitialized: boolean;
+ supervisorCountError?: string;
taskCountLoading: boolean;
runningTaskCount: number;
@@ -71,7 +66,7 @@ export interface HomeViewState {
successTaskCount: number;
failedTaskCount: number;
waitingTaskCount: number;
- taskCountError: string | null;
+ taskCountError?: string;
serverCountLoading: boolean;
coordinatorCount: number;
@@ -81,11 +76,16 @@ export interface HomeViewState {
historicalCount: number;
middleManagerCount: number;
peonCount: number;
- serverCountError: string | null;
+ serverCountError?: string;
+
+ lookupsCountLoading: boolean;
+ lookupsCount: number;
+ lookupsUninitialized: boolean;
+ lookupsCountError?: string;
}
export class HomeView extends React.PureComponent<HomeViewProps, HomeViewState> {
- private statusQueryManager: QueryManager<null, any>;
+ private versionQueryManager: QueryManager<null, string>;
private datasourceQueryManager: QueryManager<boolean, any>;
private segmentQueryManager: QueryManager<boolean, any>;
private supervisorQueryManager: QueryManager<null, any>;
@@ -96,28 +96,19 @@ export class HomeView extends React.PureComponent<HomeViewProps, HomeViewState>
constructor(props: HomeViewProps, context: any) {
super(props, context);
this.state = {
- statusLoading: true,
- status: null,
- statusError: null,
+ versionLoading: true,
+ version: '',
datasourceCountLoading: false,
datasourceCount: 0,
- datasourceCountError: null,
segmentCountLoading: false,
segmentCount: 0,
unavailableSegmentCount: 0,
- segmentCountError: null,
supervisorCountLoading: false,
runningSupervisorCount: 0,
suspendedSupervisorCount: 0,
- supervisorCountError: null,
-
- lookupsCountLoading: false,
- lookupsCount: 0,
- lookupsCountError: null,
- lookupsUninitialized: false,
taskCountLoading: false,
runningTaskCount: 0,
@@ -125,7 +116,6 @@ export class HomeView extends React.PureComponent<HomeViewProps, HomeViewState>
successTaskCount: 0,
failedTaskCount: 0,
waitingTaskCount: 0,
- taskCountError: null,
serverCountLoading: false,
coordinatorCount: 0,
@@ -135,19 +125,22 @@ export class HomeView extends React.PureComponent<HomeViewProps, HomeViewState>
historicalCount: 0,
middleManagerCount: 0,
peonCount: 0,
- serverCountError: null,
+
+ lookupsCountLoading: false,
+ lookupsCount: 0,
+ lookupsUninitialized: false,
};
- this.statusQueryManager = new QueryManager({
+ this.versionQueryManager = new QueryManager({
processQuery: async () => {
const statusResp = await axios.get('/status');
- return statusResp.data;
+ return statusResp.data.version;
},
onStateChange: ({ result, loading, error }) => {
this.setState({
- statusLoading: loading,
- status: result,
- statusError: error,
+ versionLoading: loading,
+ version: result,
+ versionError: error,
});
},
});
@@ -169,7 +162,7 @@ export class HomeView extends React.PureComponent<HomeViewProps, HomeViewState>
this.setState({
datasourceCountLoading: loading,
datasourceCount: result,
- datasourceCountError: error,
+ datasourceCountError: error || undefined,
});
},
});
@@ -309,7 +302,7 @@ GROUP BY 1`,
processQuery: async () => {
const resp = await axios.get('/druid/coordinator/v1/lookups/status');
const data = resp.data;
- const lookupsCount = Object.keys(data.__default).length;
+ const lookupsCount = sum(Object.keys(data).map(k => Object.keys(data[k]).length));
return {
lookupsCount,
};
@@ -317,9 +310,9 @@ GROUP BY 1`,
onStateChange: ({ result, loading, error }) => {
this.setState({
lookupsCount: result ? result.lookupsCount : 0,
+ lookupsUninitialized: error === 'Request failed with status code 404',
lookupsCountLoading: loading,
lookupsCountError: error,
- lookupsUninitialized: error === 'Request failed with status code 404',
});
},
});
@@ -328,7 +321,7 @@ GROUP BY 1`,
componentDidMount(): void {
const { noSqlMode } = this.props;
- this.statusQueryManager.runQuery(null);
+ this.versionQueryManager.runQuery(null);
this.datasourceQueryManager.runQuery(noSqlMode);
this.segmentQueryManager.runQuery(noSqlMode);
this.supervisorQueryManager.runQuery(null);
@@ -338,7 +331,7 @@ GROUP BY 1`,
}
componentWillUnmount(): void {
- this.statusQueryManager.terminate();
+ this.versionQueryManager.terminate();
this.datasourceQueryManager.terminate();
this.segmentQueryManager.terminate();
this.supervisorQueryManager.terminate();
@@ -349,7 +342,7 @@ GROUP BY 1`,
renderCard(cardOptions: CardOptions): JSX.Element {
return (
<a href={cardOptions.href} target={cardOptions.href[0] === '/' ? '_blank' : undefined}>
- <Card className="status-card" interactive>
+ <Card className="home-view-card" interactive>
<H5>
<Icon color="#bfccd5" icon={cardOptions.icon} />
{cardOptions.title}
@@ -366,7 +359,7 @@ GROUP BY 1`,
);
}
- render() {
+ render(): JSX.Element {
const state = this.state;
return (
@@ -375,9 +368,9 @@ GROUP BY 1`,
href: UrlBaser.base('/status'),
icon: IconNames.GRAPH,
title: 'Status',
- loading: state.statusLoading,
- content: state.status ? `Apache Druid is running version ${state.status.version}` : '',
- error: state.statusError,
+ loading: state.versionLoading,
+ content: state.version ? `Apache Druid is running version ${state.version}` : '',
+ error: state.versionError,
})}
{this.renderCard({
href: '#datasources',
@@ -493,7 +486,7 @@ GROUP BY 1`,
</p>
</>
),
- error: !state.lookupsUninitialized ? state.lookupsCountError : null,
+ error: !state.lookupsUninitialized ? state.lookupsCountError : undefined,
})}
</div>
);
diff --git a/web-console/src/views/load-data-view/filter-table/filter-table.spec.tsx b/web-console/src/views/load-data-view/filter-table/filter-table.spec.tsx
index 935ebfd..a08fff6 100644
--- a/web-console/src/views/load-data-view/filter-table/filter-table.spec.tsx
+++ b/web-console/src/views/load-data-view/filter-table/filter-table.spec.tsx
@@ -39,8 +39,8 @@ describe('filter table', () => {
columnFilter=""
dimensionFilters={[]}
selectedFilterIndex={-1}
- onShowGlobalFilter={() => null}
- onFilterSelect={() => null}
+ onShowGlobalFilter={() => {}}
+ onFilterSelect={() => {}}
/>
);
diff --git a/web-console/src/views/load-data-view/filter-table/filter-table.tsx b/web-console/src/views/load-data-view/filter-table/filter-table.tsx
index 5fde4f8..d7da946 100644
--- a/web-console/src/views/load-data-view/filter-table/filter-table.tsx
+++ b/web-console/src/views/load-data-view/filter-table/filter-table.tsx
@@ -37,7 +37,7 @@ export interface FilterTableProps {
}
export class FilterTable extends React.PureComponent<FilterTableProps> {
- render() {
+ render(): JSX.Element {
const {
sampleData,
columnFilter,
diff --git a/web-console/src/views/load-data-view/load-data-view.scss b/web-console/src/views/load-data-view/load-data-view.scss
index 583ae58..003b1dc 100644
--- a/web-console/src/views/load-data-view/load-data-view.scss
+++ b/web-console/src/views/load-data-view/load-data-view.scss
@@ -30,20 +30,27 @@
'main next';
&.load-data-continue-view {
- display: grid;
- justify-content: center;
- grid-gap: $standard-padding;
- grid-template-columns: 500px 500px;
+ display: block;
+ text-align: center;
.spec-card {
+ display: inline-block;
+ width: 480px;
height: 100px;
- display: grid;
- grid-gap: $standard-padding;
- grid-template-columns: 30px 1fr;
+ margin: 10px;
+ text-align: left;
+
+ .spec-card-icon {
+ vertical-align: top;
+ }
.spec-card-header {
font-size: 25px;
line-height: 30px;
+ display: inline-block;
+ vertical-align: top;
+ padding-left: 10px;
+
.spec-card-caption {
font-size: 15px;
line-height: 20px;
diff --git a/web-console/src/views/load-data-view/load-data-view.tsx b/web-console/src/views/load-data-view/load-data-view.tsx
index 68e0815..f3de329 100644
--- a/web-console/src/views/load-data-view/load-data-view.tsx
+++ b/web-console/src/views/load-data-view/load-data-view.tsx
@@ -152,18 +152,16 @@ function showRawLine(line: string): string {
function getTimestampSpec(headerAndRows: HeaderAndRows | null): TimestampSpec {
if (!headerAndRows) return getEmptyTimestampSpec();
- const timestampSpecs = headerAndRows.header
- .map(sampleHeader => {
- const possibleFormat = possibleDruidFormatForValues(
- filterMap(headerAndRows.rows, d => (d.parsed ? d.parsed[sampleHeader] : null)),
- );
- if (!possibleFormat) return null;
- return {
- column: sampleHeader,
- format: possibleFormat,
- };
- })
- .filter(Boolean);
+ const timestampSpecs = filterMap(headerAndRows.header, sampleHeader => {
+ const possibleFormat = possibleDruidFormatForValues(
+ filterMap(headerAndRows.rows, d => (d.parsed ? d.parsed[sampleHeader] : undefined)),
+ );
+ if (!possibleFormat) return;
+ return {
+ column: sampleHeader,
+ format: possibleFormat,
+ };
+ });
return timestampSpecs[0] || getEmptyTimestampSpec();
}
@@ -220,25 +218,25 @@ const VIEW_TITLE: Record<Step, string> = {
};
export interface LoadDataViewProps {
- initSupervisorId?: string | null;
- initTaskId?: string | null;
+ initSupervisorId?: string;
+ initTaskId?: string;
goToTask: (taskId: string | undefined, supervisor?: string) => void;
}
export interface LoadDataViewState {
step: Step;
spec: IngestionSpec;
- cacheKey: string | undefined;
+ cacheKey?: string;
// dialogs / modals
showResetConfirm: boolean;
- newRollup: boolean | null;
- newDimensionMode: DimensionMode | null;
+ newRollup?: boolean;
+ newDimensionMode?: DimensionMode;
showViewValueModal: boolean;
str: string;
// welcome
- overlordModules: string[] | null;
- selectedComboType: IngestionComboTypeWithExtra | null;
+ overlordModules?: string[];
+ selectedComboType?: IngestionComboTypeWithExtra;
// general
sampleStrategy: SampleStrategy;
@@ -254,7 +252,7 @@ export interface LoadDataViewState {
// for flatten
flattenQueryState: QueryState<HeaderAndRows>;
selectedFlattenFieldIndex: number;
- selectedFlattenField: FlattenField | null;
+ selectedFlattenField?: FlattenField;
// for timestamp
timestampQueryState: QueryState<{
@@ -265,12 +263,12 @@ export interface LoadDataViewState {
// for transform
transformQueryState: QueryState<HeaderAndRows>;
selectedTransformIndex: number;
- selectedTransform: Transform | null;
+ selectedTransform?: Transform;
// for filter
filterQueryState: QueryState<HeaderAndRows>;
selectedFilterIndex: number;
- selectedFilter: DruidFilter | null;
+ selectedFilter?: DruidFilter;
showGlobalFilter: boolean;
// for schema
@@ -280,9 +278,9 @@ export interface LoadDataViewState {
metricsSpec: MetricSpec[];
}>;
selectedDimensionSpecIndex: number;
- selectedDimensionSpec: DimensionSpec | null;
+ selectedDimensionSpec?: DimensionSpec;
selectedMetricSpecIndex: number;
- selectedMetricSpec: MetricSpec | null;
+ selectedMetricSpec?: MetricSpec;
continueToSpec: boolean;
}
@@ -296,19 +294,12 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
this.state = {
step: 'welcome',
spec,
- cacheKey: undefined,
// dialogs / modals
showResetConfirm: false,
showViewValueModal: false,
- newRollup: null,
- newDimensionMode: null,
str: '',
- // welcome
- overlordModules: null,
- selectedComboType: null,
-
// general
sampleStrategy: 'start',
columnFilter: '',
@@ -323,7 +314,6 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
// for flatten
flattenQueryState: QueryState.INIT,
selectedFlattenFieldIndex: -1,
- selectedFlattenField: null,
// for timestamp
timestampQueryState: QueryState.INIT,
@@ -331,20 +321,16 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
// for transform
transformQueryState: QueryState.INIT,
selectedTransformIndex: -1,
- selectedTransform: null,
// for filter
filterQueryState: QueryState.INIT,
selectedFilterIndex: -1,
- selectedFilter: null,
showGlobalFilter: false,
// for dimensions
schemaQueryState: QueryState.INIT,
selectedDimensionSpecIndex: -1,
- selectedDimensionSpec: null,
selectedMetricSpecIndex: -1,
- selectedMetricSpec: null,
continueToSpec: false,
};
@@ -415,16 +401,16 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
localStorageSet(LocalStorageKeys.INGESTION_SPEC, JSON.stringify(newSpec));
};
- render() {
+ render(): JSX.Element {
const { step, continueToSpec } = this.state;
if (!continueToSpec) {
return (
<div className={classNames('load-data-continue-view load-data-view')}>
- <Card className={'spec-card'} interactive onClick={this.handleResetConfirm}>
- <Icon iconSize={30} icon={IconNames.ASTERISK} />
+ <Card className={'spec-card'} interactive onClick={this.handleResetSpec}>
+ <Icon className="spec-card-icon" icon={IconNames.ASTERISK} iconSize={30} />
<div className={'spec-card-header'}>
Start a new spec
- <div className={'spec-card-caption'}>start a new spec something something</div>
+ <div className={'spec-card-caption'}>Start a new ingestion flow</div>
</div>
</Card>
<Card
@@ -432,7 +418,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
interactive
onClick={() => this.setState({ continueToSpec: true })}
>
- <Icon icon={IconNames.REPEAT} iconSize={30} />
+ <Icon className="spec-card-icon" icon={IconNames.REPEAT} iconSize={30} />
<div className={'spec-card-header'}>
Continue from previous spec
<div className={'spec-card-caption'}>
@@ -444,6 +430,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
</div>
);
}
+
return (
<div className={classNames('load-data-view', 'app-view', step)}>
{this.renderStepNav()}
@@ -542,7 +529,9 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
className={classNames({ disabled: !goodToGo, active: selectedComboType === comboType })}
interactive
onClick={() => {
- this.setState({ selectedComboType: selectedComboType !== comboType ? comboType : null });
+ this.setState({
+ selectedComboType: selectedComboType !== comboType ? comboType : undefined,
+ });
}}
>
<img src={UrlBaser.base(`/assets/${getIngestionImage(comboType)}.png`)} />
@@ -765,6 +754,11 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
this.setState({ showResetConfirm: true });
};
+ private handleResetSpec = () => {
+ this.setState({ showResetConfirm: false, step: 'welcome', continueToSpec: true });
+ this.updateSpec({} as any);
+ };
+
renderResetConfirm() {
const { showResetConfirm } = this.state;
if (!showResetConfirm) return null;
@@ -777,10 +771,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
intent={Intent.DANGER}
isOpen
onCancel={() => this.setState({ showResetConfirm: false })}
- onConfirm={() => {
- this.setState({ showResetConfirm: false, step: 'welcome', continueToSpec: true });
- this.updateSpec({} as any);
- }}
+ onConfirm={this.handleResetSpec}
>
<p>This will discard the current progress in the spec.</p>
</Alert>
@@ -934,7 +925,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const parser: Parser = deepGet(spec, 'dataSchema.parser') || EMPTY_OBJECT;
const parserColumns: string[] = deepGet(parser, 'parseSpec.columns') || [];
- let issue: string | null = null;
+ let issue: string | undefined;
if (issueWithIoConfig(ioConfig)) {
issue = `IoConfig not ready, ${issueWithIoConfig(ioConfig)}`;
} else if (issueWithParser(parser)) {
@@ -1124,7 +1115,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const close = () => {
this.setState({
selectedFlattenFieldIndex: -1,
- selectedFlattenField: null,
+ selectedFlattenField: undefined,
});
};
@@ -1211,7 +1202,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const timestampSpec =
deepGet(spec, 'dataSchema.parser.parseSpec.timestampSpec') || EMPTY_OBJECT;
- let issue: string | null = null;
+ let issue: string | undefined;
if (issueWithIoConfig(ioConfig)) {
issue = `IoConfig not ready, ${issueWithIoConfig(ioConfig)}`;
} else if (issueWithParser(parser)) {
@@ -1380,7 +1371,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const parser: Parser = deepGet(spec, 'dataSchema.parser') || EMPTY_OBJECT;
const parserColumns: string[] = deepGet(parser, 'parseSpec.columns') || [];
- let issue: string | null = null;
+ let issue: string | undefined;
if (issueWithIoConfig(ioConfig)) {
issue = `IoConfig not ready, ${issueWithIoConfig(ioConfig)}`;
} else if (issueWithParser(parser)) {
@@ -1525,7 +1516,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const close = () => {
this.setState({
selectedTransformIndex: -1,
- selectedTransform: null,
+ selectedTransform: undefined,
});
};
@@ -1604,7 +1595,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const parser: Parser = deepGet(spec, 'dataSchema.parser') || EMPTY_OBJECT;
const parserColumns: string[] = deepGet(parser, 'parseSpec.columns') || [];
- let issue: string | null = null;
+ let issue: string | undefined;
if (issueWithIoConfig(ioConfig)) {
issue = `IoConfig not ready, ${issueWithIoConfig(ioConfig)}`;
} else if (issueWithParser(parser)) {
@@ -1765,7 +1756,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const close = () => {
this.setState({
selectedFilterIndex: -1,
- selectedFilter: null,
+ selectedFilter: undefined,
});
};
@@ -1909,7 +1900,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const dimensionsSpec: DimensionsSpec =
deepGet(spec, 'dataSchema.parser.parseSpec.dimensionsSpec') || EMPTY_OBJECT;
- let issue: string | null = null;
+ let issue: string | undefined;
if (issueWithIoConfig(ioConfig)) {
issue = `IoConfig not ready, ${issueWithIoConfig(ioConfig)}`;
} else if (issueWithParser(parser)) {
@@ -2134,9 +2125,9 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
}
private onDimensionOrMetricSelect = (
- selectedDimensionSpec: DimensionSpec | null,
+ selectedDimensionSpec: DimensionSpec | undefined,
selectedDimensionSpecIndex: number,
- selectedMetricSpec: MetricSpec | null,
+ selectedMetricSpec: MetricSpec | undefined,
selectedMetricSpecIndex: number,
) => {
this.setState({
@@ -2149,7 +2140,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
renderChangeRollupAction() {
const { newRollup, spec, sampleStrategy, cacheKey } = this.state;
- if (newRollup === null) return;
+ if (typeof newRollup === 'undefined') return;
return (
<AsyncActionDialog
@@ -2171,7 +2162,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
successText={`Rollup was ${newRollup ? 'enabled' : 'disabled'}. Schema has been updated.`}
failText="Could change rollup"
intent={Intent.WARNING}
- onClose={() => this.setState({ newRollup: null })}
+ onClose={() => this.setState({ newRollup: undefined })}
>
<p>{`Are you sure you want to ${newRollup ? 'enable' : 'disable'} rollup?`}</p>
<p>Making this change will reset any work you have done in this section.</p>
@@ -2181,7 +2172,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
renderChangeDimensionModeAction() {
const { newDimensionMode, spec, sampleStrategy, cacheKey } = this.state;
- if (newDimensionMode === null) return;
+ if (typeof newDimensionMode === 'undefined') return;
const autoDetect = newDimensionMode === 'auto-detect';
return (
@@ -2206,7 +2197,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
}. Schema has been updated.`}
failText="Could change dimension mode"
intent={Intent.WARNING}
- onClose={() => this.setState({ newDimensionMode: null })}
+ onClose={() => this.setState({ newDimensionMode: undefined })}
>
<p>
{autoDetect
@@ -2224,7 +2215,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const close = () => {
this.setState({
selectedDimensionSpecIndex: -1,
- selectedDimensionSpec: null,
+ selectedDimensionSpec: undefined,
});
};
@@ -2310,7 +2301,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
const close = () => {
this.setState({
selectedMetricSpecIndex: -1,
- selectedMetricSpec: null,
+ selectedMetricSpec: undefined,
});
};
diff --git a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.spec.tsx b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.spec.tsx
index 753dabb..92da603 100644
--- a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.spec.tsx
+++ b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.spec.tsx
@@ -35,13 +35,13 @@ describe('parse data table', () => {
const parseDataTable = (
<ParseDataTable
- openModal={() => null}
+ openModal={() => {}}
sampleData={sampleData}
columnFilter=""
canFlatten={false}
flattenedColumnsOnly={false}
flattenFields={[]}
- onFlattenFieldSelect={() => null}
+ onFlattenFieldSelect={() => {}}
/>
);
diff --git a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx
index 9a47216..2d00968 100644
--- a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx
+++ b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx
@@ -38,7 +38,7 @@ export interface ParseDataTableProps {
}
export class ParseDataTable extends React.PureComponent<ParseDataTableProps> {
- render() {
+ render(): JSX.Element {
const {
sampleData,
columnFilter,
diff --git a/web-console/src/views/load-data-view/parse-time-table/parse-time-table.spec.tsx b/web-console/src/views/load-data-view/parse-time-table/parse-time-table.spec.tsx
index ea5aa5a..4982d7e 100644
--- a/web-console/src/views/load-data-view/parse-time-table/parse-time-table.spec.tsx
+++ b/web-console/src/views/load-data-view/parse-time-table/parse-time-table.spec.tsx
@@ -43,7 +43,7 @@ describe('parse time table', () => {
}}
columnFilter=""
possibleTimestampColumnsOnly={false}
- onTimestampColumnSelect={() => null}
+ onTimestampColumnSelect={() => {}}
/>
);
diff --git a/web-console/src/views/load-data-view/parse-time-table/parse-time-table.tsx b/web-console/src/views/load-data-view/parse-time-table/parse-time-table.tsx
index f2a79ca..ae1b16b 100644
--- a/web-console/src/views/load-data-view/parse-time-table/parse-time-table.tsx
+++ b/web-console/src/views/load-data-view/parse-time-table/parse-time-table.tsx
@@ -43,7 +43,7 @@ export interface ParseTimeTableProps {
}
export class ParseTimeTable extends React.PureComponent<ParseTimeTableProps> {
- render() {
+ render(): JSX.Element {
const {
sampleBundle,
columnFilter,
@@ -67,7 +67,7 @@ export class ParseTimeTable extends React.PureComponent<ParseTimeTableProps> {
const possibleFormat = timestamp
? null
: possibleDruidFormatForValues(
- filterMap(headerAndRows.rows, d => (d.parsed ? d.parsed[columnName] : null)),
+ filterMap(headerAndRows.rows, d => (d.parsed ? d.parsed[columnName] : undefined)),
);
if (possibleTimestampColumnsOnly && !timestamp && !possibleFormat) return;
diff --git a/web-console/src/views/load-data-view/schema-table/schema-table.spec.tsx b/web-console/src/views/load-data-view/schema-table/schema-table.spec.tsx
index fd530a4..9695696 100644
--- a/web-console/src/views/load-data-view/schema-table/schema-table.spec.tsx
+++ b/web-console/src/views/load-data-view/schema-table/schema-table.spec.tsx
@@ -43,7 +43,7 @@ describe('schema table', () => {
columnFilter=""
selectedDimensionSpecIndex={-1}
selectedMetricSpecIndex={-1}
- onDimensionOrMetricSelect={() => null}
+ onDimensionOrMetricSelect={() => {}}
/>
);
diff --git a/web-console/src/views/load-data-view/schema-table/schema-table.tsx b/web-console/src/views/load-data-view/schema-table/schema-table.tsx
index fbbaefa..bbfc5f9 100644
--- a/web-console/src/views/load-data-view/schema-table/schema-table.tsx
+++ b/web-console/src/views/load-data-view/schema-table/schema-table.tsx
@@ -45,15 +45,15 @@ export interface SchemaTableProps {
selectedDimensionSpecIndex: number;
selectedMetricSpecIndex: number;
onDimensionOrMetricSelect: (
- selectedDimensionSpec: DimensionSpec | null,
+ selectedDimensionSpec: DimensionSpec | undefined,
selectedDimensionSpecIndex: number,
- selectedMetricSpec: MetricSpec | null,
+ selectedMetricSpec: MetricSpec | undefined,
selectedMetricSpecIndex: number,
) => void;
}
export class SchemaTable extends React.PureComponent<SchemaTableProps> {
- render() {
+ render(): JSX.Element {
const {
sampleBundle,
columnFilter,
@@ -88,7 +88,9 @@ export class SchemaTable extends React.PureComponent<SchemaTableProps> {
Header: (
<div
className="clickable"
- onClick={() => onDimensionOrMetricSelect(null, -1, metricSpec, metricSpecIndex)}
+ onClick={() =>
+ onDimensionOrMetricSelect(undefined, -1, metricSpec, metricSpecIndex)
+ }
>
<div className="column-name">{columnName}</div>
<div className="column-detail">{metricSpec.type} </div>
@@ -123,7 +125,7 @@ export class SchemaTable extends React.PureComponent<SchemaTableProps> {
className="clickable"
onClick={() => {
if (timestamp) {
- onDimensionOrMetricSelect(null, -1, null, -1);
+ onDimensionOrMetricSelect(undefined, -1, undefined, -1);
return;
}
@@ -131,7 +133,7 @@ export class SchemaTable extends React.PureComponent<SchemaTableProps> {
onDimensionOrMetricSelect(
inflateDimensionSpec(dimensionSpec),
dimensionSpecIndex,
- null,
+ undefined,
-1,
);
}}
diff --git a/web-console/src/views/load-data-view/transform-table/transform-table.spec.tsx b/web-console/src/views/load-data-view/transform-table/transform-table.spec.tsx
index 99608e8..964c338 100644
--- a/web-console/src/views/load-data-view/transform-table/transform-table.spec.tsx
+++ b/web-console/src/views/load-data-view/transform-table/transform-table.spec.tsx
@@ -40,7 +40,7 @@ describe('transform table', () => {
transformedColumnsOnly={false}
transforms={[]}
selectedTransformIndex={-1}
- onTransformSelect={() => null}
+ onTransformSelect={() => {}}
/>
);
diff --git a/web-console/src/views/load-data-view/transform-table/transform-table.tsx b/web-console/src/views/load-data-view/transform-table/transform-table.tsx
index 50c3e01..fb5bd79 100644
--- a/web-console/src/views/load-data-view/transform-table/transform-table.tsx
+++ b/web-console/src/views/load-data-view/transform-table/transform-table.tsx
@@ -38,7 +38,7 @@ export interface TransformTableProps {
}
export class TransformTable extends React.PureComponent<TransformTableProps> {
- render() {
+ render(): JSX.Element {
const {
sampleData,
columnFilter,
diff --git a/web-console/src/views/lookups-view/__snapshots__/lookups-view.spec.tsx.snap b/web-console/src/views/lookups-view/__snapshots__/lookups-view.spec.tsx.snap
index a57aea4..58c894d 100755
--- a/web-console/src/views/lookups-view/__snapshots__/lookups-view.spec.tsx.snap
+++ b/web-console/src/views/lookups-view/__snapshots__/lookups-view.spec.tsx.snap
@@ -14,7 +14,7 @@ exports[`lookups view matches snapshot 1`] = `
<Blueprint3.Button
icon="plus"
onClick={[Function]}
- text="Add"
+ text="Add lookup"
/>
<TableColumnSelector
columns={
diff --git a/web-console/src/views/lookups-view/lookups-view.tsx b/web-console/src/views/lookups-view/lookups-view.tsx
index 2b6bb19..c29cfd7 100644
--- a/web-console/src/views/lookups-view/lookups-view.tsx
+++ b/web-console/src/views/lookups-view/lookups-view.tsx
@@ -38,9 +38,9 @@ const DEFAULT_LOOKUP_TIER: string = '__default';
export interface LookupsViewProps {}
export interface LookupsViewState {
- lookups: {}[] | null;
+ lookups?: any[];
loadingLookups: boolean;
- lookupsError: string | null;
+ lookupsError?: string;
lookupsUninitialized: boolean;
lookupEditDialogOpen: boolean;
lookupEditName: string;
@@ -50,8 +50,8 @@ export interface LookupsViewState {
isEdit: boolean;
allLookupTiers: string[];
- deleteLookupName: string | null;
- deleteLookupTier: string | null;
+ deleteLookupName?: string;
+ deleteLookupTier?: string;
hiddenColumns: LocalStorageBackedArray<string>;
}
@@ -64,7 +64,6 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
this.state = {
lookups: [],
loadingLookups: true,
- lookupsError: null,
lookupsUninitialized: false,
lookupEditDialogOpen: false,
lookupEditTier: '',
@@ -74,9 +73,6 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
isEdit: false,
allLookupTiers: [],
- deleteLookupTier: null,
- deleteLookupName: null,
-
hiddenColumns: new LocalStorageBackedArray<string>(
LocalStorageKeys.LOOKUP_TABLE_COLUMN_SELECTION,
),
@@ -110,11 +106,11 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
},
onStateChange: ({ result, loading, error }) => {
this.setState({
- lookups: result ? result.lookupEntries : null,
+ lookups: result ? result.lookupEntries : undefined,
loadingLookups: loading,
lookupsError: error,
lookupsUninitialized: error === 'Request failed with status code 404',
- allLookupTiers: result === null ? [] : result.tiers,
+ allLookupTiers: result ? result.tiers : [],
});
},
});
@@ -169,11 +165,11 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
}
}
- private changeLookup(field: string, value: string) {
+ private handleChangeLookup = (field: string, value: string) => {
this.setState({
[field]: value,
} as any);
- }
+ };
private async submitLookupEdit() {
const {
@@ -249,7 +245,7 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
failText="Could not delete lookup"
intent={Intent.DANGER}
onClose={() => {
- this.setState({ deleteLookupTier: null, deleteLookupName: null });
+ this.setState({ deleteLookupTier: undefined, deleteLookupName: undefined });
}}
onSuccess={() => {
this.lookupsQueryManager.rerunLastQuery();
@@ -274,7 +270,7 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
<div className="init-div">
<Button
icon={IconNames.BUILD}
- text="Initialize lookup"
+ text="Initialize lookups"
onClick={() => this.initializeLookup()}
/>
</div>
@@ -356,7 +352,7 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
isOpen={lookupEditDialogOpen}
onClose={() => this.setState({ lookupEditDialogOpen: false })}
onSubmit={() => this.submitLookupEdit()}
- onChange={(field: string, value: string) => this.changeLookup(field, value)}
+ onChange={this.handleChangeLookup}
lookupSpec={lookupEditSpec}
lookupName={lookupEditName}
lookupTier={lookupEditTier}
@@ -367,7 +363,7 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
);
}
- render() {
+ render(): JSX.Element {
const { lookupsError, hiddenColumns } = this.state;
return (
@@ -380,7 +376,7 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
{!lookupsError && (
<Button
icon={IconNames.PLUS}
- text="Add"
+ text="Add lookup"
onClick={() => this.openLookupEditDialog('', '')}
/>
)}
diff --git a/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap b/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap
index 3e4cfff..bbcdaf8 100644
--- a/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap
+++ b/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap
@@ -5,7 +5,6 @@ exports[`sql view matches snapshot 1`] = `
className="query-view app-view"
>
<ColumnTree
- columnMetadata={null}
columnMetadataLoading={true}
onQueryStringChange={[Function]}
/>
@@ -25,7 +24,6 @@ exports[`sql view matches snapshot 1`] = `
className="control-pane"
>
<QueryInput
- columnMetadata={null}
onQueryStringChange={[Function]}
queryString="test"
runeMode={false}
@@ -43,9 +41,7 @@ exports[`sql view matches snapshot 1`] = `
</div>
</div>
<QueryOutput
- error={null}
loading={false}
- result={null}
/>
</t>
</div>
diff --git a/web-console/src/views/query-view/column-tree/column-tree.spec.tsx b/web-console/src/views/query-view/column-tree/column-tree.spec.tsx
index bdfe4fc..e8ca98d 100644
--- a/web-console/src/views/query-view/column-tree/column-tree.spec.tsx
+++ b/web-console/src/views/query-view/column-tree/column-tree.spec.tsx
@@ -50,7 +50,7 @@ describe('column tree', () => {
},
] as ColumnMetadata[]
}
- onQueryStringChange={() => null}
+ onQueryStringChange={() => {}}
/>
);
diff --git a/web-console/src/views/query-view/column-tree/column-tree.tsx b/web-console/src/views/query-view/column-tree/column-tree.tsx
index f95708a..4e0d24f 100644
--- a/web-console/src/views/query-view/column-tree/column-tree.tsx
+++ b/web-console/src/views/query-view/column-tree/column-tree.tsx
@@ -28,13 +28,13 @@ import './column-tree.scss';
export interface ColumnTreeProps {
columnMetadataLoading: boolean;
- columnMetadata: ColumnMetadata[] | null;
+ columnMetadata?: ColumnMetadata[];
onQueryStringChange: (queryString: string) => void;
}
export interface ColumnTreeState {
- prevColumnMetadata: ColumnMetadata[] | null;
- columnTree: ITreeNode[] | null;
+ prevColumnMetadata?: ColumnMetadata[];
+ columnTree?: ITreeNode[];
selectedTreeIndex: number;
}
@@ -88,8 +88,6 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
constructor(props: ColumnTreeProps, context: any) {
super(props, context);
this.state = {
- prevColumnMetadata: null,
- columnTree: null,
selectedTreeIndex: 0,
};
}
@@ -120,7 +118,7 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
this.setState({ selectedTreeIndex: Number(e.target.value) });
};
- render() {
+ render(): JSX.Element | null {
const { columnMetadataLoading } = this.props;
if (columnMetadataLoading) {
return (
@@ -155,21 +153,28 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
const { columnTree, selectedTreeIndex } = this.state;
if (!columnTree) return;
+ const selectedNode = columnTree[selectedTreeIndex];
switch (nodePath.length) {
case 1: // Datasource
- const tableSchema = columnTree[selectedTreeIndex].label;
+ const tableSchema = selectedNode.label;
+ let columns: string[];
+ if (nodeData.childNodes) {
+ columns = nodeData.childNodes.map(child => String(child.label));
+ } else {
+ columns = ['*'];
+ }
if (tableSchema === 'druid') {
- onQueryStringChange(`SELECT *
+ onQueryStringChange(`SELECT ${columns.join(', ')}
FROM "${nodeData.label}"
WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY`);
} else {
- onQueryStringChange(`SELECT *
+ onQueryStringChange(`SELECT ${columns.join(', ')}
FROM ${tableSchema}.${nodeData.label}`);
}
break;
case 2: // Column
- const schemaNode = columnTree[selectedTreeIndex];
+ const schemaNode = selectedNode;
const columnSchema = schemaNode.label;
const columnTable = schemaNode.childNodes ? schemaNode.childNodes[nodePath[0]].label : '?';
if (columnSchema === 'druid') {
diff --git a/web-console/src/views/query-view/query-extra-info/query-extra-info.spec.tsx b/web-console/src/views/query-view/query-extra-info/query-extra-info.spec.tsx
index d173ceb..fb1ea2e 100644
--- a/web-console/src/views/query-view/query-extra-info/query-extra-info.spec.tsx
+++ b/web-console/src/views/query-view/query-extra-info/query-extra-info.spec.tsx
@@ -27,13 +27,12 @@ describe('query extra info', () => {
<QueryExtraInfo
queryExtraInfo={{
queryId: 'e3ee781b-c0b6-4385-9d99-a8a1994bebac',
- sqlQueryId: null,
startTime: new Date('1986-04-26T01:23:40+03:00'),
endTime: new Date('1986-04-26T01:23:48+03:00'),
numResults: 2000,
wrappedLimit: 2000,
}}
- onDownload={() => null}
+ onDownload={() => {}}
/>
);
diff --git a/web-console/src/views/query-view/query-extra-info/query-extra-info.tsx b/web-console/src/views/query-view/query-extra-info/query-extra-info.tsx
index d4dbbd6..a25cd79 100644
--- a/web-console/src/views/query-view/query-extra-info/query-extra-info.tsx
+++ b/web-console/src/views/query-view/query-extra-info/query-extra-info.tsx
@@ -36,8 +36,8 @@ import { pluralIfNeeded } from '../../../utils';
import './query-extra-info.scss';
export interface QueryExtraInfoData {
- queryId: string | null;
- sqlQueryId: string | null;
+ queryId?: string;
+ sqlQueryId?: string;
startTime: Date;
endTime: Date;
numResults: number;
@@ -50,7 +50,7 @@ export interface QueryExtraInfoProps {
}
export class QueryExtraInfo extends React.PureComponent<QueryExtraInfoProps> {
- render() {
+ render(): JSX.Element {
const { queryExtraInfo } = this.props;
const downloadMenu = (
diff --git a/web-console/src/views/query-view/query-input/query-input.spec.tsx b/web-console/src/views/query-view/query-input/query-input.spec.tsx
index b78ba60..f391e3d 100644
--- a/web-console/src/views/query-view/query-input/query-input.spec.tsx
+++ b/web-console/src/views/query-view/query-input/query-input.spec.tsx
@@ -24,12 +24,7 @@ import { QueryInput } from './query-input';
describe('query input', () => {
it('matches snapshot', () => {
const sqlControl = (
- <QueryInput
- queryString="hello world"
- onQueryStringChange={() => null}
- runeMode={false}
- columnMetadata={null}
- />
+ <QueryInput queryString="hello world" onQueryStringChange={() => {}} runeMode={false} />
);
const { container } = render(sqlControl);
diff --git a/web-console/src/views/query-view/query-input/query-input.tsx b/web-console/src/views/query-view/query-input/query-input.tsx
index 3d65057..0970888 100644
--- a/web-console/src/views/query-view/query-input/query-input.tsx
+++ b/web-console/src/views/query-view/query-input/query-input.tsx
@@ -18,9 +18,9 @@
import { IResizeEntry, ResizeSensor } from '@blueprintjs/core';
import ace from 'brace';
+import escape from 'lodash.escape';
import React from 'react';
import AceEditor from 'react-ace';
-import ReactDOMServer from 'react-dom/server';
import { SQL_DATE_TYPES, SQL_FUNCTIONS, SyntaxDescription } from '../../../../lib/sql-function-doc';
import { uniq } from '../../../utils';
@@ -37,14 +37,14 @@ export interface QueryInputProps {
queryString: string;
onQueryStringChange: (newQueryString: string) => void;
runeMode: boolean;
- columnMetadata: ColumnMetadata[] | null;
+ columnMetadata?: ColumnMetadata[];
}
export interface QueryInputState {
// For reasons (https://github.com/securingsincity/react-ace/issues/415) react ace editor needs an explicit height
// Since this component will grown and shrink dynamically we will measure its height and then set it.
editorHeight: number;
- prevColumnMetadata: ColumnMetadata[] | null;
+ prevColumnMetadata?: ColumnMetadata[];
}
export class QueryInput extends React.PureComponent<QueryInputProps, QueryInputState> {
@@ -87,7 +87,6 @@ export class QueryInput extends React.PureComponent<QueryInputProps, QueryInputS
super(props, context);
this.state = {
editorHeight: 200,
- prevColumnMetadata: null,
};
}
@@ -143,23 +142,22 @@ export class QueryInput extends React.PureComponent<QueryInputProps, QueryInputS
getDocTooltip: (item: any) => {
if (item.meta === 'function') {
const functionName = item.caption.slice(0, -2);
- item.docHTML = ReactDOMServer.renderToStaticMarkup(
- <div className="function-doc">
- <div className="function-doc-name">
- <b>{functionName}</b>
- </div>
- <hr />
- <div>
- <b>Syntax:</b>
- </div>
- <div>{item.syntax}</div>
- <br />
- <div>
- <b>Description:</b>
- </div>
- <div>{item.description}</div>
- </div>,
- );
+ item.docHTML = `
+<div class="function-doc">
+ <div class="function-doc-name">
+ <b>${escape(functionName)}</b>
+ </div>
+ <hr />
+ <div>
+ <b>Syntax:</b>
+ </div>
+ <div>${escape(item.syntax)}</div>
+ <br />
+ <div>
+ <b>Description:</b>
+ </div>
+ <div>${escape(item.description)}</div>
+</div>`;
}
},
});
@@ -175,7 +173,7 @@ export class QueryInput extends React.PureComponent<QueryInputProps, QueryInputS
this.setState({ editorHeight: entries[0].contentRect.height });
};
- render() {
+ render(): JSX.Element {
const { queryString, runeMode, onQueryStringChange } = this.props;
const { editorHeight } = this.state;
@@ -205,6 +203,7 @@ export class QueryInput extends React.PureComponent<QueryInputProps, QueryInputS
tabSize: 2,
}}
style={{}}
+ placeholder="SELECT * FROM ..."
/>
</div>
</ResizeSensor>
diff --git a/web-console/src/views/query-view/query-output/query-output.spec.tsx b/web-console/src/views/query-view/query-output/query-output.spec.tsx
index 3852b72..8c18e07 100644
--- a/web-console/src/views/query-view/query-output/query-output.spec.tsx
+++ b/web-console/src/views/query-view/query-output/query-output.spec.tsx
@@ -23,7 +23,7 @@ import { QueryOutput } from './query-output';
describe('query output', () => {
it('matches snapshot', () => {
- const queryOutput = <QueryOutput loading={false} result={null} error="lol" />;
+ const queryOutput = <QueryOutput loading={false} error="lol" />;
const { container } = render(queryOutput);
expect(container.firstChild).toMatchSnapshot();
diff --git a/web-console/src/views/query-view/query-output/query-output.tsx b/web-console/src/views/query-view/query-output/query-output.tsx
index e35856a..ec3428f 100644
--- a/web-console/src/views/query-view/query-output/query-output.tsx
+++ b/web-console/src/views/query-view/query-output/query-output.tsx
@@ -26,12 +26,12 @@ import './query-output.scss';
export interface QueryOutputProps {
loading: boolean;
- result: HeaderRows | null;
- error: string | null;
+ result?: HeaderRows;
+ error?: string;
}
export class QueryOutput extends React.PureComponent<QueryOutputProps> {
- render() {
+ render(): JSX.Element {
const { result, loading, error } = this.props;
return (
diff --git a/web-console/src/views/query-view/query-view.tsx b/web-console/src/views/query-view/query-view.tsx
index 6395409..8408ddf 100644
--- a/web-console/src/views/query-view/query-view.tsx
+++ b/web-console/src/views/query-view/query-view.tsx
@@ -65,18 +65,18 @@ export interface QueryViewState {
queryContext: QueryContext;
columnMetadataLoading: boolean;
- columnMetadata: ColumnMetadata[] | null;
- columnMetadataError: string | null;
+ columnMetadata?: ColumnMetadata[];
+ columnMetadataError?: string;
loading: boolean;
- result: HeaderRows | null;
- queryExtraInfo: QueryExtraInfoData | null;
- error: string | null;
+ result?: HeaderRows;
+ queryExtraInfo?: QueryExtraInfoData;
+ error?: string;
explainDialogOpen: boolean;
- explainResult: BasicQueryExplanation | SemiJoinQueryExplanation | string | null;
+ explainResult?: BasicQueryExplanation | SemiJoinQueryExplanation | string;
loadingExplain: boolean;
- explainError: Error | null;
+ explainError?: string;
}
interface QueryResult {
@@ -133,18 +133,11 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
queryContext: {},
columnMetadataLoading: false,
- columnMetadata: null,
- columnMetadataError: null,
loading: false,
- result: null,
- queryExtraInfo: null,
- error: null,
explainDialogOpen: false,
loadingExplain: false,
- explainResult: null,
- explainError: null,
};
this.metadataQueryManager = new QueryManager({
@@ -171,8 +164,8 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
this.sqlQueryManager = new QueryManager({
processQuery: async (queryWithContext: QueryWithContext): Promise<QueryResult> => {
const { queryString, queryContext, wrapQuery } = queryWithContext;
- let queryId: string | null = null;
- let sqlQueryId: string | null = null;
+ let queryId: string | undefined;
+ let sqlQueryId: string | undefined;
let wrappedLimit: number | undefined;
let queryResult: HeaderRows;
@@ -239,8 +232,8 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
},
onStateChange: ({ result, loading, error }) => {
this.setState({
- result: result ? result.queryResult : null,
- queryExtraInfo: result ? result.queryExtraInfo : null,
+ result: result ? result.queryResult : undefined,
+ queryExtraInfo: result ? result.queryExtraInfo : undefined,
loading,
error,
});
@@ -264,7 +257,7 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
this.setState({
explainResult: result,
loadingExplain: loading,
- explainError: error !== null ? new Error(error) : null,
+ explainError: error,
});
},
});
@@ -312,16 +305,15 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
renderExplainDialog() {
const { explainDialogOpen, explainResult, loadingExplain, explainError } = this.state;
- if (!loadingExplain && explainDialogOpen) {
- return (
- <QueryPlanDialog
- explainResult={explainResult}
- explainError={explainError}
- onClose={() => this.setState({ explainDialogOpen: false })}
- />
- );
- }
- return null;
+ if (loadingExplain || !explainDialogOpen) return;
+
+ return (
+ <QueryPlanDialog
+ explainResult={explainResult}
+ explainError={explainError}
+ onClose={() => this.setState({ explainDialogOpen: false })}
+ />
+ );
}
renderMainArea() {
@@ -399,7 +391,7 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
localStorageSet(LocalStorageKeys.QUERY_VIEW_PANE_SIZE, String(secondaryPaneSize));
};
- render() {
+ render(): JSX.Element {
const { columnMetadata, columnMetadataLoading, columnMetadataError } = this.state;
return (
diff --git a/web-console/src/views/query-view/run-button/run-button.spec.tsx b/web-console/src/views/query-view/run-button/run-button.spec.tsx
index 4529cc7..cbc57ae 100644
--- a/web-console/src/views/query-view/run-button/run-button.spec.tsx
+++ b/web-console/src/views/query-view/run-button/run-button.spec.tsx
@@ -27,9 +27,9 @@ describe('run button', () => {
<RunButton
runeMode={false}
queryContext={{}}
- onQueryContextChange={() => null}
- onRun={() => null}
- onExplain={() => null}
+ onQueryContextChange={() => {}}
+ onRun={() => {}}
+ onExplain={() => {}}
/>
);
diff --git a/web-console/src/views/query-view/run-button/run-button.tsx b/web-console/src/views/query-view/run-button/run-button.tsx
index f987c13..78fecfc 100644
--- a/web-console/src/views/query-view/run-button/run-button.tsx
+++ b/web-console/src/views/query-view/run-button/run-button.tsx
@@ -47,7 +47,7 @@ export interface RunButtonProps {
runeMode: boolean;
queryContext: QueryContext;
onQueryContextChange: (newQueryContext: QueryContext) => void;
- onRun: ((wrapQuery: boolean) => void) | null;
+ onRun: (wrapQuery: boolean) => void;
onExplain: () => void;
}
@@ -137,7 +137,7 @@ export class RunButton extends React.PureComponent<RunButtonProps, RunButtonStat
);
}
- render() {
+ render(): JSX.Element {
const { runeMode, onRun } = this.props;
const { wrapQuery } = this.state;
diff --git a/web-console/src/views/segments-view/segments-view.tsx b/web-console/src/views/segments-view/segments-view.tsx
index 33b5c2b..8ec0cc8 100644
--- a/web-console/src/views/segments-view/segments-view.tsx
+++ b/web-console/src/views/segments-view/segments-view.tsx
@@ -28,6 +28,7 @@ import { AsyncActionDialog } from '../../dialogs';
import { SegmentTableActionDialog } from '../../dialogs/segments-table-action-dialog/segment-table-action-dialog';
import {
addFilter,
+ filterMap,
formatBytes,
formatNumber,
LocalStorageKeys,
@@ -76,15 +77,15 @@ export interface SegmentsViewProps {
export interface SegmentsViewState {
segmentsLoading: boolean;
- segments: SegmentQueryResultRow[] | null;
- segmentsError: string | null;
+ segments?: SegmentQueryResultRow[];
+ segmentsError?: string;
segmentFilter: Filter[];
- allSegments?: SegmentQueryResultRow[] | null;
- segmentTableActionDialogId: string | null;
- datasourceTableActionDialogId: string | null;
+ allSegments?: SegmentQueryResultRow[];
+ segmentTableActionDialogId?: string;
+ datasourceTableActionDialogId?: string;
actions: BasicAction[];
- terminateSegmentId: string | null;
- terminateDatasourceId: string | null;
+ terminateSegmentId?: string;
+ terminateDatasourceId?: string;
hiddenColumns: LocalStorageBackedArray<string>;
loaded: boolean;
groupByInterval: boolean;
@@ -140,14 +141,8 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
if (props.onlyUnavailable) segmentFilter.push({ id: 'is_available', value: 'false' });
this.state = {
- segmentTableActionDialogId: null,
- datasourceTableActionDialogId: null,
actions: [],
- terminateSegmentId: null,
- terminateDatasourceId: null,
segmentsLoading: true,
- segments: null,
- segmentsError: null,
segmentFilter,
hiddenColumns: new LocalStorageBackedArray<string>(
LocalStorageKeys.SEGMENT_TABLE_COLUMN_SELECTION,
@@ -166,16 +161,14 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
processQuery: async (query: SegmentsQuery, setIntermediateQuery) => {
const totalQuerySize = (query.page + 1) * query.pageSize;
- const whereParts = query.filtered
- .map((f: Filter) => {
- if (f.id.startsWith('is_')) {
- if (f.value === 'all') return null;
- return `${JSON.stringify(f.id)} = ${f.value === 'true' ? 1 : 0}`;
- } else {
- return sqlQueryCustomTableFilter(f);
- }
- })
- .filter(Boolean);
+ const whereParts = filterMap(query.filtered, (f: Filter) => {
+ if (f.id.startsWith('is_')) {
+ if (f.value === 'all') return;
+ return `${JSON.stringify(f.id)} = ${f.value === 'true' ? 1 : 0}`;
+ } else {
+ return sqlQueryCustomTableFilter(f);
+ }
+ });
let queryParts: string[];
if (query.groupByInterval) {
@@ -258,6 +251,7 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
datasourceList.map(async (d: string) => {
const segments = (await axios.get(`/druid/coordinator/v1/datasources/${d}?full`)).data
.segments;
+
return segments.map((segment: any) => {
return {
segment_id: segment.identifier,
@@ -278,17 +272,17 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
});
}),
);
- const results: SegmentQueryResultRow[] = ([] as SegmentQueryResultRow[]).concat
- .apply([], nestedResults)
- .sort((d1: any, d2: any) => {
- return d2.start.localeCompare(d1.start);
- });
- return results;
+
+ const results: SegmentQueryResultRow[] = nestedResults.flat().sort((d1: any, d2: any) => {
+ return d2.start.localeCompare(d1.start);
+ });
+
+ return results.slice(0, SegmentsView.PAGE_SIZE);
},
onStateChange: ({ result, loading, error }) => {
this.setState({
allSegments: result,
- segments: result ? result.slice(0, SegmentsView.PAGE_SIZE) : null,
+ segments: result,
segmentsLoading: loading,
segmentsError: error,
});
@@ -599,7 +593,7 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
failText="Could not drop segment"
intent={Intent.DANGER}
onClose={() => {
- this.setState({ terminateSegmentId: null });
+ this.setState({ terminateSegmentId: undefined });
}}
onSuccess={() => {
this.segmentsNoSqlQueryManager.rerunLastQuery();
@@ -612,7 +606,7 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
);
}
- render() {
+ render(): JSX.Element {
const {
segmentTableActionDialogId,
datasourceTableActionDialogId,
@@ -681,7 +675,7 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
segmentId={segmentTableActionDialogId}
dataSourceId={datasourceTableActionDialogId}
actions={actions}
- onClose={() => this.setState({ segmentTableActionDialogId: null })}
+ onClose={() => this.setState({ segmentTableActionDialogId: undefined })}
isOpen
/>
)}
diff --git a/web-console/src/views/servers-view/servers-view.tsx b/web-console/src/views/servers-view/servers-view.tsx
index 142faa0..516237c 100644
--- a/web-console/src/views/servers-view/servers-view.tsx
+++ b/web-console/src/views/servers-view/servers-view.tsx
@@ -83,13 +83,13 @@ export interface ServersViewProps {
export interface ServersViewState {
serversLoading: boolean;
- servers: any[] | null;
- serversError: string | null;
+ servers?: any[];
+ serversError?: string;
serverFilter: Filter[];
- groupServersBy: null | 'server_type' | 'tier';
+ groupServersBy?: 'server_type' | 'tier';
- middleManagerDisableWorkerHost: string | null;
- middleManagerEnableWorkerHost: string | null;
+ middleManagerDisableWorkerHost?: string;
+ middleManagerEnableWorkerHost?: string;
hiddenColumns: LocalStorageBackedArray<string>;
}
@@ -182,13 +182,7 @@ ORDER BY "rank" DESC, "server" DESC`;
super(props, context);
this.state = {
serversLoading: true,
- servers: null,
- serversError: null,
serverFilter: [],
- groupServersBy: null,
-
- middleManagerDisableWorkerHost: null,
- middleManagerEnableWorkerHost: null,
hiddenColumns: new LocalStorageBackedArray<string>(
LocalStorageKeys.SERVER_TABLE_COLUMN_SELECTION,
@@ -576,7 +570,7 @@ ORDER BY "rank" DESC, "server" DESC`;
failText="Could not disable worker"
intent={Intent.DANGER}
onClose={() => {
- this.setState({ middleManagerDisableWorkerHost: null });
+ this.setState({ middleManagerDisableWorkerHost: undefined });
}}
onSuccess={() => {
this.serverQueryManager.rerunLastQuery();
@@ -605,7 +599,7 @@ ORDER BY "rank" DESC, "server" DESC`;
failText="Could not enable worker"
intent={Intent.PRIMARY}
onClose={() => {
- this.setState({ middleManagerEnableWorkerHost: null });
+ this.setState({ middleManagerEnableWorkerHost: undefined });
}}
onSuccess={() => {
this.serverQueryManager.rerunLastQuery();
@@ -616,7 +610,7 @@ ORDER BY "rank" DESC, "server" DESC`;
);
}
- render() {
+ render(): JSX.Element {
const { goToQuery, noSqlMode } = this.props;
const { groupServersBy, hiddenColumns } = this.state;
@@ -626,8 +620,8 @@ ORDER BY "rank" DESC, "server" DESC`;
<Label>Group by</Label>
<ButtonGroup>
<Button
- active={groupServersBy === null}
- onClick={() => this.setState({ groupServersBy: null })}
+ active={!groupServersBy}
+ onClick={() => this.setState({ groupServersBy: undefined })}
>
None
</Button>
diff --git a/web-console/src/views/task-view/tasks-view.spec.tsx b/web-console/src/views/task-view/tasks-view.spec.tsx
index 254f2ce..93bc323 100644
--- a/web-console/src/views/task-view/tasks-view.spec.tsx
+++ b/web-console/src/views/task-view/tasks-view.spec.tsx
@@ -27,9 +27,9 @@ describe('tasks view', () => {
<TasksView
openDialog={'test'}
taskId={'test'}
- goToQuery={() => null}
- goToMiddleManager={() => null}
- goToLoadDataView={() => null}
+ goToQuery={() => {}}
+ goToMiddleManager={() => {}}
+ goToLoadDataView={() => {}}
noSqlMode={false}
/>,
);
diff --git a/web-console/src/views/task-view/tasks-view.tsx b/web-console/src/views/task-view/tasks-view.tsx
index 28c0541..9480d3c 100644
--- a/web-console/src/views/task-view/tasks-view.tsx
+++ b/web-console/src/views/task-view/tasks-view.tsx
@@ -88,34 +88,33 @@ export interface TasksViewProps {
export interface TasksViewState {
supervisorsLoading: boolean;
supervisors: any[];
- supervisorsError: string | null;
+ supervisorsError?: string;
- resumeSupervisorId: string | null;
- suspendSupervisorId: string | null;
- resetSupervisorId: string | null;
- terminateSupervisorId: string | null;
+ resumeSupervisorId?: string;
+ suspendSupervisorId?: string;
+ resetSupervisorId?: string;
+ terminateSupervisorId?: string;
showResumeAllSupervisors: boolean;
showSuspendAllSupervisors: boolean;
showTerminateAllSupervisors: boolean;
tasksLoading: boolean;
- tasks: any[] | null;
- tasksError: string | null;
+ tasks?: any[];
+ tasksError?: string;
taskFilter: Filter[];
- groupTasksBy: null | 'type' | 'datasource' | 'status';
+ groupTasksBy?: 'type' | 'datasource' | 'status';
- killTaskId: string | null;
+ killTaskId?: string;
supervisorSpecDialogOpen: boolean;
taskSpecDialogOpen: boolean;
- initSpec: any;
- alertErrorMsg: string | null;
+ alertErrorMsg?: string;
- taskTableActionDialogId: string | null;
- taskTableActionDialogStatus: string | null;
+ taskTableActionDialogId?: string;
+ taskTableActionDialogStatus?: string;
taskTableActionDialogActions: BasicAction[];
- supervisorTableActionDialogId: string | null;
+ supervisorTableActionDialogId?: string;
supervisorTableActionDialogActions: BasicAction[];
hiddenTaskColumns: LocalStorageBackedArray<string>;
hiddenSupervisorColumns: LocalStorageBackedArray<string>;
@@ -202,33 +201,17 @@ ORDER BY "rank" DESC, "created_time" DESC`;
this.state = {
supervisorsLoading: true,
supervisors: [],
- supervisorsError: null,
-
- resumeSupervisorId: null,
- suspendSupervisorId: null,
- resetSupervisorId: null,
- supervisorTableActionDialogId: null,
- terminateSupervisorId: null,
showResumeAllSupervisors: false,
showSuspendAllSupervisors: false,
showTerminateAllSupervisors: false,
tasksLoading: true,
- tasks: null,
- tasksError: null,
taskFilter: props.taskId ? [{ id: 'task_id', value: props.taskId }] : [],
- groupTasksBy: null,
-
- killTaskId: null,
supervisorSpecDialogOpen: props.openDialog === 'supervisor',
taskSpecDialogOpen: props.openDialog === 'task',
- initSpec: null,
- alertErrorMsg: null,
- taskTableActionDialogId: null,
- taskTableActionDialogStatus: null,
taskTableActionDialogActions: [],
supervisorTableActionDialogActions: [],
@@ -323,7 +306,6 @@ ORDER BY "rank" DESC, "created_time" DESC`;
this.setState({
supervisorSpecDialogOpen: false,
taskSpecDialogOpen: false,
- initSpec: null,
});
};
@@ -378,11 +360,6 @@ ORDER BY "rank" DESC, "created_time" DESC`;
}
actions.push(
{
- icon: IconNames.STEP_BACKWARD,
- title: 'Reset',
- onAction: () => this.setState({ resetSupervisorId: id }),
- },
- {
icon: supervisorSuspended ? IconNames.PLAY : IconNames.PAUSE,
title: supervisorSuspended ? 'Resume' : 'Suspend',
onAction: () =>
@@ -391,6 +368,12 @@ ORDER BY "rank" DESC, "created_time" DESC`;
: this.setState({ suspendSupervisorId: id }),
},
{
+ icon: IconNames.STEP_BACKWARD,
+ title: 'Reset',
+ intent: Intent.DANGER,
+ onAction: () => this.setState({ resetSupervisorId: id }),
+ },
+ {
icon: IconNames.CROSS,
title: 'Terminate',
intent: Intent.DANGER,
@@ -418,7 +401,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
failText="Could not resume supervisor"
intent={Intent.PRIMARY}
onClose={() => {
- this.setState({ resumeSupervisorId: null });
+ this.setState({ resumeSupervisorId: undefined });
}}
onSuccess={() => {
this.supervisorQueryManager.rerunLastQuery();
@@ -447,7 +430,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
failText="Could not suspend supervisor"
intent={Intent.DANGER}
onClose={() => {
- this.setState({ suspendSupervisorId: null });
+ this.setState({ suspendSupervisorId: undefined });
}}
onSuccess={() => {
this.supervisorQueryManager.rerunLastQuery();
@@ -476,13 +459,14 @@ ORDER BY "rank" DESC, "created_time" DESC`;
failText="Could not reset supervisor"
intent={Intent.DANGER}
onClose={() => {
- this.setState({ resetSupervisorId: null });
+ this.setState({ resetSupervisorId: undefined });
}}
onSuccess={() => {
this.supervisorQueryManager.rerunLastQuery();
}}
>
<p>{`Are you sure you want to reset supervisor '${resetSupervisorId}'?`}</p>
+ <p>Resetting a supervisor could lead data loss or data duplication</p>
</AsyncActionDialog>
);
}
@@ -505,7 +489,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
failText="Could not terminate supervisor"
intent={Intent.DANGER}
onClose={() => {
- this.setState({ terminateSupervisorId: null });
+ this.setState({ terminateSupervisorId: undefined });
}}
onSuccess={() => {
this.supervisorQueryManager.rerunLastQuery();
@@ -655,7 +639,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
failText="Could not kill task"
intent={Intent.DANGER}
onClose={() => {
- this.setState({ killTaskId: null });
+ this.setState({ killTaskId: undefined });
}}
onSuccess={() => {
this.taskQueryManager.rerunLastQuery();
@@ -964,7 +948,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
);
}
- render() {
+ render(): JSX.Element {
const { goToQuery, goToLoadDataView, noSqlMode } = this.props;
const {
groupTasksBy,
@@ -1048,8 +1032,8 @@ ORDER BY "rank" DESC, "created_time" DESC`;
<Label>Group by</Label>
<ButtonGroup>
<Button
- active={groupTasksBy === null}
- onClick={() => this.setState({ groupTasksBy: null })}
+ active={!groupTasksBy}
+ onClick={() => this.setState({ groupTasksBy: undefined })}
>
None
</Button>
@@ -1116,7 +1100,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
intent={Intent.PRIMARY}
isOpen={Boolean(alertErrorMsg)}
confirmButtonText="OK"
- onConfirm={() => this.setState({ alertErrorMsg: null })}
+ onConfirm={() => this.setState({ alertErrorMsg: undefined })}
>
<p>{alertErrorMsg}</p>
</Alert>
@@ -1125,16 +1109,16 @@ ORDER BY "rank" DESC, "created_time" DESC`;
isOpen
supervisorId={supervisorTableActionDialogId}
actions={supervisorTableActionDialogActions}
- onClose={() => this.setState({ supervisorTableActionDialogId: null })}
+ onClose={() => this.setState({ supervisorTableActionDialogId: undefined })}
/>
)}
- {taskTableActionDialogId && (
+ {taskTableActionDialogId && taskTableActionDialogStatus && (
<TaskTableActionDialog
isOpen
status={taskTableActionDialogStatus}
taskId={taskTableActionDialogId}
actions={taskTableActionDialogActions}
- onClose={() => this.setState({ taskTableActionDialogId: null })}
+ onClose={() => this.setState({ taskTableActionDialogId: undefined })}
/>
)}
</>
diff --git a/web-console/tsconfig.json b/web-console/tsconfig.json
index 0e43c57..4472d5a 100644
--- a/web-console/tsconfig.json
+++ b/web-console/tsconfig.json
@@ -16,7 +16,7 @@
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
- "lib": ["dom", "es2016"],
+ "lib": ["dom", "es2016", "esnext"],
"jsx": "react",
"rootDirs": ["lib", "src"]
},
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org