diff --git a/web/.umirc.ts b/web/.umirc.ts index 75a8bb505..cae37519d 100644 --- a/web/.umirc.ts +++ b/web/.umirc.ts @@ -1,4 +1,5 @@ import path from 'path'; +import TerserPlugin from 'terser-webpack-plugin'; import { defineConfig } from 'umi'; import { appName } from './src/conf.json'; import routes from './src/routes'; @@ -23,7 +24,7 @@ export default defineConfig({ '@react-dev-inspector/umi4-plugin', '@umijs/plugins/dist/tailwindcss', ], - jsMinifier: 'terser', + jsMinifier: 'none', // Fixed the issue that the page displayed an error after packaging lexical with terser lessLoader: { modifyVars: { hack: `true; @import "~@/less/index.less";`, @@ -48,6 +49,8 @@ export default defineConfig({ chainWebpack(memo, args) { memo.module.rule('markdown').test(/\.md$/).type('asset/source'); + memo.optimization.minimizer('terser').use(TerserPlugin); // Fixed the issue that the page displayed an error after packaging lexical with terser + return memo; }, tailwindcss: {}, diff --git a/web/package-lock.json b/web/package-lock.json index 3b5d1d4cc..d4b3af06e 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -13,6 +13,7 @@ "@antv/g6": "^5.0.10", "@hookform/resolvers": "^3.9.1", "@js-preview/excel": "^1.7.8", + "@lexical/react": "^0.23.1", "@monaco-editor/react": "^4.6.0", "@radix-ui/react-alert-dialog": "^1.1.4", "@radix-ui/react-aspect-ratio": "^1.1.0", @@ -57,6 +58,7 @@ "input-otp": "^1.4.1", "js-base64": "^3.7.5", "jsencrypt": "^3.3.2", + "lexical": "^0.23.1", "lodash": "^4.17.21", "lucide-react": "^0.454.0", "mammoth": "^1.7.2", @@ -117,6 +119,7 @@ "react-dev-inspector": "^2.0.1", "remark-loader": "^6.0.0", "tailwindcss": "^3", + "terser-webpack-plugin": "^5.3.11", "ts-node": "^10.9.2", "typescript": "^5.0.3", "umi-plugin-icons": "^0.1.1" @@ -4093,6 +4096,256 @@ "resolved": "https://registry.npmmirror.com/@js-preview/excel/-/excel-1.7.8.tgz", "integrity": "sha512-pLJTDIhbzqaiH3kUPnbeWLsBFeCAHjnBwloMvoREdW4YUYTcsHDQ5h41QTyRJWSYRJBCcsy6Kt7KeDHOHDbVEw==" }, + "node_modules/@lexical/clipboard": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/clipboard/-/clipboard-0.23.1.tgz", + "integrity": "sha512-MT8IXl1rhTe8VcwnkhgFtWra6sRYNsl/I7nE9aw6QxwvPReKmRDmyBmEIeXwnKSGHRe19OJhu4/A9ciKPyVdMA==", + "dependencies": { + "@lexical/html": "0.23.1", + "@lexical/list": "0.23.1", + "@lexical/selection": "0.23.1", + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/code": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/code/-/code-0.23.1.tgz", + "integrity": "sha512-TOxaFAwoewrX3rHp4Po+u1LJT8oteP/6Kn2z6j9DaynBW62gIqTuSAFcMPysVx/Puq5hhJHPRD/be9RWDteDZw==", + "dependencies": { + "@lexical/utils": "0.23.1", + "lexical": "0.23.1", + "prismjs": "^1.27.0" + } + }, + "node_modules/@lexical/devtools-core": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/devtools-core/-/devtools-core-0.23.1.tgz", + "integrity": "sha512-QsgcrECy11ZHhWAfyNW/ougXFF1o0EuQnhFybgTdqQmw0rJ2ZgPLpPjD5lws3CE8mP8g5knBV4/cyxvv42fzzg==", + "dependencies": { + "@lexical/html": "0.23.1", + "@lexical/link": "0.23.1", + "@lexical/mark": "0.23.1", + "@lexical/table": "0.23.1", + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + }, + "peerDependencies": { + "react": ">=17.x", + "react-dom": ">=17.x" + } + }, + "node_modules/@lexical/dragon": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/dragon/-/dragon-0.23.1.tgz", + "integrity": "sha512-ZoY9VJDrTpO69sinRhIs3RlPAWviy4mwnC7lqtM77/pVK0Kaknv7z2iDqv+414PKQCgUhyoXp7PfYXu/3yb6LQ==", + "dependencies": { + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/hashtag": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/hashtag/-/hashtag-0.23.1.tgz", + "integrity": "sha512-EkRCHV/IQwKlggy3VQDF9b4Krc9DKNZEjXe84CkEVrRpQSOwXi0qORzuaAipARyN632WKLSXOZJmNzkUNocJ6A==", + "dependencies": { + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/history": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/history/-/history-0.23.1.tgz", + "integrity": "sha512-5Vro4bIePw37MwffpvPm56WlwPdlY/u+fVkvXsxdhK9bqiFesmLZhBirokDPvJEMP35V59kzmN5mmWXSYfuRpg==", + "dependencies": { + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/html": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/html/-/html-0.23.1.tgz", + "integrity": "sha512-kNkDUaDe/Awypaw8JZn65BzT1gwNj2bNkaGFcmIkXUrTtiqlvgYvKvJeOKLkoAb/i2xq990ZAbHOsJrJm1jMbw==", + "dependencies": { + "@lexical/selection": "0.23.1", + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/link": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/link/-/link-0.23.1.tgz", + "integrity": "sha512-HRaOp7prtcbHjbgq8AjJ4O02jYb8pTeS8RrGcgIRhCOq3/EcsSb1dXMwuraqmh9oxbuFyEu/JE31EFksiOW6qA==", + "dependencies": { + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/list": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/list/-/list-0.23.1.tgz", + "integrity": "sha512-TI3WyWk3avv9uaJwaq8V+m9zxLRgnzXDYNS0rREafnW09rDpaFkpVmDuX+PZVR3NqPlwVt+slWVSBuyfguAFbA==", + "dependencies": { + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/mark": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/mark/-/mark-0.23.1.tgz", + "integrity": "sha512-E7cMOBVMrNGMw0LsyWKNFQZ5Io3bUIHCC3aCUdH24z1XWnuTmDFKMqNrphywPniO7pzSgVyGpkQBZIAIN76+YA==", + "dependencies": { + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/markdown": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/markdown/-/markdown-0.23.1.tgz", + "integrity": "sha512-TQx8oXenaiVYffBPxD85m4CydbDAuYOonATiABAFG6CHkA6vi898M1TCTgVDS6/iISjtjQpqHo0SW7YjLt14jw==", + "dependencies": { + "@lexical/code": "0.23.1", + "@lexical/link": "0.23.1", + "@lexical/list": "0.23.1", + "@lexical/rich-text": "0.23.1", + "@lexical/text": "0.23.1", + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/offset": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/offset/-/offset-0.23.1.tgz", + "integrity": "sha512-ylw5egME/lldacVXDoRsdGDXPuk9lGmYgcqx/aITGrSymav+RDjQoAapHbz1HQqGmm/m18+VLaWTdjtkbrIN6g==", + "dependencies": { + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/overflow": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/overflow/-/overflow-0.23.1.tgz", + "integrity": "sha512-WubTqozpxOeyTm/tKIHXinsjuRcgPESacOvu93dS+sC7q3n+xeBIu5FL7lM6bbsk3zNtNJQ9sG0svZngmWRjCw==", + "dependencies": { + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/plain-text": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/plain-text/-/plain-text-0.23.1.tgz", + "integrity": "sha512-tM4DJw+HyT9XV4BKGVECDnejcC//jsFggjFmJgwIMTCxJPiGXEEZLZTXmGqf8QdFZ6cH1I5bhreZPQUWu6dRvg==", + "dependencies": { + "@lexical/clipboard": "0.23.1", + "@lexical/selection": "0.23.1", + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/react": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/react/-/react-0.23.1.tgz", + "integrity": "sha512-g5CQMOiK+Djqp75UaSFUceHZEUQVIXBzWBuVR69pCiptCgNqN3CNAoIxy0hTTaVrLq6S0SCjUOduBDtioN0bLA==", + "dependencies": { + "@lexical/clipboard": "0.23.1", + "@lexical/code": "0.23.1", + "@lexical/devtools-core": "0.23.1", + "@lexical/dragon": "0.23.1", + "@lexical/hashtag": "0.23.1", + "@lexical/history": "0.23.1", + "@lexical/link": "0.23.1", + "@lexical/list": "0.23.1", + "@lexical/mark": "0.23.1", + "@lexical/markdown": "0.23.1", + "@lexical/overflow": "0.23.1", + "@lexical/plain-text": "0.23.1", + "@lexical/rich-text": "0.23.1", + "@lexical/selection": "0.23.1", + "@lexical/table": "0.23.1", + "@lexical/text": "0.23.1", + "@lexical/utils": "0.23.1", + "@lexical/yjs": "0.23.1", + "lexical": "0.23.1", + "react-error-boundary": "^3.1.4" + }, + "peerDependencies": { + "react": ">=17.x", + "react-dom": ">=17.x" + } + }, + "node_modules/@lexical/react/node_modules/react-error-boundary": { + "version": "3.1.4", + "resolved": "https://registry.npmmirror.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, + "node_modules/@lexical/rich-text": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/rich-text/-/rich-text-0.23.1.tgz", + "integrity": "sha512-Y77HGxdF5aemjw/H44BXETD5KNeaNdwMRu9P7IrlK7cC1dvvimzL2D6ezbub5i7F1Ef5T0quOXjwK056vrqaKQ==", + "dependencies": { + "@lexical/clipboard": "0.23.1", + "@lexical/selection": "0.23.1", + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/selection": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/selection/-/selection-0.23.1.tgz", + "integrity": "sha512-xoehAURMZJZYf046GHUXiv8FSv5zTobhwDD2dML4fmNHPp9NxugkWHlNUinTK/b+jGgjSYVsqpEKPBmue4ZHdQ==", + "dependencies": { + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/table": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/table/-/table-0.23.1.tgz", + "integrity": "sha512-Qs+iuwSVkV4OGTt+JdL9hvyl/QO3X9waH70L5Fxu9JmQk/jLl02tIGXbE38ocJkByfpyk4PrphoXt6l7CugJZA==", + "dependencies": { + "@lexical/clipboard": "0.23.1", + "@lexical/utils": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/text": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/text/-/text-0.23.1.tgz", + "integrity": "sha512-aOuuAhmc+l2iSK99uP0x/Zg9LSQswQdNG3IxzGa0rTx844mWUHuEbAUaOqqlgDA1/zZ0WjObyhPfZJL775y63g==", + "dependencies": { + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/utils": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/utils/-/utils-0.23.1.tgz", + "integrity": "sha512-yXEkF6fj32+mJblCoP0ZT/vA0S05FA0nRUkVrvGX6sbZ9y+cIzuIbBoHi4z1ytutcWHQrwCK4TsN9hPYBIlb2w==", + "dependencies": { + "@lexical/list": "0.23.1", + "@lexical/selection": "0.23.1", + "@lexical/table": "0.23.1", + "lexical": "0.23.1" + } + }, + "node_modules/@lexical/yjs": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/@lexical/yjs/-/yjs-0.23.1.tgz", + "integrity": "sha512-ygodSxmC65srNicMIhqBRIXI2LHhmnHcR1EO9fLO7flZWGCR1HIoeGmwhHo9FLgJoc5LHanV+dE0z1onFo1qqQ==", + "dependencies": { + "@lexical/offset": "0.23.1", + "@lexical/selection": "0.23.1", + "lexical": "0.23.1" + }, + "peerDependencies": { + "yjs": ">=13.5.22" + } + }, "node_modules/@ljharb/resumer": { "version": "0.0.1", "resolved": "https://registry.npmmirror.com/@ljharb/resumer/-/resumer-0.0.1.tgz", @@ -9363,6 +9616,45 @@ "uri-js": "^4.2.2" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -14571,6 +14863,22 @@ "node": ">=6" } }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmmirror.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -17204,6 +17512,16 @@ "unfetch": "^5.0.0" } }, + "node_modules/isomorphic.js": { + "version": "0.2.5", + "resolved": "https://registry.npmmirror.com/isomorphic.js/-/isomorphic.js-0.2.5.tgz", + "integrity": "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==", + "peer": true, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -20060,6 +20378,32 @@ "node": ">= 0.8.0" } }, + "node_modules/lexical": { + "version": "0.23.1", + "resolved": "https://registry.npmmirror.com/lexical/-/lexical-0.23.1.tgz", + "integrity": "sha512-iuS72HcAYUemsCRQCm4XZzkGhZb8a9KagW+ee2TFfkkf9f3ZpUYSrobMpjYVZRkgMOx7Zk5VCPMxm1nouJTfnQ==" + }, + "node_modules/lib0": { + "version": "0.2.99", + "resolved": "https://registry.npmmirror.com/lib0/-/lib0-0.2.99.tgz", + "integrity": "sha512-vwztYuUf1uf/1zQxfzRfO5yzfNKhTtgOByCruuiQQxWQXnPb8Itaube5ylofcV0oM0aKal9Mv+S1s1Ky0UYP1w==", + "peer": true, + "dependencies": { + "isomorphic.js": "^0.2.4" + }, + "bin": { + "0ecdsa-generate-keypair": "bin/0ecdsa-generate-keypair.js", + "0gentesthtml": "bin/gentesthtml.js", + "0serve": "bin/0serve.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/lie": { "version": "3.3.0", "resolved": "https://registry.npmmirror.com/lie/-/lie-3.3.0.tgz", @@ -26988,7 +27332,6 @@ "version": "2.0.2", "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -27379,10 +27722,10 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "peer": true, + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -28969,9 +29312,10 @@ } }, "node_modules/terser": { - "version": "5.26.0", - "resolved": "https://registry.npmmirror.com/terser/-/terser-5.26.0.tgz", - "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", + "version": "5.38.1", + "resolved": "https://registry.npmmirror.com/terser/-/terser-5.38.1.tgz", + "integrity": "sha512-GWANVlPM/ZfYzuPHjq0nxT+EbOEDDN3Jwhwdg1D8TU8oSkktp8w64Uq4auuGLxFSoNTRDncTq2hQHX1Ld9KHkA==", + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -28986,20 +29330,24 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "peer": true, + "version": "5.3.11", + "resolved": "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", + "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, "peerDependencies": { "webpack": "^5.1.0" }, @@ -29015,11 +29363,38 @@ } } }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, "node_modules/terser-webpack-plugin/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "peer": true, "engines": { "node": ">=8" } @@ -29028,7 +29403,6 @@ "version": "27.5.1", "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -29038,11 +29412,35 @@ "node": ">= 10.13.0" } }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -31314,6 +31712,23 @@ "node": ">=12" } }, + "node_modules/yjs": { + "version": "13.6.23", + "resolved": "https://registry.npmmirror.com/yjs/-/yjs-13.6.23.tgz", + "integrity": "sha512-ExtnT5WIOVpkL56bhLeisG/N5c4fmzKn4k0ROVfJa5TY2QHbH7F0Wu2T5ZhR7ErsFWQEFafyrnSI8TPKVF9Few==", + "peer": true, + "dependencies": { + "lib0": "^0.2.99" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz", diff --git a/web/package.json b/web/package.json index 63f401451..cd4984e34 100644 --- a/web/package.json +++ b/web/package.json @@ -24,6 +24,7 @@ "@antv/g6": "^5.0.10", "@hookform/resolvers": "^3.9.1", "@js-preview/excel": "^1.7.8", + "@lexical/react": "^0.23.1", "@monaco-editor/react": "^4.6.0", "@radix-ui/react-alert-dialog": "^1.1.4", "@radix-ui/react-aspect-ratio": "^1.1.0", @@ -68,6 +69,7 @@ "input-otp": "^1.4.1", "js-base64": "^3.7.5", "jsencrypt": "^3.3.2", + "lexical": "^0.23.1", "lodash": "^4.17.21", "lucide-react": "^0.454.0", "mammoth": "^1.7.2", @@ -128,6 +130,7 @@ "react-dev-inspector": "^2.0.1", "remark-loader": "^6.0.0", "tailwindcss": "^3", + "terser-webpack-plugin": "^5.3.11", "ts-node": "^10.9.2", "typescript": "^5.0.3", "umi-plugin-icons": "^0.1.1" diff --git a/web/src/components/prompt-editor/index.css b/web/src/components/prompt-editor/index.css new file mode 100644 index 000000000..8f3050647 --- /dev/null +++ b/web/src/components/prompt-editor/index.css @@ -0,0 +1,76 @@ +.typeahead-popover { + background: #fff; + box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.3); + border-radius: 8px; + position: fixed; + z-index: 1000; +} + +.typeahead-popover ul { + list-style: none; + margin: 0; + max-height: 200px; + overflow-y: scroll; +} + +.typeahead-popover ul::-webkit-scrollbar { + display: none; +} + +.typeahead-popover ul { + -ms-overflow-style: none; + scrollbar-width: none; +} + +.typeahead-popover ul li { + margin: 0; + min-width: 180px; + font-size: 14px; + outline: none; + cursor: pointer; + border-radius: 8px; +} + +.typeahead-popover ul li.selected { + background: #eee; +} + +.typeahead-popover li { + margin: 0 8px 0 8px; + color: #050505; + cursor: pointer; + line-height: 16px; + font-size: 15px; + display: flex; + align-content: center; + flex-direction: row; + flex-shrink: 0; + background-color: #fff; + border: 0; +} + +.typeahead-popover li.active { + display: flex; + width: 20px; + height: 20px; + background-size: contain; +} + +.typeahead-popover li .text { + display: flex; + line-height: 20px; + flex-grow: 1; + min-width: 150px; +} + +.typeahead-popover li .icon { + display: flex; + width: 20px; + height: 20px; + user-select: none; + margin-right: 8px; + line-height: 16px; + background-size: contain; + background-repeat: no-repeat; + background-position: center; +} diff --git a/web/src/components/prompt-editor/index.tsx b/web/src/components/prompt-editor/index.tsx new file mode 100644 index 000000000..695d10047 --- /dev/null +++ b/web/src/components/prompt-editor/index.tsx @@ -0,0 +1,83 @@ +import { CodeHighlightNode, CodeNode } from '@lexical/code'; +import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin'; +import { + InitialConfigType, + LexicalComposer, +} from '@lexical/react/LexicalComposer'; +import { ContentEditable } from '@lexical/react/LexicalContentEditable'; +import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary'; +import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; +import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; +import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'; +import { HeadingNode, QuoteNode } from '@lexical/rich-text'; +import { + $getRoot, + $nodesOfType, + EditorState, + Klass, + LexicalNode, +} from 'lexical'; + +import { useTranslation } from 'react-i18next'; +import theme from './theme'; +import { VariableNode } from './variable-node'; +import VariablePickerMenuPlugin from './variable-picker-plugin'; + +// Catch any errors that occur during Lexical updates and log them +// or throw them as needed. If you don't throw them, Lexical will +// try to recover gracefully without losing user data. +function onError(error: Error) { + console.error(error); +} + +const Nodes: Array> = [ + HeadingNode, + QuoteNode, + CodeHighlightNode, + CodeNode, + VariableNode, +]; + +type IProps = { + value?: string; + onChange?: (value?: string) => void; +}; + +export function PromptEditor({ value, onChange }: IProps) { + const { t } = useTranslation(); + const initialConfig: InitialConfigType = { + namespace: 'PromptEditor', + theme, + onError, + nodes: Nodes, + }; + + function onValueChange(editorState: EditorState) { + editorState?.read(() => { + const listNodes = $nodesOfType(VariableNode); // to be removed + // const allNodes = $dfs(); + console.log('🚀 ~ onChange ~ allNodes:', listNodes); + + const text = $getRoot().getTextContent(); + onChange?.(text); + }); + } + + return ( + + + } + placeholder={ +
{t('common.pleaseInput')}
+ } + ErrorBoundary={LexicalErrorBoundary} + /> + + + + +
+ ); +} diff --git a/web/src/components/prompt-editor/theme.ts b/web/src/components/prompt-editor/theme.ts new file mode 100644 index 000000000..1cc2bc155 --- /dev/null +++ b/web/src/components/prompt-editor/theme.ts @@ -0,0 +1,43 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export default { + code: 'editor-code', + heading: { + h1: 'editor-heading-h1', + h2: 'editor-heading-h2', + h3: 'editor-heading-h3', + h4: 'editor-heading-h4', + h5: 'editor-heading-h5', + }, + image: 'editor-image', + link: 'editor-link', + list: { + listitem: 'editor-listitem', + nested: { + listitem: 'editor-nested-listitem', + }, + ol: 'editor-list-ol', + ul: 'editor-list-ul', + }, + ltr: 'ltr', + paragraph: 'editor-paragraph', + placeholder: 'editor-placeholder', + quote: 'editor-quote', + rtl: 'rtl', + text: { + bold: 'editor-text-bold', + code: 'editor-text-code', + hashtag: 'editor-text-hashtag', + italic: 'editor-text-italic', + overflowed: 'editor-text-overflowed', + strikethrough: 'editor-text-strikethrough', + underline: 'editor-text-underline', + underlineStrikethrough: 'editor-text-underlineStrikethrough', + }, +}; diff --git a/web/src/components/prompt-editor/variable-node.tsx b/web/src/components/prompt-editor/variable-node.tsx new file mode 100644 index 000000000..e2a8cc29f --- /dev/null +++ b/web/src/components/prompt-editor/variable-node.tsx @@ -0,0 +1,70 @@ +import i18n from '@/locales/config'; +import { BeginId } from '@/pages/flow/constant'; +import { DecoratorNode, LexicalNode, NodeKey } from 'lexical'; +import { ReactNode } from 'react'; +const prefix = BeginId + '@'; + +export class VariableNode extends DecoratorNode { + __value: string; + __label: string; + + static getType(): string { + return 'variable'; + } + + static clone(node: VariableNode): VariableNode { + return new VariableNode(node.__value, node.__label, node.__key); + } + + constructor(value: string, label: string, key?: NodeKey) { + super(key); + this.__value = value; + this.__label = label; + } + + createDOM(): HTMLElement { + const dom = document.createElement('span'); + dom.className = 'mr-1'; + + return dom; + } + + updateDOM(): false { + return false; + } + + decorate(): ReactNode { + let content: ReactNode = ( + {this.__label} + ); + if (this.__value.startsWith(prefix)) { + content = ( +
+ {i18n.t(`flow.begin`)} / {content} +
+ ); + } + return ( +
+ {content} +
+ ); + } + + getTextContent(): string { + return `{${this.__value}}`; + } +} + +export function $createVariableNode( + value: string, + label: string, +): VariableNode { + return new VariableNode(value, label); +} + +export function $isVariableNode( + node: LexicalNode | null | undefined, +): node is VariableNode { + return node instanceof VariableNode; +} diff --git a/web/src/components/prompt-editor/variable-picker-plugin.tsx b/web/src/components/prompt-editor/variable-picker-plugin.tsx new file mode 100644 index 000000000..4a30ad3bc --- /dev/null +++ b/web/src/components/prompt-editor/variable-picker-plugin.tsx @@ -0,0 +1,251 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; +import { + LexicalTypeaheadMenuPlugin, + MenuOption, + useBasicTypeaheadTriggerMatch, +} from '@lexical/react/LexicalTypeaheadMenuPlugin'; +import { + $createParagraphNode, + $createTextNode, + $getRoot, + $getSelection, + $isRangeSelection, + TextNode, +} from 'lexical'; +import { + ReactElement, + useCallback, + useContext, + useEffect, + useRef, +} from 'react'; +import * as ReactDOM from 'react-dom'; + +import { FlowFormContext } from '@/pages/flow/context'; +import { useBuildComponentIdSelectOptions } from '@/pages/flow/hooks/use-get-begin-query'; +import { $createVariableNode } from './variable-node'; + +import './index.css'; +class VariableInnerOption extends MenuOption { + label: string; + value: string; + + constructor(label: string, value: string) { + super(value); + this.label = label; + this.value = value; + } +} + +class VariableOption extends MenuOption { + label: ReactElement | string; + title: string; + options: VariableInnerOption[]; + + constructor( + label: ReactElement | string, + title: string, + options: VariableInnerOption[], + ) { + super(title); + this.label = label; + this.title = title; + this.options = options; + } +} + +function VariablePickerMenuItem({ + index, + option, + selectOptionAndCleanUp, +}: { + index: number; + option: VariableOption; + selectOptionAndCleanUp: ( + option: VariableOption | VariableInnerOption, + ) => void; +}) { + return ( +
  • +
    + {option.title} +
      + {option.options.map((x) => ( +
    • selectOptionAndCleanUp(x)} + className="hover:bg-slate-300 p-1" + > + {x.label} +
    • + ))} +
    +
    +
  • + ); +} + +export default function VariablePickerMenuPlugin({ + value, +}: { + value?: string; +}): JSX.Element { + const [editor] = useLexicalComposerContext(); + const isFirstRender = useRef(true); + + const node = useContext(FlowFormContext); + + const checkForTriggerMatch = useBasicTypeaheadTriggerMatch('/', { + minLength: 0, + }); + + const setQueryString = useCallback(() => {}, []); + + const options = useBuildComponentIdSelectOptions(node?.id, node?.parentId); + + const nextOptions: VariableOption[] = options.map( + (x) => + new VariableOption( + x.label, + x.title, + x.options.map((y) => new VariableInnerOption(y.label, y.value)), + ), + ); + + const findLabelByValue = useCallback( + (value: string) => { + const children = options.reduce>( + (pre, cur) => { + return pre.concat(cur.options); + }, + [], + ); + + return children.find((x) => x.value === value)?.label; + }, + [options], + ); + + const onSelectOption = useCallback( + ( + selectedOption: VariableOption | VariableInnerOption, + nodeToRemove: TextNode | null, + closeMenu: () => void, + ) => { + editor.update(() => { + const selection = $getSelection(); + + if (!$isRangeSelection(selection) || selectedOption === null) { + return; + } + + if (nodeToRemove) { + nodeToRemove.remove(); + } + + selection.insertNodes([ + $createVariableNode( + (selectedOption as VariableInnerOption).value, + selectedOption.label as string, + ), + ]); + + closeMenu(); + }); + }, + [editor], + ); + + const parseTextToVariableNodes = useCallback( + (text: string) => { + const paragraph = $createParagraphNode(); + + // Regular expression to match content within {} + const regex = /{([^}]*)}/g; + let match; + let lastIndex = 0; + + while ((match = regex.exec(text)) !== null) { + const { 1: content, index, 0: template } = match; + + // Add the previous text part (if any) + if (index > lastIndex) { + const textNode = $createTextNode(text.slice(lastIndex, index)); + + paragraph.append(textNode); + } + + // Add variable node or text node + const label = findLabelByValue(content); + if (label) { + paragraph.append($createVariableNode(content, label)); + } else { + paragraph.append($createTextNode(template)); + } + + // Update index + lastIndex = regex.lastIndex; + } + + // Add the last part of text (if any) + if (lastIndex < text.length) { + const textNode = $createTextNode(text.slice(lastIndex)); + paragraph.append(textNode); + } + + $getRoot().clear().append(paragraph); + }, + [findLabelByValue], + ); + + useEffect(() => { + if (editor && value && isFirstRender.current) { + isFirstRender.current = false; + editor.update(() => { + parseTextToVariableNodes(value); + }); + } + }, [parseTextToVariableNodes, editor, value]); + + return ( + + onQueryChange={setQueryString} + onSelectOption={onSelectOption} + triggerFn={checkForTriggerMatch} + options={nextOptions} + menuRenderFn={(anchorElementRef, { selectOptionAndCleanUp }) => + anchorElementRef.current && options.length + ? ReactDOM.createPortal( +
    +
      + {nextOptions.map((option, i: number) => ( + + ))} +
    +
    , + anchorElementRef.current, + ) + : null + } + /> + ); +} diff --git a/web/src/pages/dataset/testing/index.tsx b/web/src/pages/dataset/testing/index.tsx index 1aab3572b..992ff0243 100644 --- a/web/src/pages/dataset/testing/index.tsx +++ b/web/src/pages/dataset/testing/index.tsx @@ -6,6 +6,12 @@ const list = new Array(15).fill({ content: `Lorem ipsum odor amet, consectetuer adipiscing elit. Ullamcorper vulputate id laoreet malesuada commodo molestie. Lectus convallis class euismod; consequat in curabitur. Ablandit praesent inceptos nibh placerat lectus fringilla finibus. Hac vivamus id scelerisque et gravida nec ligula et non. Consectetur eu himenaeos eget felis quis habitant tellus. Tellus commodo inceptos litora habitant per himenaeos faucibus pretium. Gravida velit pretium amet purus rhoncus taciti. `, }); +const SimilarityList = [ + { label: '混合相似度', value: 45.88 }, + { label: '关键词似度', value: 45.88 }, + { label: '向量相似度', value: 45.88 }, +]; + export default function RetrievalTesting() { return (
    @@ -13,7 +19,7 @@ export default function RetrievalTesting() {
    -

    +

    15 Results from 3 files

    @@ -25,24 +31,18 @@ export default function RetrievalTesting() {
    - - 混合相似度 45.88 - - - 关键词似度 45.88 - - - 向量相似度 45.88 - + {SimilarityList.map((x, idx) => ( + + {x.label} + + {x.value} + + + ))}
    diff --git a/web/src/pages/flow/canvas/node/generate-node.tsx b/web/src/pages/flow/canvas/node/generate-node.tsx index 01b4829fd..255eccd99 100644 --- a/web/src/pages/flow/canvas/node/generate-node.tsx +++ b/web/src/pages/flow/canvas/node/generate-node.tsx @@ -2,11 +2,8 @@ import LLMLabel from '@/components/llm-select/llm-label'; import { useTheme } from '@/components/theme-provider'; import { IGenerateNode } from '@/interfaces/database/flow'; import { Handle, NodeProps, Position } from '@xyflow/react'; -import { Flex } from 'antd'; import classNames from 'classnames'; import { get } from 'lodash'; -import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query'; -import { IGenerateParameter } from '../../interface'; import { LeftHandleStyle, RightHandleStyle } from './handle-icon'; import styles from './index.less'; import NodeHeader from './node-header'; @@ -17,8 +14,6 @@ export function GenerateNode({ isConnectable = true, selected, }: NodeProps) { - const parameters: IGenerateParameter[] = get(data, 'form.parameters', []); - const getLabel = useGetComponentLabelByValue(id); const { theme } = useTheme(); return (
    - - {parameters.map((x) => ( - - - - {getLabel(x.component_id)} - - - ))} -
    ); } diff --git a/web/src/pages/flow/constant.tsx b/web/src/pages/flow/constant.tsx index a44511ca5..05580f847 100644 --- a/web/src/pages/flow/constant.tsx +++ b/web/src/pages/flow/constant.tsx @@ -671,7 +671,6 @@ export const RestrictedUpstreamMap = { Operator.Message, Operator.Generate, Operator.RewriteQuestion, - Operator.Categorize, Operator.Relevant, ], [Operator.KeywordExtract]: [ diff --git a/web/src/pages/flow/context.ts b/web/src/pages/flow/context.ts new file mode 100644 index 000000000..fe51d8d6d --- /dev/null +++ b/web/src/pages/flow/context.ts @@ -0,0 +1,6 @@ +import { RAGFlowNodeType } from '@/interfaces/database/flow'; +import { createContext } from 'react'; + +export const FlowFormContext = createContext( + undefined, +); diff --git a/web/src/pages/flow/flow-drawer/index.tsx b/web/src/pages/flow/flow-drawer/index.tsx index 487e746be..3dc822be0 100644 --- a/web/src/pages/flow/flow-drawer/index.tsx +++ b/web/src/pages/flow/flow-drawer/index.tsx @@ -2,7 +2,7 @@ import { useTranslate } from '@/hooks/common-hooks'; import { IModalProps } from '@/interfaces/common'; import { CloseOutlined } from '@ant-design/icons'; import { Drawer, Flex, Form, Input } from 'antd'; -import { lowerFirst } from 'lodash'; +import { get, isPlainObject, lowerFirst } from 'lodash'; import { Play } from 'lucide-react'; import { useEffect, useRef } from 'react'; import { BeginId, Operator, operatorMap } from '../constant'; @@ -40,10 +40,15 @@ import WikipediaForm from '../form/wikipedia-form'; import YahooFinanceForm from '../form/yahoo-finance-form'; import { useHandleFormValuesChange, useHandleNodeNameChange } from '../hooks'; import OperatorIcon from '../operator-icon'; -import { getDrawerWidth, needsSingleStepDebugging } from '../utils'; +import { + buildCategorizeListFromObject, + getDrawerWidth, + needsSingleStepDebugging, +} from '../utils'; import SingleDebugDrawer from './single-debug-drawer'; import { RAGFlowNodeType } from '@/interfaces/database/flow'; +import { FlowFormContext } from '../context'; import { RunTooltip } from '../flow-tooltip'; import IterationForm from '../form/iteration-from'; import styles from './index.less'; @@ -122,10 +127,21 @@ const FormDrawer = ({ if (node?.id !== previousId.current) { form.resetFields(); } - form.setFieldsValue(node?.data?.form); + + if (operatorName === Operator.Categorize) { + const items = buildCategorizeListFromObject( + get(node, 'data.form.category_description', {}), + ); + const formData = node?.data?.form; + if (isPlainObject(formData)) { + form.setFieldsValue({ ...formData, items }); + } + } else { + form.setFieldsValue(node?.data?.form); + } previousId.current = node?.id; } - }, [visible, form, node?.data?.form, node?.id]); + }, [visible, form, node?.data?.form, node?.id, node, operatorName]); return (
    {visible && ( - + + + )}
    {singleDebugDrawerVisible && ( diff --git a/web/src/pages/flow/form/categorize-form/hooks.ts b/web/src/pages/flow/form/categorize-form/hooks.ts index 3a4af97ab..a7e8f23f3 100644 --- a/web/src/pages/flow/form/categorize-form/hooks.ts +++ b/web/src/pages/flow/form/categorize-form/hooks.ts @@ -1,38 +1,10 @@ -import get from 'lodash/get'; -import omit from 'lodash/omit'; -import { useCallback, useEffect } from 'react'; import { ICategorizeItem, ICategorizeItemResult, - IOperatorForm, -} from '../../interface'; -import useGraphStore from '../../store'; - -/** - * convert the following object into a list - * - * { - "product_related": { - "description": "The question is about product usage, appearance and how it works.", - "examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?", - "to": "generate:0" - } - } -*/ -const buildCategorizeListFromObject = ( - categorizeItem: ICategorizeItemResult, -) => { - // Categorize's to field has two data sources, with edges as the data source. - // Changes in the edge or to field need to be synchronized to the form field. - return Object.keys(categorizeItem) - .reduce>((pre, cur) => { - // synchronize edge data to the to field - - pre.push({ name: cur, ...categorizeItem[cur] }); - return pre; - }, []) - .sort((a, b) => a.index - b.index); -}; +} from '@/interfaces/database/flow'; +import omit from 'lodash/omit'; +import { useCallback } from 'react'; +import { IOperatorForm } from '../../interface'; /** * Convert the list in the following form into an object @@ -58,12 +30,7 @@ const buildCategorizeObjectFromList = (list: Array) => { export const useHandleFormValuesChange = ({ onValuesChange, - form, - nodeId, }: IOperatorForm) => { - const getNode = useGraphStore((state) => state.getNode); - const node = getNode(nodeId); - const handleValuesChange = useCallback( (changedValues: any, values: any) => { onValuesChange?.(changedValues, { @@ -74,14 +41,5 @@ export const useHandleFormValuesChange = ({ [onValuesChange], ); - useEffect(() => { - const items = buildCategorizeListFromObject( - get(node, 'data.form.category_description', {}), - ); - form?.setFieldsValue({ - items, - }); - }, [form, node]); - return { handleValuesChange }; }; diff --git a/web/src/pages/flow/form/generate-form/index.tsx b/web/src/pages/flow/form/generate-form/index.tsx index ad6396d9e..076ed2518 100644 --- a/web/src/pages/flow/form/generate-form/index.tsx +++ b/web/src/pages/flow/form/generate-form/index.tsx @@ -1,11 +1,11 @@ import LLMSelect from '@/components/llm-select'; import MessageHistoryWindowSizeItem from '@/components/message-history-window-size-item'; +import { PromptEditor } from '@/components/prompt-editor'; import { useTranslate } from '@/hooks/common-hooks'; -import { Form, Input, Switch } from 'antd'; +import { Form, Switch } from 'antd'; import { IOperatorForm } from '../../interface'; -import DynamicParameters from './dynamic-parameters'; -const GenerateForm = ({ onValuesChange, form, node }: IOperatorForm) => { +const GenerateForm = ({ onValuesChange, form }: IOperatorForm) => { const { t } = useTranslate('flow'); return ( @@ -35,7 +35,7 @@ const GenerateForm = ({ onValuesChange, form, node }: IOperatorForm) => { }, ]} > - + { - ); }; diff --git a/web/src/pages/flow/form/template-form/index.tsx b/web/src/pages/flow/form/template-form/index.tsx index afe755583..ddf5c7883 100644 --- a/web/src/pages/flow/form/template-form/index.tsx +++ b/web/src/pages/flow/form/template-form/index.tsx @@ -1,9 +1,9 @@ -import { Form, Input } from 'antd'; +import { PromptEditor } from '@/components/prompt-editor'; +import { Form } from 'antd'; import { useTranslation } from 'react-i18next'; import { IOperatorForm } from '../../interface'; -import DynamicParameters from '../generate-form/dynamic-parameters'; -const TemplateForm = ({ onValuesChange, form, node }: IOperatorForm) => { +const TemplateForm = ({ onValuesChange, form }: IOperatorForm) => { const { t } = useTranslation(); return ( @@ -15,10 +15,8 @@ const TemplateForm = ({ onValuesChange, form, node }: IOperatorForm) => { layout={'vertical'} > - + - - ); }; diff --git a/web/src/pages/flow/utils.ts b/web/src/pages/flow/utils.ts index 5ce73247b..dcd0867dd 100644 --- a/web/src/pages/flow/utils.ts +++ b/web/src/pages/flow/utils.ts @@ -1,5 +1,6 @@ import { DSLComponents, + ICategorizeItem, ICategorizeItemResult, RAGFlowNodeType, } from '@/interfaces/database/flow'; @@ -389,3 +390,29 @@ export const generateDuplicateNode = ( dragHandle: getNodeDragHandle(label), }; }; + +/** + * convert the following object into a list + * + * { + "product_related": { + "description": "The question is about product usage, appearance and how it works.", + "examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?", + "to": "generate:0" + } + } +*/ +export const buildCategorizeListFromObject = ( + categorizeItem: ICategorizeItemResult, +) => { + // Categorize's to field has two data sources, with edges as the data source. + // Changes in the edge or to field need to be synchronized to the form field. + return Object.keys(categorizeItem) + .reduce>((pre, cur) => { + // synchronize edge data to the to field + + pre.push({ name: cur, ...categorizeItem[cur] }); + return pre; + }, []) + .sort((a, b) => a.index - b.index); +}; diff --git a/web/tailwind.config.js b/web/tailwind.config.js index 94df6b51c..0b0ff1d2c 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -38,6 +38,7 @@ module.exports = { 'colors-text-functional-danger': 'var(--colors-text-functional-danger)', 'colors-text-inverse-strong': 'var(--colors-text-inverse-strong)', 'colors-text-persist-light': 'var(--colors-text-persist-light)', + 'colors-text-inverse-weak': 'var(--colors-text-inverse-weak)', primary: { DEFAULT: 'hsl(var(--primary))', diff --git a/web/tailwind.css b/web/tailwind.css index de3c66387..54af4ba53 100644 --- a/web/tailwind.css +++ b/web/tailwind.css @@ -57,6 +57,7 @@ --colors-text-functional-danger: rgba(255, 81, 81, 1); --colors-text-inverse-strong: rgba(255, 255, 255, 1); --colors-text-persist-light: rgba(255, 255, 255, 1); + --colors-text-inverse-weak: rgba(184, 181, 203, 1); } .dark { @@ -138,6 +139,7 @@ --colors-text-functional-danger: rgba(255, 81, 81, 1); --colors-text-inverse-strong: rgba(17, 16, 23, 1); --colors-text-persist-light: rgba(255, 255, 255, 1); + --colors-text-inverse-weak: rgba(84, 80, 106, 1); } }