From beff78512a7e645f3cd21335c986ddf862008b76 Mon Sep 17 00:00:00 2001 From: yun-zhi-ztl <15071461069@163.com> Date: Tue, 17 Mar 2026 14:53:26 +0800 Subject: [PATCH] fix: avoid dashboard preview crash after registration --- web/src/pages/dashboard-preview.test.ts | 8 ++++++++ web/src/pages/dashboard-preview.ts | 7 ++++--- web/src/pages/dashboard.tsx | 3 ++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/web/src/pages/dashboard-preview.test.ts b/web/src/pages/dashboard-preview.test.ts index 0624595f..4b71e656 100644 --- a/web/src/pages/dashboard-preview.test.ts +++ b/web/src/pages/dashboard-preview.test.ts @@ -25,4 +25,12 @@ describe('limitPreviewItems', () => { remainingCount: 1, }) }) + + it('returns an empty preview instead of throwing when input is not an array', () => { + expect(limitPreviewItems({ items: ['a', 'b'] } as never, 3)).toEqual({ + items: [], + hasMore: false, + remainingCount: 0, + }) + }) }) diff --git a/web/src/pages/dashboard-preview.ts b/web/src/pages/dashboard-preview.ts index 66fd18c9..8cf9c8e2 100644 --- a/web/src/pages/dashboard-preview.ts +++ b/web/src/pages/dashboard-preview.ts @@ -1,10 +1,11 @@ -export function limitPreviewItems(items: T[], limit: number): { +export function limitPreviewItems(items: T[] | null | undefined | unknown, limit: number): { items: T[] hasMore: boolean remainingCount: number } { - const visibleItems = items.slice(0, limit) - const remainingCount = Math.max(items.length - visibleItems.length, 0) + const normalizedItems: T[] = Array.isArray(items) ? (items as T[]) : [] + const visibleItems = normalizedItems.slice(0, limit) + const remainingCount = Math.max(normalizedItems.length - visibleItems.length, 0) return { items: visibleItems, diff --git a/web/src/pages/dashboard.tsx b/web/src/pages/dashboard.tsx index 082e378b..896ec209 100644 --- a/web/src/pages/dashboard.tsx +++ b/web/src/pages/dashboard.tsx @@ -1,6 +1,7 @@ import { Link } from '@tanstack/react-router' import { useTranslation } from 'react-i18next' import { useAuth } from '@/features/auth/use-auth' +import type { SkillSummary } from '@/api/types' import { useMySkills } from '@/shared/hooks/use-skill-queries' import { TokenList } from '@/features/token/token-list' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/shared/ui/card' @@ -14,7 +15,7 @@ export function DashboardPage() { const { user, hasRole } = useAuth() const governanceVisible = hasRole('SKILL_ADMIN') || hasRole('SUPER_ADMIN') const { data: skillPage, isLoading: isLoadingSkills } = useMySkills({ page: 0, size: skillPreviewPageSize }) - const skillPreview = limitPreviewItems(skillPage?.items ?? [], DASHBOARD_PREVIEW_LIMIT) + const skillPreview = limitPreviewItems(skillPage?.items ?? [], DASHBOARD_PREVIEW_LIMIT) return (