import * as plugins from '../../../plugins.js'; import * as shared from '../../shared/index.js'; import { DeesElement, customElement, html, state, css, cssManager, } from '@design.estate/dees-element'; import * as appstate from '../../../appstate.js'; @customElement('cloudly-view-settings') export class CloudlyViewSettings extends DeesElement { @state() private settings: plugins.interfaces.data.ICloudlySettingsMasked = {} as any; @state() private isLoading = false; @state() private testResults: {[key: string]: {success: boolean; message: string}} = {}; constructor() { super(); this.loadSettings(); } public static styles = [ cssManager.defaultStyles, shared.viewHostCss, css` .settings-container { padding: 24px 0; display: flex; flex-direction: column; gap: 16px; } .provider-icon { margin-right: 8px; font-size: 20px; } .test-status { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; } .test-status dees-button { margin-left: auto; } .loading-container { display: flex; justify-content: center; padding: 48px; } .actions-container { display: flex; justify-content: center; margin-top: 24px; } dees-panel { margin-bottom: 16px; } .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } .form-grid.single { grid-template-columns: 1fr; } @media (max-width: 768px) { .form-grid { grid-template-columns: 1fr; } } `, ]; private async loadSettings() { this.isLoading = true; try { const response = await appstate.apiClient.settings.getSettings(); this.settings = response.settings; } catch (error: any) { console.error('Failed to load settings:', error); plugins.deesCatalog.DeesToast.createAndShow({ message: `Failed to load settings: ${error.message}`, type: 'error' }); } finally { this.isLoading = false; } } private async saveSettings(formData: any) { this.isLoading = true; try { const updates: Partial = {}; for (const [key, value] of Object.entries(formData)) { if (value !== undefined && value !== '****' && !value?.toString().endsWith('****')) { updates[key as keyof plugins.interfaces.data.ICloudlySettings] = value as string; } } const response = await appstate.apiClient.settings.updateSettings(updates); if (response.success) { plugins.deesCatalog.DeesToast.createAndShow({ message: 'Settings saved successfully', type: 'success' }); await this.loadSettings(); } else { throw new Error(response.message); } } catch (error: any) { console.error('Failed to save settings:', error); plugins.deesCatalog.DeesToast.createAndShow({ message: `Failed to save settings: ${error.message}`, type: 'error' }); } finally { this.isLoading = false; } } private async testConnection(provider: string) { this.isLoading = true; try { const response = await appstate.apiClient.settings.testProviderConnection(provider); this.testResults = { ...this.testResults, [provider]: { success: response.connectionValid, message: response.message } }; plugins.deesCatalog.DeesToast.createAndShow({ message: response.message, type: response.connectionValid ? 'success' : 'error' }); } catch (error: any) { this.testResults = { ...this.testResults, [provider]: { success: false, message: `Test failed: ${error.message}` } }; plugins.deesCatalog.DeesToast.createAndShow({ message: `Connection test failed: ${error.message}`, type: 'error' }); } finally { this.isLoading = false; } } private renderProviderStatus(provider: string) { const result = this.testResults[provider]; if (!result) return '' as any; return html``; } public render() { if (this.isLoading && Object.keys(this.settings).length === 0) { return html`
`; } return html` Settings
{ this.saveSettings((e.detail as any).data); }}>
${this.renderProviderStatus('hetzner')} { e.preventDefault(); e.stopPropagation(); this.testConnection('hetzner'); }}>
${this.renderProviderStatus('cloudflare')} { e.preventDefault(); e.stopPropagation(); this.testConnection('cloudflare'); }}>
${this.renderProviderStatus('aws')} { e.preventDefault(); e.stopPropagation(); this.testConnection('aws'); }}>
${this.renderProviderStatus('digitalocean')} { e.preventDefault(); e.stopPropagation(); this.testConnection('digitalocean'); }}>
${this.renderProviderStatus('azure')} { e.preventDefault(); e.stopPropagation(); this.testConnection('azure'); }}>
${this.renderProviderStatus('google')} { e.preventDefault(); e.stopPropagation(); this.testConnection('google'); }}>
`; } } declare global { interface HTMLElementTagNameMap { 'cloudly-view-settings': CloudlyViewSettings; } }