From 51c73b5a4e3e5743986cf3f24401e8cd14b8169a Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Fri, 21 Jun 2024 18:33:15 -0700 Subject: [PATCH] Web console: show formatted JSON value (#16632) * show formatted json value * update snapshot * window functions * count star can also have a window * better edit query context --- licenses.yaml | 2 +- web-console/lib/keywords.js | 3 + web-console/package-lock.json | 14 +-- web-console/package.json | 2 +- .../record-table-pane/record-table-pane.tsx | 4 +- .../edit-context-dialog.spec.tsx.snap | 102 ++++++++++++++++-- .../edit-context-dialog.scss | 21 +--- .../edit-context-dialog.spec.tsx | 6 +- .../edit-context-dialog.tsx | 102 ++++++++---------- .../show-value-dialog.spec.tsx.snap | 90 +++++++++------- .../show-value-dialog/show-value-dialog.scss | 23 ++-- .../show-value-dialog/show-value-dialog.tsx | 62 +++++++++-- .../string-menu-items/string-menu-items.tsx | 2 +- .../result-table-pane/result-table-pane.tsx | 4 +- .../workbench-view/run-panel/run-panel.tsx | 2 +- 15 files changed, 282 insertions(+), 157 deletions(-) diff --git a/licenses.yaml b/licenses.yaml index 3c1f7b0b2d4..700dc891553 100644 --- a/licenses.yaml +++ b/licenses.yaml @@ -5094,7 +5094,7 @@ license_category: binary module: web-console license_name: Apache License version 2.0 copyright: Imply Data -version: 0.22.15 +version: 0.22.20 --- diff --git a/web-console/lib/keywords.js b/web-console/lib/keywords.js index bf7b9a03910..dbf10e12bac 100644 --- a/web-console/lib/keywords.js +++ b/web-console/lib/keywords.js @@ -47,6 +47,7 @@ exports.SQL_KEYWORDS = [ 'FULL', 'CROSS', 'USING', + 'NATURAL', 'FETCH', 'FIRST', 'NEXT', @@ -67,6 +68,8 @@ exports.SQL_KEYWORDS = [ 'RANGE', 'PRECEDING', 'FOLLOWING', + 'CURRENT', + 'UNBOUNDED', 'EXTEND', 'PIVOT', 'UNPIVOT', diff --git a/web-console/package-lock.json b/web-console/package-lock.json index 26999644f1e..2945955d9d6 100644 --- a/web-console/package-lock.json +++ b/web-console/package-lock.json @@ -15,7 +15,7 @@ "@blueprintjs/icons": "^4.16.0", "@blueprintjs/popover2": "^1.14.9", "@blueprintjs/select": "^4.9.24", - "@druid-toolkit/query": "^0.22.15", + "@druid-toolkit/query": "^0.22.20", "@druid-toolkit/visuals-core": "^0.3.3", "@druid-toolkit/visuals-react": "^0.3.3", "ace-builds": "~1.4.14", @@ -1005,9 +1005,9 @@ } }, "node_modules/@druid-toolkit/query": { - "version": "0.22.15", - "resolved": "https://registry.npmjs.org/@druid-toolkit/query/-/query-0.22.15.tgz", - "integrity": "sha512-LyQVIVkVNhduscf2wnBO/oGBvj353tS5ElIws20xQzApvEIwNNxmlkA+8npqwy77BkJj3nRQvlenbSEDHQdqow==", + "version": "0.22.20", + "resolved": "https://registry.npmjs.org/@druid-toolkit/query/-/query-0.22.20.tgz", + "integrity": "sha512-GmmSd27y7zLVTjgTBQy+XoGeSSGhSDNmwyiwWtSua7I5LX8XqHV7Chi8HIH25YQoVgTK1pLK4RS8eRXxthRAzg==", "dependencies": { "tslib": "^2.5.2" } @@ -19147,9 +19147,9 @@ "dev": true }, "@druid-toolkit/query": { - "version": "0.22.15", - "resolved": "https://registry.npmjs.org/@druid-toolkit/query/-/query-0.22.15.tgz", - "integrity": "sha512-LyQVIVkVNhduscf2wnBO/oGBvj353tS5ElIws20xQzApvEIwNNxmlkA+8npqwy77BkJj3nRQvlenbSEDHQdqow==", + "version": "0.22.20", + "resolved": "https://registry.npmjs.org/@druid-toolkit/query/-/query-0.22.20.tgz", + "integrity": "sha512-GmmSd27y7zLVTjgTBQy+XoGeSSGhSDNmwyiwWtSua7I5LX8XqHV7Chi8HIH25YQoVgTK1pLK4RS8eRXxthRAzg==", "requires": { "tslib": "^2.5.2" } diff --git a/web-console/package.json b/web-console/package.json index 44e6986c2bd..6e38ba24684 100644 --- a/web-console/package.json +++ b/web-console/package.json @@ -69,7 +69,7 @@ "@blueprintjs/icons": "^4.16.0", "@blueprintjs/popover2": "^1.14.9", "@blueprintjs/select": "^4.9.24", - "@druid-toolkit/query": "^0.22.15", + "@druid-toolkit/query": "^0.22.20", "@druid-toolkit/visuals-core": "^0.3.3", "@druid-toolkit/visuals-react": "^0.3.3", "ace-builds": "~1.4.14", diff --git a/web-console/src/components/record-table-pane/record-table-pane.tsx b/web-console/src/components/record-table-pane/record-table-pane.tsx index 29433b25ddc..6007559fb0d 100644 --- a/web-console/src/components/record-table-pane/record-table-pane.tsx +++ b/web-console/src/components/record-table-pane/record-table-pane.tsx @@ -174,7 +174,9 @@ export const RecordTablePane = React.memo(function RecordTablePane(props: Record })} /> )} - {showValue && setShowValue(undefined)} str={showValue} />} + {showValue && ( + setShowValue(undefined)} str={showValue} size="large" /> + )} ); }); diff --git a/web-console/src/dialogs/edit-context-dialog/__snapshots__/edit-context-dialog.spec.tsx.snap b/web-console/src/dialogs/edit-context-dialog/__snapshots__/edit-context-dialog.spec.tsx.snap index b9e2d072ea9..7a2ed054f3a 100644 --- a/web-console/src/dialogs/edit-context-dialog/__snapshots__/edit-context-dialog.spec.tsx.snap +++ b/web-console/src/dialogs/edit-context-dialog/__snapshots__/edit-context-dialog.spec.tsx.snap @@ -57,18 +57,102 @@ exports[`EditContextDialog matches snapshot 1`] = ` - diff --git a/web-console/src/dialogs/show-value-dialog/show-value-dialog.scss b/web-console/src/dialogs/show-value-dialog/show-value-dialog.scss index a1da01e5931..f561f1bf99f 100644 --- a/web-console/src/dialogs/show-value-dialog/show-value-dialog.scss +++ b/web-console/src/dialogs/show-value-dialog/show-value-dialog.scss @@ -19,10 +19,6 @@ @import '../../variables'; .show-value-dialog { - &.#{$bp-ns}-dialog { - padding-bottom: 10px; - } - &.normal.#{$bp-ns}-dialog { height: 600px; } @@ -32,12 +28,21 @@ height: 90vh; } - .#{$bp-ns}-input { - margin: 10px; - flex: 1; + .#{$bp-ns}-dialog-body { + display: flex; + flex-direction: column; + + .ace-editor { + flex: 1; + } + + .#{$bp-ns}-input { + flex: 1; + resize: none; + } } - .#{$bp-ns}-dialog-footer-actions { - padding-right: 10px; + .#{$bp-ns}-dialog-footer { + margin-top: 0; } } diff --git a/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx b/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx index 8e1b0290865..4369a43bb76 100644 --- a/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx +++ b/web-console/src/dialogs/show-value-dialog/show-value-dialog.tsx @@ -16,11 +16,21 @@ * limitations under the License. */ -import { Button, Classes, Dialog, Intent, TextArea } from '@blueprintjs/core'; +import { + Button, + ButtonGroup, + Classes, + Dialog, + FormGroup, + Intent, + TextArea, +} from '@blueprintjs/core'; import { IconNames } from '@blueprintjs/icons'; import classNames from 'classnames'; import copy from 'copy-to-clipboard'; -import React from 'react'; +import * as JSONBig from 'json-bigint-native'; +import React, { useMemo, useState } from 'react'; +import AceEditor from 'react-ace'; import { AppToaster } from '../../singletons'; @@ -35,6 +45,15 @@ export interface ShowValueDialogProps { export const ShowValueDialog = React.memo(function ShowValueDialog(props: ShowValueDialogProps) { const { title, onClose, str, size } = props; + const [tab, setTab] = useState<'formatted' | 'raw'>('formatted'); + + const parsed = useMemo(() => { + try { + return JSONBig.parse(str); + } catch {} + }, [str]); + + const hasParsed = typeof parsed !== 'undefined'; function handleCopy() { copy(str, { format: 'text/plain' }); @@ -51,10 +70,41 @@ export const ShowValueDialog = React.memo(function ShowValueDialog(props: ShowVa onClose={onClose} title={title || 'Full value'} > -