WebUI 前端 & 后端超级大重构

This commit is contained in:
DrSmoothl
2026-03-14 21:06:36 +08:00
parent 6ca5a2939e
commit 172615f18a
69 changed files with 3128 additions and 6581 deletions

View File

@@ -10,6 +10,7 @@ import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import {
Dialog,
DialogBody,
DialogContent,
DialogDescription,
DialogFooter,
@@ -59,7 +60,7 @@ export function EmojiDetailDialog({
<DialogHeader>
<DialogTitle></DialogTitle>
</DialogHeader>
<ScrollArea className="max-h-[calc(90vh-8rem)] pr-4">
<DialogBody>
<div className="space-y-4">
{/* 表情包预览图 - 使用原图 */}
<div className="flex justify-center">
@@ -177,7 +178,7 @@ export function EmojiDetailDialog({
</div>
</div>
</div>
</ScrollArea>
</DialogBody>
</DialogContent>
</Dialog>
)
@@ -252,11 +253,12 @@ export function EmojiEditDialog({
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl">
<DialogContent className="max-w-2xl" confirmOnEnter>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription></DialogDescription>
</DialogHeader>
<DialogBody>
<div className="space-y-4">
<div>
<Label></Label>
@@ -310,11 +312,12 @@ export function EmojiEditDialog({
</div>
</div>
</div>
</DialogBody>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>
</Button>
<Button onClick={handleSave} disabled={saving}>
<Button data-dialog-action="confirm" onClick={handleSave} disabled={saving}>
{saving ? '保存中...' : '保存'}
</Button>
</DialogFooter>
@@ -658,7 +661,7 @@ export function EmojiUploadDialog({
<div className="flex gap-6">
{/* 预览图 */}
<div className="flex-shrink-0">
<div className="shrink-0">
<div className="w-32 h-32 rounded-lg border overflow-hidden bg-muted flex items-center justify-center">
<img
src={file.previewUrl}
@@ -764,7 +767,7 @@ export function EmojiUploadDialog({
<div className="grid grid-cols-2 gap-4">
{/* 左侧:文件卡片列表 */}
<ScrollArea className="h-[350px] pr-2">
<ScrollArea className="h-87.5 pr-2">
<div className="space-y-2">
{uploadedFiles.map((file) => {
const complete = isFileComplete(file)
@@ -782,7 +785,7 @@ export function EmojiUploadDialog({
${complete ? 'border-green-500 bg-green-50 dark:bg-green-950/20' : 'border-border hover:border-muted-foreground/50'}
`}
>
<div className="w-12 h-12 rounded border overflow-hidden bg-muted flex-shrink-0 flex items-center justify-center">
<div className="flex h-12 w-12 shrink-0 items-center justify-center overflow-hidden rounded border bg-muted">
<img
src={file.previewUrl}
alt={file.name}
@@ -796,9 +799,9 @@ export function EmojiUploadDialog({
</p>
</div>
{complete ? (
<CheckCircle2 className="h-5 w-5 text-green-500 flex-shrink-0" />
<CheckCircle2 className="h-5 w-5 shrink-0 text-green-500" />
) : (
<div className="h-5 w-5 rounded-full border-2 border-muted-foreground/30 flex-shrink-0" />
<div className="h-5 w-5 shrink-0 rounded-full border-2 border-muted-foreground/30" />
)}
</div>
)
@@ -908,7 +911,7 @@ export function EmojiUploadDialog({
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-3xl max-h-[90vh] overflow-hidden">
<DialogContent className="max-w-3xl max-h-[90vh] overflow-hidden" confirmOnEnter>
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<Upload className="h-5 w-5" />
@@ -925,11 +928,11 @@ export function EmojiUploadDialog({
</DialogDescription>
</DialogHeader>
<div className="overflow-y-auto pr-1">
<DialogBody viewportClassName="pr-1">
{step === 'select' && renderSelectStep()}
{step === 'edit-single' && renderEditSingleStep()}
{step === 'edit-multiple' && renderEditMultipleStep()}
</div>
</DialogBody>
</DialogContent>
</Dialog>
)

View File

@@ -15,6 +15,7 @@ import {
import { Button } from '@/components/ui/button'
import {
Dialog,
DialogBody,
DialogContent,
DialogDescription,
DialogFooter,
@@ -65,7 +66,7 @@ export function ExpressionDetailDialog({
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
<DialogContent className="max-w-2xl" confirmOnEnter>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
@@ -73,6 +74,7 @@ export function ExpressionDetailDialog({
</DialogDescription>
</DialogHeader>
<DialogBody>
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<InfoItem label="情境" value={expression.situation} />
@@ -131,6 +133,7 @@ export function ExpressionDetailDialog({
</div>
</div>
</div>
</DialogBody>
<DialogFooter>
<Button onClick={() => onOpenChange(false)}></Button>
@@ -233,7 +236,7 @@ export function ExpressionCreateDialog({
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
<DialogContent className="max-w-2xl" confirmOnEnter>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
@@ -241,6 +244,7 @@ export function ExpressionCreateDialog({
</DialogDescription>
</DialogHeader>
<DialogBody>
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
@@ -291,12 +295,13 @@ export function ExpressionCreateDialog({
</Select>
</div>
</div>
</DialogBody>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>
</Button>
<Button onClick={handleCreate} disabled={saving}>
<Button data-dialog-action="confirm" onClick={handleCreate} disabled={saving}>
{saving ? '创建中...' : '创建'}
</Button>
</DialogFooter>
@@ -371,7 +376,7 @@ export function ExpressionEditDialog({
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
<DialogContent className="max-w-2xl" confirmOnEnter>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
@@ -379,6 +384,7 @@ export function ExpressionEditDialog({
</DialogDescription>
</DialogHeader>
<DialogBody>
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
@@ -474,12 +480,13 @@ export function ExpressionEditDialog({
</div>
</div>
</div>
</DialogBody>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>
</Button>
<Button onClick={handleSave} disabled={saving}>
<Button data-dialog-action="confirm" onClick={handleSave} disabled={saving}>
{saving ? '保存中...' : '保存'}
</Button>
</DialogFooter>

View File

@@ -14,6 +14,7 @@ import {
import { Button } from '@/components/ui/button'
import {
Dialog,
DialogBody,
DialogContent,
DialogDescription,
DialogFooter,
@@ -24,7 +25,6 @@ import { Badge } from '@/components/ui/badge'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { MarkdownRenderer } from '@/components/markdown-renderer'
import { ScrollArea } from '@/components/ui/scroll-area'
import {
Select,
SelectContent,
@@ -92,7 +92,7 @@ export function JargonDetailDialog({
<DialogDescription></DialogDescription>
</DialogHeader>
<ScrollArea className="h-full pr-4">
<DialogBody className="h-full">
<div className="space-y-4 pb-2">
<div className="grid grid-cols-2 gap-4">
<InfoItem icon={Hash} label="记录ID" value={jargon.id.toString()} mono />
@@ -167,7 +167,7 @@ export function JargonDetailDialog({
</div>
)}
</div>
</ScrollArea>
</DialogBody>
<DialogFooter className="flex-shrink-0">
<Button onClick={() => onOpenChange(false)}></Button>
@@ -234,12 +234,13 @@ export function JargonCreateDialog({
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
<DialogContent className="max-w-2xl" confirmOnEnter>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription></DialogDescription>
</DialogHeader>
<DialogBody>
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="content">
@@ -294,10 +295,11 @@ export function JargonCreateDialog({
<Label htmlFor="is_global"></Label>
</div>
</div>
</DialogBody>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}></Button>
<Button onClick={handleCreate} disabled={saving}>
<Button data-dialog-action="confirm" onClick={handleCreate} disabled={saving}>
{saving ? '创建中...' : '创建'}
</Button>
</DialogFooter>
@@ -366,12 +368,13 @@ export function JargonEditDialog({
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
<DialogContent className="max-w-2xl" confirmOnEnter>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription></DialogDescription>
</DialogHeader>
<DialogBody>
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="edit_content"></Label>
@@ -439,10 +442,11 @@ export function JargonEditDialog({
<Label htmlFor="edit_is_global"></Label>
</div>
</div>
</DialogBody>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}></Button>
<Button onClick={handleSave} disabled={saving}>
<Button data-dialog-action="confirm" onClick={handleSave} disabled={saving}>
{saving ? '保存中...' : '保存'}
</Button>
</DialogFooter>

View File

@@ -2,11 +2,11 @@
import { Badge } from '@/components/ui/badge'
import {
Dialog,
DialogBody,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'
import { ScrollArea } from '@/components/ui/scroll-area'
import type { GraphNode, SelectedEdgeData } from './types'
@@ -24,7 +24,7 @@ export function NodeDetailDialog({ open, onOpenChange, selectedNodeData }: NodeD
<DialogTitle></DialogTitle>
</DialogHeader>
{selectedNodeData && (
<ScrollArea className="h-full pr-4">
<DialogBody className="h-full">
<div className="space-y-4 pb-2">
<div className="grid grid-cols-2 gap-4">
<div>
@@ -62,7 +62,7 @@ export function NodeDetailDialog({ open, onOpenChange, selectedNodeData }: NodeD
)}
</div>
</div>
</ScrollArea>
</DialogBody>
)}
</DialogContent>
</Dialog>
@@ -83,7 +83,7 @@ export function EdgeDetailDialog({ open, onOpenChange, selectedEdgeData }: EdgeD
<DialogTitle></DialogTitle>
</DialogHeader>
{selectedEdgeData && (
<ScrollArea className="flex-1 pr-4">
<DialogBody>
<div className="space-y-4">
<div className="flex items-center gap-4">
<div className="flex-1 min-w-0 p-3 bg-blue-50 dark:bg-blue-950 rounded border-2 border-blue-200 dark:border-blue-800">
@@ -114,7 +114,7 @@ export function EdgeDetailDialog({ open, onOpenChange, selectedEdgeData }: EdgeD
</div>
</div>
</div>
</ScrollArea>
</DialogBody>
)}
</DialogContent>
</Dialog>