fix(certificates): resolve base-domain certificate lookups and route profile list inputs

This commit is contained in:
2026-04-05 11:29:47 +00:00
parent 4e9b09616d
commit b2ccd54079
8 changed files with 113 additions and 89 deletions

View File

@@ -148,17 +148,27 @@ export class OpsViewTargetProfiles extends DeesElement {
`;
}
private getRouteCandidates() {
const routeState = appstate.routeManagementStatePart.getState();
const routes = routeState?.mergedRoutes || [];
return routes
.filter((mr) => mr.route.name)
.map((mr) => ({ viewKey: mr.route.name! }));
}
private async showCreateProfileDialog() {
const { DeesModal } = await import('@design.estate/dees-catalog');
const routeCandidates = this.getRouteCandidates();
DeesModal.createAndShow({
heading: 'Create Target Profile',
content: html`
<dees-form>
<dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
<dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
<dees-input-text .key=${'domains'} .label=${'Domains (comma-separated, e.g. *.example.com)'} ></dees-input-text>
<dees-input-text .key=${'targets'} .label=${'Targets (comma-separated host:port, e.g. 10.0.0.1:443)'}></dees-input-text>
<dees-input-text .key=${'routeRefs'} .label=${'Route Refs (comma-separated route names/IDs)'}></dees-input-text>
<dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'e.g. *.example.com'} .allowFreeform=${true}></dees-input-list>
<dees-input-list .key=${'targets'} .label=${'Targets (host:port)'} .placeholder=${'e.g. 10.0.0.1:443'} .allowFreeform=${true}></dees-input-list>
<dees-input-list .key=${'routeRefs'} .label=${'Route Refs'} .placeholder=${'Type to search routes...'} .candidates=${routeCandidates} .allowFreeform=${true}></dees-input-list>
</dees-form>
`,
menuOptions: [
@@ -172,30 +182,26 @@ export class OpsViewTargetProfiles extends DeesElement {
const data = await form.collectFormData();
if (!data.name) return;
const domains = data.domains
? String(data.domains).split(',').map((s: string) => s.trim()).filter(Boolean)
: undefined;
const targets = data.targets
? String(data.targets).split(',').map((s: string) => {
const trimmed = s.trim();
const lastColon = trimmed.lastIndexOf(':');
if (lastColon === -1) return null;
return {
host: trimmed.substring(0, lastColon),
port: parseInt(trimmed.substring(lastColon + 1), 10),
};
}).filter((t): t is { host: string; port: number } => t !== null && !isNaN(t.port))
: undefined;
const routeRefs = data.routeRefs
? String(data.routeRefs).split(',').map((s: string) => s.trim()).filter(Boolean)
: undefined;
const domains: string[] = Array.isArray(data.domains) ? data.domains : [];
const targetStrings: string[] = Array.isArray(data.targets) ? data.targets : [];
const targets = targetStrings
.map((s: string) => {
const lastColon = s.lastIndexOf(':');
if (lastColon === -1) return null;
return {
host: s.substring(0, lastColon),
port: parseInt(s.substring(lastColon + 1), 10),
};
})
.filter((t): t is { host: string; port: number } => t !== null && !isNaN(t.port));
const routeRefs: string[] = Array.isArray(data.routeRefs) ? data.routeRefs : [];
await appstate.targetProfilesStatePart.dispatchAction(appstate.createTargetProfileAction, {
name: String(data.name),
description: data.description ? String(data.description) : undefined,
domains,
targets,
routeRefs,
domains: domains.length > 0 ? domains : undefined,
targets: targets.length > 0 ? targets : undefined,
routeRefs: routeRefs.length > 0 ? routeRefs : undefined,
});
modalArg.destroy();
},
@@ -205,20 +211,22 @@ export class OpsViewTargetProfiles extends DeesElement {
}
private async showEditProfileDialog(profile: interfaces.data.ITargetProfile) {
const currentDomains = profile.domains?.join(', ') ?? '';
const currentTargets = profile.targets?.map(t => `${t.host}:${t.port}`).join(', ') ?? '';
const currentRouteRefs = profile.routeRefs?.join(', ') ?? '';
const currentDomains = profile.domains || [];
const currentTargets = profile.targets?.map(t => `${t.host}:${t.port}`) || [];
const currentRouteRefs = profile.routeRefs || [];
const { DeesModal } = await import('@design.estate/dees-catalog');
const routeCandidates = this.getRouteCandidates();
DeesModal.createAndShow({
heading: `Edit Profile: ${profile.name}`,
content: html`
<dees-form>
<dees-input-text .key=${'name'} .label=${'Name'} .value=${profile.name}></dees-input-text>
<dees-input-text .key=${'description'} .label=${'Description'} .value=${profile.description || ''}></dees-input-text>
<dees-input-text .key=${'domains'} .label=${'Domains (comma-separated, e.g. *.example.com)'} .value=${currentDomains}></dees-input-text>
<dees-input-text .key=${'targets'} .label=${'Targets (comma-separated host:port, e.g. 10.0.0.1:443)'} .value=${currentTargets}></dees-input-text>
<dees-input-text .key=${'routeRefs'} .label=${'Route Refs (comma-separated route names/IDs)'} .value=${currentRouteRefs}></dees-input-text>
<dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'e.g. *.example.com'} .allowFreeform=${true} .value=${currentDomains}></dees-input-list>
<dees-input-list .key=${'targets'} .label=${'Targets (host:port)'} .placeholder=${'e.g. 10.0.0.1:443'} .allowFreeform=${true} .value=${currentTargets}></dees-input-list>
<dees-input-list .key=${'routeRefs'} .label=${'Route Refs'} .placeholder=${'Type to search routes...'} .candidates=${routeCandidates} .allowFreeform=${true} .value=${currentRouteRefs}></dees-input-list>
</dees-form>
`,
menuOptions: [
@@ -231,24 +239,19 @@ export class OpsViewTargetProfiles extends DeesElement {
if (!form) return;
const data = await form.collectFormData();
const domains = data.domains
? String(data.domains).split(',').map((s: string) => s.trim()).filter(Boolean)
: [];
const targets = data.targets
? String(data.targets).split(',').map((s: string) => {
const trimmed = s.trim();
if (!trimmed) return null;
const lastColon = trimmed.lastIndexOf(':');
if (lastColon === -1) return null;
return {
host: trimmed.substring(0, lastColon),
port: parseInt(trimmed.substring(lastColon + 1), 10),
};
}).filter((t): t is { host: string; port: number } => t !== null && !isNaN(t.port))
: [];
const routeRefs = data.routeRefs
? String(data.routeRefs).split(',').map((s: string) => s.trim()).filter(Boolean)
: [];
const domains: string[] = Array.isArray(data.domains) ? data.domains : [];
const targetStrings: string[] = Array.isArray(data.targets) ? data.targets : [];
const targets = targetStrings
.map((s: string) => {
const lastColon = s.lastIndexOf(':');
if (lastColon === -1) return null;
return {
host: s.substring(0, lastColon),
port: parseInt(s.substring(lastColon + 1), 10),
};
})
.filter((t): t is { host: string; port: number } => t !== null && !isNaN(t.port));
const routeRefs: string[] = Array.isArray(data.routeRefs) ? data.routeRefs : [];
await appstate.targetProfilesStatePart.dispatchAction(appstate.updateTargetProfileAction, {
id: profile.id,