@serve.zone/dcrouter 13.0.5 → 13.0.7

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.
@@ -148,17 +148,35 @@ export class OpsViewTargetProfiles extends DeesElement {
148
148
  `;
149
149
  }
150
150
 
151
+ private getRouteCandidates() {
152
+ const routeState = appstate.routeManagementStatePart.getState();
153
+ const routes = routeState?.mergedRoutes || [];
154
+ return routes
155
+ .filter((mr) => mr.route.name)
156
+ .map((mr) => ({ viewKey: mr.route.name! }));
157
+ }
158
+
159
+ private async ensureRoutesLoaded() {
160
+ const routeState = appstate.routeManagementStatePart.getState();
161
+ if (!routeState?.mergedRoutes?.length) {
162
+ await appstate.routeManagementStatePart.dispatchAction(appstate.fetchMergedRoutesAction, null);
163
+ }
164
+ }
165
+
151
166
  private async showCreateProfileDialog() {
152
167
  const { DeesModal } = await import('@design.estate/dees-catalog');
168
+ await this.ensureRoutesLoaded();
169
+ const routeCandidates = this.getRouteCandidates();
170
+
153
171
  DeesModal.createAndShow({
154
172
  heading: 'Create Target Profile',
155
173
  content: html`
156
174
  <dees-form>
157
175
  <dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
158
176
  <dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
159
- <dees-input-text .key=${'domains'} .label=${'Domains (comma-separated, e.g. *.example.com)'} ></dees-input-text>
160
- <dees-input-text .key=${'targets'} .label=${'Targets (comma-separated host:port, e.g. 10.0.0.1:443)'}></dees-input-text>
161
- <dees-input-text .key=${'routeRefs'} .label=${'Route Refs (comma-separated route names/IDs)'}></dees-input-text>
177
+ <dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'e.g. *.example.com'} .allowFreeform=${true}></dees-input-list>
178
+ <dees-input-list .key=${'targets'} .label=${'Targets (host:port)'} .placeholder=${'e.g. 10.0.0.1:443'} .allowFreeform=${true}></dees-input-list>
179
+ <dees-input-list .key=${'routeRefs'} .label=${'Route Refs'} .placeholder=${'Type to search routes...'} .candidates=${routeCandidates} .allowFreeform=${true}></dees-input-list>
162
180
  </dees-form>
163
181
  `,
164
182
  menuOptions: [
@@ -172,30 +190,26 @@ export class OpsViewTargetProfiles extends DeesElement {
172
190
  const data = await form.collectFormData();
173
191
  if (!data.name) return;
174
192
 
175
- const domains = data.domains
176
- ? String(data.domains).split(',').map((s: string) => s.trim()).filter(Boolean)
177
- : undefined;
178
- const targets = data.targets
179
- ? String(data.targets).split(',').map((s: string) => {
180
- const trimmed = s.trim();
181
- const lastColon = trimmed.lastIndexOf(':');
182
- if (lastColon === -1) return null;
183
- return {
184
- host: trimmed.substring(0, lastColon),
185
- port: parseInt(trimmed.substring(lastColon + 1), 10),
186
- };
187
- }).filter((t): t is { host: string; port: number } => t !== null && !isNaN(t.port))
188
- : undefined;
189
- const routeRefs = data.routeRefs
190
- ? String(data.routeRefs).split(',').map((s: string) => s.trim()).filter(Boolean)
191
- : undefined;
193
+ const domains: string[] = Array.isArray(data.domains) ? data.domains : [];
194
+ const targetStrings: string[] = Array.isArray(data.targets) ? data.targets : [];
195
+ const targets = targetStrings
196
+ .map((s: string) => {
197
+ const lastColon = s.lastIndexOf(':');
198
+ if (lastColon === -1) return null;
199
+ return {
200
+ host: s.substring(0, lastColon),
201
+ port: parseInt(s.substring(lastColon + 1), 10),
202
+ };
203
+ })
204
+ .filter((t): t is { host: string; port: number } => t !== null && !isNaN(t.port));
205
+ const routeRefs: string[] = Array.isArray(data.routeRefs) ? data.routeRefs : [];
192
206
 
193
207
  await appstate.targetProfilesStatePart.dispatchAction(appstate.createTargetProfileAction, {
194
208
  name: String(data.name),
195
209
  description: data.description ? String(data.description) : undefined,
196
- domains,
197
- targets,
198
- routeRefs,
210
+ domains: domains.length > 0 ? domains : undefined,
211
+ targets: targets.length > 0 ? targets : undefined,
212
+ routeRefs: routeRefs.length > 0 ? routeRefs : undefined,
199
213
  });
200
214
  modalArg.destroy();
201
215
  },
@@ -205,20 +219,23 @@ export class OpsViewTargetProfiles extends DeesElement {
205
219
  }
206
220
 
207
221
  private async showEditProfileDialog(profile: interfaces.data.ITargetProfile) {
208
- const currentDomains = profile.domains?.join(', ') ?? '';
209
- const currentTargets = profile.targets?.map(t => `${t.host}:${t.port}`).join(', ') ?? '';
210
- const currentRouteRefs = profile.routeRefs?.join(', ') ?? '';
222
+ const currentDomains = profile.domains || [];
223
+ const currentTargets = profile.targets?.map(t => `${t.host}:${t.port}`) || [];
224
+ const currentRouteRefs = profile.routeRefs || [];
211
225
 
212
226
  const { DeesModal } = await import('@design.estate/dees-catalog');
227
+ await this.ensureRoutesLoaded();
228
+ const routeCandidates = this.getRouteCandidates();
229
+
213
230
  DeesModal.createAndShow({
214
231
  heading: `Edit Profile: ${profile.name}`,
215
232
  content: html`
216
233
  <dees-form>
217
234
  <dees-input-text .key=${'name'} .label=${'Name'} .value=${profile.name}></dees-input-text>
218
235
  <dees-input-text .key=${'description'} .label=${'Description'} .value=${profile.description || ''}></dees-input-text>
219
- <dees-input-text .key=${'domains'} .label=${'Domains (comma-separated, e.g. *.example.com)'} .value=${currentDomains}></dees-input-text>
220
- <dees-input-text .key=${'targets'} .label=${'Targets (comma-separated host:port, e.g. 10.0.0.1:443)'} .value=${currentTargets}></dees-input-text>
221
- <dees-input-text .key=${'routeRefs'} .label=${'Route Refs (comma-separated route names/IDs)'} .value=${currentRouteRefs}></dees-input-text>
236
+ <dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'e.g. *.example.com'} .allowFreeform=${true} .value=${currentDomains}></dees-input-list>
237
+ <dees-input-list .key=${'targets'} .label=${'Targets (host:port)'} .placeholder=${'e.g. 10.0.0.1:443'} .allowFreeform=${true} .value=${currentTargets}></dees-input-list>
238
+ <dees-input-list .key=${'routeRefs'} .label=${'Route Refs'} .placeholder=${'Type to search routes...'} .candidates=${routeCandidates} .allowFreeform=${true} .value=${currentRouteRefs}></dees-input-list>
222
239
  </dees-form>
223
240
  `,
224
241
  menuOptions: [
@@ -231,24 +248,19 @@ export class OpsViewTargetProfiles extends DeesElement {
231
248
  if (!form) return;
232
249
  const data = await form.collectFormData();
233
250
 
234
- const domains = data.domains
235
- ? String(data.domains).split(',').map((s: string) => s.trim()).filter(Boolean)
236
- : [];
237
- const targets = data.targets
238
- ? String(data.targets).split(',').map((s: string) => {
239
- const trimmed = s.trim();
240
- if (!trimmed) return null;
241
- const lastColon = trimmed.lastIndexOf(':');
242
- if (lastColon === -1) return null;
243
- return {
244
- host: trimmed.substring(0, lastColon),
245
- port: parseInt(trimmed.substring(lastColon + 1), 10),
246
- };
247
- }).filter((t): t is { host: string; port: number } => t !== null && !isNaN(t.port))
248
- : [];
249
- const routeRefs = data.routeRefs
250
- ? String(data.routeRefs).split(',').map((s: string) => s.trim()).filter(Boolean)
251
- : [];
251
+ const domains: string[] = Array.isArray(data.domains) ? data.domains : [];
252
+ const targetStrings: string[] = Array.isArray(data.targets) ? data.targets : [];
253
+ const targets = targetStrings
254
+ .map((s: string) => {
255
+ const lastColon = s.lastIndexOf(':');
256
+ if (lastColon === -1) return null;
257
+ return {
258
+ host: s.substring(0, lastColon),
259
+ port: parseInt(s.substring(lastColon + 1), 10),
260
+ };
261
+ })
262
+ .filter((t): t is { host: string; port: number } => t !== null && !isNaN(t.port));
263
+ const routeRefs: string[] = Array.isArray(data.routeRefs) ? data.routeRefs : [];
252
264
 
253
265
  await appstate.targetProfilesStatePart.dispatchAction(appstate.updateTargetProfileAction, {
254
266
  id: profile.id,