@uptime.link/statuspage 1.0.74 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist_bundle/bundle.js +5019 -519
  2. package/dist_bundle/bundle.js.map +4 -4
  3. package/dist_ts_web/00_commitinfo_data.js +2 -2
  4. package/dist_ts_web/elements/index.d.ts +3 -0
  5. package/dist_ts_web/elements/index.js +6 -1
  6. package/dist_ts_web/elements/internal/uplinternal-miniheading.d.ts +1 -0
  7. package/dist_ts_web/elements/internal/uplinternal-miniheading.js +78 -28
  8. package/dist_ts_web/elements/upl-statuspage-assetsselector.d.ts +14 -0
  9. package/dist_ts_web/elements/upl-statuspage-assetsselector.demo.d.ts +1 -0
  10. package/dist_ts_web/elements/upl-statuspage-assetsselector.demo.js +575 -0
  11. package/dist_ts_web/elements/upl-statuspage-assetsselector.js +679 -43
  12. package/dist_ts_web/elements/upl-statuspage-footer.d.ts +46 -2
  13. package/dist_ts_web/elements/upl-statuspage-footer.demo.d.ts +1 -0
  14. package/dist_ts_web/elements/upl-statuspage-footer.demo.js +679 -0
  15. package/dist_ts_web/elements/upl-statuspage-footer.js +846 -61
  16. package/dist_ts_web/elements/upl-statuspage-header.d.ts +5 -1
  17. package/dist_ts_web/elements/upl-statuspage-header.demo.d.ts +1 -0
  18. package/dist_ts_web/elements/upl-statuspage-header.demo.js +220 -0
  19. package/dist_ts_web/elements/upl-statuspage-header.js +373 -86
  20. package/dist_ts_web/elements/upl-statuspage-incidents.d.ts +22 -4
  21. package/dist_ts_web/elements/upl-statuspage-incidents.demo.d.ts +1 -0
  22. package/dist_ts_web/elements/upl-statuspage-incidents.demo.js +1147 -0
  23. package/dist_ts_web/elements/upl-statuspage-incidents.js +937 -74
  24. package/dist_ts_web/elements/upl-statuspage-pagetitle.d.ts +15 -0
  25. package/dist_ts_web/elements/upl-statuspage-pagetitle.demo.d.ts +1 -0
  26. package/dist_ts_web/elements/upl-statuspage-pagetitle.demo.js +25 -0
  27. package/dist_ts_web/elements/upl-statuspage-pagetitle.js +148 -0
  28. package/dist_ts_web/elements/upl-statuspage-statsgrid.d.ts +23 -0
  29. package/dist_ts_web/elements/upl-statuspage-statsgrid.demo.d.ts +1 -0
  30. package/dist_ts_web/elements/upl-statuspage-statsgrid.demo.js +295 -0
  31. package/dist_ts_web/elements/upl-statuspage-statsgrid.js +549 -0
  32. package/dist_ts_web/elements/upl-statuspage-statusbar.d.ts +4 -0
  33. package/dist_ts_web/elements/upl-statuspage-statusbar.demo.d.ts +1 -0
  34. package/dist_ts_web/elements/upl-statuspage-statusbar.demo.js +365 -0
  35. package/dist_ts_web/elements/upl-statuspage-statusbar.js +408 -44
  36. package/dist_ts_web/elements/upl-statuspage-statusdetails.d.ts +14 -0
  37. package/dist_ts_web/elements/upl-statuspage-statusdetails.demo.d.ts +1 -0
  38. package/dist_ts_web/elements/upl-statuspage-statusdetails.demo.js +706 -0
  39. package/dist_ts_web/elements/upl-statuspage-statusdetails.js +397 -62
  40. package/dist_ts_web/elements/upl-statuspage-statusmonth.d.ts +17 -0
  41. package/dist_ts_web/elements/upl-statuspage-statusmonth.demo.d.ts +1 -0
  42. package/dist_ts_web/elements/upl-statuspage-statusmonth.demo.js +798 -0
  43. package/dist_ts_web/elements/upl-statuspage-statusmonth.js +662 -103
  44. package/dist_ts_web/interfaces/index.d.ts +84 -0
  45. package/dist_ts_web/interfaces/index.js +4 -0
  46. package/dist_ts_web/pages/index.d.ts +4 -1
  47. package/dist_ts_web/pages/index.js +5 -2
  48. package/dist_ts_web/pages/statuspage-allgreen.d.ts +1 -0
  49. package/dist_ts_web/pages/statuspage-allgreen.js +386 -0
  50. package/dist_ts_web/pages/statuspage-demo.d.ts +1 -0
  51. package/dist_ts_web/pages/statuspage-demo.js +616 -0
  52. package/dist_ts_web/pages/statuspage-maintenance.d.ts +1 -0
  53. package/dist_ts_web/pages/statuspage-maintenance.js +544 -0
  54. package/dist_ts_web/pages/statuspage-outage.d.ts +1 -0
  55. package/dist_ts_web/pages/statuspage-outage.js +543 -0
  56. package/dist_ts_web/styles/shared.styles.d.ts +102 -0
  57. package/dist_ts_web/styles/shared.styles.js +494 -0
  58. package/dist_watch/bundle.js +52265 -32033
  59. package/dist_watch/bundle.js.map +4 -4
  60. package/dist_watch/index.html +1 -0
  61. package/npmextra.json +9 -3
  62. package/package.json +19 -19
  63. package/readme.hints.md +292 -0
  64. package/readme.md +326 -149
  65. package/readme.plan.md +261 -0
  66. package/ts_web/00_commitinfo_data.ts +1 -1
  67. package/ts_web/elements/index.ts +6 -0
  68. package/ts_web/elements/internal/uplinternal-miniheading.ts +24 -17
  69. package/ts_web/elements/upl-statuspage-assetsselector.demo.ts +607 -0
  70. package/ts_web/elements/upl-statuspage-assetsselector.ts +600 -18
  71. package/ts_web/elements/upl-statuspage-footer.demo.ts +744 -0
  72. package/ts_web/elements/upl-statuspage-footer.ts +662 -30
  73. package/ts_web/elements/upl-statuspage-header.demo.ts +241 -0
  74. package/ts_web/elements/upl-statuspage-header.ts +289 -52
  75. package/ts_web/elements/upl-statuspage-incidents.demo.ts +1216 -0
  76. package/ts_web/elements/upl-statuspage-incidents.ts +840 -26
  77. package/ts_web/elements/upl-statuspage-pagetitle.demo.ts +25 -0
  78. package/ts_web/elements/upl-statuspage-pagetitle.ts +89 -0
  79. package/ts_web/elements/upl-statuspage-statsgrid.demo.ts +315 -0
  80. package/ts_web/elements/upl-statuspage-statsgrid.ts +478 -0
  81. package/ts_web/elements/upl-statuspage-statusbar.demo.ts +393 -0
  82. package/ts_web/elements/upl-statuspage-statusbar.ts +332 -20
  83. package/ts_web/elements/upl-statuspage-statusdetails.demo.ts +754 -0
  84. package/ts_web/elements/upl-statuspage-statusdetails.ts +321 -37
  85. package/ts_web/elements/upl-statuspage-statusmonth.demo.ts +876 -0
  86. package/ts_web/elements/upl-statuspage-statusmonth.ts +584 -79
  87. package/ts_web/interfaces/index.ts +95 -0
  88. package/ts_web/pages/index.ts +4 -1
  89. package/ts_web/pages/statuspage-allgreen.ts +412 -0
  90. package/ts_web/pages/statuspage-demo.ts +653 -0
  91. package/ts_web/pages/statuspage-maintenance.ts +570 -0
  92. package/ts_web/pages/statuspage-outage.ts +568 -0
  93. package/ts_web/styles/shared.styles.ts +531 -0
  94. package/dist_ts_web/pages/page1.d.ts +0 -1
  95. package/dist_ts_web/pages/page1.js +0 -11
  96. package/ts_web/pages/page1.ts +0 -11
@@ -0,0 +1,607 @@
1
+ import { html } from '@design.estate/dees-element';
2
+ import type { IServiceStatus } from '../interfaces/index.js';
3
+
4
+ export const demoFunc = () => html`
5
+ <style>
6
+ .demo-container {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: 20px;
10
+ }
11
+ .demo-section {
12
+ border: 1px solid #ddd;
13
+ border-radius: 8px;
14
+ padding: 20px;
15
+ background: #f5f5f5;
16
+ }
17
+ .demo-title {
18
+ font-size: 14px;
19
+ font-weight: 600;
20
+ margin-bottom: 16px;
21
+ color: #333;
22
+ }
23
+ .demo-controls {
24
+ display: flex;
25
+ gap: 10px;
26
+ margin-top: 16px;
27
+ flex-wrap: wrap;
28
+ }
29
+ .demo-button {
30
+ padding: 6px 12px;
31
+ border: 1px solid #ddd;
32
+ background: white;
33
+ border-radius: 4px;
34
+ cursor: pointer;
35
+ font-size: 13px;
36
+ }
37
+ .demo-button:hover {
38
+ background: #f0f0f0;
39
+ }
40
+ .demo-info {
41
+ margin-top: 12px;
42
+ padding: 12px;
43
+ background: white;
44
+ border-radius: 4px;
45
+ font-size: 13px;
46
+ }
47
+ .event-log {
48
+ margin-top: 12px;
49
+ padding: 12px;
50
+ background: #f9f9f9;
51
+ border-radius: 4px;
52
+ font-size: 12px;
53
+ max-height: 150px;
54
+ overflow-y: auto;
55
+ font-family: monospace;
56
+ }
57
+ </style>
58
+
59
+ <div class="demo-container">
60
+ <!-- Full Featured Demo -->
61
+ <div class="demo-section">
62
+ <div class="demo-title">Full Featured Service Selector</div>
63
+ <dees-demowrapper
64
+ .runAfterRender=${async (wrapperElement: any) => {
65
+ const assetsSelector = wrapperElement.querySelector('upl-statuspage-assetsselector') as any;
66
+
67
+ // Comprehensive demo data
68
+ const demoServices: IServiceStatus[] = [
69
+ // Infrastructure
70
+ {
71
+ id: 'api-gateway',
72
+ name: 'api-gateway',
73
+ displayName: 'API Gateway',
74
+ description: 'Main API endpoint for all services',
75
+ currentStatus: 'operational',
76
+ lastChecked: Date.now(),
77
+ uptime30d: 99.95,
78
+ uptime90d: 99.92,
79
+ responseTime: 45,
80
+ category: 'Infrastructure',
81
+ selected: true
82
+ },
83
+ {
84
+ id: 'web-server',
85
+ name: 'web-server',
86
+ displayName: 'Web Server',
87
+ description: 'Frontend web application server',
88
+ currentStatus: 'operational',
89
+ lastChecked: Date.now(),
90
+ uptime30d: 99.99,
91
+ uptime90d: 99.97,
92
+ responseTime: 28,
93
+ category: 'Infrastructure',
94
+ selected: true
95
+ },
96
+ {
97
+ id: 'load-balancer',
98
+ name: 'load-balancer',
99
+ displayName: 'Load Balancer',
100
+ description: 'Traffic distribution system',
101
+ currentStatus: 'operational',
102
+ lastChecked: Date.now(),
103
+ uptime30d: 100,
104
+ uptime90d: 99.99,
105
+ responseTime: 5,
106
+ category: 'Infrastructure',
107
+ selected: false
108
+ },
109
+ {
110
+ id: 'cdn',
111
+ name: 'cdn',
112
+ displayName: 'CDN',
113
+ description: 'Content delivery network',
114
+ currentStatus: 'operational',
115
+ lastChecked: Date.now(),
116
+ uptime30d: 100,
117
+ uptime90d: 99.99,
118
+ responseTime: 12,
119
+ category: 'Infrastructure',
120
+ selected: false
121
+ },
122
+ // Data Services
123
+ {
124
+ id: 'database',
125
+ name: 'database',
126
+ displayName: 'Database Cluster',
127
+ description: 'Primary database cluster with replicas',
128
+ currentStatus: 'degraded',
129
+ lastChecked: Date.now(),
130
+ uptime30d: 98.5,
131
+ uptime90d: 99.1,
132
+ responseTime: 120,
133
+ category: 'Data',
134
+ selected: true
135
+ },
136
+ {
137
+ id: 'redis-cache',
138
+ name: 'redis-cache',
139
+ displayName: 'Redis Cache',
140
+ description: 'In-memory data caching',
141
+ currentStatus: 'operational',
142
+ lastChecked: Date.now(),
143
+ uptime30d: 99.98,
144
+ uptime90d: 99.96,
145
+ responseTime: 5,
146
+ category: 'Data',
147
+ selected: true
148
+ },
149
+ {
150
+ id: 'elasticsearch',
151
+ name: 'elasticsearch',
152
+ displayName: 'Search Engine',
153
+ description: 'Full-text search service',
154
+ currentStatus: 'partial_outage',
155
+ lastChecked: Date.now(),
156
+ uptime30d: 95.2,
157
+ uptime90d: 97.8,
158
+ responseTime: 180,
159
+ category: 'Data',
160
+ selected: false
161
+ },
162
+ {
163
+ id: 'backup-service',
164
+ name: 'backup-service',
165
+ displayName: 'Backup Service',
166
+ description: 'Automated backup and recovery',
167
+ currentStatus: 'operational',
168
+ lastChecked: Date.now(),
169
+ uptime30d: 100,
170
+ uptime90d: 99.99,
171
+ responseTime: 95,
172
+ category: 'Data',
173
+ selected: true
174
+ },
175
+ // Application Services
176
+ {
177
+ id: 'auth-service',
178
+ name: 'auth-service',
179
+ displayName: 'Authentication Service',
180
+ description: 'User authentication and authorization',
181
+ currentStatus: 'operational',
182
+ lastChecked: Date.now(),
183
+ uptime30d: 99.98,
184
+ uptime90d: 99.95,
185
+ responseTime: 65,
186
+ category: 'Services',
187
+ selected: true
188
+ },
189
+ {
190
+ id: 'payment-gateway',
191
+ name: 'payment-gateway',
192
+ displayName: 'Payment Gateway',
193
+ description: 'Payment processing service',
194
+ currentStatus: 'maintenance',
195
+ lastChecked: Date.now(),
196
+ uptime30d: 97.5,
197
+ uptime90d: 98.8,
198
+ responseTime: 250,
199
+ category: 'Services',
200
+ selected: false
201
+ },
202
+ {
203
+ id: 'email-service',
204
+ name: 'email-service',
205
+ displayName: 'Email Service',
206
+ description: 'Transactional email delivery',
207
+ currentStatus: 'operational',
208
+ lastChecked: Date.now(),
209
+ uptime30d: 99.9,
210
+ uptime90d: 99.85,
211
+ responseTime: 150,
212
+ category: 'Services',
213
+ selected: true
214
+ },
215
+ {
216
+ id: 'notification-service',
217
+ name: 'notification-service',
218
+ displayName: 'Notification Service',
219
+ description: 'Push notifications and alerts',
220
+ currentStatus: 'operational',
221
+ lastChecked: Date.now(),
222
+ uptime30d: 99.7,
223
+ uptime90d: 99.8,
224
+ responseTime: 88,
225
+ category: 'Services',
226
+ selected: false
227
+ },
228
+ {
229
+ id: 'analytics',
230
+ name: 'analytics',
231
+ displayName: 'Analytics Engine',
232
+ description: 'Real-time analytics processing',
233
+ currentStatus: 'major_outage',
234
+ lastChecked: Date.now(),
235
+ uptime30d: 89.5,
236
+ uptime90d: 94.2,
237
+ responseTime: 450,
238
+ category: 'Services',
239
+ selected: false
240
+ },
241
+ // Monitoring
242
+ {
243
+ id: 'monitoring',
244
+ name: 'monitoring',
245
+ displayName: 'Monitoring System',
246
+ description: 'System health and metrics monitoring',
247
+ currentStatus: 'operational',
248
+ lastChecked: Date.now(),
249
+ uptime30d: 99.95,
250
+ uptime90d: 99.93,
251
+ responseTime: 78,
252
+ category: 'Monitoring',
253
+ selected: true
254
+ },
255
+ {
256
+ id: 'logging',
257
+ name: 'logging',
258
+ displayName: 'Logging Service',
259
+ description: 'Centralized log management',
260
+ currentStatus: 'operational',
261
+ lastChecked: Date.now(),
262
+ uptime30d: 99.9,
263
+ uptime90d: 99.88,
264
+ responseTime: 92,
265
+ category: 'Monitoring',
266
+ selected: false
267
+ }
268
+ ];
269
+
270
+ // Set initial data
271
+ assetsSelector.services = demoServices;
272
+
273
+ // Demo loading state
274
+ assetsSelector.loading = true;
275
+ setTimeout(() => {
276
+ assetsSelector.loading = false;
277
+ }, 1000);
278
+
279
+ // Create event log
280
+ const eventLog = document.createElement('div');
281
+ eventLog.className = 'event-log';
282
+ eventLog.innerHTML = '<strong>Event Log:</strong><br>';
283
+ wrapperElement.appendChild(eventLog);
284
+
285
+ const logEvent = (message: string) => {
286
+ const time = new Date().toLocaleTimeString();
287
+ eventLog.innerHTML += `[${time}] ${message}<br>`;
288
+ eventLog.scrollTop = eventLog.scrollHeight;
289
+ };
290
+
291
+ // Listen for selection changes
292
+ assetsSelector.addEventListener('selectionChanged', (event: CustomEvent) => {
293
+ const selected = event.detail.selectedServices.length;
294
+ const total = demoServices.length;
295
+ logEvent(`Selection changed: ${selected}/${total} services selected`);
296
+ });
297
+
298
+ // Simulate status updates
299
+ setInterval(() => {
300
+ const randomService = demoServices[Math.floor(Math.random() * demoServices.length)];
301
+ const statuses: Array<IServiceStatus['currentStatus']> = ['operational', 'degraded', 'partial_outage', 'major_outage', 'maintenance'];
302
+ const newStatus = statuses[Math.floor(Math.random() * statuses.length)];
303
+
304
+ if (randomService.currentStatus !== newStatus) {
305
+ const oldStatus = randomService.currentStatus;
306
+ randomService.currentStatus = newStatus;
307
+ randomService.lastChecked = Date.now();
308
+ assetsSelector.requestUpdate();
309
+ logEvent(`${randomService.displayName}: ${oldStatus} → ${newStatus}`);
310
+ }
311
+ }, 5000);
312
+ }}
313
+ >
314
+ <upl-statuspage-assetsselector></upl-statuspage-assetsselector>
315
+ </dees-demowrapper>
316
+ </div>
317
+
318
+ <!-- Empty State -->
319
+ <div class="demo-section">
320
+ <div class="demo-title">Empty State</div>
321
+ <dees-demowrapper
322
+ .runAfterRender=${async (wrapperElement: any) => {
323
+ const assetsSelector = wrapperElement.querySelector('upl-statuspage-assetsselector') as any;
324
+
325
+ // No services
326
+ assetsSelector.services = [];
327
+
328
+ const controls = document.createElement('div');
329
+ controls.className = 'demo-controls';
330
+ controls.innerHTML = `
331
+ <button class="demo-button" id="addServices">Add Services</button>
332
+ `;
333
+ wrapperElement.appendChild(controls);
334
+
335
+ controls.querySelector('#addServices')?.addEventListener('click', () => {
336
+ assetsSelector.services = [
337
+ {
338
+ id: 'new-service-1',
339
+ name: 'new-service-1',
340
+ displayName: 'New Service 1',
341
+ description: 'Just added',
342
+ currentStatus: 'operational',
343
+ lastChecked: Date.now(),
344
+ uptime30d: 100,
345
+ uptime90d: 100,
346
+ responseTime: 50,
347
+ selected: true
348
+ },
349
+ {
350
+ id: 'new-service-2',
351
+ name: 'new-service-2',
352
+ displayName: 'New Service 2',
353
+ description: 'Just added',
354
+ currentStatus: 'operational',
355
+ lastChecked: Date.now(),
356
+ uptime30d: 100,
357
+ uptime90d: 100,
358
+ responseTime: 60,
359
+ selected: false
360
+ }
361
+ ];
362
+ });
363
+ }}
364
+ >
365
+ <upl-statuspage-assetsselector></upl-statuspage-assetsselector>
366
+ </dees-demowrapper>
367
+ </div>
368
+
369
+ <!-- Filtering Scenarios -->
370
+ <div class="demo-section">
371
+ <div class="demo-title">Advanced Filtering Demo</div>
372
+ <dees-demowrapper
373
+ .runAfterRender=${async (wrapperElement: any) => {
374
+ const assetsSelector = wrapperElement.querySelector('upl-statuspage-assetsselector') as any;
375
+
376
+ // Generate many services for filtering
377
+ const generateServices = (): IServiceStatus[] => {
378
+ const services: IServiceStatus[] = [];
379
+ const regions = ['us-east', 'us-west', 'eu-central', 'ap-south'];
380
+ const types = ['api', 'web', 'db', 'cache', 'queue'];
381
+ const statuses: Array<IServiceStatus['currentStatus']> = ['operational', 'degraded', 'partial_outage'];
382
+
383
+ regions.forEach(region => {
384
+ types.forEach(type => {
385
+ const id = `${region}-${type}`;
386
+ services.push({
387
+ id,
388
+ name: id,
389
+ displayName: `${region.toUpperCase()} ${type.toUpperCase()}`,
390
+ description: `${type} service in ${region} region`,
391
+ currentStatus: statuses[Math.floor(Math.random() * statuses.length)],
392
+ lastChecked: Date.now(),
393
+ uptime30d: 95 + Math.random() * 5,
394
+ uptime90d: 94 + Math.random() * 6,
395
+ responseTime: 20 + Math.random() * 200,
396
+ category: region,
397
+ selected: Math.random() > 0.5
398
+ });
399
+ });
400
+ });
401
+
402
+ return services;
403
+ };
404
+
405
+ assetsSelector.services = generateServices();
406
+
407
+ // Demo different filter scenarios
408
+ const scenarios = [
409
+ {
410
+ name: 'Show All',
411
+ action: () => {
412
+ assetsSelector.filterText = '';
413
+ assetsSelector.filterCategory = 'all';
414
+ assetsSelector.showOnlySelected = false;
415
+ }
416
+ },
417
+ {
418
+ name: 'Filter by Text: "api"',
419
+ action: () => {
420
+ assetsSelector.filterText = 'api';
421
+ assetsSelector.filterCategory = 'all';
422
+ assetsSelector.showOnlySelected = false;
423
+ }
424
+ },
425
+ {
426
+ name: 'Filter by Region: EU',
427
+ action: () => {
428
+ assetsSelector.filterText = '';
429
+ assetsSelector.filterCategory = 'eu-central';
430
+ assetsSelector.showOnlySelected = false;
431
+ }
432
+ },
433
+ {
434
+ name: 'Show Only Selected',
435
+ action: () => {
436
+ assetsSelector.filterText = '';
437
+ assetsSelector.filterCategory = 'all';
438
+ assetsSelector.showOnlySelected = true;
439
+ }
440
+ },
441
+ {
442
+ name: 'Complex: "db" in US regions',
443
+ action: () => {
444
+ assetsSelector.filterText = 'db';
445
+ assetsSelector.filterCategory = 'us-east';
446
+ assetsSelector.showOnlySelected = false;
447
+ }
448
+ }
449
+ ];
450
+
451
+ const controls = document.createElement('div');
452
+ controls.className = 'demo-controls';
453
+ scenarios.forEach(scenario => {
454
+ const button = document.createElement('button');
455
+ button.className = 'demo-button';
456
+ button.textContent = scenario.name;
457
+ button.onclick = scenario.action;
458
+ controls.appendChild(button);
459
+ });
460
+ wrapperElement.appendChild(controls);
461
+
462
+ const info = document.createElement('div');
463
+ info.className = 'demo-info';
464
+ wrapperElement.appendChild(info);
465
+
466
+ // Update info on changes
467
+ const updateInfo = () => {
468
+ const filtered = assetsSelector.getFilteredServices();
469
+ const selected = assetsSelector.services.filter((s: any) => s.selected).length;
470
+ info.innerHTML = `
471
+ <strong>Filter Status:</strong><br>
472
+ Total Services: ${assetsSelector.services.length}<br>
473
+ Visible Services: ${filtered.length}<br>
474
+ Selected Services: ${selected}<br>
475
+ Active Filters: ${assetsSelector.filterText ? 'Text="' + assetsSelector.filterText + '" ' : ''}${assetsSelector.filterCategory !== 'all' ? 'Category=' + assetsSelector.filterCategory + ' ' : ''}${assetsSelector.showOnlySelected ? 'Selected Only' : ''}
476
+ `;
477
+ };
478
+
479
+ // Watch for changes
480
+ assetsSelector.addEventListener('selectionChanged', updateInfo);
481
+ setInterval(updateInfo, 500);
482
+ updateInfo();
483
+ }}
484
+ >
485
+ <upl-statuspage-assetsselector></upl-statuspage-assetsselector>
486
+ </dees-demowrapper>
487
+ </div>
488
+
489
+ <!-- Performance Test -->
490
+ <div class="demo-section">
491
+ <div class="demo-title">Performance Test - Many Services</div>
492
+ <dees-demowrapper
493
+ .runAfterRender=${async (wrapperElement: any) => {
494
+ const assetsSelector = wrapperElement.querySelector('upl-statuspage-assetsselector') as any;
495
+
496
+ const controls = document.createElement('div');
497
+ controls.className = 'demo-controls';
498
+ controls.innerHTML = `
499
+ <button class="demo-button" id="load50">Load 50 Services</button>
500
+ <button class="demo-button" id="load100">Load 100 Services</button>
501
+ <button class="demo-button" id="load200">Load 200 Services</button>
502
+ <button class="demo-button" id="clear">Clear All</button>
503
+ `;
504
+ wrapperElement.appendChild(controls);
505
+
506
+ const loadServices = (count: number) => {
507
+ const services: IServiceStatus[] = [];
508
+ const statuses: Array<IServiceStatus['currentStatus']> = ['operational', 'degraded', 'partial_outage', 'major_outage', 'maintenance'];
509
+
510
+ for (let i = 0; i < count; i++) {
511
+ services.push({
512
+ id: `service-${i}`,
513
+ name: `service-${i}`,
514
+ displayName: `Service ${i}`,
515
+ description: `Auto-generated service number ${i}`,
516
+ currentStatus: statuses[Math.floor(Math.random() * statuses.length)],
517
+ lastChecked: Date.now() - Math.random() * 3600000,
518
+ uptime30d: 85 + Math.random() * 15,
519
+ uptime90d: 80 + Math.random() * 20,
520
+ responseTime: 10 + Math.random() * 500,
521
+ category: `Category ${Math.floor(i / 10)}`,
522
+ selected: Math.random() > 0.7
523
+ });
524
+ }
525
+
526
+ assetsSelector.loading = true;
527
+ setTimeout(() => {
528
+ assetsSelector.services = services;
529
+ assetsSelector.loading = false;
530
+ }, 500);
531
+ };
532
+
533
+ controls.querySelector('#load50')?.addEventListener('click', () => loadServices(50));
534
+ controls.querySelector('#load100')?.addEventListener('click', () => loadServices(100));
535
+ controls.querySelector('#load200')?.addEventListener('click', () => loadServices(200));
536
+ controls.querySelector('#clear')?.addEventListener('click', () => {
537
+ assetsSelector.services = [];
538
+ });
539
+
540
+ // Start with 50 services
541
+ loadServices(50);
542
+ }}
543
+ >
544
+ <upl-statuspage-assetsselector></upl-statuspage-assetsselector>
545
+ </dees-demowrapper>
546
+ </div>
547
+
548
+ <!-- Loading States -->
549
+ <div class="demo-section">
550
+ <div class="demo-title">Loading and Error States</div>
551
+ <dees-demowrapper
552
+ .runAfterRender=${async (wrapperElement: any) => {
553
+ const assetsSelector = wrapperElement.querySelector('upl-statuspage-assetsselector') as any;
554
+
555
+ // Start with loading
556
+ assetsSelector.loading = true;
557
+
558
+ const controls = document.createElement('div');
559
+ controls.className = 'demo-controls';
560
+ controls.innerHTML = `
561
+ <button class="demo-button" id="toggleLoading">Toggle Loading</button>
562
+ <button class="demo-button" id="simulateError">Simulate Error</button>
563
+ <button class="demo-button" id="loadSuccess">Load Successfully</button>
564
+ `;
565
+ wrapperElement.appendChild(controls);
566
+
567
+ controls.querySelector('#toggleLoading')?.addEventListener('click', () => {
568
+ assetsSelector.loading = !assetsSelector.loading;
569
+ });
570
+
571
+ controls.querySelector('#simulateError')?.addEventListener('click', () => {
572
+ assetsSelector.loading = true;
573
+ setTimeout(() => {
574
+ assetsSelector.loading = false;
575
+ assetsSelector.services = [];
576
+ // You could add an error message property to the component
577
+ assetsSelector.errorMessage = 'Failed to load services';
578
+ }, 1500);
579
+ });
580
+
581
+ controls.querySelector('#loadSuccess')?.addEventListener('click', () => {
582
+ assetsSelector.loading = true;
583
+ setTimeout(() => {
584
+ assetsSelector.loading = false;
585
+ assetsSelector.services = [
586
+ {
587
+ id: 'loaded-1',
588
+ name: 'loaded-1',
589
+ displayName: 'Successfully Loaded Service',
590
+ description: 'This service was loaded after simulated delay',
591
+ currentStatus: 'operational',
592
+ lastChecked: Date.now(),
593
+ uptime30d: 99.9,
594
+ uptime90d: 99.8,
595
+ responseTime: 45,
596
+ selected: true
597
+ }
598
+ ];
599
+ }, 1000);
600
+ });
601
+ }}
602
+ >
603
+ <upl-statuspage-assetsselector></upl-statuspage-assetsselector>
604
+ </dees-demowrapper>
605
+ </div>
606
+ </div>
607
+ `;