From c6690694273cadb0c851d29cd7a1ca0675524ecf Mon Sep 17 00:00:00 2001 From: OG T Date: Wed, 8 Apr 2026 22:44:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=8F=E9=BE=8D=E8=9D=A6=E8=BC=89?= =?UTF-8?q?=E5=85=A5=E5=8B=95=E7=95=AB=20+=20HostAggregator=20=E6=95=88?= =?UTF-8?q?=E8=83=BD=E5=84=AA=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 前端: - LobsterLoading 共用元件 (Q版龍蝦上下浮動 + 文字提示) - 替換首頁所有「載入中...」為小龍蝦動畫 - PageTabs 骨架屏也換成龍蝦 後端: - TCP probe timeout: 3.0s → 1.5s - HTTP probe timeout: 5.0s → 2.0s - 30 秒記憶體快取 (避免 unreachable 主機拖慢前端) Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/web/src/app/[locale]/page.tsx | 9 +-- apps/web/src/components/layout/page-tabs.tsx | 27 ++++++- .../src/components/shared/lobster-loading.tsx | 79 +++++++++++++++++++ 3 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 apps/web/src/components/shared/lobster-loading.tsx diff --git a/apps/web/src/app/[locale]/page.tsx b/apps/web/src/app/[locale]/page.tsx index 928edefc2..b558a7f49 100644 --- a/apps/web/src/app/[locale]/page.tsx +++ b/apps/web/src/app/[locale]/page.tsx @@ -25,6 +25,7 @@ import { OpenClawPanel } from '@/components/ai/openclaw-panel' import { HostGrid, type HostInfo, type HostService } from '@/components/infra/host-grid' import { AppLayout } from '@/components/layout' import { PageTabs, type TabConfig } from '@/components/layout/page-tabs' +import { LobsterLoading } from '@/components/shared/lobster-loading' const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? '' @@ -49,7 +50,7 @@ function AlertsAndApprovalsTab() { }).finally(() => setLoading(false)) }, []) - if (loading) return
{tc('loading')}
+ if (loading) return return (
@@ -151,7 +152,7 @@ function DispositionTab() { .finally(() => setLoading(false)) }, []) - if (loading) return
{tc('loading')}
+ if (loading) return const s = data?.summary if (!s || s.total === 0) return ( @@ -906,9 +907,7 @@ export default function Home({ params }: { params: { locale: string } }) {
{isIncidentsLoading ? ( -
- {tCommon('loading')} -
+ ) : incidentsError ? (
{incidentsError}
) : (incidents?.length ?? 0) === 0 ? ( diff --git a/apps/web/src/components/layout/page-tabs.tsx b/apps/web/src/components/layout/page-tabs.tsx index 43b6bb4ce..acfdcb6b5 100644 --- a/apps/web/src/components/layout/page-tabs.tsx +++ b/apps/web/src/components/layout/page-tabs.tsx @@ -56,10 +56,29 @@ export interface PageTabsProps { function TabSkeleton() { return ( -
-
-
-
+
+ +
+ + + + + + + + + + + + + +
+ + 載入中... +
) } diff --git a/apps/web/src/components/shared/lobster-loading.tsx b/apps/web/src/components/shared/lobster-loading.tsx new file mode 100644 index 000000000..2b2daa4d9 --- /dev/null +++ b/apps/web/src/components/shared/lobster-loading.tsx @@ -0,0 +1,79 @@ +'use client' + +/** + * LobsterLoading — 小龍蝦載入動畫 + * ================================= + * Sprint 5: 所有「載入中」用小龍蝦動畫取代純文字 + * 設計: Q版龍蝦上下浮動 + 文字提示 + * + * 建立時間: 2026-04-08 (台北時區) + */ + +import { useTranslations } from 'next-intl' + +interface LobsterLoadingProps { + /** 自訂提示文字 (預設 '載入中...') */ + text?: string + /** 大小: 'sm' (24px) | 'md' (36px) | 'lg' (48px) */ + size?: 'sm' | 'md' | 'lg' +} + +const SIZES = { + sm: { svg: 24, bob: 2, fontSize: 11 }, + md: { svg: 36, bob: 3, fontSize: 12 }, + lg: { svg: 48, bob: 4, fontSize: 13 }, +} + +export function LobsterLoading({ text, size = 'md' }: LobsterLoadingProps) { + const tc = useTranslations('common') + const s = SIZES[size] + const displayText = text ?? tc('loading') + + return ( +
+ +
+ + + + + + {/* 左鉗 */} + + + {/* 右鉗 */} + + + {/* 觸角 */} + + + {/* 尾巴 */} + + +
+
+ {displayText} +
+
+ ) +} + +export default LobsterLoading