Web-Console: Column tree button fixes (#8253)

* small fixes

* run jest -u

* add trim

* remove trim, update package

* fix package-lock
This commit is contained in:
mcbrewster 2019-08-07 16:48:17 -07:00 committed by Clint Wylie
parent 8fa114c349
commit 03a37936ec
7 changed files with 85 additions and 129 deletions

View File

@ -4395,9 +4395,9 @@
"integrity": "sha512-0sYnfUHHMoajaud/i5BHKA12bUxiWEHJ9rxGqVEppFxsEcxef0TZQ5J59lU+UniEBcz/sG5fTESRyS7cOm3tSQ==" "integrity": "sha512-0sYnfUHHMoajaud/i5BHKA12bUxiWEHJ9rxGqVEppFxsEcxef0TZQ5J59lU+UniEBcz/sG5fTESRyS7cOm3tSQ=="
}, },
"druid-query-toolkit": { "druid-query-toolkit": {
"version": "0.3.12", "version": "0.3.13",
"resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.3.12.tgz", "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.3.13.tgz",
"integrity": "sha512-q2w6dDdZFYuLRTVyUvZwyXx/63ZQivjhll3Ppo3zpRcF4iWg+z+sXY9UI+sobl5q3/WojOkw/ZI0Kwzy9bWd2Q==", "integrity": "sha512-yBPAJ0tjbV/2X1tgvByx53bnoOizMQet4mhUv43Zlx0ongS7Hj7na/6E1iISmPVKOPbJd38DfvIf7yr50BkYsw==",
"requires": { "requires": {
"tslib": "^1.10.0" "tslib": "^1.10.0"
} }

View File

@ -61,7 +61,7 @@
"d3": "^5.9.7", "d3": "^5.9.7",
"d3-array": "^2.2.0", "d3-array": "^2.2.0",
"druid-console": "^0.0.2", "druid-console": "^0.0.2",
"druid-query-toolkit": "^0.3.12", "druid-query-toolkit": "^0.3.13",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"has-own-prop": "^2.0.0", "has-own-prop": "^2.0.0",
"hjson": "^3.1.2", "hjson": "^3.1.2",

View File

@ -44,6 +44,7 @@ exports[`sql view matches snapshot 1`] = `
<QueryOutput <QueryOutput
disabled={true} disabled={true}
loading={false} loading={false}
runeMode={false}
sqlExcludeColumn={[Function]} sqlExcludeColumn={[Function]}
sqlFilterRow={[Function]} sqlFilterRow={[Function]}
sqlOrderBy={[Function]} sqlOrderBy={[Function]}

View File

@ -48,23 +48,6 @@ FROM ${tableSchema}.${nodeData.label}`);
} }
} }
function getTableQuery(tableSchema: string, nodeData: ITreeNode): string {
let columns: string[];
if (nodeData.childNodes) {
columns = nodeData.childNodes.map(child => escapeSqlIdentifier(String(child.label)));
} else {
columns = ['*'];
}
if (tableSchema === 'druid') {
return `SELECT ${columns.join(', ')}
FROM ${escapeSqlIdentifier(String(nodeData.label))}
WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY`;
} else {
return `SELECT ${columns.join(', ')}
FROM ${tableSchema}.${nodeData.label}`;
}
}
function handleColumnClick( function handleColumnClick(
columnSchema: string, columnSchema: string,
columnTable: string, columnTable: string,
@ -99,35 +82,6 @@ ORDER BY "Count" DESC`);
} }
} }
function getColumnQuery(columnSchema: string, columnTable: string, nodeData: ITreeNode): string {
if (columnSchema === 'druid') {
if (nodeData.icon === IconNames.TIME) {
return `SELECT
TIME_FLOOR(${escapeSqlIdentifier(String(nodeData.label))}, 'PT1H') AS "Time",
COUNT(*) AS "Count"
FROM ${escapeSqlIdentifier(columnTable)}
WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY
GROUP BY 1
ORDER BY "Time" ASC`;
} else {
return `SELECT
"${nodeData.label}",
COUNT(*) AS "Count"
FROM ${escapeSqlIdentifier(columnTable)}
WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY
GROUP BY 1
ORDER BY "Count" DESC`;
}
} else {
return `SELECT
${escapeSqlIdentifier(String(nodeData.label))},
COUNT(*) AS "Count"
FROM ${columnSchema}.${columnTable}
GROUP BY 1
ORDER BY "Count" DESC`;
}
}
export interface ColumnTreeProps { export interface ColumnTreeProps {
columnMetadataLoading: boolean; columnMetadataLoading: boolean;
columnMetadata?: ColumnMetadata[]; columnMetadata?: ColumnMetadata[];
@ -190,19 +144,7 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
icon={IconNames.CLIPBOARD} icon={IconNames.CLIPBOARD}
text={`Copy: ${table}`} text={`Copy: ${table}`}
onClick={() => { onClick={() => {
copyAndAlert( copyAndAlert(table, `${table} query copied to clipboard`);
getTableQuery(schema, {
id: table,
icon: IconNames.TH,
label: table,
childNodes: metadata.map(columnData => ({
id: columnData.COLUMN_NAME,
icon: ColumnTree.dataTypeToIcon(columnData.DATA_TYPE),
label: columnData.COLUMN_NAME,
})),
}),
`${table} query copied to clipboard`,
);
}} }}
/> />
</Menu> </Menu>
@ -241,11 +183,7 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
text={`Copy: ${columnData.COLUMN_NAME}`} text={`Copy: ${columnData.COLUMN_NAME}`}
onClick={() => { onClick={() => {
copyAndAlert( copyAndAlert(
getColumnQuery(schema, table, { columnData.COLUMN_NAME,
id: columnData.COLUMN_NAME,
icon: ColumnTree.dataTypeToIcon(columnData.DATA_TYPE),
label: columnData.COLUMN_NAME,
}),
`${columnData.COLUMN_NAME} query copied to clipboard`, `${columnData.COLUMN_NAME} query copied to clipboard`,
); );
}} }}

View File

@ -25,6 +25,7 @@ describe('query output', () => {
it('matches snapshot', () => { it('matches snapshot', () => {
const queryOutput = ( const queryOutput = (
<QueryOutput <QueryOutput
runeMode={false}
sqlOrderBy={() => null} sqlOrderBy={() => null}
sqlFilterRow={() => null} sqlFilterRow={() => null}
sqlExcludeColumn={() => null} sqlExcludeColumn={() => null}

View File

@ -16,7 +16,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Popover } from '@blueprintjs/core'; import { Menu, MenuItem, Popover } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons'; import { IconNames } from '@blueprintjs/icons';
import { HeaderRows } from 'druid-query-toolkit'; import { HeaderRows } from 'druid-query-toolkit';
import { import {
@ -41,6 +41,7 @@ export interface QueryOutputProps {
sorted?: { id: string; desc: boolean }[]; sorted?: { id: string; desc: boolean }[];
result?: HeaderRows; result?: HeaderRows;
error?: string; error?: string;
runeMode: boolean;
} }
export class QueryOutput extends React.PureComponent<QueryOutputProps> { export class QueryOutput extends React.PureComponent<QueryOutputProps> {
@ -91,38 +92,44 @@ export class QueryOutput extends React.PureComponent<QueryOutputProps> {
); );
} }
getHeaderActions(h: string) { getHeaderActions(h: string) {
const { disabled, sqlExcludeColumn, sqlOrderBy } = this.props; const { disabled, sqlExcludeColumn, sqlOrderBy, runeMode } = this.props;
let actionsMenu; let actionsMenu;
if (disabled) { if (disabled) {
actionsMenu = basicActionsToMenu([ actionsMenu = (
{ <Menu>
icon: IconNames.CLIPBOARD, <MenuItem
title: `Copy: ${h}`, icon={IconNames.CLIPBOARD}
onAction: () => { text={`Copy: ${h}`}
copyAndAlert(h, `${h}' copied to clipboard`); onClick={() => {
}, copyAndAlert(h, `${h}' copied to clipboard`);
}, }}
{ />
icon: IconNames.CLIPBOARD, {runeMode && (
title: `Copy: ORDER BY ${basicIdentifierEscape(h)} ASC`, <MenuItem
onAction: () => { icon={IconNames.CLIPBOARD}
copyAndAlert( text={`Copy: ORDER BY ${basicIdentifierEscape(h)} ASC`}
`ORDER BY ${basicIdentifierEscape(h)} ASC`, onClick={() =>
`ORDER BY ${basicIdentifierEscape(h)} ASC' copied to clipboard`, copyAndAlert(
); `ORDER BY ${basicIdentifierEscape(h)} ASC`,
}, `ORDER BY ${basicIdentifierEscape(h)} ASC' copied to clipboard`,
}, )
{ }
icon: IconNames.CLIPBOARD, />
title: `Copy: 'ORDER BY ${basicIdentifierEscape(h)} DESC'`, )}
onAction: () => { {runeMode && (
copyAndAlert( <MenuItem
`ORDER BY ${basicIdentifierEscape(h)} DESC`, icon={IconNames.CLIPBOARD}
`ORDER BY ${basicIdentifierEscape(h)} DESC' copied to clipboard`, text={`Copy: 'ORDER BY ${basicIdentifierEscape(h)} DESC'`}
); onClick={() =>
}, copyAndAlert(
}, `ORDER BY ${basicIdentifierEscape(h)} DESC`,
]); `ORDER BY ${basicIdentifierEscape(h)} DESC' copied to clipboard`,
)
}
/>
)}
</Menu>
);
} else { } else {
const { sorted } = this.props; const { sorted } = this.props;
const basicActions: BasicAction[] = []; const basicActions: BasicAction[] = [];
@ -162,38 +169,46 @@ export class QueryOutput extends React.PureComponent<QueryOutputProps> {
} }
getRowActions(row: string, header: string) { getRowActions(row: string, header: string) {
const { disabled, sqlFilterRow } = this.props; const { disabled, sqlFilterRow, runeMode } = this.props;
let actionsMenu; let actionsMenu;
if (disabled) { if (disabled) {
actionsMenu = basicActionsToMenu([ actionsMenu = (
{ <Menu>
icon: IconNames.CLIPBOARD, <MenuItem
title: `Copy: '${row}'`, icon={IconNames.CLIPBOARD}
onAction: () => { text={`Copy: ${row}`}
copyAndAlert(row, `${row} copied to clipboard`); onClick={() => copyAndAlert(row, `${row} copied to clipboard`)}
}, />
}, {runeMode && (
{ <MenuItem
icon: IconNames.CLIPBOARD, icon={IconNames.CLIPBOARD}
title: `Copy: ${basicIdentifierEscape(header)} = ${basicLiteralEscape(row)}`, text={`Copy: ${basicIdentifierEscape(header)} = ${basicLiteralEscape(row)}`}
onAction: () => { onClick={() =>
copyAndAlert( copyAndAlert(
`${basicIdentifierEscape(header)} = ${basicLiteralEscape(row)}`, `${basicIdentifierEscape(header)} = ${basicLiteralEscape(row)}`,
`${basicIdentifierEscape(header)} = ${basicLiteralEscape(row)} copied to clipboard`, `${basicIdentifierEscape(header)} = ${basicLiteralEscape(
); row,
}, )} copied to clipboard`,
}, )
{ }
icon: IconNames.CLIPBOARD, />
title: `Copy: ${basicIdentifierEscape(header)} != ${basicLiteralEscape(row)}`, )}
onAction: () => { {runeMode && (
copyAndAlert( <MenuItem
`${basicIdentifierEscape(header)} != ${basicLiteralEscape(row)}`, icon={IconNames.CLIPBOARD}
`${basicIdentifierEscape(header)} != ${basicLiteralEscape(row)} copied to clipboard`, text={`Copy: ${basicIdentifierEscape(header)} != ${basicLiteralEscape(row)}`}
); onClick={() =>
}, copyAndAlert(
}, `${basicIdentifierEscape(header)} != ${basicLiteralEscape(row)}`,
]); `${basicIdentifierEscape(header)} != ${basicLiteralEscape(
row,
)} copied to clipboard`,
)
}
/>
)}
</Menu>
);
} else { } else {
actionsMenu = basicActionsToMenu([ actionsMenu = basicActionsToMenu([
{ {

View File

@ -418,6 +418,7 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
sqlExcludeColumn={this.sqlExcludeColumn} sqlExcludeColumn={this.sqlExcludeColumn}
sqlFilterRow={this.sqlFilterRow} sqlFilterRow={this.sqlFilterRow}
sqlOrderBy={this.sqlOrderBy} sqlOrderBy={this.sqlOrderBy}
runeMode={runeMode}
loading={loading} loading={loading}
result={result} result={result}
error={error} error={error}