import { DeesElement, customElement, html, css, cssManager, property, state, type TemplateResult, } from '@design.estate/dees-element'; import type { DeesAppui } from '@design.estate/dees-catalog'; import './index.js'; declare global { interface HTMLElementTagNameMap { 'sz-demo-view-services': SzDemoViewServices; } } @customElement('sz-demo-view-services') export class SzDemoViewServices extends DeesElement { private appui: DeesAppui | null = null; @state() private accessor currentView: 'list' | 'create' | 'detail' | 'backups' | 'platform-detail' = 'list'; @state() private accessor selectedService: any = null; @state() private accessor selectedPlatformService: any = null; private demoServices = [ { id: '1', name: 'nginx-proxy', image: 'nginx:latest', status: 'running', cpu: '2.5%', memory: '256 MB', ports: '80, 443', uptime: '5d 12h', }, { id: '2', name: 'api-gateway', image: 'api-gateway:v2.1.0', status: 'running', cpu: '8.2%', memory: '512 MB', ports: '3000', uptime: '3d 8h', }, { id: '3', name: 'worker-service', image: 'worker:latest', status: 'stopped', cpu: '0%', memory: '0 MB', ports: '-', uptime: '-', }, { id: '4', name: 'redis-cache', image: 'redis:7-alpine', status: 'running', cpu: '1.2%', memory: '128 MB', ports: '6379', uptime: '10d 4h', }, ]; private demoPlatformService = { id: '1', name: 'MongoDB', type: 'mongodb' as const, status: 'running' as const, version: '7.0.4', host: 'localhost', port: 27017, credentials: { username: 'admin', password: '••••••••' }, config: { replicaSet: 'rs0', authEnabled: true, journaling: true }, metrics: { cpu: 12, memory: 45, storage: 23, connections: 8 }, }; private demoPlatformLogs = [ { timestamp: '2024-01-20 14:30:22', level: 'info' as const, message: 'Connection accepted from 127.0.0.1:54321' }, { timestamp: '2024-01-20 14:30:20', level: 'info' as const, message: 'Index build completed on collection users' }, { timestamp: '2024-01-20 14:30:15', level: 'warn' as const, message: 'Slow query detected: 1.2s on collection orders' }, { timestamp: '2024-01-20 14:30:10', level: 'info' as const, message: 'Checkpoint complete' }, ]; private demoBackupSchedules = [ { id: '1', scope: 'All Services', retention: 'D:7, W:4, M:12', schedule: '0 2 * * *', lastRun: '1/2/2026, 2:00:03 AM', nextRun: '1/3/2026, 2:00:00 AM', status: 'active' as const }, ]; private demoBackups = [ { id: '1', service: 'nginx-proxy', createdAt: '1/2/2026, 2:00:03 AM', size: '22.0 MB', includes: ['Image'] }, { id: '2', service: 'api-gateway', createdAt: '1/2/2026, 2:00:02 AM', size: '156.5 MB', includes: ['Image', 'Volumes'] }, { id: '3', service: 'redis-cache', createdAt: '1/2/2026, 2:00:00 AM', size: '48.0 MB', includes: ['Image', 'Data'] }, ]; public static styles = [ cssManager.defaultStyles, css` :host { display: block; padding: 24px; height: 100%; overflow-y: auto; box-sizing: border-box; } .page-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 24px; } .header-info { display: flex; flex-direction: column; gap: 8px; } .page-title { font-size: 24px; font-weight: 700; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; margin: 0; } .page-subtitle { font-size: 14px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; margin: 0; } .header-actions { display: flex; gap: 8px; } .action-button { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; background: ${cssManager.bdTheme('#18181b', '#fafafa')}; border: none; border-radius: 6px; font-size: 13px; font-weight: 500; color: ${cssManager.bdTheme('#fafafa', '#18181b')}; cursor: pointer; transition: all 200ms ease; } .action-button:hover { opacity: 0.9; } .action-button.secondary { background: ${cssManager.bdTheme('#ffffff', '#09090b')}; border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')}; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .action-button.secondary:hover { background: ${cssManager.bdTheme('#f4f4f5', '#18181b')}; } .tabs { display: flex; gap: 4px; margin-bottom: 24px; border-bottom: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')}; padding-bottom: 0; } .tab { padding: 10px 16px; font-size: 14px; font-weight: 500; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; background: transparent; border: none; cursor: pointer; position: relative; transition: color 200ms ease; } .tab:hover { color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .tab.active { color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .tab.active::after { content: ''; position: absolute; bottom: -1px; left: 0; right: 0; height: 2px; background: ${cssManager.bdTheme('#18181b', '#fafafa')}; border-radius: 1px 1px 0 0; } .back-button { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; background: transparent; border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')}; border-radius: 6px; font-size: 13px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; cursor: pointer; margin-bottom: 16px; transition: all 200ms ease; } .back-button:hover { background: ${cssManager.bdTheme('#f4f4f5', '#18181b')}; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } `, ]; public render(): TemplateResult { return html` ${this.currentView === 'list' ? this.renderListView() : ''} ${this.currentView === 'create' ? this.renderCreateView() : ''} ${this.currentView === 'detail' ? this.renderDetailView() : ''} ${this.currentView === 'backups' ? this.renderBackupsView() : ''} ${this.currentView === 'platform-detail' ? this.renderPlatformDetailView() : ''} `; } private renderListView(): TemplateResult { return html`
{ this.selectedService = e.detail; this.currentView = 'detail'; }} @start-service=${(e: CustomEvent) => console.log('Start service:', e.detail)} @stop-service=${(e: CustomEvent) => console.log('Stop service:', e.detail)} @restart-service=${(e: CustomEvent) => console.log('Restart service:', e.detail)} @delete-service=${(e: CustomEvent) => console.log('Delete service:', e.detail)} > `; } private renderCreateView(): TemplateResult { return html` { console.log('Create service:', e.detail); this.currentView = 'list'; }} @cancel=${() => this.currentView = 'list'} > `; } private renderDetailView(): TemplateResult { return html` console.log('Start')} @stop=${() => console.log('Stop')} @restart=${() => console.log('Restart')} @request-workspace=${(e: CustomEvent) => console.log('Workspace requested for:', e.detail.service.name)} > `; } private renderBackupsView(): TemplateResult { return html` console.log('Create schedule')} @run-now=${(e: CustomEvent) => console.log('Run now:', e.detail)} @download=${(e: CustomEvent) => console.log('Download:', e.detail)} > `; } private renderPlatformDetailView(): TemplateResult { return html` console.log('Start')} @stop=${() => console.log('Stop')} @restart=${() => console.log('Restart')} > `; } async onActivate(context: { appui: DeesAppui; viewId: string }) { this.appui = context.appui; // Set up content tabs this.appui.setContentTabs([ { key: 'Docker Services', action: () => { this.currentView = 'list'; this.updateSecondaryMenu(); } }, { key: 'Platform Services', action: () => { this.currentView = 'platform-detail'; this.updateSecondaryMenu(); } }, { key: 'Backups', action: () => { this.currentView = 'backups'; this.updateSecondaryMenu(); } }, ]); this.updateSecondaryMenu(); } private updateSecondaryMenu() { if (!this.appui) return; this.appui.setSecondaryMenu({ heading: 'Services', groups: [ { name: 'Actions', items: [ { type: 'action', key: 'Deploy Service', iconName: 'lucide:Plus', action: () => { this.currentView = 'create'; } }, { type: 'action', key: 'Refresh', iconName: 'lucide:RefreshCw', action: () => { console.log('Refresh'); } }, ], }, { name: 'Quick Filters', items: [ { key: 'Running', iconName: 'lucide:Play', badge: '3', badgeVariant: 'success', action: () => { console.log('Filter running'); } }, { key: 'Stopped', iconName: 'lucide:Square', badge: '1', action: () => { console.log('Filter stopped'); } }, ], }, ], }); } onDeactivate() { // Cleanup if needed } }