diff --git a/package-lock.json b/package-lock.json index d94e8fe30..cebde4049 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", @@ -81,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", @@ -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", @@ -17832,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" } @@ -18586,6 +18775,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 +20502,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 +20554,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 +22491,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 +22802,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 +24072,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 +27004,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..f0ce050be 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", @@ -144,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/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/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 60ff1593a..afac9e56c 100644 --- a/src/components/TruncatedQuery/TruncatedQuery.tsx +++ b/src/components/TruncatedQuery/TruncatedQuery.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {cn} from '../../utils/cn'; -import {CellWithPopover} from '../CellWithPopover/CellWithPopover'; +import {YqlHighlighter} from '../YqlHighlighter/YqlHighlighter'; import './TruncatedQuery.scss'; @@ -22,22 +22,10 @@ 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}; -}; - -interface OneLineQueryWithPopoverProps { - value?: string; -} - -export const OneLineQueryWithPopover = ({value = ''}: OneLineQueryWithPopoverProps) => { - return ( - - {value} - - ); + return {value}; }; diff --git a/src/components/YqlHighlighter/YqlHighlighter.tsx b/src/components/YqlHighlighter/YqlHighlighter.tsx new file mode 100644 index 000000000..90d62f0b2 --- /dev/null +++ b/src/components/YqlHighlighter/YqlHighlighter.tsx @@ -0,0 +1,28 @@ +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; +} + +export const YqlHighlighter = ({children, className}: YqlHighlighterProps) => { + const themeValue = useThemeValue(); + const isDark = themeValue === 'dark' || themeValue === 'dark-hc'; + + return ( +
+ + {children} + +
+ ); +}; diff --git a/src/components/YqlHighlighter/yql.ts b/src/components/YqlHighlighter/yql.ts new file mode 100644 index 000000000..05a77f657 --- /dev/null +++ b/src/components/YqlHighlighter/yql.ts @@ -0,0 +1,168 @@ +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'; + +export const light = { + ...lightTheme, + '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', + }, + 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', + 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', + }, + 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/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/src/containers/Tenant/Info/View/View.tsx b/src/containers/Tenant/Info/View/View.tsx index 795a13d47..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 {Text} from '@gravity-ui/uikit'; 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,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..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(`text="${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(`text="${testQuery}"`)).toBeVisible(); + await expect(historyTable.locator('.yql-highlighter', {hasText: testQuery})).toBeVisible(); }); });