@serve.zone/dcrouter 6.6.1 → 6.7.0

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.
@@ -187,7 +187,7 @@ export class OpsViewRemoteIngress extends DeesElement {
187
187
  name: edge.name,
188
188
  status: this.getEdgeStatusHtml(edge),
189
189
  publicIp: this.getEdgePublicIp(edge.id),
190
- ports: this.getPortsHtml(edge.listenPorts),
190
+ ports: this.getPortsHtml(edge),
191
191
  tunnels: this.getEdgeTunnelCount(edge.id),
192
192
  lastHeartbeat: this.getLastHeartbeat(edge.id),
193
193
  })}
@@ -198,42 +198,80 @@ export class OpsViewRemoteIngress extends DeesElement {
198
198
  type: ['header'],
199
199
  actionFunc: async () => {
200
200
  const { DeesModal } = await import('@design.estate/dees-catalog');
201
- const result = await DeesModal.createAndShow({
201
+ const modal = await DeesModal.createAndShow({
202
202
  heading: 'Create Edge Node',
203
203
  content: html`
204
204
  <dees-form>
205
205
  <dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
206
- <dees-input-text .key=${'listenPorts'} .label=${'Listen Ports (comma-separated)'} .required=${true} .value=${'443,25'}></dees-input-text>
206
+ <dees-input-text .key=${'listenPorts'} .label=${'Listen Ports (comma-separated, auto-derived if empty)'}></dees-input-text>
207
207
  <dees-input-text .key=${'tags'} .label=${'Tags (comma-separated, optional)'}></dees-input-text>
208
208
  </dees-form>
209
209
  `,
210
- menuOptions: [],
211
- });
212
- if (result) {
213
- const formData = result as any;
214
- const ports = (formData.name ? formData.listenPorts : '443')
215
- .split(',')
216
- .map((p: string) => parseInt(p.trim(), 10))
217
- .filter((p: number) => !isNaN(p));
218
- const tags = formData.tags
219
- ? formData.tags.split(',').map((t: string) => t.trim()).filter(Boolean)
220
- : undefined;
221
- await appstate.remoteIngressStatePart.dispatchAction(
222
- appstate.createRemoteIngressAction,
210
+ menuOptions: [
211
+ {
212
+ name: 'Cancel',
213
+ iconName: 'lucide:x',
214
+ action: async (modalArg: any) => await modalArg.destroy(),
215
+ },
223
216
  {
224
- name: formData.name,
225
- listenPorts: ports,
226
- tags,
217
+ name: 'Create',
218
+ iconName: 'lucide:plus',
219
+ action: async (modalArg: any) => {
220
+ const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
221
+ if (!form) return;
222
+ const formData = await form.collectFormData();
223
+ const name = formData.name;
224
+ if (!name) return;
225
+ const portsStr = formData.listenPorts?.trim();
226
+ const listenPorts = portsStr
227
+ ? portsStr.split(',').map((p: string) => parseInt(p.trim(), 10)).filter((p: number) => !isNaN(p))
228
+ : undefined;
229
+ const tags = formData.tags
230
+ ? formData.tags.split(',').map((t: string) => t.trim()).filter(Boolean)
231
+ : undefined;
232
+ await appstate.remoteIngressStatePart.dispatchAction(
233
+ appstate.createRemoteIngressAction,
234
+ { name, listenPorts, tags },
235
+ );
236
+ await modalArg.destroy();
237
+ },
227
238
  },
228
- );
229
- }
239
+ ],
240
+ });
241
+ },
242
+ },
243
+ {
244
+ name: 'Enable',
245
+ iconName: 'lucide:play',
246
+ type: ['inRow', 'contextmenu'] as any,
247
+ actionRelevancyCheckFunc: (actionData: any) => !actionData.item.enabled,
248
+ actionFunc: async (actionData: any) => {
249
+ const edge = actionData.item as interfaces.data.IRemoteIngress;
250
+ await appstate.remoteIngressStatePart.dispatchAction(
251
+ appstate.toggleRemoteIngressAction,
252
+ { id: edge.id, enabled: true },
253
+ );
254
+ },
255
+ },
256
+ {
257
+ name: 'Disable',
258
+ iconName: 'lucide:pause',
259
+ type: ['inRow', 'contextmenu'] as any,
260
+ actionRelevancyCheckFunc: (actionData: any) => actionData.item.enabled,
261
+ actionFunc: async (actionData: any) => {
262
+ const edge = actionData.item as interfaces.data.IRemoteIngress;
263
+ await appstate.remoteIngressStatePart.dispatchAction(
264
+ appstate.toggleRemoteIngressAction,
265
+ { id: edge.id, enabled: false },
266
+ );
230
267
  },
231
268
  },
232
269
  {
233
270
  name: 'Regenerate Secret',
234
271
  iconName: 'lucide:key',
235
- type: ['row'],
236
- action: async (edge: interfaces.data.IRemoteIngress) => {
272
+ type: ['inRow', 'contextmenu'] as any,
273
+ actionFunc: async (actionData: any) => {
274
+ const edge = actionData.item as interfaces.data.IRemoteIngress;
237
275
  await appstate.remoteIngressStatePart.dispatchAction(
238
276
  appstate.regenerateRemoteIngressSecretAction,
239
277
  edge.id,
@@ -243,8 +281,9 @@ export class OpsViewRemoteIngress extends DeesElement {
243
281
  {
244
282
  name: 'Delete',
245
283
  iconName: 'lucide:trash2',
246
- type: ['row'],
247
- action: async (edge: interfaces.data.IRemoteIngress) => {
284
+ type: ['inRow', 'contextmenu'] as any,
285
+ actionFunc: async (actionData: any) => {
286
+ const edge = actionData.item as interfaces.data.IRemoteIngress;
248
287
  await appstate.remoteIngressStatePart.dispatchAction(
249
288
  appstate.deleteRemoteIngressAction,
250
289
  edge.id,
@@ -277,8 +316,14 @@ export class OpsViewRemoteIngress extends DeesElement {
277
316
  return status?.publicIp || '-';
278
317
  }
279
318
 
280
- private getPortsHtml(ports: number[]): TemplateResult {
281
- return html`<div class="portsDisplay">${ports.map(p => html`<span class="portBadge">${p}</span>`)}</div>`;
319
+ private getPortsHtml(edge: interfaces.data.IRemoteIngress): TemplateResult {
320
+ const hasManualPorts = edge.listenPorts && edge.listenPorts.length > 0;
321
+ const ports = hasManualPorts ? edge.listenPorts : (edge.effectiveListenPorts || []);
322
+ const isAuto = !hasManualPorts && ports.length > 0;
323
+ if (ports.length === 0) {
324
+ return html`<span style="color: var(--text-muted, #6b7280); font-size: 12px;">none</span>`;
325
+ }
326
+ return html`<div class="portsDisplay">${ports.map(p => html`<span class="portBadge">${p}</span>`)}${isAuto ? html`<span style="font-size: 11px; color: var(--text-muted, #6b7280); align-self: center;">(auto)</span>` : ''}</div>`;
282
327
  }
283
328
 
284
329
  private getEdgeTunnelCount(edgeId: string): number {