fix whatsapp

This commit is contained in:
lpf
2026-03-09 19:35:12 +08:00
parent de77e6c786
commit 0b9192132f
25 changed files with 2311 additions and 139 deletions

View File

@@ -227,14 +227,14 @@ const Nodes: React.FC = () => {
</div>
<div className="grid grid-cols-1 xl:grid-cols-[300px_1fr_1.1fr] gap-4 flex-1 min-h-0">
<div className="brand-card rounded-[28px] border border-zinc-800 overflow-hidden flex flex-col min-h-0">
<div className="px-3 py-2 border-b border-zinc-800 space-y-2">
<div className="brand-card ui-panel rounded-[28px] overflow-hidden flex flex-col min-h-0">
<div className="px-3 py-2 border-b border-zinc-800 dark:border-zinc-700 space-y-2">
<div className="text-xs text-zinc-400 uppercase tracking-wider">{t('nodes')}</div>
<input
value={nodeFilter}
onChange={(e) => setNodeFilter(e.target.value)}
placeholder={t('nodesFilterPlaceholder')}
className="w-full rounded-xl bg-zinc-950/70 border border-zinc-800 px-3 py-2 text-sm"
className="ui-input rounded-xl px-3 py-2 text-sm"
/>
</div>
<div className="overflow-y-auto min-h-0">
@@ -277,8 +277,8 @@ const Nodes: React.FC = () => {
</div>
</div>
<div className="brand-card rounded-[28px] border border-zinc-800 overflow-hidden flex flex-col min-h-0">
<div className="px-3 py-2 border-b border-zinc-800 text-xs text-zinc-400 uppercase tracking-wider">{t('nodeDetails')}</div>
<div className="brand-card ui-panel rounded-[28px] overflow-hidden flex flex-col min-h-0">
<div className="px-3 py-2 border-b border-zinc-800 dark:border-zinc-700 text-xs text-zinc-400 uppercase tracking-wider">{t('nodeDetails')}</div>
<div className="p-4 overflow-y-auto min-h-0 space-y-4 text-sm">
{!selectedNode ? (
<div className="text-zinc-500">{t('noNodes')}</div>
@@ -310,7 +310,7 @@ const Nodes: React.FC = () => {
<div>
<div className="text-zinc-500 text-xs mb-1">{t('nodeTags')}</div>
<div className="p-3 rounded-2xl bg-zinc-950/60 border border-zinc-800 text-zinc-200 break-all">
<div className="ui-code-panel p-3 break-all">
{Array.isArray(selectedNode.tags) && selectedNode.tags.length > 0 ? selectedNode.tags.join(', ') : '-'}
</div>
</div>
@@ -318,25 +318,25 @@ const Nodes: React.FC = () => {
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<div className="text-zinc-500 text-xs mb-1">{t('nodeCapabilities')}</div>
<div className="p-3 rounded-2xl bg-zinc-950/60 border border-zinc-800 text-zinc-200 break-all">
<div className="ui-code-panel p-3 break-all">
{Object.entries(selectedNode.capabilities || {}).filter(([, enabled]) => Boolean(enabled)).map(([key]) => key).join(', ') || '-'}
</div>
</div>
<div>
<div className="text-zinc-500 text-xs mb-1">{t('nodeActions')}</div>
<div className="p-3 rounded-2xl bg-zinc-950/60 border border-zinc-800 text-zinc-200 break-all">
<div className="ui-code-panel p-3 break-all">
{Array.isArray(selectedNode.actions) && selectedNode.actions.length > 0 ? selectedNode.actions.join(', ') : '-'}
</div>
</div>
<div>
<div className="text-zinc-500 text-xs mb-1">{t('nodeModels')}</div>
<div className="p-3 rounded-2xl bg-zinc-950/60 border border-zinc-800 text-zinc-200 break-all">
<div className="ui-code-panel p-3 break-all">
{Array.isArray(selectedNode.models) && selectedNode.models.length > 0 ? selectedNode.models.join(', ') : '-'}
</div>
</div>
<div>
<div className="text-zinc-500 text-xs mb-1">{t('nodeAgents')}</div>
<div className="p-3 rounded-2xl bg-zinc-950/60 border border-zinc-800 text-zinc-200 break-all">
<div className="ui-code-panel p-3 break-all">
{Array.isArray(selectedNode.agents) && selectedNode.agents.length > 0 ? selectedNode.agents.map((item: any) => String(item?.id || '-')).join(', ') : '-'}
</div>
</div>
@@ -357,14 +357,14 @@ const Nodes: React.FC = () => {
</div>
);
}) : (
<div className="p-3 rounded-2xl bg-zinc-950/60 border border-zinc-800 text-zinc-500">{t('nodeAlertsEmpty')}</div>
<div className="ui-code-panel p-3 text-zinc-500">{t('nodeAlertsEmpty')}</div>
)}
</div>
</div>
<div>
<div className="text-zinc-500 text-xs mb-1">{t('nodeP2P')}</div>
<div className="p-3 rounded-2xl bg-zinc-950/60 border border-zinc-800 text-zinc-200">
<div className="ui-code-panel p-3">
{selectedSession ? (
<div className="grid grid-cols-2 gap-3 text-xs">
<div><div className="text-zinc-500">{t('status')}</div><div>{String(selectedSession.status || 'unknown')}</div></div>
@@ -380,7 +380,7 @@ const Nodes: React.FC = () => {
<div>
<div className="text-zinc-500 text-xs mb-1">{t('agentTree')}</div>
<div className="p-3 rounded-2xl bg-zinc-950/60 border border-zinc-800 text-zinc-200 space-y-2">
<div className="ui-code-panel p-3 space-y-2">
{Array.isArray(selectedTree?.items) && selectedTree.items.length > 0 ? selectedTree.items.map((item: any, index: number) => (
<div key={`${item?.agent_id || index}`} className="rounded-xl border border-zinc-800/80 bg-black/20 p-3">
<div className="text-sm font-medium text-zinc-100">{String(item?.display_name || item?.agent_id || '-')}</div>
@@ -396,19 +396,19 @@ const Nodes: React.FC = () => {
</div>
</div>
<div className="brand-card rounded-[28px] border border-zinc-800 overflow-hidden flex flex-col min-h-0">
<div className="px-3 py-2 border-b border-zinc-800 space-y-2">
<div className="brand-card ui-panel rounded-[28px] overflow-hidden flex flex-col min-h-0">
<div className="px-3 py-2 border-b border-zinc-800 dark:border-zinc-700 space-y-2">
<div className="text-xs text-zinc-400 uppercase tracking-wider">{t('nodeDispatchDetail')}</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-2">
<select value={dispatchActionFilter} onChange={(e) => setDispatchActionFilter(e.target.value)} className="rounded-xl bg-zinc-950/70 border border-zinc-800 px-2 py-2 text-xs">
<select value={dispatchActionFilter} onChange={(e) => setDispatchActionFilter(e.target.value)} className="ui-select rounded-xl px-2 py-2 text-xs">
<option value="all">{t('allActions')}</option>
{dispatchActions.map((action) => <option key={action} value={action}>{action}</option>)}
</select>
<select value={dispatchTransportFilter} onChange={(e) => setDispatchTransportFilter(e.target.value)} className="rounded-xl bg-zinc-950/70 border border-zinc-800 px-2 py-2 text-xs">
<select value={dispatchTransportFilter} onChange={(e) => setDispatchTransportFilter(e.target.value)} className="ui-select rounded-xl px-2 py-2 text-xs">
<option value="all">{t('allTransports')}</option>
{dispatchTransports.map((transport) => <option key={transport} value={transport}>{transport}</option>)}
</select>
<select value={dispatchStatusFilter} onChange={(e) => setDispatchStatusFilter(e.target.value)} className="rounded-xl bg-zinc-950/70 border border-zinc-800 px-2 py-2 text-xs">
<select value={dispatchStatusFilter} onChange={(e) => setDispatchStatusFilter(e.target.value)} className="ui-select rounded-xl px-2 py-2 text-xs">
<option value="all">{t('allStatus')}</option>
<option value="ok">ok</option>
<option value="error">error</option>
@@ -416,7 +416,7 @@ const Nodes: React.FC = () => {
</div>
</div>
<div className="grid grid-rows-[220px_1fr] min-h-0 flex-1">
<div className="overflow-y-auto min-h-0 border-b border-zinc-800/60">
<div className="overflow-y-auto min-h-0 border-b border-zinc-800/60 dark:border-zinc-700/60">
{filteredDispatches.length === 0 ? (
<div className="p-4 text-sm text-zinc-500">{t('dashboardNodeDispatchesEmpty')}</div>
) : filteredDispatches.map((item: any, index: number) => {
@@ -478,7 +478,7 @@ const Nodes: React.FC = () => {
<div>
<div className="text-zinc-500 text-xs mb-1">{t('error')}</div>
<div className="p-3 rounded-2xl bg-zinc-950/60 border border-zinc-800 whitespace-pre-wrap text-zinc-200">{selectedDispatch.error || '-'}</div>
<div className="ui-code-panel p-3 whitespace-pre-wrap">{selectedDispatch.error || '-'}</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
@@ -488,7 +488,7 @@ const Nodes: React.FC = () => {
<div className="grid grid-cols-3 gap-2">
<label className="space-y-1">
<div className="text-zinc-500 text-[11px]">{t('mode')}</div>
<select value={replayModeDraft} onChange={(e) => setReplayModeDraft(e.target.value)} className="w-full rounded-xl border border-zinc-800 bg-zinc-950/60 px-2 py-2 text-xs">
<select value={replayModeDraft} onChange={(e) => setReplayModeDraft(e.target.value)} className="ui-select w-full rounded-xl px-2 py-2 text-xs">
<option value="auto">auto</option>
<option value="p2p">p2p</option>
<option value="relay">relay</option>
@@ -496,16 +496,16 @@ const Nodes: React.FC = () => {
</label>
<label className="space-y-1 col-span-2">
<div className="text-zinc-500 text-[11px]">{t('model')}</div>
<input value={replayModelDraft} onChange={(e) => setReplayModelDraft(e.target.value)} className="w-full rounded-xl border border-zinc-800 bg-zinc-950/60 px-3 py-2 text-xs" />
<input value={replayModelDraft} onChange={(e) => setReplayModelDraft(e.target.value)} className="ui-input w-full rounded-xl px-3 py-2 text-xs" />
</label>
</div>
<label className="space-y-1 block">
<div className="text-zinc-500 text-[11px]">{t('task')}</div>
<textarea value={replayTaskDraft} onChange={(e) => setReplayTaskDraft(e.target.value)} className="min-h-24 w-full rounded-2xl border border-zinc-800 bg-zinc-950/60 p-3 text-xs" />
<textarea value={replayTaskDraft} onChange={(e) => setReplayTaskDraft(e.target.value)} className="ui-textarea min-h-24 w-full p-3 text-xs" />
</label>
<label className="space-y-1 block">
<div className="text-zinc-500 text-[11px]">{t('args')}</div>
<textarea value={replayArgsDraft} onChange={(e) => setReplayArgsDraft(e.target.value)} className="min-h-40 w-full rounded-2xl border border-zinc-800 bg-zinc-950/60 p-3 text-xs font-mono" />
<textarea value={replayArgsDraft} onChange={(e) => setReplayArgsDraft(e.target.value)} className="ui-textarea min-h-40 w-full p-3 text-xs font-mono" />
</label>
</div>
</div>
@@ -514,7 +514,7 @@ const Nodes: React.FC = () => {
{replayError ? (
<div className="rounded-2xl border border-red-900/50 bg-red-950/20 p-3 text-xs whitespace-pre-wrap text-red-300">{replayError}</div>
) : (
<pre className="rounded-2xl border border-zinc-800 bg-zinc-950/60 p-3 text-xs overflow-auto">{replayResult ? JSON.stringify(replayResult, null, 2) : '-'}</pre>
<pre className="ui-code-panel p-3 text-xs overflow-auto">{replayResult ? JSON.stringify(replayResult, null, 2) : '-'}</pre>
)}
</div>
</div>
@@ -551,7 +551,7 @@ const Nodes: React.FC = () => {
<div>
<div className="text-zinc-500 text-xs mb-1">{t('rawJson')}</div>
<pre className="rounded-2xl border border-zinc-800 bg-zinc-950/60 p-3 text-xs overflow-auto">{selectedDispatchPretty}</pre>
<pre className="ui-code-panel p-3 text-xs overflow-auto">{selectedDispatchPretty}</pre>
</div>
</>
)}