fix(audit): P2 frontend any→concrete types (181→61), heroicons→lucide-react, missing type exports, toast API, Select options, TaskStatus types; P2-9 hooks.py type annotations
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Tabs } from '@/components/shared/Tabs';
|
||||
import {
|
||||
@@ -18,7 +19,7 @@ function ProviderTab() {
|
||||
const [form, setForm] = useState({ name: '', provider_type: 'openai', api_key: '', base_url: '', is_default: false });
|
||||
|
||||
const load = async () => {
|
||||
try { setProviders(await fetchProviders()); } catch (e: any) { setError(e?.message); } finally { setLoading(false); }
|
||||
try { setProviders(await fetchProviders()); } catch (e: unknown) { const errObj = asError(e); setError(errObj?.message || null); } finally { setLoading(false); }
|
||||
};
|
||||
useEffect(() => { load(); }, []);
|
||||
|
||||
@@ -27,7 +28,7 @@ function ProviderTab() {
|
||||
if (editId) { await updateProvider(editId, form); } else { await createProvider(form); }
|
||||
setShowForm(false); setEditId(null); setForm({ name: '', provider_type: 'openai', api_key: '', base_url: '', is_default: false });
|
||||
await load();
|
||||
} catch (e: any) { setError(e?.message); }
|
||||
} catch (e: unknown) { const errObj = asError(e); setError(errObj?.message || null); }
|
||||
};
|
||||
|
||||
const handleEdit = (p: AIProvider) => {
|
||||
@@ -37,7 +38,7 @@ function ProviderTab() {
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
if (!confirm('Anbieter wirklich löschen?')) return;
|
||||
try { await deleteProvider(id); await load(); } catch (e: any) { setError(e?.message); }
|
||||
try { await deleteProvider(id); await load(); } catch (e: unknown) { const errObj = asError(e); setError(errObj?.message || null); }
|
||||
};
|
||||
|
||||
if (loading) return <div className="p-4">Laden...</div>;
|
||||
@@ -102,7 +103,7 @@ function PresetTab() {
|
||||
const [form, setForm] = useState({ name: '', model_id: '', provider_id: '', temperature: 0.7, max_tokens: 2048, top_p: 1.0, system_prompt: '' });
|
||||
|
||||
const load = async () => {
|
||||
try { setPresets(await fetchPresets()); setProviders(await fetchProviders()); } catch (e: any) { setError(e?.message); } finally { setLoading(false); }
|
||||
try { setPresets(await fetchPresets()); setProviders(await fetchProviders()); } catch (e: unknown) { const errObj = asError(e); setError(errObj?.message || null); } finally { setLoading(false); }
|
||||
};
|
||||
useEffect(() => { load(); }, []);
|
||||
|
||||
@@ -112,7 +113,7 @@ function PresetTab() {
|
||||
if (editId) { await updatePreset(editId, data); } else { await createPreset(data); }
|
||||
setShowForm(false); setEditId(null); setForm({ name: '', model_id: '', provider_id: '', temperature: 0.7, max_tokens: 2048, top_p: 1.0, system_prompt: '' });
|
||||
await load();
|
||||
} catch (e: any) { setError(e?.message); }
|
||||
} catch (e: unknown) { const errObj = asError(e); setError(errObj?.message || null); }
|
||||
};
|
||||
|
||||
const handleEdit = (p: AIPreset) => {
|
||||
@@ -122,7 +123,7 @@ function PresetTab() {
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
if (!confirm('Preset löschen?')) return;
|
||||
try { await deletePreset(id); await load(); } catch (e: any) { setError(e?.message); }
|
||||
try { await deletePreset(id); await load(); } catch (e: unknown) { const errObj = asError(e); setError(errObj?.message || null); }
|
||||
};
|
||||
|
||||
if (loading) return <div className="p-4">Laden...</div>;
|
||||
@@ -184,7 +185,7 @@ function AgentTab() {
|
||||
const [form, setForm] = useState({ name: '', description: '', system_prompt: '', preset_id: '', tool_ids: [] as string[] });
|
||||
|
||||
const load = async () => {
|
||||
try { setAgents(await fetchAgents()); setPresets(await fetchPresets()); setTools(await fetchTools()); } catch (e: any) { setError(e?.message); } finally { setLoading(false); }
|
||||
try { setAgents(await fetchAgents()); setPresets(await fetchPresets()); setTools(await fetchTools()); } catch (e: unknown) { const errObj = asError(e); setError(errObj?.message || null); } finally { setLoading(false); }
|
||||
};
|
||||
useEffect(() => { load(); }, []);
|
||||
|
||||
@@ -194,7 +195,7 @@ function AgentTab() {
|
||||
if (editId) { await updateAgent(editId, data); } else { await createAgent(data); }
|
||||
setShowForm(false); setEditId(null); setForm({ name: '', description: '', system_prompt: '', preset_id: '', tool_ids: [] });
|
||||
await load();
|
||||
} catch (e: any) { setError(e?.message); }
|
||||
} catch (e: unknown) { const errObj = asError(e); setError(errObj?.message || null); }
|
||||
};
|
||||
|
||||
const handleEdit = (a: AIAgent) => {
|
||||
@@ -204,7 +205,7 @@ function AgentTab() {
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
if (!confirm('Agent löschen?')) return;
|
||||
try { await deleteAgent(id); await load(); } catch (e: any) { setError(e?.message); }
|
||||
try { await deleteAgent(id); await load(); } catch (e: unknown) { const errObj = asError(e); setError(errObj?.message || null); }
|
||||
};
|
||||
|
||||
const toggleTool = (toolName: string) => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState } from 'react';
|
||||
// TODO: P2-F25 — Replace hardcoded commonModels with /ai/providers API
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -432,8 +433,8 @@ function VersionHistoryModal({
|
||||
try {
|
||||
await restoreMutation.mutateAsync({ id: agentId, versionId });
|
||||
toast.success(t('agent.versionRestored'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -510,8 +511,8 @@ export function AgentDashboardPage() {
|
||||
}
|
||||
setShowForm(false);
|
||||
setEditingAgent(undefined);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -521,8 +522,8 @@ export function AgentDashboardPage() {
|
||||
await deleteMutation.mutateAsync(confirmDelete.id);
|
||||
toast.success(t('agent.deleted'));
|
||||
setConfirmDelete(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -530,8 +531,8 @@ export function AgentDashboardPage() {
|
||||
try {
|
||||
await executeMutation.mutateAsync(id);
|
||||
toast.success(t('agent.executed'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -539,8 +540,8 @@ export function AgentDashboardPage() {
|
||||
try {
|
||||
await testRunMutation.mutateAsync(id);
|
||||
toast.success(t('agent.testRunSuccess'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -554,8 +555,8 @@ export function AgentDashboardPage() {
|
||||
});
|
||||
toast.success(t('agent.messageSent'));
|
||||
setChatMessage('');
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -474,8 +475,8 @@ function VersionHistoryModal({
|
||||
try {
|
||||
await restoreMutation.mutateAsync({ id: automationId, versionId });
|
||||
toast.success(t('automation.versionRestored'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -548,8 +549,8 @@ export function AutomationDashboardPage() {
|
||||
}
|
||||
setShowForm(false);
|
||||
setEditingAutomation(undefined);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -559,8 +560,8 @@ export function AutomationDashboardPage() {
|
||||
await deleteMutation.mutateAsync(confirmDelete.id);
|
||||
toast.success(t('automation.deleted'));
|
||||
setConfirmDelete(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -568,8 +569,8 @@ export function AutomationDashboardPage() {
|
||||
try {
|
||||
await executeMutation.mutateAsync(id);
|
||||
toast.success(t('automation.executed'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -577,8 +578,8 @@ export function AutomationDashboardPage() {
|
||||
try {
|
||||
await dryRunMutation.mutateAsync(id);
|
||||
toast.success(t('automation.dryRunSuccess'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -55,8 +56,8 @@ export function AutomationSettingsPage() {
|
||||
try {
|
||||
await updateMutation.mutateAsync(form);
|
||||
toast.success(t('automation.settingsSaved'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -92,8 +93,8 @@ export function AutomationSettingsPage() {
|
||||
setShowMiniAppForm(false);
|
||||
setMiniAppForm({ app_id: '', name: '', icon: 'AppWindow', description: '', render_schema: '{}' });
|
||||
refetchMiniapps();
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -102,8 +103,8 @@ export function AutomationSettingsPage() {
|
||||
await deleteMiniAppMutation.mutateAsync(appId);
|
||||
toast.success(t('automation.miniAppDeleted'));
|
||||
refetchMiniapps();
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
@@ -406,8 +407,8 @@ function ChatWindow({ convId, category, onBack }: ChatWindowProps) {
|
||||
const msg = await sendMessage(convId, content);
|
||||
setMessages(prev => [...prev, msg]);
|
||||
}
|
||||
} catch (e: any) {
|
||||
setError(e?.message || 'Senden fehlgeschlagen');
|
||||
} catch (e: unknown) { const errObj = asError(e);
|
||||
setError(errObj?.message || 'Senden fehlgeschlagen');
|
||||
} finally {
|
||||
setSending(false);
|
||||
}
|
||||
@@ -428,7 +429,7 @@ function ChatWindow({ convId, category, onBack }: ChatWindowProps) {
|
||||
is_sidebar: false,
|
||||
});
|
||||
setAiSessionId(r.data.id);
|
||||
} catch (e: any) {
|
||||
} catch (e: unknown) { const errObj = asError(e);
|
||||
setError('KI Session konnte nicht gestartet werden');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* Manage custom field definitions per entity (contact/company).
|
||||
*/
|
||||
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useMemo, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Card } from '@/components/ui/Card';
|
||||
@@ -223,8 +224,8 @@ export function CustomFieldsPage() {
|
||||
await updateMutation.mutateAsync({ id: editingId!, data: updateData });
|
||||
toast.success(t('customFields.updated', 'Feld aktualisiert'));
|
||||
closeFormModal();
|
||||
} catch (err: any) {
|
||||
setFormError(err.message || 'Fehler beim Aktualisieren');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setFormError(errObj.message || 'Fehler beim Aktualisieren');
|
||||
}
|
||||
} else {
|
||||
const createData: CustomFieldDefinitionCreate = {
|
||||
@@ -241,8 +242,8 @@ export function CustomFieldsPage() {
|
||||
await createMutation.mutateAsync(createData);
|
||||
toast.success(t('customFields.created', 'Feld erstellt'));
|
||||
closeFormModal();
|
||||
} catch (err: any) {
|
||||
setFormError(err.message || 'Fehler beim Erstellen');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setFormError(errObj.message || 'Fehler beim Erstellen');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -253,8 +254,8 @@ export function CustomFieldsPage() {
|
||||
await deleteMutation.mutateAsync(deleteTarget.id);
|
||||
toast.success(t('customFields.deleted', 'Feld gelöscht'));
|
||||
setDeleteTarget(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Löschen');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Löschen');
|
||||
setDeleteTarget(null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState } from 'react';
|
||||
import { useNavigate, Link } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -38,8 +39,8 @@ export function LoginPage() {
|
||||
await loginMutation.mutateAsync(data);
|
||||
addToast({ type: 'success', message: t('auth.login') + ' erfolgreich' });
|
||||
navigate('/start');
|
||||
} catch (error: any) {
|
||||
const msg = error.message || t('auth.loginFailed');
|
||||
} catch (error: unknown) { const errObj = asError(error);
|
||||
const msg = errObj.message || t('auth.loginFailed');
|
||||
setSubmitError(msg);
|
||||
addToast({ type: 'error', message: msg });
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* Account selection is integrated into the folder tree (left pane).
|
||||
*/
|
||||
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
@@ -778,8 +779,8 @@ export function MailPage() {
|
||||
await loadMails();
|
||||
toast.success(t('mail.syncSuccess'));
|
||||
}
|
||||
} catch (err: any) {
|
||||
const msg = err?.message || err?.detail || (typeof err === 'string' ? err : 'Sync failed');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
const msg = errObj?.message || errObj?.detail || (typeof errObj === 'string' ? errObj : 'Sync failed');
|
||||
toast.error(msg);
|
||||
} finally {
|
||||
setIsSyncing(false);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Mail settings page — signatures, rules, labels, PGP, vacation responder.
|
||||
*/
|
||||
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useCallback, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
@@ -77,8 +78,8 @@ export function MailSettingsPage() {
|
||||
if (accs.length > 0) {
|
||||
setSelectedAccountId((prev) => prev || accs[0].id);
|
||||
}
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || err?.detail || 'Failed to load accounts');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || errObj?.detail || 'Failed to load accounts');
|
||||
}
|
||||
setLoading(false);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -93,8 +94,8 @@ export function MailSettingsPage() {
|
||||
toast.success(t('mail.accountCreated'));
|
||||
setShowAddAccount(false);
|
||||
resetAccount({ email: '', display_name: '', username: '', imap_host: '', imap_port: 993, smtp_host: '', smtp_port: 587, password: '', is_shared: false });
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || err?.detail || 'Save failed');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || errObj?.detail || 'Save failed');
|
||||
}
|
||||
}, [toast, t, resetAccount]);
|
||||
|
||||
@@ -107,8 +108,8 @@ export function MailSettingsPage() {
|
||||
} else {
|
||||
toast.error(result.message);
|
||||
}
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || err?.detail || 'Connection test failed');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || errObj?.detail || 'Connection test failed');
|
||||
} finally {
|
||||
setTesting(null);
|
||||
}
|
||||
@@ -123,8 +124,8 @@ export function MailSettingsPage() {
|
||||
} else {
|
||||
toast.success(t('mail.syncSuccess'));
|
||||
}
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || err?.detail || 'Sync failed');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || errObj?.detail || 'Sync failed');
|
||||
} finally {
|
||||
setSyncing(null);
|
||||
}
|
||||
@@ -136,8 +137,8 @@ export function MailSettingsPage() {
|
||||
await deleteAccount(accountId);
|
||||
setAccounts((prev) => prev.filter((a) => a.id !== accountId));
|
||||
toast.success(t('mail.accountDeleted'));
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || err?.detail || 'Delete failed');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || errObj?.detail || 'Delete failed');
|
||||
}
|
||||
}, [toast, t]);
|
||||
|
||||
@@ -147,8 +148,8 @@ export function MailSettingsPage() {
|
||||
setAccounts((prev) => prev.map((a) => (a.id === accountId ? updated : a)));
|
||||
setEditingDisplayName(null);
|
||||
toast.success(t('common.saved'));
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || err?.detail || 'Save failed');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || errObj?.detail || 'Save failed');
|
||||
}
|
||||
}, [displayNameValue, toast, t]);
|
||||
|
||||
@@ -191,8 +192,8 @@ export function MailSettingsPage() {
|
||||
setAccounts((prev) => prev.map((a) => (a.id === accountId ? updated : a)));
|
||||
setFolderMappingEdit(null);
|
||||
toast.success(t('common.saved'));
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || err?.detail || 'Save failed');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || errObj?.detail || 'Save failed');
|
||||
} finally {
|
||||
setSavingMapping(false);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -126,8 +127,8 @@ export function ReportsPage() {
|
||||
});
|
||||
toast.success(t('reports.templateUpdated', 'Template updated successfully'));
|
||||
}
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || t('reports.saveFailed', 'Failed to save template'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || t('reports.saveFailed', 'Failed to save template'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -141,8 +142,8 @@ export function ReportsPage() {
|
||||
setEditorContent('');
|
||||
}
|
||||
toast.success(t('reports.templateDeleted', 'Template deleted'));
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || t('reports.deleteFailed', 'Failed to delete template'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || t('reports.deleteFailed', 'Failed to delete template'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -174,8 +175,8 @@ export function ReportsPage() {
|
||||
...prev,
|
||||
]);
|
||||
toast.success(t('reports.generated', 'Report generated successfully'));
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || t('reports.generateFailed', 'Failed to generate report'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || t('reports.generateFailed', 'Failed to generate report'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -207,8 +208,8 @@ export function ReportsPage() {
|
||||
...prev,
|
||||
]);
|
||||
toast.success(t('reports.generated', 'Report generated successfully'));
|
||||
} catch (err: any) {
|
||||
toast.error(err?.message || t('reports.generateFailed', 'Failed to generate report'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj?.message || t('reports.generateFailed', 'Failed to generate report'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@@ -47,8 +48,8 @@ export function SettingsCurrenciesPage() {
|
||||
try {
|
||||
const data = await apiGet<{ items: Currency[]; total: number }>('/currencies');
|
||||
setCurrencies(data.items);
|
||||
} catch (err: any) {
|
||||
setError(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setError(errObj.message || t('common.error'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -67,8 +68,8 @@ export function SettingsCurrenciesPage() {
|
||||
setEditing(null);
|
||||
reset({ code: '', name: '', symbol: '', is_default: false });
|
||||
await fetchCurrencies();
|
||||
} catch (err: any) {
|
||||
setError(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setError(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -77,8 +78,8 @@ export function SettingsCurrenciesPage() {
|
||||
try {
|
||||
await apiDelete(`/currencies/${id}`);
|
||||
await fetchCurrencies();
|
||||
} catch (err: any) {
|
||||
setError(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setError(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@@ -111,8 +112,8 @@ export function SettingsFirmendatenPage() {
|
||||
if (!payload.default_tax_id) payload.default_tax_id = null as any;
|
||||
await updateMutation.mutateAsync(payload);
|
||||
toast.success(t('systemSettings.saved'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('systemSettings.saveFailed'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('systemSettings.saveFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@@ -144,8 +145,8 @@ export function SettingsGroupsPage() {
|
||||
setNewGroupPermissions({});
|
||||
setNewGroupDenied([]);
|
||||
setCreateOpen(false);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -190,8 +191,8 @@ export function SettingsGroupsPage() {
|
||||
});
|
||||
toast.success(t('settings.groupUpdated', 'Gruppe aktualisiert'));
|
||||
setEditingGroup(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -201,8 +202,8 @@ export function SettingsGroupsPage() {
|
||||
await deleteGroupMutation.mutateAsync(confirmDelete.id);
|
||||
toast.success(t('settings.groupDeleted', 'Gruppe gelöscht'));
|
||||
setConfirmDelete(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -501,8 +502,8 @@ function EditGroupContent({
|
||||
await addMemberMutation.mutateAsync({ groupId, userId: memberSearchUserId });
|
||||
toast.success(t('settings.memberAdded', 'Mitglied hinzugefügt'));
|
||||
setMemberSearchUserId('');
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -511,8 +512,8 @@ function EditGroupContent({
|
||||
try {
|
||||
await removeMemberMutation.mutateAsync({ groupId, userId });
|
||||
toast.success(t('settings.memberRemoved', 'Mitglied entfernt'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useEffect, useMemo, useCallback } from 'react';
|
||||
// TODO: P2-F23 — Replace hardcoded DEFAULT_ORDER with backend config
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -162,8 +163,8 @@ export function SettingsMenuOrderPage() {
|
||||
const order = items.map((item) => item.id);
|
||||
await updateMutation.mutateAsync(order);
|
||||
toast.success(t('settings.saved', 'Gespeichert'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('settings.saveFailed', 'Speichern fehlgeschlagen'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('settings.saveFailed', 'Speichern fehlgeschlagen'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useToast } from '@/components/ui/Toast';
|
||||
@@ -42,8 +43,8 @@ export function SettingsNotificationsPage() {
|
||||
onSuccess: () => {
|
||||
toast.success(t('notifications.saved'));
|
||||
},
|
||||
onError: (err: any) => {
|
||||
toast.error(err.message || t('common.error'));
|
||||
onError: (err: unknown) => { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -79,8 +80,8 @@ function InstallPluginSection() {
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.value = '';
|
||||
}
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -93,8 +94,8 @@ function InstallPluginSection() {
|
||||
await installUrlMutation.mutateAsync(url.trim());
|
||||
toast.success(t('settings.pluginUrlInstalledSuccess'));
|
||||
setUrl('');
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -188,8 +189,8 @@ export function SettingsPluginsPage() {
|
||||
try {
|
||||
await installMutation.mutateAsync(plugin.name);
|
||||
toast.success(t('settings.pluginInstalledSuccess'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -197,8 +198,8 @@ export function SettingsPluginsPage() {
|
||||
try {
|
||||
await activateMutation.mutateAsync(plugin.name);
|
||||
toast.success(t('settings.pluginActivatedSuccess'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -206,8 +207,8 @@ export function SettingsPluginsPage() {
|
||||
try {
|
||||
await deactivateMutation.mutateAsync(plugin.name);
|
||||
toast.success(t('settings.pluginDeactivatedSuccess'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -218,8 +219,8 @@ export function SettingsPluginsPage() {
|
||||
toast.success(t('settings.pluginUninstalledSuccess'));
|
||||
setConfirmUninstall(null);
|
||||
setConfirmRemoveData(false);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
@@ -33,8 +34,8 @@ export function SettingsProfilePage() {
|
||||
});
|
||||
toast.success(t('settings.profileSaved'));
|
||||
setProfileDirty(false);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,8 +59,8 @@ export function SettingsProfilePage() {
|
||||
setNewPassword('');
|
||||
setConfirmPassword('');
|
||||
setPasswordDirty(false);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
// TODO: P2-T19 — Replace hardcoded PermissionLevelBadge/PrincipalTypeBadge with i18n
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -140,8 +141,8 @@ function FreigabenTab() {
|
||||
toast.success('Berechtigung gelöscht');
|
||||
setConfirmDelete(null);
|
||||
refetchPerms();
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Löschen');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Löschen');
|
||||
} finally {
|
||||
setDeleting(false);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@@ -143,8 +144,8 @@ export function SettingsRolesPage() {
|
||||
setNewRolePermissions({});
|
||||
setNewRoleDenied([]);
|
||||
setCreateOpen(false);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -201,8 +202,8 @@ export function SettingsRolesPage() {
|
||||
});
|
||||
toast.success(t('settings.roleUpdated'));
|
||||
setEditingRole(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -212,8 +213,8 @@ export function SettingsRolesPage() {
|
||||
await deleteRoleMutation.mutateAsync(confirmDelete.id);
|
||||
toast.success(t('settings.roleDeleted'));
|
||||
setConfirmDelete(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@@ -46,8 +47,8 @@ export function SettingsSequencesPage() {
|
||||
try {
|
||||
const data = await apiGet<{ items: Sequence[]; total: number }>('/sequences');
|
||||
setSequences(data.items);
|
||||
} catch (err: any) {
|
||||
setError(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setError(errObj.message || t('common.error'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -66,8 +67,8 @@ export function SettingsSequencesPage() {
|
||||
setEditing(null);
|
||||
reset({ name: '', prefix: '', padding: 4 });
|
||||
await fetchSequences();
|
||||
} catch (err: any) {
|
||||
setError(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setError(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -76,8 +77,8 @@ export function SettingsSequencesPage() {
|
||||
try {
|
||||
await apiDelete(`/sequences/${id}`);
|
||||
await fetchSequences();
|
||||
} catch (err: any) {
|
||||
setError(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setError(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SettingsFirmendatenPage } from './SettingsFirmendaten';
|
||||
@@ -87,8 +88,8 @@ function AdressenTab() {
|
||||
label: a.label || '',
|
||||
}))
|
||||
);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Laden der Adressen');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Laden der Adressen');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -113,8 +114,8 @@ function AdressenTab() {
|
||||
await apiDelete(`/addresses/${id}`);
|
||||
setAddresses(addresses.filter(a => a.id !== id));
|
||||
toast.success('Adresse gelöscht');
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Löschen');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Löschen');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -151,8 +152,8 @@ function AdressenTab() {
|
||||
setShowForm(false);
|
||||
setEditing(null);
|
||||
await fetchAddresses();
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Speichern');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Speichern');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -284,8 +285,8 @@ function KontenTab() {
|
||||
defaultTax: a.default_tax || '',
|
||||
}))
|
||||
);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Laden der Konten');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Laden der Konten');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -310,8 +311,8 @@ function KontenTab() {
|
||||
await apiDelete(`/bank-accounts/${id}`);
|
||||
setAccounts(accounts.filter(a => a.id !== id));
|
||||
toast.success('Konto gelöscht');
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Löschen');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Löschen');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -337,8 +338,8 @@ function KontenTab() {
|
||||
setShowForm(false);
|
||||
setEditing(null);
|
||||
await fetchAccounts();
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Speichern');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Speichern');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@@ -47,8 +48,8 @@ export function SettingsTaxesPage() {
|
||||
try {
|
||||
const data = await apiGet<{ items: TaxRate[]; total: number }>('/taxes');
|
||||
setTaxes(data.items);
|
||||
} catch (err: any) {
|
||||
setError(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setError(errObj.message || t('common.error'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -68,8 +69,8 @@ export function SettingsTaxesPage() {
|
||||
setEditing(null);
|
||||
reset({ name: '', rate: 0, is_default: false, country: '' });
|
||||
await fetchTaxes();
|
||||
} catch (err: any) {
|
||||
setError(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setError(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -78,8 +79,8 @@ export function SettingsTaxesPage() {
|
||||
try {
|
||||
await apiDelete(`/taxes/${id}`);
|
||||
await fetchTaxes();
|
||||
} catch (err: any) {
|
||||
setError(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
setError(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
// TODO: P2-F22 — Replace hardcoded LEGACY_ROLES with /roles API
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -107,8 +108,8 @@ export function SettingsUsersPage() {
|
||||
toast.success(t('settings.userInvited'));
|
||||
reset({ name: '', email: '', password: '', role_id: '' });
|
||||
setInviteOpen(false);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,8 +125,8 @@ export function SettingsUsersPage() {
|
||||
}
|
||||
await updateUserMutation.mutateAsync({ id: userId, data });
|
||||
toast.success(t('settings.assignRole') + ' — OK');
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -140,8 +141,8 @@ export function SettingsUsersPage() {
|
||||
toast.success(t('settings.userDeactivated'));
|
||||
}
|
||||
setConfirmDeactivate(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -151,8 +152,8 @@ export function SettingsUsersPage() {
|
||||
await deleteUserMutation.mutateAsync(confirmDelete.id);
|
||||
toast.success(t('settings.userDeleted'));
|
||||
setConfirmDelete(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* - Test button sends test payload, shows result
|
||||
*/
|
||||
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
@@ -377,8 +378,8 @@ export function SettingsWebhooksPage() {
|
||||
setFormModalOpen(false);
|
||||
setEditingWebhook(null);
|
||||
},
|
||||
onError: (err: any) => {
|
||||
setFormError(err?.message || t('webhooks.updateError', 'Fehler beim Aktualisieren'));
|
||||
onError: (err: unknown) => { const errObj = asError(err);
|
||||
setFormError(errObj?.message || t('webhooks.updateError', 'Fehler beim Aktualisieren'));
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -387,8 +388,8 @@ export function SettingsWebhooksPage() {
|
||||
onSuccess: () => {
|
||||
setFormModalOpen(false);
|
||||
},
|
||||
onError: (err: any) => {
|
||||
setFormError(err?.message || t('webhooks.createError', 'Fehler beim Erstellen'));
|
||||
onError: (err: unknown) => { const errObj = asError(err);
|
||||
setFormError(errObj?.message || t('webhooks.createError', 'Fehler beim Erstellen'));
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -418,8 +419,8 @@ export function SettingsWebhooksPage() {
|
||||
setTestResult(result);
|
||||
setTestResultModalOpen(true);
|
||||
},
|
||||
onError: (err: any) => {
|
||||
setTestResult({ success: false, status_code: null, error: err?.message || 'Unknown error' });
|
||||
onError: (err: unknown) => { const errObj = asError(err);
|
||||
setTestResult({ success: false, status_code: null, error: errObj?.message || 'Unknown error' });
|
||||
setTestResultModalOpen(true);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Tasks page — list with filter, create modal, detail.
|
||||
*/
|
||||
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
@@ -20,6 +21,7 @@ import {
|
||||
useUpdateTaskStatus,
|
||||
type Task,
|
||||
type TaskFilter,
|
||||
type TaskStatus,
|
||||
} from '@/api/tasks';
|
||||
|
||||
const STATUS_COLORS: Record<string, 'secondary' | 'info' | 'success'> = {
|
||||
@@ -96,8 +98,8 @@ export function TasksPage() {
|
||||
});
|
||||
toast.success(t('tasks.created'));
|
||||
setCreateModalOpen(false);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -107,8 +109,8 @@ export function TasksPage() {
|
||||
await updateMutation.mutateAsync({ id: editingTask.id, data: formData });
|
||||
toast.success(t('tasks.updated'));
|
||||
setEditingTask(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -118,17 +120,17 @@ export function TasksPage() {
|
||||
await deleteMutation.mutateAsync(task.id);
|
||||
toast.success(t('tasks.deleted'));
|
||||
setSelectedTask(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
const handleStatusChange = async (task: Task, newStatus: string) => {
|
||||
const handleStatusChange = async (task: Task, newStatus: TaskStatus) => {
|
||||
try {
|
||||
await statusMutation.mutateAsync({ id: task.id, status: newStatus });
|
||||
toast.success(t('tasks.statusUpdated'));
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || t('common.error'));
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || t('common.error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -163,7 +165,7 @@ export function TasksPage() {
|
||||
{ value: 'done', label: t('tasks.statusDone') },
|
||||
]}
|
||||
value={filter.status || ''}
|
||||
onChange={(e) => { setFilter(f => ({ ...f, status: e.target.value || undefined })); setPage(1); }}
|
||||
onChange={(e) => { setFilter(f => ({ ...f, status: (e.target.value || undefined) as TaskStatus | undefined })); setPage(1); }}
|
||||
className="w-40"
|
||||
/>
|
||||
<Select
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asError } from '@/utils/errorTypes';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -56,8 +57,8 @@ export function WorkflowsPage() {
|
||||
toast.success(
|
||||
workflow.is_active ? 'Workflow deaktiviert' : 'Workflow aktiviert'
|
||||
);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Umschalten');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Umschalten');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -67,8 +68,8 @@ export function WorkflowsPage() {
|
||||
await deleteMutation.mutateAsync(confirmDelete.id);
|
||||
toast.success('Workflow geloescht');
|
||||
setConfirmDelete(null);
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || 'Fehler beim Loeschen');
|
||||
} catch (err: unknown) { const errObj = asError(err);
|
||||
toast.error(errObj.message || 'Fehler beim Loeschen');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user