diff --git a/frontend/package-lock.json b/frontend/package-lock.json index be62f2df..d49c8220 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -37,6 +37,7 @@ "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-switch": "^1.1.2", "@radix-ui/react-tabs": "^1.1.2", + "@radix-ui/react-toast": "^1.2.4", "@reduxjs/toolkit": "^2.0.1", "@types/recharts": "^1.8.29", "ajv": "^8.17.1", @@ -60,8 +61,8 @@ "@types/dagre": "^0.7.52", "@types/fs-extra": "^11.0.4", "@types/node": "^20.17.10", - "@types/react": "^18.2.43", - "@types/react-dom": "^18.2.17", + "@types/react": "^18.3.18", + "@types/react-dom": "^18.3.5", "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.14.0", "@vitejs/plugin-react": "^4.2.1", @@ -2650,6 +2651,39 @@ } } }, + "node_modules/@radix-ui/react-toast": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-toast/-/react-toast-1.2.4.tgz", + "integrity": "sha512-Sch9idFJHJTMH9YNpxxESqABcAFweJG4tKv+0zo0m5XBvUSL8FM5xKcJLFLXononpePs8IclyX1KieL5SDUNgA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", @@ -3378,21 +3412,21 @@ "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" }, "node_modules/@types/react": { - "version": "18.3.12", - "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.3.12.tgz", - "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "version": "18.3.18", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "version": "18.3.5", + "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", "devOptional": true, - "dependencies": { - "@types/react": "*" + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@types/recharts": { diff --git a/frontend/package.json b/frontend/package.json index fc8b3d0c..035a4a3b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -39,6 +39,7 @@ "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-switch": "^1.1.2", "@radix-ui/react-tabs": "^1.1.2", + "@radix-ui/react-toast": "^1.2.4", "@reduxjs/toolkit": "^2.0.1", "@types/recharts": "^1.8.29", "ajv": "^8.17.1", @@ -62,8 +63,8 @@ "@types/dagre": "^0.7.52", "@types/fs-extra": "^11.0.4", "@types/node": "^20.17.10", - "@types/react": "^18.2.43", - "@types/react-dom": "^18.2.17", + "@types/react": "^18.3.18", + "@types/react-dom": "^18.3.5", "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.14.0", "@vitejs/plugin-react": "^4.2.1", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 4f3c537e..8ec00f53 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,17 +1,17 @@ import React from 'react'; -import { RouterProvider } from 'react-router-dom'; -import { ConfigProvider } from 'antd'; +import {RouterProvider} from 'react-router-dom'; +import {ConfigProvider} from 'antd'; import zhCN from 'antd/locale/zh_CN'; import router from './router'; -import { Toaster } from "@/components/ui/toaster"; const App: React.FC = () => { - return ( - - - - - ); + return ( + + + + + + ); }; export default App; \ No newline at end of file diff --git a/frontend/src/components/ui/toast.tsx b/frontend/src/components/ui/toast.tsx index e8e4dc63..4cba14ab 100644 --- a/frontend/src/components/ui/toast.tsx +++ b/frontend/src/components/ui/toast.tsx @@ -14,7 +14,7 @@ const ToastViewport = React.forwardRef< - {toasts.map(function ({ id, title, description, action, ...props }) { - return ( - -
- {title && {title}} - {description && ( - {description} - )} -
- {action} - -
- ) - })} + {toasts.map(({ id, title, description, action, ...props }) => ( + +
+ {title && {title}} + {description && ( + {description} + )} +
+ {action} + +
+ ))} ) diff --git a/frontend/src/index.css b/frontend/src/index.css index 7453df7e..7d150d81 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -3,89 +3,90 @@ @tailwind utilities; @layer base { - :root { - --background: 0 0% 100%; - --foreground: 0 0% 3.9%; + :root { + --background: 0 0% 100%; + --foreground: 0 0% 3.9%; - --card: 0 0% 100%; - --card-foreground: 0 0% 3.9%; - - --popover: 0 0% 100%; - --popover-foreground: 0 0% 3.9%; - - --primary: 0 0% 9%; - --primary-foreground: 0 0% 98%; - - --secondary: 0 0% 96.1%; - --secondary-foreground: 0 0% 9%; - - --muted: 0 0% 96.1%; - --muted-foreground: 0 0% 45.1%; - - --accent: 0 0% 96.1%; - --accent-foreground: 0 0% 9%; - - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 0 0% 98%; + --card: 0 0% 100%; + --card-foreground: 0 0% 3.9%; - --border: 0 0% 89.8%; - --input: 0 0% 89.8%; - --ring: 0 0% 3.9%; - - --radius: 0.5rem; - - --chart-1: 12 76% 61%; - - --chart-2: 173 58% 39%; - - --chart-3: 197 37% 24%; - - --chart-4: 43 74% 66%; - - --chart-5: 27 87% 67%; - } - - .dark { - --background: 0 0% 3.9%; - --foreground: 0 0% 98%; - - --card: 0 0% 3.9%; - --card-foreground: 0 0% 98%; - - --popover: 0 0% 3.9%; - --popover-foreground: 0 0% 98%; - - --primary: 0 0% 98%; - --primary-foreground: 0 0% 9%; - - --secondary: 0 0% 14.9%; - --secondary-foreground: 0 0% 98%; - - --muted: 0 0% 14.9%; - --muted-foreground: 0 0% 63.9%; - - --accent: 0 0% 14.9%; - --accent-foreground: 0 0% 98%; - - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 0 0% 98%; - - --border: 0 0% 14.9%; - --input: 0 0% 14.9%; - --ring: 0 0% 83.1%; - --chart-1: 220 70% 50%; - --chart-2: 160 60% 45%; - --chart-3: 30 80% 55%; - --chart-4: 280 65% 60%; - --chart-5: 340 75% 55%; - } + --popover: 0 0% 100%; + --popover-foreground: 0 0% 3.9%; + + --primary: 0 0% 9%; + --primary-foreground: 0 0% 98%; + + --secondary: 0 0% 96.1%; + --secondary-foreground: 0 0% 9%; + + --muted: 0 0% 96.1%; + --muted-foreground: 0 0% 45.1%; + + --accent: 0 0% 96.1%; + --accent-foreground: 0 0% 9%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + + --border: 0 0% 89.8%; + --input: 0 0% 89.8%; + --ring: 0 0% 3.9%; + + --radius: 0.5rem; + + --chart-1: 12 76% 61%; + + --chart-2: 173 58% 39%; + + --chart-3: 197 37% 24%; + + --chart-4: 43 74% 66%; + + --chart-5: 27 87% 67%; + } + + .dark { + --background: 0 0% 3.9%; + --foreground: 0 0% 98%; + + --card: 0 0% 3.9%; + --card-foreground: 0 0% 98%; + + --popover: 0 0% 3.9%; + --popover-foreground: 0 0% 98%; + + --primary: 0 0% 98%; + --primary-foreground: 0 0% 9%; + + --secondary: 0 0% 14.9%; + --secondary-foreground: 0 0% 98%; + + --muted: 0 0% 14.9%; + --muted-foreground: 0 0% 63.9%; + + --accent: 0 0% 14.9%; + --accent-foreground: 0 0% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + + --border: 0 0% 14.9%; + --input: 0 0% 14.9%; + --ring: 0 0% 83.1%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } } - + @layer base { - * { - @apply border-border; - } - body { - @apply bg-background text-foreground; - } + * { + @apply border-border; + } + + body { + @apply bg-background text-foreground; + } } \ No newline at end of file diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index b1bff47e..f0e8e31e 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -1,13 +1,15 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import { RouterProvider } from 'react-router-dom'; -import { Provider } from 'react-redux'; +import {RouterProvider} from 'react-router-dom'; +import {Provider} from 'react-redux'; import router from './router'; import store from './store'; import './index.css'; +import {Toaster} from "@/components/ui/toaster.tsx"; ReactDOM.createRoot(document.getElementById('root')!).render( - - - + + + + ); \ No newline at end of file diff --git a/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx b/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx index 9eb2789d..7e804fbd 100644 --- a/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx +++ b/frontend/src/pages/Deploy/ProjectGroup/List/components/ProjectGroupModal.tsx @@ -5,6 +5,7 @@ import { DialogHeader, DialogTitle, DialogFooter, + DialogDescription, } from "@/components/ui/dialog"; import {Button} from "@/components/ui/button"; import { @@ -101,25 +102,24 @@ const ProjectGroupModal: React.FC = ({ toast({ title: "操作成功", description: "项目组更新成功", - duration: 3000, + variant: "default", }); - onSuccess(); + onSuccess?.(); } else { await createProjectGroup(values); toast({ title: "操作成功", description: "项目组创建成功", - duration: 3000, + variant: "default", }); - onSuccess(); + onSuccess?.(); } } catch (error) { console.error('操作失败:', error); toast({ - variant: "destructive", title: "操作失败", description: error instanceof Error ? error.message : `项目组${isEdit ? '更新' : '创建'}失败`, - duration: 3000, + variant: "destructive", }); } finally { setLoading(false); @@ -131,6 +131,9 @@ const ProjectGroupModal: React.FC = ({ {isEdit ? '编辑' : '新建'}项目组 + + {isEdit ? '编辑现有项目组信息' : '创建一个新的项目组'} +
@@ -276,7 +279,7 @@ const ProjectGroupModal: React.FC = ({ > 取消 -