WebUI 前端 & 后端超级大重构
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
} from '@/components/ui/alert-dialog'
|
||||
import {
|
||||
Dialog,
|
||||
DialogBody,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
@@ -249,7 +250,7 @@ function RegexEditor({
|
||||
正则编辑器
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-w-[95vw] sm:max-w-[900px] max-h-[90vh]">
|
||||
<DialogContent className="max-w-[95vw] sm:max-w-225">
|
||||
<DialogHeader>
|
||||
<DialogTitle>正则表达式编辑器</DialogTitle>
|
||||
<DialogDescription className="text-sm">
|
||||
@@ -257,7 +258,7 @@ function RegexEditor({
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<ScrollArea className="max-h-[calc(90vh-120px)]">
|
||||
<DialogBody>
|
||||
<Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as 'build' | 'test')} className="w-full">
|
||||
<TabsList className="grid w-full grid-cols-2">
|
||||
<TabsTrigger value="build">🔧 构建器</TabsTrigger>
|
||||
@@ -406,7 +407,7 @@ function RegexEditor({
|
||||
value={testText}
|
||||
onChange={(e) => setTestText(e.target.value)}
|
||||
placeholder="在此输入要测试的文本... 例如:打游戏是这样的"
|
||||
className="min-h-[100px] text-sm"
|
||||
className="min-h-25 text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -444,7 +445,7 @@ function RegexEditor({
|
||||
<div className="space-y-2">
|
||||
<Label className="text-sm font-medium">匹配高亮</Label>
|
||||
<ScrollArea className="h-40 rounded-md bg-muted p-3">
|
||||
<div className="text-sm break-words">
|
||||
<div className="text-sm wrap-break-word">
|
||||
{renderHighlightedText()}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
@@ -458,7 +459,7 @@ function RegexEditor({
|
||||
<div className="space-y-2">
|
||||
{Object.entries(captureGroups).map(([name, value]) => (
|
||||
<div key={name} className="flex items-start gap-2 text-sm">
|
||||
<span className="font-mono font-semibold text-primary min-w-[80px]">[{name}]</span>
|
||||
<span className="font-mono font-semibold text-primary min-w-20">[{name}]</span>
|
||||
<span className="text-muted-foreground">=</span>
|
||||
<span className="font-mono bg-muted px-2 py-0.5 rounded">{value}</span>
|
||||
</div>
|
||||
@@ -473,7 +474,7 @@ function RegexEditor({
|
||||
<div className="space-y-2">
|
||||
<Label className="text-sm font-medium">Reaction 替换预览</Label>
|
||||
<ScrollArea className="h-48 rounded-md bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 p-3">
|
||||
<div className="text-sm break-words">
|
||||
<div className="text-sm wrap-break-word">
|
||||
{replacedReaction}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
@@ -497,7 +498,7 @@ function RegexEditor({
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</ScrollArea>
|
||||
</DialogBody>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
@@ -628,7 +629,7 @@ export const ProcessingSection = React.memo(function ProcessingSection({
|
||||
预览
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-[95vw] sm:w-[500px]">
|
||||
<PopoverContent className="w-[95vw] sm:w-125">
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-medium text-sm">配置预览</h4>
|
||||
<ScrollArea className="h-60 rounded-md bg-muted p-3">
|
||||
@@ -656,7 +657,7 @@ export const ProcessingSection = React.memo(function ProcessingSection({
|
||||
预览
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-[95vw] sm:w-[500px]">
|
||||
<PopoverContent className="w-[95vw] sm:w-125">
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-medium text-sm">配置预览</h4>
|
||||
<ScrollArea className="h-60 rounded-md bg-muted p-3">
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import {
|
||||
Dialog,
|
||||
DialogBody,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
@@ -971,9 +972,10 @@ function ModelConfigPageContent() {
|
||||
{/* 编辑模型对话框 */}
|
||||
<Dialog open={editDialogOpen} onOpenChange={handleEditDialogClose}>
|
||||
<DialogContent
|
||||
className="max-w-[95vw] sm:max-w-2xl max-h-[90vh] overflow-y-auto"
|
||||
className="max-w-[95vw] sm:max-w-2xl"
|
||||
data-tour="model-dialog"
|
||||
preventOutsideClose={tourIsRunning}
|
||||
confirmOnEnter
|
||||
>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
@@ -982,6 +984,7 @@ function ModelConfigPageContent() {
|
||||
<DialogDescription>配置模型的基本信息和参数</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<DialogBody>
|
||||
<div className="grid gap-4 py-4">
|
||||
<div className="grid gap-2" data-tour="model-name-input">
|
||||
<Label htmlFor="model_name" className={formErrors.name ? 'text-destructive' : ''}>模型名称 *</Label>
|
||||
@@ -1492,12 +1495,13 @@ function ModelConfigPageContent() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</DialogBody>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => setEditDialogOpen(false)} data-tour="model-cancel-button">
|
||||
取消
|
||||
</Button>
|
||||
<Button onClick={handleSaveEdit} data-tour="model-save-button">保存</Button>
|
||||
<Button data-dialog-action="confirm" onClick={handleSaveEdit} data-tour="model-save-button">保存</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Check, ChevronsUpDown, Copy, Eye, EyeOff } from 'lucide-react'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { HelpTooltip } from '@/components/ui/help-tooltip'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
@@ -116,9 +116,10 @@ export function ProviderForm({
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent
|
||||
className="max-w-[95vw] sm:max-w-2xl max-h-[90vh] overflow-y-auto"
|
||||
className="max-w-[95vw] sm:max-w-2xl"
|
||||
data-tour="provider-dialog"
|
||||
preventOutsideClose={tourState.isRunning}
|
||||
confirmOnEnter
|
||||
>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
@@ -130,6 +131,7 @@ export function ProviderForm({
|
||||
</DialogHeader>
|
||||
|
||||
<form onSubmit={(e) => { e.preventDefault(); handleSaveEdit(); }} autoComplete="off">
|
||||
<DialogBody>
|
||||
<div className="grid gap-4 py-4">
|
||||
<div className="grid gap-2" data-tour="provider-template-select">
|
||||
<Label htmlFor="template">提供商模板</Label>
|
||||
@@ -450,12 +452,13 @@ export function ProviderForm({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DialogBody>
|
||||
|
||||
<DialogFooter>
|
||||
<Button type="button" variant="outline" onClick={() => onOpenChange(false)} data-tour="provider-cancel-button">
|
||||
取消
|
||||
</Button>
|
||||
<Button type="submit" data-tour="provider-save-button">保存</Button>
|
||||
<Button type="submit" data-dialog-action="confirm" data-tour="provider-save-button">保存</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
|
||||
@@ -40,6 +40,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
|
||||
import {
|
||||
Dialog,
|
||||
DialogBody,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
@@ -575,7 +576,7 @@ function ApplyDialog({
|
||||
|
||||
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 className="flex items-center gap-2">
|
||||
<Package className="w-5 h-5" />
|
||||
@@ -589,6 +590,7 @@ function ApplyDialog({
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<DialogBody>
|
||||
{detectingConflicts ? (
|
||||
<div className="py-8 text-center">
|
||||
<Loader2 className="w-8 h-8 mx-auto animate-spin text-primary" />
|
||||
@@ -831,6 +833,7 @@ function ApplyDialog({
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</DialogBody>
|
||||
|
||||
<DialogFooter className="flex justify-between">
|
||||
<div>
|
||||
@@ -845,11 +848,11 @@ function ApplyDialog({
|
||||
取消
|
||||
</Button>
|
||||
{step < totalSteps ? (
|
||||
<Button onClick={() => setStep(step + 1)} disabled={detectingConflicts}>
|
||||
<Button data-dialog-action="confirm" onClick={() => setStep(step + 1)} disabled={detectingConflicts}>
|
||||
下一步
|
||||
</Button>
|
||||
) : (
|
||||
<Button onClick={onApply} disabled={applying}>
|
||||
<Button data-dialog-action="confirm" onClick={onApply} disabled={applying}>
|
||||
{applying && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
|
||||
应用模板
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user