@serve.zone/dcrouter 13.17.3 → 13.17.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,7 +28,7 @@ function setupFormVisibility(formEl: any) {
28
28
  const staticIpGroup = contentEl.querySelector('.staticIpGroup') as HTMLElement;
29
29
  const vlanIdGroup = contentEl.querySelector('.vlanIdGroup') as HTMLElement;
30
30
  const aclGroup = contentEl.querySelector('.aclGroup') as HTMLElement;
31
- if (hostIpGroup) hostIpGroup.style.display = show; // always show (forceTarget is always on)
31
+ if (hostIpGroup) hostIpGroup.style.display = show;
32
32
  if (hostIpDetails) hostIpDetails.style.display = data.useHostIp ? show : 'none';
33
33
  if (staticIpGroup) staticIpGroup.style.display = data.useDhcp ? 'none' : show;
34
34
  if (vlanIdGroup) vlanIdGroup.style.display = data.forceVlan ? show : 'none';
@@ -390,7 +390,7 @@ export class OpsViewVpn extends DeesElement {
390
390
  if (!form) return;
391
391
  const data = await form.collectFormData();
392
392
  if (!data.clientId) return;
393
- const targetProfileIds = this.resolveProfileNamesToIds(
393
+ const targetProfileIds = this.resolveProfileLabelsToIds(
394
394
  Array.isArray(data.targetProfileNames) ? data.targetProfileNames : [],
395
395
  );
396
396
 
@@ -414,10 +414,10 @@ export class OpsViewVpn extends DeesElement {
414
414
  description: data.description || undefined,
415
415
  targetProfileIds,
416
416
 
417
- useHostIp: useHostIp || undefined,
418
- useDhcp: useDhcp || undefined,
417
+ useHostIp,
418
+ useDhcp,
419
419
  staticIp,
420
- forceVlan: forceVlan || undefined,
420
+ forceVlan,
421
421
  vlanId,
422
422
  destinationAllowList,
423
423
  destinationBlockList,
@@ -485,7 +485,7 @@ export class OpsViewVpn extends DeesElement {
485
485
  <div class="infoItem"><span class="infoLabel">Transport</span><span class="infoValue">${conn.transport}</span></div>
486
486
  ` : ''}
487
487
  <div class="infoItem"><span class="infoLabel">Description</span><span class="infoValue">${client.description || '-'}</span></div>
488
- <div class="infoItem"><span class="infoLabel">Target Profiles</span><span class="infoValue">${this.resolveProfileIdsToNames(client.targetProfileIds)?.join(', ') || '-'}</span></div>
488
+ <div class="infoItem"><span class="infoLabel">Target Profiles</span><span class="infoValue">${this.resolveProfileIdsToLabels(client.targetProfileIds)?.join(', ') || '-'}</span></div>
489
489
  <div class="infoItem"><span class="infoLabel">Routing</span><span class="infoValue">${client.useHostIp ? 'Host IP' : 'SmartProxy'}</span></div>
490
490
  ${client.useHostIp ? html`
491
491
  <div class="infoItem"><span class="infoLabel">Host IP</span><span class="infoValue">${client.useDhcp ? 'DHCP' : client.staticIp ? `Static: ${client.staticIp}` : 'Not configured'}</span></div>
@@ -649,7 +649,7 @@ export class OpsViewVpn extends DeesElement {
649
649
  const client = actionData.item as interfaces.data.IVpnClient;
650
650
  const { DeesModal } = await import('@design.estate/dees-catalog');
651
651
  const currentDescription = client.description ?? '';
652
- const currentTargetProfileNames = this.resolveProfileIdsToNames(client.targetProfileIds) || [];
652
+ const currentTargetProfileNames = this.resolveProfileIdsToLabels(client.targetProfileIds) || [];
653
653
  const profileCandidates = this.getTargetProfileCandidates();
654
654
  const currentUseHostIp = client.useHostIp ?? false;
655
655
  const currentUseDhcp = client.useDhcp ?? false;
@@ -695,7 +695,7 @@ export class OpsViewVpn extends DeesElement {
695
695
  const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
696
696
  if (!form) return;
697
697
  const data = await form.collectFormData();
698
- const targetProfileIds = this.resolveProfileNamesToIds(
698
+ const targetProfileIds = this.resolveProfileLabelsToIds(
699
699
  Array.isArray(data.targetProfileNames) ? data.targetProfileNames : [],
700
700
  );
701
701
 
@@ -719,10 +719,10 @@ export class OpsViewVpn extends DeesElement {
719
719
  description: data.description || undefined,
720
720
  targetProfileIds,
721
721
 
722
- useHostIp: useHostIp || undefined,
723
- useDhcp: useDhcp || undefined,
722
+ useHostIp,
723
+ useDhcp,
724
724
  staticIp,
725
- forceVlan: forceVlan || undefined,
725
+ forceVlan,
726
726
  vlanId,
727
727
  destinationAllowList,
728
728
  destinationBlockList,
@@ -811,41 +811,52 @@ export class OpsViewVpn extends DeesElement {
811
811
  }
812
812
 
813
813
  /**
814
- * Build autocomplete candidates from loaded target profiles.
815
- * viewKey = profile name (displayed), payload = { id } (carried for resolution).
814
+ * Build stable profile labels for list inputs.
816
815
  */
817
- private getTargetProfileCandidates() {
816
+ private getTargetProfileChoices() {
818
817
  const profileState = appstate.targetProfilesStatePart.getState();
819
818
  const profiles = profileState?.profiles || [];
820
- return profiles.map((p) => ({ viewKey: p.name, payload: { id: p.id } }));
819
+ const nameCounts = new Map<string, number>();
820
+
821
+ for (const profile of profiles) {
822
+ nameCounts.set(profile.name, (nameCounts.get(profile.name) || 0) + 1);
823
+ }
824
+
825
+ return profiles.map((profile) => ({
826
+ id: profile.id,
827
+ label: (nameCounts.get(profile.name) || 0) > 1
828
+ ? `${profile.name} (${profile.id})`
829
+ : profile.name,
830
+ }));
831
+ }
832
+
833
+ private getTargetProfileCandidates() {
834
+ return this.getTargetProfileChoices().map((profile) => ({ viewKey: profile.label }));
821
835
  }
822
836
 
823
837
  /**
824
- * Convert profile IDs to profile names (for populating edit form values).
838
+ * Convert profile IDs to form labels (for populating edit form values).
825
839
  */
826
- private resolveProfileIdsToNames(ids?: string[]): string[] | undefined {
840
+ private resolveProfileIdsToLabels(ids?: string[]): string[] | undefined {
827
841
  if (!ids?.length) return undefined;
828
- const profileState = appstate.targetProfilesStatePart.getState();
829
- const profiles = profileState?.profiles || [];
842
+ const choices = this.getTargetProfileChoices();
843
+ const labelsById = new Map(choices.map((profile) => [profile.id, profile.label]));
830
844
  return ids.map((id) => {
831
- const profile = profiles.find((p) => p.id === id);
832
- return profile?.name || id;
845
+ return labelsById.get(id) || id;
833
846
  });
834
847
  }
835
848
 
836
849
  /**
837
- * Convert profile names back to IDs (for saving form data).
838
- * Uses the dees-input-list candidates' payload when available.
850
+ * Convert profile form labels back to IDs.
839
851
  */
840
- private resolveProfileNamesToIds(names: string[]): string[] | undefined {
841
- if (!names.length) return undefined;
842
- const profileState = appstate.targetProfilesStatePart.getState();
843
- const profiles = profileState?.profiles || [];
844
- return names
845
- .map((name) => {
846
- const profile = profiles.find((p) => p.name === name);
847
- return profile?.id;
848
- })
852
+ private resolveProfileLabelsToIds(labels: string[]): string[] {
853
+ if (!labels.length) return [];
854
+
855
+ const labelsToIds = new Map(
856
+ this.getTargetProfileChoices().map((profile) => [profile.label, profile.id]),
857
+ );
858
+ return labels
859
+ .map((label) => labelsToIds.get(label))
849
860
  .filter((id): id is string => !!id);
850
861
  }
851
862
  }