From 12f1084612ae1a3e310d18f2dbe4b87762083292 Mon Sep 17 00:00:00 2001 From: xion Date: Thu, 26 Sep 2024 21:08:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=EF=BC=8C=E5=AF=B9deck=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 + plugins/flex.js | 25 +++ pnpm-lock.yaml | 46 +++++ src/App.tsx | 2 +- src/components/card/CardBlank.tsx | 17 ++ src/globals.css | 40 ++++ src/hooks/index.ts | 1 + src/hooks/message.tsx | 22 +++ src/pages/ai-chat/AiModule.tsx | 102 ++++++++-- src/pages/ai-chat/store/ai-store.ts | 64 +++++- src/pages/code-editor/index.tsx | 29 ++- src/pages/container/edit/List.tsx | 5 +- src/pages/container/index.tsx | 3 +- src/pages/container/module/Select.tsx | 39 ++++ src/pages/map/index.tsx | 67 ++++++- src/pages/panel/edit/List.tsx | 185 +++++++++--------- src/pages/panel/flow/Flow.tsx | 117 +++++++++-- src/pages/panel/flow/message.ts | 2 + .../panel/flow/properties/NodeProperties.tsx | 103 ++++++++++ src/pages/panel/layouts/index.tsx | 14 +- src/pages/panel/store/panel.ts | 19 ++ src/pages/prompt/edit/List.tsx | 4 +- src/pages/prompt/store/prompt.ts | 10 +- src/utils/index.ts | 1 + src/utils/is-null.ts | 9 + src/utils/nanoid.ts | 5 + tailwind.config.js | 23 ++- theme | 2 +- vite.config.ts | 6 +- 29 files changed, 801 insertions(+), 165 deletions(-) create mode 100644 plugins/flex.js create mode 100644 src/components/card/CardBlank.tsx create mode 100644 src/hooks/index.ts create mode 100644 src/hooks/message.tsx create mode 100644 src/pages/container/module/Select.tsx create mode 100644 src/pages/panel/flow/message.ts create mode 100644 src/pages/panel/flow/properties/NodeProperties.tsx create mode 100644 src/utils/index.ts create mode 100644 src/utils/is-null.ts create mode 100644 src/utils/nanoid.ts diff --git a/package.json b/package.json index 004b134..ad2ab8e 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "clsx": "^2.1.1", "copy-to-clipboard": "^3.3.3", "d3": "^7.9.0", + "eventemitter3": "^5.0.1", "immer": "^10.1.1", "lodash-es": "^4.17.21", "marked": "^14.1.2", @@ -42,8 +43,10 @@ "devDependencies": { "@eslint/js": "^9.11.0", "@tailwindcss/aspect-ratio": "^0.4.2", + "@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/typography": "^0.5.15", "@types/d3": "^7.4.3", + "@types/lodash-es": "^4.17.12", "@types/node": "^22.5.5", "@types/react": "^18.3.8", "@types/react-dom": "^18.3.0", @@ -53,6 +56,7 @@ "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.12", "globals": "^15.9.0", + "postcss-import": "^16.1.0", "react-is": "^18.3.1", "tailwind-merge": "^2.5.2", "tailwindcss": "^3.4.13", diff --git a/plugins/flex.js b/plugins/flex.js new file mode 100644 index 0000000..ad53cd5 --- /dev/null +++ b/plugins/flex.js @@ -0,0 +1,25 @@ +const plugin = require('tailwindcss/plugin'); + +const flexCenterBaseStyles = { + display: 'flex', + 'justify-content': 'center', + 'align-items': 'center', +}; + +/** flex 居中 */ +const flexCenter = plugin(function ({ addUtilities }) { + addUtilities({ + /** flex 居中 */ + '.flex-row-center': flexCenterBaseStyles, + '.flex-col-center': { ...flexCenterBaseStyles, 'flex-direction': 'column' }, + '.layout-menu': {}, + '.scrollbar': {}, + '.card': {}, + '.card-title': {}, + '.card-subtitle': {}, + '.card-body': {}, + '.card-footer': {}, + }); +}); + +module.exports = flexCenter; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ebd977f..3928fbc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -53,6 +53,9 @@ importers: d3: specifier: ^7.9.0 version: 7.9.0 + eventemitter3: + specifier: ^5.0.1 + version: 5.0.1 immer: specifier: ^10.1.1 version: 10.1.1 @@ -93,12 +96,18 @@ importers: '@tailwindcss/aspect-ratio': specifier: ^0.4.2 version: 0.4.2(tailwindcss@3.4.13) + '@tailwindcss/line-clamp': + specifier: ^0.4.4 + version: 0.4.4(tailwindcss@3.4.13) '@tailwindcss/typography': specifier: ^0.5.15 version: 0.5.15(tailwindcss@3.4.13) '@types/d3': specifier: ^7.4.3 version: 7.4.3 + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 '@types/node': specifier: ^22.5.5 version: 22.5.5 @@ -126,6 +135,9 @@ importers: globals: specifier: ^15.9.0 version: 15.9.0 + postcss-import: + specifier: ^16.1.0 + version: 16.1.0(postcss@8.4.47) react-is: specifier: ^18.3.1 version: 18.3.1 @@ -733,6 +745,11 @@ packages: peerDependencies: tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1' + '@tailwindcss/line-clamp@0.4.4': + resolution: {integrity: sha512-5U6SY5z8N42VtrCrKlsTAA35gy2VSyYtHWCsg1H87NU1SXnEfekTVlrga9fzUDrrHcGi2Lb5KenUWb4lRQT5/g==} + peerDependencies: + tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1' + '@tailwindcss/typography@0.5.15': resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==} peerDependencies: @@ -855,6 +872,12 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.9': + resolution: {integrity: sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -1861,6 +1884,12 @@ packages: peerDependencies: postcss: ^8.0.0 + postcss-import@16.1.0: + resolution: {integrity: sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==} + engines: {node: '>=18.0.0'} + peerDependencies: + postcss: ^8.0.0 + postcss-js@4.0.1: resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} @@ -3142,6 +3171,10 @@ snapshots: dependencies: tailwindcss: 3.4.13 + '@tailwindcss/line-clamp@0.4.4(tailwindcss@3.4.13)': + dependencies: + tailwindcss: 3.4.13 + '@tailwindcss/typography@0.5.15(tailwindcss@3.4.13)': dependencies: lodash.castarray: 4.4.0 @@ -3300,6 +3333,12 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.9 + + '@types/lodash@4.17.9': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -4428,6 +4467,13 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.8 + postcss-import@16.1.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + postcss-js@4.0.1(postcss@8.4.47): dependencies: camelcase-css: 2.0.1 diff --git a/src/App.tsx b/src/App.tsx index 76b6cc0..1e929a3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; -import { ConfigProvider } from 'antd'; +import { ConfigProvider, App as AntApp } from 'antd'; import { App as ContainerApp } from './pages/container'; import { App as PanelApp } from './pages/panel'; import { App as PublishApp } from './pages/publish'; diff --git a/src/components/card/CardBlank.tsx b/src/components/card/CardBlank.tsx new file mode 100644 index 0000000..332cf2e --- /dev/null +++ b/src/components/card/CardBlank.tsx @@ -0,0 +1,17 @@ +import clsx from 'clsx'; +import twMerge from 'tailwind-merge'; + +type CardBlankProps = { + number?: number; + className?: string; +}; +export const CardBlank = (props: CardBlankProps) => { + const { number = 4, className } = props; + return ( + <> + {new Array(number).fill(0).map((_, index) => { + return
; + })} + + ); +}; diff --git a/src/globals.css b/src/globals.css index 1ad8d9b..51fd0b6 100644 --- a/src/globals.css +++ b/src/globals.css @@ -3,6 +3,13 @@ @tailwind utilities; @layer base { + html, + body { + width: 100%; + height: 100%; + font-size: 16px; + font-family: 'Montserrat', sans-serif; + } h1 { @apply text-2xl font-bold; } @@ -12,7 +19,40 @@ h3 { @apply text-lg font-bold; } +} + +@layer components { + .btn { + @apply bg-blue-500 text-white font-bold py-2 px-4 rounded; + } + .card { + @apply bg-white shadow-md rounded-lg p-4; + .card-title { + @apply text-lg font-bold; + } + .card-subtitle { + @apply text-sm text-gray-500; + } + .card-description { + @apply text-gray-700 break-words; + } + .card-code { + @apply bg-gray-100 p-2; + } + .card-body { + @apply text-gray-700; + } + .card-footer { + @apply text-sm text-gray-500; + } + } +} + +@layer utilities { .layout-menu { @apply bg-gray-900 p-2 text-white flex justify-between h-12; } + .bg-custom-blue { + background-color: #3490dc; + } } diff --git a/src/hooks/index.ts b/src/hooks/index.ts new file mode 100644 index 0000000..f545587 --- /dev/null +++ b/src/hooks/index.ts @@ -0,0 +1 @@ +export * from './message'; diff --git a/src/hooks/message.tsx b/src/hooks/message.tsx new file mode 100644 index 0000000..57af24a --- /dev/null +++ b/src/hooks/message.tsx @@ -0,0 +1,22 @@ +import { App } from 'antd'; + +export const useMessage = () => { + const { message: antMessage, modal, notification } = App.useApp(); + return { + success: antMessage.success, + error: antMessage.error, + warning: antMessage.warning, + info: antMessage.info, + loading: antMessage.loading, + open: antMessage.open, + destroy: antMessage.destroy, + modal: modal, + notification: notification, + message: antMessage, + com: ( + <> + + + ), + }; +}; diff --git a/src/pages/ai-chat/AiModule.tsx b/src/pages/ai-chat/AiModule.tsx index 3e3854c..3026ced 100644 --- a/src/pages/ai-chat/AiModule.tsx +++ b/src/pages/ai-chat/AiModule.tsx @@ -1,36 +1,110 @@ import { useShallow } from 'zustand/react/shallow'; import { useAiStore } from './store/ai-store'; import { CloseOutlined } from '@ant-design/icons'; -import { Button } from 'antd'; +import { Button, Form, Input } from 'antd'; +import { useEffect } from 'react'; +import { TextArea } from '../container/components/TextArea'; +import clsx from 'clsx'; +import { marked } from 'marked'; export const AiMoudle = () => { + const [form] = Form.useForm(); const aiStore = useAiStore( useShallow((state) => { return { open: state.open, setOpen: state.setOpen, runAi: state.runAi, + formData: state.formData, + setFormData: state.setFormData, + messages: state.messages, + setMessages: state.setMessage, }; }), ); - if (!aiStore.open) { - return null; - } + + useEffect(() => { + if (!aiStore.open) { + return; + } + const isNull = JSON.stringify(aiStore.formData) === '{}'; + if (!isNull) { + form.setFieldsValue(aiStore.formData); + } else { + form.setFieldsValue({ inputs: [] }); + } + }, [aiStore.open, aiStore.formData]); + useEffect(() => { + if (!aiStore.open) { + aiStore.setMessages([]); + } + }, [aiStore.open]); + const onSend = () => { + const data = form.getFieldsValue(); + aiStore.setFormData(data); + aiStore.runAi(); + }; return ( -
+

Ai Moudle

-
-
chat message
-
- +
+
+
chat message
+ {aiStore?.messages?.map((message, index) => { + const html = marked.parse(message?.content); + return ( +
+
{message?.role}
+
+
+
+ ); + })} +
+
+
+ + + + + {(fields, { add, remove }) => { + return ( + <> + {fields.map((field, index) => { + const key = form.getFieldValue(['inputs', index, 'key']); + console.log('key', key); + const isTitle = key === 'title'; + + return ( +
+ + +