286 lines
12 KiB
HTML
286 lines
12 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>Incident Subscription Test</title>
|
||
|
|
<script type="module" src="./dist_bundle/bundle.js"></script>
|
||
|
|
<style>
|
||
|
|
body {
|
||
|
|
margin: 0;
|
||
|
|
padding: 20px;
|
||
|
|
font-family: 'Geist Sans', -apple-system, BlinkMacSystemFont, sans-serif;
|
||
|
|
background: #fafafa;
|
||
|
|
}
|
||
|
|
@media (prefers-color-scheme: dark) {
|
||
|
|
body {
|
||
|
|
background: #09090b;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
.container {
|
||
|
|
max-width: 1200px;
|
||
|
|
margin: 0 auto;
|
||
|
|
}
|
||
|
|
h1 {
|
||
|
|
margin-bottom: 20px;
|
||
|
|
color: #0a0a0a;
|
||
|
|
}
|
||
|
|
@media (prefers-color-scheme: dark) {
|
||
|
|
h1 {
|
||
|
|
color: #fafafa;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
.info-panel {
|
||
|
|
background: #f0f9ff;
|
||
|
|
border: 1px solid #bae6fd;
|
||
|
|
border-radius: 8px;
|
||
|
|
padding: 20px;
|
||
|
|
margin-bottom: 30px;
|
||
|
|
}
|
||
|
|
@media (prefers-color-scheme: dark) {
|
||
|
|
.info-panel {
|
||
|
|
background: #0c4a6e;
|
||
|
|
border-color: #0284c7;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
.subscription-log {
|
||
|
|
background: #f3f4f6;
|
||
|
|
border: 1px solid #e5e7eb;
|
||
|
|
border-radius: 8px;
|
||
|
|
padding: 20px;
|
||
|
|
margin-top: 30px;
|
||
|
|
font-family: monospace;
|
||
|
|
font-size: 13px;
|
||
|
|
max-height: 200px;
|
||
|
|
overflow-y: auto;
|
||
|
|
}
|
||
|
|
@media (prefers-color-scheme: dark) {
|
||
|
|
.subscription-log {
|
||
|
|
background: #1f2937;
|
||
|
|
border-color: #374151;
|
||
|
|
color: #e5e7eb;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
.notification {
|
||
|
|
position: fixed;
|
||
|
|
top: 20px;
|
||
|
|
right: 20px;
|
||
|
|
padding: 16px 24px;
|
||
|
|
background: #10b981;
|
||
|
|
color: white;
|
||
|
|
border-radius: 8px;
|
||
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||
|
|
font-size: 14px;
|
||
|
|
font-weight: 500;
|
||
|
|
animation: slideIn 0.3s ease;
|
||
|
|
z-index: 1000;
|
||
|
|
}
|
||
|
|
@keyframes slideIn {
|
||
|
|
from {
|
||
|
|
transform: translateX(100%);
|
||
|
|
opacity: 0;
|
||
|
|
}
|
||
|
|
to {
|
||
|
|
transform: translateX(0);
|
||
|
|
opacity: 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
.notification.unsubscribe {
|
||
|
|
background: #6b7280;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div class="container">
|
||
|
|
<h1>Incident Subscription Feature Demo</h1>
|
||
|
|
|
||
|
|
<div class="info-panel">
|
||
|
|
<h3>How Incident Subscriptions Work:</h3>
|
||
|
|
<ul>
|
||
|
|
<li>Each incident can be individually subscribed to</li>
|
||
|
|
<li>Click on an incident to expand it and see the "Subscribe to updates" button</li>
|
||
|
|
<li>Subscribed incidents show a checkmark and "Subscribed to updates" text</li>
|
||
|
|
<li>Click again to unsubscribe</li>
|
||
|
|
<li>The component emits events for subscribe/unsubscribe actions</li>
|
||
|
|
<li>You can pre-set subscribed incidents using the <code>subscribedIncidentIds</code> property</li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<upl-statuspage-incidents id="incidents"></upl-statuspage-incidents>
|
||
|
|
|
||
|
|
<div class="subscription-log" id="log">
|
||
|
|
<strong>Event Log:</strong><br>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
document.addEventListener('DOMContentLoaded', () => {
|
||
|
|
const incidents = document.getElementById('incidents');
|
||
|
|
const log = document.getElementById('log');
|
||
|
|
|
||
|
|
// Helper function to add log entries
|
||
|
|
function addLog(message) {
|
||
|
|
const timestamp = new Date().toLocaleTimeString();
|
||
|
|
log.innerHTML += `[${timestamp}] ${message}<br>`;
|
||
|
|
log.scrollTop = log.scrollHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Helper function to show notifications
|
||
|
|
function showNotification(message, type = 'subscribe') {
|
||
|
|
const notification = document.createElement('div');
|
||
|
|
notification.className = `notification ${type === 'unsubscribe' ? 'unsubscribe' : ''}`;
|
||
|
|
notification.textContent = message;
|
||
|
|
document.body.appendChild(notification);
|
||
|
|
|
||
|
|
setTimeout(() => {
|
||
|
|
notification.style.opacity = '0';
|
||
|
|
notification.style.transform = 'translateX(100%)';
|
||
|
|
setTimeout(() => notification.remove(), 300);
|
||
|
|
}, 3000);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Set up some test incidents
|
||
|
|
const currentIncidents = [
|
||
|
|
{
|
||
|
|
id: 'inc-001',
|
||
|
|
title: 'Database Connection Pool Exhaustion',
|
||
|
|
status: 'monitoring',
|
||
|
|
severity: 'major',
|
||
|
|
affectedServices: ['API Gateway', 'User Service', 'Order Service'],
|
||
|
|
startTime: Date.now() - 2 * 60 * 60 * 1000,
|
||
|
|
impact: 'API response times are elevated. Some requests may timeout.',
|
||
|
|
updates: [
|
||
|
|
{
|
||
|
|
id: 'upd-1',
|
||
|
|
timestamp: Date.now() - 2 * 60 * 60 * 1000,
|
||
|
|
status: 'investigating',
|
||
|
|
message: 'We are investigating reports of slow API responses',
|
||
|
|
author: 'Operations Team'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'upd-2',
|
||
|
|
timestamp: Date.now() - 90 * 60 * 1000,
|
||
|
|
status: 'identified',
|
||
|
|
message: 'Database connection pool is at capacity due to increased traffic',
|
||
|
|
author: 'Database Team'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'upd-3',
|
||
|
|
timestamp: Date.now() - 30 * 60 * 1000,
|
||
|
|
status: 'monitoring',
|
||
|
|
message: 'Connection pool size has been increased. Monitoring for stability.',
|
||
|
|
author: 'Operations Team'
|
||
|
|
}
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'inc-002',
|
||
|
|
title: 'CDN Configuration Update',
|
||
|
|
status: 'identified',
|
||
|
|
severity: 'minor',
|
||
|
|
affectedServices: ['CDN', 'Static Assets'],
|
||
|
|
startTime: Date.now() - 45 * 60 * 1000,
|
||
|
|
impact: 'Some static assets may load slowly in certain regions',
|
||
|
|
updates: [
|
||
|
|
{
|
||
|
|
id: 'upd-4',
|
||
|
|
timestamp: Date.now() - 45 * 60 * 1000,
|
||
|
|
status: 'investigating',
|
||
|
|
message: 'Investigating reports of slow asset loading',
|
||
|
|
author: 'Network Team'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'upd-5',
|
||
|
|
timestamp: Date.now() - 20 * 60 * 1000,
|
||
|
|
status: 'identified',
|
||
|
|
message: 'CDN configuration needs optimization for new edge locations',
|
||
|
|
author: 'Network Team'
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
];
|
||
|
|
|
||
|
|
const pastIncidents = [
|
||
|
|
{
|
||
|
|
id: 'inc-003',
|
||
|
|
title: 'Authentication Service Outage',
|
||
|
|
status: 'resolved',
|
||
|
|
severity: 'critical',
|
||
|
|
affectedServices: ['Authentication', 'All Services'],
|
||
|
|
startTime: Date.now() - 7 * 24 * 60 * 60 * 1000,
|
||
|
|
endTime: Date.now() - 7 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000,
|
||
|
|
impact: 'Users were unable to log in',
|
||
|
|
rootCause: 'Certificate expiration in auth service',
|
||
|
|
resolution: 'Certificate renewed and monitoring alerts added',
|
||
|
|
updates: [
|
||
|
|
{
|
||
|
|
id: 'upd-6',
|
||
|
|
timestamp: Date.now() - 7 * 24 * 60 * 60 * 1000,
|
||
|
|
status: 'investigating',
|
||
|
|
message: 'Multiple reports of login failures',
|
||
|
|
author: 'On-call Engineer'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'upd-7',
|
||
|
|
timestamp: Date.now() - 7 * 24 * 60 * 60 * 1000 + 30 * 60 * 1000,
|
||
|
|
status: 'identified',
|
||
|
|
message: 'SSL certificate has expired',
|
||
|
|
author: 'Security Team'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'upd-8',
|
||
|
|
timestamp: Date.now() - 7 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000,
|
||
|
|
status: 'resolved',
|
||
|
|
message: 'Certificate renewed and service restored',
|
||
|
|
author: 'Security Team'
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
];
|
||
|
|
|
||
|
|
// Set the incidents
|
||
|
|
incidents.currentIncidents = currentIncidents;
|
||
|
|
incidents.pastIncidents = pastIncidents;
|
||
|
|
|
||
|
|
// Pre-subscribe to the first incident
|
||
|
|
incidents.subscribedIncidentIds = ['inc-001'];
|
||
|
|
addLog('Pre-subscribed to incident: "Database Connection Pool Exhaustion"');
|
||
|
|
|
||
|
|
// Handle subscription events
|
||
|
|
incidents.addEventListener('incidentSubscribe', (event) => {
|
||
|
|
const { incidentId, incidentTitle, affectedServices } = event.detail;
|
||
|
|
addLog(`SUBSCRIBED to incident: "${incidentTitle}" (ID: ${incidentId})`);
|
||
|
|
addLog(` Affected services: ${affectedServices.join(', ')}`);
|
||
|
|
showNotification(`✓ Subscribed to: ${incidentTitle}`, 'subscribe');
|
||
|
|
|
||
|
|
// In a real application, you would send this to your backend
|
||
|
|
console.log('Subscribe API call would be made here:', {
|
||
|
|
incidentId,
|
||
|
|
userEmail: 'user@example.com',
|
||
|
|
notificationPreferences: ['email', 'sms']
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
incidents.addEventListener('incidentUnsubscribe', (event) => {
|
||
|
|
const { incident } = event.detail;
|
||
|
|
addLog(`UNSUBSCRIBED from incident: "${incident.title}" (ID: ${incident.id})`);
|
||
|
|
showNotification(`Unsubscribed from: ${incident.title}`, 'unsubscribe');
|
||
|
|
|
||
|
|
// In a real application, you would send this to your backend
|
||
|
|
console.log('Unsubscribe API call would be made here:', {
|
||
|
|
incidentId: incident.id,
|
||
|
|
userEmail: 'user@example.com'
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// Simulate receiving a new update for a subscribed incident
|
||
|
|
setTimeout(() => {
|
||
|
|
if (incidents.subscribedIncidents && incidents.subscribedIncidents.has('inc-001')) {
|
||
|
|
addLog('📬 NEW UPDATE for subscribed incident "Database Connection Pool Exhaustion"');
|
||
|
|
showNotification('New update: Connection pool stable, incident will be resolved soon');
|
||
|
|
}
|
||
|
|
}, 5000);
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|