mirror of https://github.com/apache/druid.git
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:
parent
8fa114c349
commit
03a37936ec
|
@ -4395,9 +4395,9 @@
|
|||
"integrity": "sha512-0sYnfUHHMoajaud/i5BHKA12bUxiWEHJ9rxGqVEppFxsEcxef0TZQ5J59lU+UniEBcz/sG5fTESRyS7cOm3tSQ=="
|
||||
},
|
||||
"druid-query-toolkit": {
|
||||
"version": "0.3.12",
|
||||
"resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.3.12.tgz",
|
||||
"integrity": "sha512-q2w6dDdZFYuLRTVyUvZwyXx/63ZQivjhll3Ppo3zpRcF4iWg+z+sXY9UI+sobl5q3/WojOkw/ZI0Kwzy9bWd2Q==",
|
||||
"version": "0.3.13",
|
||||
"resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.3.13.tgz",
|
||||
"integrity": "sha512-yBPAJ0tjbV/2X1tgvByx53bnoOizMQet4mhUv43Zlx0ongS7Hj7na/6E1iISmPVKOPbJd38DfvIf7yr50BkYsw==",
|
||||
"requires": {
|
||||
"tslib": "^1.10.0"
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
"d3": "^5.9.7",
|
||||
"d3-array": "^2.2.0",
|
||||
"druid-console": "^0.0.2",
|
||||
"druid-query-toolkit": "^0.3.12",
|
||||
"druid-query-toolkit": "^0.3.13",
|
||||
"file-saver": "^2.0.2",
|
||||
"has-own-prop": "^2.0.0",
|
||||
"hjson": "^3.1.2",
|
||||
|
|
|
@ -44,6 +44,7 @@ exports[`sql view matches snapshot 1`] = `
|
|||
<QueryOutput
|
||||
disabled={true}
|
||||
loading={false}
|
||||
runeMode={false}
|
||||
sqlExcludeColumn={[Function]}
|
||||
sqlFilterRow={[Function]}
|
||||
sqlOrderBy={[Function]}
|
||||
|
|
|
@ -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(
|
||||
columnSchema: 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 {
|
||||
columnMetadataLoading: boolean;
|
||||
columnMetadata?: ColumnMetadata[];
|
||||
|
@ -190,19 +144,7 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
|
|||
icon={IconNames.CLIPBOARD}
|
||||
text={`Copy: ${table}`}
|
||||
onClick={() => {
|
||||
copyAndAlert(
|
||||
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`,
|
||||
);
|
||||
copyAndAlert(table, `${table} query copied to clipboard`);
|
||||
}}
|
||||
/>
|
||||
</Menu>
|
||||
|
@ -241,11 +183,7 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
|
|||
text={`Copy: ${columnData.COLUMN_NAME}`}
|
||||
onClick={() => {
|
||||
copyAndAlert(
|
||||
getColumnQuery(schema, table, {
|
||||
id: columnData.COLUMN_NAME,
|
||||
icon: ColumnTree.dataTypeToIcon(columnData.DATA_TYPE),
|
||||
label: columnData.COLUMN_NAME,
|
||||
}),
|
||||
columnData.COLUMN_NAME,
|
||||
`${columnData.COLUMN_NAME} query copied to clipboard`,
|
||||
);
|
||||
}}
|
||||
|
|
|
@ -25,6 +25,7 @@ describe('query output', () => {
|
|||
it('matches snapshot', () => {
|
||||
const queryOutput = (
|
||||
<QueryOutput
|
||||
runeMode={false}
|
||||
sqlOrderBy={() => null}
|
||||
sqlFilterRow={() => null}
|
||||
sqlExcludeColumn={() => null}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Popover } from '@blueprintjs/core';
|
||||
import { Menu, MenuItem, Popover } from '@blueprintjs/core';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import { HeaderRows } from 'druid-query-toolkit';
|
||||
import {
|
||||
|
@ -41,6 +41,7 @@ export interface QueryOutputProps {
|
|||
sorted?: { id: string; desc: boolean }[];
|
||||
result?: HeaderRows;
|
||||
error?: string;
|
||||
runeMode: boolean;
|
||||
}
|
||||
|
||||
export class QueryOutput extends React.PureComponent<QueryOutputProps> {
|
||||
|
@ -91,38 +92,44 @@ export class QueryOutput extends React.PureComponent<QueryOutputProps> {
|
|||
);
|
||||
}
|
||||
getHeaderActions(h: string) {
|
||||
const { disabled, sqlExcludeColumn, sqlOrderBy } = this.props;
|
||||
const { disabled, sqlExcludeColumn, sqlOrderBy, runeMode } = this.props;
|
||||
let actionsMenu;
|
||||
if (disabled) {
|
||||
actionsMenu = basicActionsToMenu([
|
||||
{
|
||||
icon: IconNames.CLIPBOARD,
|
||||
title: `Copy: ${h}`,
|
||||
onAction: () => {
|
||||
actionsMenu = (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
icon={IconNames.CLIPBOARD}
|
||||
text={`Copy: ${h}`}
|
||||
onClick={() => {
|
||||
copyAndAlert(h, `${h}' copied to clipboard`);
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: IconNames.CLIPBOARD,
|
||||
title: `Copy: ORDER BY ${basicIdentifierEscape(h)} ASC`,
|
||||
onAction: () => {
|
||||
}}
|
||||
/>
|
||||
{runeMode && (
|
||||
<MenuItem
|
||||
icon={IconNames.CLIPBOARD}
|
||||
text={`Copy: ORDER BY ${basicIdentifierEscape(h)} ASC`}
|
||||
onClick={() =>
|
||||
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 && (
|
||||
<MenuItem
|
||||
icon={IconNames.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 {
|
||||
const { sorted } = this.props;
|
||||
const basicActions: BasicAction[] = [];
|
||||
|
@ -162,38 +169,46 @@ export class QueryOutput extends React.PureComponent<QueryOutputProps> {
|
|||
}
|
||||
|
||||
getRowActions(row: string, header: string) {
|
||||
const { disabled, sqlFilterRow } = this.props;
|
||||
const { disabled, sqlFilterRow, runeMode } = this.props;
|
||||
let actionsMenu;
|
||||
if (disabled) {
|
||||
actionsMenu = basicActionsToMenu([
|
||||
{
|
||||
icon: IconNames.CLIPBOARD,
|
||||
title: `Copy: '${row}'`,
|
||||
onAction: () => {
|
||||
copyAndAlert(row, `${row} copied to clipboard`);
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: IconNames.CLIPBOARD,
|
||||
title: `Copy: ${basicIdentifierEscape(header)} = ${basicLiteralEscape(row)}`,
|
||||
onAction: () => {
|
||||
actionsMenu = (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
icon={IconNames.CLIPBOARD}
|
||||
text={`Copy: ${row}`}
|
||||
onClick={() => copyAndAlert(row, `${row} copied to clipboard`)}
|
||||
/>
|
||||
{runeMode && (
|
||||
<MenuItem
|
||||
icon={IconNames.CLIPBOARD}
|
||||
text={`Copy: ${basicIdentifierEscape(header)} = ${basicLiteralEscape(row)}`}
|
||||
onClick={() =>
|
||||
copyAndAlert(
|
||||
`${basicIdentifierEscape(header)} = ${basicLiteralEscape(row)}`,
|
||||
`${basicIdentifierEscape(header)} = ${basicLiteralEscape(row)} copied to clipboard`,
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: IconNames.CLIPBOARD,
|
||||
title: `Copy: ${basicIdentifierEscape(header)} != ${basicLiteralEscape(row)}`,
|
||||
onAction: () => {
|
||||
`${basicIdentifierEscape(header)} = ${basicLiteralEscape(
|
||||
row,
|
||||
)} copied to clipboard`,
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{runeMode && (
|
||||
<MenuItem
|
||||
icon={IconNames.CLIPBOARD}
|
||||
text={`Copy: ${basicIdentifierEscape(header)} != ${basicLiteralEscape(row)}`}
|
||||
onClick={() =>
|
||||
copyAndAlert(
|
||||
`${basicIdentifierEscape(header)} != ${basicLiteralEscape(row)}`,
|
||||
`${basicIdentifierEscape(header)} != ${basicLiteralEscape(row)} copied to clipboard`,
|
||||
`${basicIdentifierEscape(header)} != ${basicLiteralEscape(
|
||||
row,
|
||||
)} copied to clipboard`,
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Menu>
|
||||
);
|
||||
},
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
actionsMenu = basicActionsToMenu([
|
||||
{
|
||||
|
|
|
@ -418,6 +418,7 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
sqlExcludeColumn={this.sqlExcludeColumn}
|
||||
sqlFilterRow={this.sqlFilterRow}
|
||||
sqlOrderBy={this.sqlOrderBy}
|
||||
runeMode={runeMode}
|
||||
loading={loading}
|
||||
result={result}
|
||||
error={error}
|
||||
|
|
Loading…
Reference in New Issue