From 197e4cab9c07d7f9a7117bfb3c1981621f3d0995 Mon Sep 17 00:00:00 2001 From: KDB <937925477@qq.com> Date: Tue, 11 Aug 2026 19:43:16 +0800 Subject: [PATCH] fix(frontend): clear lint issues and enforce lint gate --- .github/workflows/ci.yml | 6 +- frontend/.eslintrc.cjs | 4 +- frontend/@/components/ui/alert-dialog.tsx | 141 -------------- frontend/@/components/ui/badge.tsx | 36 ---- frontend/@/components/ui/button.tsx | 56 ------ frontend/@/components/ui/card.tsx | 79 -------- frontend/@/components/ui/form.tsx | 176 ------------------ frontend/@/components/ui/input.tsx | 22 --- frontend/@/components/ui/label.tsx | 26 --- frontend/@/components/ui/progress.tsx | 28 --- frontend/@/components/ui/select.tsx | 158 ---------------- frontend/@/components/ui/separator.tsx | 29 --- frontend/@/components/ui/sheet.tsx | 138 -------------- frontend/@/components/ui/table.tsx | 117 ------------ frontend/@/components/ui/tabs.tsx | 53 ------ frontend/@/components/ui/textarea.tsx | 22 --- frontend/src/App.tsx | 2 +- frontend/src/components/admin/AgentAvatar.tsx | 41 +--- .../src/components/admin/AgentModeLabel.tsx | 6 +- .../components/admin/agentAvatarPresets.ts | 39 ++++ .../src/components/admin/agentModeLabels.ts | 7 + .../src/components/chat/FeedbackButtons.tsx | 1 - .../src/components/chat/MarkdownRenderer.tsx | 63 ++++--- frontend/src/components/chat/MessageList.tsx | 2 +- .../components/document/DocumentPreview.tsx | 36 +--- .../src/components/document/previewUtils.ts | 29 +++ frontend/src/components/ui/badge.tsx | 6 +- frontend/src/components/ui/button.tsx | 6 +- frontend/src/components/ui/form.tsx | 1 + frontend/src/hooks/useStreamResponse.ts | 1 + frontend/src/lib/source.ts | 1 + frontend/src/pages/admin/AdminLayout.tsx | 7 +- .../pages/admin/agents/AgentProfilePage.tsx | 6 +- .../admin/change-logs/BizChangeLogPage.tsx | 10 +- .../pages/admin/dashboard/DashboardPage.tsx | 5 +- .../pages/admin/ingestion/IngestionPage.tsx | 36 ++-- .../admin/intent-tree/IntentTreePage.tsx | 4 + .../admin/knowledge/KnowledgeChunksPage.tsx | 14 +- .../knowledge/KnowledgeDocumentsPage.tsx | 33 ++-- .../admin/knowledge/KnowledgeListPage.tsx | 6 +- .../QueryTermMappingPage.tsx | 8 +- .../sample-questions/SampleQuestionPage.tsx | 8 +- .../pages/admin/traces/RagTraceDetailPage.tsx | 7 +- .../src/pages/admin/traces/RagTracePage.tsx | 51 ++--- .../src/pages/admin/users/UserListPage.tsx | 8 +- frontend/src/router.tsx | 166 +---------------- frontend/src/routerConfig.tsx | 169 +++++++++++++++++ frontend/src/services/authService.ts | 6 +- frontend/src/services/chatService.ts | 8 +- frontend/src/services/sessionService.ts | 8 +- frontend/src/stores/authStore.ts | 3 - frontend/src/stores/chatStore.ts | 19 +- 52 files changed, 446 insertions(+), 1468 deletions(-) delete mode 100644 frontend/@/components/ui/alert-dialog.tsx delete mode 100644 frontend/@/components/ui/badge.tsx delete mode 100644 frontend/@/components/ui/button.tsx delete mode 100644 frontend/@/components/ui/card.tsx delete mode 100644 frontend/@/components/ui/form.tsx delete mode 100644 frontend/@/components/ui/input.tsx delete mode 100644 frontend/@/components/ui/label.tsx delete mode 100644 frontend/@/components/ui/progress.tsx delete mode 100644 frontend/@/components/ui/select.tsx delete mode 100644 frontend/@/components/ui/separator.tsx delete mode 100644 frontend/@/components/ui/sheet.tsx delete mode 100644 frontend/@/components/ui/table.tsx delete mode 100644 frontend/@/components/ui/tabs.tsx delete mode 100644 frontend/@/components/ui/textarea.tsx create mode 100644 frontend/src/components/admin/agentAvatarPresets.ts create mode 100644 frontend/src/components/admin/agentModeLabels.ts create mode 100644 frontend/src/components/document/previewUtils.ts create mode 100644 frontend/src/routerConfig.tsx diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a8fb3641..61ccaece7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,8 +77,6 @@ jobs: run: npm run test - name: Lint - # 仓库既有代码存在 21 个存量 lint error(配置加载原就崩溃,从未跑通过), - # 修复属于业务代码改造,列入后续计划;此处先启用 lint 并完整记录结果, - # 不阻塞 CI,也不假装 lint 已全绿。 - continue-on-error: true + # 硬门禁:存量 lint 问题已清零(含 0 warnings,--max-warnings 0), + # lint 成为与 build/test 同级的前端质量门禁。 run: npm run lint diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index 01247e808..0ed72e497 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -24,6 +24,8 @@ module.exports = { rules: { "react/react-in-jsx-scope": "off", "react/prop-types": "off", - "react-refresh/only-export-components": "error" + // allowConstantExport 放行 cva 变体常量(badge/button)与只读常量导出(AgentModeLabel), + // 这是 shadcn/ui 组件结构的官方推荐配置,常量不参与 fast refresh 失效问题。 + "react-refresh/only-export-components": ["error", { "allowConstantExport": true }] } }; diff --git a/frontend/@/components/ui/alert-dialog.tsx b/frontend/@/components/ui/alert-dialog.tsx deleted file mode 100644 index 25e7b4744..000000000 --- a/frontend/@/components/ui/alert-dialog.tsx +++ /dev/null @@ -1,141 +0,0 @@ -"use client" - -import * as React from "react" -import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" - -import { cn } from "@/lib/utils" -import { buttonVariants } from "@/components/ui/button" - -const AlertDialog = AlertDialogPrimitive.Root - -const AlertDialogTrigger = AlertDialogPrimitive.Trigger - -const AlertDialogPortal = AlertDialogPrimitive.Portal - -const AlertDialogOverlay = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName - -const AlertDialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - - -)) -AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName - -const AlertDialogHeader = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -AlertDialogHeader.displayName = "AlertDialogHeader" - -const AlertDialogFooter = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -AlertDialogFooter.displayName = "AlertDialogFooter" - -const AlertDialogTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName - -const AlertDialogDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogDescription.displayName = - AlertDialogPrimitive.Description.displayName - -const AlertDialogAction = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName - -const AlertDialogCancel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName - -export { - AlertDialog, - AlertDialogPortal, - AlertDialogOverlay, - AlertDialogTrigger, - AlertDialogContent, - AlertDialogHeader, - AlertDialogFooter, - AlertDialogTitle, - AlertDialogDescription, - AlertDialogAction, - AlertDialogCancel, -} diff --git a/frontend/@/components/ui/badge.tsx b/frontend/@/components/ui/badge.tsx deleted file mode 100644 index f000e3ef5..000000000 --- a/frontend/@/components/ui/badge.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" - -const badgeVariants = cva( - "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", - { - variants: { - variant: { - default: - "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", - secondary: - "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", - destructive: - "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", - outline: "text-foreground", - }, - }, - defaultVariants: { - variant: "default", - }, - } -) - -export interface BadgeProps - extends React.HTMLAttributes, - VariantProps {} - -function Badge({ className, variant, ...props }: BadgeProps) { - return ( -
- ) -} - -export { Badge, badgeVariants } diff --git a/frontend/@/components/ui/button.tsx b/frontend/@/components/ui/button.tsx deleted file mode 100644 index 36496a287..000000000 --- a/frontend/@/components/ui/button.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" - -const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", - { - variants: { - variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/90", - destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90", - outline: - "border border-input bg-background hover:bg-accent hover:text-accent-foreground", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", - }, - size: { - default: "h-10 px-4 py-2", - sm: "h-9 rounded-md px-3", - lg: "h-11 rounded-md px-8", - icon: "h-10 w-10", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - } -) - -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean -} - -const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button" - return ( - - ) - } -) -Button.displayName = "Button" - -export { Button, buttonVariants } diff --git a/frontend/@/components/ui/card.tsx b/frontend/@/components/ui/card.tsx deleted file mode 100644 index f62edea57..000000000 --- a/frontend/@/components/ui/card.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import * as React from "react" - -import { cn } from "@/lib/utils" - -const Card = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -Card.displayName = "Card" - -const CardHeader = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -CardHeader.displayName = "CardHeader" - -const CardTitle = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -CardTitle.displayName = "CardTitle" - -const CardDescription = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -CardDescription.displayName = "CardDescription" - -const CardContent = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -CardContent.displayName = "CardContent" - -const CardFooter = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -CardFooter.displayName = "CardFooter" - -export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/frontend/@/components/ui/form.tsx b/frontend/@/components/ui/form.tsx deleted file mode 100644 index a98b0ae49..000000000 --- a/frontend/@/components/ui/form.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import * as React from "react" -import * as LabelPrimitive from "@radix-ui/react-label" -import { Slot } from "@radix-ui/react-slot" -import { - Controller, - FormProvider, - useFormContext, - type ControllerProps, - type FieldPath, - type FieldValues, -} from "react-hook-form" - -import { cn } from "@/lib/utils" -import { Label } from "@/components/ui/label" - -const Form = FormProvider - -type FormFieldContextValue< - TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath -> = { - name: TName -} - -const FormFieldContext = React.createContext(null) - -const FormField = < - TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath ->({ - ...props -}: ControllerProps) => { - return ( - - - - ) -} - -const useFormField = () => { - const fieldContext = React.useContext(FormFieldContext) - const itemContext = React.useContext(FormItemContext) - const { getFieldState, formState } = useFormContext() - - if (!fieldContext) { - throw new Error("useFormField should be used within ") - } - - if (!itemContext) { - throw new Error("useFormField should be used within ") - } - - const fieldState = getFieldState(fieldContext.name, formState) - - const { id } = itemContext - - return { - id, - name: fieldContext.name, - formItemId: `${id}-form-item`, - formDescriptionId: `${id}-form-item-description`, - formMessageId: `${id}-form-item-message`, - ...fieldState, - } -} - -type FormItemContextValue = { - id: string -} - -const FormItemContext = React.createContext(null) - -const FormItem = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const id = React.useId() - - return ( - -
- - ) -}) -FormItem.displayName = "FormItem" - -const FormLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => { - const { error, formItemId } = useFormField() - - return ( -