109 lines
3.2 KiB
TypeScript
109 lines
3.2 KiB
TypeScript
import { useCallback, useEffect } from 'react';
|
|
import axios from 'axios';
|
|
|
|
import { APP_ENDPOINTS } from '../../../config/env';
|
|
import { resolveApiErrorMessage } from '../../../shared/http/apiErrors';
|
|
import type { BotState } from '../../../types/bot';
|
|
import type { ChatMessage } from '../../../types/bot';
|
|
import type { DashboardLabels } from '../localeTypes';
|
|
|
|
type PromptTone = 'info' | 'success' | 'warning' | 'error';
|
|
|
|
interface NotifyOptions {
|
|
title?: string;
|
|
tone?: PromptTone;
|
|
durationMs?: number;
|
|
}
|
|
|
|
interface ConfirmOptions {
|
|
title?: string;
|
|
message: string;
|
|
tone?: PromptTone;
|
|
confirmText?: string;
|
|
cancelText?: string;
|
|
}
|
|
|
|
interface UseDashboardBotManagementOptions {
|
|
confirm: (options: ConfirmOptions) => Promise<boolean>;
|
|
mergeBot: (bot: BotState) => void;
|
|
notify: (message: string, options?: NotifyOptions) => void;
|
|
refresh: () => Promise<void>;
|
|
selectedBot?: BotState;
|
|
selectedBotId: string;
|
|
setBotMessages: (botId: string, messages: ChatMessage[]) => void;
|
|
setSelectedBotId: (botId: string) => void;
|
|
t: DashboardLabels;
|
|
}
|
|
|
|
export function useDashboardBotManagement({
|
|
confirm,
|
|
mergeBot,
|
|
notify,
|
|
refresh,
|
|
selectedBot,
|
|
selectedBotId,
|
|
setBotMessages,
|
|
setSelectedBotId,
|
|
t,
|
|
}: UseDashboardBotManagementOptions) {
|
|
useEffect(() => {
|
|
if (!selectedBotId) return;
|
|
let alive = true;
|
|
const loadBotDetail = async () => {
|
|
try {
|
|
const res = await axios.get<BotState>(`${APP_ENDPOINTS.apiBase}/bots/${selectedBotId}`);
|
|
if (alive) mergeBot(res.data);
|
|
} catch (error) {
|
|
console.error(`Failed to fetch bot detail for ${selectedBotId}`, error);
|
|
}
|
|
};
|
|
void loadBotDetail();
|
|
return () => {
|
|
alive = false;
|
|
};
|
|
}, [mergeBot, selectedBotId]);
|
|
|
|
const removeBot = useCallback(async (botId?: string) => {
|
|
const targetId = botId || selectedBot?.id;
|
|
if (!targetId) return;
|
|
const ok = await confirm({
|
|
title: t.delete,
|
|
message: t.deleteBotConfirm(targetId),
|
|
tone: 'warning',
|
|
});
|
|
if (!ok) return;
|
|
try {
|
|
await axios.delete(`${APP_ENDPOINTS.apiBase}/bots/${targetId}`, { params: { delete_workspace: true } });
|
|
await refresh();
|
|
if (selectedBotId === targetId) setSelectedBotId('');
|
|
notify(t.deleteBotDone, { tone: 'success' });
|
|
} catch {
|
|
notify(t.deleteFail, { tone: 'error' });
|
|
}
|
|
}, [confirm, notify, refresh, selectedBot?.id, selectedBotId, setSelectedBotId, t]);
|
|
|
|
const clearConversationHistory = useCallback(async () => {
|
|
if (!selectedBot) return;
|
|
const target = selectedBot.name || selectedBot.id;
|
|
const ok = await confirm({
|
|
title: t.clearHistory,
|
|
message: t.clearHistoryConfirm(target),
|
|
tone: 'warning',
|
|
});
|
|
if (!ok) return;
|
|
try {
|
|
await axios.delete(`${APP_ENDPOINTS.apiBase}/bots/${selectedBot.id}/messages`);
|
|
setBotMessages(selectedBot.id, []);
|
|
notify(t.clearHistoryDone, { tone: 'success' });
|
|
} catch (error: unknown) {
|
|
const message = resolveApiErrorMessage(error, t.clearHistoryFail);
|
|
notify(message, { tone: 'error' });
|
|
}
|
|
}, [confirm, notify, selectedBot, setBotMessages, t]);
|
|
|
|
return {
|
|
clearConversationHistory,
|
|
removeBot,
|
|
};
|
|
}
|