dashboard-nanobot/frontend/src/modules/dashboard/hooks/useDashboardBotManagement.ts

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,
};
}