import * as colors from '../../00colors.js'; import * as plugins from '../../00plugins.js'; import { demoFunc } from './dees-dataview-statusobject.demo.js'; import { DeesElement, html, customElement, type TemplateResult, property, state, cssManager, css, type CSSResult, } from '@design.estate/dees-element'; import * as tsclass from '@tsclass/tsclass'; import { DeesContextmenu } from '../../00group-overlay/dees-contextmenu/dees-contextmenu.js'; import { themeDefaultStyles } from '../../00theme.js'; import '../../00group-layout/dees-tile/dees-tile.js'; declare global { interface HTMLElementTagNameMap { 'dees-dataview-statusobject': DeesDataviewStatusobject; } } @customElement('dees-dataview-statusobject') export class DeesDataviewStatusobject extends DeesElement { public static demo = demoFunc; public static demoGroups = ['Data View']; @property({ type: Object }) accessor statusObject!: tsclass.code.IStatusObject; public static styles = [ themeDefaultStyles, cssManager.defaultStyles, css` /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; } dees-tile { color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 98%)')}; cursor: default; } .heading { display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 16px; } h1 { display: block; margin: 0; padding: 0; font-size: 14px; font-weight: 500; letter-spacing: -0.01em; color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 63.9%)')}; flex: 1; } .statusdot { height: 10px; width: 10px; border-radius: 50%; background: ${cssManager.bdTheme('hsl(0 0% 63.9%)', 'hsl(0 0% 45.1%)')}; margin: auto; box-shadow: 0 0 0 3px ${cssManager.bdTheme('hsl(0 0% 63.9% / 0.2)', 'hsl(0 0% 45.1% / 0.2)')}; transition: all 0.2s ease; } .copyMain { font-size: 11px; font-weight: 500; background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 14.9%)')}; border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; text-align: center; padding: 4px 10px; border-radius: 4px; color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')}; user-select: none; cursor: pointer; transition: all 0.15s ease; } .copyMain:hover { background: ${cssManager.bdTheme('hsl(0 0% 95.1%)', 'hsl(0 0% 14.9%)')}; border-color: ${cssManager.bdTheme('hsl(0 0% 79.8%)', 'hsl(0 0% 20.9%)')}; color: ${cssManager.bdTheme('hsl(0 0% 15%)', 'hsl(0 0% 93.9%)')}; } .copyMain:active { background: ${cssManager.bdTheme('hsl(0 0% 91%)', 'hsl(0 0% 14.9%)')}; transform: scale(0.98); } .statusdot.ok { background: ${cssManager.bdTheme('hsl(142.1 76.2% 36.3%)', 'hsl(142.1 70.6% 45.3%)')}; box-shadow: 0 0 0 3px ${cssManager.bdTheme('hsl(142.1 76.2% 36.3% / 0.2)', 'hsl(142.1 70.6% 45.3% / 0.2)')}; } .statusdot.not_ok { background: ${cssManager.bdTheme('hsl(0 84.2% 60.2%)', 'hsl(0 72.2% 50.6%)')}; box-shadow: 0 0 0 3px ${cssManager.bdTheme('hsl(0 84.2% 60.2% / 0.2)', 'hsl(0 72.2% 50.6% / 0.2)')}; } .statusdot.partly_ok { background: ${cssManager.bdTheme('hsl(25 95% 53%)', 'hsl(25 95% 63%)')}; box-shadow: 0 0 0 3px ${cssManager.bdTheme('hsl(25 95% 53% / 0.2)', 'hsl(25 95% 63% / 0.2)')}; } .detail { display: flex; align-items: center; gap: 10px; height: 36px; padding: 0 16px; border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(0 0% 10%)')}; transition: background-color 0.15s ease; cursor: context-menu; } .detail:last-child { border-bottom: none; } .detail:hover { background: ${cssManager.bdTheme('hsl(222.2 47.4% 51.2% / 0.04)', 'hsl(217.2 91.2% 59.8% / 0.06)')}; } .detail .statusdot { margin: 0; flex-shrink: 0; } .detail .detailsText { display: flex; align-items: baseline; flex: 1; min-width: 0; } .detail .detailsText .label { font-size: 12px; font-weight: 500; color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')}; letter-spacing: -0.01em; white-space: nowrap; flex-shrink: 0; } .detail .detailsText .value { font-size: 13px; font-family: 'Intel One Mono', 'Geist Mono', monospace; color: ${cssManager.bdTheme('hsl(0 0% 15%)', 'hsl(0 0% 90%)')}; margin-left: auto; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .bottomBar { color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')}; height: 28px; font-size: 11px; line-height: 28px; display: flex; justify-content: flex-end; align-items: center; padding: 0 16px; width: 100%; box-sizing: border-box; } .bottomBar .statusLabel { font-weight: 500; } `, ]; render(): TemplateResult { return html`

${this.statusObject?.name || 'No status object assigned'}

Copy JSON
${this.statusObject?.details?.map((detailArg) => { return html`
{ event.preventDefault(); DeesContextmenu.openContextMenuWithOptions(event, [ { name: 'Copy Value', iconName: 'lucide:copy', action: async () => { await this.copyToClipboard(detailArg.value, 'Value'); }, }, { name: 'Copy Key', iconName: 'lucide:key', action: async () => { await this.copyToClipboard(detailArg.name, 'Key'); }, }, { name: 'Copy Key:Value', iconName: 'lucide:copy-plus', action: async () => { await this.copyToClipboard(`${detailArg.name}: ${detailArg.value}`, 'Key:Value'); }, }, ]); }} >
${detailArg.name} ${detailArg.value}
`; })}
${this.statusObject?.lastUpdated ? `Last updated: ${new Date(this.statusObject.lastUpdated).toLocaleString()}` : ''}
`; } async firstUpdated() {} private async copyToClipboard(text: string, type: string = 'Text') { try { await navigator.clipboard.writeText(text); console.log(`${type} copied to clipboard`); // You could add visual feedback here if needed } catch (err) { console.error(`Failed to copy ${type}:`, err); } } private async handleCopyAsJson() { if (!this.statusObject) return; try { await navigator.clipboard.writeText(JSON.stringify(this.statusObject, null, 2)); // Show feedback const button = this.shadowRoot!.querySelector('.copyMain') as HTMLElement; const originalText = button.textContent; button.textContent = 'Copied!'; // Apply success styles based on theme const isDark = !this.goBright; button.style.background = isDark ? 'hsl(142.1 70.6% 45.3% / 0.1)' : 'hsl(142.1 76.2% 36.3% / 0.1)'; button.style.borderColor = isDark ? 'hsl(142.1 70.6% 45.3%)' : 'hsl(142.1 76.2% 36.3%)'; button.style.color = isDark ? 'hsl(142.1 70.6% 45.3%)' : 'hsl(142.1 76.2% 36.3%)'; setTimeout(() => { button.textContent = originalText; button.style.background = ''; button.style.borderColor = ''; button.style.color = ''; }, 1500); } catch (err) { console.error('Failed to copy:', err); } } }