import { DeesElement, customElement, html, css, cssManager, property, type TemplateResult, } from '@design.estate/dees-element'; declare global { interface HTMLElementTagNameMap { 'sz-resource-usage-card': SzResourceUsageCard; } } export interface IResourceUsage { cpu: number; memoryUsed: string; memoryTotal: string; networkIn: string; networkOut: string; topConsumers: Array<{ name: string; memory: string }>; } @customElement('sz-resource-usage-card') export class SzResourceUsageCard extends DeesElement { public static demo = () => html`
`; public static demoGroups = ['Dashboard']; @property({ type: Object }) public accessor data: IResourceUsage = { cpu: 0, memoryUsed: '0 MB', memoryTotal: '0 GB', networkIn: '0 KB/s', networkOut: '0 KB/s', topConsumers: [], }; @property({ type: String }) public accessor serviceCount: string = '0'; public static styles = [ cssManager.defaultStyles, css` :host { display: block; height: 100%; } .card { background: ${cssManager.bdTheme('#ffffff', '#09090b')}; border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')}; border-radius: 8px; padding: 20px; height: 100%; box-sizing: border-box; } .header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 16px; } .title { font-size: 16px; font-weight: 600; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .subtitle { font-size: 13px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; margin-top: 2px; } .view-all { font-size: 13px; color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')}; text-decoration: none; cursor: pointer; } .view-all:hover { text-decoration: underline; } .metrics { display: flex; flex-direction: column; gap: 16px; } .metric-row { display: flex; flex-direction: column; gap: 6px; } .metric-header { display: flex; justify-content: space-between; align-items: center; } .metric-label { font-size: 14px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; } .metric-value { font-size: 14px; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .progress-bar { height: 6px; background: ${cssManager.bdTheme('#f4f4f5', '#27272a')}; border-radius: 3px; overflow: hidden; } .progress-fill { height: 100%; background: ${cssManager.bdTheme('#3b82f6', '#60a5fa')}; border-radius: 3px; transition: width 300ms ease; } .network-row { display: flex; gap: 16px; align-items: center; } .network-item { display: flex; align-items: center; gap: 4px; font-size: 14px; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .network-icon { width: 14px; height: 14px; } .network-icon.down { color: ${cssManager.bdTheme('#16a34a', '#22c55e')}; } .network-icon.up { color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')}; } .top-consumers { margin-top: 8px; padding-top: 12px; border-top: 1px solid ${cssManager.bdTheme('#f4f4f5', '#27272a')}; } .consumers-label { font-size: 13px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; margin-bottom: 6px; } .consumers-list { display: flex; flex-wrap: wrap; gap: 12px; } .consumer-item { font-size: 13px; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .consumer-name { color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; } `, ]; public render(): TemplateResult { return html`
Resource Usage
Aggregated across ${this.serviceCount} services
View All
CPU ${this.data.cpu.toFixed(1)}%
Memory ${this.data.memoryUsed} / ${this.data.memoryTotal}
Network
${this.data.networkIn} ${this.data.networkOut}
${this.data.topConsumers.length > 0 ? html`
Top consumers
${this.data.topConsumers.map( (consumer) => html` ${consumer.name}: ${consumer.memory} ` )}
` : ''}
`; } private calculateMemoryPercent(): number { // Simple extraction of numbers - in real app would parse properly const used = parseFloat(this.data.memoryUsed); const total = parseFloat(this.data.memoryTotal); if (total === 0) return 0; // Assuming both are in same unit for demo return Math.min((used / total) * 100, 100); } }