import * as plugins from '../plugins.js'; import { DeesElement, property, html, customElement, type TemplateResult, css, cssManager, unsafeCSS, } from '@design.estate/dees-element'; import type { IStatusHistoryPoint } from '../interfaces/index.js'; import { fonts, colors, shadows, borderRadius, spacing, commonStyles, getStatusColor } from '../styles/shared.styles.js'; import './internal/uplinternal-miniheading.js'; import { demoFunc } from './upl-statuspage-statusdetails.demo.js'; declare global { interface HTMLElementTagNameMap { 'upl-statuspage-statusdetails': UplStatuspageStatusdetails; } } @customElement('upl-statuspage-statusdetails') export class UplStatuspageStatusdetails extends DeesElement { public static demo = demoFunc; @property({ type: Array }) public historyData: IStatusHistoryPoint[] = []; @property({ type: Array }) public dataPoints: IStatusHistoryPoint[] = []; @property({ type: String }) public serviceId: string = ''; @property({ type: String }) public serviceName: string = 'Service'; @property({ type: Boolean }) public loading: boolean = false; @property({ type: Number }) public hoursToShow: number = 48; constructor() { super(); } public static styles = [ plugins.domtools.elementBasic.staticStyles, commonStyles, css` :host { position: relative; display: block; background: transparent; font-family: ${unsafeCSS(fonts.base)}; color: ${colors.text.primary}; } .container { max-width: 1200px; margin: 0 auto; padding: 0 ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)}; } .graph-wrapper { display: flex; flex-direction: column; gap: 4px; } .graph-container { position: relative; } .mainbox { background: transparent; border: none; border-radius: 0; padding: 0; } .mainbox .barContainer { position: relative; display: flex; gap: 1px; padding: ${unsafeCSS(spacing.sm)}; background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')}; border: 1px solid ${cssManager.bdTheme('#f3f4f6', '#1f1f1f')}; border-radius: ${unsafeCSS(borderRadius.base)}; overflow: hidden; height: 40px; } .mainbox .barContainer .bar { flex: 1; height: 100%; cursor: pointer; transition: opacity 0.15s ease; position: relative; } .mainbox .barContainer .bar:hover { opacity: 0.8; } .mainbox .barContainer .bar.operational { background: ${cssManager.bdTheme('#22c55e', '#22c55e')}; } .mainbox .barContainer .bar.degraded { background: ${cssManager.bdTheme('#fbbf24', '#fbbf24')}; } .mainbox .barContainer .bar.partial_outage { background: ${cssManager.bdTheme('#f87171', '#f87171')}; } .mainbox .barContainer .bar.major_outage { background: ${cssManager.bdTheme('#ef4444', '#ef4444')}; } .mainbox .barContainer .bar.maintenance { background: ${cssManager.bdTheme('#60a5fa', '#60a5fa')}; } .mainbox .barContainer .bar.no-data { background: ${cssManager.bdTheme('#f3f4f6', '#27272a')}; } .time-labels { display: flex; justify-content: space-between; padding: 0; margin-top: ${unsafeCSS(spacing.xs)}; font-size: 10px; color: ${cssManager.bdTheme('#9ca3af', '#71717a')}; font-family: ${unsafeCSS(fonts.base)}; opacity: 0.8; } .tooltip { position: absolute; background: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; color: ${cssManager.bdTheme('#fafafa', '#0a0a0a')}; padding: 6px 10px; border-radius: 4px; font-size: 11px; pointer-events: none; opacity: 0; transition: opacity 0.15s; z-index: 50; white-space: nowrap; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); line-height: 1.4; } .tooltip.visible { opacity: 1; } .tooltip-time { font-weight: 600; display: block; margin-bottom: 2px; } .tooltip-stat { font-size: 10px; opacity: 0.9; } .loading-skeleton { display: flex; gap: 1px; height: 24px; } .loading-skeleton .skeleton-bar { flex: 1; height: 100%; background: ${cssManager.bdTheme('#f3f4f6', '#27272a')}; animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } @keyframes loading { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } .stats-row { display: flex; align-items: center; justify-content: space-between; margin-top: ${unsafeCSS(spacing.lg)}; padding: ${unsafeCSS(spacing.sm)} 0; border-top: 1px solid ${cssManager.bdTheme('#f3f4f6', '#1f1f1f')}; font-size: 12px; } .stat-item { display: flex; align-items: center; gap: ${unsafeCSS(spacing.sm)}; color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')}; } .stat-value { font-weight: 500; color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; font-variant-numeric: tabular-nums; } .status-indicator { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-right: 4px; } @media (max-width: 640px) { .container { padding: 0 ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)}; } .graph-container { padding: ${unsafeCSS(spacing.sm)}; } .mainbox .barContainer { height: 32px; padding: ${unsafeCSS(spacing.xs)}; } .time-labels { font-size: 9px; } .stats-row { font-size: 11px; flex-direction: column; gap: ${unsafeCSS(spacing.sm)}; align-items: flex-start; } } `, ]; public render(): TemplateResult { return html`