import * as plugins from '../../../plugins.js'; import * as appstate from '../../../appstate.js'; import * as shared from '../../shared/index.js'; import { DeesElement, css, cssManager, customElement, html, state, } from '@design.estate/dees-element'; type TBaseOsImageBuild = any; @customElement('cloudly-view-baseos') export class CloudlyViewBaseOs extends DeesElement { @state() private builds: TBaseOsImageBuild[] = []; @state() private isLoading = false; private refreshTimer?: number; public static styles = [ cssManager.defaultStyles, shared.viewHostCss, css` .layout { display: grid; grid-template-columns: 420px 1fr; gap: 16px; padding: 24px 0; } .builds { display: flex; flex-direction: column; gap: 12px; } .build { border: 1px solid #2a2f3a; border-radius: 12px; padding: 16px; background: #10151f; } .build-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; } .meta { color: #9aa4b2; font-size: 13px; margin-top: 8px; } .logs { margin-top: 12px; max-height: 120px; overflow: auto; font-family: monospace; font-size: 12px; color: #bac4d1; white-space: pre-wrap; } @media (max-width: 900px) { .layout { grid-template-columns: 1fr; } } `, ]; public async connectedCallback() { await super.connectedCallback(); await this.loadBuilds(); this.refreshTimer = window.setInterval(() => this.loadBuilds(), 5000); } public async disconnectedCallback() { await super.disconnectedCallback(); if (this.refreshTimer) { window.clearInterval(this.refreshTimer); } } public render() { return html` BaseOS Images
this.createBuild((eventArg.detail as any).data)}>
${this.builds.length === 0 ? html`` : this.builds.map((buildArg) => this.renderBuild(buildArg))}
`; } private renderBuild(buildArg: TBaseOsImageBuild) { const data = buildArg.data; return html`
${data.hostname || buildArg.id}
${data.imageKind || 'ubuntu-iso'} · ${data.architecture} · ${data.cloudlyUrl}
${data.artifact ? `${data.artifact.filename} · ${Math.round(data.artifact.size / 1024 / 1024)} MB · ${data.artifact.sha256.slice(0, 12)}...` : data.errorText || 'Waiting for artifact'}
${data.status === 'ready' ? html` this.downloadBuild(buildArg.id)}>` : ''} ${data.logs?.length ? html`
${data.logs.slice(-8).join('\n')}
` : ''}
`; } private async loadBuilds() { try { const response = await this.fireBaseOsRequest('getBaseOsImageBuilds', {}); this.builds = response.builds || []; } catch (error) { console.error('Failed to load BaseOS image builds:', error); } } private async createBuild(formDataArg: any) { this.isLoading = true; try { const response = await this.fireBaseOsRequest('createBaseOsImageBuild', { build: { architecture: formDataArg.architecture || 'amd64', imageKind: formDataArg.imageKind || undefined, cloudlyUrl: formDataArg.cloudlyUrl || window.location.origin, hostname: formDataArg.hostname || undefined, sourceImageUrl: formDataArg.sourceImageUrl || undefined, wifi: formDataArg.wifiSsid ? { ssid: formDataArg.wifiSsid, password: formDataArg.wifiPassword || undefined, } : undefined, sshPublicKey: formDataArg.sshPublicKey || undefined, }, }); this.builds = [response.build, ...this.builds]; plugins.deesCatalog.DeesToast.createAndShow({ message: 'BaseOS image build queued', type: 'success' }); } catch (error: any) { plugins.deesCatalog.DeesToast.createAndShow({ message: `Failed to create image build: ${error.message}`, type: 'error' }); } finally { this.isLoading = false; } } private async downloadBuild(buildIdArg: string) { const response = await this.fireBaseOsRequest('createBaseOsImageDownloadUrl', { buildId: buildIdArg, }); window.location.href = response.url; } private async fireBaseOsRequest(methodArg: string, payloadArg: Record) { appstate.apiClient.identity = appstate.loginStatePart.getState()?.identity || null as any; if (!appstate.apiClient.typedsocketClient) { await appstate.apiClient.start(); } const request = appstate.apiClient.typedsocketClient.createTypedRequest(methodArg); return await request.fire({ identity: appstate.apiClient.identity, ...payloadArg, }); } } declare global { interface HTMLElementTagNameMap { 'cloudly-view-baseos': CloudlyViewBaseOs; } }