import { DeesElement, property, html, customElement, type TemplateResult, cssManager, css, unsafeCSS, } from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; import type { IServiceStatus } 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-assetsselector.demo.js'; declare global { interface HTMLElementTagNameMap { 'upl-statuspage-assetsselector': UplStatuspageAssetsselector; } } @customElement('upl-statuspage-assetsselector') export class UplStatuspageAssetsselector extends DeesElement { public static demo = demoFunc; @property({ type: Array }) public services: IServiceStatus[] = []; @property({ type: String }) public filterText: string = ''; @property({ type: String }) public filterCategory: string = 'all'; @property({ type: Boolean }) public showOnlySelected: boolean = false; @property({ type: Boolean }) public loading: boolean = false; @property({ type: Boolean }) public expanded: boolean = false; constructor() { super(); } public static styles = [ cssManager.defaultStyles, commonStyles, css` :host { 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)}; } .controls { display: flex; gap: ${unsafeCSS(spacing.sm)}; margin-bottom: ${unsafeCSS(spacing.md)}; flex-wrap: wrap; align-items: center; } .search-input { flex: 1; min-width: 200px; padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.sm)}; border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; border-radius: ${unsafeCSS(borderRadius.base)}; background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')}; color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; font-size: 13px; font-family: ${unsafeCSS(fonts.base)}; transition: all 0.2s ease; height: 32px; } .search-input:focus { outline: none; border-color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; } .search-input::placeholder { color: ${cssManager.bdTheme('#9ca3af', '#71717a')}; } .filter-button { display: inline-flex; align-items: center; justify-content: center; padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.sm)}; border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; border-radius: ${unsafeCSS(borderRadius.base)}; background: transparent; color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')}; cursor: pointer; font-size: 13px; font-weight: 400; font-family: ${unsafeCSS(fonts.base)}; transition: all 0.2s ease; height: 32px; } .filter-button:hover { border-color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; } .filter-button.active { background: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; color: ${cssManager.bdTheme('#fafafa', '#0a0a0a')}; border-color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; } .selected-services { display: flex; flex-wrap: wrap; gap: ${unsafeCSS(spacing.sm)}; align-items: center; } .service-pill { display: inline-flex; align-items: center; gap: ${unsafeCSS(spacing.xs)}; padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.md)}; background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')}; border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; border-radius: ${unsafeCSS(borderRadius.full)}; font-size: 13px; transition: all 0.2s ease; } .service-pill:hover { border-color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; } .service-pill .status-dot { width: 6px; height: 6px; border-radius: 50%; } .manage-button { display: inline-flex; align-items: center; gap: ${unsafeCSS(spacing.xs)}; padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.md)}; background: transparent; border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; border-radius: ${unsafeCSS(borderRadius.base)}; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')}; font-family: ${unsafeCSS(fonts.base)}; } .manage-button:hover { border-color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; } .expandable-section { margin-top: ${unsafeCSS(spacing.lg)}; overflow: hidden; transition: all 0.3s ease; } .expandable-content { padding: ${unsafeCSS(spacing.lg)}; background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')}; border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; border-radius: ${unsafeCSS(borderRadius.base)}; } .assets-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: ${unsafeCSS(spacing.sm)}; margin-top: ${unsafeCSS(spacing.md)}; } .asset-card { display: flex; align-items: center; padding: ${unsafeCSS(spacing.sm)} ${unsafeCSS(spacing.md)}; background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')}; border-radius: ${unsafeCSS(borderRadius.base)}; cursor: pointer; transition: all 0.2s ease; border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; gap: ${unsafeCSS(spacing.sm)}; } .asset-card:hover { border-color: ${cssManager.bdTheme('#d1d5db', '#3f3f46')}; } .asset-card.selected { border-color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; background: ${cssManager.bdTheme('#f9fafb', '#0f0f0f')}; } .asset-checkbox { width: 16px; height: 16px; cursor: pointer; accent-color: ${colors.text.primary}; flex-shrink: 0; } .asset-info { flex: 1; min-width: 0; } .asset-name { font-weight: 600; font-size: 14px; margin-bottom: ${unsafeCSS(spacing.xs)}; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .asset-description { font-size: 13px; color: ${colors.text.secondary}; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .asset-status { display: flex; align-items: center; gap: ${unsafeCSS(spacing.xs)}; flex-shrink: 0; } .status-indicator { width: 8px; height: 8px; border-radius: ${unsafeCSS(borderRadius.full)}; } .status-indicator.operational, .status-dot.operational { background: #22c55e; } .status-indicator.degraded, .status-dot.degraded { background: #fbbf24; } .status-indicator.partial_outage, .status-dot.partial_outage { background: #f87171; } .status-indicator.major_outage, .status-dot.major_outage { background: #ef4444; } .status-indicator.maintenance, .status-dot.maintenance { background: #60a5fa; } .status-text { font-size: 12px; text-transform: capitalize; color: ${colors.text.secondary}; } .loading-message, .no-results { grid-column: 1 / -1; text-align: center; padding: ${unsafeCSS(spacing.xl)}; color: ${cssManager.bdTheme('#9ca3af', '#71717a')}; font-size: 13px; } .summary { text-align: right; font-size: 12px; margin-top: ${unsafeCSS(spacing.md)}; color: ${cssManager.bdTheme('#9ca3af', '#71717a')}; } .no-services { padding: ${unsafeCSS(spacing.xl)}; text-align: center; color: ${cssManager.bdTheme('#9ca3af', '#71717a')}; font-size: 13px; } @media (max-width: 640px) { .container { padding: 0 ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)}; } .controls { flex-direction: column; align-items: stretch; } .search-input { width: 100%; } .selected-services { flex-direction: column; align-items: stretch; } .service-pill { width: auto; } .expandable-content { padding: ${unsafeCSS(spacing.md)}; } .assets-grid { grid-template-columns: 1fr; } .asset-card { padding: ${unsafeCSS(spacing.sm)}; } } `, ] public render(): TemplateResult { const selectedServices = this.services.filter(s => s.selected); const selectedCount = selectedServices.length; const categories = this.getUniqueCategories(); return html`