From 2bc93a57441dcb0ccdd61f6f93e41c37c550099d Mon Sep 17 00:00:00 2001 From: dengqichen Date: Fri, 27 Dec 2024 18:55:14 +0800 Subject: [PATCH] 1 --- frontend/package.json | 2 + frontend/pnpm-lock.yaml | 69 +++++++++ frontend/src/pages/Dashboard/index.tsx | 206 ++++++++++++++----------- 3 files changed, 186 insertions(+), 91 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index b09a4394..8a1c8f33 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -28,11 +28,13 @@ "@logicflow/extension": "^2.0.13", "@monaco-editor/react": "^4.6.0", "@radix-ui/react-avatar": "^1.1.2", + "@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-label": "^2.1.1", "@radix-ui/react-progress": "^1.1.1", "@radix-ui/react-select": "^2.1.4", "@radix-ui/react-separator": "^1.1.1", "@radix-ui/react-slot": "^1.1.1", + "@radix-ui/react-switch": "^1.1.2", "@radix-ui/react-tabs": "^1.1.2", "@reduxjs/toolkit": "^2.0.1", "@types/recharts": "^1.8.29", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index e4a269b6..93333eec 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: '@radix-ui/react-avatar': specifier: ^1.1.2 version: 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-label': specifier: ^2.1.1 version: 2.1.1(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -77,6 +80,9 @@ importers: '@radix-ui/react-slot': specifier: ^1.1.1 version: 1.1.1(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-switch': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-tabs': specifier: ^1.1.2 version: 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -877,6 +883,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-dialog@1.1.4': + resolution: {integrity: sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==} + 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 + '@radix-ui/react-direction@1.1.0': resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} peerDependencies: @@ -1056,6 +1075,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-switch@1.1.2': + resolution: {integrity: sha512-zGukiWHjEdBCRyXvKR6iXAQG6qXm2esuAD6kDOi9Cn+1X6ev3ASo4+CsYaD6Fov9r/AQFekqnD/7+V0Cs6/98g==} + 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 + '@radix-ui/react-tabs@1.1.2': resolution: {integrity: sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==} peerDependencies: @@ -4288,6 +4320,28 @@ snapshots: optionalDependencies: '@types/react': 18.3.16 + '@radix-ui/react-dialog@1.1.4(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.3(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.1(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-portal': 1.1.3(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.1(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.16)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.2(@types/react@18.3.16)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.16 + '@types/react-dom': 18.3.5(@types/react@18.3.16) + '@radix-ui/react-direction@1.1.0(@types/react@18.3.16)(react@18.3.1)': dependencies: react: 18.3.1 @@ -4459,6 +4513,21 @@ snapshots: optionalDependencies: '@types/react': 18.3.16 + '@radix-ui/react-switch@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.16)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.16)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.16 + '@types/react-dom': 18.3.5(@types/react@18.3.16) + '@radix-ui/react-tabs@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 diff --git a/frontend/src/pages/Dashboard/index.tsx b/frontend/src/pages/Dashboard/index.tsx index ee1dec2e..2b83d50a 100644 --- a/frontend/src/pages/Dashboard/index.tsx +++ b/frontend/src/pages/Dashboard/index.tsx @@ -1,37 +1,40 @@ -import React, { useState, useEffect } from 'react'; -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; -import { Badge } from "@/components/ui/badge"; -import { Progress } from "@/components/ui/progress"; -import { Button } from "@/components/ui/button"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { Input } from "@/components/ui/input"; +import React, {useState, useEffect} from 'react'; +import {Card, CardContent, CardHeader, CardTitle} from "@/components/ui/card"; +import {Badge} from "@/components/ui/badge"; +import {Progress} from "@/components/ui/progress"; +import {Button} from "@/components/ui/button"; +import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs"; +import {Input} from "@/components/ui/input"; import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, } from "@/components/ui/select"; -import { cn } from "@/lib/utils"; -import { - Clock, - Search, - Edit, - ChevronRight, - CheckCircle, - AlertTriangle, - XCircle, - Loader2, - ServerCrash, - Server +import {cn} from "@/lib/utils"; +import { + Clock, + Search, + Edit, + Package, + ChevronRight, + CheckCircle, + AlertTriangle, + XCircle, + Loader2, + ServerCrash, + Server } from "lucide-react"; -import { getEnvironmentList } from '@/pages/Deploy/Environment/List/service'; -import { getDevelopmentLanguages } from '@/pages/Deploy/Application/List/service'; -import { getDeploymentConfigPage } from '@/pages/Deploy/Deployment/List/service'; -import type { Environment } from '@/pages/Deploy/Environment/List/types'; -import type { DevelopmentLanguageType } from '@/pages/Deploy/Application/List/types'; -import type { DeploymentConfig, DeploymentConfigQueryParams } from '@/pages/Deploy/Deployment/List/types'; -import type { Page } from '@/types/base'; +import {getEnvironmentList} from '@/pages/Deploy/Environment/List/service'; +import {getDevelopmentLanguages} from '@/pages/Deploy/Application/List/service'; +import {getDeploymentConfigPage} from '@/pages/Deploy/Deployment/List/service'; +import type {Environment} from '@/pages/Deploy/Environment/List/types'; +import type {DevelopmentLanguageType} from '@/pages/Deploy/Application/List/types'; +import type {DeploymentConfig} from '@/pages/Deploy/Deployment/List/types'; +import type {Page} from '@/types/base'; +import type { JsonNode } from '@/types/common'; +import DeploymentFormModal from './components/DeploymentFormModal'; type EnvironmentStatus = 'success' | 'warning' | 'error'; @@ -46,10 +49,10 @@ interface EnhancedEnvironment extends Environment { } const EmptyState: React.FC<{ title: string; description: string; icon: React.ReactNode }> = ({ - title, - description, - icon -}) => ( + title, + description, + icon + }) => (
{icon} @@ -62,14 +65,14 @@ const EmptyState: React.FC<{ title: string; description: string; icon: React.Rea const LoadingState = () => (
- +

加载中,请稍候...

); const Dashboard: React.FC = () => { - const [projectType, setProjectType] = useState(""); + const [projectType, setProjectType] = useState("ALL"); const [status, setStatus] = useState(""); const [environments, setEnvironments] = useState([]); const [loading, setLoading] = useState(true); @@ -77,6 +80,8 @@ const Dashboard: React.FC = () => { const [deployConfigs, setDeployConfigs] = useState([]); const [searchText, setSearchText] = useState(""); const [currentEnvId, setCurrentEnvId] = useState(); + const [deployModalOpen, setDeployModalOpen] = useState(false); + const [selectedConfig, setSelectedConfig] = useState(null); // 获取环境和语言数据 useEffect(() => { @@ -124,24 +129,23 @@ const Dashboard: React.FC = () => { useEffect(() => { const fetchDeployConfigs = async () => { if (!currentEnvId) return; - + try { - const queryParams: DeploymentConfigQueryParams = { + const response = await getDeploymentConfigPage({ pageSize: 100, pageNum: 1, environmentId: currentEnvId, - workflowDefinitionId: 0 - }; - - const response = await getDeploymentConfigPage(queryParams); + workflowDefinitionId: 0, + enabled: undefined + }); if (response) { setDeployConfigs(response.content); // 更新环境的项目数量 - setEnvironments(prevEnvs => - prevEnvs.map(env => - env.id === currentEnvId - ? { ...env, projectCount: response.totalElements } + setEnvironments(prevEnvs => + prevEnvs.map(env => + env.id === currentEnvId + ? {...env, projectCount: response.totalElements} : env ) ); @@ -156,27 +160,24 @@ const Dashboard: React.FC = () => { const handleSearch = async () => { if (!currentEnvId) return; - + try { - const queryParams: DeploymentConfigQueryParams = { + const params: any = { pageSize: 100, pageNum: 1, environmentId: currentEnvId, - workflowDefinitionId: 0, enabled: status === 'active' ? true : status === 'paused' ? false : undefined }; - const response = await getDeploymentConfigPage(queryParams); + // 如果选择了具体语言(不是"所有"),添加到查询参数 + if (projectType !== 'ALL') { + params.languageType = projectType; + } + + const response = await getDeploymentConfigPage(params); if (response) { - // 在前端过滤开发语言 - const filteredConfigs = response.content.filter(config => { - if (projectType && config.languageType !== projectType) { - return false; - } - return true; - }); - setDeployConfigs(filteredConfigs); + setDeployConfigs(response.content); } } catch (error) { console.error('Failed to search deployment configs:', error); @@ -185,17 +186,16 @@ const Dashboard: React.FC = () => { const handleReset = () => { setSearchText(""); - setProjectType(""); + setProjectType("ALL"); setStatus(""); if (currentEnvId) { - const queryParams: DeploymentConfigQueryParams = { + getDeploymentConfigPage({ pageSize: 100, pageNum: 1, environmentId: currentEnvId, - workflowDefinitionId: 0 - }; - - getDeploymentConfigPage(queryParams).then(response => { + workflowDefinitionId: 0, + enabled: undefined + }).then(response => { if (response) { setDeployConfigs(response.content); } @@ -213,21 +213,21 @@ const Dashboard: React.FC = () => { const getStatusIcon = (status: string) => { switch (status) { case 'success': - return ; + return ; case 'warning': - return ; + return ; case 'error': - return ; + return ; default: - return ; + return ; } }; const getBuildStatusBadge = (enabled: boolean) => { const config = enabled - ? { className: "bg-green-100 text-green-800", text: "活跃" } - : { className: "bg-red-100 text-red-800", text: "暂停" }; - + ? {className: "bg-green-100 text-green-800", text: "活跃"} + : {className: "bg-red-100 text-red-800", text: "暂停"}; + return ( {config.text} @@ -235,8 +235,16 @@ const Dashboard: React.FC = () => { ); }; + const handleDeploy = (config: DeploymentConfig) => { + console.log('Deploy config:', config); + console.log('Workflow definition:', config.publishedWorkflowDefinition); + console.log('Form variables:', config.publishedWorkflowDefinition?.formVariables); + setSelectedConfig(config); + setDeployModalOpen(true); + }; + if (loading) { - return ; + return ; } const hasEnvironments = environments.length > 0; @@ -245,12 +253,12 @@ const Dashboard: React.FC = () => { return (

部署环境概览

- + {!hasEnvironments ? ( } + icon={} title="暂无环境数据" description="当前系统中还没有配置任何环境。请先添加部署环境,然后开始使用部署功能。" /> @@ -270,7 +278,7 @@ const Dashboard: React.FC = () => {

个项目

- + 最近部署: {env.lastDeployment}
@@ -278,21 +286,21 @@ const Dashboard: React.FC = () => { CPU {env.cpu}%
- +
内存 {env.memory}%
- +
存储 {env.storage}%
- +
@@ -301,8 +309,8 @@ const Dashboard: React.FC = () => {
- @@ -324,16 +332,17 @@ const Dashboard: React.FC = () => {
- setSearchText(e.target.value)} />
-
@@ -423,6 +432,21 @@ const Dashboard: React.FC = () => {
)} + {selectedConfig && selectedConfig.publishedWorkflowDefinition && ( + <> + {console.log('Selected config:', selectedConfig)} + {console.log('Workflow definition:', selectedConfig.publishedWorkflowDefinition)} + {console.log('Form variables:', selectedConfig.publishedWorkflowDefinition.formVariables)} + { + setDeployModalOpen(false); + setSelectedConfig(null); + }} + formSchema={selectedConfig.publishedWorkflowDefinition.formVariables} + /> + + )}
); };