From 573e12c75fc0465d38ef37cae092125882f27eeb Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Fri, 7 Oct 2022 12:44:40 -0700 Subject: [PATCH] Web console: making the cell filter menu more functional, removing the old query view, and updating d3 (#13169) * remove old query view * update tests * add filter * fix test * bump d3 things to latest versions * rent too far into the future with d3 * make config dialogs load * goodies * update snapshots * only compute duration when running or pending --- licenses.yaml | 24 +- licenses/bin/d3-array.BSD3 | 2 +- licenses/bin/d3-array.ISC | 13 + licenses/bin/d3-axis.ISC | 13 + licenses/bin/d3-color.ISC | 13 + licenses/bin/d3-interpolate.ISC | 13 + licenses/bin/d3-scale.ISC | 13 + licenses/bin/d3-selection.ISC | 13 + licenses/bin/internmap.ISC | 13 + .../e2e-tests/component/query/overview.ts | 10 +- web-console/package-lock.json | 228 +-- web-console/package.json | 18 +- .../cell-filter-menu/cell-filter-menu.tsx | 200 +++ .../__snapshots__/header-bar.spec.tsx.snap | 1 - .../src/components/header-bar/header-bar.tsx | 8 +- .../record-table-pane/record-table-pane.scss | 4 + .../record-table-pane/record-table-pane.tsx | 129 +- web-console/src/console-application.tsx | 21 +- ...inator-dynamic-config-dialog.spec.tsx.snap | 206 +-- .../coordinator-dynamic-config-dialog.scss | 6 + .../coordinator-dynamic-config-dialog.tsx | 66 +- ...erload-dynamic-config-dialog.spec.tsx.snap | 27 +- .../overlord-dynamic-config-dialog.scss | 6 + .../overlord-dynamic-config-dialog.tsx | 46 +- web-console/src/utils/local-storage-keys.tsx | 1 - web-console/src/views/index.ts | 1 - .../views/ingestion-view/ingestion-view.tsx | 2 +- .../__snapshots__/query-view.spec.tsx.snap | 163 -- .../live-query-mode-button.spec.tsx.snap | 153 -- .../live-query-mode-button.scss | 40 - .../live-query-mode-button.spec.tsx | 48 - .../live-query-mode-button.tsx | 80 - .../query-extra-info.spec.tsx.snap | 51 - .../query-extra-info/query-extra-info.scss | 29 - .../query-extra-info.spec.tsx | 40 - .../query-extra-info/query-extra-info.tsx | 108 -- .../query-history-dialog.spec.tsx.snap | 98 -- .../query-history-dialog.scss | 39 - .../query-history-dialog.spec.tsx | 32 - .../query-history-dialog.tsx | 88 - .../__snapshots__/query-input.spec.tsx.snap | 111 -- .../query-view/query-input/query-input.scss | 27 - .../query-input/query-input.spec.tsx | 43 - .../query-view/query-input/query-input.tsx | 279 ---- .../__snapshots__/query-output.spec.tsx.snap | 1461 ----------------- .../column-rename-input.spec.tsx.snap | 13 - .../column-rename-input.spec.tsx | 30 - .../column-rename-input.tsx | 62 - .../query-view/query-output/query-output.scss | 76 - .../query-output/query-output.spec.tsx | 61 - .../query-view/query-output/query-output.tsx | 422 ----- .../__snapshots__/query-timer.spec.tsx.snap | 32 - .../query-view/query-timer/query-timer.scss | 23 - .../query-timer/query-timer.spec.tsx | 42 - .../query-view/query-timer/query-timer.tsx | 48 - .../src/views/query-view/query-view.scss | 125 -- .../src/views/query-view/query-view.spec.tsx | 34 - .../src/views/query-view/query-view.tsx | 617 ------- .../__snapshots__/run-button.spec.tsx.snap | 129 -- .../query-view/run-button/run-button.scss | 23 - .../query-view/run-button/run-button.spec.tsx | 62 - .../query-view/run-button/run-button.tsx | 196 --- .../preview-table/preview-table.scss | 2 +- .../preview-table/preview-table.tsx | 76 +- .../__snapshots__/column-tree.spec.tsx.snap | 0 .../column-tree/column-tree-menu/index.ts | 0 .../number-menu-items.spec.tsx.snap | 0 .../number-menu-items.spec.tsx | 0 .../number-menu-items/number-menu-items.tsx | 0 .../string-menu-items.spec.tsx.snap | 0 .../string-menu-items.spec.tsx | 0 .../string-menu-items/string-menu-items.tsx | 0 .../time-menu-items.spec.tsx.snap | 0 .../time-menu-items/time-menu-items.spec.tsx | 0 .../time-menu-items/time-menu-items.tsx | 0 .../column-tree/column-tree.scss | 0 .../column-tree/column-tree.spec.tsx | 0 .../column-tree/column-tree.tsx | 0 .../explain-dialog.spec.tsx.snap | 0 .../explain-dialog/explain-dialog.scss | 2 +- .../explain-dialog/explain-dialog.spec.tsx | 0 .../explain-dialog/explain-dialog.tsx | 0 .../result-table-pane/result-table-pane.scss | 4 + .../result-table-pane/result-table-pane.tsx | 130 +- .../views/workbench-view/workbench-view.tsx | 4 +- 85 files changed, 588 insertions(+), 5612 deletions(-) create mode 100644 licenses/bin/d3-array.ISC create mode 100644 licenses/bin/d3-axis.ISC create mode 100644 licenses/bin/d3-color.ISC create mode 100644 licenses/bin/d3-interpolate.ISC create mode 100644 licenses/bin/d3-scale.ISC create mode 100644 licenses/bin/d3-selection.ISC create mode 100644 licenses/bin/internmap.ISC create mode 100644 web-console/src/components/cell-filter-menu/cell-filter-menu.tsx delete mode 100644 web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap delete mode 100644 web-console/src/views/query-view/live-query-mode-button/__snapshots__/live-query-mode-button.spec.tsx.snap delete mode 100644 web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.scss delete mode 100644 web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.spec.tsx delete mode 100644 web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.tsx delete mode 100644 web-console/src/views/query-view/query-extra-info/__snapshots__/query-extra-info.spec.tsx.snap delete mode 100644 web-console/src/views/query-view/query-extra-info/query-extra-info.scss delete mode 100644 web-console/src/views/query-view/query-extra-info/query-extra-info.spec.tsx delete mode 100644 web-console/src/views/query-view/query-extra-info/query-extra-info.tsx delete mode 100644 web-console/src/views/query-view/query-history-dialog/__snapshots__/query-history-dialog.spec.tsx.snap delete mode 100644 web-console/src/views/query-view/query-history-dialog/query-history-dialog.scss delete mode 100644 web-console/src/views/query-view/query-history-dialog/query-history-dialog.spec.tsx delete mode 100644 web-console/src/views/query-view/query-history-dialog/query-history-dialog.tsx delete mode 100644 web-console/src/views/query-view/query-input/__snapshots__/query-input.spec.tsx.snap delete mode 100644 web-console/src/views/query-view/query-input/query-input.scss delete mode 100644 web-console/src/views/query-view/query-input/query-input.spec.tsx delete mode 100644 web-console/src/views/query-view/query-input/query-input.tsx delete mode 100644 web-console/src/views/query-view/query-output/__snapshots__/query-output.spec.tsx.snap delete mode 100644 web-console/src/views/query-view/query-output/column-rename-input/__snapshots__/column-rename-input.spec.tsx.snap delete mode 100644 web-console/src/views/query-view/query-output/column-rename-input/column-rename-input.spec.tsx delete mode 100644 web-console/src/views/query-view/query-output/column-rename-input/column-rename-input.tsx delete mode 100644 web-console/src/views/query-view/query-output/query-output.scss delete mode 100644 web-console/src/views/query-view/query-output/query-output.spec.tsx delete mode 100644 web-console/src/views/query-view/query-output/query-output.tsx delete mode 100644 web-console/src/views/query-view/query-timer/__snapshots__/query-timer.spec.tsx.snap delete mode 100644 web-console/src/views/query-view/query-timer/query-timer.scss delete mode 100644 web-console/src/views/query-view/query-timer/query-timer.spec.tsx delete mode 100644 web-console/src/views/query-view/query-timer/query-timer.tsx delete mode 100644 web-console/src/views/query-view/query-view.scss delete mode 100644 web-console/src/views/query-view/query-view.spec.tsx delete mode 100644 web-console/src/views/query-view/query-view.tsx delete mode 100644 web-console/src/views/query-view/run-button/__snapshots__/run-button.spec.tsx.snap delete mode 100644 web-console/src/views/query-view/run-button/run-button.scss delete mode 100644 web-console/src/views/query-view/run-button/run-button.spec.tsx delete mode 100644 web-console/src/views/query-view/run-button/run-button.tsx rename web-console/src/views/{query-view => workbench-view}/column-tree/__snapshots__/column-tree.spec.tsx.snap (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/index.ts (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/number-menu-items/__snapshots__/number-menu-items.spec.tsx.snap (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/number-menu-items/number-menu-items.spec.tsx (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/number-menu-items/number-menu-items.tsx (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/string-menu-items/__snapshots__/string-menu-items.spec.tsx.snap (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/string-menu-items/string-menu-items.spec.tsx (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/string-menu-items/string-menu-items.tsx (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/time-menu-items/__snapshots__/time-menu-items.spec.tsx.snap (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/time-menu-items/time-menu-items.spec.tsx (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree-menu/time-menu-items/time-menu-items.tsx (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree.scss (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree.spec.tsx (100%) rename web-console/src/views/{query-view => workbench-view}/column-tree/column-tree.tsx (100%) rename web-console/src/views/{query-view => workbench-view}/explain-dialog/__snapshots__/explain-dialog.spec.tsx.snap (100%) rename web-console/src/views/{query-view => workbench-view}/explain-dialog/explain-dialog.scss (98%) rename web-console/src/views/{query-view => workbench-view}/explain-dialog/explain-dialog.spec.tsx (100%) rename web-console/src/views/{query-view => workbench-view}/explain-dialog/explain-dialog.tsx (100%) diff --git a/licenses.yaml b/licenses.yaml index 2ef5576ec02..3607ce4efbd 100644 --- a/licenses.yaml +++ b/licenses.yaml @@ -5494,7 +5494,7 @@ license_category: binary module: web-console license_name: BSD-3-Clause License copyright: Mike Bostock -version: 2.3.3 +version: 2.12.1 license_file_path: licenses/bin/d3-array.BSD3 --- @@ -5504,7 +5504,7 @@ license_category: binary module: web-console license_name: BSD-3-Clause License copyright: Mike Bostock -version: 1.0.12 +version: 2.1.0 license_file_path: licenses/bin/d3-axis.BSD3 --- @@ -5514,7 +5514,7 @@ license_category: binary module: web-console license_name: BSD-3-Clause License copyright: Mike Bostock -version: 1.4.0 +version: 2.0.0 license_file_path: licenses/bin/d3-color.BSD3 --- @@ -5534,7 +5534,7 @@ license_category: binary module: web-console license_name: BSD-3-Clause License copyright: Mike Bostock -version: 1.3.2 +version: 2.0.1 license_file_path: licenses/bin/d3-interpolate.BSD3 --- @@ -5544,7 +5544,7 @@ license_category: binary module: web-console license_name: BSD-3-Clause License copyright: Mike Bostock -version: 3.2.0 +version: 3.3.0 license_file_path: licenses/bin/d3-scale.BSD3 --- @@ -5554,7 +5554,7 @@ license_category: binary module: web-console license_name: BSD-3-Clause License copyright: Mike Bostock -version: 1.4.0 +version: 2.0.0 license_file_path: licenses/bin/d3-selection.BSD3 --- @@ -5653,7 +5653,7 @@ license_category: binary module: web-console license_name: Apache License version 2.0 copyright: Imply Data -version: 0.15.1 +version: 0.15.3 --- @@ -5837,6 +5837,16 @@ license_file_path: licenses/bin/import-fresh.MIT --- +name: "internmap" +license_category: binary +module: web-console +license_name: ISC License +copyright: Mike Bostock +version: 1.0.1 +license_file_path: licenses/bin/internmap.ISC + +--- + name: "is-arguments" license_category: binary module: web-console diff --git a/licenses/bin/d3-array.BSD3 b/licenses/bin/d3-array.BSD3 index b1b22233e2c..894ddc6549f 100644 --- a/licenses/bin/d3-array.BSD3 +++ b/licenses/bin/d3-array.BSD3 @@ -1,4 +1,4 @@ -Copyright 2010-2018 Mike Bostock +Copyright 2010-2020 Mike Bostock All rights reserved. Redistribution and use in source and binary forms, with or without modification, diff --git a/licenses/bin/d3-array.ISC b/licenses/bin/d3-array.ISC new file mode 100644 index 00000000000..fbe44bdc9ad --- /dev/null +++ b/licenses/bin/d3-array.ISC @@ -0,0 +1,13 @@ +Copyright 2010-2022 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/licenses/bin/d3-axis.ISC b/licenses/bin/d3-axis.ISC new file mode 100644 index 00000000000..b0145150fd3 --- /dev/null +++ b/licenses/bin/d3-axis.ISC @@ -0,0 +1,13 @@ +Copyright 2010-2021 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/licenses/bin/d3-color.ISC b/licenses/bin/d3-color.ISC new file mode 100644 index 00000000000..fbe44bdc9ad --- /dev/null +++ b/licenses/bin/d3-color.ISC @@ -0,0 +1,13 @@ +Copyright 2010-2022 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/licenses/bin/d3-interpolate.ISC b/licenses/bin/d3-interpolate.ISC new file mode 100644 index 00000000000..b0145150fd3 --- /dev/null +++ b/licenses/bin/d3-interpolate.ISC @@ -0,0 +1,13 @@ +Copyright 2010-2021 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/licenses/bin/d3-scale.ISC b/licenses/bin/d3-scale.ISC new file mode 100644 index 00000000000..b0145150fd3 --- /dev/null +++ b/licenses/bin/d3-scale.ISC @@ -0,0 +1,13 @@ +Copyright 2010-2021 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/licenses/bin/d3-selection.ISC b/licenses/bin/d3-selection.ISC new file mode 100644 index 00000000000..b0145150fd3 --- /dev/null +++ b/licenses/bin/d3-selection.ISC @@ -0,0 +1,13 @@ +Copyright 2010-2021 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/licenses/bin/internmap.ISC b/licenses/bin/internmap.ISC new file mode 100644 index 00000000000..6fca7113f8b --- /dev/null +++ b/licenses/bin/internmap.ISC @@ -0,0 +1,13 @@ +Copyright 2021 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/web-console/e2e-tests/component/query/overview.ts b/web-console/e2e-tests/component/query/overview.ts index b12909c8152..9ae4badcf1c 100644 --- a/web-console/e2e-tests/component/query/overview.ts +++ b/web-console/e2e-tests/component/query/overview.ts @@ -30,27 +30,27 @@ export class QueryOverview { constructor(page: playwright.Page, unifiedConsoleUrl: string) { this.page = page; - this.baseUrl = unifiedConsoleUrl + '#query'; + this.baseUrl = unifiedConsoleUrl + '#workbench'; } async runQuery(query: string): Promise { await this.page.goto(this.baseUrl); await this.page.reload({ waitUntil: 'networkidle' }); - const input = await this.page.waitForSelector('div.query-input textarea'); + const input = await this.page.waitForSelector('div.flexible-query-input textarea'); await input.fill(query); await clickButton(this.page, 'Run'); - await this.page.waitForSelector('div.query-info'); + await this.page.waitForSelector('div.result-table-pane'); - return await extractTable(this.page, 'div.query-output div.rt-tr-group', 'div.rt-td'); + return await extractTable(this.page, 'div.result-table-pane div.rt-tr-group', 'div.rt-td'); } async cancelQuery(query: string): Promise { await this.page.goto(this.baseUrl); await this.page.reload({ waitUntil: 'networkidle' }); - const input = await this.page.waitForSelector('div.query-input textarea'); + const input = await this.page.waitForSelector('div.flexible-query-input textarea'); await input.fill(query); await Promise.all([ diff --git a/web-console/package-lock.json b/web-console/package-lock.json index 2cdbcae4120..5f1e35cef33 100644 --- a/web-console/package-lock.json +++ b/web-console/package-lock.json @@ -18,11 +18,11 @@ "classnames": "^2.2.6", "copy-to-clipboard": "^3.2.0", "core-js": "^3.10.1", - "d3-array": "^2.3.3", - "d3-axis": "^1.0.12", - "d3-scale": "^3.2.0", - "d3-selection": "^1.4.0", - "druid-query-toolkit": "^0.15.1", + "d3-array": "^2.12.1", + "d3-axis": "^2.1.0", + "d3-scale": "^3.3.0", + "d3-selection": "^2.0.0", + "druid-query-toolkit": "^0.15.3", "file-saver": "^2.0.2", "follow-redirects": "^1.14.7", "fontsource-open-sans": "^3.0.9", @@ -54,10 +54,10 @@ "@babel/preset-env": "^7.14.4", "@testing-library/react": "^8.0.9", "@types/classnames": "^2.2.9", - "@types/d3-array": "^2.0.0", - "@types/d3-axis": "^1.0.12", - "@types/d3-scale": "^2.1.1", - "@types/d3-selection": "^1.4.1", + "@types/d3-array": "^2.12.3", + "@types/d3-axis": "^2.1.3", + "@types/d3-scale": "^3.3.2", + "@types/d3-selection": "^2.0.1", "@types/enzyme": "^3.10.3", "@types/enzyme-adapter-react-16": "^1.0.5", "@types/file-saver": "^2.0.1", @@ -4600,39 +4600,39 @@ "dev": true }, "node_modules/@types/d3-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-2.0.0.tgz", - "integrity": "sha512-rGqfPVowNDTszSFvwoZIXvrPG7s/qKzm9piCRIH6xwTTRu7pPZ3ootULFnPkTt74B6i5lN0FpLQL24qGOw1uZA==", + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-2.12.3.tgz", + "integrity": "sha512-hN879HLPTVqZV3FQEXy7ptt083UXwguNbnxdTGzVW4y4KjX5uyNKljrQixZcSJfLyFirbpUokxpXtvR+N5+KIg==", "dev": true }, "node_modules/@types/d3-axis": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-1.0.12.tgz", - "integrity": "sha512-BZISgSD5M8TgURyNtcPAmUB9sk490CO1Thb6/gIn0WZTt3Y50IssX+2Z0vTccoqZksUDTep0b+o4ofXslvNbqg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-2.1.3.tgz", + "integrity": "sha512-QjXjwZ0xzyrW2ndkmkb09ErgWDEYtbLBKGui73QLMFm3woqWpxptfD5Y7vqQdybMcu7WEbjZ5q+w2w5+uh2IjA==", "dev": true, "dependencies": { - "@types/d3-selection": "*" + "@types/d3-selection": "^2" } }, "node_modules/@types/d3-scale": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-2.1.1.tgz", - "integrity": "sha512-kNTkbZQ+N/Ip8oX9PByXfDLoCSaZYm+VUOasbmsa6KD850/ziMdYepg/8kLg2plHzoLANdMqPoYQbvExevLUHg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz", + "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==", "dev": true, "dependencies": { - "@types/d3-time": "*" + "@types/d3-time": "^2" } }, "node_modules/@types/d3-selection": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.4.1.tgz", - "integrity": "sha512-bv8IfFYo/xG6dxri9OwDnK3yCagYPeRIjTlrcdYJSx+FDWlCeBDepIHUpqROmhPtZ53jyna0aUajZRk0I3rXNA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-2.0.1.tgz", + "integrity": "sha512-3mhtPnGE+c71rl/T5HMy+ykg7migAZ4T6gzU0HxpgBFKcasBrSnwRbYV1/UZR6o5fkpySxhWxAhd7yhjj8jL7g==", "dev": true }, "node_modules/@types/d3-time": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.0.10.tgz", - "integrity": "sha512-aKf62rRQafDQmSiv1NylKhIMmznsjRN+MnXRXTqHoqm0U/UZzVpdrtRnSIfdiLS616OuC1soYeX1dBg2n1u8Xw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==", "dev": true }, "node_modules/@types/dom4": { @@ -8465,19 +8465,22 @@ "integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==" }, "node_modules/d3-array": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.3.3.tgz", - "integrity": "sha512-syv3wp0U5aB6toP2zb2OdBkhTy1MWDsCAaYk6OXJZv+G4u7bSWEmYgxLoFyc88RQUhZYGCebW9a9UD1gFi5+MQ==" + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } }, "node_modules/d3-axis": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", - "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-2.1.0.tgz", + "integrity": "sha512-z/G2TQMyuf0X3qP+Mh+2PimoJD41VOCjViJzT0BHeL/+JQAofkiWZbWxlwFGb1N8EN+Cl/CW+MUKbVzr1689Cw==" }, "node_modules/d3-color": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz", - "integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" }, "node_modules/d3-format": { "version": "1.4.1", @@ -8485,29 +8488,37 @@ "integrity": "sha512-TUswGe6hfguUX1CtKxyG2nymO+1lyThbkS1ifLX0Sr+dOQtAD5gkrffpHnx+yHNKUZ0Bmg5T4AjUQwugPDrm0g==" }, "node_modules/d3-interpolate": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz", - "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", "dependencies": { - "d3-color": "1" + "d3-color": "1 - 2" } }, "node_modules/d3-scale": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.0.tgz", - "integrity": "sha512-1RnLYPmH3f2E96hSsCr3ok066myuAxoH3+pnlJAedeMOp7jeW7A+GZHAyVWWaStfphyPEBiDoLFA9zl+DcnC2Q==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", "dependencies": { - "d3-array": "1.2.0 - 2", - "d3-format": "1", - "d3-interpolate": "1", - "d3-time": "1", - "d3-time-format": "2" + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "^2.1.1", + "d3-time-format": "2 - 3" + } + }, + "node_modules/d3-scale/node_modules/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "dependencies": { + "d3-array": "2" } }, "node_modules/d3-selection": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.0.tgz", - "integrity": "sha512-EYVwBxQGEjLCKF2pJ4+yrErskDnz5v403qvAid96cNdCMr8rmCYfY5RGzWz24mdIbxmDf6/4EAH+K9xperD5jg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", + "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==" }, "node_modules/d3-time": { "version": "1.1.0", @@ -8956,9 +8967,9 @@ } }, "node_modules/druid-query-toolkit": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.15.1.tgz", - "integrity": "sha512-yklAD1Ksokh2s+llEaR/lvvMHjW6CgdCG7X+JFnWsttM/xITpTFMu4Zo5/MqVvoo9021/deg87QQMCOKNfo3wQ==", + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.15.3.tgz", + "integrity": "sha512-AtKnmCDWSHh1+bHFs36drJAKQ60914ttF62x3wIxXbD1zoUEmwwsX4Ks2zD3SItantVS4fTj3cyjMl/c0fojpA==", "dependencies": { "tslib": "^2.3.1" }, @@ -12599,6 +12610,11 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, "node_modules/interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", @@ -31092,39 +31108,39 @@ "dev": true }, "@types/d3-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-2.0.0.tgz", - "integrity": "sha512-rGqfPVowNDTszSFvwoZIXvrPG7s/qKzm9piCRIH6xwTTRu7pPZ3ootULFnPkTt74B6i5lN0FpLQL24qGOw1uZA==", + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-2.12.3.tgz", + "integrity": "sha512-hN879HLPTVqZV3FQEXy7ptt083UXwguNbnxdTGzVW4y4KjX5uyNKljrQixZcSJfLyFirbpUokxpXtvR+N5+KIg==", "dev": true }, "@types/d3-axis": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-1.0.12.tgz", - "integrity": "sha512-BZISgSD5M8TgURyNtcPAmUB9sk490CO1Thb6/gIn0WZTt3Y50IssX+2Z0vTccoqZksUDTep0b+o4ofXslvNbqg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-2.1.3.tgz", + "integrity": "sha512-QjXjwZ0xzyrW2ndkmkb09ErgWDEYtbLBKGui73QLMFm3woqWpxptfD5Y7vqQdybMcu7WEbjZ5q+w2w5+uh2IjA==", "dev": true, "requires": { - "@types/d3-selection": "*" + "@types/d3-selection": "^2" } }, "@types/d3-scale": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-2.1.1.tgz", - "integrity": "sha512-kNTkbZQ+N/Ip8oX9PByXfDLoCSaZYm+VUOasbmsa6KD850/ziMdYepg/8kLg2plHzoLANdMqPoYQbvExevLUHg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz", + "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==", "dev": true, "requires": { - "@types/d3-time": "*" + "@types/d3-time": "^2" } }, "@types/d3-selection": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-1.4.1.tgz", - "integrity": "sha512-bv8IfFYo/xG6dxri9OwDnK3yCagYPeRIjTlrcdYJSx+FDWlCeBDepIHUpqROmhPtZ53jyna0aUajZRk0I3rXNA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-2.0.1.tgz", + "integrity": "sha512-3mhtPnGE+c71rl/T5HMy+ykg7migAZ4T6gzU0HxpgBFKcasBrSnwRbYV1/UZR6o5fkpySxhWxAhd7yhjj8jL7g==", "dev": true }, "@types/d3-time": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.0.10.tgz", - "integrity": "sha512-aKf62rRQafDQmSiv1NylKhIMmznsjRN+MnXRXTqHoqm0U/UZzVpdrtRnSIfdiLS616OuC1soYeX1dBg2n1u8Xw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==", "dev": true }, "@types/dom4": { @@ -34140,19 +34156,22 @@ "integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==" }, "d3-array": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.3.3.tgz", - "integrity": "sha512-syv3wp0U5aB6toP2zb2OdBkhTy1MWDsCAaYk6OXJZv+G4u7bSWEmYgxLoFyc88RQUhZYGCebW9a9UD1gFi5+MQ==" + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "requires": { + "internmap": "^1.0.0" + } }, "d3-axis": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", - "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-2.1.0.tgz", + "integrity": "sha512-z/G2TQMyuf0X3qP+Mh+2PimoJD41VOCjViJzT0BHeL/+JQAofkiWZbWxlwFGb1N8EN+Cl/CW+MUKbVzr1689Cw==" }, "d3-color": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz", - "integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" }, "d3-format": { "version": "1.4.1", @@ -34160,29 +34179,39 @@ "integrity": "sha512-TUswGe6hfguUX1CtKxyG2nymO+1lyThbkS1ifLX0Sr+dOQtAD5gkrffpHnx+yHNKUZ0Bmg5T4AjUQwugPDrm0g==" }, "d3-interpolate": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz", - "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", "requires": { - "d3-color": "1" + "d3-color": "1 - 2" } }, "d3-scale": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.0.tgz", - "integrity": "sha512-1RnLYPmH3f2E96hSsCr3ok066myuAxoH3+pnlJAedeMOp7jeW7A+GZHAyVWWaStfphyPEBiDoLFA9zl+DcnC2Q==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", "requires": { - "d3-array": "1.2.0 - 2", - "d3-format": "1", - "d3-interpolate": "1", - "d3-time": "1", - "d3-time-format": "2" + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "^2.1.1", + "d3-time-format": "2 - 3" + }, + "dependencies": { + "d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "requires": { + "d3-array": "2" + } + } } }, "d3-selection": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.0.tgz", - "integrity": "sha512-EYVwBxQGEjLCKF2pJ4+yrErskDnz5v403qvAid96cNdCMr8rmCYfY5RGzWz24mdIbxmDf6/4EAH+K9xperD5jg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", + "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==" }, "d3-time": { "version": "1.1.0", @@ -34562,9 +34591,9 @@ } }, "druid-query-toolkit": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.15.1.tgz", - "integrity": "sha512-yklAD1Ksokh2s+llEaR/lvvMHjW6CgdCG7X+JFnWsttM/xITpTFMu4Zo5/MqVvoo9021/deg87QQMCOKNfo3wQ==", + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.15.3.tgz", + "integrity": "sha512-AtKnmCDWSHh1+bHFs36drJAKQ60914ttF62x3wIxXbD1zoUEmwwsX4Ks2zD3SItantVS4fTj3cyjMl/c0fojpA==", "requires": { "tslib": "^2.3.1" } @@ -37367,6 +37396,11 @@ "side-channel": "^1.0.4" } }, + "internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, "interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", diff --git a/web-console/package.json b/web-console/package.json index eb7ce021482..6cde5763041 100644 --- a/web-console/package.json +++ b/web-console/package.json @@ -75,11 +75,11 @@ "classnames": "^2.2.6", "copy-to-clipboard": "^3.2.0", "core-js": "^3.10.1", - "d3-array": "^2.3.3", - "d3-axis": "^1.0.12", - "d3-scale": "^3.2.0", - "d3-selection": "^1.4.0", - "druid-query-toolkit": "^0.15.1", + "d3-array": "^2.12.1", + "d3-axis": "^2.1.0", + "d3-scale": "^3.3.0", + "d3-selection": "^2.0.0", + "druid-query-toolkit": "^0.15.3", "file-saver": "^2.0.2", "follow-redirects": "^1.14.7", "fontsource-open-sans": "^3.0.9", @@ -111,10 +111,10 @@ "@babel/preset-env": "^7.14.4", "@testing-library/react": "^8.0.9", "@types/classnames": "^2.2.9", - "@types/d3-array": "^2.0.0", - "@types/d3-axis": "^1.0.12", - "@types/d3-scale": "^2.1.1", - "@types/d3-selection": "^1.4.1", + "@types/d3-array": "^2.12.3", + "@types/d3-axis": "^2.1.3", + "@types/d3-scale": "^3.3.2", + "@types/d3-selection": "^2.0.1", "@types/enzyme": "^3.10.3", "@types/enzyme-adapter-react-16": "^1.0.5", "@types/file-saver": "^2.0.1", diff --git a/web-console/src/components/cell-filter-menu/cell-filter-menu.tsx b/web-console/src/components/cell-filter-menu/cell-filter-menu.tsx new file mode 100644 index 00000000000..a5e9022537e --- /dev/null +++ b/web-console/src/components/cell-filter-menu/cell-filter-menu.tsx @@ -0,0 +1,200 @@ +/* + * 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. + */ + +import { Menu, MenuItem } from '@blueprintjs/core'; +import { IconNames } from '@blueprintjs/icons'; +import { + Column, + SqlComparison, + SqlExpression, + SqlLiteral, + SqlQuery, + SqlRecord, + SqlRef, + trimString, +} from 'druid-query-toolkit'; +import React from 'react'; + +import { copyAndAlert, prettyPrintSql, QueryAction, stringifyValue } from '../../utils'; + +function sqlLiteralForColumnValue(column: Column, value: unknown): SqlLiteral | undefined { + if (column.sqlType === 'TIMESTAMP') { + const asDate = new Date(value as any); + if (!isNaN(asDate.valueOf())) { + return SqlLiteral.create(asDate); + } + } + + return SqlLiteral.maybe(value); +} + +function isComparable(x: unknown): boolean { + return x !== null && x !== ''; +} + +function addToClause(clause: SqlExpression, newValue: SqlLiteral): SqlExpression | undefined { + if (!(clause instanceof SqlComparison)) return; + const { op, lhs, rhs } = clause; + + switch (op) { + case '=': + if (!(rhs instanceof SqlLiteral)) return; + if (rhs.equals(newValue)) return; + return lhs.in([rhs, newValue]); + + case '<>': + if (!(rhs instanceof SqlLiteral)) return; + if (rhs.equals(newValue)) return; + return lhs.notIn([rhs, newValue]); + + case 'IN': + if (!(rhs instanceof SqlRecord)) return; + if (rhs.contains(newValue)) return; + return clause.changeRhs(rhs.prepend(newValue)); + + default: + return; + } +} + +function clipboardMenuItem(clause: SqlExpression) { + const prettyLabel = prettyPrintSql(clause); + return ( + copyAndAlert(clause.toString(), `${prettyLabel} copied to clipboard`)} + /> + ); +} + +export interface CellFilterMenuProps { + column: Column; + value: unknown; + headerIndex: number; + runeMode?: boolean; + query: SqlQuery | undefined; + onQueryAction?(action: QueryAction): void; + onShowFullValue?(valueString: string): void; +} + +export function CellFilterMenu(props: CellFilterMenuProps) { + const { column, value, runeMode, headerIndex, query, onQueryAction, onShowFullValue } = props; + + const showFullValueMenuItem = onShowFullValue ? ( + { + onShowFullValue(stringifyValue(value)); + }} + /> + ) : undefined; + + const val = sqlLiteralForColumnValue(column, value); + + if (query) { + let ex: SqlExpression | undefined; + let having = false; + if (query.hasStarInSelect()) { + ex = SqlRef.column(column.name); + } else { + const selectValue = query.getSelectExpressionForIndex(headerIndex); + if (selectValue) { + const outputName = selectValue.getOutputName(); + having = query.isAggregateSelectIndex(headerIndex); + if (having && outputName) { + ex = SqlRef.column(outputName); + } else { + ex = selectValue.getUnderlyingExpression(); + } + } + } + + const filterOnMenuItem = (clause: SqlExpression) => { + if (!onQueryAction) return; + return ( + { + const column = clause.getUsedColumns()[0]; + onQueryAction( + having + ? q => q.removeFromHaving(column).addHaving(clause) + : q => q.removeColumnFromWhere(column).addWhere(clause), + ); + }} + /> + ); + }; + + const currentFilterExpression = having + ? query.getHavingExpression() + : query.getWhereExpression(); + + const currentClauses = + currentFilterExpression + ?.decomposeViaAnd() + ?.filter(ex => String(ex.getUsedColumns()) === column.name) || []; + + const updatedClause = + currentClauses.length === 1 && val ? addToClause(currentClauses[0], val) : undefined; + console.log(updatedClause, currentClauses); + + const jsonColumn = column.nativeType === 'COMPLEX'; + return ( + + {ex?.getFirstColumn() && val && !jsonColumn && ( + <> + {updatedClause && filterOnMenuItem(updatedClause)} + {filterOnMenuItem(ex.equal(val))} + {filterOnMenuItem(ex.unequal(val))} + {isComparable(value) && ( + <> + {filterOnMenuItem(ex.greaterThanOrEqual(val))} + {filterOnMenuItem(ex.lessThanOrEqual(val))} + + )} + + )} + {showFullValueMenuItem} + + ); + } else { + const ref = SqlRef.column(column.name); + const stringValue = stringifyValue(value); + const trimmedValue = trimString(stringValue, 50); + return ( + + copyAndAlert(stringValue, `${trimmedValue} copied to clipboard`)} + /> + {!runeMode && val && ( + <> + {clipboardMenuItem(ref.equal(val))} + {clipboardMenuItem(ref.unequal(val))} + + )} + {showFullValueMenuItem} + + ); + } +} diff --git a/web-console/src/components/header-bar/__snapshots__/header-bar.spec.tsx.snap b/web-console/src/components/header-bar/__snapshots__/header-bar.spec.tsx.snap index cc7f53463cc..92ea6c77b87 100644 --- a/web-console/src/components/header-bar/__snapshots__/header-bar.spec.tsx.snap +++ b/web-console/src/components/header-bar/__snapshots__/header-bar.spec.tsx.snap @@ -20,7 +20,6 @@ exports[`HeaderBar matches snapshot 1`] = ` href="#workbench" icon="application" minimal={true} - onClick={[Function]} text="Query" /> { - if (!e.altKey) return; - e.preventDefault(); - location.hash = '#query'; - }} /> {showSplitDataLoaderMenu ? ( ({ page: 0, @@ -96,95 +71,17 @@ export const RecordTablePane = React.memo(function RecordTablePane(props: Record ); } - function filterOnMenuItem(icon: IconName, clause: SqlExpression) { - if (!parsedQuery || !addFilter) return; - - return ( - { - addFilter(clause.toString()); - }} - /> - ); - } - - function actionMenuItem(clause: SqlExpression) { - if (!addFilter) return; - const prettyLabel = prettyPrintSql(clause); - return ( - addFilter(clause.toString())} - /> - ); - } - function getCellMenu(column: Column, headerIndex: number, value: unknown) { - const showFullValueMenuItem = ( - { - setShowValue(stringifyValue(value)); - }} + return ( + ); - - const val = sqlLiteralForColumnValue(column, value); - - if (parsedQuery) { - let ex: SqlExpression | undefined; - if (parsedQuery.hasStarInSelect()) { - ex = SqlRef.column(column.name); - } else { - const selectValue = parsedQuery.getSelectExpressionForIndex(headerIndex); - if (selectValue) { - ex = selectValue.getUnderlyingExpression(); - } - } - - const jsonColumn = column.nativeType === 'COMPLEX'; - return ( - - {ex && val && !jsonColumn && ( - <> - {filterOnMenuItem(IconNames.FILTER, ex.equal(val))} - {filterOnMenuItem(IconNames.FILTER, ex.unequal(val))} - {isComparable(value) && ( - <> - {filterOnMenuItem(IconNames.FILTER, ex.greaterThanOrEqual(val))} - {filterOnMenuItem(IconNames.FILTER, ex.lessThanOrEqual(val))} - - )} - - )} - {showFullValueMenuItem} - - ); - } else { - const ref = SqlRef.column(column.name); - const stringValue = stringifyValue(value); - const trimmedValue = trimString(stringValue, 50); - return ( - - copyAndAlert(stringValue, `${trimmedValue} copied to clipboard`)} - /> - {val && ( - <> - {actionMenuItem(ref.equal(val))} - {actionMenuItem(ref.unequal(val))} - - )} - {showFullValueMenuItem} - - ); - } } function getHeaderClassName(header: string) { diff --git a/web-console/src/console-application.tsx b/web-console/src/console-application.tsx index d5dc61cebc9..02845835dd1 100644 --- a/web-console/src/console-application.tsx +++ b/web-console/src/console-application.tsx @@ -20,7 +20,7 @@ import { HotkeysProvider, Intent } from '@blueprintjs/core'; import { IconNames } from '@blueprintjs/icons'; import classNames from 'classnames'; import React from 'react'; -import { RouteComponentProps } from 'react-router'; +import { Redirect, RouteComponentProps } from 'react-router'; import { HashRouter, Route, Switch } from 'react-router-dom'; import { HeaderActiveTab, HeaderBar, Loader } from './components'; @@ -33,7 +33,6 @@ import { IngestionView, LoadDataView, LookupsView, - QueryView, SegmentsView, ServicesView, SqlDataLoaderView, @@ -245,20 +244,6 @@ export class ConsoleApplication extends React.PureComponent< ); }; - private readonly wrappedQueryView = () => { - const { defaultQueryContext, mandatoryQueryContext } = this.props; - - return this.wrapInViewContainer( - 'query', - , - 'thin', - ); - }; - private readonly wrappedWorkbenchView = (p: RouteComponentProps) => { const { defaultQueryContext, mandatoryQueryContext } = this.props; const { capabilities } = this.state; @@ -384,7 +369,9 @@ export class ConsoleApplication extends React.PureComponent< - + + + -

- Edit the coordinator dynamic configuration on the fly. For more information please refer to the - - - documentation - - . -

- - - The maximum number of segments that can be moved at any given time. - , - "name": "maxSegmentsToMove", - "type": "number", - }, - Object { - "defaultValue": 1, - "info": - Thread pool size for computing moving cost of segments in segment balancing. Consider increasing this if you have a lot of segments and moving segments starts to get stuck. - , - "name": "balancerComputeThreads", - "type": "number", - }, - Object { - "defaultValue": false, - "info": - Boolean flag for whether or not we should emit balancing stats. This is an expensive operation. - , - "name": "emitBalancingStats", - "type": "boolean", - }, - Object { - "defaultValue": false, - "info": - Send kill tasks for ALL dataSources if property - - druid.coordinator.kill.on - - is true. If this is set to true then - - killDataSourceWhitelist - - must not be specified or be empty list. - , - "name": "killAllDataSources", - "type": "boolean", - }, - Object { - "emptyValue": Array [], - "info": - List of dataSources for which kill tasks are sent if property - - - druid.coordinator.kill.on - - is true. This can be a list of comma-separated dataSources or a JSON array. - , - "name": "killDataSourceWhitelist", - "type": "string-array", - }, - Object { - "emptyValue": Array [], - "info": - List of dataSources for which pendingSegments are NOT cleaned up if property - - - druid.coordinator.kill.pendingSegments.on - - is true. This can be a list of comma-separated dataSources or a JSON array. - , - "name": "killPendingSegmentsSkipList", - "type": "string-array", - }, - Object { - "defaultValue": 0, - "info": - The maximum number of segments that could be queued for loading to any given server. This parameter could be used to speed up segments loading process, especially if there are "slow" nodes in the cluster (with low loading speed) or if too much segments scheduled to be replicated to some particular node (faster loading could be preferred to better segments distribution). Desired value depends on segments loading speed, acceptable replication time and number of nodes. Value 1000 could be a start point for a rather big cluster. Default value is 0 (loading queue is unbounded) - , - "name": "maxSegmentsInNodeLoadingQueue", - "type": "number", - }, - Object { - "defaultValue": 524288000, - "info": - The maximum total uncompressed size in bytes of segments to merge. - , - "name": "mergeBytesLimit", - "type": "size-bytes", - }, - Object { - "defaultValue": 100, - "info": - The maximum number of segments that can be in a single append task. - , - "name": "mergeSegmentsLimit", - "type": "number", - }, - Object { - "defaultValue": 900000, - "info": - How long does the Coordinator need to be active before it can start removing (marking unused) segments in metadata storage. - , - "name": "millisToWaitBeforeDeleting", - "type": "number", - }, - Object { - "defaultValue": 15, - "info": - The maximum number of Coordinator runs for a segment to be replicated before we start alerting. - , - "name": "replicantLifetime", - "type": "number", - }, - Object { - "defaultValue": 10, - "info": - The maximum number of segments that can be replicated at one time. - , - "name": "replicationThrottleLimit", - "type": "number", - }, - Object { - "emptyValue": Array [], - "info": - List of historical services to 'decommission'. Coordinator will not assign new segments to 'decommissioning' services, and segments will be moved away from them to be placed on non-decommissioning services at the maximum rate specified by - - - decommissioningMaxPercentOfMaxSegmentsToMove - - . - , - "name": "decommissioningNodes", - "type": "string-array", - }, - Object { - "defaultValue": 70, - "info": - The maximum number of segments that may be moved away from 'decommissioning' services to non-decommissioning (that is, active) services during one Coordinator run. This value is relative to the total maximum segment movements allowed during one run which is determined by - - maxSegmentsToMove - - . If - - decommissioningMaxPercentOfMaxSegmentsToMove - - is 0, segments will neither be moved from or to 'decommissioning' services, effectively putting them in a sort of "maintenance" mode that will not participate in balancing or assignment by load rules. Decommissioning can also become stalled if there are no available active services to place the segments. By leveraging the maximum percent of decommissioning segment movements, an operator can prevent active services from overload by prioritizing balancing, or decrease decommissioning time instead. The value should be between 0 and 100. - , - "name": "decommissioningMaxPercentOfMaxSegmentsToMove", - "type": "number", - }, - Object { - "defaultValue": false, - "info": - Boolean flag for whether or not we should use the Reservoir Sampling with a reservoir of size k instead of fixed size 1 to pick segments to move. This option can be enabled to speed up segment balancing process, especially if there are huge number of segments in the cluster or if there are too many segments to move. - , - "name": "useBatchedSegmentSampler", - "type": "boolean", - }, - Object { - "defaultValue": 100, - "info": - Deprecated. This will eventually be phased out by the batched segment sampler. You can enable the batched segment sampler now by setting the dynamic Coordinator config, useBatchedSegmentSampler, to true. Note that if you choose to enable the batched segment sampler, percentOfSegmentsToConsiderPerMove will no longer have any effect on balancing. If useBatchedSegmentSampler == false, this config defines the percentage of the total number of segments in the cluster that are considered every time a segment needs to be selected for a move. Druid orders servers by available capacity ascending (the least available capacity first) and then iterates over the servers. For each server, Druid iterates over the segments on the server, considering them for moving. The default config of 100% means that every segment on every server is a candidate to be moved. This should make sense for most small to medium-sized clusters. However, an admin may find it preferable to drop this value lower if they don't think that it is worthwhile to consider every single segment in the cluster each time it is looking for a segment to move. - , - "name": "percentOfSegmentsToConsiderPerMove", - "type": "number", - }, - Object { - "defaultValue": false, - "info": - Boolean flag for whether or not the coordinator should execute its various duties of coordinating the cluster. Setting this to true essentially pauses all coordination work while allowing the API to remain up. - , - "name": "pauseCoordination", - "type": "boolean", - }, - Object { - "defaultValue": false, - "info": - Boolean flag for whether or not additional replication is needed for segments that have failed to load due to the expiry of coordinator load timeout. If this is set to true, the coordinator will attempt to replicate the failed segment on a different historical server. - , - "name": "replicateAfterLoadTimeout", - "type": "boolean", - }, - Object { - "defaultValue": 2147483647, - "info": - The maximum number of non-primary replicants to load in a single Coordinator cycle. Once this limit is hit, only primary replicants will be loaded for the remainder of the cycle. Tuning this value lower can help reduce the delay in loading primary segments when the cluster has a very large number of non-primary replicants to load (such as when a single historical drops out of the cluster leaving many under-replicated segments). - , - "name": "maxNonPrimaryReplicantsToLoad", - "type": "number", - }, - ] - } - model={Object {}} - onChange={[Function]} - /> + `; diff --git a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.scss b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.scss index 6ca75056008..2618b054b3d 100644 --- a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.scss +++ b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.scss @@ -24,6 +24,12 @@ top: 5%; } + .loader { + position: relative; + height: 60vh; + width: 100%; + } + .#{$bp-ns}-dialog-body { max-height: 70vh; diff --git a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx index c0e02af84cf..7fa8925220f 100644 --- a/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx +++ b/web-console/src/dialogs/coordinator-dynamic-config-dialog/coordinator-dynamic-config-dialog.tsx @@ -26,6 +26,7 @@ import { FormJsonSelector, FormJsonTabs, JsonInput, + Loader, } from '../../components'; import { COORDINATOR_DYNAMIC_CONFIG_FIELDS, CoordinatorDynamicConfig } from '../../druid-models'; import { useQueryManager } from '../../hooks'; @@ -37,7 +38,7 @@ import { SnitchDialog } from '..'; import './coordinator-dynamic-config-dialog.scss'; export interface CoordinatorDynamicConfigDialogProps { - onClose: () => void; + onClose(): void; } export const CoordinatorDynamicConfigDialog = React.memo(function CoordinatorDynamicConfigDialog( @@ -45,18 +46,19 @@ export const CoordinatorDynamicConfigDialog = React.memo(function CoordinatorDyn ) { const { onClose } = props; const [currentTab, setCurrentTab] = useState('form'); - const [dynamicConfig, setDynamicConfig] = useState({}); + const [dynamicConfig, setDynamicConfig] = useState(); const [jsonError, setJsonError] = useState(); const [historyRecordsState] = useQueryManager({ + initQuery: null, processQuery: async () => { const historyResp = await Api.instance.get(`/druid/coordinator/v1/config/history?count=100`); return historyResp.data; }, - initQuery: null, }); useQueryManager>({ + initQuery: null, processQuery: async () => { try { const configResp = await Api.instance.get('/druid/coordinator/v1/config'); @@ -67,12 +69,10 @@ export const CoordinatorDynamicConfigDialog = React.memo(function CoordinatorDyn intent: Intent.DANGER, message: `Could not load coordinator dynamic config: ${getDruidErrorMessage(e)}`, }); - setDynamicConfig({}); onClose(); } return {}; }, - initQuery: null, }); async function saveConfig(comment: string) { @@ -107,31 +107,39 @@ export const CoordinatorDynamicConfigDialog = React.memo(function CoordinatorDyn title="Coordinator dynamic config" historyRecords={historyRecordsState.data} > -

- Edit the coordinator dynamic configuration on the fly. For more information please refer to - the{' '} - - documentation - - . -

- - {currentTab === 'form' ? ( - + {dynamicConfig ? ( + <> +

+ Edit the coordinator dynamic configuration on the fly. For more information please refer + to the{' '} + + documentation + + . +

+ + {currentTab === 'form' ? ( + + ) : ( + { + setDynamicConfig(v); + setJsonError(undefined); + }} + onError={setJsonError} + /> + )} + ) : ( - { - setDynamicConfig(v); - setJsonError(undefined); - }} - onError={setJsonError} - /> + )} ); diff --git a/web-console/src/dialogs/overlord-dynamic-config-dialog/__snapshots__/overload-dynamic-config-dialog.spec.tsx.snap b/web-console/src/dialogs/overlord-dynamic-config-dialog/__snapshots__/overload-dynamic-config-dialog.spec.tsx.snap index 008ba4d10eb..a7ac71240a2 100644 --- a/web-console/src/dialogs/overlord-dynamic-config-dialog/__snapshots__/overload-dynamic-config-dialog.spec.tsx.snap +++ b/web-console/src/dialogs/overlord-dynamic-config-dialog/__snapshots__/overload-dynamic-config-dialog.spec.tsx.snap @@ -7,31 +7,6 @@ exports[`OverlordDynamicConfigDialog matches snapshot 1`] = ` onSave={[Function]} title="Overlord dynamic config" > -

- Edit the overlord dynamic configuration on the fly. For more information please refer to the - - - documentation - - . -

- + `; diff --git a/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.scss b/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.scss index 8829e93b501..4f2f242c212 100644 --- a/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.scss +++ b/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.scss @@ -25,6 +25,12 @@ width: 600px; } + .loader { + position: relative; + height: 60vh; + width: 100%; + } + .#{$bp-ns}-dialog-body { max-height: 70vh; diff --git a/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx b/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx index c726bdc278a..76b28084502 100644 --- a/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx +++ b/web-console/src/dialogs/overlord-dynamic-config-dialog/overlord-dynamic-config-dialog.tsx @@ -20,7 +20,7 @@ import { Intent } from '@blueprintjs/core'; import { IconNames } from '@blueprintjs/icons'; import React, { useState } from 'react'; -import { AutoForm, ExternalLink } from '../../components'; +import { AutoForm, ExternalLink, Loader } from '../../components'; import { OVERLORD_DYNAMIC_CONFIG_FIELDS, OverlordDynamicConfig } from '../../druid-models'; import { useQueryManager } from '../../hooks'; import { getLink } from '../../links'; @@ -31,24 +31,25 @@ import { SnitchDialog } from '..'; import './overlord-dynamic-config-dialog.scss'; export interface OverlordDynamicConfigDialogProps { - onClose: () => void; + onClose(): void; } export const OverlordDynamicConfigDialog = React.memo(function OverlordDynamicConfigDialog( props: OverlordDynamicConfigDialogProps, ) { const { onClose } = props; - const [dynamicConfig, setDynamicConfig] = useState({}); + const [dynamicConfig, setDynamicConfig] = useState(); const [historyRecordsState] = useQueryManager({ + initQuery: null, processQuery: async () => { const historyResp = await Api.instance.get(`/druid/indexer/v1/worker/history?count=100`); return historyResp.data; }, - initQuery: null, }); useQueryManager>({ + initQuery: null, processQuery: async () => { try { const configResp = await Api.instance.get(`/druid/indexer/v1/worker`); @@ -59,12 +60,10 @@ export const OverlordDynamicConfigDialog = React.memo(function OverlordDynamicCo intent: Intent.DANGER, message: `Could not load overlord dynamic config: ${getDruidErrorMessage(e)}`, }); - setDynamicConfig({}); onClose(); } return {}; }, - initQuery: null, }); async function saveConfig(comment: string) { @@ -98,20 +97,27 @@ export const OverlordDynamicConfigDialog = React.memo(function OverlordDynamicCo title="Overlord dynamic config" historyRecords={historyRecordsState.data} > -

- Edit the overlord dynamic configuration on the fly. For more information please refer to the{' '} - - documentation - - . -

- + {dynamicConfig ? ( + <> +

+ Edit the overlord dynamic configuration on the fly. For more information please refer to + the{' '} + + documentation + + . +

+ + + ) : ( + + )} ); }); diff --git a/web-console/src/utils/local-storage-keys.tsx b/web-console/src/utils/local-storage-keys.tsx index d218d4b18a7..81c8266bbde 100644 --- a/web-console/src/utils/local-storage-keys.tsx +++ b/web-console/src/utils/local-storage-keys.tsx @@ -40,7 +40,6 @@ export const LocalStorageKeys = { QUERY_KEY: 'druid-console-query' as const, QUERY_CONTEXT: 'query-context' as const, INGESTION_VIEW_PANE_SIZE: 'ingestion-view-pane-size' as const, - QUERY_VIEW_PANE_SIZE: 'query-view-pane-size' as const, TASKS_REFRESH_RATE: 'task-refresh-rate' as const, DATASOURCES_REFRESH_RATE: 'datasources-refresh-rate' as const, SEGMENTS_REFRESH_RATE: 'segments-refresh-rate' as const, diff --git a/web-console/src/views/index.ts b/web-console/src/views/index.ts index 7af1b655428..7a6fc865180 100644 --- a/web-console/src/views/index.ts +++ b/web-console/src/views/index.ts @@ -21,7 +21,6 @@ export * from './home-view/home-view'; export * from './ingestion-view/ingestion-view'; export * from './load-data-view/load-data-view'; export * from './lookups-view/lookups-view'; -export * from './query-view/query-view'; export * from './segments-view/segments-view'; export * from './services-view/services-view'; export * from './sql-data-loader-view/sql-data-loader-view'; diff --git a/web-console/src/views/ingestion-view/ingestion-view.tsx b/web-console/src/views/ingestion-view/ingestion-view.tsx index 06064a8ec49..e25d9be28de 100644 --- a/web-console/src/views/ingestion-view/ingestion-view.tsx +++ b/web-console/src/views/ingestion-view/ingestion-view.tsx @@ -921,7 +921,7 @@ ORDER BY if (value > 0) { return formatDuration(value); } - if (original.created_time) { + if (oneOf(original.status, 'RUNNING', 'PENDING') && original.created_time) { // Compute running duration from the created time if it exists return formatDuration(Date.now() - Date.parse(original.created_time)); } diff --git a/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap b/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap deleted file mode 100644 index 8a643462115..00000000000 --- a/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap +++ /dev/null @@ -1,163 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`QueryView matches snapshot 1`] = ` -
- = CURRENT_TIMESTAMP - INTERVAL '1' DAY"} - getParsedQuery={[Function]} - onQueryChange={[Function]} - /> - -
- -
- - - - - - -
-
-
- -
-
-
-`; - -exports[`QueryView matches snapshot with query 1`] = ` -
- = CURRENT_TIMESTAMP - INTERVAL '1' DAY"} - getParsedQuery={[Function]} - onQueryChange={[Function]} - /> - -
- -
- - - - - - -
-
-
- -
-
-
-`; diff --git a/web-console/src/views/query-view/live-query-mode-button/__snapshots__/live-query-mode-button.spec.tsx.snap b/web-console/src/views/query-view/live-query-mode-button/__snapshots__/live-query-mode-button.spec.tsx.snap deleted file mode 100644 index dab20a797f6..00000000000 --- a/web-console/src/views/query-view/live-query-mode-button/__snapshots__/live-query-mode-button.spec.tsx.snap +++ /dev/null @@ -1,153 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`LiveQueryModeButton matches snapshot auto 1`] = ` - - - - - - } - defaultIsOpen={false} - disabled={false} - fill={false} - hasBackdrop={false} - hoverCloseDelay={300} - hoverOpenDelay={150} - inheritDarkTheme={true} - interactionKind="click" - minimal={false} - openOnTargetFocus={true} - portalClassName="live-query-mode-button-portal" - position="bottom-left" - positioningStrategy="absolute" - shouldReturnFocusOnClose={false} - targetTagName="span" - transitionDuration={300} - usePortal={true} -> - - Live query: - - - Auto - - - -`; - -exports[`LiveQueryModeButton matches snapshot on 1`] = ` - - - - - - } - defaultIsOpen={false} - disabled={false} - fill={false} - hasBackdrop={false} - hoverCloseDelay={300} - hoverOpenDelay={150} - inheritDarkTheme={true} - interactionKind="click" - minimal={false} - openOnTargetFocus={true} - portalClassName="live-query-mode-button-portal" - position="bottom-left" - positioningStrategy="absolute" - shouldReturnFocusOnClose={false} - targetTagName="span" - transitionDuration={300} - usePortal={true} -> - - Live query: - - - On - - - -`; diff --git a/web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.scss b/web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.scss deleted file mode 100644 index b6c257a20ee..00000000000 --- a/web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.scss +++ /dev/null @@ -1,40 +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. - */ - -@import '../../../variables'; -@import '../../../blueprint-overrides/common/colors'; - -.live-query-mode-button { - .auto.auto-on { - color: $druid-brand; - } - - .on { - color: $druid-brand; - } -} - -.live-query-mode-button-portal { - .auto.auto-on .#{$bp-ns}-text-overflow-ellipsis { - color: $druid-brand; - } - - .on .#{$bp-ns}-text-overflow-ellipsis { - color: $druid-brand; - } -} diff --git a/web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.spec.tsx b/web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.spec.tsx deleted file mode 100644 index f49a5caaa5f..00000000000 --- a/web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.spec.tsx +++ /dev/null @@ -1,48 +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. - */ - -import { shallow } from 'enzyme'; -import React from 'react'; - -import { LiveQueryModeButton } from './live-query-mode-button'; - -describe('LiveQueryModeButton', () => { - it('matches snapshot on', () => { - const liveQueryModeSelector = shallow( - {}} - autoLiveQueryModeShouldRun - />, - ); - - expect(liveQueryModeSelector).toMatchSnapshot(); - }); - - it('matches snapshot auto', () => { - const liveQueryModeSelector = shallow( - {}} - autoLiveQueryModeShouldRun - />, - ); - - expect(liveQueryModeSelector).toMatchSnapshot(); - }); -}); diff --git a/web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.tsx b/web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.tsx deleted file mode 100644 index cae6f3a62de..00000000000 --- a/web-console/src/views/query-view/live-query-mode-button/live-query-mode-button.tsx +++ /dev/null @@ -1,80 +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. - */ - -import { Button, Menu, MenuItem, PopoverPosition } from '@blueprintjs/core'; -import { Popover2 } from '@blueprintjs/popover2'; -import classNames from 'classnames'; -import React from 'react'; - -import { tickIcon } from '../../../utils'; - -import './live-query-mode-button.scss'; - -export type LiveQueryMode = 'auto' | 'on' | 'off'; -export const LIVE_QUERY_MODES: LiveQueryMode[] = ['auto', 'on', 'off']; -export const LIVE_QUERY_MODE_TITLE: Record = { - auto: 'Auto', - on: 'On', - off: 'Off', -}; - -export interface LiveQueryModeButtonProps { - liveQueryMode: LiveQueryMode; - onLiveQueryModeChange(liveQueryMode: LiveQueryMode): void; - autoLiveQueryModeShouldRun: boolean; - minimal?: boolean; -} - -export const LiveQueryModeButton = React.memo(function LiveQueryModeButton( - props: LiveQueryModeButtonProps, -) { - const { liveQueryMode, onLiveQueryModeChange, autoLiveQueryModeShouldRun, minimal } = props; - - return ( - - {LIVE_QUERY_MODES.map(m => ( - onLiveQueryModeChange(m)} - /> - ))} - - } - > - - - ); -}); diff --git a/web-console/src/views/query-view/query-extra-info/__snapshots__/query-extra-info.spec.tsx.snap b/web-console/src/views/query-view/query-extra-info/__snapshots__/query-extra-info.spec.tsx.snap deleted file mode 100644 index 0c0bb065ee0..00000000000 --- a/web-console/src/views/query-view/query-extra-info/__snapshots__/query-extra-info.spec.tsx.snap +++ /dev/null @@ -1,51 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`QueryExtraInfo matches snapshot 1`] = ` -
-
- - - 0 results in 8.00s - - -
- - - -
-`; diff --git a/web-console/src/views/query-view/query-extra-info/query-extra-info.scss b/web-console/src/views/query-view/query-extra-info/query-extra-info.scss deleted file mode 100644 index 3b16a5d8e7d..00000000000 --- a/web-console/src/views/query-view/query-extra-info/query-extra-info.scss +++ /dev/null @@ -1,29 +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. - */ - -.query-extra-info { - & > * { - display: inline-block; - } - - .query-info { - line-height: 30px; - white-space: nowrap; - cursor: pointer; - } -} diff --git a/web-console/src/views/query-view/query-extra-info/query-extra-info.spec.tsx b/web-console/src/views/query-view/query-extra-info/query-extra-info.spec.tsx deleted file mode 100644 index 118c9cf5b78..00000000000 --- a/web-console/src/views/query-view/query-extra-info/query-extra-info.spec.tsx +++ /dev/null @@ -1,40 +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. - */ - -import { render } from '@testing-library/react'; -import { QueryResult } from 'druid-query-toolkit'; -import React from 'react'; - -import { QueryExtraInfo } from './query-extra-info'; - -describe('QueryExtraInfo', () => { - it('matches snapshot', () => { - const queryExtraInfo = ( - {}} - onLoadMore={() => {}} - /> - ); - - const { container } = render(queryExtraInfo); - expect(container.firstChild).toMatchSnapshot(); - }); -}); diff --git a/web-console/src/views/query-view/query-extra-info/query-extra-info.tsx b/web-console/src/views/query-view/query-extra-info/query-extra-info.tsx deleted file mode 100644 index ce3996685b1..00000000000 --- a/web-console/src/views/query-view/query-extra-info/query-extra-info.tsx +++ /dev/null @@ -1,108 +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. - */ - -import { Button, Intent, Menu, MenuDivider, MenuItem, Position } from '@blueprintjs/core'; -import { IconNames } from '@blueprintjs/icons'; -import { Popover2, Tooltip2 } from '@blueprintjs/popover2'; -import copy from 'copy-to-clipboard'; -import { QueryResult } from 'druid-query-toolkit'; -import React, { MouseEvent } from 'react'; - -import { AppToaster } from '../../../singletons'; -import { pluralIfNeeded } from '../../../utils'; - -import './query-extra-info.scss'; - -export interface QueryExtraInfoProps { - queryResult: QueryResult; - onDownload: (filename: string, format: string) => void; - onLoadMore: () => void; -} - -export const QueryExtraInfo = React.memo(function QueryExtraInfo(props: QueryExtraInfoProps) { - const { queryResult, onDownload, onLoadMore } = props; - const wrapQueryLimit = queryResult.getSqlOuterLimit(); - const hasMoreResults = queryResult.getNumResults() === wrapQueryLimit; - - function handleQueryInfoClick(e: MouseEvent) { - if (e.altKey) { - if (hasMoreResults) { - onLoadMore(); - } - } else { - const id = queryResult.queryId || queryResult.sqlQueryId; - if (!id) return; - - copy(id, { format: 'text/plain' }); - AppToaster.show({ - message: 'Query ID copied to clipboard', - intent: Intent.SUCCESS, - }); - } - } - - function handleDownload(format: string) { - const id = queryResult.queryId || queryResult.sqlQueryId; - if (!id) return; - - onDownload(`query-${id}.${format}`, format); - } - - const downloadMenu = ( - - - handleDownload('csv')} /> - handleDownload('tsv')} /> - handleDownload('json')} /> - - ); - - const resultCount = hasMoreResults - ? `${queryResult.getNumResults() - 1}+ results` - : pluralIfNeeded(queryResult.getNumResults(), 'result'); - - let tooltipContent: JSX.Element | undefined; - if (queryResult.queryId) { - tooltipContent = ( - <> - Query ID: {queryResult.queryId} (click to copy) - - ); - } else if (queryResult.sqlQueryId) { - tooltipContent = ( - <> - SQL query ID: {queryResult.sqlQueryId} (click to copy) - - ); - } - - return ( -
- {typeof queryResult.queryDuration !== 'undefined' && ( -
- - {`${resultCount} in ${(queryResult.queryDuration / 1000).toFixed(2)}s`} - -
- )} - -
- ); -}); diff --git a/web-console/src/views/query-view/query-history-dialog/__snapshots__/query-history-dialog.spec.tsx.snap b/web-console/src/views/query-view/query-history-dialog/__snapshots__/query-history-dialog.spec.tsx.snap deleted file mode 100644 index a833c85c1a5..00000000000 --- a/web-console/src/views/query-view/query-history-dialog/__snapshots__/query-history-dialog.spec.tsx.snap +++ /dev/null @@ -1,98 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`QueryHistoryDialog matches snapshot 1`] = ` -
-
-
-
-
- -
-
-
-
-`; diff --git a/web-console/src/views/query-view/query-history-dialog/query-history-dialog.scss b/web-console/src/views/query-view/query-history-dialog/query-history-dialog.scss deleted file mode 100644 index b18f74f8fdb..00000000000 --- a/web-console/src/views/query-view/query-history-dialog/query-history-dialog.scss +++ /dev/null @@ -1,39 +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. - */ - -@import '../../../variables'; - -.query-history-dialog { - &.#{$bp-ns}-dialog { - width: 900px; - } - - .panel { - width: 100%; - } - - .text-area { - width: 100%; - height: 500px; - resize: none; - } - - .center-message { - height: 400px; - } -} diff --git a/web-console/src/views/query-view/query-history-dialog/query-history-dialog.spec.tsx b/web-console/src/views/query-view/query-history-dialog/query-history-dialog.spec.tsx deleted file mode 100644 index e5cd42d74d1..00000000000 --- a/web-console/src/views/query-view/query-history-dialog/query-history-dialog.spec.tsx +++ /dev/null @@ -1,32 +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. - */ - -import { render } from '@testing-library/react'; -import React from 'react'; - -import { QueryHistoryDialog } from './query-history-dialog'; - -describe('QueryHistoryDialog', () => { - it('matches snapshot', () => { - const queryPlanDialog = ( - null} queryRecords={[]} onClose={() => {}} /> - ); - render(queryPlanDialog); - expect(document.body.lastChild).toMatchSnapshot(); - }); -}); diff --git a/web-console/src/views/query-view/query-history-dialog/query-history-dialog.tsx b/web-console/src/views/query-view/query-history-dialog/query-history-dialog.tsx deleted file mode 100644 index df7dbc8a080..00000000000 --- a/web-console/src/views/query-view/query-history-dialog/query-history-dialog.tsx +++ /dev/null @@ -1,88 +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. - */ - -import { Button, Classes, Dialog, Intent, Tab, Tabs, TextArea } from '@blueprintjs/core'; -import React, { useState } from 'react'; - -import { CenterMessage } from '../../../components'; -import { QueryRecord } from '../../../utils/query-history'; - -import './query-history-dialog.scss'; - -export interface QueryHistoryDialogProps { - queryRecords: readonly QueryRecord[]; - setQueryString: (queryString: string, queryContext: Record) => void; - onClose: () => void; -} - -export const QueryHistoryDialog = React.memo(function QueryHistoryDialog( - props: QueryHistoryDialogProps, -) { - const [activeTab, setActiveTab] = useState(0); - const { queryRecords, setQueryString, onClose } = props; - - function handleSelect() { - const queryRecord = queryRecords[activeTab]; - setQueryString(queryRecord.queryString, queryRecord.queryContext || {}); - onClose(); - } - - function renderContent(): JSX.Element { - if (!queryRecords.length) { - return The query history is empty.; - } - - const versions = queryRecords.map((record, index) => ( - } - panelClassName="panel" - /> - )); - - return ( - setActiveTab(t)} - > - {versions} - - - ); - } - - return ( - -
{renderContent()}
-
-
-
-
-
- ); -}); diff --git a/web-console/src/views/query-view/query-input/__snapshots__/query-input.spec.tsx.snap b/web-console/src/views/query-view/query-input/__snapshots__/query-input.spec.tsx.snap deleted file mode 100644 index d67f1bbcc81..00000000000 --- a/web-console/src/views/query-view/query-input/__snapshots__/query-input.spec.tsx.snap +++ /dev/null @@ -1,111 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`QueryInput correctly formats helper HTML 1`] = ` -" -
COUNT
-
COUNT(*)
-
Counts the number of things
" -`; - -exports[`QueryInput matches snapshot 1`] = ` -
-
-
-