Operations expand inline under service row

This commit is contained in:
2026-07-23 11:51:52 +04:00
parent 6b098509e9
commit 2723f922d4
+21 -17
View File
@@ -51,54 +51,58 @@
<span class="ops-count" id="ops-{{ s.svcId }}">?</span> <span class="ops-count" id="ops-{{ s.svcId }}">?</span>
</td> </td>
</tr> </tr>
<tr class="ops-detail" id="detail-{{ s.svcId }}" style="display:none;">
<td colspan="3" style="padding:4px 10px;background:var(--brand-grey-light);">
<span style="color:var(--muted);font-size:12px;">Загрузка...</span>
</td>
</tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<div class="card" id="ops-panel" style="max-width: 780px; margin: 16px auto; display: none;">
<div class="card-header" id="ops-title">Операции</div>
<div class="card-body" id="ops-body" style="padding: 8px 14px;"></div>
</div>
<script> <script>
const opsCache = {}; const opsCache = {};
document.querySelectorAll('.svc-row').forEach(row => { document.querySelectorAll('.svc-row').forEach(row => {
row.addEventListener('click', async () => { row.addEventListener('click', async () => {
const svcId = row.dataset.svcId; const svcId = row.dataset.svcId;
const detail = document.getElementById('detail-' + svcId);
if (detail.style.display === 'table-row') {
detail.style.display = 'none';
row.style.background = '';
return;
}
document.querySelectorAll('.ops-detail').forEach(d => d.style.display = 'none');
document.querySelectorAll('.svc-row').forEach(r => r.style.background = ''); document.querySelectorAll('.svc-row').forEach(r => r.style.background = '');
row.style.background = 'var(--brand-grey-light)'; row.style.background = 'var(--brand-grey-light)';
detail.style.display = 'table-row';
if (opsCache[svcId]) { if (opsCache[svcId]) {
showOps(svcId, opsCache[svcId]); fillDetail(svcId, opsCache[svcId]);
return; return;
} }
try { try {
const r = await fetch('/api/operations/' + svcId); const r = await fetch('/api/operations/' + svcId);
const d = await r.json(); const d = await r.json();
opsCache[svcId] = d; opsCache[svcId] = d;
showOps(svcId, d); fillDetail(svcId, d);
} catch(e) { } catch(e) {
document.getElementById('ops-body').innerHTML = '<p style=\"color:var(--destructive);\">Ошибка</p>'; detail.cells[0].innerHTML = '<span style=\"color:var(--destructive);font-size:12px;\">Ошибка загрузки</span>';
} }
}); });
}); });
function showOps(svcId, data) { function fillDetail(svcId, data) {
const panel = document.getElementById('ops-panel'); const detail = document.getElementById('detail-' + svcId);
const title = document.getElementById('ops-title');
const body = document.getElementById('ops-body');
panel.style.display = 'block';
title.textContent = 'Операции: ' + data.svc + ' (svcId=' + svcId + ')';
if (data.error) { if (data.error) {
body.innerHTML = '<p style=\"color:var(--destructive);\">' + data.error + '</p>'; detail.cells[0].innerHTML = '<span style=\"color:var(--destructive);font-size:12px;\">' + data.error + '</span>';
return; return;
} }
const ops = data.operations || []; const ops = data.operations || [];
document.getElementById('ops-' + svcId).textContent = ops.length; document.getElementById('ops-' + svcId).textContent = ops.length;
body.innerHTML = ops.map(o => detail.cells[0].innerHTML = ops.map(o =>
'<span class=\"badge\" style=\"margin:2px;\">' + o.operation + '</span>' '<span class=\"badge\" style=\"margin:2px;\">' + o.operation + '</span>'
).join('') || '<p style=\"color:var(--muted);\">Нет операций</p>'; ).join('') || '<span style=\"color:var(--muted);font-size:12px;\">Нет операций</span>';
} }
</script> </script>
{% endif %} {% endif %}