- Implemented alert notes JavaScript module for loading and displaying alerts for customers and contacts. - Created HTML template for alert boxes to display alerts inline on detail pages. - Developed modal for creating and editing alert notes with form validation and user restrictions. - Added modal for displaying alerts with acknowledgment functionality. - Enhanced user experience with toast notifications for successful operations.
200 lines
5.7 KiB
HTML
200 lines
5.7 KiB
HTML
<!-- Alert Notes Box Component - For inline display on detail pages -->
|
|
<style>
|
|
.alert-note-box {
|
|
border-left: 5px solid;
|
|
padding: 15px 20px;
|
|
margin: 15px 0;
|
|
background: var(--bg-card);
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.alert-note-box:hover {
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
}
|
|
|
|
.alert-note-info {
|
|
border-left-color: #0dcaf0;
|
|
background: #d1ecf1;
|
|
}
|
|
|
|
[data-bs-theme="dark"] .alert-note-info {
|
|
background: rgba(13, 202, 240, 0.15);
|
|
}
|
|
|
|
.alert-note-warning {
|
|
border-left-color: #ffc107;
|
|
background: #fff3cd;
|
|
}
|
|
|
|
[data-bs-theme="dark"] .alert-note-warning {
|
|
background: rgba(255, 193, 7, 0.15);
|
|
}
|
|
|
|
.alert-note-critical {
|
|
border-left-color: #dc3545;
|
|
background: #f8d7da;
|
|
}
|
|
|
|
[data-bs-theme="dark"] .alert-note-critical {
|
|
background: rgba(220, 53, 69, 0.15);
|
|
}
|
|
|
|
.alert-note-title {
|
|
font-weight: 600;
|
|
font-size: 1.1rem;
|
|
margin-bottom: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.alert-note-severity-badge {
|
|
font-size: 0.75rem;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
text-transform: uppercase;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.alert-note-severity-badge.info {
|
|
background: #0dcaf0;
|
|
color: white;
|
|
}
|
|
|
|
.alert-note-severity-badge.warning {
|
|
background: #ffc107;
|
|
color: #000;
|
|
}
|
|
|
|
.alert-note-severity-badge.critical {
|
|
background: #dc3545;
|
|
color: white;
|
|
}
|
|
|
|
.alert-note-message {
|
|
margin-bottom: 12px;
|
|
line-height: 1.6;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.alert-note-restrictions {
|
|
padding: 10px;
|
|
background: rgba(0,0,0,0.05);
|
|
border-radius: 6px;
|
|
font-size: 0.9rem;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
[data-bs-theme="dark"] .alert-note-restrictions {
|
|
background: rgba(255,255,255,0.05);
|
|
}
|
|
|
|
.alert-note-restrictions strong {
|
|
display: block;
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.alert-note-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-top: 12px;
|
|
font-size: 0.85rem;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.alert-note-acknowledge-btn {
|
|
font-size: 0.85rem;
|
|
padding: 4px 12px;
|
|
}
|
|
</style>
|
|
|
|
<!-- Template structure (fill via JavaScript) -->
|
|
<div id="alert-notes-container"></div>
|
|
|
|
<script>
|
|
function renderAlertBox(alert) {
|
|
const severityClass = `alert-note-${alert.severity}`;
|
|
const severityBadgeClass = alert.severity;
|
|
|
|
let restrictionsHtml = '';
|
|
if (alert.restrictions && alert.restrictions.length > 0) {
|
|
const restrictionNames = alert.restrictions.map(r => r.restriction_name).join(', ');
|
|
restrictionsHtml = `
|
|
<div class="alert-note-restrictions">
|
|
<strong><i class="bi bi-shield-lock"></i> Håndteres kun af:</strong>
|
|
${restrictionNames}
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
let acknowledgeBtn = '';
|
|
if (alert.requires_acknowledgement && !alert.user_has_acknowledged) {
|
|
acknowledgeBtn = `
|
|
<button class="btn btn-sm btn-outline-secondary alert-note-acknowledge-btn"
|
|
onclick="acknowledgeAlert(${alert.id}, this)">
|
|
<i class="bi bi-check-circle"></i> Forstået
|
|
</button>
|
|
`;
|
|
}
|
|
|
|
// Edit button (always show for admins/creators)
|
|
const editBtn = `
|
|
<button class="btn btn-sm btn-outline-primary alert-note-acknowledge-btn"
|
|
onclick="openAlertNoteForm('${alert.entity_type}', ${alert.entity_id}, ${alert.id})"
|
|
title="Rediger alert note">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
`;
|
|
|
|
const createdBy = alert.created_by_user_name ? ` • Oprettet af ${alert.created_by_user_name}` : '';
|
|
|
|
return `
|
|
<div class="alert-note-box ${severityClass}" data-alert-id="${alert.id}">
|
|
<div class="alert-note-title">
|
|
<span class="alert-note-severity-badge ${severityBadgeClass}">
|
|
${alert.severity === 'info' ? 'INFO' : alert.severity === 'warning' ? 'ADVARSEL' : 'KRITISK'}
|
|
<div class="d-flex gap-2">
|
|
${editBtn}
|
|
${acknowledgeBtn}
|
|
</div>
|
|
${alert.title}
|
|
</div>
|
|
<div class="alert-note-message">${alert.message}</div>
|
|
${restrictionsHtml}
|
|
<div class="alert-note-footer">
|
|
<span class="text-muted">
|
|
<i class="bi bi-calendar"></i> ${new Date(alert.created_at).toLocaleDateString('da-DK')}${createdBy}
|
|
</span>
|
|
${acknowledgeBtn}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
function acknowledgeAlert(alertId, buttonElement) {
|
|
fetch(`/api/v1/alert-notes/${alertId}/acknowledge`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.status === 'acknowledged' || data.status === 'already_acknowledged') {
|
|
// Remove the alert box with fade animation
|
|
const alertBox = buttonElement.closest('.alert-note-box');
|
|
alertBox.style.opacity = '0';
|
|
alertBox.style.transform = 'translateX(-20px)';
|
|
setTimeout(() => alertBox.remove(), 300);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error acknowledging alert:', error);
|
|
alert('Kunne ikke markere som læst. Prøv igen.');
|
|
});
|
|
}
|
|
</script>
|