158 lines
6.7 KiB
JavaScript
158 lines
6.7 KiB
JavaScript
import { api } from '../../../js/api.js';
|
||
import { escapeHtml, showAlert, hideAlert, renderStatusMessage, renderTableMessage } from '../../../js/utils.js';
|
||
|
||
export async function initDatabase() {
|
||
const tenantsTbody = document.getElementById('tenants-tbody');
|
||
const addTenantForm = document.getElementById('add-tenant-form');
|
||
const statusInfo = document.getElementById('db-status-info');
|
||
const btnTest = document.getElementById('btn-test-connection');
|
||
|
||
// === Загрузка статуса текущего подключения ===
|
||
async function loadStatus() {
|
||
try {
|
||
const data = await api.get('/api/database/status');
|
||
const statusBadge = data.connected
|
||
? '<span class="badge badge-available">Доступно</span>'
|
||
: '<span class="badge badge-unavailable">Недоступно</span>';
|
||
|
||
statusInfo.innerHTML = `
|
||
<div style="display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;">
|
||
<div>
|
||
<span style="color: var(--text-secondary); font-size: 0.85rem;">Тенант:</span>
|
||
<strong>${escapeHtml(data.tenant || '—')}</strong>
|
||
</div>
|
||
<div>
|
||
<span style="color: var(--text-secondary); font-size: 0.85rem;">Название:</span>
|
||
<strong>${escapeHtml(data.name || '—')}</strong>
|
||
</div>
|
||
<div>
|
||
<span style="color: var(--text-secondary); font-size: 0.85rem;">Статус:</span>
|
||
${statusBadge}
|
||
</div>
|
||
${data.url ? `<div>
|
||
<span style="color: var(--text-secondary); font-size: 0.85rem;">URL:</span>
|
||
<code style="font-size: 0.85rem;">${escapeHtml(data.url)}</code>
|
||
</div>` : ''}
|
||
</div>
|
||
`;
|
||
} catch (e) {
|
||
renderStatusMessage(statusInfo, 'Не удалось загрузить статус подключения');
|
||
}
|
||
}
|
||
|
||
// === Загрузка списка тенантов ===
|
||
async function loadTenants() {
|
||
try {
|
||
const tenants = await api.get('/api/database/tenants');
|
||
renderTenantsTable(tenants);
|
||
} catch (e) {
|
||
renderTableMessage(tenantsTbody, 6, 'Не удалось загрузить список тенантов');
|
||
}
|
||
}
|
||
|
||
function renderTenantsTable(tenants) {
|
||
if (!tenants || !tenants.length) {
|
||
tenantsTbody.innerHTML = '<tr><td colspan="6" class="loading-row">Нет подключённых тенантов</td></tr>';
|
||
return;
|
||
}
|
||
|
||
tenantsTbody.innerHTML = tenants.map(t => {
|
||
const statusBadge = t.connected
|
||
? '<span class="badge badge-available">Доступно</span>'
|
||
: '<span class="badge badge-unavailable">Недоступно</span>';
|
||
|
||
return `
|
||
<tr>
|
||
<td>${escapeHtml(t.name || '—')}</td>
|
||
<td><code>${escapeHtml(t.domain)}</code></td>
|
||
<td><code style="font-size: 0.82rem;">${escapeHtml(t.url)}</code></td>
|
||
<td>${escapeHtml(t.username || '—')}</td>
|
||
<td>${statusBadge}</td>
|
||
<td><button class="btn btn-sm btn-danger btn-delete-tenant" data-domain="${escapeHtml(t.domain)}">Удалить</button></td>
|
||
</tr>`;
|
||
}).join('');
|
||
}
|
||
|
||
// === Тест подключения ===
|
||
btnTest.addEventListener('click', async () => {
|
||
hideAlert('add-tenant-alert');
|
||
const url = document.getElementById('tenant-url').value.trim();
|
||
const username = document.getElementById('tenant-username').value.trim();
|
||
const password = document.getElementById('tenant-password').value;
|
||
|
||
if (!url) {
|
||
showAlert('add-tenant-alert', 'Введите JDBC URL', 'error');
|
||
return;
|
||
}
|
||
|
||
btnTest.textContent = '...';
|
||
btnTest.disabled = true;
|
||
|
||
try {
|
||
const result = await api.post('/api/database/test', { url, username, password });
|
||
if (result.success) {
|
||
showAlert('add-tenant-alert', '✓ Подключение успешно!', 'success');
|
||
} else {
|
||
showAlert('add-tenant-alert', `✗ ${result.message}`, 'error');
|
||
}
|
||
} catch (e) {
|
||
showAlert('add-tenant-alert', 'Не удалось проверить подключение', 'error');
|
||
} finally {
|
||
btnTest.textContent = 'Тест';
|
||
btnTest.disabled = false;
|
||
}
|
||
});
|
||
|
||
// === Добавление тенанта ===
|
||
addTenantForm.addEventListener('submit', async (e) => {
|
||
e.preventDefault();
|
||
hideAlert('add-tenant-alert');
|
||
|
||
const name = document.getElementById('tenant-name').value.trim();
|
||
const domain = document.getElementById('tenant-domain').value.trim().toLowerCase();
|
||
const url = document.getElementById('tenant-url').value.trim();
|
||
const username = document.getElementById('tenant-username').value.trim();
|
||
const password = document.getElementById('tenant-password').value;
|
||
|
||
if (!name || !domain || !url) {
|
||
showAlert('add-tenant-alert', 'Заполните все обязательные поля', 'error');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const result = await api.post('/api/database/tenants', { name, domain, url, username, password });
|
||
if (result.success) {
|
||
showAlert('add-tenant-alert', `Тенант «${domain}» добавлен`, 'success');
|
||
addTenantForm.reset();
|
||
loadTenants();
|
||
loadStatus();
|
||
} else {
|
||
showAlert('add-tenant-alert', result.message, 'error');
|
||
}
|
||
} catch (e) {
|
||
showAlert('add-tenant-alert', 'Не удалось добавить тенант', 'error');
|
||
}
|
||
});
|
||
|
||
// === Удаление тенанта ===
|
||
tenantsTbody.addEventListener('click', async (e) => {
|
||
const btn = e.target.closest('.btn-delete-tenant');
|
||
if (!btn) return;
|
||
|
||
const domain = btn.dataset.domain;
|
||
if (!confirm(`Удалить тенант "${domain}"? Пул соединений будет закрыт.`)) return;
|
||
|
||
try {
|
||
await api.delete(`/api/database/tenants/${domain}`);
|
||
loadTenants();
|
||
loadStatus();
|
||
} catch (e) {
|
||
alert('Не удалось удалить тенант');
|
||
}
|
||
});
|
||
|
||
// === Init ===
|
||
loadStatus();
|
||
loadTenants();
|
||
}
|