/**
* EcoOS Displays View
* Display management with enable/disable/primary controls
*/
import {
html,
DeesElement,
customElement,
property,
state,
css,
type TemplateResult,
} from '@design.estate/dees-element';
import { sharedStyles } from '../styles/shared.js';
import type { IDisplayInfo } from '../../ts_interfaces/display.js';
@customElement('ecoos-displays')
export class EcoosDisplays extends DeesElement {
@property({ type: Array })
public accessor displays: IDisplayInfo[] = [];
@state()
private accessor loading: boolean = false;
public static styles = [
sharedStyles,
css`
:host {
display: block;
padding: 20px;
}
.display-item {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 12px 0;
border-bottom: 1px solid var(--ecoos-border);
}
.display-item:last-child {
border-bottom: none;
}
.display-info {
flex: 1;
min-width: 150px;
}
.display-name {
font-weight: 500;
font-size: 14px;
}
.display-details {
font-size: 11px;
color: var(--ecoos-text-dim);
}
.display-actions {
display: flex;
gap: 4px;
align-items: center;
}
.display-actions .btn {
padding: 4px 12px;
margin: 0;
font-size: 11px;
}
.section-header {
font-size: 12px;
color: var(--ecoos-text-dim);
margin: 16px 0 8px 0;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
}
.section-header:hover {
color: var(--ecoos-text);
}
.collapsed-content {
display: none;
}
.collapsed-content.expanded {
display: block;
}
`,
];
render(): TemplateResult {
const enabledDisplays = this.displays.filter(d => d.active);
const disabledDisplays = this.displays.filter(d => !d.active);
return html`
Displays
${this.displays.length === 0
? html`
No displays detected
`
: html`
${enabledDisplays.map(d => this.renderDisplayItem(d))}
${disabledDisplays.length > 0 ? html`
${disabledDisplays.map(d => this.renderDisplayItem(d))}
` : ''}
`
}
`;
}
private renderDisplayItem(display: IDisplayInfo): TemplateResult {
return html`
${display.name}
${display.width}x${display.height} @ ${display.refreshRate}Hz
${display.make !== 'Unknown' ? ` • ${display.make}` : ''}
${display.isPrimary
? html`Primary`
: display.active
? html`
`
: ''
}
`;
}
private async toggleDisplay(name: string, enable: boolean): Promise {
this.loading = true;
try {
const action = enable ? 'enable' : 'disable';
const response = await fetch(`/api/displays/${encodeURIComponent(name)}/${action}`, {
method: 'POST',
});
const result = await response.json();
if (!result.success) {
alert(result.message);
}
this.dispatchEvent(new CustomEvent('refresh-displays'));
} catch (error) {
alert(`Error: ${error}`);
} finally {
this.loading = false;
}
}
private async setKioskDisplay(name: string): Promise {
this.loading = true;
try {
const response = await fetch(`/api/displays/${encodeURIComponent(name)}/primary`, {
method: 'POST',
});
const result = await response.json();
if (!result.success) {
alert(result.message);
}
this.dispatchEvent(new CustomEvent('refresh-displays'));
} catch (error) {
alert(`Error: ${error}`);
} finally {
this.loading = false;
}
}
}