@uptime.link/statuspage 1.0.73 → 1.1.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.
- package/dist_bundle/bundle.js +4096 -504
- package/dist_bundle/bundle.js.map +4 -4
- package/dist_ts_web/00_commitinfo_data.js +2 -2
- package/dist_ts_web/elements/index.d.ts +3 -0
- package/dist_ts_web/elements/index.js +6 -1
- package/dist_ts_web/elements/internal/uplinternal-miniheading.d.ts +1 -0
- package/dist_ts_web/elements/internal/uplinternal-miniheading.js +78 -28
- package/dist_ts_web/elements/upl-statuspage-assetsselector.d.ts +14 -0
- package/dist_ts_web/elements/upl-statuspage-assetsselector.demo.d.ts +1 -0
- package/dist_ts_web/elements/upl-statuspage-assetsselector.demo.js +575 -0
- package/dist_ts_web/elements/upl-statuspage-assetsselector.js +605 -43
- package/dist_ts_web/elements/upl-statuspage-footer.d.ts +46 -2
- package/dist_ts_web/elements/upl-statuspage-footer.demo.d.ts +1 -0
- package/dist_ts_web/elements/upl-statuspage-footer.demo.js +679 -0
- package/dist_ts_web/elements/upl-statuspage-footer.js +792 -61
- package/dist_ts_web/elements/upl-statuspage-header.d.ts +5 -1
- package/dist_ts_web/elements/upl-statuspage-header.demo.d.ts +1 -0
- package/dist_ts_web/elements/upl-statuspage-header.demo.js +220 -0
- package/dist_ts_web/elements/upl-statuspage-header.js +313 -86
- package/dist_ts_web/elements/upl-statuspage-incidents.d.ts +22 -4
- package/dist_ts_web/elements/upl-statuspage-incidents.demo.d.ts +1 -0
- package/dist_ts_web/elements/upl-statuspage-incidents.demo.js +1147 -0
- package/dist_ts_web/elements/upl-statuspage-incidents.js +750 -74
- package/dist_ts_web/elements/upl-statuspage-pagetitle.d.ts +15 -0
- package/dist_ts_web/elements/upl-statuspage-pagetitle.demo.d.ts +1 -0
- package/dist_ts_web/elements/upl-statuspage-pagetitle.demo.js +25 -0
- package/dist_ts_web/elements/upl-statuspage-pagetitle.js +148 -0
- package/dist_ts_web/elements/upl-statuspage-statsgrid.d.ts +23 -0
- package/dist_ts_web/elements/upl-statuspage-statsgrid.demo.d.ts +1 -0
- package/dist_ts_web/elements/upl-statuspage-statsgrid.demo.js +295 -0
- package/dist_ts_web/elements/upl-statuspage-statsgrid.js +374 -0
- package/dist_ts_web/elements/upl-statuspage-statusbar.d.ts +4 -0
- package/dist_ts_web/elements/upl-statuspage-statusbar.demo.d.ts +1 -0
- package/dist_ts_web/elements/upl-statuspage-statusbar.demo.js +365 -0
- package/dist_ts_web/elements/upl-statuspage-statusbar.js +357 -44
- package/dist_ts_web/elements/upl-statuspage-statusdetails.d.ts +14 -0
- package/dist_ts_web/elements/upl-statuspage-statusdetails.demo.d.ts +1 -0
- package/dist_ts_web/elements/upl-statuspage-statusdetails.demo.js +706 -0
- package/dist_ts_web/elements/upl-statuspage-statusdetails.js +373 -63
- package/dist_ts_web/elements/upl-statuspage-statusmonth.d.ts +15 -0
- package/dist_ts_web/elements/upl-statuspage-statusmonth.demo.d.ts +1 -0
- package/dist_ts_web/elements/upl-statuspage-statusmonth.demo.js +798 -0
- package/dist_ts_web/elements/upl-statuspage-statusmonth.js +474 -100
- package/dist_ts_web/interfaces/index.d.ts +84 -0
- package/dist_ts_web/interfaces/index.js +4 -0
- package/dist_ts_web/pages/index.d.ts +4 -1
- package/dist_ts_web/pages/index.js +5 -2
- package/dist_ts_web/pages/statuspage-allgreen.d.ts +1 -0
- package/dist_ts_web/pages/statuspage-allgreen.js +386 -0
- package/dist_ts_web/pages/statuspage-demo.d.ts +1 -0
- package/dist_ts_web/pages/statuspage-demo.js +616 -0
- package/dist_ts_web/pages/statuspage-maintenance.d.ts +1 -0
- package/dist_ts_web/pages/statuspage-maintenance.js +544 -0
- package/dist_ts_web/pages/statuspage-outage.d.ts +1 -0
- package/dist_ts_web/pages/statuspage-outage.js +543 -0
- package/dist_ts_web/styles/shared.styles.d.ts +80 -0
- package/dist_ts_web/styles/shared.styles.js +351 -0
- package/dist_watch/bundle.js +54534 -26433
- package/dist_watch/bundle.js.map +4 -4
- package/dist_watch/index.html +3 -10
- package/npmextra.json +9 -3
- package/package.json +19 -19
- package/readme.hints.md +292 -0
- package/readme.md +326 -149
- package/readme.plan.md +261 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/index.ts +6 -0
- package/ts_web/elements/internal/uplinternal-miniheading.ts +24 -17
- package/ts_web/elements/upl-statuspage-assetsselector.demo.ts +607 -0
- package/ts_web/elements/upl-statuspage-assetsselector.ts +526 -18
- package/ts_web/elements/upl-statuspage-footer.demo.ts +744 -0
- package/ts_web/elements/upl-statuspage-footer.ts +608 -30
- package/ts_web/elements/upl-statuspage-header.demo.ts +241 -0
- package/ts_web/elements/upl-statuspage-header.ts +220 -52
- package/ts_web/elements/upl-statuspage-incidents.demo.ts +1216 -0
- package/ts_web/elements/upl-statuspage-incidents.ts +649 -26
- package/ts_web/elements/upl-statuspage-pagetitle.demo.ts +25 -0
- package/ts_web/elements/upl-statuspage-pagetitle.ts +89 -0
- package/ts_web/elements/upl-statuspage-statsgrid.demo.ts +315 -0
- package/ts_web/elements/upl-statuspage-statsgrid.ts +306 -0
- package/ts_web/elements/upl-statuspage-statusbar.demo.ts +393 -0
- package/ts_web/elements/upl-statuspage-statusbar.ts +281 -20
- package/ts_web/elements/upl-statuspage-statusdetails.demo.ts +754 -0
- package/ts_web/elements/upl-statuspage-statusdetails.ts +297 -38
- package/ts_web/elements/upl-statuspage-statusmonth.demo.ts +876 -0
- package/ts_web/elements/upl-statuspage-statusmonth.ts +397 -76
- package/ts_web/interfaces/index.ts +95 -0
- package/ts_web/pages/index.ts +4 -1
- package/ts_web/pages/statuspage-allgreen.ts +412 -0
- package/ts_web/pages/statuspage-demo.ts +653 -0
- package/ts_web/pages/statuspage-maintenance.ts +570 -0
- package/ts_web/pages/statuspage-outage.ts +568 -0
- package/ts_web/styles/shared.styles.ts +367 -0
- package/dist_ts_web/pages/page1.d.ts +0 -1
- package/dist_ts_web/pages/page1.js +0 -11
- package/ts_web/pages/page1.ts +0 -11
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeesElement,
|
|
3
|
+
property,
|
|
4
|
+
html,
|
|
5
|
+
customElement,
|
|
6
|
+
type TemplateResult,
|
|
7
|
+
css,
|
|
8
|
+
cssManager,
|
|
9
|
+
unsafeCSS,
|
|
10
|
+
} from '@design.estate/dees-element';
|
|
11
|
+
import * as domtools from '@design.estate/dees-domtools';
|
|
12
|
+
import * as sharedStyles from '../styles/shared.styles.js';
|
|
13
|
+
|
|
14
|
+
import './internal/uplinternal-miniheading.js';
|
|
15
|
+
import { demoFunc } from './upl-statuspage-statsgrid.demo.js';
|
|
16
|
+
|
|
17
|
+
declare global {
|
|
18
|
+
interface HTMLElementTagNameMap {
|
|
19
|
+
'upl-statuspage-statsgrid': UplStatuspageStatsgrid;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@customElement('upl-statuspage-statsgrid')
|
|
24
|
+
export class UplStatuspageStatsgrid extends DeesElement {
|
|
25
|
+
public static demo = demoFunc;
|
|
26
|
+
|
|
27
|
+
@property({ type: Number })
|
|
28
|
+
accessor uptime: number = 99.99;
|
|
29
|
+
|
|
30
|
+
@property({ type: Number })
|
|
31
|
+
accessor avgResponseTime: number = 125;
|
|
32
|
+
|
|
33
|
+
@property({ type: Number })
|
|
34
|
+
accessor totalIncidents: number = 0;
|
|
35
|
+
|
|
36
|
+
@property({ type: Number })
|
|
37
|
+
accessor affectedServices: number = 0;
|
|
38
|
+
|
|
39
|
+
@property({ type: Number })
|
|
40
|
+
accessor totalServices: number = 0;
|
|
41
|
+
|
|
42
|
+
@property({ type: String })
|
|
43
|
+
accessor currentStatus: string = 'operational';
|
|
44
|
+
|
|
45
|
+
@property({ type: Boolean })
|
|
46
|
+
accessor loading: boolean = false;
|
|
47
|
+
|
|
48
|
+
@property({ type: String })
|
|
49
|
+
accessor timePeriod: string = '90 days';
|
|
50
|
+
|
|
51
|
+
constructor() {
|
|
52
|
+
super();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public static styles = [
|
|
56
|
+
domtools.elementBasic.staticStyles,
|
|
57
|
+
sharedStyles.commonStyles,
|
|
58
|
+
css`
|
|
59
|
+
:host {
|
|
60
|
+
display: block;
|
|
61
|
+
background: transparent;
|
|
62
|
+
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
|
63
|
+
color: ${sharedStyles.colors.text.primary};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.container {
|
|
67
|
+
max-width: 1200px;
|
|
68
|
+
margin: 0 auto;
|
|
69
|
+
padding: 0 ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.stats-grid {
|
|
73
|
+
display: grid;
|
|
74
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
75
|
+
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.stat-card {
|
|
79
|
+
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
|
80
|
+
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
|
81
|
+
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
|
82
|
+
padding: ${unsafeCSS(sharedStyles.spacing.lg)};
|
|
83
|
+
transition: all 0.2s ease;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.stat-card:hover {
|
|
87
|
+
border-color: ${cssManager.bdTheme('#d1d5db', '#3f3f46')};
|
|
88
|
+
box-shadow: ${cssManager.bdTheme(
|
|
89
|
+
'0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
|
90
|
+
'0 0 0 1px rgba(255, 255, 255, 0.1)'
|
|
91
|
+
)};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.stat-label {
|
|
95
|
+
font-size: 12px;
|
|
96
|
+
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
|
97
|
+
text-transform: uppercase;
|
|
98
|
+
letter-spacing: 0.05em;
|
|
99
|
+
font-weight: 500;
|
|
100
|
+
margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.stat-value {
|
|
107
|
+
font-size: 24px;
|
|
108
|
+
font-weight: 600;
|
|
109
|
+
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
|
110
|
+
font-variant-numeric: tabular-nums;
|
|
111
|
+
line-height: 1.2;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.stat-unit {
|
|
115
|
+
font-size: 14px;
|
|
116
|
+
font-weight: 400;
|
|
117
|
+
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
|
118
|
+
margin-left: 4px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.stat-change {
|
|
122
|
+
font-size: 12px;
|
|
123
|
+
margin-top: ${unsafeCSS(sharedStyles.spacing.xs)};
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
gap: 4px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.stat-change.positive {
|
|
130
|
+
color: ${cssManager.bdTheme('#10b981', '#10b981')};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.stat-change.negative {
|
|
134
|
+
color: ${cssManager.bdTheme('#ef4444', '#ef4444')};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.stat-change.neutral {
|
|
138
|
+
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.loading-skeleton {
|
|
142
|
+
display: grid;
|
|
143
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
144
|
+
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.skeleton-card {
|
|
148
|
+
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
|
149
|
+
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
|
150
|
+
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
|
151
|
+
padding: ${unsafeCSS(sharedStyles.spacing.lg)};
|
|
152
|
+
height: 100px;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.skeleton-label {
|
|
156
|
+
height: 14px;
|
|
157
|
+
width: 80px;
|
|
158
|
+
background: ${cssManager.bdTheme('#f3f4f6', '#27272a')};
|
|
159
|
+
border-radius: 4px;
|
|
160
|
+
margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
|
|
161
|
+
animation: pulse 2s infinite;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.skeleton-value {
|
|
165
|
+
height: 28px;
|
|
166
|
+
width: 120px;
|
|
167
|
+
background: ${cssManager.bdTheme('#f3f4f6', '#27272a')};
|
|
168
|
+
border-radius: 4px;
|
|
169
|
+
animation: pulse 2s infinite;
|
|
170
|
+
animation-delay: 0.1s;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@keyframes pulse {
|
|
174
|
+
0%, 100% { opacity: 1; }
|
|
175
|
+
50% { opacity: 0.5; }
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.status-indicator {
|
|
179
|
+
display: inline-block;
|
|
180
|
+
width: 6px;
|
|
181
|
+
height: 6px;
|
|
182
|
+
border-radius: 50%;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.status-indicator.operational {
|
|
186
|
+
background: ${sharedStyles.colors.status.operational};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.status-indicator.degraded {
|
|
190
|
+
background: ${sharedStyles.colors.status.degraded};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.status-indicator.partial_outage {
|
|
194
|
+
background: ${sharedStyles.colors.status.partial};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.status-indicator.major_outage {
|
|
198
|
+
background: ${sharedStyles.colors.status.major};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.status-indicator.maintenance {
|
|
202
|
+
background: ${sharedStyles.colors.status.maintenance};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@media (max-width: 640px) {
|
|
206
|
+
.container {
|
|
207
|
+
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.stats-grid {
|
|
211
|
+
grid-template-columns: 1fr;
|
|
212
|
+
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.stat-card {
|
|
216
|
+
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.stat-value {
|
|
220
|
+
font-size: 20px;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
`,
|
|
224
|
+
];
|
|
225
|
+
|
|
226
|
+
public render(): TemplateResult {
|
|
227
|
+
return html`
|
|
228
|
+
<div class="container">
|
|
229
|
+
${this.loading ? html`
|
|
230
|
+
<div class="loading-skeleton">
|
|
231
|
+
${Array(4).fill(0).map(() => html`
|
|
232
|
+
<div class="skeleton-card">
|
|
233
|
+
<div class="skeleton-label"></div>
|
|
234
|
+
<div class="skeleton-value"></div>
|
|
235
|
+
</div>
|
|
236
|
+
`)}
|
|
237
|
+
</div>
|
|
238
|
+
` : html`
|
|
239
|
+
<div class="stats-grid">
|
|
240
|
+
<div class="stat-card">
|
|
241
|
+
<div class="stat-label">
|
|
242
|
+
<span class="status-indicator ${this.currentStatus}"></span>
|
|
243
|
+
Current Status
|
|
244
|
+
</div>
|
|
245
|
+
<div class="stat-value">
|
|
246
|
+
${this.formatStatus(this.currentStatus)}
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
<div class="stat-card">
|
|
251
|
+
<div class="stat-label">Uptime</div>
|
|
252
|
+
<div class="stat-value">
|
|
253
|
+
${this.uptime.toFixed(2)}<span class="stat-unit">%</span>
|
|
254
|
+
</div>
|
|
255
|
+
<div class="stat-change neutral">
|
|
256
|
+
Last ${this.timePeriod}
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
|
|
260
|
+
<div class="stat-card">
|
|
261
|
+
<div class="stat-label">Avg Response Time</div>
|
|
262
|
+
<div class="stat-value">
|
|
263
|
+
${this.avgResponseTime}<span class="stat-unit">ms</span>
|
|
264
|
+
</div>
|
|
265
|
+
${this.renderResponseChange()}
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
<div class="stat-card">
|
|
269
|
+
<div class="stat-label">Incidents</div>
|
|
270
|
+
<div class="stat-value">
|
|
271
|
+
${this.totalIncidents}
|
|
272
|
+
</div>
|
|
273
|
+
<div class="stat-change neutral">
|
|
274
|
+
${this.affectedServices} of ${this.totalServices} services
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
`}
|
|
279
|
+
</div>
|
|
280
|
+
`;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private formatStatus(status: string): string {
|
|
284
|
+
const statusMap: Record<string, string> = {
|
|
285
|
+
operational: 'Operational',
|
|
286
|
+
degraded: 'Degraded',
|
|
287
|
+
partial_outage: 'Partial Outage',
|
|
288
|
+
major_outage: 'Major Outage',
|
|
289
|
+
maintenance: 'Maintenance',
|
|
290
|
+
};
|
|
291
|
+
return statusMap[status] || 'Unknown';
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
private renderResponseChange(): TemplateResult {
|
|
295
|
+
// This could be enhanced with actual trend data
|
|
296
|
+
const trend = this.avgResponseTime < 200 ? 'positive' : this.avgResponseTime > 500 ? 'negative' : 'neutral';
|
|
297
|
+
const icon = trend === 'positive' ? '↓' : trend === 'negative' ? '↑' : '→';
|
|
298
|
+
|
|
299
|
+
return html`
|
|
300
|
+
<div class="stat-change ${trend}">
|
|
301
|
+
<span>${icon}</span>
|
|
302
|
+
<span>${trend === 'positive' ? 'Fast' : trend === 'negative' ? 'Slow' : 'Normal'}</span>
|
|
303
|
+
</div>
|
|
304
|
+
`;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { html } from '@design.estate/dees-element';
|
|
2
|
+
import type { IOverallStatus } 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
|
+
.status-info {
|
|
41
|
+
margin-top: 12px;
|
|
42
|
+
padding: 12px;
|
|
43
|
+
background: white;
|
|
44
|
+
border-radius: 4px;
|
|
45
|
+
font-size: 13px;
|
|
46
|
+
line-height: 1.6;
|
|
47
|
+
}
|
|
48
|
+
</style>
|
|
49
|
+
|
|
50
|
+
<div class="demo-container">
|
|
51
|
+
<!-- Cycling Through All States -->
|
|
52
|
+
<div class="demo-section">
|
|
53
|
+
<div class="demo-title">Automatic Status Cycling</div>
|
|
54
|
+
<dees-demowrapper
|
|
55
|
+
.runAfterRender=${async (wrapperElement: any) => {
|
|
56
|
+
const statusBar = wrapperElement.querySelector('upl-statuspage-statusbar') as any;
|
|
57
|
+
|
|
58
|
+
const statusStates: IOverallStatus[] = [
|
|
59
|
+
{
|
|
60
|
+
status: 'operational',
|
|
61
|
+
message: 'All Systems Operational',
|
|
62
|
+
lastUpdated: Date.now(),
|
|
63
|
+
affectedServices: 0,
|
|
64
|
+
totalServices: 12
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
status: 'degraded',
|
|
68
|
+
message: 'Minor Service Degradation',
|
|
69
|
+
lastUpdated: Date.now(),
|
|
70
|
+
affectedServices: 2,
|
|
71
|
+
totalServices: 12
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
status: 'partial_outage',
|
|
75
|
+
message: 'Partial System Outage',
|
|
76
|
+
lastUpdated: Date.now(),
|
|
77
|
+
affectedServices: 4,
|
|
78
|
+
totalServices: 12
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
status: 'major_outage',
|
|
82
|
+
message: 'Major Service Disruption',
|
|
83
|
+
lastUpdated: Date.now(),
|
|
84
|
+
affectedServices: 8,
|
|
85
|
+
totalServices: 12
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
status: 'maintenance',
|
|
89
|
+
message: 'Scheduled Maintenance in Progress',
|
|
90
|
+
lastUpdated: Date.now(),
|
|
91
|
+
affectedServices: 3,
|
|
92
|
+
totalServices: 12
|
|
93
|
+
}
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
let statusIndex = 0;
|
|
97
|
+
|
|
98
|
+
// Initial loading demo
|
|
99
|
+
statusBar.loading = true;
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
statusBar.loading = false;
|
|
102
|
+
statusBar.overallStatus = statusStates[0];
|
|
103
|
+
}, 1500);
|
|
104
|
+
|
|
105
|
+
// Cycle through states
|
|
106
|
+
setInterval(() => {
|
|
107
|
+
statusIndex = (statusIndex + 1) % statusStates.length;
|
|
108
|
+
statusBar.overallStatus = statusStates[statusIndex];
|
|
109
|
+
statusBar.overallStatus = { ...statusBar.overallStatus, lastUpdated: Date.now() };
|
|
110
|
+
}, 3000);
|
|
111
|
+
|
|
112
|
+
// Handle clicks
|
|
113
|
+
statusBar.addEventListener('statusClick', (event: CustomEvent) => {
|
|
114
|
+
console.log('Status bar clicked:', event.detail);
|
|
115
|
+
alert(`Status Details:\n\nStatus: ${event.detail.status.status}\nMessage: ${event.detail.status.message}\nAffected Services: ${event.detail.status.affectedServices}`);
|
|
116
|
+
});
|
|
117
|
+
}}
|
|
118
|
+
>
|
|
119
|
+
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
|
120
|
+
</dees-demowrapper>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<!-- Manual Status Control -->
|
|
124
|
+
<div class="demo-section">
|
|
125
|
+
<div class="demo-title">Manual Status Control</div>
|
|
126
|
+
<dees-demowrapper
|
|
127
|
+
.runAfterRender=${async (wrapperElement: any) => {
|
|
128
|
+
const statusBar = wrapperElement.querySelector('upl-statuspage-statusbar') as any;
|
|
129
|
+
|
|
130
|
+
// Initial state
|
|
131
|
+
statusBar.overallStatus = {
|
|
132
|
+
status: 'operational',
|
|
133
|
+
message: 'All Systems Operational',
|
|
134
|
+
lastUpdated: Date.now(),
|
|
135
|
+
affectedServices: 0,
|
|
136
|
+
totalServices: 15
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Create controls
|
|
140
|
+
const controls = document.createElement('div');
|
|
141
|
+
controls.className = 'demo-controls';
|
|
142
|
+
controls.innerHTML = `
|
|
143
|
+
<button class="demo-button" data-status="operational">Operational</button>
|
|
144
|
+
<button class="demo-button" data-status="degraded">Degraded</button>
|
|
145
|
+
<button class="demo-button" data-status="partial_outage">Partial Outage</button>
|
|
146
|
+
<button class="demo-button" data-status="major_outage">Major Outage</button>
|
|
147
|
+
<button class="demo-button" data-status="maintenance">Maintenance</button>
|
|
148
|
+
`;
|
|
149
|
+
wrapperElement.appendChild(controls);
|
|
150
|
+
|
|
151
|
+
// Status messages
|
|
152
|
+
const statusMessages = {
|
|
153
|
+
operational: 'All Systems Operational',
|
|
154
|
+
degraded: 'Performance Issues Detected',
|
|
155
|
+
partial_outage: 'Some Services Unavailable',
|
|
156
|
+
major_outage: 'Critical System Failure',
|
|
157
|
+
maintenance: 'Planned Maintenance Window'
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const affectedCounts = {
|
|
161
|
+
operational: 0,
|
|
162
|
+
degraded: 3,
|
|
163
|
+
partial_outage: 7,
|
|
164
|
+
major_outage: 12,
|
|
165
|
+
maintenance: 5
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Handle button clicks
|
|
169
|
+
controls.querySelectorAll('.demo-button').forEach(button => {
|
|
170
|
+
button.addEventListener('click', () => {
|
|
171
|
+
const status = button.getAttribute('data-status') as keyof typeof statusMessages;
|
|
172
|
+
statusBar.overallStatus = {
|
|
173
|
+
status: status as any,
|
|
174
|
+
message: statusMessages[status],
|
|
175
|
+
lastUpdated: Date.now(),
|
|
176
|
+
affectedServices: affectedCounts[status],
|
|
177
|
+
totalServices: 15
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}}
|
|
182
|
+
>
|
|
183
|
+
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
|
184
|
+
</dees-demowrapper>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
<!-- Loading States -->
|
|
188
|
+
<div class="demo-section">
|
|
189
|
+
<div class="demo-title">Loading and Refresh States</div>
|
|
190
|
+
<dees-demowrapper
|
|
191
|
+
.runAfterRender=${async (wrapperElement: any) => {
|
|
192
|
+
const statusBar = wrapperElement.querySelector('upl-statuspage-statusbar') as any;
|
|
193
|
+
|
|
194
|
+
// Initial loading
|
|
195
|
+
statusBar.loading = true;
|
|
196
|
+
|
|
197
|
+
const controls = document.createElement('div');
|
|
198
|
+
controls.className = 'demo-controls';
|
|
199
|
+
controls.innerHTML = `
|
|
200
|
+
<button class="demo-button" id="toggleLoading">Toggle Loading</button>
|
|
201
|
+
<button class="demo-button" id="refresh">Refresh Status</button>
|
|
202
|
+
<button class="demo-button" id="simulateError">Simulate Error</button>
|
|
203
|
+
`;
|
|
204
|
+
wrapperElement.appendChild(controls);
|
|
205
|
+
|
|
206
|
+
// Set initial status after loading
|
|
207
|
+
setTimeout(() => {
|
|
208
|
+
statusBar.loading = false;
|
|
209
|
+
statusBar.overallStatus = {
|
|
210
|
+
status: 'operational',
|
|
211
|
+
message: 'All Systems Operational',
|
|
212
|
+
lastUpdated: Date.now(),
|
|
213
|
+
affectedServices: 0,
|
|
214
|
+
totalServices: 10
|
|
215
|
+
};
|
|
216
|
+
}, 2000);
|
|
217
|
+
|
|
218
|
+
// Toggle loading
|
|
219
|
+
controls.querySelector('#toggleLoading')?.addEventListener('click', () => {
|
|
220
|
+
statusBar.loading = !statusBar.loading;
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Refresh simulation
|
|
224
|
+
controls.querySelector('#refresh')?.addEventListener('click', () => {
|
|
225
|
+
statusBar.loading = true;
|
|
226
|
+
setTimeout(() => {
|
|
227
|
+
statusBar.loading = false;
|
|
228
|
+
// Simulate random status after refresh
|
|
229
|
+
const statuses = ['operational', 'degraded', 'partial_outage'];
|
|
230
|
+
const randomStatus = statuses[Math.floor(Math.random() * statuses.length)];
|
|
231
|
+
statusBar.overallStatus = {
|
|
232
|
+
status: randomStatus as any,
|
|
233
|
+
message: 'Status refreshed at ' + new Date().toLocaleTimeString(),
|
|
234
|
+
lastUpdated: Date.now(),
|
|
235
|
+
affectedServices: randomStatus === 'operational' ? 0 : Math.floor(Math.random() * 5) + 1,
|
|
236
|
+
totalServices: 10
|
|
237
|
+
};
|
|
238
|
+
}, 1000);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Error simulation
|
|
242
|
+
controls.querySelector('#simulateError')?.addEventListener('click', () => {
|
|
243
|
+
statusBar.loading = true;
|
|
244
|
+
setTimeout(() => {
|
|
245
|
+
statusBar.loading = false;
|
|
246
|
+
statusBar.overallStatus = {
|
|
247
|
+
status: 'major_outage',
|
|
248
|
+
message: 'Unable to fetch status - Connection Error',
|
|
249
|
+
lastUpdated: Date.now(),
|
|
250
|
+
affectedServices: -1, // Unknown
|
|
251
|
+
totalServices: -1
|
|
252
|
+
};
|
|
253
|
+
}, 1500);
|
|
254
|
+
});
|
|
255
|
+
}}
|
|
256
|
+
>
|
|
257
|
+
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
|
258
|
+
</dees-demowrapper>
|
|
259
|
+
</div>
|
|
260
|
+
|
|
261
|
+
<!-- Edge Cases -->
|
|
262
|
+
<div class="demo-section">
|
|
263
|
+
<div class="demo-title">Edge Cases and Special States</div>
|
|
264
|
+
<dees-demowrapper
|
|
265
|
+
.runAfterRender=${async (wrapperElement: any) => {
|
|
266
|
+
const statusBar = wrapperElement.querySelector('upl-statuspage-statusbar') as any;
|
|
267
|
+
|
|
268
|
+
const edgeCases = [
|
|
269
|
+
{
|
|
270
|
+
label: 'No Services',
|
|
271
|
+
status: {
|
|
272
|
+
status: 'operational',
|
|
273
|
+
message: 'No services to monitor',
|
|
274
|
+
lastUpdated: Date.now(),
|
|
275
|
+
affectedServices: 0,
|
|
276
|
+
totalServices: 0
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
label: 'All Services Down',
|
|
281
|
+
status: {
|
|
282
|
+
status: 'major_outage',
|
|
283
|
+
message: 'Complete System Failure',
|
|
284
|
+
lastUpdated: Date.now(),
|
|
285
|
+
affectedServices: 25,
|
|
286
|
+
totalServices: 25
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
label: 'Very Long Message',
|
|
291
|
+
status: {
|
|
292
|
+
status: 'degraded',
|
|
293
|
+
message: 'Multiple services experiencing degraded performance due to increased load from seasonal traffic surge',
|
|
294
|
+
lastUpdated: Date.now(),
|
|
295
|
+
affectedServices: 7,
|
|
296
|
+
totalServices: 20
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
label: 'Old Timestamp',
|
|
301
|
+
status: {
|
|
302
|
+
status: 'operational',
|
|
303
|
+
message: 'Status data may be stale',
|
|
304
|
+
lastUpdated: Date.now() - 24 * 60 * 60 * 1000, // 24 hours ago
|
|
305
|
+
affectedServices: 0,
|
|
306
|
+
totalServices: 10
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
label: 'Future Maintenance',
|
|
311
|
+
status: {
|
|
312
|
+
status: 'maintenance',
|
|
313
|
+
message: 'Scheduled maintenance starting in 2 hours',
|
|
314
|
+
lastUpdated: Date.now(),
|
|
315
|
+
affectedServices: 0,
|
|
316
|
+
totalServices: 15
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
];
|
|
320
|
+
|
|
321
|
+
let currentCase = 0;
|
|
322
|
+
statusBar.overallStatus = edgeCases[0].status;
|
|
323
|
+
|
|
324
|
+
// Create info display
|
|
325
|
+
const info = document.createElement('div');
|
|
326
|
+
info.className = 'status-info';
|
|
327
|
+
info.innerHTML = `<strong>Current Case:</strong> ${edgeCases[0].label}`;
|
|
328
|
+
wrapperElement.appendChild(info);
|
|
329
|
+
|
|
330
|
+
// Create controls
|
|
331
|
+
const controls = document.createElement('div');
|
|
332
|
+
controls.className = 'demo-controls';
|
|
333
|
+
controls.innerHTML = `
|
|
334
|
+
<button class="demo-button" id="prevCase">← Previous Case</button>
|
|
335
|
+
<button class="demo-button" id="nextCase">Next Case →</button>
|
|
336
|
+
`;
|
|
337
|
+
wrapperElement.appendChild(controls);
|
|
338
|
+
|
|
339
|
+
const updateCase = (index: number) => {
|
|
340
|
+
currentCase = index;
|
|
341
|
+
statusBar.overallStatus = edgeCases[currentCase].status;
|
|
342
|
+
info.innerHTML = `<strong>Current Case:</strong> ${edgeCases[currentCase].label}`;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
controls.querySelector('#prevCase')?.addEventListener('click', () => {
|
|
346
|
+
const newIndex = (currentCase - 1 + edgeCases.length) % edgeCases.length;
|
|
347
|
+
updateCase(newIndex);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
controls.querySelector('#nextCase')?.addEventListener('click', () => {
|
|
351
|
+
const newIndex = (currentCase + 1) % edgeCases.length;
|
|
352
|
+
updateCase(newIndex);
|
|
353
|
+
});
|
|
354
|
+
}}
|
|
355
|
+
>
|
|
356
|
+
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
|
357
|
+
</dees-demowrapper>
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
<!-- Non-Expandable Status Bar -->
|
|
361
|
+
<div class="demo-section">
|
|
362
|
+
<div class="demo-title">Non-Expandable Status Bar</div>
|
|
363
|
+
<dees-demowrapper
|
|
364
|
+
.runAfterRender=${async (wrapperElement: any) => {
|
|
365
|
+
const statusBar = wrapperElement.querySelector('upl-statuspage-statusbar') as any;
|
|
366
|
+
|
|
367
|
+
// Disable expandable behavior
|
|
368
|
+
statusBar.expandable = false;
|
|
369
|
+
|
|
370
|
+
statusBar.overallStatus = {
|
|
371
|
+
status: 'operational',
|
|
372
|
+
message: 'This status bar cannot be clicked',
|
|
373
|
+
lastUpdated: Date.now(),
|
|
374
|
+
affectedServices: 0,
|
|
375
|
+
totalServices: 8
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
// This event won't fire since expandable is false
|
|
379
|
+
statusBar.addEventListener('statusClick', (event: CustomEvent) => {
|
|
380
|
+
console.log('This should not fire');
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const info = document.createElement('div');
|
|
384
|
+
info.className = 'status-info';
|
|
385
|
+
info.innerHTML = 'Try clicking the status bar - it should not respond to clicks when expandable=false';
|
|
386
|
+
wrapperElement.appendChild(info);
|
|
387
|
+
}}
|
|
388
|
+
>
|
|
389
|
+
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
|
390
|
+
</dees-demowrapper>
|
|
391
|
+
</div>
|
|
392
|
+
</div>
|
|
393
|
+
`;
|