Files
SDS-CRM/public/js/pages/options.js
2026-03-23 02:09:14 +01:00

138 lines
4.9 KiB
JavaScript

import { apiGet, apiPost, apiPut, isAuthRedirectError } from '../api.js';
import { guard } from '../core/auth-guard.js';
import { esc, formatDeSyncDateTime } from '../core/utils.js';
const loadingEl = document.getElementById('page-loading');
const mainEl = document.getElementById('page-main');
const errEl = document.getElementById('page-error');
function showError(msg) {
loadingEl.hidden = true;
mainEl.hidden = true;
errEl.hidden = false;
errEl.textContent = msg;
}
function renderSyncLog(entries) {
const tbody = document.getElementById('sync-log-body');
if (!entries.length) {
tbody.innerHTML =
'<tr><td colspan="5" class="muted">Noch keine Einträge.</td></tr>';
return;
}
tbody.innerHTML = entries
.map(
(e) => `
<tr>
<td>${esc(formatDeSyncDateTime(e.finishedAt))}</td>
<td>${e.triggerType === 'automatic' ? 'Automatisch' : 'Manuell'}</td>
<td><span class="sync-status-badge ${e.status === 'success' ? 'sync-status-ok' : 'sync-status-err'}">${e.status === 'success' ? 'Erfolg' : 'Fehler'}</span></td>
<td class="num">${esc(String(e.usersSynced ?? 0))}</td>
<td>${e.errorMessage ? esc(e.errorMessage) : '—'}</td>
</tr>`,
)
.join('');
}
function applyIntegrationForm(data) {
const ldap = data.ldap || {};
document.getElementById('ldap_syncEnabled').checked = Boolean(ldap.syncEnabled);
document.getElementById('ldap_serverUrl').value = ldap.serverUrl ?? '';
document.getElementById('ldap_searchBase').value = ldap.searchBase ?? '';
document.getElementById('ldap_bindDn').value = ldap.bindDn ?? '';
document.getElementById('ldap_bindPassword').value = '';
document.getElementById('ldap_userSearchFilter').value =
ldap.userSearchFilter || ldap.userFilter || '';
document.getElementById('ldap_usernameAttribute').value =
ldap.usernameAttribute ?? '';
document.getElementById('ldap_firstNameAttribute').value =
ldap.firstNameAttribute ?? '';
document.getElementById('ldap_lastNameAttribute').value =
ldap.lastNameAttribute ?? '';
document.getElementById('ldap_syncIntervalMinutes').value = String(
ldap.syncIntervalMinutes ?? 1440,
);
const tv = data.teamviewer || {};
document.getElementById('tv_bearerToken').value =
tv.bearerToken || tv.apiToken || '';
document.getElementById('tv_notes').value = tv.notes ?? tv.apiNotes ?? '';
}
async function run() {
const data = await apiGet('/settings/integrations');
let syncStatus = { lastSyncAt: null, entries: [] };
try {
syncStatus = await apiGet('/ldap/sync-status');
} catch {
/* ältere Server */
}
applyIntegrationForm(data);
document.getElementById('ldap-last-sync').textContent =
`Letzte Synchronisation: ${formatDeSyncDateTime(syncStatus.lastSyncAt)}`;
renderSyncLog(Array.isArray(syncStatus.entries) ? syncStatus.entries : []);
const ldapBody = document.getElementById('ldap-section-body');
const ldapToggle = document.getElementById('ldap-toggle');
const chev = ldapToggle.querySelector('.ldap-chevron');
function setLdapOpen(open) {
ldapBody.hidden = !open;
ldapToggle.setAttribute('aria-expanded', String(open));
chev.textContent = open ? '▲' : '▼';
}
ldapToggle.onclick = () => setLdapOpen(ldapBody.hidden);
document.getElementById('btn-ldap-sync-now').onclick = async () => {
const btn = document.getElementById('btn-ldap-sync-now');
btn.disabled = true;
try {
await apiPost('/ldap/sync', {});
location.reload();
} catch (err) {
alert(err.message || String(err));
} finally {
btn.disabled = false;
}
};
document.getElementById('form-opt').onsubmit = async (e) => {
e.preventDefault();
const fd = new FormData(e.target);
await apiPut('/settings/integrations', {
ldap: {
serverUrl: fd.get('ldap_serverUrl'),
bindDn: fd.get('ldap_bindDn'),
bindPassword: fd.get('ldap_bindPassword'),
searchBase: fd.get('ldap_searchBase'),
userSearchFilter: fd.get('ldap_userSearchFilter'),
usernameAttribute: fd.get('ldap_usernameAttribute'),
firstNameAttribute: fd.get('ldap_firstNameAttribute'),
lastNameAttribute: fd.get('ldap_lastNameAttribute'),
syncIntervalMinutes: fd.get('ldap_syncIntervalMinutes'),
syncEnabled: fd.get('ldap_syncEnabled') === 'on',
},
teamviewer: {
bearerToken: fd.get('tv_bearerToken'),
notes: fd.get('tv_notes'),
},
});
location.reload();
};
}
async function init() {
const st = await guard({ needsAdmin: true, activeNav: 'options' });
if (!st) return;
loadingEl.hidden = true;
mainEl.hidden = false;
try {
await run();
} catch (e) {
if (isAuthRedirectError(e)) return;
showError(e.message || 'Fehler');
}
}
init();