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-dns') export class CloudlyViewDns extends DeesElement { @state() private data: appstate.IDataState = { secretGroups: [], secretBundles: [], dnsEntries: [], domains: [] } as any; constructor() { super(); const subscription = appstate.dataState.select((stateArg) => stateArg).subscribe((dataArg) => { this.data = dataArg; }); this.rxSubscriptions.push(subscription); } async connectedCallback() { super.connectedCallback(); await appstate.dataState.dispatchAction(appstate.getAllDataAction, {}); } public static styles = [ cssManager.defaultStyles, shared.viewHostCss, css` .dns-type-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.85em; font-weight: 500; color: white; } .type-A { background: #4CAF50; } .type-AAAA { background: #45a049; } .type-CNAME { background: #2196F3; } .type-MX { background: #FF9800; } .type-TXT { background: #9C27B0; } .type-NS { background: #795548; } .type-SOA { background: #607D8B; } .type-SRV { background: #E91E63; } .type-CAA { background: #00BCD4; } .type-PTR { background: #673AB7; } .status-active { color: #4CAF50; } .status-inactive { color: #f44336; } `, ]; private getRecordTypeBadge(type: string) { return html`${type}`; } private getStatusBadge(active: boolean) { return html`${active ? '✓ Active' : '✗ Inactive'}`; } public render() { return html` DNS Management { return { Type: this.getRecordTypeBadge(itemArg.data.type), Name: itemArg.data.name === '@' ? '' : itemArg.data.name, Value: itemArg.data.value, TTL: `${itemArg.data.ttl}s`, Priority: itemArg.data.priority || '-', Zone: itemArg.data.zone, Status: this.getStatusBadge(itemArg.data.active), Description: itemArg.data.description || '-', }; }} .dataActions=${[ { name: 'Add DNS Entry', iconName: 'plus', type: ['header', 'footer'], actionFunc: async () => { const modal = await plugins.deesCatalog.DeesModal.createAndShow({ heading: 'Add DNS Entry', content: html` ({ key: domain.id, option: domain.data.name })) || []} .required=${true}> `, menuOptions: [ { name: 'Create DNS Entry', action: async (modalArg: any) => { const form = modalArg.shadowRoot.querySelector('dees-form') as any; const formData = await form.gatherData(); // Guard: only allow on activated domains const domain = (this.data.domains || []).find((d: any) => d.id === formData.domainId); if (!domain || (domain.data as any).activationState !== 'activated') { plugins.deesCatalog.DeesToast.createAndShow({ message: 'Selected domain is not activated. Activate it first.', type: 'error' }); return; } await appstate.dataState.dispatchAction(appstate.createDnsEntryAction, { dnsEntryData: { type: formData.type, domainId: formData.domainId, zone: '', name: formData.name || '@', value: formData.value, ttl: parseInt(formData.ttl) || 3600, priority: formData.priority ? parseInt(formData.priority) : undefined, weight: formData.weight ? parseInt(formData.weight) : undefined, port: formData.port ? parseInt(formData.port) : undefined, active: formData.active, description: formData.description || undefined, }, }); await modalArg.destroy(); } }, { name: 'Cancel', action: async (modalArg: any) => modalArg.destroy() }, ], }); } }, { name: 'Edit', iconName: 'edit', type: ['contextmenu', 'inRow'], actionFunc: async (actionDataArg: any) => { const dnsEntry = actionDataArg.item as plugins.interfaces.data.IDnsEntry; const modal = await plugins.deesCatalog.DeesModal.createAndShow({ heading: `Edit DNS Entry`, content: html` ({ key: domain.id, option: domain.data.name })) || []} .value=${dnsEntry.data.domainId || ''} .required=${true}> `, menuOptions: [ { name: 'Update DNS Entry', action: async (modalArg: any) => { const form = modalArg.shadowRoot.querySelector('dees-form') as any; const formData = await form.gatherData(); if (formData.domainId) { const domain = (this.data.domains || []).find((d: any) => d.id === formData.domainId); if (!domain || (domain.data as any).activationState !== 'activated') { plugins.deesCatalog.DeesToast.createAndShow({ message: 'Selected domain is not activated. Activate it first.', type: 'error' }); return; } } await appstate.dataState.dispatchAction(appstate.updateDnsEntryAction, { dnsEntryId: dnsEntry.id, dnsEntryData: { ...dnsEntry.data, type: formData.type, domainId: formData.domainId, zone: '', name: formData.name || '@', value: formData.value, ttl: parseInt(formData.ttl) || 3600, priority: formData.priority ? parseInt(formData.priority) : undefined, weight: formData.weight ? parseInt(formData.weight) : undefined, port: formData.port ? parseInt(formData.port) : undefined, active: formData.active, description: formData.description || undefined, }, }); await modalArg.destroy(); } }, { name: 'Cancel', action: async (modalArg: any) => modalArg.destroy() }, ], }); } }, { name: 'Duplicate', iconName: 'copy', type: ['contextmenu', 'inRow'], actionFunc: async (actionDataArg: any) => { const dnsEntry = actionDataArg.item as plugins.interfaces.data.IDnsEntry; await appstate.dataState.dispatchAction(appstate.createDnsEntryAction, { dnsEntryData: { ...dnsEntry.data, description: `Copy of ${dnsEntry.data.description || dnsEntry.data.name}`, }, }); } }, { name: 'Toggle Active', iconName: 'power', type: ['contextmenu', 'inRow'], actionFunc: async (actionDataArg: any) => { const dnsEntry = actionDataArg.item as plugins.interfaces.data.IDnsEntry; await appstate.dataState.dispatchAction(appstate.updateDnsEntryAction, { dnsEntryId: dnsEntry.id, dnsEntryData: { ...dnsEntry.data, active: !dnsEntry.data.active, }, }); } }, { name: 'Delete', iconName: 'trash', type: ['contextmenu', 'inRow'], actionFunc: async (actionDataArg: any) => { const dnsEntry = actionDataArg.item as plugins.interfaces.data.IDnsEntry; plugins.deesCatalog.DeesModal.createAndShow({ heading: `Delete DNS Entry`, content: html`
Are you sure you want to delete this DNS entry?
${dnsEntry.data.type} - ${dnsEntry.data.name}.${dnsEntry.data.zone}
${dnsEntry.data.value}
${dnsEntry.data.description ? html`
${dnsEntry.data.description}
` : ''}
`, menuOptions: [ { name: 'Cancel', action: async (modalArg: any) => { await modalArg.destroy(); } }, { name: 'Delete', action: async (modalArg: any) => { await appstate.dataState.dispatchAction(appstate.deleteDnsEntryAction, { dnsEntryId: dnsEntry.id, }); await modalArg.destroy(); } }, ], }); } }, ] as plugins.deesCatalog.ITableAction[]} >
`; } } declare global { interface HTMLElementTagNameMap { 'cloudly-view-dns': CloudlyViewDns; } }