mirror of https://github.com/apache/druid.git
Web-console: fix alerts from lgtm (#8346)
* fix alerts from lgtm * remove unordered imports * fix introduced alert * move getExpanded to renderSchemaSelector * use getDerivedStateFromProps * use prevState * add semi colons, remove unused imports * fixes
This commit is contained in:
parent
c87b68d2a4
commit
e4aa7fb268
|
@ -27,8 +27,8 @@ This is the unified Druid web console that servers as a data management layer fo
|
|||
2. Install the modules with `npm install`
|
||||
3. Run `npm start` will start in development mode and will proxy druid requests to `localhost:8888`
|
||||
|
||||
**Note:** you can provide an environment variable to proxy to a different Druid host like so: `druid_host=1.2.3.4:8888 npm start`
|
||||
|
||||
**Note:** you can provide an environment variable to proxy to a different Druid host like so: `druid_host=1.2.3.4:8888 npm start`
|
||||
**Note:** you can provide an environment variable use webpack-bundle-analyzer as a plugin in the build script or like so: `BUNDLE_ANALYZER_PLUGIN='TRUE' npm start`
|
||||
|
||||
## Description of the directory structure
|
||||
|
||||
|
@ -50,7 +50,6 @@ Generated/copied dynamically
|
|||
- `pages/` - The files for the older coordinator console
|
||||
- `coordinator-console/` - Files for the coordinator console
|
||||
|
||||
|
||||
## List of non SQL data reading APIs used
|
||||
|
||||
```
|
||||
|
|
|
@ -29,6 +29,7 @@ PATH="./target/node:$PATH" ./script/create-sql-function-doc.js
|
|||
echo "Transpiling ReactTable CSS..."
|
||||
PATH="./target/node:$PATH" ./node_modules/.bin/stylus lib/react-table.styl -o lib/react-table.css
|
||||
|
||||
# add BUNDLE_ANALYZER_PLUGIN='TRUE' here to enable webpack-bundle-analyzer as a plugin
|
||||
echo "Webpacking everything..."
|
||||
PATH="./target/node:$PATH" NODE_ENV=production ./node_modules/.bin/webpack -c webpack.config.js
|
||||
|
||||
|
|
|
@ -60,116 +60,119 @@ function injectConsoleLicenses(consoleLicenses) {
|
|||
// Write out the new file
|
||||
fs.writeFileSync(
|
||||
LICENSES_FILE,
|
||||
[
|
||||
beforeLines.join('\n'),
|
||||
consoleLicenses.join(SEPARATOR),
|
||||
afterLines.join('\n')
|
||||
].join('\n')
|
||||
[beforeLines.join('\n'), consoleLicenses.join(SEPARATOR), afterLines.join('\n')].join('\n'),
|
||||
);
|
||||
}
|
||||
|
||||
checker.init({
|
||||
start: '.',
|
||||
production: true
|
||||
}, function(err, packages) {
|
||||
if (err) {
|
||||
console.log('err', err);
|
||||
return;
|
||||
}
|
||||
|
||||
const mapped = Object.keys(packages).sort().map(p => {
|
||||
const m = p.match(/^(.+)@(\d+\.\d+\.\d+.*)$/);
|
||||
if (!m) throw new Error(`Malformed name@version`);
|
||||
const name = m[1];
|
||||
if (name === 'web-console') return null; // This is me!
|
||||
|
||||
const version = m[2];
|
||||
const meta = packages[p];
|
||||
let { publisher, licenses, licenseFile } = meta;
|
||||
if (!licenses) throw new Error(`Package '${p} does not have a licenses`);
|
||||
|
||||
let properLicenseName; // Map the licenses to their proper name
|
||||
let licenseExt; // Map the licenses to the right extension
|
||||
switch (licenses) {
|
||||
case 'MIT':
|
||||
properLicenseName = 'MIT License';
|
||||
licenseExt = 'MIT';
|
||||
break;
|
||||
|
||||
case 'Apache-2.0':
|
||||
properLicenseName = 'Apache License version 2.0';
|
||||
licenseExt = 'A2';
|
||||
break;
|
||||
|
||||
case 'BSD-3-Clause':
|
||||
properLicenseName = 'BSD-3-Clause License';
|
||||
licenseExt = 'BSD3';
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown license '${licenses}' in ${p}`);
|
||||
checker.init(
|
||||
{
|
||||
start: '.',
|
||||
production: true,
|
||||
},
|
||||
function(err, packages) {
|
||||
if (err) {
|
||||
console.log('err', err);
|
||||
return;
|
||||
}
|
||||
|
||||
const simpleName = name.replace('/', '-');
|
||||
const licenseDest = `licenses/bin/${simpleName}.${licenseExt}`
|
||||
const mapped = Object.keys(packages)
|
||||
.sort()
|
||||
.map(p => {
|
||||
const m = p.match(/^(.+)@(\d+\.\d+\.\d+.*)$/);
|
||||
if (!m) throw new Error(`Malformed name@version`);
|
||||
const name = m[1];
|
||||
if (name === 'web-console') return null; // This is me!
|
||||
|
||||
let hasLicense = false;
|
||||
if (licenseExt !== 'A2') {
|
||||
if (licenseFile && licenseFile.match(/\/license(?:\.\w+)?/i)) {
|
||||
// If the file ends with license.ext? then copy it over
|
||||
try {
|
||||
fs.copyFileSync(licenseFile, `../${licenseDest}`);
|
||||
hasLicense = true;
|
||||
} catch (e) {
|
||||
console.log(`Could not copy license for '${p}': ${JSON.stringify(meta)}`);
|
||||
const version = m[2];
|
||||
const meta = packages[p];
|
||||
let { publisher, licenses, licenseFile } = meta;
|
||||
if (!licenses) throw new Error(`Package '${p} does not have a licenses`);
|
||||
|
||||
let properLicenseName; // Map the licenses to their proper name
|
||||
let licenseExt; // Map the licenses to the right extension
|
||||
switch (licenses) {
|
||||
case 'MIT':
|
||||
properLicenseName = 'MIT License';
|
||||
licenseExt = 'MIT';
|
||||
break;
|
||||
|
||||
case 'Apache-2.0':
|
||||
properLicenseName = 'Apache License version 2.0';
|
||||
licenseExt = 'A2';
|
||||
break;
|
||||
|
||||
case 'BSD-3-Clause':
|
||||
properLicenseName = 'BSD-3-Clause License';
|
||||
licenseExt = 'BSD3';
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown license '${licenses}' in ${p}`);
|
||||
}
|
||||
} else {
|
||||
// See if the license is already there (manually) keep it
|
||||
try {
|
||||
fs.statSync(`../${licenseDest}`);
|
||||
hasLicense = true;
|
||||
} catch (e) {
|
||||
console.log(`Could not find license for '${p}': ${JSON.stringify(meta)}`);
|
||||
|
||||
const simpleName = name.replace('/', '-');
|
||||
const licenseDest = `licenses/bin/${simpleName}.${licenseExt}`;
|
||||
|
||||
let hasLicense = false;
|
||||
if (licenseExt !== 'A2') {
|
||||
if (licenseFile && licenseFile.match(/\/license(?:\.\w+)?/i)) {
|
||||
// If the file ends with license.ext? then copy it over
|
||||
try {
|
||||
fs.copyFileSync(licenseFile, `../${licenseDest}`);
|
||||
hasLicense = true;
|
||||
} catch (e) {
|
||||
console.log(`Could not copy license for '${p}': ${JSON.stringify(meta)}`);
|
||||
}
|
||||
} else {
|
||||
// See if the license is already there (manually) keep it
|
||||
try {
|
||||
fs.statSync(`../${licenseDest}`);
|
||||
hasLicense = true;
|
||||
} catch (e) {
|
||||
console.log(`Could not find license for '${p}': ${JSON.stringify(meta)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!publisher && hasLicense) {
|
||||
// Extract copyright from license
|
||||
const licenseText = fs.readFileSync(`../${licenseDest}`, 'utf-8');
|
||||
const m = licenseText.match(/(?:^|\n)\s*Copyright(?: (?:\(c\)|©))?(?: 2[0-9]{3}(?:-\w+)?,?)? ([^0-9][^\n]*)\n/m);
|
||||
if (m) {
|
||||
publisher = m[1]
|
||||
.replace(/All rights reserved./i, '')
|
||||
.replace(/[0-9-]{4,9}/, '')
|
||||
.trim();
|
||||
}
|
||||
}
|
||||
if (!publisher && hasLicense) {
|
||||
// Extract copyright from license
|
||||
const licenseText = fs.readFileSync(`../${licenseDest}`, 'utf-8');
|
||||
const m = licenseText.match(
|
||||
/(?:^|\n)\s*Copyright(?: (?:\(c\)|©))?(?: 2[0-9]{3}(?:-\w+)?,?)? ([^0-9][^\n]*)\n/m,
|
||||
);
|
||||
if (m) {
|
||||
publisher = m[1]
|
||||
.replace(/All rights reserved./i, '')
|
||||
.replace(/[0-9-]{4,9}/, '')
|
||||
.trim();
|
||||
}
|
||||
}
|
||||
|
||||
if (!publisher) {
|
||||
// Hand coded copyrights
|
||||
if (name === 'asap') publisher = 'Contributors'
|
||||
if (name === 'diff-match-patch') publisher = 'Google'
|
||||
}
|
||||
if (!publisher) {
|
||||
// Hand coded copyrights
|
||||
if (name === 'asap') publisher = 'Contributors';
|
||||
if (name === 'diff-match-patch') publisher = 'Google';
|
||||
}
|
||||
|
||||
if (!publisher) {
|
||||
console.log(`No license for '${name}' ('${licenseDest}')`);
|
||||
}
|
||||
if (!publisher) {
|
||||
console.log(`No license for '${name}' ('${licenseDest}')`);
|
||||
}
|
||||
|
||||
// Make our blob
|
||||
const lines = [
|
||||
`name: "${name}"`,
|
||||
`license_category: binary`,
|
||||
`module: web-console`,
|
||||
`license_name: ${properLicenseName}`,
|
||||
publisher ? `copyright: ${publisher}` : null,
|
||||
`version: ${version}`,
|
||||
hasLicense ? `license_file_path: ${licenseDest}` : null,
|
||||
];
|
||||
// Make our blob
|
||||
const lines = [
|
||||
`name: "${name}"`,
|
||||
`license_category: binary`,
|
||||
`module: web-console`,
|
||||
`license_name: ${properLicenseName}`,
|
||||
publisher ? `copyright: ${publisher}` : null,
|
||||
`version: ${version}`,
|
||||
hasLicense ? `license_file_path: ${licenseDest}` : null,
|
||||
];
|
||||
|
||||
return lines.filter(Boolean).join('\n');
|
||||
}).filter(Boolean);
|
||||
|
||||
injectConsoleLicenses(mapped);
|
||||
});
|
||||
return lines.filter(Boolean).join('\n');
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
injectConsoleLicenses(mapped);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -105,7 +105,7 @@ export class DatasourceColumnsTable extends React.PureComponent<
|
|||
return (
|
||||
<div className="datasource-columns-table">
|
||||
<div className="main-area">
|
||||
{loading ? <Loader loadingText="" loading /> : !loading && this.renderTable()}
|
||||
{loading ? <Loader loadingText="" loading /> : this.renderTable()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
exports[`external link matches snapshot 1`] = `
|
||||
<a
|
||||
href="http://test/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<div>
|
||||
|
|
|
@ -27,7 +27,7 @@ export class ExternalLink extends React.PureComponent<ExternalLinkProps> {
|
|||
const { href, children } = this.props;
|
||||
|
||||
return (
|
||||
<a href={href} target="_blank">
|
||||
<a href={href} target="_blank" rel="noopener noreferrer">
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
|
|
|
@ -71,7 +71,7 @@ export class ShowHistory extends React.PureComponent<ShowHistoryProps, ShowHisto
|
|||
|
||||
render(): JSX.Element | null {
|
||||
const { downloadFilename, endpoint } = this.props;
|
||||
const { data, loading } = this.state;
|
||||
const { data, loading, error } = this.state;
|
||||
if (loading) return <Loader />;
|
||||
if (!data) return null;
|
||||
|
||||
|
@ -82,7 +82,9 @@ export class ShowHistory extends React.PureComponent<ShowHistoryProps, ShowHisto
|
|||
title={pastSupervisor.version}
|
||||
panel={
|
||||
<ShowValue
|
||||
jsonValue={JSON.stringify(pastSupervisor.spec, undefined, 2)}
|
||||
jsonValue={
|
||||
pastSupervisor.spec ? JSON.stringify(pastSupervisor.spec, undefined, 2) : error
|
||||
}
|
||||
downloadFilename={`version-${pastSupervisor.version}-${downloadFilename}`}
|
||||
endpoint={endpoint}
|
||||
/>
|
||||
|
|
|
@ -60,10 +60,39 @@ exports[`show log describe show log 1`] = `
|
|||
<div
|
||||
class="main-area"
|
||||
>
|
||||
<textarea
|
||||
class="bp3-input"
|
||||
readonly=""
|
||||
/>
|
||||
<div
|
||||
class="loader"
|
||||
>
|
||||
<div
|
||||
class="loader-logo"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 100 100"
|
||||
>
|
||||
<path
|
||||
class="one"
|
||||
d="M54.2,69.8h-2.7c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h2.7c11.5,0,23.8-7.4,23.8-23.7
|
||||
c0-9.1-6.9-15.8-16.4-15.8H38c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h23.6c5.3,0,10.1,1.9,13.6,5.3c3.5,3.4,5.4,8,5.4,13.1
|
||||
c0,6.6-2.3,13-6.3,17.7C69.5,66.8,62.5,69.8,54.2,69.8z"
|
||||
/>
|
||||
<path
|
||||
class="two"
|
||||
d="M55.7,59.5h-26c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h26c7.5,0,11.5-5.8,11.5-11.5
|
||||
c0-4.2-3.2-7.3-7.7-7.3h-26c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h26c5.9,0,10.3,4.3,10.3,9.9c0,3.7-1.3,7.2-3.7,9.8
|
||||
C63.5,58,59.9,59.5,55.7,59.5z"
|
||||
/>
|
||||
<path
|
||||
class="three"
|
||||
d="M27.2,38h-6.3c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h6.3c0.7,0,1.3,0.6,1.3,1.3S27.9,38,27.2,38z"
|
||||
/>
|
||||
<path
|
||||
class="four"
|
||||
d="M45.1,69.8h-5.8c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h5.8c0.7,0,1.3,0.6,1.3,1.3
|
||||
C46.4,69.2,45.8,69.8,45.1,69.8z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
|
|
@ -21,6 +21,7 @@ import axios from 'axios';
|
|||
import copy from 'copy-to-clipboard';
|
||||
import React from 'react';
|
||||
|
||||
import { Loader } from '../../components';
|
||||
import { AppToaster } from '../../singletons/toaster';
|
||||
import { UrlBaser } from '../../singletons/url-baser';
|
||||
import { QueryManager } from '../../utils';
|
||||
|
@ -109,7 +110,7 @@ export class ShowLog extends React.PureComponent<ShowLogProps, ShowLogState> {
|
|||
|
||||
render(): JSX.Element {
|
||||
const { endpoint, downloadFilename, status } = this.props;
|
||||
const { logValue, error } = this.state;
|
||||
const { logValue, error, loading } = this.state;
|
||||
|
||||
return (
|
||||
<div className="show-log">
|
||||
|
@ -144,12 +145,16 @@ export class ShowLog extends React.PureComponent<ShowLogProps, ShowLogState> {
|
|||
</ButtonGroup>
|
||||
</div>
|
||||
<div className="main-area">
|
||||
<textarea
|
||||
className="bp3-input"
|
||||
readOnly
|
||||
value={logValue ? logValue : error}
|
||||
ref={this.log}
|
||||
/>
|
||||
{loading ? (
|
||||
<Loader loadingText="" loading />
|
||||
) : (
|
||||
<textarea
|
||||
className="bp3-input"
|
||||
readOnly
|
||||
value={logValue ? logValue : error}
|
||||
ref={this.log}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -170,7 +170,7 @@ export class SupervisorStatisticsTable extends React.PureComponent<
|
|||
</ButtonGroup>
|
||||
</div>
|
||||
<div className="main-area">
|
||||
{loading ? <Loader loadingText="" loading /> : !loading && this.renderTable(error)}
|
||||
{loading ? <Loader loadingText="" loading /> : this.renderTable(error)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -48,7 +48,6 @@ export interface ConsoleApplicationProps {
|
|||
}
|
||||
|
||||
export interface ConsoleApplicationState {
|
||||
aboutDialogOpen: boolean;
|
||||
noSqlMode: boolean;
|
||||
capabilitiesLoading: boolean;
|
||||
}
|
||||
|
@ -124,7 +123,6 @@ export class ConsoleApplication extends React.PureComponent<
|
|||
constructor(props: ConsoleApplicationProps, context: any) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
aboutDialogOpen: false,
|
||||
noSqlMode: false,
|
||||
capabilitiesLoading: true,
|
||||
};
|
||||
|
|
|
@ -84,6 +84,7 @@ exports[`about dialog matches snapshot 1`] = `
|
|||
|
||||
<a
|
||||
href="https://druid.apache.org/community/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
community page
|
||||
|
@ -92,6 +93,7 @@ exports[`about dialog matches snapshot 1`] = `
|
|||
|
||||
<a
|
||||
href="https://groups.google.com/forum/#!forum/druid-user"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
user groups
|
||||
|
@ -103,6 +105,7 @@ exports[`about dialog matches snapshot 1`] = `
|
|||
|
||||
<a
|
||||
href="https://lists.apache.org/list.html?dev@druid.apache.org"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
developer group
|
||||
|
|
|
@ -60,6 +60,7 @@ exports[`coordinator dynamic config matches snapshot 1`] = `
|
|||
|
||||
<a
|
||||
href="https://druid.apache.org/docs/latest/configuration/index.html#dynamic-configuration"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
documentation
|
||||
|
|
|
@ -20,9 +20,7 @@ import { IDialogProps } from '@blueprintjs/core';
|
|||
import React from 'react';
|
||||
|
||||
import { DatasourceColumnsTable } from '../../components/datasource-columns-table/datasource-columns-table';
|
||||
import { queryDruidSql, QueryManager } from '../../utils';
|
||||
import { BasicAction } from '../../utils/basic-action';
|
||||
import { ColumnMetadata } from '../../utils/column-metadata';
|
||||
import { SideButtonMetaData, TableActionDialog } from '../table-action-dialog/table-action-dialog';
|
||||
|
||||
interface DatasourceTableActionDialogProps extends IDialogProps {
|
||||
|
@ -33,40 +31,17 @@ interface DatasourceTableActionDialogProps extends IDialogProps {
|
|||
|
||||
interface DatasourceTableActionDialogState {
|
||||
activeTab: 'columns';
|
||||
dimensions?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export class DatasourceTableActionDialog extends React.PureComponent<
|
||||
DatasourceTableActionDialogProps,
|
||||
DatasourceTableActionDialogState
|
||||
> {
|
||||
private dimensionsQueryManager: QueryManager<null, string>;
|
||||
constructor(props: DatasourceTableActionDialogProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
activeTab: 'columns',
|
||||
};
|
||||
|
||||
/// This should be a table
|
||||
this.dimensionsQueryManager = new QueryManager({
|
||||
processQuery: async () => {
|
||||
const { datasourceId } = this.props;
|
||||
const resp = await queryDruidSql<ColumnMetadata>({
|
||||
query: `SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'druid' AND TABLE_NAME = '${datasourceId}'`,
|
||||
});
|
||||
const dimensionArray = resp.map(object => object.COLUMN_NAME);
|
||||
return JSON.stringify(dimensionArray, undefined, 2);
|
||||
},
|
||||
onStateChange: ({ result, error }) => {
|
||||
this.setState({ dimensions: result, error });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.dimensionsQueryManager.runQuery(null);
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
|
|
|
@ -60,6 +60,7 @@ exports[`overload dynamic config matches snapshot 1`] = `
|
|||
|
||||
<a
|
||||
href="https://druid.apache.org/docs/latest/configuration/index.html#overlord-dynamic-configuration"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
documentation
|
||||
|
|
|
@ -306,13 +306,13 @@ GROUP BY 1`;
|
|||
this.datasourceQueryManager.rerunLastQuery(auto);
|
||||
// this looks ugly, but it forces the chart to re-render when refresh is clicked
|
||||
this.setState(
|
||||
{
|
||||
showChart: !this.state.showChart,
|
||||
},
|
||||
prevState => ({
|
||||
showChart: !prevState.showChart,
|
||||
}),
|
||||
() =>
|
||||
this.setState({
|
||||
showChart: !this.state.showChart,
|
||||
}),
|
||||
this.setState(prevState => ({
|
||||
showChart: !prevState.showChart,
|
||||
})),
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -989,7 +989,11 @@ GROUP BY 1`;
|
|||
/>
|
||||
<TableColumnSelector
|
||||
columns={noSqlMode ? tableColumnsNoSql : tableColumns}
|
||||
onChange={column => this.setState({ hiddenColumns: hiddenColumns.toggle(column) })}
|
||||
onChange={column =>
|
||||
this.setState(prevState => ({
|
||||
hiddenColumns: prevState.hiddenColumns.toggle(column),
|
||||
}))
|
||||
}
|
||||
tableColumnsHidden={hiddenColumns.storedArray}
|
||||
/>
|
||||
</ViewControlBar>
|
||||
|
|
|
@ -266,7 +266,6 @@ export interface LoadDataViewState {
|
|||
parserQueryState: QueryState<HeaderAndRows>;
|
||||
|
||||
// for flatten
|
||||
flattenQueryState: QueryState<HeaderAndRows>;
|
||||
selectedFlattenFieldIndex: number;
|
||||
selectedFlattenField?: FlattenField;
|
||||
|
||||
|
@ -328,7 +327,6 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
|
|||
parserQueryState: QueryState.INIT,
|
||||
|
||||
// for flatten
|
||||
flattenQueryState: QueryState.INIT,
|
||||
selectedFlattenFieldIndex: -1,
|
||||
|
||||
// for timestamp
|
||||
|
|
|
@ -138,21 +138,21 @@ export class LookupsView extends React.PureComponent<LookupsViewProps, LookupsVi
|
|||
}
|
||||
|
||||
private async openLookupEditDialog(tier: string, id: string) {
|
||||
const { lookups, allLookupTiers } = this.state;
|
||||
const { lookups } = this.state;
|
||||
if (!lookups) return;
|
||||
|
||||
const target: any = lookups.find((lookupEntry: any) => {
|
||||
return lookupEntry.tier === tier && lookupEntry.id === id;
|
||||
});
|
||||
if (id === '') {
|
||||
this.setState({
|
||||
this.setState(prevState => ({
|
||||
lookupEditName: '',
|
||||
lookupEditTier: allLookupTiers[0],
|
||||
lookupEditTier: prevState.allLookupTiers[0],
|
||||
lookupEditDialogOpen: true,
|
||||
lookupEditSpec: '',
|
||||
lookupEditVersion: new Date().toISOString(),
|
||||
isEdit: false,
|
||||
});
|
||||
}));
|
||||
} else {
|
||||
this.setState({
|
||||
lookupEditName: id,
|
||||
|
|
|
@ -143,8 +143,8 @@ export interface ColumnTreeProps {
|
|||
|
||||
export interface ColumnTreeState {
|
||||
prevColumnMetadata?: readonly ColumnMetadata[];
|
||||
prevGroupByStatus?: boolean;
|
||||
columnTree?: ITreeNode[];
|
||||
currentSchemaSubtree?: ITreeNode[];
|
||||
selectedTreeIndex: number;
|
||||
expandedNode: number;
|
||||
}
|
||||
|
@ -317,12 +317,21 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
|
|||
}
|
||||
}
|
||||
|
||||
if (!columnTree) return null;
|
||||
const currentSchemaSubtree =
|
||||
columnTree[selectedTreeIndex > -1 ? selectedTreeIndex : 0].childNodes;
|
||||
if (!currentSchemaSubtree) return null;
|
||||
|
||||
if (expandedNode > -1) {
|
||||
currentSchemaSubtree[expandedNode].isExpanded = true;
|
||||
}
|
||||
|
||||
return {
|
||||
prevColumnMetadata: columnMetadata,
|
||||
columnTree,
|
||||
selectedTreeIndex,
|
||||
expandedNode,
|
||||
prevGroupByStatus: props.hasGroupBy,
|
||||
currentSchemaSubtree,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
|
@ -377,6 +386,8 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
|
|||
|
||||
render(): JSX.Element | null {
|
||||
const { columnMetadataLoading } = this.props;
|
||||
const { currentSchemaSubtree } = this.state;
|
||||
|
||||
if (columnMetadataLoading) {
|
||||
return (
|
||||
<div className="column-tree">
|
||||
|
@ -385,15 +396,8 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
|
|||
);
|
||||
}
|
||||
|
||||
const { columnTree, selectedTreeIndex, expandedNode } = this.state;
|
||||
if (!columnTree) return null;
|
||||
const currentSchemaSubtree =
|
||||
columnTree[selectedTreeIndex > -1 ? selectedTreeIndex : 0].childNodes;
|
||||
if (!currentSchemaSubtree) return null;
|
||||
|
||||
if (expandedNode > -1) {
|
||||
currentSchemaSubtree[expandedNode].isExpanded = true;
|
||||
}
|
||||
return (
|
||||
<div className="column-tree">
|
||||
{this.renderSchemaSelector()}
|
||||
|
@ -423,6 +427,8 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
|
|||
bounceState() {
|
||||
const { columnTree } = this.state;
|
||||
if (!columnTree) return;
|
||||
this.setState({ columnTree: columnTree.slice() });
|
||||
this.setState(prevState => ({
|
||||
columnTree: prevState.columnTree ? prevState.columnTree.slice() : undefined,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -617,10 +617,8 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
if (!queryAst) return;
|
||||
|
||||
let modifiedAst: SqlQuery = queryAst;
|
||||
if (queryAst) {
|
||||
for (const filter of filters) {
|
||||
modifiedAst = modifiedAst.filterRow(filter.header, filter.row, filter.operator);
|
||||
}
|
||||
for (const filter of filters) {
|
||||
modifiedAst = modifiedAst.filterRow(filter.header, filter.row, filter.operator);
|
||||
}
|
||||
this.handleQueryStringChange(modifiedAst.toString(), preferablyRun);
|
||||
};
|
||||
|
|
|
@ -61,9 +61,6 @@ export interface RunButtonProps {
|
|||
export class RunButton extends React.PureComponent<RunButtonProps> {
|
||||
constructor(props: RunButtonProps, context: any) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
wrapQuery: true,
|
||||
};
|
||||
}
|
||||
|
||||
public renderHotkeys() {
|
||||
|
|
|
@ -97,7 +97,6 @@ export interface SegmentsViewState {
|
|||
terminateSegmentId?: string;
|
||||
terminateDatasourceId?: string;
|
||||
hiddenColumns: LocalStorageBackedArray<string>;
|
||||
loaded: boolean;
|
||||
groupByInterval: boolean;
|
||||
|
||||
// table state
|
||||
|
@ -157,7 +156,6 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
|
|||
hiddenColumns: new LocalStorageBackedArray<string>(
|
||||
LocalStorageKeys.SEGMENT_TABLE_COLUMN_SELECTION,
|
||||
),
|
||||
loaded: false,
|
||||
groupByInterval: false,
|
||||
|
||||
// Table state
|
||||
|
@ -696,7 +694,11 @@ export class SegmentsView extends React.PureComponent<SegmentsViewProps, Segment
|
|||
{this.renderBulkSegmentsActions()}
|
||||
<TableColumnSelector
|
||||
columns={noSqlMode ? tableColumnsNoSql : tableColumns}
|
||||
onChange={column => this.setState({ hiddenColumns: hiddenColumns.toggle(column) })}
|
||||
onChange={column =>
|
||||
this.setState(prevState => ({
|
||||
hiddenColumns: prevState.hiddenColumns.toggle(column),
|
||||
}))
|
||||
}
|
||||
tableColumnsHidden={hiddenColumns.storedArray}
|
||||
/>
|
||||
</ViewControlBar>
|
||||
|
|
|
@ -677,7 +677,11 @@ ORDER BY "rank" DESC, "server" DESC`;
|
|||
{this.renderBulkServersActions()}
|
||||
<TableColumnSelector
|
||||
columns={serverTableColumns}
|
||||
onChange={column => this.setState({ hiddenColumns: hiddenColumns.toggle(column) })}
|
||||
onChange={column =>
|
||||
this.setState(prevState => ({
|
||||
hiddenColumns: prevState.hiddenColumns.toggle(column),
|
||||
}))
|
||||
}
|
||||
tableColumnsHidden={hiddenColumns.storedArray}
|
||||
/>
|
||||
</ViewControlBar>
|
||||
|
|
|
@ -1106,7 +1106,9 @@ ORDER BY "rank" DESC, "created_time" DESC`;
|
|||
<TableColumnSelector
|
||||
columns={supervisorTableColumns}
|
||||
onChange={column =>
|
||||
this.setState({ hiddenSupervisorColumns: hiddenSupervisorColumns.toggle(column) })
|
||||
this.setState(prevState => ({
|
||||
hiddenSupervisorColumns: prevState.hiddenSupervisorColumns.toggle(column),
|
||||
}))
|
||||
}
|
||||
tableColumnsHidden={hiddenSupervisorColumns.storedArray}
|
||||
/>
|
||||
|
@ -1153,7 +1155,9 @@ ORDER BY "rank" DESC, "created_time" DESC`;
|
|||
<TableColumnSelector
|
||||
columns={taskTableColumns}
|
||||
onChange={column =>
|
||||
this.setState({ hiddenTaskColumns: hiddenTaskColumns.toggle(column) })
|
||||
this.setState(prevState => ({
|
||||
hiddenTaskColumns: prevState.hiddenTaskColumns.toggle(column),
|
||||
}))
|
||||
}
|
||||
tableColumnsHidden={hiddenTaskColumns.storedArray}
|
||||
/>
|
||||
|
|
|
@ -57,21 +57,16 @@ export interface HoveredBarInfo {
|
|||
}
|
||||
|
||||
export class StackedBarChart extends React.Component<StackedBarChartProps, StackedBarChartState> {
|
||||
constructor(props: StackedBarChartProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
width: this.props.svgWidth - this.props.margin.left - this.props.margin.right,
|
||||
height: this.props.svgHeight - this.props.margin.bottom - this.props.margin.top,
|
||||
static getDerivedStateFromProps(props: StackedBarChartProps) {
|
||||
const width = props.svgWidth - props.margin.left - props.margin.right;
|
||||
const height = props.svgHeight - props.margin.bottom - props.margin.top;
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: StackedBarChartProps): void {
|
||||
if (nextProps !== this.props) {
|
||||
this.setState({
|
||||
width: nextProps.svgWidth - this.props.margin.left - this.props.margin.right,
|
||||
height: nextProps.svgHeight - this.props.margin.bottom - this.props.margin.top,
|
||||
});
|
||||
}
|
||||
constructor(props: StackedBarChartProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
renderBarChart() {
|
||||
|
|
|
@ -97,10 +97,10 @@ module.exports = env => {
|
|||
],
|
||||
},
|
||||
{
|
||||
test: (ALWAYS_BABEL || mode === 'production') ? /\.m?js$/ : /^xxx$/,
|
||||
test: ALWAYS_BABEL || mode === 'production' ? /\.m?js$/ : /^xxx$/,
|
||||
use: {
|
||||
loader: 'babel-loader'
|
||||
}
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.s?css$/,
|
||||
|
@ -124,10 +124,8 @@ module.exports = env => {
|
|||
],
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
hints: false,
|
||||
},
|
||||
plugins: [
|
||||
// new BundleAnalyzerPlugin()
|
||||
],
|
||||
plugins: process.env.BUNDLE_ANALYZER_PLUGIN === 'TRUE' ? [new BundleAnalyzerPlugin()] : [],
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue