/
pv_hum
/
schemaforge
Обзор
Документация
Войти
/
pv_hum
/
schemaforge
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
frontend/src/components/DbConnectionModal.tsx
134 строки
5 KB
pv_hum
Initial commit
21 май 2026, 22:25
21 май 2026, 22:25
0de9fa8
Код
Авторство
О чём код?
import { Loader2, Plug, Search, X } from 'lucide-react'; import { useState } from 'react'; import { api } from '../lib/api'; import { useStudioStore } from '../store/useStudioStore'; export default function DbConnectionModal() { const store = useStudioStore(); const [loading, setLoading] = useState<'test' | 'introspect' | null>(null); const [message, setMessage] = useState(''); if (!store.dbModalOpen) return null; const close = () => store.setDbModalOpen(false); const test = async () => { setLoading('test'); setMessage(''); try { const res = await api.dbTestConnection(store.dbParams); store.setDbStatus({ connected: true, lastError: '' }); setMessage(res.message); } catch (e) { store.setDbStatus({ connected: false, lastError: (e as Error).message }); setMessage(`Ошибка: ${(e as Error).message}`); } finally { setLoading(null); } }; const introspect = async () => { setLoading('introspect'); setMessage(''); try { const res = await api.dbIntrospect(store.dbParams); const status = await api.dbStatus(); store.setDbStatus(status); setMessage(`${res.message} Таблиц: ${res.tableCount}. ${res.summary}`); } catch (e) { store.setDbStatus({ introspected: false, lastError: (e as Error).message }); setMessage(`Ошибка: ${(e as Error).message}`); } finally { setLoading(null); } }; const disconnect = async () => { await api.dbDisconnect(); store.setDbStatus({ connected: false, introspected: false, hasMetadataContext: false, sourceType: '', databaseName: '', lastError: '', }); store.setUseDatabaseContext(false); setMessage('Подключение сброшено.'); }; return ( <div className="modal-overlay" role="dialog" aria-modal="true"> <div className="modal-card"> <div className="modal-header"> <h2>Подключение к БД</h2> <button className="ghost-btn icon-only" onClick={close} aria-label="Закрыть"> <X size={16} /> </button> </div> <p className="modal-sub">Только метаданные схемы. Данные таблиц не читаются и не передаются в LLM.</p> <div className="modal-grid"> <label> Тип БД <select value={store.dbParams.sourceType} onChange={(e) => store.setDbParams({ sourceType: e.target.value as 'postgresql' | 'mysql' })} > <option value="postgresql">PostgreSQL</option> <option value="mysql">MySQL</option> </select> </label> <label> Хост <input value={store.dbParams.host} onChange={(e) => store.setDbParams({ host: e.target.value })} /> </label> <label> Порт <input type="number" value={store.dbParams.port} onChange={(e) => store.setDbParams({ port: Number(e.target.value) })} /> </label> <label> База данных <input value={store.dbParams.database} onChange={(e) => store.setDbParams({ database: e.target.value })} /> </label> <label> Пользователь <input value={store.dbParams.username} onChange={(e) => store.setDbParams({ username: e.target.value })} /> </label> <label> Пароль <input type="password" value={store.dbParams.password} onChange={(e) => store.setDbParams({ password: e.target.value })} autoComplete="off" /> </label> {store.dbParams.sourceType === 'postgresql' ? ( <label className="span-2"> Схема (PostgreSQL) <input value={store.dbParams.schema ?? 'public'} onChange={(e) => store.setDbParams({ schema: e.target.value })} /> </label> ) : null} </div> <div className="modal-actions"> <button className="secondary-btn" disabled={!!loading} onClick={test}> {loading === 'test' ? <Loader2 size={14} className="spin" /> : <Plug size={14} />} Проверить подключение </button> <button className="primary-btn" disabled={!!loading} onClick={introspect}> {loading === 'introspect' ? <Loader2 size={14} className="spin" /> : <Search size={14} />} Извлечь метаданные </button> <button className="ghost-btn" onClick={disconnect}> Отключить </button> </div> {message ? <p className="modal-message">{message}</p> : null} </div> </div> ); }