import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { NumberInput, Switch, Button, Stack, Paper, Text, Loader, Group, TextInput, PasswordInput, Select, Badge } from '@mantine/core'; import { alert } from '@app/components/toast'; import RestartConfirmationModal from '@app/components/shared/config/RestartConfirmationModal'; import { useRestartServer } from '@app/components/shared/config/useRestartServer'; import { useAdminSettings } from '@app/hooks/useAdminSettings'; import PendingBadge from '@app/components/shared/config/PendingBadge'; import { useLoginRequired } from '@app/hooks/useLoginRequired'; import LoginRequiredBanner from '@app/components/shared/config/LoginRequiredBanner'; import apiClient from '@app/services/apiClient'; interface DatabaseSettingsData { enableCustomDatabase?: boolean; customDatabaseUrl?: string; username?: string; password?: string; type?: string; hostName?: string; port?: number; name?: string; } export default function AdminDatabaseSection() { const { t } = useTranslation(); const { loginEnabled, validateLoginEnabled, getDisabledStyles } = useLoginRequired(); const { restartModalOpened, showRestartModal, closeRestartModal, restartServer } = useRestartServer(); const { settings, setSettings, loading, saving, fetchSettings, saveSettings, isFieldPending, } = useAdminSettings({ sectionName: 'database', fetchTransformer: async () => { const response = await apiClient.get('/api/v1/admin/settings/section/system'); const systemData = response.data || {}; // Extract datasource from system response and handle pending const datasource = systemData.datasource || { enableCustomDatabase: false, customDatabaseUrl: '', username: '', password: '', type: 'postgresql', hostName: 'localhost', port: 5432, name: 'postgres' }; // Map pending changes from system._pending.datasource to root level const result: any = { ...datasource }; if (systemData._pending?.datasource) { result._pending = systemData._pending.datasource; } return result; }, saveTransformer: (settings) => { // Convert flat settings to dot-notation for delta endpoint const deltaSettings: Record = { 'system.datasource.enableCustomDatabase': settings.enableCustomDatabase, 'system.datasource.customDatabaseUrl': settings.customDatabaseUrl, 'system.datasource.username': settings.username, 'system.datasource.password': settings.password, 'system.datasource.type': settings.type, 'system.datasource.hostName': settings.hostName, 'system.datasource.port': settings.port, 'system.datasource.name': settings.name }; return { sectionData: {}, deltaSettings }; } }); useEffect(() => { if (loginEnabled) { fetchSettings(); } }, [loginEnabled, fetchSettings]); const handleSave = async () => { if (!validateLoginEnabled()) { return; } try { await saveSettings(); showRestartModal(); } catch (_error) { alert({ alertType: 'error', title: t('admin.error', 'Error'), body: t('admin.settings.saveError', 'Failed to save settings'), }); } }; // Override loading state when login is disabled const actualLoading = loginEnabled ? loading : false; if (actualLoading) { return ( ); } return (
{t('admin.settings.database.title', 'Database')} {t('admin.settings.database.description', 'Configure custom database connection settings for enterprise deployments.')}
ENTERPRISE
{/* Database Configuration */} {t('admin.settings.database.configuration', 'Database Configuration')}
{t('admin.settings.database.enableCustom.label', 'Enable Custom Database')} {t('admin.settings.database.enableCustom.description', 'Use your own custom database configuration instead of the default embedded database')}
{ if (!loginEnabled) return; setSettings({ ...settings, enableCustomDatabase: e.target.checked }); }} disabled={!loginEnabled} styles={getDisabledStyles()} />
{settings?.enableCustomDatabase && ( <>
{t('admin.settings.database.customUrl.label', 'Custom Database URL')} } description={t('admin.settings.database.customUrl.description', 'Full JDBC connection string (e.g., jdbc:postgresql://localhost:5432/postgres). If provided, individual connection settings below are not used.')} value={settings?.customDatabaseUrl || ''} onChange={(e) => setSettings({ ...settings, customDatabaseUrl: e.target.value })} placeholder="jdbc:postgresql://localhost:5432/postgres" disabled={!loginEnabled} />