From 14ca9f9a8db0750a32135c4f571b2260a8c0ab33 Mon Sep 17 00:00:00 2001 From: astandrik Date: Tue, 17 Dec 2024 17:44:40 +0300 Subject: [PATCH 1/6] feat: display view query text --- package-lock.json | 280 +++++++++++++++++- package.json | 2 + playwright.config.ts | 1 + .../SqlHighlighter/SqlHighlighter.scss | 13 + .../SqlHighlighter/SqlHighlighter.tsx | 30 ++ src/components/SqlHighlighter/keywords.ts | 13 + src/components/SqlHighlighter/yql.ts | 159 ++++++++++ .../TruncatedQuery/TruncatedQuery.tsx | 12 +- src/containers/Tenant/Info/View/View.tsx | 8 +- .../tenant/queryHistory/queryHistory.test.ts | 4 +- 10 files changed, 509 insertions(+), 13 deletions(-) create mode 100644 src/components/SqlHighlighter/SqlHighlighter.scss create mode 100644 src/components/SqlHighlighter/SqlHighlighter.tsx create mode 100644 src/components/SqlHighlighter/keywords.ts create mode 100644 src/components/SqlHighlighter/yql.ts diff --git a/package-lock.json b/package-lock.json index d94e8fe30..8ffbeb629 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,6 +45,7 @@ "react-redux": "^9.1.2", "react-router-dom": "^5.3.4", "react-split": "^2.0.14", + "react-syntax-highlighter": "^15.6.1", "redux": "^5.0.1", "redux-location-state": "^2.8.2", "tslib": "^2.6.3", @@ -73,6 +74,7 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", + "@types/react-syntax-highlighter": "^15.5.13", "@types/uuid": "^10.0.0", "copyfiles": "^2.4.1", "http-proxy-middleware": "^2.0.6", @@ -6066,6 +6068,15 @@ "@types/node": "*" } }, + "node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, "node_modules/@types/history": { "version": "4.7.11", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", @@ -6263,6 +6274,16 @@ "@types/react-router": "*" } }, + "node_modules/@types/react-syntax-highlighter": { + "version": "15.5.13", + "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.13.tgz", + "integrity": "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -6324,6 +6345,12 @@ "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==", "dev": true }, + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, "node_modules/@types/use-sync-external-store": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", @@ -8189,6 +8216,36 @@ "node": ">=10" } }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/check-types": { "version": "11.2.2", "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz", @@ -8568,6 +8625,16 @@ "node": ">= 0.8" } }, + "node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -11883,6 +11950,19 @@ "reusify": "^1.0.4" } }, + "node_modules/fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/faye-websocket": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", @@ -12207,6 +12287,14 @@ "node": ">= 6" } }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -12770,6 +12858,33 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -12779,6 +12894,21 @@ "he": "bin/he" } }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/highlightjs-vue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz", + "integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==", + "license": "CC0-1.0" + }, "node_modules/history": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", @@ -13366,6 +13496,30 @@ "node": ">= 10" } }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-array-buffer": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", @@ -13497,6 +13651,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -13578,6 +13742,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", @@ -17439,6 +17613,20 @@ "tslib": "^2.0.3" } }, + "node_modules/lowlight": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "license": "MIT", + "dependencies": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -18586,6 +18774,24 @@ "node": ">=6" } }, + "node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -20295,6 +20501,15 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -20338,6 +20553,19 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -22262,6 +22490,23 @@ "prop-types": "^15.5.4" } }, + "node_modules/react-syntax-highlighter": { + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.1.tgz", + "integrity": "sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.3.1", + "highlight.js": "^10.4.1", + "highlightjs-vue": "^1.0.0", + "lowlight": "^1.17.0", + "prismjs": "^1.27.0", + "refractor": "^3.6.0" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -22556,6 +22801,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/refractor": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", + "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", + "license": "MIT", + "dependencies": { + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.27.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -23802,6 +24071,16 @@ "deprecated": "Please use @jridgewell/sourcemap-codec instead", "dev": true }, + "node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -26724,7 +27003,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, "engines": { "node": ">=0.4" } diff --git a/package.json b/package.json index b01e2d4d5..dc1ae9707 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "react-redux": "^9.1.2", "react-router-dom": "^5.3.4", "react-split": "^2.0.14", + "react-syntax-highlighter": "^15.6.1", "redux": "^5.0.1", "redux-location-state": "^2.8.2", "tslib": "^2.6.3", @@ -136,6 +137,7 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/react-router-dom": "^5.3.3", + "@types/react-syntax-highlighter": "^15.5.13", "@types/uuid": "^10.0.0", "copyfiles": "^2.4.1", "http-proxy-middleware": "^2.0.6", diff --git a/playwright.config.ts b/playwright.config.ts index 1c7995b30..4db02a1c3 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -19,6 +19,7 @@ const config: PlaywrightTestConfig = { : { command: 'npm run dev', port: 3000, + reuseExistingServer: true, }, use: { baseURL: baseUrl || 'http://localhost:3000/', diff --git a/src/components/SqlHighlighter/SqlHighlighter.scss b/src/components/SqlHighlighter/SqlHighlighter.scss new file mode 100644 index 000000000..bdde6c902 --- /dev/null +++ b/src/components/SqlHighlighter/SqlHighlighter.scss @@ -0,0 +1,13 @@ +.sql-highlighter { + code { + white-space: pre-wrap !important; + + color: var(--g-color-text-primary) !important; + } + + pre { + margin: 0 !important; + + background: transparent !important; + } +} diff --git a/src/components/SqlHighlighter/SqlHighlighter.tsx b/src/components/SqlHighlighter/SqlHighlighter.tsx new file mode 100644 index 000000000..e3705d5db --- /dev/null +++ b/src/components/SqlHighlighter/SqlHighlighter.tsx @@ -0,0 +1,30 @@ +import {useThemeValue} from '@gravity-ui/uikit'; +import {PrismLight as SyntaxHighlighter} from 'react-syntax-highlighter'; + +import {cn} from '../../utils/cn'; + +import {dark, light, yql} from './yql'; + +import './SqlHighlighter.scss'; + +SyntaxHighlighter.registerLanguage('yql', yql); + +const b = cn('sql-highlighter'); + +interface SqlHighlighterProps { + children: string; + className?: string; +} + +export const SqlHighlighter = ({children, className}: SqlHighlighterProps) => { + const themeValue = useThemeValue(); + const isDark = themeValue === 'dark' || themeValue === 'dark-hc'; + + return ( +
+ + {children} + +
+ ); +}; diff --git a/src/components/SqlHighlighter/keywords.ts b/src/components/SqlHighlighter/keywords.ts new file mode 100644 index 000000000..b20bc2da0 --- /dev/null +++ b/src/components/SqlHighlighter/keywords.ts @@ -0,0 +1,13 @@ +export const keywords = + '$row|$rows|action|add|all|alter|and|any|as|asc|assume|async|bigserial|serial|smallserial|serial8|serial4|serial2|begin|bernoulli|between|by|case|changefeed|column|columns|commit|compact|create|cross|cube|declare|define|delete|desc|dict|discard|distinct|do|drop|else|empty_action|end|erase|evaluate|exclusion|exists|export|family|flatten|for|from|full|global|group|grouping|having|if|ignore|ilike|import|in|index|inner|insert|into|is|join|key|left|like|limit|list|match|not|null|nulls|offset|on|only|optional|or|order|over|partition|pragma|presort|primary|process|reduce|regexp|repeatable|replace|respect|result|return|right|rlike|rollup|sample|schema|select|semi|set|sets|stream|subquery|sync|table|tablesample|then|truncate|union|intersect|except|update|upsert|use|using|values|view|when|where|window|with|without|xor|callable|resource|tagged|generic|unit|void|emptylist|emptydict|flow|callable|resource|tagged|generic|unit|void|emptylist|emptydict|flow'.split( + '|', + ); +export const typeKeywords = + 'bool|date|datetime|decimal|double|float|int16|int32|int64|int8|interval|json|jsondocument|string|timestamp|tzdate|tzdatetime|tztimestamp|uint16|uint32|uint64|uint8|utf8|uuid|yson|text|bytes'.split( + '|', + ); + +export const builtinFunctions = + 'abs|aggregate_by|aggregate_list|aggregate_list_distinct|agg_list|agg_list_distinct|as_table|avg|avg_if|adaptivedistancehistogram|adaptivewardhistogram|adaptiveweighthistogram|addmember|addtimezone|aggregateflatten|aggregatetransforminput|aggregatetransformoutput|aggregationfactory|asatom|asdict|asdictstrict|asenum|aslist|asliststrict|asset|assetstrict|asstruct|astagged|astuple|asvariant|atomcode|bitcast|bit_and|bit_or|bit_xor|bool_and|bool_or|bool_xor|bottom|bottom_by|blockwardhistogram|blockweighthistogram|cast|coalesce|concat|concat_strict|correlation|count|count_if|covariance|covariance_population|covariance_sample|callableargument|callableargumenttype|callableresulttype|callabletype|callabletypecomponents|callabletypehandle|choosemembers|combinemembers|countdistinctestimate|currentauthenticateduser|currentoperationid|currentoperationsharedid|currenttzdate|currenttzdatetime|currenttztimestamp|currentutcdate|currentutcdatetime|currentutctimestamp|dense_rank|datatype|datatypecomponents|datatypehandle|dictaggregate|dictcontains|dictcreate|dicthasitems|dictitems|dictkeytype|dictkeys|dictlength|dictlookup|dictpayloadtype|dictpayloads|dicttype|dicttypecomponents|dicttypehandle|each|each_strict|emptydicttype|emptydicttypehandle|emptylisttype|emptylisttypehandle|endswith|ensure|ensureconvertibleto|ensuretype|enum|evaluateatom|evaluatecode|evaluateexpr|evaluatetype|expandstruct|filter|filter_strict|find|first_value|folder|filecontent|filepath|flattenmembers|forceremovemember|forceremovemembers|forcerenamemembers|forcespreadmembers|formatcode|formattype|frombytes|frompg|funccode|greatest|grouping|gathermembers|generictype|histogram|hll|hoppingwindowpgcast|hyperloglog|if|if_strict|instanceof|json_exists|json_query|json_value|jointablerow|just|lag|last_value|lead|least|len|length|like|likely|like_strict|lambdaargumentscount|lambdacode|lambdaoptionalargumentscount|linearhistogram|listaggregate|listall|listany|listavg|listcode|listcollect|listconcat|listcreate|listdistinct|listenumerate|listextend|listextendstrict|listextract|listfilter|listflatmap|listflatten|listfold|listfold1|listfold1map|listfoldmap|listfromrange|listfromtuple|listhas|listhasitems|listhead|listindexof|listitemtype|listlast|listlength|listmap|listmax|listmin|listnotnull|listreplicate|listreverse|listskip|listskipwhile|listskipwhileinclusive|listsort|listsortasc|listsortdesc|listsum|listtake|listtakewhile|listtakewhileinclusive|listtop|listtopsort|listtopasc|listtopdesc|listtopsortasc|listtopsortdesc|listtotuple|listtype|listtypehandle|listunionall|listuniq|listzip|listzipall|loghistogram|logarithmichistogram|max|max_by|max_of|median|min|min_by|min_of|mode|multi_aggregate_by|nanvl|nvl|nothing|nulltype|nulltypehandle|optionalitemtype|optionaltype|optionaltypehandle|percentile|parsefile|parsetype|parsetypehandle|pgand|pgarray|pgcall|pgconst|pgnot|pgop|pgor|pickle|quotecode|range|range_strict|rank|regexp|regexp_strict|rfind|row_number|random|randomnumber|randomuuid|removemember|removemembers|removetimezone|renamemembers|replacemember|reprcode|resourcetype|resourcetypehandle|resourcetypetag|some|stddev|stddev_population|stddev_sample|substring|sum|sum_if|sessionstart|sessionwindow|setcreate|setdifference|setincludes|setintersection|setisdisjoint|setsymmetricdifference|setunion|spreadmembers|stablepickle|startswith|staticmap|staticzip|streamitemtype|streamtype|streamtypehandle|structmembertype|structmembers|structtypecomponents|structtypehandle|subqueryextend|subqueryextendfor|subquerymerge|subquerymergefor|subqueryunionall|subqueryunionallfor|subqueryunionmerge|subqueryunionmergefor|top|topfreq|top_by|tablename|tablepath|tablerecordindex|tablerow|tablerows|taggedtype|taggedtypecomponents|taggedtypehandle|tobytes|todict|tomultidict|topg|toset|tosorteddict|tosortedmultidict|trymember|tupleelementtype|tupletype|tupletypecomponents|tupletypehandle|typehandle|typekind|typeof|udaf|udf|unittype|unpickle|untag|unwrap|variance|variance_population|variance_sample|variant|varianttype|varianttypehandle|variantunderlyingtype|voidtype|voidtypehandle|way|worldcode|weakfield'.split( + '|', + ); diff --git a/src/components/SqlHighlighter/yql.ts b/src/components/SqlHighlighter/yql.ts new file mode 100644 index 000000000..93bbb0789 --- /dev/null +++ b/src/components/SqlHighlighter/yql.ts @@ -0,0 +1,159 @@ +import { + vscDarkPlus as darkTheme, + materialLight as lightTheme, +} from 'react-syntax-highlighter/dist/esm/styles/prism'; + +import {builtinFunctions, keywords, typeKeywords} from './keywords'; + +export const light = { + ...lightTheme, + 'pre[class*="language-"]': { + ...lightTheme['pre[class*="language-"]'], + background: 'transparent', + }, + 'code[class*="language-"]': { + ...lightTheme['code[class*="language-"]'], + background: 'transparent', + }, + comment: { + color: '#969896', + }, + string: { + color: '#a31515', + }, + tablepath: { + color: '#338186', + }, + function: { + color: '#7a3e9d', + }, + udf: { + color: '#7a3e9d', + }, + type: { + color: '#4d932d', + }, + boolean: { + color: '#608b4e', + }, + constant: { + color: '#608b4e', + }, + variable: { + color: '#001188', + }, +}; + +export const dark = { + ...darkTheme, + 'pre[class*="language-"]': { + ...darkTheme['pre[class*="language-"]'], + background: 'transparent', + }, + 'code[class*="language-"]': { + ...darkTheme['code[class*="language-"]'], + background: 'transparent', + }, + comment: { + color: '#969896', + }, + string: { + color: '#ce9178', + }, + tablepath: { + color: '#338186', + }, + function: { + color: '#9e7bb0', + }, + udf: { + color: '#9e7bb0', + }, + type: { + color: '#6A8759', + }, + boolean: { + color: '#608b4e', + }, + constant: { + color: '#608b4e', + }, + variable: { + color: '#74b0df', + }, +}; + +export function yql(Prism: any) { + // Define YQL language + Prism.languages.yql = { + comment: [ + { + pattern: /--.*$/m, + greedy: true, + }, + { + pattern: /\/\*[\s\S]*?(?:\*\/|$)/, + greedy: true, + }, + ], + tablepath: { + pattern: /(`[\w/]+`\s*\.\s*)?`[^`]+`/, + greedy: true, + }, + string: [ + { + pattern: /'(?:\\[\s\S]|[^\\'])*'/, + greedy: true, + }, + { + pattern: /"(?:\\[\s\S]|[^\\"])*"/, + greedy: true, + }, + { + pattern: /@@(?:[^@]|@(?!@))*@@/, + greedy: true, + }, + ], + variable: [ + { + pattern: /\$[a-zA-Z_]\w*/, + greedy: true, + }, + ], + function: { + pattern: new RegExp(`\\b(?:${builtinFunctions.join('|')})\\b`, 'i'), + greedy: true, + }, + keyword: { + pattern: new RegExp(`\\b(?:${keywords.join('|')})\\b`, 'i'), + greedy: true, + }, + udf: { + pattern: /[A-Za-z_]\w*::[A-Za-z_]\w*/, + greedy: true, + }, + type: { + pattern: new RegExp(`\\b(?:${typeKeywords.join('|')})\\b`, 'i'), + greedy: true, + }, + boolean: { + pattern: /\b(?:true|false|null)\b/i, + greedy: true, + }, + number: { + pattern: /[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/i, + greedy: true, + }, + operator: { + pattern: /[-+*/%<>!=&|^~]+|\b(?:and|or|not|is|like|ilike|rlike|in|between)\b/i, + greedy: true, + }, + punctuation: { + pattern: /[;[\](){}.,]/, + greedy: true, + }, + }; +} + +yql.displayName = 'yql'; +yql.aliases = ['yql'] as string[]; diff --git a/src/components/TruncatedQuery/TruncatedQuery.tsx b/src/components/TruncatedQuery/TruncatedQuery.tsx index 60ff1593a..c0453ca0b 100644 --- a/src/components/TruncatedQuery/TruncatedQuery.tsx +++ b/src/components/TruncatedQuery/TruncatedQuery.tsx @@ -2,6 +2,7 @@ import React from 'react'; import {cn} from '../../utils/cn'; import {CellWithPopover} from '../CellWithPopover/CellWithPopover'; +import {SqlHighlighter} from '../SqlHighlighter/SqlHighlighter'; import './TruncatedQuery.scss'; @@ -22,12 +23,12 @@ export const TruncatedQuery = ({value = '', maxQueryHeight = 6}: TruncatedQueryP '\n...\nThe request was truncated. Click on the line to show the full query on the query tab'; return ( - {content} + {content} {message} ); } - return {value}; + return {value}; }; interface OneLineQueryWithPopoverProps { @@ -36,8 +37,11 @@ interface OneLineQueryWithPopoverProps { export const OneLineQueryWithPopover = ({value = ''}: OneLineQueryWithPopoverProps) => { return ( - - {value} + {value}} + > + {value} ); }; diff --git a/src/containers/Tenant/Info/View/View.tsx b/src/containers/Tenant/Info/View/View.tsx index 795a13d47..910b26f9b 100644 --- a/src/containers/Tenant/Info/View/View.tsx +++ b/src/containers/Tenant/Info/View/View.tsx @@ -1,6 +1,6 @@ import type {DefinitionListItem} from '@gravity-ui/components'; -import {Text} from '@gravity-ui/uikit'; +import {SqlHighlighter} from '../../../../components/SqlHighlighter/SqlHighlighter'; import {YDBDefinitionList} from '../../../../components/YDBDefinitionList/YDBDefinitionList'; import type {TEvDescribeSchemeResult} from '../../../../types/api/schema'; import {getEntityName} from '../../utils'; @@ -13,11 +13,7 @@ const prepareViewItems = (data: TEvDescribeSchemeResult): DefinitionListItem[] = { name: i18n('view.query-text'), copyText: queryText, - content: ( - - {queryText} - - ), + content: queryText ? {queryText} : null, }, ]; }; diff --git a/tests/suites/tenant/queryHistory/queryHistory.test.ts b/tests/suites/tenant/queryHistory/queryHistory.test.ts index 7e08853a3..a42d4fe53 100644 --- a/tests/suites/tenant/queryHistory/queryHistory.test.ts +++ b/tests/suites/tenant/queryHistory/queryHistory.test.ts @@ -34,7 +34,7 @@ test.describe('Query History', () => { // Check if the query appears in the history const historyTable = page.locator('.ydb-queries-history table'); - await expect(historyTable.locator(`text="${testQuery}"`)).toBeVisible({ + await expect(historyTable.locator('.sql-highlighter', {hasText: testQuery})).toBeVisible({ timeout: VISIBILITY_TIMEOUT, }); }); @@ -85,6 +85,6 @@ test.describe('Query History', () => { // Check if the query appears in the history const historyTable = page.locator('.ydb-queries-history table'); - await expect(historyTable.locator(`text="${testQuery}"`)).toBeVisible(); + await expect(historyTable.locator('.sql-highlighter', {hasText: testQuery})).toBeVisible(); }); }); From 9fbcecf8a1529091f39e82c45a4621a80411f70c Mon Sep 17 00:00:00 2001 From: astandrik Date: Mon, 23 Dec 2024 16:28:29 +0300 Subject: [PATCH 2/6] fix: import keywords --- package-lock.json | 9 +++++---- package.json | 2 +- src/components/SqlHighlighter/keywords.ts | 13 ------------- src/components/SqlHighlighter/yql.ts | 7 +++++-- 4 files changed, 11 insertions(+), 20 deletions(-) delete mode 100644 src/components/SqlHighlighter/keywords.ts diff --git a/package-lock.json b/package-lock.json index 8ffbeb629..cebde4049 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,7 +83,7 @@ "lint-staged": "^15.2.7", "mini-css-extract-plugin": "^2.9.1", "monaco-editor-webpack-plugin": "^7.1.0", - "monaco-yql-languages": "^1.0.6", + "monaco-yql-languages": "^1.2.1", "npm-run-all": "^4.1.5", "postcss": "^8.4.38", "prettier": "^3.2.5", @@ -18020,10 +18020,11 @@ } }, "node_modules/monaco-yql-languages": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/monaco-yql-languages/-/monaco-yql-languages-1.0.6.tgz", - "integrity": "sha512-s1WcPg0kRmC4nWsXl01tvkxnox1xR3U05PYA6rGNTji/9LiBcLipZNj7UFdO+h39QeBnv8KfRYocLGsz/pia8w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/monaco-yql-languages/-/monaco-yql-languages-1.2.1.tgz", + "integrity": "sha512-mIV1i8jvpLm6IF89gHuN81x6a0UY8gXAYbfT7d7267TD9mAaxvHrFsFMTK0yz7e5vHtZ3nz34FhPDSbwAEMCvg==", "dev": true, + "license": "MIT", "peerDependencies": { "monaco-editor": ">=0.27.0" } diff --git a/package.json b/package.json index dc1ae9707..f0ce050be 100644 --- a/package.json +++ b/package.json @@ -146,7 +146,7 @@ "lint-staged": "^15.2.7", "mini-css-extract-plugin": "^2.9.1", "monaco-editor-webpack-plugin": "^7.1.0", - "monaco-yql-languages": "^1.0.6", + "monaco-yql-languages": "^1.2.1", "npm-run-all": "^4.1.5", "postcss": "^8.4.38", "prettier": "^3.2.5", diff --git a/src/components/SqlHighlighter/keywords.ts b/src/components/SqlHighlighter/keywords.ts deleted file mode 100644 index b20bc2da0..000000000 --- a/src/components/SqlHighlighter/keywords.ts +++ /dev/null @@ -1,13 +0,0 @@ -export const keywords = - '$row|$rows|action|add|all|alter|and|any|as|asc|assume|async|bigserial|serial|smallserial|serial8|serial4|serial2|begin|bernoulli|between|by|case|changefeed|column|columns|commit|compact|create|cross|cube|declare|define|delete|desc|dict|discard|distinct|do|drop|else|empty_action|end|erase|evaluate|exclusion|exists|export|family|flatten|for|from|full|global|group|grouping|having|if|ignore|ilike|import|in|index|inner|insert|into|is|join|key|left|like|limit|list|match|not|null|nulls|offset|on|only|optional|or|order|over|partition|pragma|presort|primary|process|reduce|regexp|repeatable|replace|respect|result|return|right|rlike|rollup|sample|schema|select|semi|set|sets|stream|subquery|sync|table|tablesample|then|truncate|union|intersect|except|update|upsert|use|using|values|view|when|where|window|with|without|xor|callable|resource|tagged|generic|unit|void|emptylist|emptydict|flow|callable|resource|tagged|generic|unit|void|emptylist|emptydict|flow'.split( - '|', - ); -export const typeKeywords = - 'bool|date|datetime|decimal|double|float|int16|int32|int64|int8|interval|json|jsondocument|string|timestamp|tzdate|tzdatetime|tztimestamp|uint16|uint32|uint64|uint8|utf8|uuid|yson|text|bytes'.split( - '|', - ); - -export const builtinFunctions = - 'abs|aggregate_by|aggregate_list|aggregate_list_distinct|agg_list|agg_list_distinct|as_table|avg|avg_if|adaptivedistancehistogram|adaptivewardhistogram|adaptiveweighthistogram|addmember|addtimezone|aggregateflatten|aggregatetransforminput|aggregatetransformoutput|aggregationfactory|asatom|asdict|asdictstrict|asenum|aslist|asliststrict|asset|assetstrict|asstruct|astagged|astuple|asvariant|atomcode|bitcast|bit_and|bit_or|bit_xor|bool_and|bool_or|bool_xor|bottom|bottom_by|blockwardhistogram|blockweighthistogram|cast|coalesce|concat|concat_strict|correlation|count|count_if|covariance|covariance_population|covariance_sample|callableargument|callableargumenttype|callableresulttype|callabletype|callabletypecomponents|callabletypehandle|choosemembers|combinemembers|countdistinctestimate|currentauthenticateduser|currentoperationid|currentoperationsharedid|currenttzdate|currenttzdatetime|currenttztimestamp|currentutcdate|currentutcdatetime|currentutctimestamp|dense_rank|datatype|datatypecomponents|datatypehandle|dictaggregate|dictcontains|dictcreate|dicthasitems|dictitems|dictkeytype|dictkeys|dictlength|dictlookup|dictpayloadtype|dictpayloads|dicttype|dicttypecomponents|dicttypehandle|each|each_strict|emptydicttype|emptydicttypehandle|emptylisttype|emptylisttypehandle|endswith|ensure|ensureconvertibleto|ensuretype|enum|evaluateatom|evaluatecode|evaluateexpr|evaluatetype|expandstruct|filter|filter_strict|find|first_value|folder|filecontent|filepath|flattenmembers|forceremovemember|forceremovemembers|forcerenamemembers|forcespreadmembers|formatcode|formattype|frombytes|frompg|funccode|greatest|grouping|gathermembers|generictype|histogram|hll|hoppingwindowpgcast|hyperloglog|if|if_strict|instanceof|json_exists|json_query|json_value|jointablerow|just|lag|last_value|lead|least|len|length|like|likely|like_strict|lambdaargumentscount|lambdacode|lambdaoptionalargumentscount|linearhistogram|listaggregate|listall|listany|listavg|listcode|listcollect|listconcat|listcreate|listdistinct|listenumerate|listextend|listextendstrict|listextract|listfilter|listflatmap|listflatten|listfold|listfold1|listfold1map|listfoldmap|listfromrange|listfromtuple|listhas|listhasitems|listhead|listindexof|listitemtype|listlast|listlength|listmap|listmax|listmin|listnotnull|listreplicate|listreverse|listskip|listskipwhile|listskipwhileinclusive|listsort|listsortasc|listsortdesc|listsum|listtake|listtakewhile|listtakewhileinclusive|listtop|listtopsort|listtopasc|listtopdesc|listtopsortasc|listtopsortdesc|listtotuple|listtype|listtypehandle|listunionall|listuniq|listzip|listzipall|loghistogram|logarithmichistogram|max|max_by|max_of|median|min|min_by|min_of|mode|multi_aggregate_by|nanvl|nvl|nothing|nulltype|nulltypehandle|optionalitemtype|optionaltype|optionaltypehandle|percentile|parsefile|parsetype|parsetypehandle|pgand|pgarray|pgcall|pgconst|pgnot|pgop|pgor|pickle|quotecode|range|range_strict|rank|regexp|regexp_strict|rfind|row_number|random|randomnumber|randomuuid|removemember|removemembers|removetimezone|renamemembers|replacemember|reprcode|resourcetype|resourcetypehandle|resourcetypetag|some|stddev|stddev_population|stddev_sample|substring|sum|sum_if|sessionstart|sessionwindow|setcreate|setdifference|setincludes|setintersection|setisdisjoint|setsymmetricdifference|setunion|spreadmembers|stablepickle|startswith|staticmap|staticzip|streamitemtype|streamtype|streamtypehandle|structmembertype|structmembers|structtypecomponents|structtypehandle|subqueryextend|subqueryextendfor|subquerymerge|subquerymergefor|subqueryunionall|subqueryunionallfor|subqueryunionmerge|subqueryunionmergefor|top|topfreq|top_by|tablename|tablepath|tablerecordindex|tablerow|tablerows|taggedtype|taggedtypecomponents|taggedtypehandle|tobytes|todict|tomultidict|topg|toset|tosorteddict|tosortedmultidict|trymember|tupleelementtype|tupletype|tupletypecomponents|tupletypehandle|typehandle|typekind|typeof|udaf|udf|unittype|unpickle|untag|unwrap|variance|variance_population|variance_sample|variant|varianttype|varianttypehandle|variantunderlyingtype|voidtype|voidtypehandle|way|worldcode|weakfield'.split( - '|', - ); diff --git a/src/components/SqlHighlighter/yql.ts b/src/components/SqlHighlighter/yql.ts index 93bbb0789..afb26c843 100644 --- a/src/components/SqlHighlighter/yql.ts +++ b/src/components/SqlHighlighter/yql.ts @@ -1,10 +1,13 @@ +import { + builtinFunctions, + keywords, + typeKeywords, +} from 'monaco-yql-languages/build/yql/yql.keywords'; import { vscDarkPlus as darkTheme, materialLight as lightTheme, } from 'react-syntax-highlighter/dist/esm/styles/prism'; -import {builtinFunctions, keywords, typeKeywords} from './keywords'; - export const light = { ...lightTheme, 'pre[class*="language-"]': { From b5e9b9009e9cfecf4486b577863691b7d9388cf4 Mon Sep 17 00:00:00 2001 From: astandrik Date: Mon, 23 Dec 2024 16:34:22 +0300 Subject: [PATCH 3/6] fix: rename --- src/components/TruncatedQuery/TruncatedQuery.tsx | 10 +++++----- .../YqlHighlighter.scss} | 2 +- .../YqlHighlighter.tsx} | 8 ++++---- .../{SqlHighlighter => YqlHighlighter}/yql.ts | 0 src/containers/Tenant/Info/View/View.tsx | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) rename src/components/{SqlHighlighter/SqlHighlighter.scss => YqlHighlighter/YqlHighlighter.scss} (91%) rename src/components/{SqlHighlighter/SqlHighlighter.tsx => YqlHighlighter/YqlHighlighter.tsx} (80%) rename src/components/{SqlHighlighter => YqlHighlighter}/yql.ts (100%) diff --git a/src/components/TruncatedQuery/TruncatedQuery.tsx b/src/components/TruncatedQuery/TruncatedQuery.tsx index c0453ca0b..02a9cb07a 100644 --- a/src/components/TruncatedQuery/TruncatedQuery.tsx +++ b/src/components/TruncatedQuery/TruncatedQuery.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {cn} from '../../utils/cn'; import {CellWithPopover} from '../CellWithPopover/CellWithPopover'; -import {SqlHighlighter} from '../SqlHighlighter/SqlHighlighter'; +import {YqlHighlighter} from '../YqlHighlighter/YqlHighlighter'; import './TruncatedQuery.scss'; @@ -23,12 +23,12 @@ export const TruncatedQuery = ({value = '', maxQueryHeight = 6}: TruncatedQueryP '\n...\nThe request was truncated. Click on the line to show the full query on the query tab'; return ( - {content} + {content} {message} ); } - return {value}; + return {value}; }; interface OneLineQueryWithPopoverProps { @@ -39,9 +39,9 @@ export const OneLineQueryWithPopover = ({value = ''}: OneLineQueryWithPopoverPro return ( {value}} + content={{value}} > - {value} + {value} ); }; diff --git a/src/components/SqlHighlighter/SqlHighlighter.scss b/src/components/YqlHighlighter/YqlHighlighter.scss similarity index 91% rename from src/components/SqlHighlighter/SqlHighlighter.scss rename to src/components/YqlHighlighter/YqlHighlighter.scss index bdde6c902..f91084da7 100644 --- a/src/components/SqlHighlighter/SqlHighlighter.scss +++ b/src/components/YqlHighlighter/YqlHighlighter.scss @@ -1,4 +1,4 @@ -.sql-highlighter { +.yql-highlighter { code { white-space: pre-wrap !important; diff --git a/src/components/SqlHighlighter/SqlHighlighter.tsx b/src/components/YqlHighlighter/YqlHighlighter.tsx similarity index 80% rename from src/components/SqlHighlighter/SqlHighlighter.tsx rename to src/components/YqlHighlighter/YqlHighlighter.tsx index e3705d5db..40fad9e71 100644 --- a/src/components/SqlHighlighter/SqlHighlighter.tsx +++ b/src/components/YqlHighlighter/YqlHighlighter.tsx @@ -5,18 +5,18 @@ import {cn} from '../../utils/cn'; import {dark, light, yql} from './yql'; -import './SqlHighlighter.scss'; +import './YqlHighlighter.scss'; SyntaxHighlighter.registerLanguage('yql', yql); -const b = cn('sql-highlighter'); +const b = cn('yql-highlighter'); -interface SqlHighlighterProps { +interface YqlHighlighterProps { children: string; className?: string; } -export const SqlHighlighter = ({children, className}: SqlHighlighterProps) => { +export const YqlHighlighter = ({children, className}: YqlHighlighterProps) => { const themeValue = useThemeValue(); const isDark = themeValue === 'dark' || themeValue === 'dark-hc'; diff --git a/src/components/SqlHighlighter/yql.ts b/src/components/YqlHighlighter/yql.ts similarity index 100% rename from src/components/SqlHighlighter/yql.ts rename to src/components/YqlHighlighter/yql.ts diff --git a/src/containers/Tenant/Info/View/View.tsx b/src/containers/Tenant/Info/View/View.tsx index 910b26f9b..14cc06d3e 100644 --- a/src/containers/Tenant/Info/View/View.tsx +++ b/src/containers/Tenant/Info/View/View.tsx @@ -1,7 +1,7 @@ import type {DefinitionListItem} from '@gravity-ui/components'; -import {SqlHighlighter} from '../../../../components/SqlHighlighter/SqlHighlighter'; import {YDBDefinitionList} from '../../../../components/YDBDefinitionList/YDBDefinitionList'; +import {YqlHighlighter} from '../../../../components/YqlHighlighter/YqlHighlighter'; import type {TEvDescribeSchemeResult} from '../../../../types/api/schema'; import {getEntityName} from '../../utils'; import i18n from '../i18n'; @@ -13,7 +13,7 @@ const prepareViewItems = (data: TEvDescribeSchemeResult): DefinitionListItem[] = { name: i18n('view.query-text'), copyText: queryText, - content: queryText ? {queryText} : null, + content: queryText ? {queryText} : null, }, ]; }; From eb089ce38274f8a5de1f17d72fe26bbc686ffad4 Mon Sep 17 00:00:00 2001 From: astandrik Date: Mon, 23 Dec 2024 16:44:05 +0300 Subject: [PATCH 4/6] fix: remove important --- src/components/YqlHighlighter/YqlHighlighter.scss | 2 -- src/components/YqlHighlighter/yql.ts | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/YqlHighlighter/YqlHighlighter.scss b/src/components/YqlHighlighter/YqlHighlighter.scss index f91084da7..d08a242ab 100644 --- a/src/components/YqlHighlighter/YqlHighlighter.scss +++ b/src/components/YqlHighlighter/YqlHighlighter.scss @@ -1,8 +1,6 @@ .yql-highlighter { code { white-space: pre-wrap !important; - - color: var(--g-color-text-primary) !important; } pre { diff --git a/src/components/YqlHighlighter/yql.ts b/src/components/YqlHighlighter/yql.ts index afb26c843..c9398bcef 100644 --- a/src/components/YqlHighlighter/yql.ts +++ b/src/components/YqlHighlighter/yql.ts @@ -17,6 +17,7 @@ export const light = { 'code[class*="language-"]': { ...lightTheme['code[class*="language-"]'], background: 'transparent', + color: 'var(--g-color-text-primary)', }, comment: { color: '#969896', @@ -56,6 +57,7 @@ export const dark = { 'code[class*="language-"]': { ...darkTheme['code[class*="language-"]'], background: 'transparent', + color: 'var(--g-color-text-primary)', }, comment: { color: '#969896', From b5c1aee5e2613b6b263b6f55979163ab234deef1 Mon Sep 17 00:00:00 2001 From: astandrik Date: Mon, 23 Dec 2024 16:48:31 +0300 Subject: [PATCH 5/6] fix: inline styles instead of scss --- src/components/YqlHighlighter/YqlHighlighter.scss | 11 ----------- src/components/YqlHighlighter/YqlHighlighter.tsx | 8 +------- src/components/YqlHighlighter/yql.ts | 4 ++++ 3 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 src/components/YqlHighlighter/YqlHighlighter.scss diff --git a/src/components/YqlHighlighter/YqlHighlighter.scss b/src/components/YqlHighlighter/YqlHighlighter.scss deleted file mode 100644 index d08a242ab..000000000 --- a/src/components/YqlHighlighter/YqlHighlighter.scss +++ /dev/null @@ -1,11 +0,0 @@ -.yql-highlighter { - code { - white-space: pre-wrap !important; - } - - pre { - margin: 0 !important; - - background: transparent !important; - } -} diff --git a/src/components/YqlHighlighter/YqlHighlighter.tsx b/src/components/YqlHighlighter/YqlHighlighter.tsx index 40fad9e71..94838108c 100644 --- a/src/components/YqlHighlighter/YqlHighlighter.tsx +++ b/src/components/YqlHighlighter/YqlHighlighter.tsx @@ -1,16 +1,10 @@ import {useThemeValue} from '@gravity-ui/uikit'; import {PrismLight as SyntaxHighlighter} from 'react-syntax-highlighter'; -import {cn} from '../../utils/cn'; - import {dark, light, yql} from './yql'; -import './YqlHighlighter.scss'; - SyntaxHighlighter.registerLanguage('yql', yql); -const b = cn('yql-highlighter'); - interface YqlHighlighterProps { children: string; className?: string; @@ -21,7 +15,7 @@ export const YqlHighlighter = ({children, className}: YqlHighlighterProps) => { const isDark = themeValue === 'dark' || themeValue === 'dark-hc'; return ( -
+
{children} diff --git a/src/components/YqlHighlighter/yql.ts b/src/components/YqlHighlighter/yql.ts index c9398bcef..05a77f657 100644 --- a/src/components/YqlHighlighter/yql.ts +++ b/src/components/YqlHighlighter/yql.ts @@ -13,11 +13,13 @@ export const light = { 'pre[class*="language-"]': { ...lightTheme['pre[class*="language-"]'], background: 'transparent', + margin: 0, }, 'code[class*="language-"]': { ...lightTheme['code[class*="language-"]'], background: 'transparent', color: 'var(--g-color-text-primary)', + whiteSpace: 'pre-wrap' as const, }, comment: { color: '#969896', @@ -53,11 +55,13 @@ export const dark = { 'pre[class*="language-"]': { ...darkTheme['pre[class*="language-"]'], background: 'transparent', + margin: 0, }, 'code[class*="language-"]': { ...darkTheme['code[class*="language-"]'], background: 'transparent', color: 'var(--g-color-text-primary)', + whiteSpace: 'pre-wrap' as const, }, comment: { color: '#969896', From f628c9eb6cc2e4557098a6eddcb40227d6fe7cbe Mon Sep 17 00:00:00 2001 From: astandrik Date: Mon, 23 Dec 2024 17:05:01 +0300 Subject: [PATCH 6/6] fix: remove cell with popopver --- .../TruncatedQuery/TruncatedQuery.scss | 8 -------- src/components/TruncatedQuery/TruncatedQuery.tsx | 16 ---------------- src/components/YqlHighlighter/YqlHighlighter.tsx | 6 +++++- .../Diagnostics/TopQueries/columns/columns.tsx | 8 +++----- .../tenant/queryHistory/queryHistory.test.ts | 4 ++-- 5 files changed, 10 insertions(+), 32 deletions(-) diff --git a/src/components/TruncatedQuery/TruncatedQuery.scss b/src/components/TruncatedQuery/TruncatedQuery.scss index 5bbbaecd1..b5072f5c0 100644 --- a/src/components/TruncatedQuery/TruncatedQuery.scss +++ b/src/components/TruncatedQuery/TruncatedQuery.scss @@ -14,12 +14,4 @@ } } } - - &__popover-content { - overflow: hidden; - - max-width: 600px; - - white-space: pre; - } } diff --git a/src/components/TruncatedQuery/TruncatedQuery.tsx b/src/components/TruncatedQuery/TruncatedQuery.tsx index 02a9cb07a..afac9e56c 100644 --- a/src/components/TruncatedQuery/TruncatedQuery.tsx +++ b/src/components/TruncatedQuery/TruncatedQuery.tsx @@ -1,7 +1,6 @@ import React from 'react'; import {cn} from '../../utils/cn'; -import {CellWithPopover} from '../CellWithPopover/CellWithPopover'; import {YqlHighlighter} from '../YqlHighlighter/YqlHighlighter'; import './TruncatedQuery.scss'; @@ -30,18 +29,3 @@ export const TruncatedQuery = ({value = '', maxQueryHeight = 6}: TruncatedQueryP } return {value}; }; - -interface OneLineQueryWithPopoverProps { - value?: string; -} - -export const OneLineQueryWithPopover = ({value = ''}: OneLineQueryWithPopoverProps) => { - return ( - {value}} - > - {value} - - ); -}; diff --git a/src/components/YqlHighlighter/YqlHighlighter.tsx b/src/components/YqlHighlighter/YqlHighlighter.tsx index 94838108c..90d62f0b2 100644 --- a/src/components/YqlHighlighter/YqlHighlighter.tsx +++ b/src/components/YqlHighlighter/YqlHighlighter.tsx @@ -1,10 +1,14 @@ import {useThemeValue} from '@gravity-ui/uikit'; import {PrismLight as SyntaxHighlighter} from 'react-syntax-highlighter'; +import {cn} from '../../utils/cn'; + import {dark, light, yql} from './yql'; SyntaxHighlighter.registerLanguage('yql', yql); +const b = cn('yql-highlighter'); + interface YqlHighlighterProps { children: string; className?: string; @@ -15,7 +19,7 @@ export const YqlHighlighter = ({children, className}: YqlHighlighterProps) => { const isDark = themeValue === 'dark' || themeValue === 'dark-hc'; return ( -
+
{children} diff --git a/src/containers/Tenant/Diagnostics/TopQueries/columns/columns.tsx b/src/containers/Tenant/Diagnostics/TopQueries/columns/columns.tsx index 0b1f13904..657cde5fe 100644 --- a/src/containers/Tenant/Diagnostics/TopQueries/columns/columns.tsx +++ b/src/containers/Tenant/Diagnostics/TopQueries/columns/columns.tsx @@ -1,10 +1,8 @@ import DataTable from '@gravity-ui/react-data-table'; import type {Column} from '@gravity-ui/react-data-table'; -import { - OneLineQueryWithPopover, - TruncatedQuery, -} from '../../../../../components/TruncatedQuery/TruncatedQuery'; +import {TruncatedQuery} from '../../../../../components/TruncatedQuery/TruncatedQuery'; +import {YqlHighlighter} from '../../../../../components/YqlHighlighter/YqlHighlighter'; import type {KeyValueRow} from '../../../../../types/api/query'; import {cn} from '../../../../../utils/cn'; import {formatDateTime, formatNumber} from '../../../../../utils/dataFormatters/dataFormatters'; @@ -82,7 +80,7 @@ const userSIDColumn: Column = { const oneLineQueryTextColumn: Column = { name: TOP_QUERIES_COLUMNS_IDS.OneLineQueryText, header: TOP_QUERIES_COLUMNS_TITLES.OneLineQueryText, - render: ({row}) => , + render: ({row}) => {row.QueryText?.toString() || ''}, sortable: false, width: 500, }; diff --git a/tests/suites/tenant/queryHistory/queryHistory.test.ts b/tests/suites/tenant/queryHistory/queryHistory.test.ts index a42d4fe53..172777554 100644 --- a/tests/suites/tenant/queryHistory/queryHistory.test.ts +++ b/tests/suites/tenant/queryHistory/queryHistory.test.ts @@ -34,7 +34,7 @@ test.describe('Query History', () => { // Check if the query appears in the history const historyTable = page.locator('.ydb-queries-history table'); - await expect(historyTable.locator('.sql-highlighter', {hasText: testQuery})).toBeVisible({ + await expect(historyTable.locator('.yql-highlighter', {hasText: testQuery})).toBeVisible({ timeout: VISIBILITY_TIMEOUT, }); }); @@ -85,6 +85,6 @@ test.describe('Query History', () => { // Check if the query appears in the history const historyTable = page.locator('.ydb-queries-history table'); - await expect(historyTable.locator('.sql-highlighter', {hasText: testQuery})).toBeVisible(); + await expect(historyTable.locator('.yql-highlighter', {hasText: testQuery})).toBeVisible(); }); });