feat(statuspage-incidents): Add status icons/labels and revamp incident header layout; replace left border with internal severity bar and clean up formatting
This commit is contained in:
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-12-24 - 1.4.0 - feat(statuspage-incidents)
|
||||||
|
Add status icons/labels and revamp incident header layout; replace left border with internal severity bar and clean up formatting
|
||||||
|
|
||||||
|
- Introduce TIncidentStatus and mappings for statusIcons and statusLabels for consistent iconography and human-readable labels
|
||||||
|
- Update incident header layout to match admin catalog (adjust padding, alignment, spacing)
|
||||||
|
- Replace border-left severity indicator with an internal .incident-severity element and apply severity-specific styles
|
||||||
|
- Minor code/style cleanups: whitespace fixes in formatDate/formatDuration and normalized event detail object formatting
|
||||||
|
|
||||||
## 2025-12-23 - 1.3.1 - fix(statuspage)
|
## 2025-12-23 - 1.3.1 - fix(statuspage)
|
||||||
update timeline connector and dot positioning in statuspage incidents component
|
update timeline connector and dot positioning in statuspage incidents component
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@uptime.link/statuspage',
|
name: '@uptime.link/statuspage',
|
||||||
version: '1.3.1',
|
version: '1.4.0',
|
||||||
description: 'A catalog of web components for the UptimeLink dashboard.'
|
description: 'A catalog of web components for the UptimeLink dashboard.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TIncidentStatus = 'investigating' | 'identified' | 'monitoring' | 'resolved' | 'postmortem';
|
||||||
|
|
||||||
@customElement('upl-statuspage-incidents')
|
@customElement('upl-statuspage-incidents')
|
||||||
export class UplStatuspageIncidents extends DeesElement {
|
export class UplStatuspageIncidents extends DeesElement {
|
||||||
// STATIC
|
// STATIC
|
||||||
@@ -68,6 +70,22 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
})
|
})
|
||||||
private accessor subscribedIncidents: Set<string> = new Set();
|
private accessor subscribedIncidents: Set<string> = new Set();
|
||||||
|
|
||||||
|
private statusIcons: Record<TIncidentStatus, string> = {
|
||||||
|
investigating: 'lucide:Search',
|
||||||
|
identified: 'lucide:Target',
|
||||||
|
monitoring: 'lucide:Eye',
|
||||||
|
resolved: 'lucide:CheckCircle',
|
||||||
|
postmortem: 'lucide:FileText',
|
||||||
|
};
|
||||||
|
|
||||||
|
private statusLabels: Record<TIncidentStatus, string> = {
|
||||||
|
investigating: 'Investigating',
|
||||||
|
identified: 'Identified',
|
||||||
|
monitoring: 'Monitoring',
|
||||||
|
resolved: 'Resolved',
|
||||||
|
postmortem: 'Postmortem',
|
||||||
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@@ -171,112 +189,151 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* New header layout matching admin catalog */
|
||||||
.incident-header {
|
.incident-header {
|
||||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.xl)};
|
|
||||||
border-left: 4px solid;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: start;
|
align-items: flex-start;
|
||||||
justify-content: space-between;
|
gap: 16px;
|
||||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
padding: 16px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
|
transition: background-color ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-header:hover {
|
.incident-header:hover {
|
||||||
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.02)', 'rgba(255, 255, 255, 0.02)')};
|
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.02)', 'rgba(255, 255, 255, 0.02)')};
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-header.critical {
|
/* Internal severity bar (replacing border-left) */
|
||||||
border-left-color: ${sharedStyles.colors.status.major};
|
.incident-severity {
|
||||||
|
width: 4px;
|
||||||
|
align-self: stretch;
|
||||||
|
border-radius: 2px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-header.major {
|
.incident-severity.critical { background: ${sharedStyles.colors.status.major}; }
|
||||||
border-left-color: ${sharedStyles.colors.status.partial};
|
.incident-severity.major { background: ${sharedStyles.colors.status.partial}; }
|
||||||
|
.incident-severity.minor { background: ${sharedStyles.colors.status.degraded}; }
|
||||||
|
.incident-severity.maintenance { background: ${sharedStyles.colors.status.maintenance}; }
|
||||||
|
|
||||||
|
.incident-main {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-header.minor {
|
.incident-title-row {
|
||||||
border-left-color: ${sharedStyles.colors.status.degraded};
|
|
||||||
}
|
|
||||||
|
|
||||||
.incident-header.maintenance {
|
|
||||||
border-left-color: ${sharedStyles.colors.status.maintenance};
|
|
||||||
}
|
|
||||||
|
|
||||||
.incident-title {
|
|
||||||
font-size: 17px;
|
|
||||||
font-weight: 600;
|
|
||||||
margin: 0;
|
|
||||||
line-height: 1.4;
|
|
||||||
letter-spacing: -0.01em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.incident-meta {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: ${unsafeCSS(sharedStyles.spacing.lg)};
|
align-items: center;
|
||||||
margin-top: ${unsafeCSS(sharedStyles.spacing.sm)};
|
gap: 8px;
|
||||||
font-size: 13px;
|
margin-bottom: 6px;
|
||||||
color: ${sharedStyles.colors.text.secondary};
|
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-meta span {
|
.incident-title {
|
||||||
display: flex;
|
font-size: 15px;
|
||||||
align-items: center;
|
font-weight: 600;
|
||||||
gap: 4px;
|
margin: 0;
|
||||||
|
color: ${sharedStyles.colors.text.primary};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Status badge inline with title */
|
||||||
.incident-status {
|
.incident-status {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 6px 12px;
|
padding: 4px 10px;
|
||||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.full)};
|
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-weight: 600;
|
font-weight: 500;
|
||||||
|
border-radius: 9999px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.04em;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
|
}
|
||||||
|
|
||||||
|
.incident-status dees-icon {
|
||||||
|
--icon-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-status.investigating {
|
.incident-status.investigating {
|
||||||
background: ${cssManager.bdTheme('#fef3c7', '#78350f')};
|
background: ${cssManager.bdTheme('rgba(249, 115, 22, 0.1)', 'rgba(249, 115, 22, 0.2)')};
|
||||||
color: ${cssManager.bdTheme('#92400e', '#fbbf24')};
|
color: ${cssManager.bdTheme('#ea580c', '#fb923c')};
|
||||||
|
--icon-color: ${cssManager.bdTheme('#ea580c', '#fb923c')};
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-status.identified {
|
.incident-status.identified {
|
||||||
background: ${cssManager.bdTheme('#e9d5ff', '#581c87')};
|
background: ${cssManager.bdTheme('rgba(234, 179, 8, 0.1)', 'rgba(234, 179, 8, 0.2)')};
|
||||||
color: ${cssManager.bdTheme('#6b21a8', '#d8b4fe')};
|
color: ${cssManager.bdTheme('#ca8a04', '#facc15')};
|
||||||
|
--icon-color: ${cssManager.bdTheme('#ca8a04', '#facc15')};
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-status.monitoring {
|
.incident-status.monitoring {
|
||||||
background: ${cssManager.bdTheme('#dbeafe', '#1e3a8a')};
|
background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.1)', 'rgba(59, 130, 246, 0.2)')};
|
||||||
color: ${cssManager.bdTheme('#1e40af', '#93c5fd')};
|
color: ${cssManager.bdTheme('#2563eb', '#60a5fa')};
|
||||||
|
--icon-color: ${cssManager.bdTheme('#2563eb', '#60a5fa')};
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-status.resolved {
|
.incident-status.resolved {
|
||||||
background: ${cssManager.bdTheme('#d1fae5', '#064e3b')};
|
background: ${cssManager.bdTheme('rgba(34, 197, 94, 0.1)', 'rgba(34, 197, 94, 0.2)')};
|
||||||
color: ${cssManager.bdTheme('#047857', '#6ee7b7')};
|
color: ${cssManager.bdTheme('#16a34a', '#4ade80')};
|
||||||
|
--icon-color: ${cssManager.bdTheme('#16a34a', '#4ade80')};
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-status.postmortem {
|
.incident-status.postmortem {
|
||||||
background: ${cssManager.bdTheme('#e5e7eb', '#374151')};
|
background: ${cssManager.bdTheme('rgba(168, 85, 247, 0.1)', 'rgba(168, 85, 247, 0.2)')};
|
||||||
color: ${cssManager.bdTheme('#4b5563', '#d1d5db')};
|
color: ${cssManager.bdTheme('#9333ea', '#c084fc')};
|
||||||
|
--icon-color: ${cssManager.bdTheme('#9333ea', '#c084fc')};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pulse for investigating status */
|
.incident-meta {
|
||||||
.incident-status.investigating .status-dot {
|
display: flex;
|
||||||
animation: status-pulse 1.5s ease-in-out infinite;
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: ${sharedStyles.colors.text.secondary};
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes status-pulse {
|
.incident-meta-item {
|
||||||
0%, 100% { opacity: 1; transform: scale(1); }
|
display: flex;
|
||||||
50% { opacity: 0.6; transform: scale(1.2); }
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.incident-meta-item dees-icon {
|
||||||
|
--icon-size: 12px;
|
||||||
|
--icon-color: ${sharedStyles.colors.text.muted};
|
||||||
|
}
|
||||||
|
|
||||||
|
.incident-expand {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: ${sharedStyles.colors.text.muted};
|
||||||
|
transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.incident-expand:hover {
|
||||||
|
background: ${sharedStyles.colors.background.muted};
|
||||||
|
color: ${sharedStyles.colors.text.primary};
|
||||||
|
}
|
||||||
|
|
||||||
|
.incident-expand dees-icon {
|
||||||
|
--icon-size: 16px;
|
||||||
|
transition: transform ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.incident-expand.expanded dees-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-body {
|
.incident-body {
|
||||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.xl)} ${unsafeCSS(sharedStyles.spacing.xl)} ${unsafeCSS(sharedStyles.spacing.xl)};
|
padding: 0 16px 16px 36px;
|
||||||
animation: slideDown 0.3s ${unsafeCSS(sharedStyles.easings.default)};
|
animation: slideDown 0.3s ${unsafeCSS(sharedStyles.easings.default)};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,8 +419,6 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vertical connector line from each dot to the next */
|
|
||||||
/* Dot: left -22px, width 12px + border 2px*2 = 16px total, center at -14px */
|
|
||||||
.update-item:not(:last-child)::after {
|
.update-item:not(:last-child)::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -374,7 +429,6 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
background: ${sharedStyles.colors.border.default};
|
background: ${sharedStyles.colors.border.default};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Timeline dot */
|
|
||||||
.update-item::before {
|
.update-item::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -528,39 +582,23 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
background: ${cssManager.bdTheme('#dcfce7', '#065f46')};
|
background: ${cssManager.bdTheme('#dcfce7', '#065f46')};
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapsed-hint {
|
|
||||||
font-size: 12px;
|
|
||||||
color: ${sharedStyles.colors.text.secondary};
|
|
||||||
text-align: center;
|
|
||||||
margin-top: ${unsafeCSS(sharedStyles.spacing.md)};
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expand icon animation */
|
|
||||||
.expand-icon {
|
|
||||||
transition: transform ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
|
|
||||||
}
|
|
||||||
|
|
||||||
.expand-icon.rotated {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.container {
|
.container {
|
||||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
|
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-header {
|
.incident-header {
|
||||||
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
padding: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-body {
|
.incident-body {
|
||||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
|
padding: 0 12px 12px 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.incident-meta {
|
.incident-meta {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline {
|
.timeline {
|
||||||
@@ -573,7 +611,6 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
height: 10px;
|
height: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mobile dot: left -18px, width 10px + border 2px*2 = 14px, center at -11px */
|
|
||||||
.update-item:not(:last-child)::after {
|
.update-item:not(:last-child)::after {
|
||||||
left: -12px;
|
left: -12px;
|
||||||
top: 16px;
|
top: 16px;
|
||||||
@@ -621,73 +658,53 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
this.formatDuration(Date.now() - incident.startTime);
|
this.formatDuration(Date.now() - incident.startTime);
|
||||||
|
|
||||||
const isActive = isCurrent && latestUpdate?.status !== 'resolved';
|
const isActive = isCurrent && latestUpdate?.status !== 'resolved';
|
||||||
|
const isExpanded = this.expandedIncidents.has(incident.id);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="incident-card ${this.expandedIncidents.has(incident.id) ? 'expanded' : ''} ${isActive ? 'active-incident' : ''}">
|
<div class="incident-card ${isExpanded ? 'expanded' : ''} ${isActive ? 'active-incident' : ''}">
|
||||||
<div class="incident-header ${incident.severity}" @click=${() => this.toggleIncident(incident.id)}>
|
<div class="incident-header" @click=${() => this.toggleIncident(incident.id)}>
|
||||||
<div>
|
<div class="incident-severity ${incident.severity}"></div>
|
||||||
<h3 class="incident-title">${incident.title}</h3>
|
|
||||||
|
<div class="incident-main">
|
||||||
|
<div class="incident-title-row">
|
||||||
|
<h3 class="incident-title">${incident.title}</h3>
|
||||||
|
<span class="incident-status ${latestUpdate.status}">
|
||||||
|
<dees-icon .icon=${this.statusIcons[latestUpdate.status as TIncidentStatus]} .iconSize=${12}></dees-icon>
|
||||||
|
${this.statusLabels[latestUpdate.status as TIncidentStatus] || latestUpdate.status}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div class="incident-meta">
|
<div class="incident-meta">
|
||||||
<span>Started: ${this.formatDate(incident.startTime)}</span>
|
<span class="incident-meta-item">
|
||||||
<span>Duration: ${duration}</span>
|
<dees-icon .icon=${'lucide:Calendar'} .iconSize=${12}></dees-icon>
|
||||||
${incident.endTime ? html`
|
${this.formatDate(incident.startTime)}
|
||||||
<span>Ended: ${this.formatDate(incident.endTime)}</span>
|
</span>
|
||||||
` : ''}
|
<span class="incident-meta-item">
|
||||||
</div>
|
<dees-icon .icon=${'lucide:Clock'} .iconSize=${12}></dees-icon>
|
||||||
${!this.expandedIncidents.has(incident.id) ? html`
|
${duration}
|
||||||
<div style="
|
</span>
|
||||||
margin-top: ${unsafeCSS(sharedStyles.spacing.sm)};
|
<span class="incident-meta-item">
|
||||||
font-size: 13px;
|
<dees-icon .icon=${'lucide:Server'} .iconSize=${12}></dees-icon>
|
||||||
color: ${sharedStyles.colors.text.secondary};
|
${incident.affectedServices.length} service${incident.affectedServices.length !== 1 ? 's' : ''}
|
||||||
display: flex;
|
</span>
|
||||||
align-items: center;
|
<span class="incident-meta-item">
|
||||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
<dees-icon .icon=${'lucide:MessageSquare'} .iconSize=${12}></dees-icon>
|
||||||
">
|
${incident.updates.length} update${incident.updates.length !== 1 ? 's' : ''}
|
||||||
${incident.impact ? html`
|
</span>
|
||||||
<span style="
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
max-width: 500px;
|
|
||||||
">${incident.impact}</span>
|
|
||||||
` : ''}
|
|
||||||
<span style="
|
|
||||||
font-size: 12px;
|
|
||||||
color: ${cssManager.bdTheme('#9ca3af', '#71717a')};
|
|
||||||
">
|
|
||||||
${incident.updates.length} update${incident.updates.length !== 1 ? 's' : ''}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
</div>
|
|
||||||
<div style="display: flex; align-items: center; gap: ${unsafeCSS(sharedStyles.spacing.md)};">
|
|
||||||
<div class="incident-status ${latestUpdate.status}">
|
|
||||||
${this.getStatusIcon(latestUpdate.status)}
|
|
||||||
${latestUpdate.status.replace(/_/g, ' ')}
|
|
||||||
</div>
|
|
||||||
<div class="expand-icon" style="
|
|
||||||
font-size: 10px;
|
|
||||||
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
|
||||||
transition: transform 0.2s ease;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: ${cssManager.bdTheme('#f3f4f6', '#27272a')};
|
|
||||||
${this.expandedIncidents.has(incident.id) ? 'transform: rotate(180deg);' : ''}
|
|
||||||
">
|
|
||||||
▼
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button class="incident-expand ${isExpanded ? 'expanded' : ''}">
|
||||||
|
<dees-icon .icon=${'lucide:ChevronDown'} .iconSize=${16}></dees-icon>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${this.expandedIncidents.has(incident.id) ? html`
|
${isExpanded ? html`
|
||||||
<div class="incident-body">
|
<div class="incident-body">
|
||||||
<div class="incident-impact">
|
${incident.impact ? html`
|
||||||
<strong>Impact:</strong> ${incident.impact}
|
<div class="incident-impact">
|
||||||
</div>
|
<strong>Impact:</strong> ${incident.impact}
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
|
||||||
${incident.affectedServices.length > 0 ? html`
|
${incident.affectedServices.length > 0 ? html`
|
||||||
<div class="affected-services">
|
<div class="affected-services">
|
||||||
@@ -728,15 +745,10 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
${this.isSubscribedToIncident(incident.id) ? html`
|
${this.isSubscribedToIncident(incident.id) ? html`
|
||||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<dees-icon .icon=${'lucide:Check'} .iconSize=${14}></dees-icon>
|
||||||
<path d="M11.6667 3.5L5.25 9.91667L2.33334 7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
Subscribed to updates
|
Subscribed to updates
|
||||||
` : html`
|
` : html`
|
||||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<dees-icon .icon=${'lucide:Bell'} .iconSize=${14}></dees-icon>
|
||||||
<path d="M10.5 5.25V8.75C10.5 9.34674 10.2629 9.91903 9.84099 10.341C9.41903 10.7629 8.84674 11 8.25 11L3.75 11C3.15326 11 2.58097 10.7629 2.15901 10.341C1.73705 9.91903 1.5 9.34674 1.5 8.75V4.25C1.5 3.65326 1.73705 3.08097 2.15901 2.65901C2.58097 2.23705 3.15326 2 3.75 2H7.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<path d="M9 1.5H12.5M12.5 1.5V5M12.5 1.5L6 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
Subscribe to updates
|
Subscribe to updates
|
||||||
`}
|
`}
|
||||||
</button>
|
</button>
|
||||||
@@ -763,10 +775,7 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
<div class="update-message">${update.message}</div>
|
<div class="update-message">${update.message}</div>
|
||||||
${update.author ? html`
|
${update.author ? html`
|
||||||
<div class="update-author">
|
<div class="update-author">
|
||||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<dees-icon .icon=${'lucide:User'} .iconSize=${12}></dees-icon>
|
||||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
|
||||||
<circle cx="12" cy="7" r="4"></circle>
|
|
||||||
</svg>
|
|
||||||
${update.author}
|
${update.author}
|
||||||
</div>
|
</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
@@ -774,19 +783,6 @@ export class UplStatuspageIncidents extends DeesElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getStatusIcon(status: string): TemplateResult {
|
|
||||||
return html`<span class="status-dot" style="
|
|
||||||
display: inline-block;
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: ${status === 'resolved' ? sharedStyles.colors.status.operational :
|
|
||||||
status === 'monitoring' ? sharedStyles.colors.status.maintenance :
|
|
||||||
status === 'identified' ? sharedStyles.colors.status.degraded :
|
|
||||||
sharedStyles.colors.status.partial};
|
|
||||||
"></span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private formatDate(timestamp: number): string {
|
private formatDate(timestamp: number): string {
|
||||||
const date = new Date(timestamp);
|
const date = new Date(timestamp);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|||||||
Reference in New Issue
Block a user