Add Switch component to UI and integrate it into DebugDrawer for tool state management. Update Assistants page to utilize the new Switch for enabling/disabling tools, enhancing user interaction and component functionality.

This commit is contained in:
Xin Wang
2026-02-27 17:55:35 +08:00
parent 531cf6080a
commit 4d9f083e20
2 changed files with 37 additions and 10 deletions

View File

@@ -65,6 +65,37 @@ export const Select: React.FC<SelectProps> = ({ className = '', children, ...pro
);
};
interface SwitchProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> {
checked: boolean;
onCheckedChange: (checked: boolean) => void;
}
export const Switch: React.FC<SwitchProps> = ({
checked,
onCheckedChange,
className = '',
disabled,
...props
}) => {
return (
<button
type="button"
role="switch"
aria-checked={checked}
disabled={disabled}
onClick={() => {
if (!disabled) onCheckedChange(!checked);
}}
className={`relative h-6 w-11 rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60 focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 ${checked ? 'bg-emerald-500/80' : 'bg-white/20'} ${className}`}
{...props}
>
<span
className={`absolute left-0.5 top-1/2 h-5 w-5 -translate-y-1/2 rounded-full bg-white shadow transition-transform ${checked ? 'translate-x-5' : 'translate-x-0'}`}
/>
</button>
);
};
// Card - Glassmorphism style, very subtle border
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;

View File

@@ -2,7 +2,7 @@
import React, { useState, useEffect, useMemo, useRef } from 'react';
import { createPortal } from 'react-dom';
import { Plus, Search, Play, Square, Copy, Trash2, Mic, MessageSquare, Save, Video, PhoneOff, Camera, ArrowLeftRight, Send, Phone, Rocket, AlertTriangle, PhoneCall, CameraOff, Image, Images, CloudSun, Calendar, TrendingUp, Coins, Wrench, Globe, Terminal, X, ClipboardCheck, Sparkles, Volume2, Timer, ChevronDown, Database, Server, Zap, ExternalLink, Key, BrainCircuit, Ear, Book, Filter } from 'lucide-react';
import { Button, Input, Badge, Drawer, Dialog } from '../components/UI';
import { Button, Input, Badge, Drawer, Dialog, Switch } from '../components/UI';
import { ASRModel, Assistant, KnowledgeBase, LLMModel, TabValue, Tool, Voice } from '../types';
import { createAssistant, deleteAssistant, fetchASRModels, fetchAssistantOpenerAudioPcmBuffer, fetchAssistants, fetchKnowledgeBases, fetchLLMModels, fetchTools, fetchVoices, generateAssistantOpenerAudio, updateAssistant as updateAssistantApi } from '../services/backendApi';
@@ -3642,16 +3642,12 @@ export const DebugDrawer: React.FC<{
<div className="text-[11px] font-mono text-foreground truncate">{tool.name}</div>
<div className="text-[10px] text-muted-foreground truncate">{tool.description}</div>
</div>
<button
type="button"
onClick={() => setClientToolEnabledMap((prev) => ({ ...prev, [tool.id]: !enabled }))}
className={`relative h-6 w-11 rounded-full transition-colors ${enabled ? 'bg-emerald-500/80' : 'bg-white/20'}`}
<Switch
checked={enabled}
onCheckedChange={(next) => setClientToolEnabledMap((prev) => ({ ...prev, [tool.id]: next }))}
title={enabled ? '点击关闭' : '点击开启'}
>
<span
className={`absolute top-0.5 h-5 w-5 rounded-full bg-white shadow transition-transform ${enabled ? 'translate-x-5' : 'translate-x-0.5'}`}
aria-label={`${tool.name} ${enabled ? '开启' : '关闭'}`}
/>
</button>
</div>
);
})}