fix: render metrics and smooth route transitions
This commit is contained in:
1 parent
655783b724
commit
38824a0055
3 files changed
+71
-11
No files matched your search
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user