89 lines
3.4 KiB
TypeScript
89 lines
3.4 KiB
TypeScript
import * as shared from './shared/index.js';
|
|
import * as appstate from '../appstate.js';
|
|
import { appRouter } from '../router.js';
|
|
import {
|
|
DeesElement,
|
|
customElement,
|
|
html,
|
|
state,
|
|
css,
|
|
cssManager,
|
|
type TemplateResult,
|
|
} from '@design.estate/dees-element';
|
|
|
|
@customElement('ob-view-dns-records')
|
|
export class ObViewDnsRecords extends DeesElement {
|
|
@state()
|
|
accessor networkState: appstate.INetworkState = {
|
|
targets: [],
|
|
stats: null,
|
|
trafficStats: null,
|
|
dnsRecords: [],
|
|
domains: [],
|
|
gatewayDomains: [],
|
|
gatewayDnsRecords: [],
|
|
certificates: [],
|
|
};
|
|
|
|
constructor() {
|
|
super();
|
|
const networkSub = appstate.networkStatePart.select((s) => s).subscribe((newState) => {
|
|
this.networkState = newState;
|
|
});
|
|
this.rxSubscriptions.push(networkSub);
|
|
}
|
|
|
|
public static styles = [
|
|
cssManager.defaultStyles,
|
|
shared.viewHostCss,
|
|
css`
|
|
.table { border: 1px solid var(--ci-shade-2, #e4e4e7); border-radius: 10px; overflow: hidden; }
|
|
.row { display: grid; grid-template-columns: 2fr 90px 2fr 90px 140px 220px; gap: 16px; align-items: center; padding: 14px 16px; border-bottom: 1px solid var(--ci-shade-2, #e4e4e7); }
|
|
.row:last-child { border-bottom: none; }
|
|
.header { font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--ci-shade-5, #71717a); background: var(--ci-shade-1, #f4f4f5); }
|
|
.name { font-weight: 600; }
|
|
.value { font-family: monospace; color: var(--ci-shade-5, #71717a); overflow-wrap: anywhere; }
|
|
.badge { border-radius: 999px; padding: 3px 8px; background: var(--ci-shade-1, #f4f4f5); font-size: 12px; }
|
|
.missing { color: #dc2626; }
|
|
a, button.link { color: var(--ci-primary, #2563eb); background: none; border: none; padding: 0; cursor: pointer; font: inherit; text-decoration: none; }
|
|
.actions { display: flex; gap: 12px; }
|
|
.empty { padding: 32px; text-align: center; color: var(--ci-shade-5, #71717a); }
|
|
`,
|
|
];
|
|
|
|
async connectedCallback() {
|
|
super.connectedCallback();
|
|
await appstate.networkStatePart.dispatchAction(appstate.fetchGatewayDnsRecordsAction, null);
|
|
}
|
|
|
|
public render(): TemplateResult {
|
|
const records = this.networkState.gatewayDnsRecords;
|
|
return html`
|
|
<ob-sectionheading>DNS Records</ob-sectionheading>
|
|
<div class="table">
|
|
<div class="row header">
|
|
<span>Name</span>
|
|
<span>Type</span>
|
|
<span>Value</span>
|
|
<span>Status</span>
|
|
<span>Service</span>
|
|
<span>Actions</span>
|
|
</div>
|
|
${records.length ? records.map((record) => html`
|
|
<div class="row ${record.status === 'missing' ? 'missing' : ''}">
|
|
<span class="name">${record.name}</span>
|
|
<span><span class="badge">${record.type}</span></span>
|
|
<span class="value">${record.value || '-'}</span>
|
|
<span>${record.status}</span>
|
|
<span>${record.serviceName || record.appId}</span>
|
|
<span class="actions">
|
|
<button class="link" @click=${() => appRouter.navigateToView('services')}>View service</button>
|
|
${record.manageUrl ? html`<a href=${record.manageUrl} target="_blank" rel="noopener">Manage in dcrouter</a>` : ''}
|
|
</span>
|
|
</div>
|
|
`) : html`<div class="empty">No gateway DNS records found. Configure a dcrouter gateway in Settings.</div>`}
|
|
</div>
|
|
`;
|
|
}
|
|
}
|