update
This commit is contained in:
754
ts_web/elements/upl-statuspage-statusdetails.demo.ts
Normal file
754
ts_web/elements/upl-statuspage-statusdetails.demo.ts
Normal file
@@ -0,0 +1,754 @@
|
||||
import { html } from '@design.estate/dees-element';
|
||||
import type { IStatusHistoryPoint } from '../interfaces/index.js';
|
||||
|
||||
export const demoFunc = () => html`
|
||||
<style>
|
||||
.demo-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
.demo-section {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.demo-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 16px;
|
||||
color: #333;
|
||||
}
|
||||
.demo-controls {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.demo-button {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ddd;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
}
|
||||
.demo-button:hover {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
.demo-button.active {
|
||||
background: #2196F3;
|
||||
color: white;
|
||||
border-color: #2196F3;
|
||||
}
|
||||
.demo-info {
|
||||
margin-top: 12px;
|
||||
padding: 12px;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.stat-box {
|
||||
background: white;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #2196F3;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="demo-container">
|
||||
<!-- Time Range Demo -->
|
||||
<div class="demo-section">
|
||||
<div class="demo-title">Different Time Ranges</div>
|
||||
<dees-demowrapper
|
||||
.runAfterRender=${async (wrapperElement: any) => {
|
||||
const statusDetails = wrapperElement.querySelector('upl-statuspage-statusdetails') as any;
|
||||
|
||||
// Generate data for different time ranges
|
||||
const generateDataForRange = (hours: number, pattern: 'stable' | 'degrading' | 'improving' | 'volatile' = 'stable'): IStatusHistoryPoint[] => {
|
||||
const now = Date.now();
|
||||
const data: IStatusHistoryPoint[] = [];
|
||||
|
||||
// For proper display, we need hourly data points that align with actual hours
|
||||
for (let i = hours - 1; i >= 0; i--) {
|
||||
// Create timestamp at the start of each hour
|
||||
const date = new Date();
|
||||
date.setMinutes(0, 0, 0);
|
||||
date.setHours(date.getHours() - i);
|
||||
const timestamp = date.getTime();
|
||||
let status: IStatusHistoryPoint['status'] = 'operational';
|
||||
let responseTime = 50 + Math.random() * 50;
|
||||
let errorRate = 0;
|
||||
|
||||
switch (pattern) {
|
||||
case 'degrading':
|
||||
// Getting worse over time
|
||||
const degradation = (hours - i) / hours;
|
||||
if (degradation > 0.7) {
|
||||
status = 'major_outage';
|
||||
responseTime = 800 + Math.random() * 200;
|
||||
errorRate = 0.3 + Math.random() * 0.2;
|
||||
} else if (degradation > 0.5) {
|
||||
status = 'partial_outage';
|
||||
responseTime = 500 + Math.random() * 200;
|
||||
errorRate = 0.1 + Math.random() * 0.1;
|
||||
} else if (degradation > 0.3) {
|
||||
status = 'degraded';
|
||||
responseTime = 200 + Math.random() * 100;
|
||||
errorRate = 0.02 + Math.random() * 0.03;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'improving':
|
||||
// Getting better over time
|
||||
const improvement = i / hours;
|
||||
if (improvement < 0.3) {
|
||||
status = 'major_outage';
|
||||
responseTime = 800 + Math.random() * 200;
|
||||
errorRate = 0.3 + Math.random() * 0.2;
|
||||
} else if (improvement < 0.5) {
|
||||
status = 'partial_outage';
|
||||
responseTime = 500 + Math.random() * 200;
|
||||
errorRate = 0.1 + Math.random() * 0.1;
|
||||
} else if (improvement < 0.7) {
|
||||
status = 'degraded';
|
||||
responseTime = 200 + Math.random() * 100;
|
||||
errorRate = 0.02 + Math.random() * 0.03;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'volatile':
|
||||
// Random ups and downs
|
||||
const rand = Math.random();
|
||||
if (rand < 0.05) {
|
||||
status = 'major_outage';
|
||||
responseTime = 800 + Math.random() * 200;
|
||||
errorRate = 0.3 + Math.random() * 0.2;
|
||||
} else if (rand < 0.1) {
|
||||
status = 'partial_outage';
|
||||
responseTime = 500 + Math.random() * 200;
|
||||
errorRate = 0.1 + Math.random() * 0.1;
|
||||
} else if (rand < 0.2) {
|
||||
status = 'degraded';
|
||||
responseTime = 200 + Math.random() * 100;
|
||||
errorRate = 0.02 + Math.random() * 0.03;
|
||||
} else if (rand < 0.25) {
|
||||
status = 'maintenance';
|
||||
responseTime = 100 + Math.random() * 50;
|
||||
errorRate = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Stable with occasional hiccups
|
||||
if (Math.random() < 0.02) {
|
||||
status = 'degraded';
|
||||
responseTime = 200 + Math.random() * 100;
|
||||
errorRate = 0.01 + Math.random() * 0.02;
|
||||
}
|
||||
}
|
||||
|
||||
data.push({
|
||||
timestamp,
|
||||
status,
|
||||
responseTime,
|
||||
errorRate
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
// Initial setup
|
||||
statusDetails.serviceId = 'api-gateway';
|
||||
statusDetails.serviceName = 'API Gateway';
|
||||
statusDetails.historyData = generateDataForRange(24);
|
||||
|
||||
// Create controls
|
||||
const controls = document.createElement('div');
|
||||
controls.className = 'demo-controls';
|
||||
|
||||
const timeRanges = [
|
||||
{ hours: 24, label: '24 Hours' },
|
||||
{ hours: 168, label: '7 Days' },
|
||||
{ hours: 720, label: '30 Days' },
|
||||
{ hours: 2160, label: '90 Days' }
|
||||
];
|
||||
|
||||
timeRanges.forEach((range, index) => {
|
||||
const button = document.createElement('button');
|
||||
button.className = 'demo-button' + (index === 0 ? ' active' : '');
|
||||
button.textContent = range.label;
|
||||
button.onclick = () => {
|
||||
// Update active button
|
||||
controls.querySelectorAll('.demo-button').forEach(btn => btn.classList.remove('active'));
|
||||
button.classList.add('active');
|
||||
|
||||
// Load new data with loading state
|
||||
statusDetails.loading = true;
|
||||
setTimeout(() => {
|
||||
statusDetails.historyData = generateDataForRange(range.hours, 'volatile');
|
||||
statusDetails.loading = false;
|
||||
updateStats();
|
||||
}, 500);
|
||||
};
|
||||
controls.appendChild(button);
|
||||
});
|
||||
|
||||
wrapperElement.appendChild(controls);
|
||||
|
||||
// Add statistics display
|
||||
const statsDiv = document.createElement('div');
|
||||
statsDiv.className = 'stats-grid';
|
||||
wrapperElement.appendChild(statsDiv);
|
||||
|
||||
const updateStats = () => {
|
||||
const data = statusDetails.historyData || [];
|
||||
const operational = data.filter(d => d.status === 'operational').length;
|
||||
const avgResponseTime = data.reduce((sum, d) => sum + (d.responseTime || 0), 0) / data.length;
|
||||
const uptime = (operational / data.length) * 100;
|
||||
const incidents = data.filter(d => d.status !== 'operational' && d.status !== 'maintenance').length;
|
||||
|
||||
statsDiv.innerHTML = `
|
||||
<div class="stat-box">
|
||||
<div class="stat-value">${uptime.toFixed(2)}%</div>
|
||||
<div class="stat-label">Uptime</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="stat-value">${avgResponseTime.toFixed(0)}ms</div>
|
||||
<div class="stat-label">Avg Response Time</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="stat-value">${incidents}</div>
|
||||
<div class="stat-label">Incidents</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="stat-value">${data.length}</div>
|
||||
<div class="stat-label">Data Points</div>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
|
||||
updateStats();
|
||||
|
||||
// Handle bar clicks
|
||||
statusDetails.addEventListener('barClick', (event: CustomEvent) => {
|
||||
const { timestamp, status, responseTime, errorRate } = event.detail;
|
||||
const date = new Date(timestamp);
|
||||
alert(`Details for ${date.toLocaleString()}:\n\nStatus: ${status}\nResponse Time: ${responseTime.toFixed(0)}ms\nError Rate: ${(errorRate * 100).toFixed(2)}%`);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<upl-statuspage-statusdetails></upl-statuspage-statusdetails>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
|
||||
<!-- Data Pattern Scenarios -->
|
||||
<div class="demo-section">
|
||||
<div class="demo-title">Different Data Patterns</div>
|
||||
<dees-demowrapper
|
||||
.runAfterRender=${async (wrapperElement: any) => {
|
||||
const statusDetails = wrapperElement.querySelector('upl-statuspage-statusdetails') as any;
|
||||
|
||||
// Pattern generators
|
||||
const patterns = {
|
||||
stable: () => {
|
||||
const data: IStatusHistoryPoint[] = [];
|
||||
for (let i = 47; i >= 0; i--) {
|
||||
const date = new Date();
|
||||
date.setMinutes(0, 0, 0);
|
||||
date.setHours(date.getHours() - i);
|
||||
data.push({
|
||||
timestamp: date.getTime(),
|
||||
status: 'operational',
|
||||
responseTime: 40 + Math.random() * 20,
|
||||
errorRate: 0
|
||||
});
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
degrading: () => {
|
||||
const now = Date.now();
|
||||
const data: IStatusHistoryPoint[] = [];
|
||||
for (let i = 47; i >= 0; i--) {
|
||||
const degradation = (47 - i) / 47;
|
||||
let status: IStatusHistoryPoint['status'] = 'operational';
|
||||
let responseTime = 50;
|
||||
let errorRate = 0;
|
||||
|
||||
if (degradation > 0.8) {
|
||||
status = 'major_outage';
|
||||
responseTime = 800 + Math.random() * 200;
|
||||
errorRate = 0.4;
|
||||
} else if (degradation > 0.6) {
|
||||
status = 'partial_outage';
|
||||
responseTime = 500 + Math.random() * 100;
|
||||
errorRate = 0.2;
|
||||
} else if (degradation > 0.4) {
|
||||
status = 'degraded';
|
||||
responseTime = 200 + Math.random() * 100;
|
||||
errorRate = 0.05;
|
||||
} else {
|
||||
responseTime = 50 + degradation * 100;
|
||||
}
|
||||
|
||||
data.push({
|
||||
timestamp: now - (i * 60 * 60 * 1000),
|
||||
status,
|
||||
responseTime,
|
||||
errorRate
|
||||
});
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
recovering: () => {
|
||||
const now = Date.now();
|
||||
const data: IStatusHistoryPoint[] = [];
|
||||
for (let i = 47; i >= 0; i--) {
|
||||
const recovery = i / 47;
|
||||
let status: IStatusHistoryPoint['status'] = 'operational';
|
||||
let responseTime = 50;
|
||||
let errorRate = 0;
|
||||
|
||||
if (recovery < 0.2) {
|
||||
status = 'operational';
|
||||
responseTime = 50 + Math.random() * 20;
|
||||
} else if (recovery < 0.4) {
|
||||
status = 'degraded';
|
||||
responseTime = 150 + Math.random() * 50;
|
||||
errorRate = 0.02;
|
||||
} else if (recovery < 0.7) {
|
||||
status = 'partial_outage';
|
||||
responseTime = 400 + Math.random() * 100;
|
||||
errorRate = 0.15;
|
||||
} else {
|
||||
status = 'major_outage';
|
||||
responseTime = 800 + Math.random() * 200;
|
||||
errorRate = 0.35;
|
||||
}
|
||||
|
||||
data.push({
|
||||
timestamp: now - (i * 60 * 60 * 1000),
|
||||
status,
|
||||
responseTime,
|
||||
errorRate
|
||||
});
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
periodic: () => {
|
||||
const now = Date.now();
|
||||
const data: IStatusHistoryPoint[] = [];
|
||||
for (let i = 47; i >= 0; i--) {
|
||||
// Issues every 12 hours
|
||||
const hourOfDay = i % 24;
|
||||
let status: IStatusHistoryPoint['status'] = 'operational';
|
||||
let responseTime = 50 + Math.random() * 30;
|
||||
let errorRate = 0;
|
||||
|
||||
if (hourOfDay >= 9 && hourOfDay <= 11) {
|
||||
// Morning peak
|
||||
status = 'degraded';
|
||||
responseTime = 200 + Math.random() * 100;
|
||||
errorRate = 0.05;
|
||||
} else if (hourOfDay >= 18 && hourOfDay <= 20) {
|
||||
// Evening peak
|
||||
status = 'degraded';
|
||||
responseTime = 250 + Math.random() * 150;
|
||||
errorRate = 0.08;
|
||||
}
|
||||
|
||||
data.push({
|
||||
timestamp: now - (i * 60 * 60 * 1000),
|
||||
status,
|
||||
responseTime,
|
||||
errorRate
|
||||
});
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
maintenance: () => {
|
||||
const now = Date.now();
|
||||
const data: IStatusHistoryPoint[] = [];
|
||||
for (let i = 47; i >= 0; i--) {
|
||||
let status: IStatusHistoryPoint['status'] = 'operational';
|
||||
let responseTime = 50 + Math.random() * 30;
|
||||
let errorRate = 0;
|
||||
|
||||
// Maintenance window from hour 20-24
|
||||
if (i >= 20 && i <= 24) {
|
||||
status = 'maintenance';
|
||||
responseTime = 0;
|
||||
errorRate = 0;
|
||||
}
|
||||
|
||||
data.push({
|
||||
timestamp: now - (i * 60 * 60 * 1000),
|
||||
status,
|
||||
responseTime,
|
||||
errorRate
|
||||
});
|
||||
}
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
// Initial setup
|
||||
statusDetails.serviceId = 'web-server';
|
||||
statusDetails.serviceName = 'Web Server';
|
||||
statusDetails.historyData = patterns.stable();
|
||||
|
||||
// Create controls
|
||||
const controls = document.createElement('div');
|
||||
controls.className = 'demo-controls';
|
||||
|
||||
Object.entries(patterns).forEach(([name, generator]) => {
|
||||
const button = document.createElement('button');
|
||||
button.className = 'demo-button' + (name === 'stable' ? ' active' : '');
|
||||
button.textContent = name.charAt(0).toUpperCase() + name.slice(1);
|
||||
button.onclick = () => {
|
||||
controls.querySelectorAll('.demo-button').forEach(btn => btn.classList.remove('active'));
|
||||
button.classList.add('active');
|
||||
|
||||
statusDetails.loading = true;
|
||||
setTimeout(() => {
|
||||
statusDetails.historyData = generator();
|
||||
statusDetails.loading = false;
|
||||
updateInfo(name);
|
||||
}, 300);
|
||||
};
|
||||
controls.appendChild(button);
|
||||
});
|
||||
|
||||
wrapperElement.appendChild(controls);
|
||||
|
||||
// Add info display
|
||||
const info = document.createElement('div');
|
||||
info.className = 'demo-info';
|
||||
wrapperElement.appendChild(info);
|
||||
|
||||
const updateInfo = (pattern: string) => {
|
||||
const descriptions = {
|
||||
stable: 'Service running smoothly with consistent performance',
|
||||
degrading: 'Service health deteriorating over time',
|
||||
recovering: 'Service recovering from a major outage',
|
||||
periodic: 'Regular performance issues during peak hours (9-11 AM and 6-8 PM)',
|
||||
maintenance: 'Scheduled maintenance window (hours 20-24)'
|
||||
};
|
||||
|
||||
info.innerHTML = `<strong>Pattern:</strong> ${descriptions[pattern as keyof typeof descriptions] || pattern}`;
|
||||
};
|
||||
|
||||
updateInfo('stable');
|
||||
}}
|
||||
>
|
||||
<upl-statuspage-statusdetails></upl-statuspage-statusdetails>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
|
||||
<!-- Interactive Real-time Updates -->
|
||||
<div class="demo-section">
|
||||
<div class="demo-title">Real-time Updates with Manual Control</div>
|
||||
<dees-demowrapper
|
||||
.runAfterRender=${async (wrapperElement: any) => {
|
||||
const statusDetails = wrapperElement.querySelector('upl-statuspage-statusdetails') as any;
|
||||
|
||||
// Initialize with recent data
|
||||
const now = Date.now();
|
||||
const initialData: IStatusHistoryPoint[] = [];
|
||||
for (let i = 23; i >= 0; i--) {
|
||||
initialData.push({
|
||||
timestamp: now - (i * 60 * 60 * 1000),
|
||||
status: 'operational',
|
||||
responseTime: 50 + Math.random() * 30,
|
||||
errorRate: 0
|
||||
});
|
||||
}
|
||||
|
||||
statusDetails.serviceId = 'real-time-api';
|
||||
statusDetails.serviceName = 'Real-time API';
|
||||
statusDetails.historyData = initialData;
|
||||
statusDetails.timeRange = '24h';
|
||||
|
||||
// Create controls
|
||||
const controls = document.createElement('div');
|
||||
controls.className = 'demo-controls';
|
||||
controls.innerHTML = `
|
||||
<button class="demo-button" id="addHealthy">Add Healthy Point</button>
|
||||
<button class="demo-button" id="addDegraded">Add Degraded Point</button>
|
||||
<button class="demo-button" id="addOutage">Add Outage Point</button>
|
||||
<button class="demo-button" id="simulateSpike">Simulate Traffic Spike</button>
|
||||
<button class="demo-button" id="clearData">Clear All Data</button>
|
||||
`;
|
||||
wrapperElement.appendChild(controls);
|
||||
|
||||
const addDataPoint = (status: IStatusHistoryPoint['status'], responseTime: number, errorRate: number = 0) => {
|
||||
const data = [...(statusDetails.historyData || [])];
|
||||
if (data.length >= 24) {
|
||||
data.shift(); // Keep only 24 points
|
||||
}
|
||||
|
||||
data.push({
|
||||
timestamp: Date.now(),
|
||||
status,
|
||||
responseTime,
|
||||
errorRate
|
||||
});
|
||||
|
||||
statusDetails.historyData = data;
|
||||
};
|
||||
|
||||
controls.querySelector('#addHealthy')?.addEventListener('click', () => {
|
||||
addDataPoint('operational', 50 + Math.random() * 30);
|
||||
});
|
||||
|
||||
controls.querySelector('#addDegraded')?.addEventListener('click', () => {
|
||||
addDataPoint('degraded', 200 + Math.random() * 100, 0.05);
|
||||
});
|
||||
|
||||
controls.querySelector('#addOutage')?.addEventListener('click', () => {
|
||||
addDataPoint('major_outage', 800 + Math.random() * 200, 0.5);
|
||||
});
|
||||
|
||||
controls.querySelector('#simulateSpike')?.addEventListener('click', () => {
|
||||
// Add several degraded points
|
||||
for (let i = 0; i < 3; i++) {
|
||||
setTimeout(() => {
|
||||
addDataPoint('degraded', 300 + Math.random() * 200, 0.1 + Math.random() * 0.1);
|
||||
}, i * 1000);
|
||||
}
|
||||
});
|
||||
|
||||
controls.querySelector('#clearData')?.addEventListener('click', () => {
|
||||
statusDetails.historyData = [];
|
||||
});
|
||||
|
||||
// Auto-update every 5 seconds
|
||||
let autoUpdate = setInterval(() => {
|
||||
const rand = Math.random();
|
||||
if (rand < 0.8) {
|
||||
addDataPoint('operational', 40 + Math.random() * 40);
|
||||
} else if (rand < 0.95) {
|
||||
addDataPoint('degraded', 150 + Math.random() * 100, 0.02);
|
||||
} else {
|
||||
addDataPoint('partial_outage', 400 + Math.random() * 200, 0.15);
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
// Add toggle for auto-updates
|
||||
const autoToggle = document.createElement('button');
|
||||
autoToggle.className = 'demo-button active';
|
||||
autoToggle.textContent = 'Auto-update: ON';
|
||||
autoToggle.style.marginLeft = '10px';
|
||||
autoToggle.onclick = () => {
|
||||
if (autoUpdate) {
|
||||
clearInterval(autoUpdate);
|
||||
autoUpdate = null;
|
||||
autoToggle.textContent = 'Auto-update: OFF';
|
||||
autoToggle.classList.remove('active');
|
||||
} else {
|
||||
autoUpdate = setInterval(() => {
|
||||
const rand = Math.random();
|
||||
if (rand < 0.8) {
|
||||
addDataPoint('operational', 40 + Math.random() * 40);
|
||||
} else if (rand < 0.95) {
|
||||
addDataPoint('degraded', 150 + Math.random() * 100, 0.02);
|
||||
} else {
|
||||
addDataPoint('partial_outage', 400 + Math.random() * 200, 0.15);
|
||||
}
|
||||
}, 5000);
|
||||
autoToggle.textContent = 'Auto-update: ON';
|
||||
autoToggle.classList.add('active');
|
||||
}
|
||||
};
|
||||
controls.appendChild(autoToggle);
|
||||
|
||||
// Cleanup on unmount
|
||||
wrapperElement.addEventListener('remove', () => {
|
||||
if (autoUpdate) clearInterval(autoUpdate);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<upl-statuspage-statusdetails></upl-statuspage-statusdetails>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
|
||||
<!-- Edge Cases -->
|
||||
<div class="demo-section">
|
||||
<div class="demo-title">Edge Cases and Special Scenarios</div>
|
||||
<dees-demowrapper
|
||||
.runAfterRender=${async (wrapperElement: any) => {
|
||||
const statusDetails = wrapperElement.querySelector('upl-statuspage-statusdetails') as any;
|
||||
|
||||
const scenarios = {
|
||||
noData: {
|
||||
name: 'No Data Available',
|
||||
data: []
|
||||
},
|
||||
singlePoint: {
|
||||
name: 'Single Data Point',
|
||||
data: [{
|
||||
timestamp: Date.now(),
|
||||
status: 'operational' as const,
|
||||
responseTime: 75,
|
||||
errorRate: 0
|
||||
}]
|
||||
},
|
||||
allDown: {
|
||||
name: 'Complete Outage',
|
||||
data: Array.from({ length: 48 }, (_, i) => ({
|
||||
timestamp: Date.now() - (i * 60 * 60 * 1000),
|
||||
status: 'major_outage' as const,
|
||||
responseTime: 0,
|
||||
errorRate: 1
|
||||
}))
|
||||
},
|
||||
highLatency: {
|
||||
name: 'High Latency Issues',
|
||||
data: Array.from({ length: 48 }, (_, i) => ({
|
||||
timestamp: Date.now() - (i * 60 * 60 * 1000),
|
||||
status: 'operational' as const,
|
||||
responseTime: 2000 + Math.random() * 1000,
|
||||
errorRate: 0
|
||||
}))
|
||||
},
|
||||
mixedStatuses: {
|
||||
name: 'All Status Types',
|
||||
data: Array.from({ length: 50 }, (_, i) => {
|
||||
const statuses: IStatusHistoryPoint['status'][] = ['operational', 'degraded', 'partial_outage', 'major_outage', 'maintenance'];
|
||||
const status = statuses[i % statuses.length];
|
||||
return {
|
||||
timestamp: Date.now() - (i * 60 * 60 * 1000),
|
||||
status,
|
||||
responseTime: status === 'operational' ? 50 : status === 'maintenance' ? 0 : 200 + Math.random() * 600,
|
||||
errorRate: status === 'operational' || status === 'maintenance' ? 0 : 0.1 + Math.random() * 0.4
|
||||
};
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
// Initial scenario
|
||||
let currentScenario = 'noData';
|
||||
statusDetails.serviceId = 'edge-case-service';
|
||||
statusDetails.serviceName = 'Edge Case Service';
|
||||
statusDetails.historyData = scenarios[currentScenario].data;
|
||||
|
||||
// Create scenario buttons
|
||||
const controls = document.createElement('div');
|
||||
controls.className = 'demo-controls';
|
||||
|
||||
Object.entries(scenarios).forEach(([key, scenario]) => {
|
||||
const button = document.createElement('button');
|
||||
button.className = 'demo-button' + (key === currentScenario ? ' active' : '');
|
||||
button.textContent = scenario.name;
|
||||
button.onclick = () => {
|
||||
controls.querySelectorAll('.demo-button').forEach(btn => btn.classList.remove('active'));
|
||||
button.classList.add('active');
|
||||
|
||||
currentScenario = key;
|
||||
statusDetails.loading = true;
|
||||
setTimeout(() => {
|
||||
statusDetails.historyData = scenario.data;
|
||||
statusDetails.loading = false;
|
||||
}, 300);
|
||||
};
|
||||
controls.appendChild(button);
|
||||
});
|
||||
|
||||
wrapperElement.appendChild(controls);
|
||||
}}
|
||||
>
|
||||
<upl-statuspage-statusdetails></upl-statuspage-statusdetails>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
|
||||
<!-- Loading and Error States -->
|
||||
<div class="demo-section">
|
||||
<div class="demo-title">Loading and Error Handling</div>
|
||||
<dees-demowrapper
|
||||
.runAfterRender=${async (wrapperElement: any) => {
|
||||
const statusDetails = wrapperElement.querySelector('upl-statuspage-statusdetails') as any;
|
||||
|
||||
// Start with loading
|
||||
statusDetails.loading = true;
|
||||
statusDetails.serviceId = 'loading-demo';
|
||||
statusDetails.serviceName = 'Loading Demo Service';
|
||||
|
||||
const controls = document.createElement('div');
|
||||
controls.className = 'demo-controls';
|
||||
controls.innerHTML = `
|
||||
<button class="demo-button" id="toggleLoading">Toggle Loading</button>
|
||||
<button class="demo-button" id="loadSuccess">Load Successfully</button>
|
||||
<button class="demo-button" id="loadError">Simulate Error</button>
|
||||
<button class="demo-button" id="loadSlowly">Load Slowly (3s)</button>
|
||||
`;
|
||||
wrapperElement.appendChild(controls);
|
||||
|
||||
controls.querySelector('#toggleLoading')?.addEventListener('click', () => {
|
||||
statusDetails.loading = !statusDetails.loading;
|
||||
});
|
||||
|
||||
controls.querySelector('#loadSuccess')?.addEventListener('click', () => {
|
||||
statusDetails.loading = true;
|
||||
setTimeout(() => {
|
||||
const now = Date.now();
|
||||
statusDetails.historyData = Array.from({ length: 24 }, (_, i) => ({
|
||||
timestamp: now - (i * 60 * 60 * 1000),
|
||||
status: Math.random() > 0.9 ? 'degraded' : 'operational',
|
||||
responseTime: 50 + Math.random() * 50,
|
||||
errorRate: 0
|
||||
}));
|
||||
statusDetails.loading = false;
|
||||
}, 500);
|
||||
});
|
||||
|
||||
controls.querySelector('#loadError')?.addEventListener('click', () => {
|
||||
statusDetails.loading = true;
|
||||
setTimeout(() => {
|
||||
statusDetails.loading = false;
|
||||
statusDetails.historyData = [];
|
||||
statusDetails.errorMessage = 'Failed to load status data: Connection timeout';
|
||||
}, 1500);
|
||||
});
|
||||
|
||||
controls.querySelector('#loadSlowly')?.addEventListener('click', () => {
|
||||
statusDetails.loading = true;
|
||||
setTimeout(() => {
|
||||
const now = Date.now();
|
||||
statusDetails.historyData = Array.from({ length: 48 }, (_, i) => ({
|
||||
timestamp: now - (i * 60 * 60 * 1000),
|
||||
status: 'operational',
|
||||
responseTime: 45 + Math.random() * 30,
|
||||
errorRate: 0
|
||||
}));
|
||||
statusDetails.loading = false;
|
||||
}, 3000);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<upl-statuspage-statusdetails></upl-statuspage-statusdetails>
|
||||
</dees-demowrapper>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
Reference in New Issue
Block a user