@@ -383,9 +390,9 @@ export class OpsViewVpn extends DeesElement {
if (!form) return;
const data = await form.collectFormData();
if (!data.clientId) return;
- const targetProfileIds = data.targetProfileIds
- ? data.targetProfileIds.split(',').map((t: string) => t.trim()).filter(Boolean)
- : undefined;
+ const targetProfileIds = this.resolveProfileNamesToIds(
+ Array.isArray(data.targetProfileNames) ? data.targetProfileNames : [],
+ );
// Apply conditional logic based on checkbox states
const forceSmartproxy = data.forceDestinationSmartproxy ?? true;
@@ -479,7 +486,7 @@ export class OpsViewVpn extends DeesElement {
Transport${conn.transport}
` : ''}
Description${client.description || '-'}
-
Target Profiles${client.targetProfileIds?.join(', ') || '-'}
+
Target Profiles${this.resolveProfileIdsToNames(client.targetProfileIds)?.join(', ') || '-'}
Routing${client.forceDestinationSmartproxy !== false ? 'SmartProxy' : client.useHostIp ? 'Host IP' : 'Direct'}
${client.useHostIp ? html`
Host IP${client.useDhcp ? 'DHCP' : client.staticIp ? `Static: ${client.staticIp}` : 'Not configured'}
@@ -643,7 +650,8 @@ export class OpsViewVpn extends DeesElement {
const client = actionData.item as interfaces.data.IVpnClient;
const { DeesModal } = await import('@design.estate/dees-catalog');
const currentDescription = client.description ?? '';
- const currentTargetProfileIds = client.targetProfileIds?.join(', ') ?? '';
+ const currentTargetProfileNames = this.resolveProfileIdsToNames(client.targetProfileIds) || [];
+ const profileCandidates = this.getTargetProfileCandidates();
const currentForceSmartproxy = client.forceDestinationSmartproxy ?? true;
const currentUseHostIp = client.useHostIp ?? false;
const currentUseDhcp = client.useDhcp ?? false;
@@ -659,7 +667,7 @@ export class OpsViewVpn extends DeesElement {
content: html`
-
+
@@ -690,9 +698,9 @@ export class OpsViewVpn extends DeesElement {
const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
if (!form) return;
const data = await form.collectFormData();
- const targetProfileIds = data.targetProfileIds
- ? data.targetProfileIds.split(',').map((t: string) => t.trim()).filter(Boolean)
- : [];
+ const targetProfileIds = this.resolveProfileNamesToIds(
+ Array.isArray(data.targetProfileNames) ? data.targetProfileNames : [],
+ );
// Apply conditional logic based on checkbox states
const forceSmartproxy = data.forceDestinationSmartproxy ?? true;
@@ -805,4 +813,43 @@ export class OpsViewVpn extends DeesElement {
`;
}
+
+ /**
+ * Build autocomplete candidates from loaded target profiles.
+ * viewKey = profile name (displayed), payload = { id } (carried for resolution).
+ */
+ private getTargetProfileCandidates() {
+ const profileState = appstate.targetProfilesStatePart.getState();
+ const profiles = profileState?.profiles || [];
+ return profiles.map((p) => ({ viewKey: p.name, payload: { id: p.id } }));
+ }
+
+ /**
+ * Convert profile IDs to profile names (for populating edit form values).
+ */
+ private resolveProfileIdsToNames(ids?: string[]): string[] | undefined {
+ if (!ids?.length) return undefined;
+ const profileState = appstate.targetProfilesStatePart.getState();
+ const profiles = profileState?.profiles || [];
+ return ids.map((id) => {
+ const profile = profiles.find((p) => p.id === id);
+ return profile?.name || id;
+ });
+ }
+
+ /**
+ * Convert profile names back to IDs (for saving form data).
+ * Uses the dees-input-list candidates' payload when available.
+ */
+ private resolveProfileNamesToIds(names: string[]): string[] | undefined {
+ if (!names.length) return undefined;
+ const profileState = appstate.targetProfilesStatePart.getState();
+ const profiles = profileState?.profiles || [];
+ return names
+ .map((name) => {
+ const profile = profiles.find((p) => p.name === name);
+ return profile?.id;
+ })
+ .filter((id): id is string => !!id);
+ }
}