fix: render metrics and smooth route transitions

This commit is contained in:
admin committed 2026-08-20 09:45:49 +08:00
1 parent 655783b724
commit 38824a0055
3 files changed
+72 -12

No files matched your search

+6 -1
View File
@@ -35,6 +35,11 @@ export default function AdminLayout() {
const [collapsed, setCollapsed] = useState(false) const [collapsed, setCollapsed] = useState(false)
const navigate = useNavigate() const navigate = useNavigate()
const location = useLocation() const location = useLocation()
function navigateWithTransition(path: string) {
const startViewTransition = (document as unknown as { startViewTransition?: (callback: () => void) => void }).startViewTransition
if (startViewTransition) startViewTransition(() => navigate(path))
else navigate(path)
}
const outlet = useOutlet() const outlet = useOutlet()
const selectedKey = menuItems.find( const selectedKey = menuItems.find(
@@ -66,7 +71,7 @@ export default function AdminLayout() {
</Text> </Text>
</div> </div>
<Menu mode="inline" selectedKeys={[selectedKey]} items={menuItems} <Menu mode="inline" selectedKeys={[selectedKey]} items={menuItems}
onClick={({ key }) => navigate(key)} onClick={({ key }) => navigateWithTransition(String(key))}
style={{ border: 'none', marginTop: 8 }} /> style={{ border: 'none', marginTop: 8 }} />
</Sider> </Sider>
<Layout> <Layout>
+8 -4
View File
@@ -62,12 +62,16 @@ export default function LiveBoard() {
message.error('看板数据加载失败') message.error('看板数据加载失败')
} finally { } finally {
try { try {
const [metrics, nodeResponse] = await Promise.all([getSystemMetrics(), api.get<NodeMetric[]>('/nodes')]) setSystemMetrics(await getSystemMetrics())
setSystemMetrics(metrics)
setNodes(nodeResponse.data)
} catch { } catch {
setSystemMetrics(null) setSystemMetrics(null)
} }
try {
const nodeResponse = await api.get<NodeMetric[]>('/nodes')
setNodes(nodeResponse.data)
} catch {
setNodes([])
}
setLoading(false) setLoading(false)
} }
} }
@@ -176,4 +180,4 @@ export default function LiveBoard() {
</Space> </Space>
</div> </div>
) )
} }
+58 -7
View File
@@ -1,28 +1,79 @@
.app-route-transition, .app-route-transition,
.admin-page-transition { .admin-page-transition {
min-height: 100%; min-height: 100%;
animation: page-fade-slide-in 220ms cubic-bezier(0.22, 1, 0.36, 1) both; animation: page-soft-enter 260ms cubic-bezier(0.22, 1, 0.36, 1) both;
will-change: opacity, transform; will-change: transform, opacity, filter;
background: transparent;
} }
.admin-page-transition { .admin-page-transition {
transform-origin: top center; transform-origin: top center;
} }
@keyframes page-fade-slide-in { .route-loading {
min-height: 280px;
display: grid;
place-items: center;
border-radius: 24px;
background: linear-gradient(135deg, rgba(255,255,255,0.92), rgba(248,244,238,0.78));
}
.route-loading span {
width: 28px;
height: 28px;
border-radius: 999px;
border: 3px solid rgba(194, 105, 58, 0.2);
border-top-color: #C2693A;
animation: route-loading-spin 760ms linear infinite;
}
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 220ms;
animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}
::view-transition-old(root) {
animation-name: view-soft-out;
}
::view-transition-new(root) {
animation-name: view-soft-in;
}
@keyframes page-soft-enter {
from { from {
opacity: 0; opacity: 0.94;
transform: translateY(14px) scale(0.995); transform: translate3d(18px, 0, 0) scale(0.998);
filter: blur(0.2px);
} }
to { to {
opacity: 1; opacity: 1;
transform: translateY(0) scale(1); transform: translate3d(0, 0, 0) scale(1);
filter: blur(0);
} }
} }
@keyframes view-soft-out {
from { opacity: 1; transform: translate3d(0, 0, 0); }
to { opacity: 0.96; transform: translate3d(-8px, 0, 0); }
}
@keyframes view-soft-in {
from { opacity: 0.96; transform: translate3d(10px, 0, 0); }
to { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes route-loading-spin {
to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
.app-route-transition, .app-route-transition,
.admin-page-transition { .admin-page-transition,
.route-loading span,
::view-transition-old(root),
::view-transition-new(root) {
animation: none; animation: none;
} }
} }