From 12acdf8f9f53e865814583567988e7d0ae9304e1 Mon Sep 17 00:00:00 2001 From: astandrik Date: Tue, 17 Dec 2024 17:44:40 +0300 Subject: [PATCH 01/11] feat: display view query text --- package-lock.json | 280 +++++++++++++++++- package.json | 2 + .../SqlHighlighter/SqlHighlighter.scss | 13 + .../SqlHighlighter/SqlHighlighter.tsx | 30 ++ .../TruncatedQuery/TruncatedQuery.tsx | 12 +- src/containers/Tenant/Info/View/View.tsx | 8 +- 6 files changed, 334 insertions(+), 11 deletions(-) create mode 100644 src/components/SqlHighlighter/SqlHighlighter.scss create mode 100644 src/components/SqlHighlighter/SqlHighlighter.tsx diff --git a/package-lock.json b/package-lock.json index 3ab638d2a9..9b9e5379a6 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 7ee11b741b..9aa4646f48 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/src/components/SqlHighlighter/SqlHighlighter.scss b/src/components/SqlHighlighter/SqlHighlighter.scss new file mode 100644 index 0000000000..7f6c05dbcc --- /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: var(--g-color-base-background) !important; + } +} diff --git a/src/components/SqlHighlighter/SqlHighlighter.tsx b/src/components/SqlHighlighter/SqlHighlighter.tsx new file mode 100644 index 0000000000..a026f031e0 --- /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 sql from 'react-syntax-highlighter/dist/esm/languages/prism/sql'; +import {oneLight, tomorrow} from 'react-syntax-highlighter/dist/esm/styles/prism'; + +import {cn} from '../../utils/cn'; + +import './SqlHighlighter.scss'; + +SyntaxHighlighter.registerLanguage('sql', sql); + +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/TruncatedQuery/TruncatedQuery.tsx b/src/components/TruncatedQuery/TruncatedQuery.tsx index 60ff1593aa..c0453ca0b4 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 795a13d47c..910b26f9b6 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, }, ]; }; From 7d59c74d5400b41e4780e0bd5e89c5fdee534562 Mon Sep 17 00:00:00 2001 From: astandrik Date: Wed, 18 Dec 2024 13:26:43 +0300 Subject: [PATCH 02/11] fix: tests --- playwright.config.ts | 1 + tests/suites/tenant/queryHistory/queryHistory.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index 2d5423c0a9..ab6c8e0efa 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/tests/suites/tenant/queryHistory/queryHistory.test.ts b/tests/suites/tenant/queryHistory/queryHistory.test.ts index 7e08853a38..a42d4fe534 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 e2b654e77409486787a892f1c3c9a6a1eadd1a9c Mon Sep 17 00:00:00 2001 From: astandrik Date: Thu, 19 Dec 2024 17:20:56 +0300 Subject: [PATCH 03/11] fix: style fixes --- src/components/SqlHighlighter/SqlHighlighter.scss | 2 +- src/components/SqlHighlighter/SqlHighlighter.tsx | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/SqlHighlighter/SqlHighlighter.scss b/src/components/SqlHighlighter/SqlHighlighter.scss index 7f6c05dbcc..bdde6c902e 100644 --- a/src/components/SqlHighlighter/SqlHighlighter.scss +++ b/src/components/SqlHighlighter/SqlHighlighter.scss @@ -8,6 +8,6 @@ pre { margin: 0 !important; - background: var(--g-color-base-background) !important; + background: transparent !important; } } diff --git a/src/components/SqlHighlighter/SqlHighlighter.tsx b/src/components/SqlHighlighter/SqlHighlighter.tsx index a026f031e0..b60d1a3c15 100644 --- a/src/components/SqlHighlighter/SqlHighlighter.tsx +++ b/src/components/SqlHighlighter/SqlHighlighter.tsx @@ -1,7 +1,10 @@ import {useThemeValue} from '@gravity-ui/uikit'; import {PrismLight as SyntaxHighlighter} from 'react-syntax-highlighter'; import sql from 'react-syntax-highlighter/dist/esm/languages/prism/sql'; -import {oneLight, tomorrow} from 'react-syntax-highlighter/dist/esm/styles/prism'; +import { + vscDarkPlus as dark, + materialLight as light, +} from 'react-syntax-highlighter/dist/esm/styles/prism'; import {cn} from '../../utils/cn'; @@ -22,7 +25,7 @@ export const SqlHighlighter = ({children, className}: SqlHighlighterProps) => { return (
- + {children}
From 216c64509c2b27a04fcec21722a9ccd697b7e4dd Mon Sep 17 00:00:00 2001 From: astandrik Date: Thu, 19 Dec 2024 17:39:30 +0300 Subject: [PATCH 04/11] fix: invisible rows background --- .../SqlHighlighter/SqlHighlighter.tsx | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/components/SqlHighlighter/SqlHighlighter.tsx b/src/components/SqlHighlighter/SqlHighlighter.tsx index b60d1a3c15..62024f0219 100644 --- a/src/components/SqlHighlighter/SqlHighlighter.tsx +++ b/src/components/SqlHighlighter/SqlHighlighter.tsx @@ -1,16 +1,41 @@ import {useThemeValue} from '@gravity-ui/uikit'; import {PrismLight as SyntaxHighlighter} from 'react-syntax-highlighter'; -import sql from 'react-syntax-highlighter/dist/esm/languages/prism/sql'; +import plsql from 'react-syntax-highlighter/dist/esm/languages/prism/plsql'; import { - vscDarkPlus as dark, - materialLight as light, + vscDarkPlus as darkTheme, + materialLight as lightTheme, } from 'react-syntax-highlighter/dist/esm/styles/prism'; +// Create custom themes with transparent backgrounds +const light = { + ...lightTheme, + 'pre[class*="language-"]': { + ...lightTheme['pre[class*="language-"]'], + background: 'transparent', + }, + 'code[class*="language-"]': { + ...lightTheme['code[class*="language-"]'], + background: 'transparent', + }, +}; + +const dark = { + ...darkTheme, + 'pre[class*="language-"]': { + ...darkTheme['pre[class*="language-"]'], + background: 'transparent', + }, + 'code[class*="language-"]': { + ...darkTheme['code[class*="language-"]'], + background: 'transparent', + }, +}; + import {cn} from '../../utils/cn'; import './SqlHighlighter.scss'; -SyntaxHighlighter.registerLanguage('sql', sql); +SyntaxHighlighter.registerLanguage('plsql', plsql); const b = cn('sql-highlighter'); From 4a7527769d09cc918028cdeab541a2f7f66b4493 Mon Sep 17 00:00:00 2001 From: astandrik Date: Thu, 19 Dec 2024 20:24:17 +0300 Subject: [PATCH 05/11] fix: code snippets --- src/components/Snippet/Snippet.scss | 11 +++ src/components/Snippet/Snippet.tsx | 69 +++++++++++++++++++ .../SqlHighlighter/SqlHighlighter.scss | 13 ---- .../SqlHighlighter/SqlHighlighter.tsx | 58 ---------------- .../TruncatedQuery/TruncatedQuery.tsx | 27 ++------ .../TopQueries/columns/columns.tsx | 3 +- src/containers/Tenant/Info/View/View.tsx | 4 +- .../Query/QueriesHistory/QueriesHistory.tsx | 4 +- .../Tenant/Query/QueryEditor/QueryEditor.tsx | 2 +- .../Query/QueryResult/components/Ast/Ast.tsx | 2 +- .../Query/SavedQueries/SavedQueries.tsx | 5 +- src/containers/Tenant/utils/constants.ts | 2 - src/utils/monaco/constants.ts | 4 ++ src/utils/monaco/constats.ts | 2 - 14 files changed, 99 insertions(+), 107 deletions(-) create mode 100644 src/components/Snippet/Snippet.scss create mode 100644 src/components/Snippet/Snippet.tsx delete mode 100644 src/components/SqlHighlighter/SqlHighlighter.scss delete mode 100644 src/components/SqlHighlighter/SqlHighlighter.tsx create mode 100644 src/utils/monaco/constants.ts delete mode 100644 src/utils/monaco/constats.ts diff --git a/src/components/Snippet/Snippet.scss b/src/components/Snippet/Snippet.scss new file mode 100644 index 0000000000..b02a474853 --- /dev/null +++ b/src/components/Snippet/Snippet.scss @@ -0,0 +1,11 @@ +.snippet { + &__content { + border: 1px solid var(--g-color-line-generic); + + overflow: auto; + + * { + cursor: pointer !important; + } + } +} diff --git a/src/components/Snippet/Snippet.tsx b/src/components/Snippet/Snippet.tsx new file mode 100644 index 0000000000..99f3cdc5ab --- /dev/null +++ b/src/components/Snippet/Snippet.tsx @@ -0,0 +1,69 @@ +import React from 'react'; + +import {useThemeValue} from '@gravity-ui/uikit'; +import type {editor} from 'monaco-editor'; +import 'monaco-yql-languages/build/monaco.contribution'; +import MonacoEditor from 'react-monaco-editor'; + +import {cn} from '../../utils/cn'; +import {YQL_LANGUAGE_ID} from '../../utils/monaco/constants'; + +import './Snippet.scss'; + +const block = cn('snippet'); +const SNIPPET_LENGTH = 7; + +export interface SnippetProps { + className?: string; + children: string; + language?: string; +} + +export const Snippet = ({ + className, + children, + language = YQL_LANGUAGE_ID, +}: SnippetProps): JSX.Element => { + const themeValue = useThemeValue(); + const theme = `vs-${themeValue}`; + + const editorOptions = React.useMemo( + () => ({ + readOnly: true, + minimap: {enabled: false}, + scrollBeyondLastLine: false, + lineNumbers: 'off' as const, + scrollbar: { + vertical: 'visible', + horizontal: 'visible', + verticalScrollbarSize: 8, + horizontalScrollbarSize: 8, + alwaysConsumeMouseWheel: false, + }, + renderLineHighlight: 'none' as const, + overviewRulerLanes: 0, + hideCursorInOverviewRuler: true, + overviewRulerBorder: false, + lineDecorationsWidth: 0, + contextmenu: false, + fontSize: 13, + lineHeight: 20, + domReadOnly: true, + }), + [], + ); + + return ( +
+
+ +
+
+ ); +}; diff --git a/src/components/SqlHighlighter/SqlHighlighter.scss b/src/components/SqlHighlighter/SqlHighlighter.scss deleted file mode 100644 index bdde6c902e..0000000000 --- a/src/components/SqlHighlighter/SqlHighlighter.scss +++ /dev/null @@ -1,13 +0,0 @@ -.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 deleted file mode 100644 index 62024f0219..0000000000 --- a/src/components/SqlHighlighter/SqlHighlighter.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import {useThemeValue} from '@gravity-ui/uikit'; -import {PrismLight as SyntaxHighlighter} from 'react-syntax-highlighter'; -import plsql from 'react-syntax-highlighter/dist/esm/languages/prism/plsql'; -import { - vscDarkPlus as darkTheme, - materialLight as lightTheme, -} from 'react-syntax-highlighter/dist/esm/styles/prism'; - -// Create custom themes with transparent backgrounds -const light = { - ...lightTheme, - 'pre[class*="language-"]': { - ...lightTheme['pre[class*="language-"]'], - background: 'transparent', - }, - 'code[class*="language-"]': { - ...lightTheme['code[class*="language-"]'], - background: 'transparent', - }, -}; - -const dark = { - ...darkTheme, - 'pre[class*="language-"]': { - ...darkTheme['pre[class*="language-"]'], - background: 'transparent', - }, - 'code[class*="language-"]': { - ...darkTheme['code[class*="language-"]'], - background: 'transparent', - }, -}; - -import {cn} from '../../utils/cn'; - -import './SqlHighlighter.scss'; - -SyntaxHighlighter.registerLanguage('plsql', plsql); - -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/TruncatedQuery/TruncatedQuery.tsx b/src/components/TruncatedQuery/TruncatedQuery.tsx index c0453ca0b4..9ef5d6e9f1 100644 --- a/src/components/TruncatedQuery/TruncatedQuery.tsx +++ b/src/components/TruncatedQuery/TruncatedQuery.tsx @@ -1,8 +1,6 @@ -import React from 'react'; - import {cn} from '../../utils/cn'; import {CellWithPopover} from '../CellWithPopover/CellWithPopover'; -import {SqlHighlighter} from '../SqlHighlighter/SqlHighlighter'; +import {Snippet} from '../Snippet/Snippet'; import './TruncatedQuery.scss'; @@ -10,25 +8,10 @@ const b = cn('kv-truncated-query'); interface TruncatedQueryProps { value?: string; - maxQueryHeight?: number; } -export const TruncatedQuery = ({value = '', maxQueryHeight = 6}: TruncatedQueryProps) => { - const lines = value.split('\n'); - const truncated = lines.length > maxQueryHeight; - - if (truncated) { - const content = lines.slice(0, maxQueryHeight).join('\n'); - const message = - '\n...\nThe request was truncated. Click on the line to show the full query on the query tab'; - return ( - - {content} - {message} - - ); - } - return {value}; +export const TruncatedQuery = ({value = ''}: TruncatedQueryProps) => { + return {value}; }; interface OneLineQueryWithPopoverProps { @@ -39,9 +22,9 @@ export const OneLineQueryWithPopover = ({value = ''}: OneLineQueryWithPopoverPro return ( {value}} + content={{value}} > - {value} + {value} ); }; diff --git a/src/containers/Tenant/Diagnostics/TopQueries/columns/columns.tsx b/src/containers/Tenant/Diagnostics/TopQueries/columns/columns.tsx index 0b1f139049..e5672d10d1 100644 --- a/src/containers/Tenant/Diagnostics/TopQueries/columns/columns.tsx +++ b/src/containers/Tenant/Diagnostics/TopQueries/columns/columns.tsx @@ -10,7 +10,6 @@ import {cn} from '../../../../../utils/cn'; import {formatDateTime, formatNumber} from '../../../../../utils/dataFormatters/dataFormatters'; import {generateHash} from '../../../../../utils/generateHash'; import {formatToMs, parseUsToMs} from '../../../../../utils/timeParsers'; -import {MAX_QUERY_HEIGHT} from '../../../utils/constants'; import { TOP_QUERIES_COLUMNS_IDS, @@ -38,7 +37,7 @@ const queryTextColumn: Column = { sortAccessor: (row) => Number(row.CPUTimeUs), render: ({row}) => (
- +
), sortable: false, diff --git a/src/containers/Tenant/Info/View/View.tsx b/src/containers/Tenant/Info/View/View.tsx index 910b26f9b6..3dbfccf399 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 {SqlHighlighter} from '../../../../components/SqlHighlighter/SqlHighlighter'; +import {Snippet} from '../../../../components/Snippet/Snippet'; import {YDBDefinitionList} from '../../../../components/YDBDefinitionList/YDBDefinitionList'; import type {TEvDescribeSchemeResult} from '../../../../types/api/schema'; import {getEntityName} from '../../utils'; @@ -13,7 +13,7 @@ const prepareViewItems = (data: TEvDescribeSchemeResult): DefinitionListItem[] = { name: i18n('view.query-text'), copyText: queryText, - content: queryText ? {queryText} : null, + content: queryText ? {queryText} : null, }, ]; }; diff --git a/src/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx b/src/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx index 5db6bc1867..ec476fdac6 100644 --- a/src/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx +++ b/src/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx @@ -17,7 +17,7 @@ import {formatDateTime} from '../../../../utils/dataFormatters/dataFormatters'; import {useTypedDispatch, useTypedSelector} from '../../../../utils/hooks'; import {useChangeInputWithConfirmation} from '../../../../utils/hooks/withConfirmation/useChangeInputWithConfirmation'; import {formatToMs, parseUsToMs} from '../../../../utils/timeParsers'; -import {MAX_QUERY_HEIGHT, QUERY_TABLE_SETTINGS} from '../../utils/constants'; +import {QUERY_TABLE_SETTINGS} from '../../utils/constants'; import i18n from '../i18n'; import './QueriesHistory.scss'; @@ -55,7 +55,7 @@ function QueriesHistory({changeUserInput}: QueriesHistoryProps) { render: ({row}) => { return (
- +
); }, diff --git a/src/containers/Tenant/Query/QueryEditor/QueryEditor.tsx b/src/containers/Tenant/Query/QueryEditor/QueryEditor.tsx index 29cd198ad0..a305a4cf35 100644 --- a/src/containers/Tenant/Query/QueryEditor/QueryEditor.tsx +++ b/src/containers/Tenant/Query/QueryEditor/QueryEditor.tsx @@ -41,7 +41,7 @@ import { } from '../../../../utils/hooks'; import {useChangedQuerySettings} from '../../../../utils/hooks/useChangedQuerySettings'; import {useLastQueryExecutionSettings} from '../../../../utils/hooks/useLastQueryExecutionSettings'; -import {YQL_LANGUAGE_ID} from '../../../../utils/monaco/constats'; +import {YQL_LANGUAGE_ID} from '../../../../utils/monaco/constants'; import {QUERY_ACTIONS} from '../../../../utils/query'; import type {InitialPaneState} from '../../utils/paneVisibilityToggleHelpers'; import { diff --git a/src/containers/Tenant/Query/QueryResult/components/Ast/Ast.tsx b/src/containers/Tenant/Query/QueryResult/components/Ast/Ast.tsx index e56c9f6e51..c30731f579 100644 --- a/src/containers/Tenant/Query/QueryResult/components/Ast/Ast.tsx +++ b/src/containers/Tenant/Query/QueryResult/components/Ast/Ast.tsx @@ -1,7 +1,7 @@ import MonacoEditor from 'react-monaco-editor'; import {cn} from '../../../../../../utils/cn'; -import {S_EXPRESSION_LANGUAGE_ID} from '../../../../../../utils/monaco/constats'; +import {S_EXPRESSION_LANGUAGE_ID} from '../../../../../../utils/monaco/constants'; import './Ast.scss'; diff --git a/src/containers/Tenant/Query/SavedQueries/SavedQueries.tsx b/src/containers/Tenant/Query/SavedQueries/SavedQueries.tsx index 6f91e8746d..500f4b7b1f 100644 --- a/src/containers/Tenant/Query/SavedQueries/SavedQueries.tsx +++ b/src/containers/Tenant/Query/SavedQueries/SavedQueries.tsx @@ -21,7 +21,7 @@ import type {SavedQuery} from '../../../../types/store/query'; import {cn} from '../../../../utils/cn'; import {useTypedDispatch, useTypedSelector} from '../../../../utils/hooks'; import {useChangeInputWithConfirmation} from '../../../../utils/hooks/withConfirmation/useChangeInputWithConfirmation'; -import {MAX_QUERY_HEIGHT, QUERY_TABLE_SETTINGS} from '../../utils/constants'; +import {QUERY_TABLE_SETTINGS} from '../../utils/constants'; import i18n from '../i18n'; import {useSavedQueries} from '../utils/useSavedQueries'; @@ -125,7 +125,7 @@ export const SavedQueries = ({changeUserInput}: SavedQueriesProps) => { render: ({row: query}) => (
- +