kpi-dashboard / templates /kpi_sync_test.html
Admin
Initial HF deploy
04477e7
Raw
History Blame
4.01 kB
{% extends "base.html" %}
{% block title %}Тест синхронизации KPI{% endblock %}
{% block page_title %}Тест синхронизации KPI{% endblock %}
{% block content %}
<style>
.sync-card { background:rgba(6,11,40,0.6); backdrop-filter:blur(20px); border:1px solid rgba(255,255,255,0.05); border-radius:20px; padding:16px; }
.sync-card .rebus-name { font-size:11px; color:#A0A5B5; margin-bottom:8px; }
.sync-card .sync-log { font-size:10px; color:#A0A5B5; margin-top:8px; max-height:120px; overflow-y:auto; }
.sync-log-line.ok { color:#01B574; }
.sync-log-line.err { color:#ef4444; }
.sync-log-line.info { color:#A0A5B5; }
</style>
<div class="sync-card" style="margin-bottom:16px;">
<div style="margin-bottom:12px;">
<label style="font-size:12px;color:#A0A5B5;display:block;margin-bottom:4px;">Rebus login:</label>
<input type="text" id="globalUsername" class="form-control form-control-sm" style="background:rgba(6,11,40,0.4);border-color:rgba(255,255,255,0.1);color:#fff;border-radius:12px;" placeholder="Оставьте пустым для использования сохранённой сессии">
</div>
<div style="margin-bottom:12px;">
<label style="font-size:12px;color:#A0A5B5;display:block;margin-bottom:4px;">Rebus password:</label>
<input type="password" id="globalPassword" class="form-control form-control-sm" style="background:rgba(6,11,40,0.4);border-color:rgba(255,255,255,0.1);color:#fff;border-radius:12px;" placeholder="Оставьте пустым для использования сохранённой сессии">
</div>
<div style="margin-bottom:12px;">
<label style="font-size:12px;color:#A0A5B5;display:block;margin-bottom:4px;">Month:</label>
<input type="month" id="globalMonth" class="form-control form-control-sm" value="{{ month }}" style="width:auto;background:rgba(6,11,40,0.4);border-color:rgba(255,255,255,0.1);color:#fff;border-radius:12px;">
</div>
<button class="btn-apple" onclick="syncAll()" style="border-radius:12px;">Sync All</button>
<div id="globalLog" class="sync-log" style="margin-top:12px;"></div>
</div>
<h3 style="font-size:14px;font-weight:600;margin-bottom:12px;color:#fff;">Сотрудники</h3>
<div class="row g-2">
{% for emp in employees %}
{% set m = mappings.get(emp.id) %}
<div class="col-md-4 col-sm-6">
<div class="sync-card">
<div style="font-weight:600;font-size:13px;color:#fff;">{{ emp.full_name }}</div>
<div class="rebus-name">{{ m if m else '—' }}</div>
<button class="btn btn-sm btn-apple" onclick="syncOne({{ emp.id }})" style="border-radius:8px;font-size:10px;">Sync</button>
<div id="log-{{ emp.id }}" class="sync-log"></div>
</div>
</div>
{% endfor %}
</div>
<script>
async function syncAll() {
const log = document.getElementById('globalLog');
log.innerHTML = '<div class="sync-log-line info">Starting sync all...</div>';
const username = document.getElementById('globalUsername').value;
const password = document.getElementById('globalPassword').value;
const month = document.getElementById('globalMonth').value;
const resp = await fetch('/api/platform/sync?month=' + (month || '') + '&username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(password));
const result = await resp.json();
log.innerHTML = (result.log || []).map(l => '<div class="sync-log-line ' + (l.includes('ERROR') ? 'err' : l.includes('OK') || l.includes('Saved') ? 'ok' : 'info') + '">' + l + '</div>').join('');
}
async function syncOne(uid) {
const log = document.getElementById('log-' + uid);
log.innerHTML = '<div class="sync-log-line info">Starting sync...</div>';
const resp = await fetch('/api/platform/sync-employee/' + uid);
const result = await resp.json();
log.innerHTML = (result.log || []).map(l => '<div class="sync-log-line ' + (l.includes('ERROR') ? 'err' : l.includes('OK') || l.includes('Saved') ? 'ok' : 'info') + '">' + l + '</div>').join('');
}
</script>
{% endblock %}