feat: ITTO显示隐藏平滑过渡动画 + 资源管理数据更新

- ProcessDetailPage: 用motion height动画替换AnimatePresence,消除滚动条跳动
- P6.3 获取资源:添加ITTO明细
- P6.5 管理团队:添加ITTO明细
- P6.6 控制资源:添加ITTO明细

via [HAPI](https://hapi.run)

Co-Authored-By: HAPI <noreply@hapi.run>
This commit is contained in:
ittoview
2026-02-22 14:20:27 +00:00
parent cfbd06f676
commit b5f6f47138

View File

@@ -1,5 +1,5 @@
import { useParams, Link, useLocation, useNavigate } from 'react-router-dom'
import { motion, AnimatePresence } from 'framer-motion'
import { motion } from 'framer-motion'
import { ArrowLeft, ArrowRight, FileText, Wrench, FileOutput, LayoutGrid, Workflow, User, Target, Clock, MapPin, HelpCircle, Cog, Eye, EyeOff } from 'lucide-react'
import { getProcessDetail, processes } from '@/data'
import { useState, useEffect } from 'react'
@@ -227,16 +227,14 @@ export function ProcessDetailPage() {
<span>{visible.inputs ? '隐藏' : '显示'}</span>
</button>
</div>
<AnimatePresence mode="wait" initial={false}>
<motion.div
animate={{ height: visible.inputs ? 'auto' : 48, opacity: 1 }}
initial={false}
transition={{ duration: 0.25, ease: 'easeInOut' }}
style={{ overflow: 'hidden' }}
>
{visible.inputs ? (
<motion.ul
key="inputs-list"
initial={{ opacity: 0, y: 4 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -4 }}
transition={{ duration: 0.18 }}
className="divide-y divide-gray-100 dark:divide-gray-700"
>
<ul className="divide-y divide-gray-100 dark:divide-gray-700">
{processDetail.inputDetails?.map((inputDetail: any) => {
const hasDetail = inputDetail.detail && inputDetail.detail.length > 0
return (
@@ -261,20 +259,13 @@ export function ProcessDetailPage() {
</li>
)
})}
</motion.ul>
</ul>
) : (
<motion.div
key="inputs-hidden"
initial={{ opacity: 0, y: 4 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -4 }}
transition={{ duration: 0.18 }}
className="px-3 py-6 text-center text-xs text-gray-500 dark:text-gray-400"
>
<div className="px-3 py-3 text-center text-xs text-gray-500 dark:text-gray-400">
{processDetail.inputs.length}
</motion.div>
</div>
)}
</AnimatePresence>
</motion.div>
</div>
{/* 工具与技术 */}
@@ -295,16 +286,14 @@ export function ProcessDetailPage() {
<span>{visible.tools ? '隐藏' : '显示'}</span>
</button>
</div>
<AnimatePresence mode="wait" initial={false}>
<motion.div
animate={{ height: visible.tools ? 'auto' : 48, opacity: 1 }}
initial={false}
transition={{ duration: 0.25, ease: 'easeInOut' }}
style={{ overflow: 'hidden' }}
>
{visible.tools ? (
<motion.ul
key="tools-list"
initial={{ opacity: 0, y: 4 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -4 }}
transition={{ duration: 0.18 }}
className="divide-y divide-gray-100 dark:divide-gray-700"
>
<ul className="divide-y divide-gray-100 dark:divide-gray-700">
{processDetail.toolDetails?.map((toolDetail: any) => {
const hasDetail = toolDetail.detail && toolDetail.detail.length > 0
return (
@@ -329,20 +318,13 @@ export function ProcessDetailPage() {
</li>
)
})}
</motion.ul>
</ul>
) : (
<motion.div
key="tools-hidden"
initial={{ opacity: 0, y: 4 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -4 }}
transition={{ duration: 0.18 }}
className="px-3 py-6 text-center text-xs text-gray-500 dark:text-gray-400"
>
<div className="px-3 py-3 text-center text-xs text-gray-500 dark:text-gray-400">
{processDetail.tools.length}
</motion.div>
</div>
)}
</AnimatePresence>
</motion.div>
</div>
{/* 输出 */}
@@ -363,16 +345,14 @@ export function ProcessDetailPage() {
<span>{visible.outputs ? '隐藏' : '显示'}</span>
</button>
</div>
<AnimatePresence mode="wait" initial={false}>
<motion.div
animate={{ height: visible.outputs ? 'auto' : 48, opacity: 1 }}
initial={false}
transition={{ duration: 0.25, ease: 'easeInOut' }}
style={{ overflow: 'hidden' }}
>
{visible.outputs ? (
<motion.ul
key="outputs-list"
initial={{ opacity: 0, y: 4 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -4 }}
transition={{ duration: 0.18 }}
className="divide-y divide-gray-100 dark:divide-gray-700"
>
<ul className="divide-y divide-gray-100 dark:divide-gray-700">
{processDetail.outputDetails?.map((outputDetail: any) => {
const hasDetail = outputDetail.detail && outputDetail.detail.length > 0
return (
@@ -397,20 +377,13 @@ export function ProcessDetailPage() {
</li>
)
})}
</motion.ul>
</ul>
) : (
<motion.div
key="outputs-hidden"
initial={{ opacity: 0, y: 4 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -4 }}
transition={{ duration: 0.18 }}
className="px-3 py-6 text-center text-xs text-gray-500 dark:text-gray-400"
>
<div className="px-3 py-3 text-center text-xs text-gray-500 dark:text-gray-400">
{processDetail.outputs.length}
</motion.div>
</div>
)}
</AnimatePresence>
</motion.div>
</div>
</motion.div>