update
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,7 +3,6 @@
|
||||
# artifacts
|
||||
coverage/
|
||||
public/
|
||||
pages/
|
||||
|
||||
# installs
|
||||
node_modules/
|
||||
|
||||
4
ts_web/pages/index.ts
Normal file
4
ts_web/pages/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './statuspage-demo.js';
|
||||
export * from './statuspage-allgreen.js';
|
||||
export * from './statuspage-outage.js';
|
||||
export * from './statuspage-maintenance.js';
|
||||
421
ts_web/pages/statuspage-allgreen.ts
Normal file
421
ts_web/pages/statuspage-allgreen.ts
Normal file
@@ -0,0 +1,421 @@
|
||||
import { html, cssManager } from "@design.estate/dees-element";
|
||||
import type { IServiceStatus, IOverallStatus, IIncidentDetails, IStatusHistoryPoint, IMonthlyUptime } from '../interfaces/index.js';
|
||||
|
||||
export const statuspageAllgreen = () => html`
|
||||
<style>
|
||||
.demo-page-wrapper {
|
||||
min-height: 100vh;
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
}
|
||||
|
||||
.demo-info {
|
||||
padding: 20px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-family: 'Geist Sans', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.demo-info h3 {
|
||||
margin: 0 0 10px 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
.demo-info p {
|
||||
margin: 0;
|
||||
opacity: 0.9;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="demo-page-wrapper">
|
||||
<div class="demo-info">
|
||||
<h3>All Systems Operational</h3>
|
||||
<p>This demo shows a status page where everything is running perfectly with no issues.</p>
|
||||
</div>
|
||||
|
||||
<dees-demowrapper
|
||||
.runAfterRender=${async (wrapperElement: any) => {
|
||||
const header = wrapperElement.querySelector('upl-statuspage-header') as any;
|
||||
const statusBar = wrapperElement.querySelector('upl-statuspage-statusbar') as any;
|
||||
const assetsSelector = wrapperElement.querySelector('upl-statuspage-assetsselector') as any;
|
||||
const statusDetails = wrapperElement.querySelector('upl-statuspage-statusdetails') as any;
|
||||
const statusMonth = wrapperElement.querySelector('upl-statuspage-statusmonth') as any;
|
||||
const incidents = wrapperElement.querySelector('upl-statuspage-incidents') as any;
|
||||
const footer = wrapperElement.querySelector('upl-statuspage-footer') as any;
|
||||
|
||||
// Configure Header
|
||||
header.pageTitle = 'TechVault Services Status';
|
||||
header.showReportButton = true;
|
||||
header.showSubscribeButton = true;
|
||||
header.logoUrl = 'https://via.placeholder.com/150x50/4CAF50/ffffff?text=TechVault';
|
||||
header.customStyles = true;
|
||||
header.brandColor = '#4CAF50';
|
||||
|
||||
// Configure Overall Status - All Green
|
||||
statusBar.overallStatus = {
|
||||
status: 'operational',
|
||||
message: 'All Systems Operational',
|
||||
lastUpdated: Date.now(),
|
||||
affectedServices: 0,
|
||||
totalServices: 12
|
||||
};
|
||||
|
||||
// Configure Services - All Operational
|
||||
const services: IServiceStatus[] = [
|
||||
{
|
||||
id: 'web-app',
|
||||
name: 'web-app',
|
||||
displayName: 'Web Application',
|
||||
description: 'Main customer-facing application',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.99,
|
||||
uptime90d: 99.98,
|
||||
responseTime: 32,
|
||||
category: 'Frontend',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'mobile-app',
|
||||
name: 'mobile-app',
|
||||
displayName: 'Mobile Applications',
|
||||
description: 'iOS and Android apps',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 99.99,
|
||||
responseTime: 45,
|
||||
category: 'Frontend',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'api',
|
||||
name: 'api',
|
||||
displayName: 'API Services',
|
||||
description: 'RESTful and GraphQL APIs',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.97,
|
||||
uptime90d: 99.96,
|
||||
responseTime: 28,
|
||||
category: 'Backend',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'auth',
|
||||
name: 'auth',
|
||||
displayName: 'Authentication',
|
||||
description: 'OAuth and SSO services',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 99.99,
|
||||
responseTime: 22,
|
||||
category: 'Backend',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'database',
|
||||
name: 'database',
|
||||
displayName: 'Database Cluster',
|
||||
description: 'Primary data storage',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 99.99,
|
||||
responseTime: 15,
|
||||
category: 'Infrastructure',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'cache',
|
||||
name: 'cache',
|
||||
displayName: 'Cache Layer',
|
||||
description: 'Redis cache clusters',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 100,
|
||||
responseTime: 3,
|
||||
category: 'Infrastructure',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'search',
|
||||
name: 'search',
|
||||
displayName: 'Search Service',
|
||||
description: 'Elasticsearch clusters',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.98,
|
||||
uptime90d: 99.97,
|
||||
responseTime: 42,
|
||||
category: 'Infrastructure',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'cdn',
|
||||
name: 'cdn',
|
||||
displayName: 'CDN',
|
||||
description: 'Global content delivery',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 100,
|
||||
responseTime: 8,
|
||||
category: 'Network',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'email',
|
||||
name: 'email',
|
||||
displayName: 'Email Service',
|
||||
description: 'Transactional emails',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.95,
|
||||
uptime90d: 99.94,
|
||||
responseTime: 125,
|
||||
category: 'Communication',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'sms',
|
||||
name: 'sms',
|
||||
displayName: 'SMS Service',
|
||||
description: 'SMS notifications',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.92,
|
||||
uptime90d: 99.90,
|
||||
responseTime: 180,
|
||||
category: 'Communication',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'payments',
|
||||
name: 'payments',
|
||||
displayName: 'Payment Processing',
|
||||
description: 'Payment gateway integration',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 99.99,
|
||||
responseTime: 95,
|
||||
category: 'Services',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'analytics',
|
||||
name: 'analytics',
|
||||
displayName: 'Analytics Engine',
|
||||
description: 'Real-time analytics',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.96,
|
||||
uptime90d: 99.95,
|
||||
responseTime: 55,
|
||||
category: 'Services',
|
||||
selected: true
|
||||
}
|
||||
];
|
||||
|
||||
assetsSelector.services = services;
|
||||
|
||||
// Configure Status Details - All operational for 48 hours
|
||||
const generateStatusDetails = (): IStatusHistoryPoint[] => {
|
||||
const details: IStatusHistoryPoint[] = [];
|
||||
const now = new Date();
|
||||
|
||||
for (let i = 47; i >= 0; i--) {
|
||||
const date = new Date(now);
|
||||
date.setMinutes(0, 0, 0);
|
||||
date.setHours(date.getHours() - i);
|
||||
|
||||
details.push({
|
||||
timestamp: date.getTime(),
|
||||
status: 'operational',
|
||||
responseTime: 20 + Math.random() * 10 // Very consistent response times
|
||||
});
|
||||
}
|
||||
|
||||
return details;
|
||||
};
|
||||
|
||||
statusDetails.dataPoints = generateStatusDetails();
|
||||
statusDetails.serviceId = 'api';
|
||||
statusDetails.serviceName = 'API Services';
|
||||
|
||||
// Configure Monthly Status - Near perfect uptime
|
||||
const generateMonthlyData = (): IMonthlyUptime[] => {
|
||||
const months: IMonthlyUptime[] = [];
|
||||
const now = new Date();
|
||||
|
||||
for (let m = 4; m >= 0; m--) {
|
||||
const monthDate = new Date(now.getFullYear(), now.getMonth() - m, 1);
|
||||
const daysInMonth = new Date(monthDate.getFullYear(), monthDate.getMonth() + 1, 0).getDate();
|
||||
const monthKey = monthDate.toISOString().slice(0, 7);
|
||||
|
||||
const days = [];
|
||||
let totalUptime = 0;
|
||||
let incidents = 0;
|
||||
|
||||
for (let d = 1; d <= daysInMonth; d++) {
|
||||
const dayDate = new Date(monthDate.getFullYear(), monthDate.getMonth(), d);
|
||||
const isFuture = dayDate > now;
|
||||
|
||||
if (isFuture) continue;
|
||||
|
||||
// Almost all days are perfect
|
||||
let status: 'operational' | 'degraded' | 'partial_outage' | 'major_outage' = 'operational';
|
||||
let uptime = 100;
|
||||
let dayIncidents = 0;
|
||||
|
||||
// Very rare minor issues
|
||||
if (Math.random() > 0.98) {
|
||||
status = 'degraded';
|
||||
uptime = 99.5 + Math.random() * 0.5;
|
||||
dayIncidents = 1;
|
||||
}
|
||||
|
||||
days.push({
|
||||
date: dayDate.toISOString().slice(0, 10),
|
||||
status,
|
||||
uptime,
|
||||
incidents: dayIncidents,
|
||||
totalDowntime: Math.round((100 - uptime) * 14.4)
|
||||
});
|
||||
|
||||
totalUptime += uptime;
|
||||
incidents += dayIncidents;
|
||||
}
|
||||
|
||||
months.push({
|
||||
month: monthKey,
|
||||
days,
|
||||
overallUptime: totalUptime / days.length,
|
||||
totalIncidents: incidents
|
||||
});
|
||||
}
|
||||
|
||||
return months;
|
||||
};
|
||||
|
||||
statusMonth.monthlyData = generateMonthlyData();
|
||||
statusMonth.serviceId = 'all-services';
|
||||
statusMonth.serviceName = 'All Services';
|
||||
|
||||
// Configure Incidents - None current, few past
|
||||
const currentIncidents: IIncidentDetails[] = [];
|
||||
|
||||
const pastIncidents: IIncidentDetails[] = [
|
||||
{
|
||||
id: 'inc-2024-001',
|
||||
title: 'Brief API Response Time Increase',
|
||||
impact: 'API responses were slightly slower than usual',
|
||||
severity: 'minor',
|
||||
status: 'resolved',
|
||||
startTime: Date.now() - 45 * 24 * 60 * 60 * 1000,
|
||||
endTime: Date.now() - 45 * 24 * 60 * 60 * 1000 + 15 * 60 * 1000,
|
||||
affectedServices: ['API Services'],
|
||||
rootCause: 'Temporary increase in traffic due to a viral marketing campaign.',
|
||||
resolution: 'Auto-scaling handled the load increase. No manual intervention required.',
|
||||
updates: [
|
||||
{
|
||||
id: 'update-1',
|
||||
timestamp: Date.now() - 45 * 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Monitoring increased API response times.',
|
||||
author: 'Automated Monitoring'
|
||||
},
|
||||
{
|
||||
id: 'update-2',
|
||||
timestamp: Date.now() - 45 * 24 * 60 * 60 * 1000 + 5 * 60 * 1000,
|
||||
status: 'identified',
|
||||
message: 'Traffic spike identified. Auto-scaling in progress.',
|
||||
author: 'DevOps Team'
|
||||
},
|
||||
{
|
||||
id: 'update-3',
|
||||
timestamp: Date.now() - 45 * 24 * 60 * 60 * 1000 + 15 * 60 * 1000,
|
||||
status: 'resolved',
|
||||
message: 'Response times back to normal. Incident resolved.',
|
||||
author: 'Automated Monitoring'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'inc-2023-089',
|
||||
title: 'Scheduled Database Maintenance',
|
||||
impact: 'Database was in read-only mode for 30 minutes',
|
||||
severity: 'minor',
|
||||
status: 'resolved',
|
||||
startTime: Date.now() - 90 * 24 * 60 * 60 * 1000,
|
||||
endTime: Date.now() - 90 * 24 * 60 * 60 * 1000 + 30 * 60 * 1000,
|
||||
affectedServices: ['Database Cluster'],
|
||||
rootCause: 'Scheduled maintenance for security patches.',
|
||||
resolution: 'Maintenance completed successfully as planned.',
|
||||
updates: [
|
||||
{
|
||||
id: 'update-4',
|
||||
timestamp: Date.now() - 97 * 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Scheduled maintenance announced.',
|
||||
author: 'Database Team'
|
||||
},
|
||||
{
|
||||
id: 'update-5',
|
||||
timestamp: Date.now() - 90 * 24 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Maintenance started. Database in read-only mode.',
|
||||
author: 'Database Team'
|
||||
},
|
||||
{
|
||||
id: 'update-6',
|
||||
timestamp: Date.now() - 90 * 24 * 60 * 60 * 1000 + 30 * 60 * 1000,
|
||||
status: 'resolved',
|
||||
message: 'Maintenance completed. All systems operational.',
|
||||
author: 'Database Team'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
incidents.currentIncidents = currentIncidents;
|
||||
incidents.pastIncidents = pastIncidents;
|
||||
|
||||
// Configure Footer
|
||||
footer.companyName = 'TechVault Services';
|
||||
footer.legalUrl = 'https://techvault.example.com/legal';
|
||||
footer.supportEmail = 'support@techvault.example.com';
|
||||
footer.statusPageUrl = 'https://status.techvault.example.com';
|
||||
footer.lastUpdated = Date.now();
|
||||
footer.currentYear = new Date().getFullYear();
|
||||
footer.socialLinks = [
|
||||
{ platform: 'twitter', url: 'https://twitter.com/techvault' },
|
||||
{ platform: 'github', url: 'https://github.com/techvault' },
|
||||
{ platform: 'linkedin', url: 'https://linkedin.com/company/techvault' },
|
||||
{ platform: 'youtube', url: 'https://youtube.com/techvault' }
|
||||
];
|
||||
footer.rssFeedUrl = 'https://status.techvault.example.com/rss';
|
||||
footer.apiStatusUrl = 'https://api.techvault.example.com/v1/status';
|
||||
footer.enableSubscribe = true;
|
||||
footer.subscriberCount = 5421;
|
||||
footer.additionalLinks = [
|
||||
{ label: 'API Documentation', url: 'https://docs.techvault.example.com' },
|
||||
{ label: 'System Architecture', url: 'https://techvault.example.com/architecture' },
|
||||
{ label: 'Security', url: 'https://techvault.example.com/security' }
|
||||
];
|
||||
}}
|
||||
>
|
||||
<upl-statuspage-header></upl-statuspage-header>
|
||||
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
||||
<upl-statuspage-assetsselector></upl-statuspage-assetsselector>
|
||||
<upl-statuspage-statusdetails></upl-statuspage-statusdetails>
|
||||
<upl-statuspage-statusmonth></upl-statuspage-statusmonth>
|
||||
<upl-statuspage-incidents></upl-statuspage-incidents>
|
||||
<upl-statuspage-footer></upl-statuspage-footer>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
`;
|
||||
650
ts_web/pages/statuspage-demo.ts
Normal file
650
ts_web/pages/statuspage-demo.ts
Normal file
@@ -0,0 +1,650 @@
|
||||
import { html, cssManager } from "@design.estate/dees-element";
|
||||
import type { IServiceStatus, IOverallStatus, IIncidentDetails, IStatusHistoryPoint, IMonthlyUptime } from '../interfaces/index.js';
|
||||
|
||||
export const statuspageDemo = () => html`
|
||||
<style>
|
||||
.demo-page-wrapper {
|
||||
min-height: 100vh;
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
}
|
||||
|
||||
.demo-info {
|
||||
padding: 20px;
|
||||
background: #2196F3;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-family: 'Geist Sans', Inter, sans-serif;
|
||||
}
|
||||
.demo-info h3 {
|
||||
margin: 0 0 10px 0;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.demo-info p {
|
||||
margin: 0;
|
||||
opacity: 0.9;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="demo-page-wrapper">
|
||||
<div class="demo-info">
|
||||
<h3>CloudFlow Infrastructure Status Page</h3>
|
||||
<p>This demo shows a comprehensive status page for a cloud infrastructure provider with real-time monitoring.</p>
|
||||
</div>
|
||||
|
||||
<dees-demowrapper
|
||||
.runAfterRender=${async (wrapperElement: any) => {
|
||||
const header = wrapperElement.querySelector('upl-statuspage-header') as any;
|
||||
const statusBar = wrapperElement.querySelector('upl-statuspage-statusbar') as any;
|
||||
const assetsSelector = wrapperElement.querySelector('upl-statuspage-assetsselector') as any;
|
||||
const statusDetails = wrapperElement.querySelector('upl-statuspage-statusdetails') as any;
|
||||
const statusMonth = wrapperElement.querySelector('upl-statuspage-statusmonth') as any;
|
||||
const incidents = wrapperElement.querySelector('upl-statuspage-incidents') as any;
|
||||
const footer = wrapperElement.querySelector('upl-statuspage-footer') as any;
|
||||
|
||||
// Configure Header
|
||||
header.pageTitle = 'CloudFlow Infrastructure Status';
|
||||
header.showReportButton = true;
|
||||
header.showSubscribeButton = true;
|
||||
header.logoUrl = 'https://via.placeholder.com/150x50/2196F3/ffffff?text=CloudFlow';
|
||||
header.customStyles = true;
|
||||
header.brandColor = '#2196F3';
|
||||
|
||||
// Configure Overall Status
|
||||
statusBar.overallStatus = {
|
||||
status: 'degraded',
|
||||
message: 'Minor service degradation in EU-West region',
|
||||
lastUpdated: Date.now(),
|
||||
affectedServices: 3,
|
||||
totalServices: 18
|
||||
};
|
||||
|
||||
// Configure Services
|
||||
const services: IServiceStatus[] = [
|
||||
// Core Infrastructure
|
||||
{
|
||||
id: 'api-gateway',
|
||||
name: 'api-gateway',
|
||||
displayName: 'API Gateway',
|
||||
description: 'Main API endpoint for all services',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.95,
|
||||
uptime90d: 99.92,
|
||||
responseTime: 45,
|
||||
category: 'Core Services',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'auth-service',
|
||||
name: 'auth-service',
|
||||
displayName: 'Authentication Service',
|
||||
description: 'User authentication and authorization',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.98,
|
||||
uptime90d: 99.95,
|
||||
responseTime: 32,
|
||||
category: 'Core Services',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'user-dashboard',
|
||||
name: 'user-dashboard',
|
||||
displayName: 'User Dashboard',
|
||||
description: 'Web application dashboard',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.99,
|
||||
uptime90d: 99.97,
|
||||
responseTime: 128,
|
||||
category: 'Web Services',
|
||||
selected: true
|
||||
},
|
||||
// Regional Services - US
|
||||
{
|
||||
id: 'us-east-compute',
|
||||
name: 'us-east-compute',
|
||||
displayName: 'US-East Compute',
|
||||
description: 'Virtual machine instances',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.94,
|
||||
uptime90d: 99.91,
|
||||
responseTime: 22,
|
||||
category: 'US-East',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'us-east-storage',
|
||||
name: 'us-east-storage',
|
||||
displayName: 'US-East Storage',
|
||||
description: 'Object storage service',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 99.99,
|
||||
responseTime: 18,
|
||||
category: 'US-East',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'us-east-database',
|
||||
name: 'us-east-database',
|
||||
displayName: 'US-East Database',
|
||||
description: 'Managed database clusters',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.97,
|
||||
uptime90d: 99.95,
|
||||
responseTime: 14,
|
||||
category: 'US-East',
|
||||
selected: false
|
||||
},
|
||||
// Regional Services - EU (Degraded)
|
||||
{
|
||||
id: 'eu-west-compute',
|
||||
name: 'eu-west-compute',
|
||||
displayName: 'EU-West Compute',
|
||||
description: 'Virtual machine instances',
|
||||
currentStatus: 'degraded',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 98.2,
|
||||
uptime90d: 99.1,
|
||||
responseTime: 145,
|
||||
category: 'EU-West',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'eu-west-storage',
|
||||
name: 'eu-west-storage',
|
||||
displayName: 'EU-West Storage',
|
||||
description: 'Object storage service',
|
||||
currentStatus: 'degraded',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 98.5,
|
||||
uptime90d: 99.3,
|
||||
responseTime: 220,
|
||||
category: 'EU-West',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'eu-west-database',
|
||||
name: 'eu-west-database',
|
||||
displayName: 'EU-West Database',
|
||||
description: 'Managed database clusters',
|
||||
currentStatus: 'partial_outage',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 97.8,
|
||||
uptime90d: 98.9,
|
||||
responseTime: 450,
|
||||
category: 'EU-West',
|
||||
selected: true
|
||||
},
|
||||
// Regional Services - Asia
|
||||
{
|
||||
id: 'ap-south-compute',
|
||||
name: 'ap-south-compute',
|
||||
displayName: 'Asia-Pacific Compute',
|
||||
description: 'Virtual machine instances',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.91,
|
||||
uptime90d: 99.88,
|
||||
responseTime: 38,
|
||||
category: 'Asia-Pacific',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'ap-south-storage',
|
||||
name: 'ap-south-storage',
|
||||
displayName: 'Asia-Pacific Storage',
|
||||
description: 'Object storage service',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.95,
|
||||
uptime90d: 99.93,
|
||||
responseTime: 42,
|
||||
category: 'Asia-Pacific',
|
||||
selected: false
|
||||
},
|
||||
// Supporting Services
|
||||
{
|
||||
id: 'cdn',
|
||||
name: 'cdn',
|
||||
displayName: 'Content Delivery Network',
|
||||
description: 'Global CDN for static assets',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 99.99,
|
||||
responseTime: 12,
|
||||
category: 'Network',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'dns',
|
||||
name: 'dns',
|
||||
displayName: 'DNS Service',
|
||||
description: 'Managed DNS resolution',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 100,
|
||||
responseTime: 8,
|
||||
category: 'Network',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'monitoring',
|
||||
name: 'monitoring',
|
||||
displayName: 'Monitoring Service',
|
||||
description: 'Infrastructure monitoring',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.92,
|
||||
uptime90d: 99.90,
|
||||
responseTime: 65,
|
||||
category: 'Operations',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'logging',
|
||||
name: 'logging',
|
||||
displayName: 'Logging Service',
|
||||
description: 'Centralized log management',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.88,
|
||||
uptime90d: 99.85,
|
||||
responseTime: 72,
|
||||
category: 'Operations',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'backup-service',
|
||||
name: 'backup-service',
|
||||
displayName: 'Backup Service',
|
||||
description: 'Automated backup system',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 100,
|
||||
uptime90d: 99.98,
|
||||
responseTime: 95,
|
||||
category: 'Operations',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'email-service',
|
||||
name: 'email-service',
|
||||
displayName: 'Email Delivery',
|
||||
description: 'Transactional email service',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.94,
|
||||
uptime90d: 99.91,
|
||||
responseTime: 125,
|
||||
category: 'Communication',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'sms-service',
|
||||
name: 'sms-service',
|
||||
displayName: 'SMS Gateway',
|
||||
description: 'SMS notification service',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.89,
|
||||
uptime90d: 99.87,
|
||||
responseTime: 180,
|
||||
category: 'Communication',
|
||||
selected: false
|
||||
}
|
||||
];
|
||||
|
||||
assetsSelector.services = services;
|
||||
|
||||
// Configure Status Details (48 hours of data)
|
||||
const generateStatusDetails = (): IStatusHistoryPoint[] => {
|
||||
const details: IStatusHistoryPoint[] = [];
|
||||
const now = new Date();
|
||||
|
||||
for (let i = 47; i >= 0; i--) {
|
||||
const date = new Date(now);
|
||||
date.setMinutes(0, 0, 0);
|
||||
date.setHours(date.getHours() - i);
|
||||
|
||||
let status: 'operational' | 'degraded' | 'outage' = 'operational';
|
||||
let value = 100;
|
||||
|
||||
// Simulate the EU-West issues from 6-3 hours ago
|
||||
if (i >= 3 && i <= 6) {
|
||||
status = 'degraded';
|
||||
value = 85 + Math.random() * 10;
|
||||
} else if (i > 6 && i <= 12) {
|
||||
// Some minor issues earlier
|
||||
if (Math.random() > 0.8) {
|
||||
status = 'degraded';
|
||||
value = 90 + Math.random() * 10;
|
||||
}
|
||||
}
|
||||
|
||||
details.push({
|
||||
timestamp: date.getTime(),
|
||||
status,
|
||||
responseTime: status === 'operational' ? 20 + Math.random() * 30 : 50 + Math.random() * 100
|
||||
});
|
||||
}
|
||||
|
||||
return details;
|
||||
};
|
||||
|
||||
statusDetails.dataPoints = generateStatusDetails();
|
||||
statusDetails.serviceId = 'eu-west-database';
|
||||
statusDetails.serviceName = 'EU-West Database';
|
||||
|
||||
// Configure Monthly Status
|
||||
const generateMonthlyData = (): IMonthlyUptime[] => {
|
||||
const months: IMonthlyUptime[] = [];
|
||||
const now = new Date();
|
||||
|
||||
for (let m = 4; m >= 0; m--) {
|
||||
const monthDate = new Date(now.getFullYear(), now.getMonth() - m, 1);
|
||||
const daysInMonth = new Date(monthDate.getFullYear(), monthDate.getMonth() + 1, 0).getDate();
|
||||
const monthKey = monthDate.toISOString().slice(0, 7);
|
||||
|
||||
const days = [];
|
||||
let totalUptime = 0;
|
||||
let incidents = 0;
|
||||
|
||||
for (let d = 1; d <= daysInMonth; d++) {
|
||||
const dayDate = new Date(monthDate.getFullYear(), monthDate.getMonth(), d);
|
||||
const isToday = dayDate.toDateString() === now.toDateString();
|
||||
const isFuture = dayDate > now;
|
||||
|
||||
if (isFuture) continue;
|
||||
|
||||
let status: 'operational' | 'degraded' | 'partial_outage' | 'major_outage' = 'operational';
|
||||
let uptime = 100;
|
||||
let dayIncidents = 0;
|
||||
|
||||
// Add some random incidents
|
||||
if (!isToday && Math.random() > 0.92) {
|
||||
status = 'degraded';
|
||||
uptime = 95 + Math.random() * 4;
|
||||
dayIncidents = 1;
|
||||
} else if (!isToday && Math.random() > 0.98) {
|
||||
status = 'partial_outage';
|
||||
uptime = 80 + Math.random() * 15;
|
||||
dayIncidents = 2;
|
||||
}
|
||||
|
||||
// Today's incident
|
||||
if (isToday) {
|
||||
status = 'degraded';
|
||||
uptime = 96.5;
|
||||
dayIncidents = 1;
|
||||
}
|
||||
|
||||
days.push({
|
||||
date: dayDate.toISOString().slice(0, 10),
|
||||
status,
|
||||
uptime,
|
||||
incidents: dayIncidents,
|
||||
totalDowntime: Math.round((100 - uptime) * 14.4) // Convert to minutes (1440 minutes per day)
|
||||
});
|
||||
|
||||
totalUptime += uptime;
|
||||
incidents += dayIncidents;
|
||||
}
|
||||
|
||||
months.push({
|
||||
month: monthKey,
|
||||
days,
|
||||
overallUptime: totalUptime / days.length,
|
||||
totalIncidents: incidents
|
||||
});
|
||||
}
|
||||
|
||||
return months;
|
||||
};
|
||||
|
||||
statusMonth.monthlyData = generateMonthlyData();
|
||||
statusMonth.serviceId = 'all-services';
|
||||
statusMonth.serviceName = 'All Services';
|
||||
|
||||
// Configure Incidents
|
||||
const currentIncidents: IIncidentDetails[] = [
|
||||
{
|
||||
id: 'inc-2024-001',
|
||||
title: 'EU-West Database Performance Degradation',
|
||||
impact: 'Users in EU-West region may experience slower database queries and occasional timeouts',
|
||||
severity: 'major',
|
||||
status: 'investigating',
|
||||
startTime: Date.now() - 3 * 60 * 60 * 1000, // 3 hours ago
|
||||
affectedServices: ['EU-West Database', 'EU-West Compute', 'EU-West Storage'],
|
||||
updates: [
|
||||
{
|
||||
id: 'update-1',
|
||||
timestamp: Date.now() - 3 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'We are investigating reports of database performance issues in the EU-West region.',
|
||||
author: 'CloudFlow Operations'
|
||||
},
|
||||
{
|
||||
id: 'update-2',
|
||||
timestamp: Date.now() - 2.5 * 60 * 60 * 1000,
|
||||
status: 'identified',
|
||||
message: 'We have identified unusual load patterns on our EU-West database cluster. Our team is working on redistributing the load.',
|
||||
author: 'Database Team'
|
||||
},
|
||||
{
|
||||
id: 'update-3',
|
||||
timestamp: Date.now() - 1 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Load balancing adjustments have been applied. We are monitoring the situation closely. Performance is gradually improving.',
|
||||
author: 'CloudFlow Operations'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const pastIncidents: IIncidentDetails[] = [
|
||||
{
|
||||
id: 'inc-2023-098',
|
||||
title: 'Global Authentication Service Outage',
|
||||
impact: 'Users were unable to log in to their accounts',
|
||||
severity: 'critical',
|
||||
status: 'resolved',
|
||||
startTime: Date.now() - 7 * 24 * 60 * 60 * 1000, // 7 days ago
|
||||
endTime: Date.now() - 7 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000, // 2 hour duration
|
||||
affectedServices: ['Authentication Service', 'User Dashboard', 'API Gateway'],
|
||||
rootCause: 'A configuration change in our authentication service caused a cascading failure in the token validation system.',
|
||||
resolution: 'The configuration was rolled back and additional safeguards were implemented to prevent similar issues.',
|
||||
updates: [
|
||||
{
|
||||
id: 'update-4',
|
||||
timestamp: Date.now() - 7 * 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Multiple reports of login failures across all regions.',
|
||||
author: 'CloudFlow Operations'
|
||||
},
|
||||
{
|
||||
id: 'update-5',
|
||||
timestamp: Date.now() - 7 * 24 * 60 * 60 * 1000 + 30 * 60 * 1000,
|
||||
status: 'identified',
|
||||
message: 'Root cause identified as misconfiguration in auth service. Rolling back changes.',
|
||||
author: 'Security Team'
|
||||
},
|
||||
{
|
||||
id: 'update-6',
|
||||
timestamp: Date.now() - 7 * 24 * 60 * 60 * 1000 + 90 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Service restored. Monitoring for any lingering issues.',
|
||||
author: 'CloudFlow Operations'
|
||||
},
|
||||
{
|
||||
id: 'update-7',
|
||||
timestamp: Date.now() - 7 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000,
|
||||
status: 'resolved',
|
||||
message: 'All systems operating normally. Incident resolved.',
|
||||
author: 'CloudFlow Operations'
|
||||
},
|
||||
{
|
||||
id: 'update-8',
|
||||
timestamp: Date.now() - 6 * 24 * 60 * 60 * 1000,
|
||||
status: 'postmortem',
|
||||
message: 'Postmortem completed. Action items identified and assigned to prevent recurrence.',
|
||||
author: 'Engineering Lead'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'inc-2023-095',
|
||||
title: 'US-East Storage Service Maintenance',
|
||||
impact: 'Reduced redundancy for stored objects during maintenance window',
|
||||
severity: 'minor',
|
||||
status: 'resolved',
|
||||
startTime: Date.now() - 14 * 24 * 60 * 60 * 1000,
|
||||
endTime: Date.now() - 14 * 24 * 60 * 60 * 1000 + 4 * 60 * 60 * 1000,
|
||||
affectedServices: ['US-East Storage'],
|
||||
rootCause: 'Scheduled maintenance for storage infrastructure upgrade.',
|
||||
resolution: 'Maintenance completed successfully. All systems operating at full redundancy.',
|
||||
updates: [
|
||||
{
|
||||
id: 'update-9',
|
||||
timestamp: Date.now() - 21 * 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Scheduled maintenance announced for US-East Storage service.',
|
||||
author: 'CloudFlow Operations'
|
||||
},
|
||||
{
|
||||
id: 'update-10',
|
||||
timestamp: Date.now() - 14 * 24 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Maintenance window has begun. No customer impact expected.',
|
||||
author: 'Storage Team'
|
||||
},
|
||||
{
|
||||
id: 'update-11',
|
||||
timestamp: Date.now() - 14 * 24 * 60 * 60 * 1000 + 4 * 60 * 60 * 1000,
|
||||
status: 'resolved',
|
||||
message: 'Maintenance completed successfully.',
|
||||
author: 'Storage Team'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'inc-2023-089',
|
||||
title: 'API Gateway Rate Limiting Issues',
|
||||
impact: 'Some API requests were incorrectly rate limited',
|
||||
severity: 'major',
|
||||
status: 'resolved',
|
||||
startTime: Date.now() - 30 * 24 * 60 * 60 * 1000,
|
||||
endTime: Date.now() - 30 * 24 * 60 * 60 * 1000 + 45 * 60 * 1000,
|
||||
affectedServices: ['API Gateway'],
|
||||
rootCause: 'A bug in the rate limiting algorithm caused legitimate requests to be blocked.',
|
||||
resolution: 'Hotfix deployed to correct the rate limiting logic.',
|
||||
updates: [
|
||||
{
|
||||
id: 'update-12',
|
||||
timestamp: Date.now() - 30 * 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Reports of API requests being blocked despite being within rate limits.',
|
||||
author: 'API Team'
|
||||
},
|
||||
{
|
||||
id: 'update-13',
|
||||
timestamp: Date.now() - 30 * 24 * 60 * 60 * 1000 + 20 * 60 * 1000,
|
||||
status: 'identified',
|
||||
message: 'Bug identified in rate limiting code. Preparing hotfix.',
|
||||
author: 'API Team'
|
||||
},
|
||||
{
|
||||
id: 'update-14',
|
||||
timestamp: Date.now() - 30 * 24 * 60 * 60 * 1000 + 45 * 60 * 1000,
|
||||
status: 'resolved',
|
||||
message: 'Hotfix deployed. Rate limiting now functioning correctly.',
|
||||
author: 'API Team'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
incidents.currentIncidents = currentIncidents;
|
||||
incidents.pastIncidents = pastIncidents;
|
||||
|
||||
// Configure Footer
|
||||
footer.companyName = 'CloudFlow Infrastructure';
|
||||
footer.legalUrl = 'https://cloudflow.example.com/legal';
|
||||
footer.supportEmail = 'support@cloudflow.example.com';
|
||||
footer.statusPageUrl = 'https://status.cloudflow.example.com';
|
||||
footer.lastUpdated = Date.now();
|
||||
footer.currentYear = new Date().getFullYear();
|
||||
footer.socialLinks = [
|
||||
{ platform: 'twitter', url: 'https://twitter.com/cloudflow' },
|
||||
{ platform: 'github', url: 'https://github.com/cloudflow' },
|
||||
{ platform: 'linkedin', url: 'https://linkedin.com/company/cloudflow' }
|
||||
];
|
||||
footer.rssFeedUrl = 'https://status.cloudflow.example.com/rss';
|
||||
footer.apiStatusUrl = 'https://api.cloudflow.example.com/v1/status';
|
||||
footer.enableSubscribe = true;
|
||||
footer.subscriberCount = 2847;
|
||||
footer.additionalLinks = [
|
||||
{ label: 'API Documentation', url: 'https://docs.cloudflow.example.com' },
|
||||
{ label: 'Service SLA', url: 'https://cloudflow.example.com/sla' },
|
||||
{ label: 'Privacy Policy', url: 'https://cloudflow.example.com/privacy' }
|
||||
];
|
||||
|
||||
// Add event listeners for interactivity
|
||||
header.addEventListener('reportNewIncident', () => {
|
||||
alert('Report Incident: This would open a form to report a new incident.');
|
||||
});
|
||||
|
||||
header.addEventListener('statusSubscribe', () => {
|
||||
alert('Subscribe: This would open a subscription form for status updates.');
|
||||
});
|
||||
|
||||
footer.addEventListener('subscribeClick', () => {
|
||||
alert('Subscribe to updates: Enter your email for status notifications.');
|
||||
});
|
||||
|
||||
assetsSelector.addEventListener('selectionChanged', (event: CustomEvent) => {
|
||||
console.log('Selected services changed:', event.detail.selectedServices);
|
||||
// In a real app, this would update the other components to show only selected services
|
||||
});
|
||||
|
||||
statusMonth.addEventListener('dayClick', (event: CustomEvent) => {
|
||||
console.log('Day clicked:', event.detail);
|
||||
alert(`Day details: ${event.detail.date}\nUptime: ${event.detail.uptime}%\nIncidents: ${event.detail.incidents}`);
|
||||
});
|
||||
|
||||
// Simulate real-time updates
|
||||
setInterval(() => {
|
||||
// Update last checked times
|
||||
services.forEach(service => {
|
||||
service.lastChecked = Date.now();
|
||||
// Randomly change response times
|
||||
service.responseTime = service.responseTime * (0.9 + Math.random() * 0.2);
|
||||
});
|
||||
assetsSelector.requestUpdate();
|
||||
|
||||
// Update overall status last updated
|
||||
statusBar.overallStatus = { ...statusBar.overallStatus, lastUpdated: Date.now() };
|
||||
|
||||
// Update footer last updated
|
||||
footer.lastUpdated = Date.now();
|
||||
}, 30000); // Every 30 seconds
|
||||
}}
|
||||
>
|
||||
<upl-statuspage-header></upl-statuspage-header>
|
||||
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
||||
<upl-statuspage-assetsselector></upl-statuspage-assetsselector>
|
||||
<upl-statuspage-statusdetails></upl-statuspage-statusdetails>
|
||||
<upl-statuspage-statusmonth></upl-statuspage-statusmonth>
|
||||
<upl-statuspage-incidents></upl-statuspage-incidents>
|
||||
<upl-statuspage-footer></upl-statuspage-footer>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
`;
|
||||
575
ts_web/pages/statuspage-maintenance.ts
Normal file
575
ts_web/pages/statuspage-maintenance.ts
Normal file
@@ -0,0 +1,575 @@
|
||||
import { html, cssManager } from "@design.estate/dees-element";
|
||||
import type { IServiceStatus, IOverallStatus, IIncidentDetails, IStatusHistoryPoint, IMonthlyUptime } from '../interfaces/index.js';
|
||||
|
||||
export const statuspageMaintenance = () => html`
|
||||
<style>
|
||||
.demo-page-wrapper {
|
||||
min-height: 100vh;
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
}
|
||||
|
||||
.demo-info {
|
||||
padding: 20px;
|
||||
background: #2196F3;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-family: 'Geist Sans', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.demo-info h3 {
|
||||
margin: 0 0 10px 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
.demo-info p {
|
||||
margin: 0;
|
||||
opacity: 0.9;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="demo-page-wrapper">
|
||||
<div class="demo-info">
|
||||
<h3>Scheduled Maintenance</h3>
|
||||
<p>This demo shows a status page during a scheduled maintenance window with some services offline.</p>
|
||||
</div>
|
||||
|
||||
<dees-demowrapper
|
||||
.runAfterRender=${async (wrapperElement: any) => {
|
||||
const header = wrapperElement.querySelector('upl-statuspage-header') as any;
|
||||
const statusBar = wrapperElement.querySelector('upl-statuspage-statusbar') as any;
|
||||
const assetsSelector = wrapperElement.querySelector('upl-statuspage-assetsselector') as any;
|
||||
const statusDetails = wrapperElement.querySelector('upl-statuspage-statusdetails') as any;
|
||||
const statusMonth = wrapperElement.querySelector('upl-statuspage-statusmonth') as any;
|
||||
const incidents = wrapperElement.querySelector('upl-statuspage-incidents') as any;
|
||||
const footer = wrapperElement.querySelector('upl-statuspage-footer') as any;
|
||||
|
||||
// Configure Header
|
||||
header.pageTitle = 'SecureVault Infrastructure Status';
|
||||
header.showReportButton = true;
|
||||
header.showSubscribeButton = true;
|
||||
header.logoUrl = 'https://via.placeholder.com/150x50/2196F3/ffffff?text=SecureVault';
|
||||
header.customStyles = true;
|
||||
header.brandColor = '#2196F3';
|
||||
|
||||
// Configure Overall Status - Maintenance
|
||||
statusBar.overallStatus = {
|
||||
status: 'maintenance',
|
||||
message: 'Scheduled maintenance in progress - Expected completion: 2:00 AM UTC',
|
||||
lastUpdated: Date.now(),
|
||||
affectedServices: 5,
|
||||
totalServices: 14
|
||||
};
|
||||
|
||||
// Configure Services - Mix of maintenance and operational
|
||||
const services: IServiceStatus[] = [
|
||||
// Core Services - Some under maintenance
|
||||
{
|
||||
id: 'web-app',
|
||||
name: 'web-app',
|
||||
displayName: 'Web Application',
|
||||
description: 'Customer portal',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.92,
|
||||
uptime90d: 99.89,
|
||||
responseTime: 45,
|
||||
category: 'Frontend',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'mobile-api',
|
||||
name: 'mobile-api',
|
||||
displayName: 'Mobile API',
|
||||
description: 'Mobile app backend',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.88,
|
||||
uptime90d: 99.85,
|
||||
responseTime: 62,
|
||||
category: 'Frontend',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'auth-service',
|
||||
name: 'auth-service',
|
||||
displayName: 'Authentication Service',
|
||||
description: 'User authentication',
|
||||
currentStatus: 'maintenance',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.5,
|
||||
uptime90d: 99.7,
|
||||
responseTime: 0,
|
||||
category: 'Core Services',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'api-gateway',
|
||||
name: 'api-gateway',
|
||||
displayName: 'API Gateway',
|
||||
description: 'Main API endpoint',
|
||||
currentStatus: 'degraded',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.2,
|
||||
uptime90d: 99.4,
|
||||
responseTime: 125,
|
||||
category: 'Core Services',
|
||||
selected: true
|
||||
},
|
||||
// Database Services
|
||||
{
|
||||
id: 'primary-db',
|
||||
name: 'primary-db',
|
||||
displayName: 'Primary Database',
|
||||
description: 'Main database cluster',
|
||||
currentStatus: 'maintenance',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.6,
|
||||
uptime90d: 99.7,
|
||||
responseTime: 0,
|
||||
category: 'Data Storage',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'replica-db',
|
||||
name: 'replica-db',
|
||||
displayName: 'Database Replicas',
|
||||
description: 'Read replicas (read-only mode)',
|
||||
currentStatus: 'degraded',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.7,
|
||||
uptime90d: 99.8,
|
||||
responseTime: 85,
|
||||
category: 'Data Storage',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'cache',
|
||||
name: 'cache',
|
||||
displayName: 'Cache Service',
|
||||
description: 'Redis cache layer',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.95,
|
||||
uptime90d: 99.93,
|
||||
responseTime: 8,
|
||||
category: 'Data Storage',
|
||||
selected: false
|
||||
},
|
||||
// Backup and Storage
|
||||
{
|
||||
id: 'backup-service',
|
||||
name: 'backup-service',
|
||||
displayName: 'Backup Service',
|
||||
description: 'Automated backups',
|
||||
currentStatus: 'maintenance',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.8,
|
||||
uptime90d: 99.85,
|
||||
responseTime: 0,
|
||||
category: 'Operations',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'file-storage',
|
||||
name: 'file-storage',
|
||||
displayName: 'File Storage',
|
||||
description: 'Object storage service',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.99,
|
||||
uptime90d: 99.98,
|
||||
responseTime: 42,
|
||||
category: 'Operations',
|
||||
selected: false
|
||||
},
|
||||
// Monitoring and Support
|
||||
{
|
||||
id: 'monitoring',
|
||||
name: 'monitoring',
|
||||
displayName: 'Monitoring System',
|
||||
description: 'System monitoring',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.9,
|
||||
uptime90d: 99.88,
|
||||
responseTime: 32,
|
||||
category: 'Support',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'logging',
|
||||
name: 'logging',
|
||||
displayName: 'Logging Service',
|
||||
description: 'Centralized logs',
|
||||
currentStatus: 'maintenance',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.7,
|
||||
uptime90d: 99.75,
|
||||
responseTime: 0,
|
||||
category: 'Support',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'alerting',
|
||||
name: 'alerting',
|
||||
displayName: 'Alerting System',
|
||||
description: 'Alert notifications',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.85,
|
||||
uptime90d: 99.82,
|
||||
responseTime: 28,
|
||||
category: 'Support',
|
||||
selected: false
|
||||
},
|
||||
// Communication Services
|
||||
{
|
||||
id: 'email',
|
||||
name: 'email',
|
||||
displayName: 'Email Service',
|
||||
description: 'Transactional emails',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.6,
|
||||
uptime90d: 99.55,
|
||||
responseTime: 142,
|
||||
category: 'Communication',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'webhooks',
|
||||
name: 'webhooks',
|
||||
displayName: 'Webhook Delivery',
|
||||
description: 'Webhook notifications',
|
||||
currentStatus: 'maintenance',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.4,
|
||||
uptime90d: 99.45,
|
||||
responseTime: 0,
|
||||
category: 'Communication',
|
||||
selected: false
|
||||
}
|
||||
];
|
||||
|
||||
assetsSelector.services = services;
|
||||
|
||||
// Configure Status Details - Showing maintenance period
|
||||
const generateStatusDetails = (): IStatusHistoryPoint[] => {
|
||||
const details: IStatusHistoryPoint[] = [];
|
||||
const now = new Date();
|
||||
const maintenanceStarted = 2; // 2 hours ago
|
||||
|
||||
for (let i = 47; i >= 0; i--) {
|
||||
const date = new Date(now);
|
||||
date.setMinutes(0, 0, 0);
|
||||
date.setHours(date.getHours() - i);
|
||||
|
||||
let status: 'operational' | 'degraded' | 'outage' = 'operational';
|
||||
let value = 100;
|
||||
let responseTime = 25;
|
||||
|
||||
// Maintenance window
|
||||
if (i <= maintenanceStarted) {
|
||||
status = 'degraded';
|
||||
value = 60;
|
||||
responseTime = 0;
|
||||
} else if (i <= maintenanceStarted + 2) {
|
||||
// Pre-maintenance prep
|
||||
status = 'degraded';
|
||||
value = 85;
|
||||
responseTime = 80;
|
||||
}
|
||||
|
||||
details.push({
|
||||
timestamp: date.getTime(),
|
||||
status,
|
||||
responseTime
|
||||
});
|
||||
}
|
||||
|
||||
return details;
|
||||
};
|
||||
|
||||
statusDetails.dataPoints = generateStatusDetails();
|
||||
statusDetails.serviceId = 'primary-db';
|
||||
statusDetails.serviceName = 'Primary Database';
|
||||
|
||||
// Configure Monthly Status - Good uptime with scheduled maintenance windows
|
||||
const generateMonthlyData = (): IMonthlyUptime[] => {
|
||||
const months: IMonthlyUptime[] = [];
|
||||
const now = new Date();
|
||||
|
||||
for (let m = 4; m >= 0; m--) {
|
||||
const monthDate = new Date(now.getFullYear(), now.getMonth() - m, 1);
|
||||
const daysInMonth = new Date(monthDate.getFullYear(), monthDate.getMonth() + 1, 0).getDate();
|
||||
const monthKey = monthDate.toISOString().slice(0, 7);
|
||||
|
||||
const days = [];
|
||||
let totalUptime = 0;
|
||||
let incidents = 0;
|
||||
|
||||
for (let d = 1; d <= daysInMonth; d++) {
|
||||
const dayDate = new Date(monthDate.getFullYear(), monthDate.getMonth(), d);
|
||||
const isToday = dayDate.toDateString() === now.toDateString();
|
||||
const isFuture = dayDate > now;
|
||||
const isFirstSunday = dayDate.getDay() === 0 && d <= 7;
|
||||
|
||||
if (isFuture) continue;
|
||||
|
||||
let status: 'operational' | 'degraded' | 'partial_outage' | 'major_outage' = 'operational';
|
||||
let uptime = 100;
|
||||
let dayIncidents = 0;
|
||||
|
||||
// Today - maintenance
|
||||
if (isToday) {
|
||||
status = 'degraded';
|
||||
uptime = 92; // 2 hours of maintenance = 8% downtime
|
||||
dayIncidents = 0; // Maintenance is not an incident
|
||||
} else if (isFirstSunday) {
|
||||
// Monthly maintenance on first Sunday
|
||||
status = 'degraded';
|
||||
uptime = 96; // 1 hour maintenance
|
||||
dayIncidents = 0;
|
||||
} else if (Math.random() > 0.95) {
|
||||
// Occasional issues
|
||||
status = 'degraded';
|
||||
uptime = 98 + Math.random() * 2;
|
||||
dayIncidents = 1;
|
||||
}
|
||||
|
||||
days.push({
|
||||
date: dayDate.toISOString().slice(0, 10),
|
||||
status,
|
||||
uptime,
|
||||
incidents: dayIncidents,
|
||||
totalDowntime: Math.round((100 - uptime) * 14.4)
|
||||
});
|
||||
|
||||
totalUptime += uptime;
|
||||
incidents += dayIncidents;
|
||||
}
|
||||
|
||||
months.push({
|
||||
month: monthKey,
|
||||
days,
|
||||
overallUptime: totalUptime / days.length,
|
||||
totalIncidents: incidents
|
||||
});
|
||||
}
|
||||
|
||||
return months;
|
||||
};
|
||||
|
||||
statusMonth.monthlyData = generateMonthlyData();
|
||||
statusMonth.serviceId = 'all-services';
|
||||
statusMonth.serviceName = 'All Services';
|
||||
|
||||
// Configure Incidents - Current maintenance
|
||||
const currentIncidents: IIncidentDetails[] = [
|
||||
{
|
||||
id: 'maint-2024-001',
|
||||
title: 'Scheduled Database Maintenance',
|
||||
impact: 'Database will be in read-only mode. Some features may be temporarily unavailable.',
|
||||
severity: 'minor',
|
||||
status: 'monitoring',
|
||||
startTime: Date.now() - 2 * 60 * 60 * 1000,
|
||||
affectedServices: ['Primary Database', 'Authentication Service', 'Backup Service', 'Logging Service', 'Webhook Delivery'],
|
||||
updates: [
|
||||
{
|
||||
id: 'update-1',
|
||||
timestamp: Date.now() - 7 * 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Scheduled maintenance has been announced for database upgrades and security patches.',
|
||||
author: 'Operations Team'
|
||||
},
|
||||
{
|
||||
id: 'update-2',
|
||||
timestamp: Date.now() - 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Reminder: Database maintenance scheduled for tomorrow at 12:00 AM UTC.',
|
||||
author: 'Operations Team'
|
||||
},
|
||||
{
|
||||
id: 'update-3',
|
||||
timestamp: Date.now() - 2 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Maintenance window has begun. Database is now in read-only mode.',
|
||||
author: 'Database Team'
|
||||
},
|
||||
{
|
||||
id: 'update-4',
|
||||
timestamp: Date.now() - 1.5 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Security patches applied successfully. Beginning database schema updates.',
|
||||
author: 'Database Team'
|
||||
},
|
||||
{
|
||||
id: 'update-5',
|
||||
timestamp: Date.now() - 1 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Schema updates 50% complete. Everything proceeding as planned.',
|
||||
author: 'Database Team'
|
||||
},
|
||||
{
|
||||
id: 'update-6',
|
||||
timestamp: Date.now() - 30 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Final testing phase. Services will begin coming back online shortly.',
|
||||
author: 'Operations Team'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const pastIncidents: IIncidentDetails[] = [
|
||||
{
|
||||
id: 'maint-2024-prev-001',
|
||||
title: 'Previous Monthly Maintenance',
|
||||
impact: 'Services were in maintenance mode for 1 hour',
|
||||
severity: 'minor',
|
||||
status: 'resolved',
|
||||
startTime: Date.now() - 30 * 24 * 60 * 60 * 1000,
|
||||
endTime: Date.now() - 30 * 24 * 60 * 60 * 1000 + 60 * 60 * 1000,
|
||||
affectedServices: ['Primary Database', 'Backup Service'],
|
||||
rootCause: 'Scheduled monthly maintenance for security updates.',
|
||||
resolution: 'Maintenance completed successfully with all updates applied.',
|
||||
updates: [
|
||||
{
|
||||
id: 'update-7',
|
||||
timestamp: Date.now() - 30 * 24 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Monthly maintenance started.',
|
||||
author: 'Operations Team'
|
||||
},
|
||||
{
|
||||
id: 'update-8',
|
||||
timestamp: Date.now() - 30 * 24 * 60 * 60 * 1000 + 60 * 60 * 1000,
|
||||
status: 'resolved',
|
||||
message: 'Maintenance completed successfully.',
|
||||
author: 'Operations Team'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'inc-2024-001',
|
||||
title: 'API Gateway Performance Issues',
|
||||
impact: 'Slow API responses for some users',
|
||||
severity: 'minor',
|
||||
status: 'resolved',
|
||||
startTime: Date.now() - 15 * 24 * 60 * 60 * 1000,
|
||||
endTime: Date.now() - 15 * 24 * 60 * 60 * 1000 + 45 * 60 * 1000,
|
||||
affectedServices: ['API Gateway'],
|
||||
rootCause: 'Memory leak in API Gateway service.',
|
||||
resolution: 'Service restarted and patch applied.',
|
||||
updates: [
|
||||
{
|
||||
id: 'update-9',
|
||||
timestamp: Date.now() - 15 * 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Investigating reports of slow API responses.',
|
||||
author: 'API Team'
|
||||
},
|
||||
{
|
||||
id: 'update-10',
|
||||
timestamp: Date.now() - 15 * 24 * 60 * 60 * 1000 + 30 * 60 * 1000,
|
||||
status: 'identified',
|
||||
message: 'Memory leak identified. Preparing fix.',
|
||||
author: 'API Team'
|
||||
},
|
||||
{
|
||||
id: 'update-11',
|
||||
timestamp: Date.now() - 15 * 24 * 60 * 60 * 1000 + 45 * 60 * 1000,
|
||||
status: 'resolved',
|
||||
message: 'Fix applied. Performance back to normal.',
|
||||
author: 'API Team'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'maint-2023-012',
|
||||
title: 'Year-End Infrastructure Upgrade',
|
||||
impact: 'Planned downtime for major infrastructure improvements',
|
||||
severity: 'major',
|
||||
status: 'resolved',
|
||||
startTime: Date.now() - 60 * 24 * 60 * 60 * 1000,
|
||||
endTime: Date.now() - 60 * 24 * 60 * 60 * 1000 + 4 * 60 * 60 * 1000,
|
||||
affectedServices: ['All Services'],
|
||||
rootCause: 'Annual infrastructure upgrade and capacity expansion.',
|
||||
resolution: 'All upgrades completed successfully. System capacity increased by 50%.',
|
||||
updates: [
|
||||
{
|
||||
id: 'update-12',
|
||||
timestamp: Date.now() - 67 * 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Year-end maintenance scheduled for next week.',
|
||||
author: 'CTO'
|
||||
},
|
||||
{
|
||||
id: 'update-13',
|
||||
timestamp: Date.now() - 60 * 24 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Maintenance window started. All services going offline.',
|
||||
author: 'Operations Team'
|
||||
},
|
||||
{
|
||||
id: 'update-14',
|
||||
timestamp: Date.now() - 60 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Hardware upgrades complete. Software updates in progress.',
|
||||
author: 'Infrastructure Team'
|
||||
},
|
||||
{
|
||||
id: 'update-15',
|
||||
timestamp: Date.now() - 60 * 24 * 60 * 60 * 1000 + 4 * 60 * 60 * 1000,
|
||||
status: 'resolved',
|
||||
message: 'All systems back online. Performance improvements confirmed.',
|
||||
author: 'Operations Team'
|
||||
},
|
||||
{
|
||||
id: 'update-16',
|
||||
timestamp: Date.now() - 59 * 24 * 60 * 60 * 1000,
|
||||
status: 'postmortem',
|
||||
message: 'Maintenance report published. 50% capacity increase achieved.',
|
||||
author: 'Engineering Team'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
incidents.currentIncidents = currentIncidents;
|
||||
incidents.pastIncidents = pastIncidents;
|
||||
|
||||
// Configure Footer
|
||||
footer.companyName = 'SecureVault Infrastructure';
|
||||
footer.legalUrl = 'https://securevault.example.com/legal';
|
||||
footer.supportEmail = 'support@securevault.example.com';
|
||||
footer.statusPageUrl = 'https://status.securevault.example.com';
|
||||
footer.lastUpdated = Date.now();
|
||||
footer.currentYear = new Date().getFullYear();
|
||||
footer.socialLinks = [
|
||||
{ platform: 'twitter', url: 'https://twitter.com/securevault' },
|
||||
{ platform: 'linkedin', url: 'https://linkedin.com/company/securevault' }
|
||||
];
|
||||
footer.rssFeedUrl = 'https://status.securevault.example.com/rss';
|
||||
footer.apiStatusUrl = 'https://api.securevault.example.com/v1/status';
|
||||
footer.enableSubscribe = true;
|
||||
footer.subscriberCount = 3892;
|
||||
footer.additionalLinks = [
|
||||
{ label: 'Maintenance Schedule', url: 'https://securevault.example.com/maintenance' },
|
||||
{ label: 'API Documentation', url: 'https://docs.securevault.example.com' },
|
||||
{ label: 'Support Portal', url: 'https://support.securevault.example.com' }
|
||||
];
|
||||
footer.latestStatusUpdate = 'Database maintenance 50% complete - On track for 2:00 AM UTC completion';
|
||||
}}
|
||||
>
|
||||
<upl-statuspage-header></upl-statuspage-header>
|
||||
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
||||
<upl-statuspage-assetsselector></upl-statuspage-assetsselector>
|
||||
<upl-statuspage-statusdetails></upl-statuspage-statusdetails>
|
||||
<upl-statuspage-statusmonth></upl-statuspage-statusmonth>
|
||||
<upl-statuspage-incidents></upl-statuspage-incidents>
|
||||
<upl-statuspage-footer></upl-statuspage-footer>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
`;
|
||||
573
ts_web/pages/statuspage-outage.ts
Normal file
573
ts_web/pages/statuspage-outage.ts
Normal file
@@ -0,0 +1,573 @@
|
||||
import { html, cssManager } from "@design.estate/dees-element";
|
||||
import type { IServiceStatus, IOverallStatus, IIncidentDetails, IStatusHistoryPoint, IMonthlyUptime } from '../interfaces/index.js';
|
||||
|
||||
export const statuspageOutage = () => html`
|
||||
<style>
|
||||
.demo-page-wrapper {
|
||||
min-height: 100vh;
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
}
|
||||
|
||||
.demo-info {
|
||||
padding: 20px;
|
||||
background: #F44336;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-family: 'Geist Sans', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.demo-info h3 {
|
||||
margin: 0 0 10px 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
.demo-info p {
|
||||
margin: 0;
|
||||
opacity: 0.9;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="demo-page-wrapper">
|
||||
<div class="demo-info">
|
||||
<h3>Major Outage Scenario</h3>
|
||||
<p>This demo shows a critical situation with multiple services experiencing major outages.</p>
|
||||
</div>
|
||||
|
||||
<dees-demowrapper
|
||||
.runAfterRender=${async (wrapperElement: any) => {
|
||||
const header = wrapperElement.querySelector('upl-statuspage-header') as any;
|
||||
const statusBar = wrapperElement.querySelector('upl-statuspage-statusbar') as any;
|
||||
const assetsSelector = wrapperElement.querySelector('upl-statuspage-assetsselector') as any;
|
||||
const statusDetails = wrapperElement.querySelector('upl-statuspage-statusdetails') as any;
|
||||
const statusMonth = wrapperElement.querySelector('upl-statuspage-statusmonth') as any;
|
||||
const incidents = wrapperElement.querySelector('upl-statuspage-incidents') as any;
|
||||
const footer = wrapperElement.querySelector('upl-statuspage-footer') as any;
|
||||
|
||||
// Configure Header
|
||||
header.pageTitle = 'DataStream Platform Status';
|
||||
header.showReportButton = true;
|
||||
header.showSubscribeButton = true;
|
||||
header.logoUrl = 'https://via.placeholder.com/150x50/F44336/ffffff?text=DataStream';
|
||||
header.customStyles = true;
|
||||
header.brandColor = '#F44336';
|
||||
|
||||
// Configure Overall Status - Major Outage
|
||||
statusBar.overallStatus = {
|
||||
status: 'major_outage',
|
||||
message: 'Major service disruption affecting multiple regions',
|
||||
lastUpdated: Date.now(),
|
||||
affectedServices: 8,
|
||||
totalServices: 15
|
||||
};
|
||||
|
||||
// Configure Services - Multiple Outages
|
||||
const services: IServiceStatus[] = [
|
||||
// Core Services - Major Outage
|
||||
{
|
||||
id: 'api-gateway',
|
||||
name: 'api-gateway',
|
||||
displayName: 'API Gateway',
|
||||
description: 'Main API endpoint',
|
||||
currentStatus: 'major_outage',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 85.2,
|
||||
uptime90d: 92.5,
|
||||
responseTime: 2500,
|
||||
category: 'Core Infrastructure',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'auth-service',
|
||||
name: 'auth-service',
|
||||
displayName: 'Authentication',
|
||||
description: 'Login and authorization',
|
||||
currentStatus: 'major_outage',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 84.8,
|
||||
uptime90d: 91.2,
|
||||
responseTime: 3200,
|
||||
category: 'Core Infrastructure',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'web-portal',
|
||||
name: 'web-portal',
|
||||
displayName: 'Web Portal',
|
||||
description: 'Customer web interface',
|
||||
currentStatus: 'partial_outage',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 88.5,
|
||||
uptime90d: 94.2,
|
||||
responseTime: 1800,
|
||||
category: 'Frontend',
|
||||
selected: true
|
||||
},
|
||||
// Database Services - Critical
|
||||
{
|
||||
id: 'primary-db',
|
||||
name: 'primary-db',
|
||||
displayName: 'Primary Database',
|
||||
description: 'Main data storage',
|
||||
currentStatus: 'major_outage',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 82.1,
|
||||
uptime90d: 90.5,
|
||||
responseTime: 5000,
|
||||
category: 'Data Layer',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'replica-db',
|
||||
name: 'replica-db',
|
||||
displayName: 'Database Replicas',
|
||||
description: 'Read replicas',
|
||||
currentStatus: 'partial_outage',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 86.7,
|
||||
uptime90d: 93.1,
|
||||
responseTime: 2200,
|
||||
category: 'Data Layer',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'cache-layer',
|
||||
name: 'cache-layer',
|
||||
displayName: 'Cache Layer',
|
||||
description: 'Redis cache',
|
||||
currentStatus: 'degraded',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 92.3,
|
||||
uptime90d: 95.8,
|
||||
responseTime: 450,
|
||||
category: 'Data Layer',
|
||||
selected: true
|
||||
},
|
||||
// Regional Services
|
||||
{
|
||||
id: 'us-east',
|
||||
name: 'us-east',
|
||||
displayName: 'US East Region',
|
||||
description: 'Primary US datacenter',
|
||||
currentStatus: 'major_outage',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 81.5,
|
||||
uptime90d: 89.2,
|
||||
responseTime: 4500,
|
||||
category: 'Regional',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'us-west',
|
||||
name: 'us-west',
|
||||
displayName: 'US West Region',
|
||||
description: 'Secondary US datacenter',
|
||||
currentStatus: 'degraded',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 94.2,
|
||||
uptime90d: 96.8,
|
||||
responseTime: 180,
|
||||
category: 'Regional',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'eu-central',
|
||||
name: 'eu-central',
|
||||
displayName: 'EU Central Region',
|
||||
description: 'European datacenter',
|
||||
currentStatus: 'major_outage',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 83.7,
|
||||
uptime90d: 91.2,
|
||||
responseTime: 3800,
|
||||
category: 'Regional',
|
||||
selected: true
|
||||
},
|
||||
// Some operational services
|
||||
{
|
||||
id: 'status-page',
|
||||
name: 'status-page',
|
||||
displayName: 'Status Page',
|
||||
description: 'This status page',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 99.9,
|
||||
uptime90d: 99.8,
|
||||
responseTime: 45,
|
||||
category: 'Support',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'support-portal',
|
||||
name: 'support-portal',
|
||||
displayName: 'Support Portal',
|
||||
description: 'Customer support system',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 98.5,
|
||||
uptime90d: 99.1,
|
||||
responseTime: 120,
|
||||
category: 'Support',
|
||||
selected: false
|
||||
},
|
||||
// Degraded services
|
||||
{
|
||||
id: 'email-service',
|
||||
name: 'email-service',
|
||||
displayName: 'Email Notifications',
|
||||
description: 'Automated emails',
|
||||
currentStatus: 'degraded',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 91.2,
|
||||
uptime90d: 94.5,
|
||||
responseTime: 850,
|
||||
category: 'Communication',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'analytics',
|
||||
name: 'analytics',
|
||||
displayName: 'Analytics Platform',
|
||||
description: 'Usage analytics',
|
||||
currentStatus: 'partial_outage',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 87.3,
|
||||
uptime90d: 92.8,
|
||||
responseTime: 1200,
|
||||
category: 'Services',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'backup-system',
|
||||
name: 'backup-system',
|
||||
displayName: 'Backup System',
|
||||
description: 'Data backups',
|
||||
currentStatus: 'degraded',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 95.2,
|
||||
uptime90d: 97.1,
|
||||
responseTime: 320,
|
||||
category: 'Services',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 'monitoring',
|
||||
name: 'monitoring',
|
||||
displayName: 'Monitoring System',
|
||||
description: 'Infrastructure monitoring',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: Date.now(),
|
||||
uptime30d: 98.7,
|
||||
uptime90d: 99.2,
|
||||
responseTime: 65,
|
||||
category: 'Services',
|
||||
selected: true
|
||||
}
|
||||
];
|
||||
|
||||
assetsSelector.services = services;
|
||||
|
||||
// Configure Status Details - Showing the outage timeline
|
||||
const generateStatusDetails = (): IStatusHistoryPoint[] => {
|
||||
const details: IStatusHistoryPoint[] = [];
|
||||
const now = new Date();
|
||||
|
||||
for (let i = 47; i >= 0; i--) {
|
||||
const date = new Date(now);
|
||||
date.setMinutes(0, 0, 0);
|
||||
date.setHours(date.getHours() - i);
|
||||
|
||||
let status: 'operational' | 'degraded' | 'major_outage' = 'operational';
|
||||
let value = 100;
|
||||
let responseTime = 30;
|
||||
|
||||
// Outage started 8 hours ago
|
||||
if (i <= 8) {
|
||||
status = 'major_outage';
|
||||
value = 15 + Math.random() * 20;
|
||||
responseTime = 2000 + Math.random() * 3000;
|
||||
} else if (i <= 12) {
|
||||
// Degradation before the outage
|
||||
status = 'degraded';
|
||||
value = 70 + Math.random() * 20;
|
||||
responseTime = 200 + Math.random() * 800;
|
||||
} else if (i <= 24) {
|
||||
// Some issues yesterday
|
||||
if (Math.random() > 0.7) {
|
||||
status = 'degraded';
|
||||
value = 85 + Math.random() * 10;
|
||||
responseTime = 100 + Math.random() * 200;
|
||||
}
|
||||
}
|
||||
|
||||
details.push({
|
||||
timestamp: date.getTime(),
|
||||
status,
|
||||
responseTime
|
||||
});
|
||||
}
|
||||
|
||||
return details;
|
||||
};
|
||||
|
||||
statusDetails.dataPoints = generateStatusDetails();
|
||||
statusDetails.serviceId = 'primary-db';
|
||||
statusDetails.serviceName = 'Primary Database';
|
||||
|
||||
// Configure Monthly Status - Poor performance
|
||||
const generateMonthlyData = (): IMonthlyUptime[] => {
|
||||
const months: IMonthlyUptime[] = [];
|
||||
const now = new Date();
|
||||
|
||||
for (let m = 4; m >= 0; m--) {
|
||||
const monthDate = new Date(now.getFullYear(), now.getMonth() - m, 1);
|
||||
const daysInMonth = new Date(monthDate.getFullYear(), monthDate.getMonth() + 1, 0).getDate();
|
||||
const monthKey = monthDate.toISOString().slice(0, 7);
|
||||
|
||||
const days = [];
|
||||
let totalUptime = 0;
|
||||
let incidents = 0;
|
||||
|
||||
for (let d = 1; d <= daysInMonth; d++) {
|
||||
const dayDate = new Date(monthDate.getFullYear(), monthDate.getMonth(), d);
|
||||
const isToday = dayDate.toDateString() === now.toDateString();
|
||||
const isFuture = dayDate > now;
|
||||
|
||||
if (isFuture) continue;
|
||||
|
||||
let status: 'operational' | 'degraded' | 'partial_outage' | 'major_outage' = 'operational';
|
||||
let uptime = 100;
|
||||
let dayIncidents = 0;
|
||||
|
||||
// Today - major outage
|
||||
if (isToday) {
|
||||
status = 'major_outage';
|
||||
uptime = 45;
|
||||
dayIncidents = 3;
|
||||
} else if (Math.random() > 0.7) {
|
||||
// Frequent issues
|
||||
if (Math.random() > 0.5) {
|
||||
status = 'partial_outage';
|
||||
uptime = 75 + Math.random() * 15;
|
||||
dayIncidents = 2;
|
||||
} else {
|
||||
status = 'degraded';
|
||||
uptime = 85 + Math.random() * 10;
|
||||
dayIncidents = 1;
|
||||
}
|
||||
}
|
||||
|
||||
days.push({
|
||||
date: dayDate.toISOString().slice(0, 10),
|
||||
status,
|
||||
uptime,
|
||||
incidents: dayIncidents,
|
||||
totalDowntime: Math.round((100 - uptime) * 14.4)
|
||||
});
|
||||
|
||||
totalUptime += uptime;
|
||||
incidents += dayIncidents;
|
||||
}
|
||||
|
||||
months.push({
|
||||
month: monthKey,
|
||||
days,
|
||||
overallUptime: totalUptime / days.length,
|
||||
totalIncidents: incidents
|
||||
});
|
||||
}
|
||||
|
||||
return months;
|
||||
};
|
||||
|
||||
statusMonth.monthlyData = generateMonthlyData();
|
||||
statusMonth.serviceId = 'all-services';
|
||||
statusMonth.serviceName = 'All Services';
|
||||
|
||||
// Configure Incidents - Multiple current incidents
|
||||
const currentIncidents: IIncidentDetails[] = [
|
||||
{
|
||||
id: 'inc-2024-crit-001',
|
||||
title: 'Complete Database Failure in Multiple Regions',
|
||||
impact: 'Users unable to access any services. Complete system outage.',
|
||||
severity: 'critical',
|
||||
status: 'investigating',
|
||||
startTime: Date.now() - 8 * 60 * 60 * 1000,
|
||||
affectedServices: ['Primary Database', 'Database Replicas', 'API Gateway', 'Authentication', 'US East Region', 'EU Central Region'],
|
||||
updates: [
|
||||
{
|
||||
id: 'update-1',
|
||||
timestamp: Date.now() - 8 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Multiple alerts triggered. Complete service failure detected across regions.',
|
||||
author: 'Automated Monitoring'
|
||||
},
|
||||
{
|
||||
id: 'update-2',
|
||||
timestamp: Date.now() - 7.5 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'All hands on deck. Engineering teams mobilized. Initial investigation points to cascading database failure.',
|
||||
author: 'Incident Commander'
|
||||
},
|
||||
{
|
||||
id: 'update-3',
|
||||
timestamp: Date.now() - 6 * 60 * 60 * 1000,
|
||||
status: 'identified',
|
||||
message: 'Root cause identified: Corrupted replication logs causing database cluster failures. Working on recovery.',
|
||||
author: 'Database Team'
|
||||
},
|
||||
{
|
||||
id: 'update-4',
|
||||
timestamp: Date.now() - 4 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Attempting to restore from backups. This is a complex operation and will take time.',
|
||||
author: 'Infrastructure Team'
|
||||
},
|
||||
{
|
||||
id: 'update-5',
|
||||
timestamp: Date.now() - 2 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Partial recovery in progress. Some read-only operations may become available soon.',
|
||||
author: 'Database Team'
|
||||
},
|
||||
{
|
||||
id: 'update-6',
|
||||
timestamp: Date.now() - 30 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Critical update: Recovery is taking longer than expected. We are exploring all options including failover to disaster recovery site.',
|
||||
author: 'CTO'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'inc-2024-maj-002',
|
||||
title: 'API Gateway Overload',
|
||||
impact: 'API requests failing or timing out',
|
||||
severity: 'major',
|
||||
status: 'monitoring',
|
||||
startTime: Date.now() - 6 * 60 * 60 * 1000,
|
||||
affectedServices: ['API Gateway', 'Web Portal'],
|
||||
updates: [
|
||||
{
|
||||
id: 'update-7',
|
||||
timestamp: Date.now() - 6 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'API Gateway experiencing extreme load due to retry storms from database failures.',
|
||||
author: 'API Team'
|
||||
},
|
||||
{
|
||||
id: 'update-8',
|
||||
timestamp: Date.now() - 5 * 60 * 60 * 1000,
|
||||
status: 'identified',
|
||||
message: 'Implementing rate limiting and circuit breakers to prevent cascade failures.',
|
||||
author: 'API Team'
|
||||
},
|
||||
{
|
||||
id: 'update-9',
|
||||
timestamp: Date.now() - 3 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Rate limiting in place. Load is stabilizing but service remains degraded.',
|
||||
author: 'API Team'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'inc-2024-maj-003',
|
||||
title: 'Email Service Delays',
|
||||
impact: 'Notification emails delayed by up to 2 hours',
|
||||
severity: 'major',
|
||||
status: 'monitoring',
|
||||
startTime: Date.now() - 5 * 60 * 60 * 1000,
|
||||
affectedServices: ['Email Notifications'],
|
||||
updates: [
|
||||
{
|
||||
id: 'update-10',
|
||||
timestamp: Date.now() - 5 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Email queue backing up due to system outages.',
|
||||
author: 'Communications Team'
|
||||
},
|
||||
{
|
||||
id: 'update-11',
|
||||
timestamp: Date.now() - 3 * 60 * 60 * 1000,
|
||||
status: 'monitoring',
|
||||
message: 'Processing backlog slowly. Prioritizing critical notifications.',
|
||||
author: 'Communications Team'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const pastIncidents: IIncidentDetails[] = [
|
||||
{
|
||||
id: 'inc-2024-prev-001',
|
||||
title: 'Previous Major Outage',
|
||||
impact: 'Services unavailable for 4 hours',
|
||||
severity: 'critical',
|
||||
status: 'resolved',
|
||||
startTime: Date.now() - 30 * 24 * 60 * 60 * 1000,
|
||||
endTime: Date.now() - 30 * 24 * 60 * 60 * 1000 + 4 * 60 * 60 * 1000,
|
||||
affectedServices: ['All Services'],
|
||||
rootCause: 'Power failure at primary datacenter with UPS failure.',
|
||||
resolution: 'Power restored. UPS systems replaced and tested.',
|
||||
updates: [
|
||||
{
|
||||
id: 'update-12',
|
||||
timestamp: Date.now() - 30 * 24 * 60 * 60 * 1000,
|
||||
status: 'investigating',
|
||||
message: 'Complete datacenter power loss.',
|
||||
author: 'Operations'
|
||||
},
|
||||
{
|
||||
id: 'update-13',
|
||||
timestamp: Date.now() - 30 * 24 * 60 * 60 * 1000 + 4 * 60 * 60 * 1000,
|
||||
status: 'resolved',
|
||||
message: 'Power restored. Services coming back online.',
|
||||
author: 'Operations'
|
||||
},
|
||||
{
|
||||
id: 'update-14',
|
||||
timestamp: Date.now() - 29 * 24 * 60 * 60 * 1000,
|
||||
status: 'postmortem',
|
||||
message: 'Postmortem published. Multiple redundancy improvements implemented.',
|
||||
author: 'Engineering'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
incidents.currentIncidents = currentIncidents;
|
||||
incidents.pastIncidents = pastIncidents;
|
||||
|
||||
// Configure Footer
|
||||
footer.companyName = 'DataStream Platform';
|
||||
footer.legalUrl = 'https://datastream.example.com/legal';
|
||||
footer.supportEmail = 'emergency@datastream.example.com';
|
||||
footer.statusPageUrl = 'https://status.datastream.example.com';
|
||||
footer.lastUpdated = Date.now();
|
||||
footer.currentYear = new Date().getFullYear();
|
||||
footer.socialLinks = [
|
||||
{ platform: 'twitter', url: 'https://twitter.com/datastream' }
|
||||
];
|
||||
footer.rssFeedUrl = 'https://status.datastream.example.com/rss';
|
||||
footer.apiStatusUrl = 'https://api.datastream.example.com/v1/status';
|
||||
footer.enableSubscribe = true;
|
||||
footer.enableReportIssue = true;
|
||||
footer.subscriberCount = 15234;
|
||||
footer.errorMessage = 'Critical: Multiple services experiencing major outages';
|
||||
footer.additionalLinks = [
|
||||
{ label: 'Emergency Support', url: 'tel:+1-800-HELP-NOW' },
|
||||
{ label: 'Incident Updates', url: 'https://datastream.example.com/incidents' }
|
||||
];
|
||||
}}
|
||||
>
|
||||
<upl-statuspage-header></upl-statuspage-header>
|
||||
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
||||
<upl-statuspage-assetsselector></upl-statuspage-assetsselector>
|
||||
<upl-statuspage-statusdetails></upl-statuspage-statusdetails>
|
||||
<upl-statuspage-statusmonth></upl-statuspage-statusmonth>
|
||||
<upl-statuspage-incidents></upl-statuspage-incidents>
|
||||
<upl-statuspage-footer></upl-statuspage-footer>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
`;
|
||||
Reference in New Issue
Block a user