}
}
+ // Track selected escalations
+ const selectedEscalations = new Set();
+
async function loadEscalations() {
const container = document.getElementById('escalation-list');
try {
- container.innerHTML = `
-
-
🚨
-
No escalations found
-
Click "+ Create Escalation" to create one
+ // Mock escalation data - in production, fetch from API
+ const escalations = [
+ {
+ id: 'esc_001',
+ priority: 'critical',
+ status: 'pending_review',
+ title: 'High-Risk Decision Approval Required',
+ description: 'Decision dec_user_123 requires senior approval due to high security risk score (87)',
+ decision_id: 'dec_user_123',
+ created_at: '2026-01-10T10:30:00Z',
+ sla_violation: true
+ },
+ {
+ id: 'esc_002',
+ priority: 'high',
+ status: 'pending_review',
+ title: 'Privacy Compliance Review Needed',
+ description: 'Multiple privacy risk dimensions exceed threshold for decision dec_data_456',
+ decision_id: 'dec_data_456',
+ created_at: '2026-01-10T11:00:00Z',
+ sla_violation: false
+ },
+ {
+ id: 'esc_003',
+ priority: 'high',
+ status: 'pending_review',
+ title: 'Financial Impact Assessment',
+ description: 'Decision dec_contract_789 has high financial risk requiring CFO review',
+ decision_id: 'dec_contract_789',
+ created_at: '2026-01-10T11:15:00Z',
+ sla_violation: false
+ }
+ ];
+
+ if (escalations.length === 0) {
+ container.innerHTML = `
+
+
🚨
+
No escalations found
+
Click "+ Create Escalation" to create one
+
+ `;
+ return;
+ }
+
+ container.innerHTML = escalations.map(esc => `
+
+
+
+ ${esc.description}
+
+
- `;
+ `).join('');
+
+ // Update stats
+ document.getElementById('pending-escalations').textContent = escalations.length;
+ const slaViolations = escalations.filter(e => e.sla_violation).length;
+ document.getElementById('escalation-trend').innerHTML = slaViolations > 0
+ ? `
⚠️ ${slaViolations} SLA violations`
+ : `
✓ All within SLA`;
+
} catch (error) {
console.error('Error loading escalations:', error);
container.innerHTML = `
Error loading escalations
`;
@@ -1100,6 +1304,88 @@
Assess Risk for Decision
}
});
});
+
+ // Batch Selection Functions
+ function toggleEscalationSelection(escalationId) {
+ if (selectedEscalations.has(escalationId)) {
+ selectedEscalations.delete(escalationId);
+ } else {
+ selectedEscalations.add(escalationId);
+ }
+ updateBatchActionBar();
+ updateEscalationCardStyles();
+ }
+
+ function updateBatchActionBar() {
+ const batchBar = document.getElementById('batch-action-bar');
+ const batchCount = document.getElementById('batch-count');
+ const count = selectedEscalations.size;
+
+ batchCount.textContent = count;
+
+ if (count > 0) {
+ batchBar.classList.add('show');
+ } else {
+ batchBar.classList.remove('show');
+ }
+ }
+
+ function updateEscalationCardStyles() {
+ document.querySelectorAll('.escalation-card').forEach(card => {
+ const id = card.getAttribute('data-escalation-id');
+ if (selectedEscalations.has(id)) {
+ card.classList.add('selected');
+ } else {
+ card.classList.remove('selected');
+ }
+ });
+ }
+
+ async function batchApproveEscalations() {
+ if (selectedEscalations.size === 0) return;
+
+ const count = selectedEscalations.size;
+ const ids = Array.from(selectedEscalations);
+
+ // In production, send to API:
+ // await fetch(`${API_BASE}/api/governance/escalations/batch-approve`, {
+ // method: 'POST',
+ // headers: { 'Content-Type': 'application/json' },
+ // body: JSON.stringify({ escalation_ids: ids })
+ // });
+
+ showToast(`${count} escalation${count > 1 ? 's' : ''} approved successfully`, 'success');
+ clearBatchSelection();
+ await loadEscalations();
+ }
+
+ async function batchReviewEscalations() {
+ if (selectedEscalations.size === 0) return;
+
+ const count = selectedEscalations.size;
+ const ids = Array.from(selectedEscalations);
+
+ // In production, send to API:
+ // await fetch(`${API_BASE}/api/governance/escalations/batch-review`, {
+ // method: 'POST',
+ // headers: { 'Content-Type': 'application/json' },
+ // body: JSON.stringify({ escalation_ids: ids })
+ // });
+
+ showToast(`${count} escalation${count > 1 ? 's' : ''} marked for review`, 'success');
+ clearBatchSelection();
+ await loadEscalations();
+ }
+
+ function clearBatchSelection() {
+ selectedEscalations.clear();
+ updateBatchActionBar();
+ // Uncheck all checkboxes
+ document.querySelectorAll('.escalation-card input[type="checkbox"]').forEach(cb => {
+ cb.checked = false;
+ });
+ updateEscalationCardStyles();
+ }