This commit is contained in:
parent
c81fd6db24
commit
79ea884dd5
2 changed files with 54 additions and 0 deletions
|
|
@ -36,6 +36,7 @@
|
||||||
<button class="settings-tab-btn" data-tab="automation" onclick="openSettingsTab('automation')">Automation</button>
|
<button class="settings-tab-btn" data-tab="automation" onclick="openSettingsTab('automation')">Automation</button>
|
||||||
<button class="settings-tab-btn" data-tab="statuses" onclick="openSettingsTab('statuses')">Internal Statuses</button>
|
<button class="settings-tab-btn" data-tab="statuses" onclick="openSettingsTab('statuses')">Internal Statuses</button>
|
||||||
<button class="settings-tab-btn" data-tab="users" onclick="openSettingsTab('users')">Users</button>
|
<button class="settings-tab-btn" data-tab="users" onclick="openSettingsTab('users')">Users</button>
|
||||||
|
<button class="settings-tab-btn" data-tab="intra-clients" onclick="openSettingsTab('intra-clients')">Клиенты IntraDesk</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-tab-pane" data-tab="api">
|
<div class="settings-tab-pane" data-tab="api">
|
||||||
|
|
@ -135,6 +136,14 @@
|
||||||
<thead><tr><th>Username</th><th>Created</th><th>New Password</th><th></th></tr></thead>
|
<thead><tr><th>Username</th><th>Created</th><th>New Password</th><th></th></tr></thead>
|
||||||
<tbody id="users-tbody"></tbody>
|
<tbody id="users-tbody"></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div class="settings-tab-pane" data-tab="intra-clients" style="display:none;">
|
||||||
|
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;">
|
||||||
|
<div class="settings-section-title" style="margin-bottom:0;">Пользователи клиентов IntraDesk</div>
|
||||||
|
<button class="btn btn-default" id="sync-clients-btn" onclick="syncIntraClients()">↻ Синхронизировать</button>
|
||||||
|
</div>
|
||||||
|
<div id="sync-clients-status" style="font-size:12px;color:var(--text3);margin-bottom:10px;min-height:16px;"></div>
|
||||||
|
<div id="intra-clients-list" style="max-height:420px;overflow-y:auto;display:flex;flex-direction:column;gap:6px;"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,50 @@ async function loadCommentCounts() { const d = await apiGet('/api/comments/count
|
||||||
async function loadClientDict() { const d = await apiGet('/api/clients'); if (Array.isArray(d)) window._allClients = d; }
|
async function loadClientDict() { const d = await apiGet('/api/clients'); if (Array.isArray(d)) window._allClients = d; }
|
||||||
async function loadClientUsers() { const d = await apiGet('/api/client-users'); if (d && typeof d === 'object') window._clientUsers = d; }
|
async function loadClientUsers() { const d = await apiGet('/api/client-users'); if (d && typeof d === 'object') window._clientUsers = d; }
|
||||||
|
|
||||||
|
async function syncIntraClients() {
|
||||||
|
const btn = document.getElementById('sync-clients-btn');
|
||||||
|
const statusEl = document.getElementById('sync-clients-status');
|
||||||
|
if (btn) { btn.disabled = true; btn.textContent = '⏳ Синхронизация...'; }
|
||||||
|
if (statusEl) statusEl.textContent = '';
|
||||||
|
try {
|
||||||
|
const r = await apiPost('/api/admin/sync-client-users', {});
|
||||||
|
if (r?.ok) {
|
||||||
|
if (statusEl) statusEl.textContent = `✓ Синхронизировано. Записей в базе: ${r.count}`;
|
||||||
|
await loadClientUsers();
|
||||||
|
renderIntraClientsList();
|
||||||
|
} else {
|
||||||
|
if (statusEl) statusEl.textContent = `❌ ${r?.error || 'Ошибка'}`;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (statusEl) statusEl.textContent = `❌ ${e.message}`;
|
||||||
|
} finally {
|
||||||
|
if (btn) { btn.disabled = false; btn.textContent = '↻ Синхронизировать'; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderIntraClientsList() {
|
||||||
|
const container = document.getElementById('intra-clients-list');
|
||||||
|
if (!container) return;
|
||||||
|
const clientUsers = window._clientUsers || {};
|
||||||
|
const allClients = window._allClients || [];
|
||||||
|
if (!allClients.length) {
|
||||||
|
container.innerHTML = '<div style="color:var(--text3);font-size:12px;">Нет данных. Нажмите «Синхронизировать».</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const sorted = [...allClients].sort((a, b) => a.name.localeCompare(b.name, 'ru'));
|
||||||
|
container.innerHTML = sorted.map((c) => {
|
||||||
|
const users = clientUsers[String(c.client_id)] || [];
|
||||||
|
const usersHtml = users.length
|
||||||
|
? users.map((u) => `<div style="font-size:11px;color:var(--text2);padding:2px 0 2px 10px;border-left:2px solid var(--border2);">${escHtml(u)}</div>`).join('')
|
||||||
|
: '<div style="font-size:11px;color:var(--text3);padding:2px 0 2px 10px;font-style:italic;">нет пользователей</div>';
|
||||||
|
return `<div style="border:1px solid var(--border);border-radius:6px;padding:8px 10px;">
|
||||||
|
<div style="font-size:12px;font-weight:600;color:var(--text);margin-bottom:4px;">${escHtml(c.name)} <span style="font-weight:400;color:var(--text3);font-size:11px;">(id: ${c.client_id}, ${users.length} польз.)</span></div>
|
||||||
|
${usersHtml}
|
||||||
|
</div>`;
|
||||||
|
}).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async function loadTasksFromServer(silent = false) {
|
async function loadTasksFromServer(silent = false) {
|
||||||
if (!silent && !allData.length) showLoading();
|
if (!silent && !allData.length) showLoading();
|
||||||
const data = await apiGet('/api/tasks');
|
const data = await apiGet('/api/tasks');
|
||||||
|
|
@ -366,6 +410,7 @@ function openSettingsTab(tabName) {
|
||||||
document.querySelectorAll('.settings-tab-pane').forEach((pane) => {
|
document.querySelectorAll('.settings-tab-pane').forEach((pane) => {
|
||||||
pane.style.display = pane.dataset.tab === tabName ? 'block' : 'none';
|
pane.style.display = pane.dataset.tab === tabName ? 'block' : 'none';
|
||||||
});
|
});
|
||||||
|
if (tabName === 'intra-clients') renderIntraClientsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadInternalStatusesAdmin() {
|
async function loadInternalStatusesAdmin() {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue