mirror of https://github.com/apache/druid.git
Update console packages and enforce tslint quotes (#7419)
* update packages and enforce tslint quotes * remove direct dep on tslint-react
This commit is contained in:
parent
799c66d9ac
commit
c69c37e99d
File diff suppressed because it is too large
Load Diff
|
@ -14,6 +14,10 @@
|
|||
"pretest": "./script/build",
|
||||
"run": "./script/run",
|
||||
"test": "jest --silent 2>&1",
|
||||
"tslint": "./node_modules/.bin/tslint -c tslint.json --project tsconfig.json --formatters-dir ./node_modules/awesome-code-style/formatter 'src/**/*.ts?(x)'",
|
||||
"tslint-fix": "npm run tslint -- --fix",
|
||||
"tslint-changed-only": "git diff --diff-filter=ACMR --name-only | grep -E \\.tsx\\?$ | xargs ./node_modules/.bin/tslint -c tslint.json --project tsconfig.json --formatters-dir ./node_modules/awesome-code-style/formatter",
|
||||
"tslint-fix-changed-only": "npm run tslint-changed-only -- --fix",
|
||||
"generate-licenses-file": "license-checker --production --json --out licenses.json",
|
||||
"check-licenses": "license-checker --production --onlyAllow 'Apache-1.1;Apache-2.0;BSD-2-Clause;BSD-3-Clause;MIT;CC0-1.0' --summary",
|
||||
"start": "webpack-dev-server --hot --open",
|
||||
|
@ -26,58 +30,58 @@
|
|||
"classnames": "^2.2.6",
|
||||
"d3-array": "^2.0.3",
|
||||
"druid-console": "^0.0.2",
|
||||
"es6-shim": "^0.35.4",
|
||||
"es6-shim": "^0.35.5",
|
||||
"es7-shim": "^6.0.0",
|
||||
"hjson": "^3.1.2",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"numeral": "^2.0.6",
|
||||
"react": "^16.8.3",
|
||||
"react": "^16.8.6",
|
||||
"react-ace": "^6.4.0",
|
||||
"react-dom": "^16.8.3",
|
||||
"react-router": "^4.3.1",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-router": "^5.0.0",
|
||||
"react-router-dom": "^5.0.0",
|
||||
"react-table": "~6.8.6",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/d3-array": "^1.2.4",
|
||||
"@types/hjson": "^2.4.0",
|
||||
"@types/jest": "^23.3.13",
|
||||
"@types/lodash.debounce": "^4.0.4",
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/node": "^10.12.18",
|
||||
"@types/d3-array": "^2.0.0",
|
||||
"@types/hjson": "^2.4.1",
|
||||
"@types/jest": "^24.0.11",
|
||||
"@types/lodash.debounce": "^4.0.6",
|
||||
"@types/mocha": "^5.2.6",
|
||||
"@types/node": "^11.13.0",
|
||||
"@types/numeral": "^0.0.25",
|
||||
"@types/react-dom": "^16.0.11",
|
||||
"@types/react-dom": "^16.8.3",
|
||||
"@types/react-router-dom": "^4.3.1",
|
||||
"@types/react-table": "^6.7.21",
|
||||
"autoprefixer": "^9.4.6",
|
||||
"css-loader": "^2.1.0",
|
||||
"@types/react-table": "^6.8.0",
|
||||
"autoprefixer": "^9.5.0",
|
||||
"awesome-code-style": "^1.1.4",
|
||||
"css-loader": "^2.1.1",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"ignore-styles": "^5.0.1",
|
||||
"jest": "^24.0.0",
|
||||
"jest": "^24.7.1",
|
||||
"license-checker": "^25.0.1",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha": "^6.0.2",
|
||||
"node-sass": "^4.11.0",
|
||||
"node-sass-chokidar": "^1.3.4",
|
||||
"postcss-cli": "^6.1.1",
|
||||
"postcss-cli": "^6.1.2",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-preset-env": "^6.5.0",
|
||||
"postcss-preset-env": "^6.6.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"stylelint": "^9.10.1",
|
||||
"stylelint-config-recommended-scss": "^3.2.0",
|
||||
"stylelint-scss": "^3.5.4",
|
||||
"stylus": "^0.54.5",
|
||||
"ts-jest": "^23.10.5",
|
||||
"ts-jest": "^24.0.1",
|
||||
"ts-loader": "^5.3.3",
|
||||
"ts-node": "^8.0.2",
|
||||
"tslint": "^5.14.0",
|
||||
"ts-node": "^8.0.3",
|
||||
"tslint": "^5.15.0",
|
||||
"tslint-loader": "^3.5.4",
|
||||
"tslint-react": "^3.6.0",
|
||||
"typescript": "^3.2.4",
|
||||
"webpack": "^4.29.0",
|
||||
"webpack-cli": "^3.2.1",
|
||||
"webpack-dev-server": "^3.1.14"
|
||||
"typescript": "^3.4.1",
|
||||
"webpack": "^4.29.6",
|
||||
"webpack-cli": "^3.3.0",
|
||||
"webpack-dev-server": "^3.2.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Trick blueprint 1.0.1 into accepting React 16 as React 15.
|
||||
// This is broken into its own file to make linting and import sorting easy
|
||||
// This file "a" to make sure it is imported before console-application in entry.ts
|
||||
|
||||
// tslint:disable
|
||||
import * as React from 'react';
|
||||
(React as any).PropTypes = require('prop-types');
|
|
@ -16,13 +16,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button } from "@blueprintjs/core";
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import * as React from 'react';
|
||||
import { Filter, ReactTableDefaults } from "react-table";
|
||||
import { Filter, ReactTableDefaults } from 'react-table';
|
||||
|
||||
import { Loader } from '../components/loader';
|
||||
import { countBy, makeTextFilter } from '../utils';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
|
||||
class FullButton extends React.Component {
|
||||
render() {
|
||||
return <Button fill {...this.props}/>;
|
||||
|
@ -37,6 +39,8 @@ class NoData extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
/* tslint:enable:max-classes-per-file */
|
||||
|
||||
Object.assign(ReactTableDefaults, {
|
||||
defaultFilterMethod: (filter: Filter, row: any, column: any) => {
|
||||
const id = filter.pivotId || filter.id;
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { InputGroup } from "@blueprintjs/core";
|
||||
import { FormGroup, HTMLSelect, NumericInput, TagInput } from "@blueprintjs/core";
|
||||
import { InputGroup } from '@blueprintjs/core';
|
||||
import { FormGroup, HTMLSelect, NumericInput, TagInput } from '@blueprintjs/core';
|
||||
import * as React from 'react';
|
||||
|
||||
import { JSONInput } from './json-input';
|
||||
|
||||
import "./auto-form.scss";
|
||||
import './auto-form.scss';
|
||||
|
||||
interface Field {
|
||||
name: string;
|
||||
|
@ -44,7 +44,7 @@ export interface AutoFormState<T> {
|
|||
|
||||
export class AutoForm<T> extends React.Component<AutoFormProps<T>, AutoFormState<T>> {
|
||||
static makeLabelName(label: string): string {
|
||||
let newLabel = label.split(/(?=[A-Z])/).map(s => s.toLowerCase()).join(" ");
|
||||
let newLabel = label.split(/(?=[A-Z])/).map(s => s.toLowerCase()).join(' ');
|
||||
newLabel = newLabel[0].toUpperCase() + newLabel.slice(1);
|
||||
return newLabel;
|
||||
}
|
||||
|
@ -95,9 +95,9 @@ export class AutoForm<T> extends React.Component<AutoFormProps<T>, AutoFormState
|
|||
private renderBooleanInput(field: Field): JSX.Element {
|
||||
const { model, onChange } = this.props;
|
||||
return <HTMLSelect
|
||||
value={(model as any)[field.name] === true ? "True" : "False"}
|
||||
value={(model as any)[field.name] === true ? 'True' : 'False'}
|
||||
onChange={(e: any) => {
|
||||
onChange(Object.assign({}, model, { [field.name]: e.currentTarget.value === "True" }));
|
||||
onChange(Object.assign({}, model, { [field.name]: e.currentTarget.value === 'True' }));
|
||||
}}
|
||||
>
|
||||
<option value="True">True</option>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
.header-bar {
|
||||
z-index: 10;
|
||||
overflow: hidden;
|
||||
|
||||
.logo {
|
||||
position: relative;
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Alignment, AnchorButton, Button, Classes, Menu, MenuItem, Navbar, NavbarDivider, NavbarGroup, Popover, Position } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { Alignment, AnchorButton, Button, Classes, Menu, MenuItem, Navbar, NavbarDivider, NavbarGroup, Popover, Position } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
|
||||
import { AboutDialog } from "../dialogs/about-dialog";
|
||||
import { AboutDialog } from '../dialogs/about-dialog';
|
||||
import { CoordinatorDynamicConfigDialog } from '../dialogs/coordinator-dynamic-config';
|
||||
import { OverlordDynamicConfigDialog } from "../dialogs/overlord-dynamic-config";
|
||||
import { OverlordDynamicConfigDialog } from '../dialogs/overlord-dynamic-config';
|
||||
import {
|
||||
DRUID_DOCS,
|
||||
DRUID_GITHUB,
|
||||
|
@ -32,7 +32,7 @@ import {
|
|||
LEGACY_OVERLORD_CONSOLE
|
||||
} from '../variables';
|
||||
|
||||
import "./header-bar.scss";
|
||||
import './header-bar.scss';
|
||||
|
||||
export type HeaderActiveTab = null | 'datasources' | 'segments' | 'tasks' | 'servers' | 'sql' | 'lookups';
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ export class JSONCollapse extends React.Component<JSONCollapseProps, JSONCollaps
|
|||
const { stringValue, buttonText} = this.props;
|
||||
const { isOpen } = this.state;
|
||||
const prettyValue = JSON.stringify(JSON.parse(stringValue), undefined, 2);
|
||||
return <div className={"json-collapse"}>
|
||||
return <div className="json-collapse">
|
||||
<Button
|
||||
minimal
|
||||
active={isOpen}
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import AceEditor from "react-ace";
|
||||
import AceEditor from 'react-ace';
|
||||
|
||||
import { parseStringToJSON, stringifyJSON, validJson } from "../utils";
|
||||
import { parseStringToJSON, stringifyJSON, validJson } from '../utils';
|
||||
|
||||
interface JSONInputProps extends React.Props<any> {
|
||||
onChange: (newJSONValue: any) => void;
|
||||
|
@ -38,7 +38,7 @@ export class JSONInput extends React.Component<JSONInputProps, JSONInputState> {
|
|||
constructor(props: JSONInputProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
stringValue: ""
|
||||
stringValue: ''
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -62,19 +62,19 @@ export class JSONInput extends React.Component<JSONInputProps, JSONInputState> {
|
|||
const { onChange, updateInputValidity, focus, width, height } = this.props;
|
||||
const { stringValue } = this.state;
|
||||
return <AceEditor
|
||||
key={"hjson"}
|
||||
mode={"hjson"}
|
||||
key="hjson"
|
||||
mode="hjson"
|
||||
theme="solarized_dark"
|
||||
name="ace-editor"
|
||||
onChange={(e: string) => {
|
||||
this.setState({stringValue: e});
|
||||
if (validJson(e) || e === "") onChange(parseStringToJSON(e));
|
||||
if (validJson(e) || e === '') onChange(parseStringToJSON(e));
|
||||
if (updateInputValidity) updateInputValidity(validJson(e) || e === '');
|
||||
}}
|
||||
focus={focus}
|
||||
fontSize={12}
|
||||
width={width || '100%'}
|
||||
height={height || "8vh"}
|
||||
height={height || '8vh'}
|
||||
showPrintMargin={false}
|
||||
showGutter={false}
|
||||
value={stringValue}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Card, Collapse, ControlGroup, FormGroup, HTMLSelect, InputGroup, NumericInput, TagInput } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { Button, Card, Collapse, ControlGroup, FormGroup, HTMLSelect, InputGroup, NumericInput, TagInput } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as React from 'react';
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Checkbox, Classes, FormGroup, Intent, Menu, Popover, Position } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import axios from "axios";
|
||||
import { Button, Checkbox, Classes, FormGroup, Intent, Menu, Popover, Position } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as ace from 'brace';
|
||||
import 'brace/ext/language_tools';
|
||||
import 'brace/mode/hjson';
|
||||
|
@ -26,11 +26,11 @@ import 'brace/mode/sql';
|
|||
import 'brace/theme/solarized_dark';
|
||||
import * as classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
import AceEditor from "react-ace";
|
||||
import AceEditor from 'react-ace';
|
||||
import * as ReactDOMServer from 'react-dom/server';
|
||||
|
||||
import { SQLFunctionDoc } from "../../lib/sql-function-doc";
|
||||
import { AppToaster } from "../singletons/toaster";
|
||||
import { SQLFunctionDoc } from '../../lib/sql-function-doc';
|
||||
import { AppToaster } from '../singletons/toaster';
|
||||
|
||||
import './sql-control.scss';
|
||||
|
||||
|
@ -59,13 +59,13 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
|
|||
}
|
||||
|
||||
private addDatasourceAutoCompleter = async (): Promise<any> => {
|
||||
const datasourceResp = await axios.post("/druid/v2/sql", { query: `SELECT datasource FROM sys.segments GROUP BY 1`});
|
||||
const datasourceResp = await axios.post('/druid/v2/sql', { query: `SELECT datasource FROM sys.segments GROUP BY 1`});
|
||||
const datasourceList: any[] = datasourceResp.data.map((d: any) => {
|
||||
const datasourceName: string = d.datasource;
|
||||
return {
|
||||
value: datasourceName,
|
||||
score: 50,
|
||||
meta: "datasource"
|
||||
meta: 'datasource'
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -79,13 +79,13 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
|
|||
}
|
||||
|
||||
private addColumnNameAutoCompleter = async (): Promise<any> => {
|
||||
const columnNameResp = await axios.post("/druid/v2/sql", {query: `SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'druid'`});
|
||||
const columnNameResp = await axios.post('/druid/v2/sql', {query: `SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'druid'`});
|
||||
const columnNameList: any[] = columnNameResp.data.map((d: any) => {
|
||||
const columnName: string = d.COLUMN_NAME;
|
||||
return {
|
||||
value: columnName,
|
||||
score: 50,
|
||||
meta: "column"
|
||||
meta: 'column'
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -100,12 +100,12 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
|
|||
|
||||
private addFunctionAutoCompleter = (): void => {
|
||||
const functionList: any[] = SQLFunctionDoc.map((entry: any) => {
|
||||
let funcName: string = entry.syntax.replace(/\(.*\)/, "()");
|
||||
if (!funcName.includes("(")) funcName = funcName.substr(0, 10);
|
||||
let funcName: string = entry.syntax.replace(/\(.*\)/, '()');
|
||||
if (!funcName.includes('(')) funcName = funcName.substr(0, 10);
|
||||
return {
|
||||
value: funcName,
|
||||
score: 80,
|
||||
meta: "function",
|
||||
meta: 'function',
|
||||
syntax: entry.syntax,
|
||||
description: entry.description,
|
||||
completer: {
|
||||
|
@ -123,11 +123,11 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
|
|||
callback(null, functionList);
|
||||
},
|
||||
getDocTooltip: (item: any) => {
|
||||
if (item.meta === "function") {
|
||||
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>
|
||||
<div className="function-doc">
|
||||
<div className="function-doc-name"><b>{functionName}</b></div>
|
||||
<hr/>
|
||||
<div><b>Syntax:</b></div>
|
||||
<div>{item.syntax}</div>
|
||||
|
@ -149,7 +149,7 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
|
|||
await this.addColumnNameAutoCompleter();
|
||||
} catch (e) {
|
||||
AppToaster.show({
|
||||
message: "Failed to load SQL auto completer",
|
||||
message: 'Failed to load SQL auto completer',
|
||||
intent: Intent.DANGER
|
||||
});
|
||||
}
|
||||
|
@ -173,16 +173,16 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
|
|||
|
||||
const SqlControlPopover = <Popover position={Position.BOTTOM_LEFT}>
|
||||
<Button minimal icon={IconNames.MORE}/>
|
||||
<div className={"sql-control-popover"}>
|
||||
<div className="sql-control-popover">
|
||||
<Checkbox
|
||||
checked={isRune ? false : autoCompleteOn}
|
||||
label={"Auto complete"}
|
||||
label="Auto complete"
|
||||
onChange={() => this.setState({autoCompleteOn: !autoCompleteOn})}
|
||||
/>
|
||||
<Button
|
||||
icon={IconNames.CLEAN}
|
||||
className={Classes.POPOVER_DISMISS}
|
||||
text={"Explain"}
|
||||
text="Explain"
|
||||
onClick={() => onExplain(query)}
|
||||
minimal
|
||||
/>
|
||||
|
@ -192,15 +192,15 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
|
|||
// Set the key in the AceEditor to force a rebind and prevent an error that happens otherwise
|
||||
return <div className="sql-control">
|
||||
<AceEditor
|
||||
key={isRune ? "hjson" : "sql"}
|
||||
mode={isRune ? "hjson" : "sql"}
|
||||
key={isRune ? 'hjson' : 'sql'}
|
||||
mode={isRune ? 'hjson' : 'sql'}
|
||||
theme="solarized_dark"
|
||||
name="ace-editor"
|
||||
onChange={this.handleChange}
|
||||
focus
|
||||
fontSize={14}
|
||||
width={'100%'}
|
||||
height={"30vh"}
|
||||
width="100%"
|
||||
height="30vh"
|
||||
showPrintMargin={false}
|
||||
value={query}
|
||||
editorProps={{
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Checkbox, FormGroup, Menu, Popover, Position } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { Button, Checkbox, FormGroup, Menu, Popover, Position } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import * as React from 'react';
|
||||
|
||||
import "./table-column-selection.scss";
|
||||
import './table-column-selection.scss';
|
||||
|
||||
interface TableColumnSelectionProps extends React.Props<any> {
|
||||
columns: string[];
|
||||
|
@ -61,7 +61,7 @@ export class TableColumnSelection extends React.Component<TableColumnSelectionPr
|
|||
content={checkboxes}
|
||||
position={Position.BOTTOM_RIGHT}
|
||||
>
|
||||
<Button rightIcon={IconNames.CARET_DOWN} text={"Columns"} />
|
||||
<Button rightIcon={IconNames.CARET_DOWN} text="Columns" />
|
||||
</Popover>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,25 +16,25 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Intent } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
import { HashRouter, Route, Switch } from "react-router-dom";
|
||||
import { HashRouter, Route, Switch } from 'react-router-dom';
|
||||
|
||||
import { HeaderActiveTab, HeaderBar } from './components/header-bar';
|
||||
import { AppToaster } from './singletons/toaster';
|
||||
import { DRUID_DOCS_SQL, LEGACY_COORDINATOR_CONSOLE, LEGACY_OVERLORD_CONSOLE } from './variables';
|
||||
import { DatasourcesView } from './views/datasource-view';
|
||||
import { HomeView } from './views/home-view';
|
||||
import { LookupsView } from "./views/lookups-view";
|
||||
import { LookupsView } from './views/lookups-view';
|
||||
import { SegmentsView } from './views/segments-view';
|
||||
import { ServersView } from './views/servers-view';
|
||||
import { SqlView } from './views/sql-view';
|
||||
import { TasksView } from './views/tasks-view';
|
||||
|
||||
import "./console-application.scss";
|
||||
import './console-application.scss';
|
||||
|
||||
export interface ConsoleApplicationProps extends React.Props<any> {
|
||||
hideLegacy: boolean;
|
||||
|
@ -51,12 +51,12 @@ export class ConsoleApplication extends React.Component<ConsoleApplicationProps,
|
|||
|
||||
static async ensureSql() {
|
||||
try {
|
||||
await axios.post("/druid/v2/sql", { query: 'SELECT 1337' });
|
||||
await axios.post('/druid/v2/sql', { query: 'SELECT 1337' });
|
||||
} catch (e) {
|
||||
const { response } = e;
|
||||
if (response.status !== 405 || response.statusText !== "Method Not Allowed") return true; // other failure
|
||||
if (response.status !== 405 || response.statusText !== 'Method Not Allowed') return true; // other failure
|
||||
try {
|
||||
await axios.get("/status");
|
||||
await axios.get('/status');
|
||||
} catch (e) {
|
||||
return true; // total failure
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AnchorButton, Button, Classes, Dialog, Intent } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { AnchorButton, Button, Classes, Dialog, Intent } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import * as React from 'react';
|
||||
|
||||
import { DRUID_COMMUNITY, DRUID_DEVELOPER_GROUP, DRUID_USER_GROUP, DRUID_WEBSITE } from '../variables';
|
||||
|
|
|
@ -23,8 +23,8 @@ import {
|
|||
Dialog,
|
||||
FormGroup,
|
||||
Icon, Intent, NumericInput, ProgressBar, TagInput
|
||||
} from "@blueprintjs/core";
|
||||
import { IconName } from "@blueprintjs/icons";
|
||||
} from '@blueprintjs/core';
|
||||
import { IconName } from '@blueprintjs/icons';
|
||||
import classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Classes, Dialog, Intent } from "@blueprintjs/core";
|
||||
import { Button, Classes, Dialog, Intent } from '@blueprintjs/core';
|
||||
import * as React from 'react';
|
||||
|
||||
import { AutoForm } from '../components/auto-form';
|
||||
|
@ -52,7 +52,7 @@ export class CompactionDialog extends React.Component<CompactionDialogProps, Com
|
|||
inputSegmentSizeBytes: 419430400,
|
||||
keepSegmentGranularity: true,
|
||||
maxNumSegmentsToCompact: 150,
|
||||
skipOffsetFromLatest: "P1D",
|
||||
skipOffsetFromLatest: 'P1D',
|
||||
targetCompactionSizeBytes: 419430400,
|
||||
taskContext: null,
|
||||
taskPriority: 25,
|
||||
|
@ -79,36 +79,36 @@ export class CompactionDialog extends React.Component<CompactionDialogProps, Com
|
|||
<AutoForm
|
||||
fields={[
|
||||
{
|
||||
name: "inputSegmentSizeBytes",
|
||||
type: "number"
|
||||
name: 'inputSegmentSizeBytes',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "keepSegmentGranularity",
|
||||
type: "boolean"
|
||||
name: 'keepSegmentGranularity',
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: "maxNumSegmentsToCompact",
|
||||
type: "number"
|
||||
name: 'maxNumSegmentsToCompact',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "skipOffsetFromLatest",
|
||||
type: "string"
|
||||
name: 'skipOffsetFromLatest',
|
||||
type: 'string'
|
||||
},
|
||||
{
|
||||
name: "targetCompactionSizeBytes",
|
||||
type: "number"
|
||||
name: 'targetCompactionSizeBytes',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "taskContext",
|
||||
type: "json"
|
||||
name: 'taskContext',
|
||||
type: 'json'
|
||||
},
|
||||
{
|
||||
name: "taskPriority",
|
||||
type: "number"
|
||||
name: 'taskPriority',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "tuningConfig",
|
||||
type: "json"
|
||||
name: 'tuningConfig',
|
||||
type: 'json'
|
||||
}
|
||||
]}
|
||||
model={currentConfig}
|
||||
|
|
|
@ -70,7 +70,7 @@ export class CoordinatorDynamicConfigDialog extends React.Component<CoordinatorD
|
|||
async getClusterConfig() {
|
||||
let config: Record<string, any> | null = null;
|
||||
try {
|
||||
const configResp = await axios.get("/druid/coordinator/v1/config");
|
||||
const configResp = await axios.get('/druid/coordinator/v1/config');
|
||||
config = configResp.data;
|
||||
} catch (e) {
|
||||
AppToaster.show({
|
||||
|
@ -89,10 +89,10 @@ export class CoordinatorDynamicConfigDialog extends React.Component<CoordinatorD
|
|||
const { onClose } = this.props;
|
||||
const newState: any = this.state.dynamicConfig;
|
||||
try {
|
||||
await axios.post("/druid/coordinator/v1/config", newState, {
|
||||
await axios.post('/druid/coordinator/v1/config', newState, {
|
||||
headers: {
|
||||
"X-Druid-Author": "console",
|
||||
"X-Druid-Comment": comment
|
||||
'X-Druid-Author': 'console',
|
||||
'X-Druid-Comment': comment
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -129,52 +129,52 @@ export class CoordinatorDynamicConfigDialog extends React.Component<CoordinatorD
|
|||
<AutoForm
|
||||
fields={[
|
||||
{
|
||||
name: "balancerComputeThreads",
|
||||
type: "number"
|
||||
name: 'balancerComputeThreads',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "emitBalancingStats",
|
||||
type: "boolean"
|
||||
name: 'emitBalancingStats',
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: "killAllDataSources",
|
||||
type: "boolean"
|
||||
name: 'killAllDataSources',
|
||||
type: 'boolean'
|
||||
},
|
||||
{
|
||||
name: "killDataSourceWhitelist",
|
||||
type: "string-array"
|
||||
name: 'killDataSourceWhitelist',
|
||||
type: 'string-array'
|
||||
},
|
||||
{
|
||||
name: "killPendingSegmentsSkipList",
|
||||
type: "string-array"
|
||||
name: 'killPendingSegmentsSkipList',
|
||||
type: 'string-array'
|
||||
},
|
||||
{
|
||||
name: "maxSegmentsInNodeLoadingQueue",
|
||||
type: "number"
|
||||
name: 'maxSegmentsInNodeLoadingQueue',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "maxSegmentsToMove",
|
||||
type: "number"
|
||||
name: 'maxSegmentsToMove',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "mergeBytesLimit",
|
||||
type: "size-bytes"
|
||||
name: 'mergeBytesLimit',
|
||||
type: 'size-bytes'
|
||||
},
|
||||
{
|
||||
name: "mergeSegmentsLimit",
|
||||
type: "number"
|
||||
name: 'mergeSegmentsLimit',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "millisToWaitBeforeDeleting",
|
||||
type: "number"
|
||||
name: 'millisToWaitBeforeDeleting',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "replicantLifetime",
|
||||
type: "number"
|
||||
name: 'replicantLifetime',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
name: "replicationThrottleLimit",
|
||||
type: "number"
|
||||
name: 'replicationThrottleLimit',
|
||||
type: 'number'
|
||||
}
|
||||
]}
|
||||
model={dynamicConfig}
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Card, Dialog } from "@blueprintjs/core";
|
||||
import * as React from "react";
|
||||
import { Card, Dialog } from '@blueprintjs/core';
|
||||
import * as React from 'react';
|
||||
|
||||
import { JSONCollapse } from '../components/json-collapse';
|
||||
|
||||
import "./history-dialog.scss";
|
||||
import './history-dialog.scss';
|
||||
|
||||
interface HistoryDialogProps extends React.Props<any> {
|
||||
historyRecords: any;
|
||||
|
@ -43,28 +43,28 @@ export class HistoryDialog extends React.Component<HistoryDialogProps, HistoryDi
|
|||
const {children, historyRecords} = this.props;
|
||||
let content;
|
||||
if (historyRecords.length === 0) {
|
||||
content = <div className={"no-record"}>No history records available</div>;
|
||||
content = <div className="no-record">No history records available</div>;
|
||||
} else {
|
||||
content = <>
|
||||
<h3>History</h3>
|
||||
<div className={"history-record-entries"}>
|
||||
<div className="history-record-entries">
|
||||
{
|
||||
historyRecords.map((record: any) => {
|
||||
const auditInfo = record.auditInfo;
|
||||
const auditTime = record.auditTime;
|
||||
const formattedTime = auditTime.replace("T", " ").substring(0, auditTime.length - 5);
|
||||
const formattedTime = auditTime.replace('T', ' ').substring(0, auditTime.length - 5);
|
||||
|
||||
return <div key={record.auditTime} className={"history-record-entry"}>
|
||||
return <div key={record.auditTime} className="history-record-entry">
|
||||
<Card>
|
||||
<div className={"history-record-title"}>
|
||||
<div className="history-record-title">
|
||||
<h5>Change</h5>
|
||||
<p>{formattedTime}</p>
|
||||
</div>
|
||||
<hr/>
|
||||
<p>{auditInfo.comment === "" ? "(No comment)" : auditInfo.comment}</p>
|
||||
<p>{auditInfo.comment === '' ? '(No comment)' : auditInfo.comment}</p>
|
||||
<JSONCollapse
|
||||
stringValue={record.payload}
|
||||
buttonText={"Payload"}
|
||||
buttonText="Payload"
|
||||
/>
|
||||
</Card>
|
||||
</div>;
|
||||
|
@ -73,7 +73,7 @@ export class HistoryDialog extends React.Component<HistoryDialogProps, HistoryDi
|
|||
</div>
|
||||
</>;
|
||||
}
|
||||
return <div className={"history-record-container"}>
|
||||
return <div className="history-record-container">
|
||||
{content}
|
||||
{children}
|
||||
</div>;
|
||||
|
@ -81,9 +81,9 @@ export class HistoryDialog extends React.Component<HistoryDialogProps, HistoryDi
|
|||
|
||||
render(): React.ReactNode {
|
||||
return <Dialog
|
||||
className="history-dialog"
|
||||
isOpen
|
||||
{...this.props}
|
||||
className={"history-dialog"}
|
||||
>
|
||||
{this.renderRecords()}
|
||||
</Dialog>;
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Classes, Dialog, FormGroup, HTMLSelect, InputGroup, Intent } from "@blueprintjs/core";
|
||||
import * as React from "react";
|
||||
import AceEditor from "react-ace";
|
||||
import { Button, Classes, Dialog, FormGroup, HTMLSelect, InputGroup, Intent } from '@blueprintjs/core';
|
||||
import * as React from 'react';
|
||||
import AceEditor from 'react-ace';
|
||||
|
||||
import { validJson } from "../utils";
|
||||
import { validJson } from '../utils';
|
||||
|
||||
import "./lookup-edit-dialog.scss";
|
||||
import './lookup-edit-dialog.scss';
|
||||
|
||||
export interface LookupEditDialogProps extends React.Props<any> {
|
||||
isOpen: boolean;
|
||||
|
@ -53,22 +53,22 @@ export class LookupEditDialog extends React.Component<LookupEditDialogProps, Loo
|
|||
const {onChange} = this.props;
|
||||
const currentDate = new Date();
|
||||
const ISOString = currentDate.toISOString();
|
||||
onChange("lookupEditVersion", ISOString);
|
||||
onChange('lookupEditVersion', ISOString);
|
||||
}
|
||||
|
||||
private renderTierInput() {
|
||||
const { isEdit, lookupTier, allLookupTiers, onChange } = this.props;
|
||||
if (isEdit) {
|
||||
return <FormGroup className={"lookup-label"} label={"Tier: "}>
|
||||
return <FormGroup className="lookup-label" label="Tier: ">
|
||||
<InputGroup
|
||||
value={lookupTier}
|
||||
onChange={(e: any) => onChange("lookupEditTier", e.target.value)}
|
||||
onChange={(e: any) => onChange('lookupEditTier', e.target.value)}
|
||||
disabled
|
||||
/>
|
||||
</FormGroup>;
|
||||
} else {
|
||||
return <FormGroup className={"lookup-label"} label={"Tier:"}>
|
||||
<HTMLSelect disabled={isEdit} value={lookupTier} onChange={(e: any) => onChange("lookupEditTier", e.target.value)}>
|
||||
return <FormGroup className="lookup-label" label="Tier:">
|
||||
<HTMLSelect disabled={isEdit} value={lookupTier} onChange={(e: any) => onChange('lookupEditTier', e.target.value)}>
|
||||
{allLookupTiers.map(tier => (
|
||||
<option key={tier} value={tier}>{tier}</option>
|
||||
))}
|
||||
|
@ -80,47 +80,47 @@ export class LookupEditDialog extends React.Component<LookupEditDialogProps, Loo
|
|||
render() {
|
||||
const { isOpen, onClose, onSubmit, lookupSpec, lookupTier, lookupName, lookupVersion, onChange, isEdit, allLookupTiers } = this.props;
|
||||
|
||||
const disableSubmit = lookupName === "" || lookupVersion === "" ||
|
||||
lookupTier === "" || !validJson(lookupSpec);
|
||||
const disableSubmit = lookupName === '' || lookupVersion === '' ||
|
||||
lookupTier === '' || !validJson(lookupSpec);
|
||||
|
||||
return <Dialog
|
||||
className={"lookup-edit-dialog"}
|
||||
className="lookup-edit-dialog"
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
title={isEdit ? "Edit lookup" : "Add lookup"}
|
||||
title={isEdit ? 'Edit lookup' : 'Add lookup'}
|
||||
>
|
||||
<FormGroup className={"lookup-label"} label={"Name: "}>
|
||||
<FormGroup className="lookup-label" label="Name: ">
|
||||
<InputGroup
|
||||
value={lookupName}
|
||||
onChange={(e: any) => onChange("lookupEditName", e.target.value)}
|
||||
onChange={(e: any) => onChange('lookupEditName', e.target.value)}
|
||||
disabled={isEdit}
|
||||
placeholder={"Enter the lookup name"}
|
||||
placeholder="Enter the lookup name"
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{this.renderTierInput()}
|
||||
|
||||
<FormGroup className={"lookup-label"} label={"Version:"}>
|
||||
<FormGroup className="lookup-label" label="Version:">
|
||||
<InputGroup
|
||||
value={lookupVersion}
|
||||
onChange={(e: any) => onChange("lookupEditVersion", e.target.value)}
|
||||
placeholder={"Enter the lookup version"}
|
||||
rightElement={<Button minimal text={"Use ISO as version"} onClick={() => this.addISOVersion()} />}
|
||||
onChange={(e: any) => onChange('lookupEditVersion', e.target.value)}
|
||||
placeholder="Enter the lookup version"
|
||||
rightElement={<Button minimal text="Use ISO as version" onClick={() => this.addISOVersion()} />}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className={"lookup-label"} label={"Spec:"}/>
|
||||
<FormGroup className="lookup-label" label="Spec:"/>
|
||||
|
||||
<AceEditor
|
||||
className={"lookup-edit-dialog-textarea"}
|
||||
className="lookup-edit-dialog-textarea"
|
||||
mode="sql"
|
||||
theme="solarized_dark"
|
||||
onChange={
|
||||
(e: any) => onChange("lookupEditSpec", e)
|
||||
(e: any) => onChange('lookupEditSpec', e)
|
||||
}
|
||||
fontSize={12}
|
||||
height={"40vh"}
|
||||
width={"auto"}
|
||||
height="40vh"
|
||||
width="auto"
|
||||
showPrintMargin={false}
|
||||
showGutter={false}
|
||||
value={lookupSpec}
|
||||
|
|
|
@ -16,18 +16,18 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Intent } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import axios from "axios";
|
||||
import * as React from "react";
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as React from 'react';
|
||||
|
||||
import { AutoForm } from "../components/auto-form";
|
||||
import { AppToaster } from "../singletons/toaster";
|
||||
import { getDruidErrorMessage, QueryManager } from "../utils";
|
||||
import { AutoForm } from '../components/auto-form';
|
||||
import { AppToaster } from '../singletons/toaster';
|
||||
import { getDruidErrorMessage, QueryManager } from '../utils';
|
||||
|
||||
import { SnitchDialog } from "./snitch-dialog";
|
||||
import { SnitchDialog } from './snitch-dialog';
|
||||
|
||||
import "./overlord-dynamic-config.scss";
|
||||
import './overlord-dynamic-config.scss';
|
||||
|
||||
export interface OverlordDynamicConfigDialogProps extends React.Props<any> {
|
||||
onClose: () => void;
|
||||
|
@ -72,7 +72,7 @@ export class OverlordDynamicConfigDialog extends React.Component<OverlordDynamic
|
|||
async getConfig() {
|
||||
let config: Record<string, any> | null = null;
|
||||
try {
|
||||
const configResp = await axios.get("/druid/indexer/v1/worker");
|
||||
const configResp = await axios.get('/druid/indexer/v1/worker');
|
||||
config = configResp.data || {};
|
||||
} catch (e) {
|
||||
AppToaster.show({
|
||||
|
@ -91,10 +91,10 @@ export class OverlordDynamicConfigDialog extends React.Component<OverlordDynamic
|
|||
const { onClose } = this.props;
|
||||
const newState: any = this.state.dynamicConfig;
|
||||
try {
|
||||
await axios.post("/druid/indexer/v1/worker", newState, {
|
||||
await axios.post('/druid/indexer/v1/worker', newState, {
|
||||
headers: {
|
||||
"X-Druid-Author": "console",
|
||||
"X-Druid-Comment": comment
|
||||
'X-Druid-Author': 'console',
|
||||
'X-Druid-Comment': comment
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -132,12 +132,12 @@ export class OverlordDynamicConfigDialog extends React.Component<OverlordDynamic
|
|||
<AutoForm
|
||||
fields={[
|
||||
{
|
||||
name: "selectStrategy",
|
||||
type: "json"
|
||||
name: 'selectStrategy',
|
||||
type: 'json'
|
||||
},
|
||||
{
|
||||
name: "autoScaler",
|
||||
type: "json"
|
||||
name: 'autoScaler',
|
||||
type: 'json'
|
||||
}
|
||||
]}
|
||||
model={dynamicConfig}
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Classes, Dialog, FormGroup, InputGroup, TextArea } from "@blueprintjs/core";
|
||||
import * as React from "react";
|
||||
import { Button, Classes, Dialog, FormGroup, InputGroup, TextArea } from '@blueprintjs/core';
|
||||
import * as React from 'react';
|
||||
|
||||
import { BasicQueryExplanation, SemiJoinQueryExplanation } from "../utils";
|
||||
import { BasicQueryExplanation, SemiJoinQueryExplanation } from '../utils';
|
||||
|
||||
import "./query-plan-dialog.scss";
|
||||
import './query-plan-dialog.scss';
|
||||
|
||||
export interface QueryPlanDialogProps extends React.Props<any> {
|
||||
explainResult: BasicQueryExplanation | SemiJoinQueryExplanation | string | null;
|
||||
|
@ -53,17 +53,17 @@ export class QueryPlanDialog extends React.Component<QueryPlanDialogProps, Query
|
|||
|
||||
let signature: JSX.Element | null = null;
|
||||
if ((explainResult as BasicQueryExplanation).signature) {
|
||||
const signatureContent = (explainResult as BasicQueryExplanation).signature || "";
|
||||
const signatureContent = (explainResult as BasicQueryExplanation).signature || '';
|
||||
signature = <FormGroup
|
||||
label={"Signature"}
|
||||
label="Signature"
|
||||
>
|
||||
<InputGroup defaultValue={signatureContent} readOnly/>
|
||||
</FormGroup>;
|
||||
}
|
||||
|
||||
content = <div className={"one-query"}>
|
||||
content = <div className="one-query">
|
||||
<FormGroup
|
||||
label={"Query"}
|
||||
label="Query"
|
||||
>
|
||||
<TextArea
|
||||
readOnly
|
||||
|
@ -77,25 +77,25 @@ export class QueryPlanDialog extends React.Component<QueryPlanDialogProps, Query
|
|||
let mainSignature: JSX.Element | null = null;
|
||||
let subSignature: JSX.Element | null = null;
|
||||
if ((explainResult as SemiJoinQueryExplanation).mainQuery.signature) {
|
||||
const signatureContent = (explainResult as SemiJoinQueryExplanation).mainQuery.signature || "";
|
||||
const signatureContent = (explainResult as SemiJoinQueryExplanation).mainQuery.signature || '';
|
||||
mainSignature = <FormGroup
|
||||
label={"Signature"}
|
||||
label="Signature"
|
||||
>
|
||||
<InputGroup defaultValue={signatureContent} readOnly/>
|
||||
</FormGroup>;
|
||||
}
|
||||
if ((explainResult as SemiJoinQueryExplanation).subQueryRight.signature) {
|
||||
const signatureContent = (explainResult as SemiJoinQueryExplanation).subQueryRight.signature || "";
|
||||
const signatureContent = (explainResult as SemiJoinQueryExplanation).subQueryRight.signature || '';
|
||||
subSignature = <FormGroup
|
||||
label={"Signature"}
|
||||
label="Signature"
|
||||
>
|
||||
<InputGroup defaultValue={signatureContent} readOnly/>
|
||||
</FormGroup>;
|
||||
}
|
||||
|
||||
content = <div className={"two-queries"}>
|
||||
content = <div className="two-queries">
|
||||
<FormGroup
|
||||
label={"Main query"}
|
||||
label="Main query"
|
||||
>
|
||||
<TextArea
|
||||
readOnly
|
||||
|
@ -104,7 +104,7 @@ export class QueryPlanDialog extends React.Component<QueryPlanDialogProps, Query
|
|||
</FormGroup>
|
||||
{mainSignature}
|
||||
<FormGroup
|
||||
label={"Sub query"}
|
||||
label="Sub query"
|
||||
>
|
||||
<TextArea
|
||||
readOnly
|
||||
|
@ -118,10 +118,10 @@ export class QueryPlanDialog extends React.Component<QueryPlanDialogProps, Query
|
|||
}
|
||||
|
||||
return <Dialog
|
||||
className={'query-plan-dialog'}
|
||||
className="query-plan-dialog"
|
||||
isOpen
|
||||
onClose={onClose}
|
||||
title={"Query plan"}
|
||||
title="Query plan"
|
||||
>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
{content}
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, FormGroup } from "@blueprintjs/core";
|
||||
import { Button, FormGroup } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as React from 'react';
|
||||
|
||||
import { Rule, RuleEditor } from '../components/rule-editor';
|
||||
import { QueryManager } from "../utils";
|
||||
import { QueryManager } from '../utils';
|
||||
|
||||
import { SnitchDialog } from './snitch-dialog';
|
||||
|
||||
|
|
|
@ -24,12 +24,12 @@ import {
|
|||
IDialogProps,
|
||||
InputGroup,
|
||||
Intent
|
||||
} from "@blueprintjs/core";
|
||||
} from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import classNames = require('classnames');
|
||||
import * as React from 'react';
|
||||
|
||||
import { HistoryDialog } from "./history-dialog";
|
||||
import { HistoryDialog } from './history-dialog';
|
||||
|
||||
import './snitch-dialog.scss';
|
||||
|
||||
|
@ -54,7 +54,7 @@ export class SnitchDialog extends React.Component<SnitchDialogProps, SnitchDialo
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
comment: "",
|
||||
comment: '',
|
||||
saveDisabled: true
|
||||
};
|
||||
}
|
||||
|
@ -107,11 +107,11 @@ export class SnitchDialog extends React.Component<SnitchDialogProps, SnitchDialo
|
|||
|
||||
return <Dialog {...this.props}>
|
||||
<div className={`dialog-body ${Classes.DIALOG_BODY}`}>
|
||||
<FormGroup label={"Why are you making this change?"} className={"comment"}>
|
||||
<FormGroup label="Why are you making this change?" className="comment">
|
||||
<InputGroup
|
||||
large
|
||||
value={comment}
|
||||
placeholder={"Enter description here"}
|
||||
placeholder="Enter description here"
|
||||
onChange={(e: any) => this.changeComment(e.target.value)}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
@ -147,7 +147,7 @@ export class SnitchDialog extends React.Component<SnitchDialogProps, SnitchDialo
|
|||
|
||||
{ showFinalStep
|
||||
? <Button onClick={this.back} icon={IconNames.ARROW_LEFT}>Back</Button>
|
||||
: onReset ? <Button onClick={this.reset} intent={"none" as any}>Reset</Button> : null
|
||||
: onReset ? <Button onClick={this.reset} intent={'none' as any}>Reset</Button> : null
|
||||
}
|
||||
|
||||
{ showFinalStep
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Classes, Dialog, Intent } from "@blueprintjs/core";
|
||||
import "brace/mode/json";
|
||||
import "brace/theme/solarized_dark";
|
||||
import * as React from "react";
|
||||
import AceEditor from "react-ace";
|
||||
import { Button, Classes, Dialog, Intent } from '@blueprintjs/core';
|
||||
import 'brace/mode/json';
|
||||
import 'brace/theme/solarized_dark';
|
||||
import * as React from 'react';
|
||||
import AceEditor from 'react-ace';
|
||||
|
||||
import "./spec-dialog.scss";
|
||||
import './spec-dialog.scss';
|
||||
|
||||
export interface SpecDialogProps extends React.Props<any> {
|
||||
onSubmit: (spec: JSON) => void;
|
||||
|
@ -65,7 +65,7 @@ export class SpecDialog extends React.Component<SpecDialogProps, SpecDialogState
|
|||
const { spec } = this.state;
|
||||
|
||||
return <Dialog
|
||||
className={"spec-dialog"}
|
||||
className="spec-dialog"
|
||||
isOpen
|
||||
onClose={onClose}
|
||||
title={title}
|
||||
|
@ -74,14 +74,14 @@ export class SpecDialog extends React.Component<SpecDialogProps, SpecDialogState
|
|||
<AceEditor
|
||||
mode="json"
|
||||
theme="solarized_dark"
|
||||
className={"spec-dialog-textarea"}
|
||||
className="spec-dialog-textarea"
|
||||
onChange={(e) => { this.setState({ spec: e }); }}
|
||||
fontSize={12}
|
||||
showPrintMargin={false}
|
||||
showGutter
|
||||
highlightActiveLine
|
||||
value={spec}
|
||||
width={"100%"}
|
||||
width="100%"
|
||||
setOptions={{
|
||||
enableBasicAutocompletion: true,
|
||||
enableLiveAutocompletion: true,
|
||||
|
|
|
@ -21,11 +21,10 @@ import 'es7-shim'; // Webpack with automatically pick browser.js which does the
|
|||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
|
||||
import "./bootstrap/a-shim-for-react-props";
|
||||
import "./bootstrap/react-table-defaults";
|
||||
import './bootstrap/react-table-defaults';
|
||||
import { ConsoleApplication } from './console-application';
|
||||
|
||||
import "./entry.scss";
|
||||
import './entry.scss';
|
||||
|
||||
const container = document.getElementsByClassName('app-container')[0];
|
||||
if (!container) throw new Error('container not found');
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Position, Toaster } from "@blueprintjs/core";
|
||||
import { Position, Toaster } from '@blueprintjs/core';
|
||||
|
||||
export const AppToaster = Toaster.create({
|
||||
className: "recipe-toaster",
|
||||
className: 'recipe-toaster',
|
||||
position: Position.TOP
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ export function getDruidErrorMessage(e: any) {
|
|||
export async function queryDruidRune(runeQuery: Record<string, any>): Promise<any> {
|
||||
let runeResultResp: AxiosResponse<any>;
|
||||
try {
|
||||
runeResultResp = await axios.post("/druid/v2", runeQuery);
|
||||
runeResultResp = await axios.post('/druid/v2', runeQuery);
|
||||
} catch (e) {
|
||||
throw new Error(getDruidErrorMessage(e));
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export async function queryDruidRune(runeQuery: Record<string, any>): Promise<an
|
|||
export async function queryDruidSql(sqlQuery: Record<string, any>): Promise<any[]> {
|
||||
let sqlResultResp: AxiosResponse<any>;
|
||||
try {
|
||||
sqlResultResp = await axios.post("/druid/v2/sql", sqlQuery);
|
||||
sqlResultResp = await axios.post('/druid/v2/sql', sqlQuery);
|
||||
} catch (e) {
|
||||
throw new Error(getDruidErrorMessage(e));
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
import { Button, HTMLSelect, InputGroup, Intent } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import * as numeral from "numeral";
|
||||
import * as numeral from 'numeral';
|
||||
import * as React from 'react';
|
||||
import { Filter, FilterRender } from 'react-table';
|
||||
|
||||
|
@ -55,7 +55,7 @@ export function makeBooleanFilter(): FilterRender {
|
|||
key={key}
|
||||
style={{ width: '100%' }}
|
||||
onChange={(event: any) => onChange(event.target.value)}
|
||||
value={filterValue || "all"}
|
||||
value={filterValue || 'all'}
|
||||
fill
|
||||
>
|
||||
<option value="all">Show all</option>
|
||||
|
@ -141,13 +141,13 @@ export function stringifyJSON(item: any): string {
|
|||
if (item != null) {
|
||||
return JSON.stringify(item, null, 2);
|
||||
} else {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// parse string to JSON object; if string is empty, return null
|
||||
export function parseStringToJSON(s: string): JSON | null {
|
||||
if (s === "") {
|
||||
if (s === '') {
|
||||
return null;
|
||||
} else {
|
||||
return JSON.parse(s);
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
*/
|
||||
|
||||
export const LocalStorageKeys = {
|
||||
DATASOURCE_TABLE_COLUMN_SELECTION: "datasource-table-column-selection" as "datasource-table-column-selection",
|
||||
SEGMENT_TABLE_COLUMN_SELECTION: "segment-table-column-selection" as "segment-table-column-selection",
|
||||
SUPERVISOR_TABLE_COLUMN_SELECTION: "supervisor-table-column-selection" as "supervisor-table-column-selection",
|
||||
TASK_TABLE_COLUMN_SELECTION: "task-table-column-selection" as "task-table-column-selection",
|
||||
SERVER_TABLE_COLUMN_SELECTION: "historical-table-column-selection" as "historical-table-column-selection",
|
||||
MIDDLEMANAGER_TABLE_COLUMN_SELECTION: "middleManager-table-column-selection" as "middleManager-table-column-selection",
|
||||
LOOKUP_TABLE_COLUMN_SELECTION: "lookup-table-column-selection" as "lookup-table-column-selection",
|
||||
DATASOURCE_TABLE_COLUMN_SELECTION: 'datasource-table-column-selection' as 'datasource-table-column-selection',
|
||||
SEGMENT_TABLE_COLUMN_SELECTION: 'segment-table-column-selection' as 'segment-table-column-selection',
|
||||
SUPERVISOR_TABLE_COLUMN_SELECTION: 'supervisor-table-column-selection' as 'supervisor-table-column-selection',
|
||||
TASK_TABLE_COLUMN_SELECTION: 'task-table-column-selection' as 'task-table-column-selection',
|
||||
SERVER_TABLE_COLUMN_SELECTION: 'historical-table-column-selection' as 'historical-table-column-selection',
|
||||
MIDDLEMANAGER_TABLE_COLUMN_SELECTION: 'middleManager-table-column-selection' as 'middleManager-table-column-selection',
|
||||
LOOKUP_TABLE_COLUMN_SELECTION: 'lookup-table-column-selection' as 'lookup-table-column-selection',
|
||||
QUERY_KEY: 'druid-console-query' as 'druid-console-query'
|
||||
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { localStorageGet, LocalStorageKeys, localStorageSet } from "../utils";
|
||||
import { localStorageGet, LocalStorageKeys, localStorageSet } from '../utils';
|
||||
|
||||
export class TableColumnSelectionHandler {
|
||||
tableName: LocalStorageKeys;
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export const LEGACY_COORDINATOR_CONSOLE = "/index.html";
|
||||
export const LEGACY_OVERLORD_CONSOLE = "/console.html";
|
||||
export const LEGACY_COORDINATOR_CONSOLE = '/index.html';
|
||||
export const LEGACY_OVERLORD_CONSOLE = '/console.html';
|
||||
|
||||
export const DRUID_WEBSITE = "http://druid.io";
|
||||
export const DRUID_GITHUB = "https://github.com/apache/druid";
|
||||
export const DRUID_DOCS = "http://druid.io/docs/latest";
|
||||
export const DRUID_DOCS_SQL = "http://druid.io/docs/latest/querying/sql.html";
|
||||
export const DRUID_COMMUNITY = "http://druid.io/community/";
|
||||
export const DRUID_USER_GROUP = "https://groups.google.com/forum/#!forum/druid-user";
|
||||
export const DRUID_DEVELOPER_GROUP = "https://lists.apache.org/list.html?dev@druid.apache.org";
|
||||
export const DRUID_WEBSITE = 'http://druid.io';
|
||||
export const DRUID_GITHUB = 'https://github.com/apache/druid';
|
||||
export const DRUID_DOCS = 'http://druid.io/docs/latest';
|
||||
export const DRUID_DOCS_SQL = 'http://druid.io/docs/latest/querying/sql.html';
|
||||
export const DRUID_COMMUNITY = 'http://druid.io/community/';
|
||||
export const DRUID_USER_GROUP = 'https://groups.google.com/forum/#!forum/druid-user';
|
||||
export const DRUID_DEVELOPER_GROUP = 'https://lists.apache.org/list.html?dev@druid.apache.org';
|
||||
|
|
|
@ -16,16 +16,16 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Intent, Switch } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { Button, Intent, Switch } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as React from 'react';
|
||||
import ReactTable, { Filter } from "react-table";
|
||||
import ReactTable, { Filter } from 'react-table';
|
||||
|
||||
import { RuleEditor } from '../components/rule-editor';
|
||||
import { TableColumnSelection } from "../components/table-column-selection";
|
||||
import { TableColumnSelection } from '../components/table-column-selection';
|
||||
import { AsyncActionDialog } from '../dialogs/async-action-dialog';
|
||||
import { CompactionDialog } from "../dialogs/compaction-dialog";
|
||||
import { CompactionDialog } from '../dialogs/compaction-dialog';
|
||||
import { RetentionDialog } from '../dialogs/retention-dialog';
|
||||
import { AppToaster } from '../singletons/toaster';
|
||||
import {
|
||||
|
@ -38,11 +38,11 @@ import {
|
|||
pluralIfNeeded,
|
||||
queryDruidSql,
|
||||
QueryManager, TableColumnSelectionHandler
|
||||
} from "../utils";
|
||||
} from '../utils';
|
||||
|
||||
import "./datasource-view.scss";
|
||||
import './datasource-view.scss';
|
||||
|
||||
const tableColumns: string[] = ["Datasource", "Availability", "Retention", "Compaction", "Size", "Num rows", "Actions"];
|
||||
const tableColumns: string[] = ['Datasource', 'Availability', 'Retention', 'Compaction', 'Size', 'Num rows', 'Actions'];
|
||||
|
||||
export interface DatasourcesViewProps extends React.Props<any> {
|
||||
goToSql: (initSql: string) => void;
|
||||
|
@ -252,8 +252,8 @@ GROUP BY 1`);
|
|||
try {
|
||||
await axios.post(`/druid/coordinator/v1/rules/${datasource}`, rules, {
|
||||
headers: {
|
||||
"X-Druid-Author": "console",
|
||||
"X-Druid-Comment": comment
|
||||
'X-Druid-Author': 'console',
|
||||
'X-Druid-Comment': comment
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -308,7 +308,7 @@ GROUP BY 1`);
|
|||
message: `Are you sure you want to delete ${datasource}'s compaction?`,
|
||||
intent: Intent.DANGER,
|
||||
action: {
|
||||
text: "Confirm",
|
||||
text: 'Confirm',
|
||||
onClick: async () => {
|
||||
try {
|
||||
await axios.delete(`/druid/coordinator/v1/config/compaction/${datasource}`);
|
||||
|
@ -372,18 +372,18 @@ GROUP BY 1`);
|
|||
}}
|
||||
columns={[
|
||||
{
|
||||
Header: "Datasource",
|
||||
accessor: "datasource",
|
||||
Header: 'Datasource',
|
||||
accessor: 'datasource',
|
||||
width: 150,
|
||||
Cell: row => {
|
||||
const value = row.value;
|
||||
return <a onClick={() => { this.setState({ datasourcesFilter: addFilter(datasourcesFilter, 'datasource', value) }); }}>{value}</a>;
|
||||
},
|
||||
show: tableColumnSelectionHandler.showColumn("Datasource")
|
||||
show: tableColumnSelectionHandler.showColumn('Datasource')
|
||||
},
|
||||
{
|
||||
Header: "Availability",
|
||||
id: "availability",
|
||||
Header: 'Availability',
|
||||
id: 'availability',
|
||||
filterable: false,
|
||||
accessor: (row) => row.num_available_segments / row.num_segments,
|
||||
Cell: (row) => {
|
||||
|
@ -414,7 +414,7 @@ GROUP BY 1`);
|
|||
|
||||
}
|
||||
},
|
||||
show: tableColumnSelectionHandler.showColumn("Availability")
|
||||
show: tableColumnSelectionHandler.showColumn('Availability')
|
||||
},
|
||||
{
|
||||
Header: 'Retention',
|
||||
|
@ -432,13 +432,13 @@ GROUP BY 1`);
|
|||
|
||||
return <span
|
||||
onClick={() => this.setState({retentionDialogOpenOn: { datasource: row.original.datasource, rules: row.original.rules }})}
|
||||
className={"clickable-cell"}
|
||||
className="clickable-cell"
|
||||
>
|
||||
{text}
|
||||
<a>✎</a>
|
||||
</span>;
|
||||
},
|
||||
show: tableColumnSelectionHandler.showColumn("Retention")
|
||||
show: tableColumnSelectionHandler.showColumn('Retention')
|
||||
},
|
||||
{
|
||||
Header: 'Compaction',
|
||||
|
@ -458,14 +458,14 @@ GROUP BY 1`);
|
|||
text = 'None';
|
||||
}
|
||||
return <span
|
||||
className={"clickable-cell"}
|
||||
className="clickable-cell"
|
||||
onClick={() => this.setState({compactionDialogOpenOn: compactionOpenOn})}
|
||||
>
|
||||
{text}
|
||||
<a>✎</a>
|
||||
</span>;
|
||||
},
|
||||
show: tableColumnSelectionHandler.showColumn("Compaction")
|
||||
show: tableColumnSelectionHandler.showColumn('Compaction')
|
||||
},
|
||||
{
|
||||
Header: 'Size',
|
||||
|
@ -473,7 +473,7 @@ GROUP BY 1`);
|
|||
filterable: false,
|
||||
width: 100,
|
||||
Cell: (row) => formatBytes(row.value),
|
||||
show: tableColumnSelectionHandler.showColumn("Size")
|
||||
show: tableColumnSelectionHandler.showColumn('Size')
|
||||
},
|
||||
{
|
||||
Header: 'Num rows',
|
||||
|
@ -481,7 +481,7 @@ GROUP BY 1`);
|
|||
filterable: false,
|
||||
width: 100,
|
||||
Cell: (row) => formatNumber(row.value),
|
||||
show: tableColumnSelectionHandler.showColumn("Num rows")
|
||||
show: tableColumnSelectionHandler.showColumn('Num rows')
|
||||
},
|
||||
{
|
||||
Header: 'Actions',
|
||||
|
@ -503,7 +503,7 @@ GROUP BY 1`);
|
|||
</div>;
|
||||
}
|
||||
},
|
||||
show: tableColumnSelectionHandler.showColumn("Actions")
|
||||
show: tableColumnSelectionHandler.showColumn('Actions')
|
||||
}
|
||||
]}
|
||||
defaultPageSize={50}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Card, H5, Icon } from "@blueprintjs/core";
|
||||
import { IconName, IconNames } from "@blueprintjs/icons";
|
||||
import { Card, H5, Icon } from '@blueprintjs/core';
|
||||
import { IconName, IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
|
@ -175,13 +175,13 @@ export class HomeView extends React.Component<HomeViewProps, HomeViewState> {
|
|||
pendingTaskCount: 0
|
||||
};
|
||||
for (const dataStatus of taskCountsFromSql) {
|
||||
if (dataStatus.status === "SUCCESS") {
|
||||
if (dataStatus.status === 'SUCCESS') {
|
||||
taskCounts.successTaskCount = dataStatus.count;
|
||||
} else if (dataStatus.status === "FAILED") {
|
||||
} else if (dataStatus.status === 'FAILED') {
|
||||
taskCounts.failedTaskCount = dataStatus.count;
|
||||
} else if (dataStatus.status === "RUNNING") {
|
||||
} else if (dataStatus.status === 'RUNNING') {
|
||||
taskCounts.runningTaskCount = dataStatus.count;
|
||||
} else if (dataStatus.status === "WAITING") {
|
||||
} else if (dataStatus.status === 'WAITING') {
|
||||
taskCounts.waitingTaskCount = dataStatus.count;
|
||||
} else {
|
||||
taskCounts.pendingTaskCount = dataStatus.count;
|
||||
|
@ -230,7 +230,7 @@ GROUP BY 1`);
|
|||
|
||||
this.middleManagerQueryManager = new QueryManager({
|
||||
processQuery: async (query) => {
|
||||
const middleManagerResp = await axios.get("/druid/indexer/v1/workers");
|
||||
const middleManagerResp = await axios.get('/druid/indexer/v1/workers');
|
||||
const middleManagerCount: number = middleManagerResp.data.length;
|
||||
return middleManagerCount;
|
||||
},
|
||||
|
@ -269,36 +269,36 @@ GROUP BY 1`);
|
|||
|
||||
return <div className="home-view app-view">
|
||||
{this.renderCard({
|
||||
href: "/status",
|
||||
href: '/status',
|
||||
icon: IconNames.GRAPH,
|
||||
title: "Status",
|
||||
title: 'Status',
|
||||
loading: state.statusLoading,
|
||||
content: state.status ? `Apache Druid is running version ${state.status.version}` : '',
|
||||
error: state.statusError
|
||||
})}
|
||||
|
||||
{this.renderCard({
|
||||
href: "#datasources",
|
||||
href: '#datasources',
|
||||
icon: IconNames.MULTI_SELECT,
|
||||
title: "Datasources",
|
||||
title: 'Datasources',
|
||||
loading: state.datasourceCountLoading,
|
||||
content: pluralIfNeeded(state.datasourceCount, 'datasource'),
|
||||
error: state.datasourceCountError
|
||||
})}
|
||||
|
||||
{this.renderCard({
|
||||
href: "#segments",
|
||||
href: '#segments',
|
||||
icon: IconNames.STACKED_CHART,
|
||||
title: "Segments",
|
||||
title: 'Segments',
|
||||
loading: state.segmentCountLoading,
|
||||
content: pluralIfNeeded(state.segmentCount, 'segment'),
|
||||
error: state.datasourceCountError
|
||||
})}
|
||||
|
||||
{this.renderCard({
|
||||
href: "#tasks",
|
||||
href: '#tasks',
|
||||
icon: IconNames.GANTT_CHART,
|
||||
title: "Tasks",
|
||||
title: 'Tasks',
|
||||
loading: state.taskCountLoading,
|
||||
content: <>
|
||||
{Boolean(state.runningTaskCount) && <p>{pluralIfNeeded(state.runningTaskCount, 'running task')}</p>}
|
||||
|
@ -314,9 +314,9 @@ GROUP BY 1`);
|
|||
})}
|
||||
|
||||
{this.renderCard({
|
||||
href: "#servers",
|
||||
href: '#servers',
|
||||
icon: IconNames.DATABASE,
|
||||
title: "Data servers",
|
||||
title: 'Data servers',
|
||||
loading: state.dataServerCountLoading || state.middleManagerCountLoading,
|
||||
content: <>
|
||||
<p>{pluralIfNeeded(state.dataServerCount, 'historical')}</p>
|
||||
|
|
|
@ -16,26 +16,26 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Intent } from "@blueprintjs/core";
|
||||
import { Button, Intent } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
import ReactTable from "react-table";
|
||||
import ReactTable from 'react-table';
|
||||
|
||||
import { TableColumnSelection } from "../components/table-column-selection";
|
||||
import { TableColumnSelection } from '../components/table-column-selection';
|
||||
import { AsyncActionDialog } from '../dialogs/async-action-dialog';
|
||||
import { LookupEditDialog } from "../dialogs/lookup-edit-dialog";
|
||||
import { AppToaster } from "../singletons/toaster";
|
||||
import { LookupEditDialog } from '../dialogs/lookup-edit-dialog';
|
||||
import { AppToaster } from '../singletons/toaster';
|
||||
import {
|
||||
getDruidErrorMessage, LocalStorageKeys,
|
||||
QueryManager,
|
||||
TableColumnSelectionHandler
|
||||
} from "../utils";
|
||||
} from '../utils';
|
||||
|
||||
import "./lookups-view.scss";
|
||||
import './lookups-view.scss';
|
||||
|
||||
const tableColumns: string[] = ["Lookup name", "Tier", "Type", "Version", "Actions"];
|
||||
const tableColumns: string[] = ['Lookup name', 'Tier', 'Type', 'Version', 'Actions'];
|
||||
|
||||
export interface LookupsViewProps extends React.Props<any> {
|
||||
|
||||
|
@ -70,10 +70,10 @@ export class LookupsView extends React.Component<LookupsViewProps, LookupsViewSt
|
|||
lookupsError: null,
|
||||
lookupsUninitialized: false,
|
||||
lookupEditDialogOpen: false,
|
||||
lookupEditTier: "",
|
||||
lookupEditName: "",
|
||||
lookupEditVersion: "",
|
||||
lookupEditSpec: "",
|
||||
lookupEditTier: '',
|
||||
lookupEditName: '',
|
||||
lookupEditVersion: '',
|
||||
lookupEditSpec: '',
|
||||
isEdit: false,
|
||||
allLookupTiers: [],
|
||||
|
||||
|
@ -92,7 +92,7 @@ export class LookupsView extends React.Component<LookupsViewProps, LookupsViewSt
|
|||
const tiers = tiersResp.data;
|
||||
|
||||
const lookupEntries: {}[] = [];
|
||||
const lookupResp = await axios.get("/druid/coordinator/v1/lookups/config/all");
|
||||
const lookupResp = await axios.get('/druid/coordinator/v1/lookups/config/all');
|
||||
const lookupData = lookupResp.data;
|
||||
Object.keys(lookupData).map((tier: string) => {
|
||||
const lookupIds = lookupData[tier];
|
||||
|
@ -117,7 +117,7 @@ export class LookupsView extends React.Component<LookupsViewProps, LookupsViewSt
|
|||
}
|
||||
});
|
||||
|
||||
this.lookupsGetQueryManager.runQuery("dummy");
|
||||
this.lookupsGetQueryManager.runQuery('dummy');
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
|
@ -146,12 +146,12 @@ export class LookupsView extends React.Component<LookupsViewProps, LookupsViewSt
|
|||
const target: any = lookups.find((lookupEntry: any) => {
|
||||
return lookupEntry.tier === tier && lookupEntry.id === id;
|
||||
});
|
||||
if (id === "") {
|
||||
if (id === '') {
|
||||
this.setState({
|
||||
lookupEditName: "",
|
||||
lookupEditName: '',
|
||||
lookupEditTier: allLookupTiers[0],
|
||||
lookupEditDialogOpen: true,
|
||||
lookupEditSpec: "",
|
||||
lookupEditSpec: '',
|
||||
lookupEditVersion: (new Date()).toISOString(),
|
||||
isEdit: false
|
||||
});
|
||||
|
@ -175,7 +175,7 @@ export class LookupsView extends React.Component<LookupsViewProps, LookupsViewSt
|
|||
|
||||
private async submitLookupEdit() {
|
||||
const { lookupEditTier, lookupEditName, lookupEditSpec, lookupEditVersion, isEdit } = this.state;
|
||||
let endpoint = "/druid/coordinator/v1/lookups/config";
|
||||
let endpoint = '/druid/coordinator/v1/lookups/config';
|
||||
const specJSON: any = JSON.parse(lookupEditSpec);
|
||||
let dataJSON: any;
|
||||
if (isEdit) {
|
||||
|
@ -240,7 +240,7 @@ export class LookupsView extends React.Component<LookupsViewProps, LookupsViewSt
|
|||
const { tableColumnSelectionHandler } = this;
|
||||
|
||||
if (lookupsUninitialized) {
|
||||
return <div className={"init-div"}>
|
||||
return <div className="init-div">
|
||||
<Button
|
||||
icon={IconNames.BUILD}
|
||||
text="Initialize lookup"
|
||||
|
@ -257,36 +257,36 @@ export class LookupsView extends React.Component<LookupsViewProps, LookupsViewSt
|
|||
filterable
|
||||
columns={[
|
||||
{
|
||||
Header: "Lookup name",
|
||||
id: "lookup_name",
|
||||
Header: 'Lookup name',
|
||||
id: 'lookup_name',
|
||||
accessor: (row: any) => row.id,
|
||||
filterable: true,
|
||||
show: tableColumnSelectionHandler.showColumn("Lookup name")
|
||||
show: tableColumnSelectionHandler.showColumn('Lookup name')
|
||||
},
|
||||
{
|
||||
Header: "Tier",
|
||||
id: "tier",
|
||||
Header: 'Tier',
|
||||
id: 'tier',
|
||||
accessor: (row: any) => row.tier,
|
||||
filterable: true,
|
||||
show: tableColumnSelectionHandler.showColumn("Tier")
|
||||
show: tableColumnSelectionHandler.showColumn('Tier')
|
||||
},
|
||||
{
|
||||
Header: "Type",
|
||||
id: "type",
|
||||
Header: 'Type',
|
||||
id: 'type',
|
||||
accessor: (row: any) => row.spec.type,
|
||||
filterable: true,
|
||||
show: tableColumnSelectionHandler.showColumn("Type")
|
||||
show: tableColumnSelectionHandler.showColumn('Type')
|
||||
},
|
||||
{
|
||||
Header: "Version",
|
||||
id: "version",
|
||||
Header: 'Version',
|
||||
id: 'version',
|
||||
accessor: (row: any) => row.version,
|
||||
filterable: true,
|
||||
show: tableColumnSelectionHandler.showColumn("Version")
|
||||
show: tableColumnSelectionHandler.showColumn('Version')
|
||||
},
|
||||
{
|
||||
Header: "Actions",
|
||||
id: "actions",
|
||||
Header: 'Actions',
|
||||
id: 'actions',
|
||||
accessor: row => ({id: row.id, tier: row.tier}),
|
||||
filterable: false,
|
||||
Cell: (row: any) => {
|
||||
|
@ -298,7 +298,7 @@ export class LookupsView extends React.Component<LookupsViewProps, LookupsViewSt
|
|||
<a onClick={() => this.setState({ deleteLookupTier: lookupTier, deleteLookupName: lookupId })}>Delete</a>
|
||||
</div>;
|
||||
},
|
||||
show: tableColumnSelectionHandler.showColumn("Actions")
|
||||
show: tableColumnSelectionHandler.showColumn('Actions')
|
||||
}
|
||||
]}
|
||||
defaultPageSize={50}
|
||||
|
@ -340,7 +340,7 @@ export class LookupsView extends React.Component<LookupsViewProps, LookupsViewSt
|
|||
<Button
|
||||
icon={IconNames.PLUS}
|
||||
text="Add"
|
||||
onClick={() => this.openLookupEditDialog("", "")}
|
||||
onClick={() => this.openLookupEditDialog('', '')}
|
||||
/>
|
||||
}
|
||||
<TableColumnSelection
|
||||
|
|
|
@ -16,17 +16,17 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Intent } from "@blueprintjs/core";
|
||||
import { H5 } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { Button, Intent } from '@blueprintjs/core';
|
||||
import { H5 } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
import ReactTable from "react-table";
|
||||
import { Filter } from "react-table";
|
||||
import ReactTable from 'react-table';
|
||||
import { Filter } from 'react-table';
|
||||
|
||||
import { TableColumnSelection } from "../components/table-column-selection";
|
||||
import { AppToaster } from "../singletons/toaster";
|
||||
import { TableColumnSelection } from '../components/table-column-selection';
|
||||
import { AppToaster } from '../singletons/toaster';
|
||||
import {
|
||||
addFilter,
|
||||
formatBytes,
|
||||
|
@ -35,12 +35,12 @@ import {
|
|||
parseList,
|
||||
queryDruidSql,
|
||||
QueryManager, TableColumnSelectionHandler
|
||||
} from "../utils";
|
||||
} from '../utils';
|
||||
|
||||
import "./segments-view.scss";
|
||||
import './segments-view.scss';
|
||||
|
||||
const tableColumns: string[] = ["Segment ID", "Datasource", "Start", "End", "Version", "Partition",
|
||||
"Size", "Num rows", "Replicas", "Is published", "Is realtime", "Is available"];
|
||||
const tableColumns: string[] = ['Segment ID', 'Datasource', 'Start', 'End', 'Version', 'Partition',
|
||||
'Size', 'Num rows', 'Replicas', 'Is published', 'Is realtime', 'Is available'];
|
||||
|
||||
export interface SegmentsViewProps extends React.Props<any> {
|
||||
goToSql: (initSql: string) => void;
|
||||
|
@ -156,7 +156,7 @@ export class SegmentsView extends React.Component<SegmentsViewProps, SegmentsVie
|
|||
manual
|
||||
filterable
|
||||
filtered={segmentFilter}
|
||||
defaultSorted={[{id: "start", desc: true}]}
|
||||
defaultSorted={[{id: 'start', desc: true}]}
|
||||
onFilteredChange={(filtered, column) => {
|
||||
this.setState({ segmentFilter: filtered });
|
||||
}}
|
||||
|
@ -165,100 +165,100 @@ export class SegmentsView extends React.Component<SegmentsViewProps, SegmentsVie
|
|||
ofText=""
|
||||
columns={[
|
||||
{
|
||||
Header: "Segment ID",
|
||||
accessor: "segment_id",
|
||||
Header: 'Segment ID',
|
||||
accessor: 'segment_id',
|
||||
width: 300,
|
||||
show: tableColumnSelectionHandler.showColumn("Segment ID")
|
||||
show: tableColumnSelectionHandler.showColumn('Segment ID')
|
||||
},
|
||||
{
|
||||
Header: "Datasource",
|
||||
accessor: "datasource",
|
||||
Header: 'Datasource',
|
||||
accessor: 'datasource',
|
||||
Cell: row => {
|
||||
const value = row.value;
|
||||
return <a onClick={() => { this.setState({ segmentFilter: addFilter(segmentFilter, 'datasource', value) }); }}>{value}</a>;
|
||||
},
|
||||
show: tableColumnSelectionHandler.showColumn("Datasource")
|
||||
show: tableColumnSelectionHandler.showColumn('Datasource')
|
||||
},
|
||||
{
|
||||
Header: "Start",
|
||||
accessor: "start",
|
||||
Header: 'Start',
|
||||
accessor: 'start',
|
||||
width: 120,
|
||||
defaultSortDesc: true,
|
||||
Cell: row => {
|
||||
const value = row.value;
|
||||
return <a onClick={() => { this.setState({ segmentFilter: addFilter(segmentFilter, 'start', value) }); }}>{value}</a>;
|
||||
},
|
||||
show: tableColumnSelectionHandler.showColumn("Start")
|
||||
show: tableColumnSelectionHandler.showColumn('Start')
|
||||
},
|
||||
{
|
||||
Header: "End",
|
||||
accessor: "end",
|
||||
Header: 'End',
|
||||
accessor: 'end',
|
||||
defaultSortDesc: true,
|
||||
width: 120,
|
||||
Cell: row => {
|
||||
const value = row.value;
|
||||
return <a onClick={() => { this.setState({ segmentFilter: addFilter(segmentFilter, 'end', value) }); }}>{value}</a>;
|
||||
},
|
||||
show: tableColumnSelectionHandler.showColumn("End")
|
||||
show: tableColumnSelectionHandler.showColumn('End')
|
||||
},
|
||||
{
|
||||
Header: "Version",
|
||||
accessor: "version",
|
||||
Header: 'Version',
|
||||
accessor: 'version',
|
||||
defaultSortDesc: true,
|
||||
width: 120,
|
||||
show: tableColumnSelectionHandler.showColumn("Version")
|
||||
show: tableColumnSelectionHandler.showColumn('Version')
|
||||
},
|
||||
{
|
||||
Header: "Partition",
|
||||
accessor: "partition_num",
|
||||
Header: 'Partition',
|
||||
accessor: 'partition_num',
|
||||
width: 60,
|
||||
filterable: false,
|
||||
show: tableColumnSelectionHandler.showColumn("Partition")
|
||||
show: tableColumnSelectionHandler.showColumn('Partition')
|
||||
},
|
||||
{
|
||||
Header: "Size",
|
||||
accessor: "size",
|
||||
Header: 'Size',
|
||||
accessor: 'size',
|
||||
filterable: false,
|
||||
defaultSortDesc: true,
|
||||
Cell: row => formatBytes(row.value),
|
||||
show: tableColumnSelectionHandler.showColumn("Size")
|
||||
show: tableColumnSelectionHandler.showColumn('Size')
|
||||
},
|
||||
{
|
||||
Header: "Num rows",
|
||||
accessor: "num_rows",
|
||||
Header: 'Num rows',
|
||||
accessor: 'num_rows',
|
||||
filterable: false,
|
||||
defaultSortDesc: true,
|
||||
Cell: row => formatNumber(row.value),
|
||||
show: tableColumnSelectionHandler.showColumn("Num rows")
|
||||
show: tableColumnSelectionHandler.showColumn('Num rows')
|
||||
},
|
||||
{
|
||||
Header: "Replicas",
|
||||
accessor: "num_replicas",
|
||||
Header: 'Replicas',
|
||||
accessor: 'num_replicas',
|
||||
width: 60,
|
||||
filterable: false,
|
||||
defaultSortDesc: true,
|
||||
show: tableColumnSelectionHandler.showColumn("Replicas")
|
||||
show: tableColumnSelectionHandler.showColumn('Replicas')
|
||||
},
|
||||
{
|
||||
Header: "Is published",
|
||||
id: "is_published",
|
||||
Header: 'Is published',
|
||||
id: 'is_published',
|
||||
accessor: (row) => String(Boolean(row.is_published)),
|
||||
Filter: makeBooleanFilter(),
|
||||
show: tableColumnSelectionHandler.showColumn("Is published")
|
||||
show: tableColumnSelectionHandler.showColumn('Is published')
|
||||
},
|
||||
{
|
||||
Header: "Is realtime",
|
||||
id: "is_realtime",
|
||||
Header: 'Is realtime',
|
||||
id: 'is_realtime',
|
||||
accessor: (row) => String(Boolean(row.is_realtime)),
|
||||
Filter: makeBooleanFilter(),
|
||||
show: tableColumnSelectionHandler.showColumn("Is realtime")
|
||||
show: tableColumnSelectionHandler.showColumn('Is realtime')
|
||||
},
|
||||
{
|
||||
Header: "Is available",
|
||||
id: "is_available",
|
||||
Header: 'Is available',
|
||||
id: 'is_available',
|
||||
accessor: (row) => String(Boolean(row.is_available)),
|
||||
Filter: makeBooleanFilter(),
|
||||
show: tableColumnSelectionHandler.showColumn("Is available")
|
||||
show: tableColumnSelectionHandler.showColumn('Is available')
|
||||
}
|
||||
]}
|
||||
defaultPageSize={50}
|
||||
|
|
|
@ -16,28 +16,28 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Switch } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { Button, Switch } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as classNames from 'classnames';
|
||||
import { sum } from "d3-array";
|
||||
import { sum } from 'd3-array';
|
||||
import * as React from 'react';
|
||||
import ReactTable from "react-table";
|
||||
import { Filter } from "react-table";
|
||||
import ReactTable from 'react-table';
|
||||
import { Filter } from 'react-table';
|
||||
|
||||
import { TableColumnSelection } from "../components/table-column-selection";
|
||||
import { TableColumnSelection } from '../components/table-column-selection';
|
||||
import {
|
||||
addFilter,
|
||||
formatBytes,
|
||||
formatBytesCompact, LocalStorageKeys,
|
||||
queryDruidSql,
|
||||
QueryManager, TableColumnSelectionHandler
|
||||
} from "../utils";
|
||||
} from '../utils';
|
||||
|
||||
import "./servers-view.scss";
|
||||
import './servers-view.scss';
|
||||
|
||||
const serverTableColumns: string[] = ["Server", "Tier", "Curr size", "Max size", "Usage", "Load/drop queues", "Host", "Port"];
|
||||
const middleManagerTableColumns: string[] = ["Host", "Usage", "Availability groups", "Last completed task time", "Blacklisted until"];
|
||||
const serverTableColumns: string[] = ['Server', 'Tier', 'Curr size', 'Max size', 'Usage', 'Load/drop queues', 'Host', 'Port'];
|
||||
const middleManagerTableColumns: string[] = ['Host', 'Usage', 'Availability groups', 'Last completed task time', 'Blacklisted until'];
|
||||
|
||||
function formatQueues(segmentsToLoad: number, segmentsToLoadSize: number, segmentsToDrop: number, segmentsToDropSize: number): string {
|
||||
const queueParts: string[] = [];
|
||||
|
@ -104,7 +104,7 @@ export class ServersView extends React.Component<ServersViewProps, ServersViewSt
|
|||
processQuery: async (query: string) => {
|
||||
const servers = await queryDruidSql({ query });
|
||||
|
||||
const loadQueueResponse = await axios.get("/druid/coordinator/v1/loadqueue?simple");
|
||||
const loadQueueResponse = await axios.get('/druid/coordinator/v1/loadqueue?simple');
|
||||
const loadQueues = loadQueueResponse.data;
|
||||
|
||||
return servers.map((s: any) => {
|
||||
|
@ -131,7 +131,7 @@ WHERE "server_type" = 'historical'`);
|
|||
|
||||
this.middleManagerQueryManager = new QueryManager({
|
||||
processQuery: async (query: string) => {
|
||||
const resp = await axios.get("/druid/indexer/v1/workers");
|
||||
const resp = await axios.get('/druid/indexer/v1/workers');
|
||||
return resp.data;
|
||||
},
|
||||
onStateChange: ({ result, loading, error }) => {
|
||||
|
@ -172,26 +172,26 @@ WHERE "server_type" = 'historical'`);
|
|||
onFilteredChange={(filtered, column) => {
|
||||
this.setState({ serverFilter: filtered });
|
||||
}}
|
||||
pivotBy={groupByTier ? ["tier"] : []}
|
||||
pivotBy={groupByTier ? ['tier'] : []}
|
||||
columns={[
|
||||
{
|
||||
Header: "Server",
|
||||
accessor: "server",
|
||||
Header: 'Server',
|
||||
accessor: 'server',
|
||||
width: 300,
|
||||
Aggregated: row => '',
|
||||
show: serverTableColumnSelectionHandler.showColumn("Server")
|
||||
show: serverTableColumnSelectionHandler.showColumn('Server')
|
||||
},
|
||||
{
|
||||
Header: "Tier",
|
||||
accessor: "tier",
|
||||
Header: 'Tier',
|
||||
accessor: 'tier',
|
||||
Cell: row => {
|
||||
const value = row.value;
|
||||
return <a onClick={() => { this.setState({ serverFilter: addFilter(serverFilter, 'tier', value) }); }}>{value}</a>;
|
||||
},
|
||||
show: serverTableColumnSelectionHandler.showColumn("Tier")
|
||||
show: serverTableColumnSelectionHandler.showColumn('Tier')
|
||||
},
|
||||
{
|
||||
Header: "Curr size",
|
||||
Header: 'Curr size',
|
||||
id: 'curr_size',
|
||||
width: 100,
|
||||
filterable: false,
|
||||
|
@ -206,10 +206,10 @@ WHERE "server_type" = 'historical'`);
|
|||
if (row.value === null) return '';
|
||||
return formatBytes(row.value);
|
||||
},
|
||||
show: serverTableColumnSelectionHandler.showColumn("Curr size")
|
||||
show: serverTableColumnSelectionHandler.showColumn('Curr size')
|
||||
},
|
||||
{
|
||||
Header: "Max size",
|
||||
Header: 'Max size',
|
||||
id: 'max_size',
|
||||
width: 100,
|
||||
filterable: false,
|
||||
|
@ -224,10 +224,10 @@ WHERE "server_type" = 'historical'`);
|
|||
if (row.value === null) return '';
|
||||
return formatBytes(row.value);
|
||||
},
|
||||
show: serverTableColumnSelectionHandler.showColumn("Max size")
|
||||
show: serverTableColumnSelectionHandler.showColumn('Max size')
|
||||
},
|
||||
{
|
||||
Header: "Usage",
|
||||
Header: 'Usage',
|
||||
id: 'usage',
|
||||
width: 100,
|
||||
filterable: false,
|
||||
|
@ -243,10 +243,10 @@ WHERE "server_type" = 'historical'`);
|
|||
if (row.value === null) return '';
|
||||
return fillIndicator(row.value);
|
||||
},
|
||||
show: serverTableColumnSelectionHandler.showColumn("Usage")
|
||||
show: serverTableColumnSelectionHandler.showColumn('Usage')
|
||||
},
|
||||
{
|
||||
Header: "Load/drop queues",
|
||||
Header: 'Load/drop queues',
|
||||
id: 'queue',
|
||||
width: 400,
|
||||
filterable: false,
|
||||
|
@ -264,16 +264,16 @@ WHERE "server_type" = 'historical'`);
|
|||
const segmentsToDropSize = sum(originals, s => s.segmentsToDropSize);
|
||||
return formatQueues(segmentsToLoad, segmentsToLoadSize, segmentsToDrop, segmentsToDropSize);
|
||||
},
|
||||
show: serverTableColumnSelectionHandler.showColumn("Load/drop queues")
|
||||
show: serverTableColumnSelectionHandler.showColumn('Load/drop queues')
|
||||
},
|
||||
{
|
||||
Header: "Host",
|
||||
accessor: "host",
|
||||
Header: 'Host',
|
||||
accessor: 'host',
|
||||
Aggregated: () => '',
|
||||
show: serverTableColumnSelectionHandler.showColumn("Host")
|
||||
show: serverTableColumnSelectionHandler.showColumn('Host')
|
||||
},
|
||||
{
|
||||
Header: "Port",
|
||||
Header: 'Port',
|
||||
id: 'port',
|
||||
accessor: (row) => {
|
||||
const ports: string[] = [];
|
||||
|
@ -286,7 +286,7 @@ WHERE "server_type" = 'historical'`);
|
|||
return ports.join(', ') || 'No port';
|
||||
},
|
||||
Aggregated: () => '',
|
||||
show: serverTableColumnSelectionHandler.showColumn("Port")
|
||||
show: serverTableColumnSelectionHandler.showColumn('Port')
|
||||
}
|
||||
]}
|
||||
defaultPageSize={10}
|
||||
|
@ -310,47 +310,47 @@ WHERE "server_type" = 'historical'`);
|
|||
}}
|
||||
columns={[
|
||||
{
|
||||
Header: "Host",
|
||||
id: "host",
|
||||
Header: 'Host',
|
||||
id: 'host',
|
||||
accessor: (row) => row.worker.host,
|
||||
Cell: row => {
|
||||
const value = row.value;
|
||||
return <a onClick={() => { this.setState({ middleManagerFilter: addFilter(middleManagerFilter, 'host', value) }); }}>{value}</a>;
|
||||
},
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn("Host")
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn('Host')
|
||||
},
|
||||
{
|
||||
Header: "Usage",
|
||||
id: "usage",
|
||||
Header: 'Usage',
|
||||
id: 'usage',
|
||||
width: 60,
|
||||
accessor: (row) => `${row.currCapacityUsed} / ${row.worker.capacity}`,
|
||||
filterable: false,
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn("Usage")
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn('Usage')
|
||||
},
|
||||
{
|
||||
Header: "Availability groups",
|
||||
id: "availabilityGroups",
|
||||
Header: 'Availability groups',
|
||||
id: 'availabilityGroups',
|
||||
width: 60,
|
||||
accessor: (row) => row.availabilityGroups.length,
|
||||
filterable: false,
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn("Availability groups")
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn('Availability groups')
|
||||
},
|
||||
{
|
||||
Header: "Last completed task time",
|
||||
accessor: "lastCompletedTaskTime",
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn("Last completed task time")
|
||||
Header: 'Last completed task time',
|
||||
accessor: 'lastCompletedTaskTime',
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn('Last completed task time')
|
||||
},
|
||||
{
|
||||
Header: "Blacklisted until",
|
||||
accessor: "blacklistedUntil",
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn("Blacklisted until")
|
||||
Header: 'Blacklisted until',
|
||||
accessor: 'blacklistedUntil',
|
||||
show: middleManagerTableColumnSelectionHandler.showColumn('Blacklisted until')
|
||||
}
|
||||
]}
|
||||
defaultPageSize={10}
|
||||
className="-striped -highlight"
|
||||
SubComponent={rowInfo => {
|
||||
const runningTasks = rowInfo.original.runningTasks;
|
||||
return <div style={{ padding: "20px" }}>
|
||||
return <div style={{ padding: '20px' }}>
|
||||
{
|
||||
runningTasks.length ?
|
||||
<>
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as Hjson from "hjson";
|
||||
import * as Hjson from 'hjson';
|
||||
import * as React from 'react';
|
||||
import ReactTable from "react-table";
|
||||
import ReactTable from 'react-table';
|
||||
|
||||
import { SqlControl } from '../components/sql-control';
|
||||
import { QueryPlanDialog } from "../dialogs/query-plan-dialog";
|
||||
import { QueryPlanDialog } from '../dialogs/query-plan-dialog';
|
||||
import {
|
||||
BasicQueryExplanation,
|
||||
decodeRune,
|
||||
|
@ -32,7 +32,7 @@ import {
|
|||
queryDruidSql, QueryManager, SemiJoinQueryExplanation
|
||||
} from '../utils';
|
||||
|
||||
import "./sql-view.scss";
|
||||
import './sql-view.scss';
|
||||
|
||||
export interface SqlViewProps extends React.Props<any> {
|
||||
initSql: string | null;
|
||||
|
@ -77,7 +77,7 @@ export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
|
|||
} else {
|
||||
const result = await queryDruidSql({
|
||||
query,
|
||||
resultFormat: "array",
|
||||
resultFormat: 'array',
|
||||
header: true
|
||||
});
|
||||
|
||||
|
@ -101,9 +101,9 @@ export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
|
|||
const explainQuery = `explain plan for ${query}`;
|
||||
const result = await queryDruidSql({
|
||||
query: explainQuery,
|
||||
resultFormat: "object"
|
||||
resultFormat: 'object'
|
||||
});
|
||||
const data: BasicQueryExplanation | SemiJoinQueryExplanation | string = parseQueryPlan(result[0]["PLAN"]);
|
||||
const data: BasicQueryExplanation | SemiJoinQueryExplanation | string = parseQueryPlan(result[0]['PLAN']);
|
||||
return data;
|
||||
},
|
||||
onStateChange: ({ result, loading, error }) => {
|
||||
|
|
|
@ -16,17 +16,17 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Alert, Button, ButtonGroup, Intent, Label } from "@blueprintjs/core";
|
||||
import { IconNames } from "@blueprintjs/icons";
|
||||
import { Alert, Button, ButtonGroup, Intent, Label } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import axios from 'axios';
|
||||
import * as classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
import ReactTable from "react-table";
|
||||
import { Filter } from "react-table";
|
||||
import ReactTable from 'react-table';
|
||||
import { Filter } from 'react-table';
|
||||
|
||||
import { TableColumnSelection } from "../components/table-column-selection";
|
||||
import { AsyncActionDialog } from "../dialogs/async-action-dialog";
|
||||
import { SpecDialog } from "../dialogs/spec-dialog";
|
||||
import { TableColumnSelection } from '../components/table-column-selection';
|
||||
import { AsyncActionDialog } from '../dialogs/async-action-dialog';
|
||||
import { SpecDialog } from '../dialogs/spec-dialog';
|
||||
import { AppToaster } from '../singletons/toaster';
|
||||
import {
|
||||
addFilter,
|
||||
|
@ -35,12 +35,12 @@ import {
|
|||
getDruidErrorMessage, LocalStorageKeys,
|
||||
queryDruidSql,
|
||||
QueryManager, TableColumnSelectionHandler
|
||||
} from "../utils";
|
||||
} from '../utils';
|
||||
|
||||
import "./tasks-view.scss";
|
||||
import './tasks-view.scss';
|
||||
|
||||
const supervisorTableColumns: string[] = ["Datasource", "Type", "Topic/Stream", "Status", "Actions"];
|
||||
const taskTableColumns: string[] = ["Task ID", "Type", "Datasource", "Created time", "Status", "Duration", "Actions"];
|
||||
const supervisorTableColumns: string[] = ['Datasource', 'Type', 'Topic/Stream', 'Status', 'Actions'];
|
||||
const taskTableColumns: string[] = ['Task ID', 'Type', 'Datasource', 'Created time', 'Status', 'Duration', 'Actions'];
|
||||
|
||||
export interface TasksViewProps extends React.Props<any> {
|
||||
taskId: string | null;
|
||||
|
@ -126,7 +126,7 @@ export class TasksView extends React.Component<TasksViewProps, TasksViewState> {
|
|||
componentDidMount(): void {
|
||||
this.supervisorQueryManager = new QueryManager({
|
||||
processQuery: async (query: string) => {
|
||||
const resp = await axios.get("/druid/indexer/v1/supervisor?full");
|
||||
const resp = await axios.get('/druid/indexer/v1/supervisor?full');
|
||||
return resp.data;
|
||||
},
|
||||
onStateChange: ({ result, loading, error }) => {
|
||||
|
@ -328,11 +328,11 @@ ORDER BY "rank" DESC, "created_time" DESC`);
|
|||
filterable
|
||||
columns={[
|
||||
{
|
||||
Header: "Datasource",
|
||||
Header: 'Datasource',
|
||||
id: 'datasource',
|
||||
accessor: "id",
|
||||
accessor: 'id',
|
||||
width: 300,
|
||||
show: supervisorTableColumnSelectionHandler.showColumn("Datasource")
|
||||
show: supervisorTableColumnSelectionHandler.showColumn('Datasource')
|
||||
},
|
||||
{
|
||||
Header: 'Type',
|
||||
|
@ -344,7 +344,7 @@ ORDER BY "rank" DESC, "created_time" DESC`);
|
|||
if (!tuningConfig) return '';
|
||||
return tuningConfig.type;
|
||||
},
|
||||
show: supervisorTableColumnSelectionHandler.showColumn("Type")
|
||||
show: supervisorTableColumnSelectionHandler.showColumn('Type')
|
||||
},
|
||||
{
|
||||
Header: 'Topic/Stream',
|
||||
|
@ -356,10 +356,10 @@ ORDER BY "rank" DESC, "created_time" DESC`);
|
|||
if (!ioConfig) return '';
|
||||
return ioConfig.topic || ioConfig.stream || '';
|
||||
},
|
||||
show: supervisorTableColumnSelectionHandler.showColumn("Topic/Stream")
|
||||
show: supervisorTableColumnSelectionHandler.showColumn('Topic/Stream')
|
||||
},
|
||||
{
|
||||
Header: "Status",
|
||||
Header: 'Status',
|
||||
id: 'status',
|
||||
accessor: (row) => row.spec.suspended ? 'Suspended' : 'Running',
|
||||
Cell: row => {
|
||||
|
@ -373,7 +373,7 @@ ORDER BY "rank" DESC, "created_time" DESC`);
|
|||
{value}
|
||||
</span>;
|
||||
},
|
||||
show: supervisorTableColumnSelectionHandler.showColumn("Status")
|
||||
show: supervisorTableColumnSelectionHandler.showColumn('Status')
|
||||
},
|
||||
{
|
||||
Header: 'Actions',
|
||||
|
@ -397,7 +397,7 @@ ORDER BY "rank" DESC, "created_time" DESC`);
|
|||
<a onClick={() => this.setState({ terminateSupervisorId: id })}>Terminate</a>
|
||||
</div>;
|
||||
},
|
||||
show: supervisorTableColumnSelectionHandler.showColumn("Actions")
|
||||
show: supervisorTableColumnSelectionHandler.showColumn('Actions')
|
||||
}
|
||||
]}
|
||||
defaultPageSize={10}
|
||||
|
@ -452,44 +452,44 @@ ORDER BY "rank" DESC, "created_time" DESC`);
|
|||
onFilteredChange={(filtered, column) => {
|
||||
this.setState({ taskFilter: filtered });
|
||||
}}
|
||||
defaultSorted={[{id: "status", desc: true}]}
|
||||
defaultSorted={[{id: 'status', desc: true}]}
|
||||
pivotBy={groupTasksBy ? [groupTasksBy] : []}
|
||||
columns={[
|
||||
{
|
||||
Header: "Task ID",
|
||||
accessor: "task_id",
|
||||
Header: 'Task ID',
|
||||
accessor: 'task_id',
|
||||
width: 300,
|
||||
Aggregated: row => '',
|
||||
show: taskTableColumnSelectionHandler.showColumn("Task ID")
|
||||
show: taskTableColumnSelectionHandler.showColumn('Task ID')
|
||||
},
|
||||
{
|
||||
Header: "Type",
|
||||
accessor: "type",
|
||||
Header: 'Type',
|
||||
accessor: 'type',
|
||||
Cell: row => {
|
||||
const value = row.value;
|
||||
return <a onClick={() => { this.setState({ taskFilter: addFilter(taskFilter, 'type', value) }); }}>{value}</a>;
|
||||
},
|
||||
show: taskTableColumnSelectionHandler.showColumn("Type")
|
||||
show: taskTableColumnSelectionHandler.showColumn('Type')
|
||||
},
|
||||
{
|
||||
Header: "Datasource",
|
||||
accessor: "datasource",
|
||||
Header: 'Datasource',
|
||||
accessor: 'datasource',
|
||||
Cell: row => {
|
||||
const value = row.value;
|
||||
return <a onClick={() => { this.setState({ taskFilter: addFilter(taskFilter, 'datasource', value) }); }}>{value}</a>;
|
||||
},
|
||||
show: taskTableColumnSelectionHandler.showColumn("Datasource")
|
||||
show: taskTableColumnSelectionHandler.showColumn('Datasource')
|
||||
},
|
||||
{
|
||||
Header: "Created time",
|
||||
accessor: "created_time",
|
||||
Header: 'Created time',
|
||||
accessor: 'created_time',
|
||||
width: 120,
|
||||
Aggregated: row => '',
|
||||
show: taskTableColumnSelectionHandler.showColumn("Created time")
|
||||
show: taskTableColumnSelectionHandler.showColumn('Created time')
|
||||
},
|
||||
{
|
||||
Header: "Status",
|
||||
id: "status",
|
||||
Header: 'Status',
|
||||
id: 'status',
|
||||
width: 110,
|
||||
accessor: (row) => `${row.rank}_${row.created_time}_${row.status}`,
|
||||
Cell: row => {
|
||||
|
@ -519,15 +519,15 @@ ORDER BY "rank" DESC, "created_time" DESC`);
|
|||
const previewCount = countBy(previewValues);
|
||||
return <span>{Object.keys(previewCount).sort().map(v => `${v} (${previewCount[v]})`).join(', ')}</span>;
|
||||
},
|
||||
show: taskTableColumnSelectionHandler.showColumn("Status")
|
||||
show: taskTableColumnSelectionHandler.showColumn('Status')
|
||||
},
|
||||
{
|
||||
Header: "Duration",
|
||||
accessor: "duration",
|
||||
Header: 'Duration',
|
||||
accessor: 'duration',
|
||||
filterable: false,
|
||||
Cell: (row) => row.value > 0 ? formatDuration(row.value) : '',
|
||||
Aggregated: () => '',
|
||||
show: taskTableColumnSelectionHandler.showColumn("Duration")
|
||||
show: taskTableColumnSelectionHandler.showColumn('Duration')
|
||||
},
|
||||
{
|
||||
Header: 'Actions',
|
||||
|
@ -549,7 +549,7 @@ ORDER BY "rank" DESC, "created_time" DESC`);
|
|||
</div>;
|
||||
},
|
||||
Aggregated: row => '',
|
||||
show: taskTableColumnSelectionHandler.showColumn("Actions")
|
||||
show: taskTableColumnSelectionHandler.showColumn('Actions')
|
||||
}
|
||||
]}
|
||||
defaultPageSize={20}
|
||||
|
|
|
@ -1,125 +1,18 @@
|
|||
{
|
||||
"extends": [
|
||||
"tslint:recommended",
|
||||
"tslint-react"
|
||||
],
|
||||
"extends": "awesome-code-style/tslint.json",
|
||||
"rules": {
|
||||
"align": true,
|
||||
"array-type": [true, "array"],
|
||||
"arrow-parens": false,
|
||||
"ban": [false,
|
||||
["_", "extend"],
|
||||
["_", "isNull"],
|
||||
["_", "isDefined"]
|
||||
],
|
||||
"comment-format": [false,
|
||||
"check-space"
|
||||
],
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"file-header": [true, "Licensed to the Apache Software Foundation \\(ASF\\).+"],
|
||||
"forin": false,
|
||||
"indent": [true, "spaces", 2],
|
||||
"interface-name": [true, "never-prefix"],
|
||||
"jsdoc-format": true,
|
||||
"label-position": true,
|
||||
"max-line-length": [true, 200],
|
||||
"max-classes-per-file": false,
|
||||
"member-access": false,
|
||||
"member-ordering": [true,
|
||||
{
|
||||
"order": [
|
||||
"static-field",
|
||||
"static-method",
|
||||
"instance-field",
|
||||
"constructor",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-any": false,
|
||||
"no-arg": true,
|
||||
"no-console": [true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-empty": [true, "allow-empty-catch"],
|
||||
"no-empty-interface": false,
|
||||
"no-eval": true,
|
||||
"no-inferrable-types": true,
|
||||
"no-null-keyword": false,
|
||||
"no-parameter-properties": true,
|
||||
"no-require-imports": false,
|
||||
"no-shadowed-variable": false,
|
||||
"no-string-literal": false,
|
||||
"no-switch-case-fall-through": false,
|
||||
"no-trailing-whitespace": true,
|
||||
"no-unused-expression": false,
|
||||
"no-use-before-declare": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"one-line": [true,
|
||||
"check-catch",
|
||||
"check-else",
|
||||
"check-finally",
|
||||
"check-open-brace",
|
||||
"check-whitespace"
|
||||
],
|
||||
"ordered-imports": [
|
||||
true,
|
||||
{
|
||||
"import-sources-order": "case-insensitive",
|
||||
"grouped-imports": true,
|
||||
"groups": [
|
||||
{ "name": "parent directories", "match": "^\\.\\.", "order": 20 },
|
||||
{ "name": "styles", "match": ".scss$", "order": 40 },
|
||||
{ "name": "current directory", "match": "^\\.", "order": 30 },
|
||||
{ "name": "libraries", "match": ".*", "order": 10 }
|
||||
]
|
||||
}
|
||||
],
|
||||
"prefer-const": [true, {"destructuring": "all"}],
|
||||
"quotemark": [false, "double", "jsx-double", "avoid-escape"],
|
||||
"semicolon": true,
|
||||
"switch-default": false,
|
||||
"trailing-comma": [true, {
|
||||
"singleline": "never",
|
||||
"multiline": "never"
|
||||
}],
|
||||
"triple-equals": [true, "allow-null-check"],
|
||||
"typedef": false,
|
||||
"typedef-whitespace": [true, {
|
||||
"call-signature": "nospace",
|
||||
"index-signature": "nospace",
|
||||
"parameter": "nospace",
|
||||
"property-declaration": "nospace",
|
||||
"variable-declaration": "nospace"
|
||||
}, {
|
||||
"call-signature": "onespace",
|
||||
"index-signature": "onespace",
|
||||
"parameter": "onespace",
|
||||
"property-declaration": "onespace",
|
||||
"variable-declaration": "onespace"
|
||||
}],
|
||||
"variable-name": false,
|
||||
"whitespace": [true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-module",
|
||||
"check-separator",
|
||||
"check-type",
|
||||
"check-type-operator"
|
||||
],
|
||||
"jsx-alignment": true,
|
||||
"jsx-boolean-value": [true, "never"],
|
||||
"jsx-curly-spacing": [true, "never"],
|
||||
"jsx-no-lambda": false,
|
||||
"jsx-no-multiline-js": false,
|
||||
"jsx-no-string-ref": true,
|
||||
"jsx-self-close": true,
|
||||
"jsx-space-before-trailing-slash": false,
|
||||
"jsx-wrap-multiline": false
|
||||
"no-conditional-assignment": true,
|
||||
"no-string-literal": false,
|
||||
"object-literal-shorthand": false,
|
||||
"no-require-imports": false,
|
||||
"arrow-return-shorthand": false,
|
||||
"no-var-requires": false,
|
||||
"no-unused-variable": false
|
||||
},
|
||||
"linterOptions": {
|
||||
"format": "useful"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue