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:
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user