import * as plugins from '../plugins.js'; import * as shared from './shared/index.js'; import * as appstate from '../appstate.js'; import { DeesElement, customElement, html, state, css, cssManager, } from '@design.estate/dees-element'; @customElement('ops-view-config') export class OpsViewConfig extends DeesElement { @state() private configState: appstate.IConfigState = { config: null, isLoading: false, error: null, }; @state() private editingSection: string | null = null; @state() private editedConfig: any = null; constructor() { super(); const subscription = appstate.configStatePart .select((stateArg) => stateArg) .subscribe((configState) => { this.configState = configState; }); this.rxSubscriptions.push(subscription); } public static styles = [ cssManager.defaultStyles, shared.viewHostCss, css` .configSection { background: white; border: 1px solid #e9ecef; border-radius: 8px; margin-bottom: 24px; overflow: hidden; } .sectionHeader { background: #f8f9fa; padding: 16px 24px; border-bottom: 1px solid #e9ecef; display: flex; justify-content: space-between; align-items: center; } .sectionTitle { font-size: 18px; font-weight: 600; color: #333; } .sectionContent { padding: 24px; } .configField { margin-bottom: 20px; } .fieldLabel { font-size: 14px; font-weight: 600; color: #666; margin-bottom: 8px; display: block; } .fieldValue { font-family: 'Consolas', 'Monaco', monospace; font-size: 14px; color: #333; background: #f8f9fa; padding: 8px 12px; border-radius: 4px; border: 1px solid #e9ecef; } .configEditor { width: 100%; min-height: 200px; font-family: 'Consolas', 'Monaco', monospace; font-size: 14px; padding: 12px; border: 1px solid #e9ecef; border-radius: 4px; background: #f8f9fa; resize: vertical; } .buttonGroup { display: flex; gap: 8px; margin-top: 16px; } .warning { background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 4px; padding: 12px; margin-bottom: 16px; color: #856404; display: flex; align-items: center; gap: 8px; } .errorMessage { background: #fee; border: 1px solid #fcc; border-radius: 4px; padding: 16px; color: #c00; margin: 16px 0; } .loadingMessage { text-align: center; padding: 40px; color: #666; } `, ]; public render() { return html` Configuration ${this.configState.isLoading ? html`

Loading configuration...

` : this.configState.error ? html`
Error loading configuration: ${this.configState.error}
` : this.configState.config ? html`
Changes to configuration will take effect immediately. Please be careful when editing production settings.
${this.renderConfigSection('server', 'Server Configuration', this.configState.config.server)} ${this.renderConfigSection('email', 'Email Configuration', this.configState.config.email)} ${this.renderConfigSection('dns', 'DNS Configuration', this.configState.config.dns)} ${this.renderConfigSection('security', 'Security Configuration', this.configState.config.security)} ${this.renderConfigSection('storage', 'Storage Configuration', this.configState.config.storage)} ` : html`
No configuration loaded
`} `; } private renderConfigSection(key: string, title: string, config: any) { const isEditing = this.editingSection === key; return html`

${title}

${isEditing ? html` this.saveConfig(key)} type="highlighted" > Save this.cancelEdit()} > Cancel ` : html` this.startEdit(key, config)} > Edit `}
${isEditing ? html` ` : html` ${this.renderConfigFields(config)} `}
`; } private renderConfigFields(config: any, prefix = '') { if (!config || typeof config !== 'object') { return html`
${config}
`; } return Object.entries(config).map(([key, value]) => { const fieldName = prefix ? `${prefix}.${key}` : key; if (typeof value === 'object' && !Array.isArray(value)) { return html`
${this.renderConfigFields(value, fieldName)}
`; } return html`
${Array.isArray(value) ? value.join(', ') : value}
`; }); } private startEdit(section: string, config: any) { this.editingSection = section; this.editedConfig = JSON.stringify(config, null, 2); } private cancelEdit() { this.editingSection = null; this.editedConfig = null; } private async saveConfig(section: string) { try { const parsedConfig = JSON.parse(this.editedConfig); await appstate.configStatePart.dispatchAction(appstate.updateConfigurationAction, { section, config: parsedConfig, }); this.editingSection = null; this.editedConfig = null; // Configuration updated successfully } catch (error) { console.error(`Error updating configuration:`, error); } } }