feat: 重构项目页面架构并实现流水线步骤拖拽排序功能

主要更新:
- 重构项目页面结构:将原有项目页面拆分为 list 和 detail 两个子模块
- 新增项目详情页面,支持多标签页展示(流水线、部署记录)
- 实现流水线管理功能:支持新建、编辑、复制、删除、启用/禁用
- 实现流水线步骤管理:支持添加、编辑、删除、启用/禁用步骤
- 新增流水线步骤拖拽排序功能:集成 @dnd-kit 实现拖拽重排
- 优化左右两栏布局:左侧流水线列表,右侧步骤详情
- 新增部署记录展示功能:左右两栏布局,支持选中切换
- 提取可复用组件:DeployRecordItem、PipelineStepItem
- 添加表单验证和用户交互反馈
- 更新路由配置支持项目详情页面

技术改进:
- 安装 @dnd-kit 相关依赖实现拖拽功能
- 优化 TypeScript 类型定义
- 改进组件化设计,提高代码复用性
- 增强用户体验和交互反馈
This commit is contained in:
2025-09-07 22:35:33 +08:00
parent f0e1a649ee
commit ef4fce6d42
14 changed files with 1272 additions and 122 deletions

118
pnpm-lock.yaml generated
View File

@@ -77,22 +77,31 @@ importers:
dependencies:
'@arco-design/web-react':
specifier: ^2.66.4
version: 2.66.5(@types/react@19.1.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
version: 2.66.5(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@dnd-kit/core':
specifier: ^6.3.1
version: 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@dnd-kit/sortable':
specifier: ^10.0.0
version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
'@dnd-kit/utilities':
specifier: ^3.2.2
version: 3.2.2(react@18.3.1)
axios:
specifier: ^1.11.0
version: 1.11.0
react:
specifier: ^18.3.1
specifier: ^18.2.0
version: 18.3.1
react-dom:
specifier: ^18.3.1
specifier: ^18.2.0
version: 18.3.1(react@18.3.1)
react-router:
specifier: ^7.8.0
version: 7.8.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
zustand:
specifier: ^5.0.8
version: 5.0.8(@types/react@19.1.12)(react@18.3.1)
version: 5.0.8(@types/react@18.3.24)(react@18.3.1)
devDependencies:
'@arco-plugins/unplugin-react':
specifier: 2.0.0-beta.5
@@ -113,11 +122,11 @@ importers:
specifier: ^4.1.11
version: 4.1.12
'@types/react':
specifier: ^19.1.9
version: 19.1.12
specifier: ^18.3.24
version: 18.3.24
'@types/react-dom':
specifier: ^19.1.7
version: 19.1.9(@types/react@19.1.12)
specifier: ^18.3.7
version: 18.3.7(@types/react@18.3.24)
tailwindcss:
specifier: ^4.1.11
version: 4.1.12
@@ -273,6 +282,28 @@ packages:
cpu: [x64]
os: [win32]
'@dnd-kit/accessibility@3.1.1':
resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==}
peerDependencies:
react: '>=16.8.0'
'@dnd-kit/core@6.3.1':
resolution: {integrity: sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==}
peerDependencies:
react: '>=16.8.0'
react-dom: '>=16.8.0'
'@dnd-kit/sortable@10.0.0':
resolution: {integrity: sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==}
peerDependencies:
'@dnd-kit/core': ^6.3.0
react: '>=16.8.0'
'@dnd-kit/utilities@3.2.2':
resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==}
peerDependencies:
react: '>=16.8.0'
'@emnapi/core@1.4.5':
resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==}
@@ -846,19 +877,22 @@ packages:
'@types/node@24.3.0':
resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==}
'@types/prop-types@15.7.15':
resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
'@types/qs@6.14.0':
resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==}
'@types/range-parser@1.2.7':
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
'@types/react-dom@19.1.9':
resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==}
'@types/react-dom@18.3.7':
resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==}
peerDependencies:
'@types/react': ^19.0.0
'@types/react': ^18.0.0
'@types/react@19.1.12':
resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==}
'@types/react@18.3.24':
resolution: {integrity: sha512-0dLEBsA1kI3OezMBF8nSsb7Nk19ZnsyE1LLhB8r27KbgU5H4pvuqZLdtE+aUkJVoXgTVuA+iLIwmZ0TuK4tx6A==}
'@types/send@0.17.5':
resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==}
@@ -1949,7 +1983,7 @@ snapshots:
dependencies:
color: 3.2.1
'@arco-design/web-react@2.66.5(@types/react@19.1.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@arco-design/web-react@2.66.5(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@arco-design/color': 0.4.0
'@babel/runtime': 7.28.3
@@ -1961,7 +1995,7 @@ snapshots:
number-precision: 1.6.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-focus-lock: 2.13.6(@types/react@19.1.12)(react@18.3.1)
react-focus-lock: 2.13.6(@types/react@18.3.24)(react@18.3.1)
react-is: 18.3.1
react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
resize-observer-polyfill: 1.5.1
@@ -2112,6 +2146,31 @@ snapshots:
'@biomejs/cli-win32-x64@2.0.6':
optional: true
'@dnd-kit/accessibility@3.1.1(react@18.3.1)':
dependencies:
react: 18.3.1
tslib: 2.8.1
'@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@dnd-kit/accessibility': 3.1.1(react@18.3.1)
'@dnd-kit/utilities': 3.2.2(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
tslib: 2.8.1
'@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
dependencies:
'@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@dnd-kit/utilities': 3.2.2(react@18.3.1)
react: 18.3.1
tslib: 2.8.1
'@dnd-kit/utilities@3.2.2(react@18.3.1)':
dependencies:
react: 18.3.1
tslib: 2.8.1
'@emnapi/core@1.4.5':
dependencies:
'@emnapi/wasi-threads': 1.0.4
@@ -2650,16 +2709,19 @@ snapshots:
dependencies:
undici-types: 7.10.0
'@types/prop-types@15.7.15': {}
'@types/qs@6.14.0': {}
'@types/range-parser@1.2.7': {}
'@types/react-dom@19.1.9(@types/react@19.1.12)':
'@types/react-dom@18.3.7(@types/react@18.3.24)':
dependencies:
'@types/react': 19.1.12
'@types/react': 18.3.24
'@types/react@19.1.12':
'@types/react@18.3.24':
dependencies:
'@types/prop-types': 15.7.15
csstype: 3.1.3
'@types/send@0.17.5':
@@ -3462,17 +3524,17 @@ snapshots:
react: 18.3.1
scheduler: 0.23.2
react-focus-lock@2.13.6(@types/react@19.1.12)(react@18.3.1):
react-focus-lock@2.13.6(@types/react@18.3.24)(react@18.3.1):
dependencies:
'@babel/runtime': 7.28.3
focus-lock: 1.3.6
prop-types: 15.8.1
react: 18.3.1
react-clientside-effect: 1.2.8(react@18.3.1)
use-callback-ref: 1.3.3(@types/react@19.1.12)(react@18.3.1)
use-sidecar: 1.1.3(@types/react@19.1.12)(react@18.3.1)
use-callback-ref: 1.3.3(@types/react@18.3.24)(react@18.3.1)
use-sidecar: 1.1.3(@types/react@18.3.24)(react@18.3.1)
optionalDependencies:
'@types/react': 19.1.12
'@types/react': 18.3.24
react-is@16.13.1: {}
@@ -3659,20 +3721,20 @@ snapshots:
escalade: 3.2.0
picocolors: 1.1.1
use-callback-ref@1.3.3(@types/react@19.1.12)(react@18.3.1):
use-callback-ref@1.3.3(@types/react@18.3.24)(react@18.3.1):
dependencies:
react: 18.3.1
tslib: 2.8.1
optionalDependencies:
'@types/react': 19.1.12
'@types/react': 18.3.24
use-sidecar@1.1.3(@types/react@19.1.12)(react@18.3.1):
use-sidecar@1.1.3(@types/react@18.3.24)(react@18.3.1):
dependencies:
detect-node-es: 1.1.0
react: 18.3.1
tslib: 2.8.1
optionalDependencies:
'@types/react': 19.1.12
'@types/react': 18.3.24
vary@1.1.2: {}
@@ -3686,7 +3748,7 @@ snapshots:
zod@4.1.5: {}
zustand@5.0.8(@types/react@19.1.12)(react@18.3.1):
zustand@5.0.8(@types/react@18.3.24)(react@18.3.1):
optionalDependencies:
'@types/react': 19.1.12
'@types/react': 18.3.24
react: 18.3.1