@burdenoff/microfe-devportal 2026.623.9 → 2026.624.2

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.
@@ -13,12 +13,12 @@ import { DataTable as w, DetailList as T } from "../components/DataTable.js";
13
13
  import { InputField as E, SelectField as D, TextareaField as O } from "../components/FormField.js";
14
14
  import { ConfirmDialog as k } from "../components/ConfirmDialog.js";
15
15
  import { GrantDelegationModal as A } from "../components/GrantDelegationModal.js";
16
- import { DEVPORTAL_PERMISSIONS as j } from "../constants/permissions.js";
17
- import { useDevportalPermission as te } from "../hooks/usePermission.js";
18
- import { usePackageUpload as M } from "../hooks/usePackageUpload.js";
19
- import { useCallback as N, useEffect as ne, useMemo as P, useRef as F, useState as I } from "react";
20
- import { useI18n as L } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
21
- import { AlertCircle as re, AppWindow as ie, BarChart3 as R, CheckCircle as z, Clock as ae, Download as oe, Edit as se, ExternalLink as B, FlaskConical as ce, Info as V, Key as le, Loader2 as H, MoreHorizontal as ue, Plus as U, Power as de, RefreshCw as fe, SendHorizontal as pe, Shield as me, Store as he, Upload as W, Users as G, Webhook as ge, X as K, XCircle as _e } from "lucide-react";
16
+ import { DEVPORTAL_PERMISSIONS as te } from "../constants/permissions.js";
17
+ import { useDevportalPermission as ne } from "../hooks/usePermission.js";
18
+ import { usePackageUpload as j } from "../hooks/usePackageUpload.js";
19
+ import { useCallback as M, useEffect as re, useMemo as N, useRef as P, useState as F } from "react";
20
+ import { useI18n as I } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
21
+ import { AlertCircle as ie, AppWindow as ae, BarChart3 as L, CheckCircle as R, Clock as oe, Download as se, Edit as ce, ExternalLink as z, FlaskConical as le, Info as B, Key as ue, Loader2 as V, MoreHorizontal as de, Plus as H, Power as fe, RefreshCw as pe, SendHorizontal as me, Shield as U, Store as he, Upload as W, Users as G, Webhook as ge, X as K, XCircle as _e } from "lucide-react";
22
22
  import { useParams as ve } from "react-router-dom";
23
23
  import { Fragment as q, jsx as J, jsxs as Y } from "react/jsx-runtime";
24
24
  //#region src/devportal/pages/ApplicationDetailPage.tsx
@@ -136,7 +136,12 @@ var Se = [
136
136
  {
137
137
  id: "overview",
138
138
  label: "Overview",
139
- icon: ie
139
+ icon: ae
140
+ },
141
+ {
142
+ id: "permissions",
143
+ label: "Permissions",
144
+ icon: U
140
145
  },
141
146
  {
142
147
  id: "webhooks",
@@ -151,12 +156,12 @@ var Se = [
151
156
  {
152
157
  id: "analytics",
153
158
  label: "Analytics",
154
- icon: R
159
+ icon: L
155
160
  },
156
161
  {
157
162
  id: "playground",
158
163
  label: "API Playground",
159
- icon: B
164
+ icon: z
160
165
  },
161
166
  {
162
167
  id: "store-listing",
@@ -169,7 +174,7 @@ var Se = [
169
174
  EXPIRED: "bg-bg-sunken text-text-secondary"
170
175
  }, we = ({ message: e = "Loading..." }) => /* @__PURE__ */ Y("div", {
171
176
  className: "flex items-center justify-center gap-3 py-12",
172
- children: [/* @__PURE__ */ J(H, {
177
+ children: [/* @__PURE__ */ J(V, {
173
178
  size: 20,
174
179
  className: "animate-spin text-muted-foreground"
175
180
  }), /* @__PURE__ */ J("p", {
@@ -178,7 +183,7 @@ var Se = [
178
183
  })]
179
184
  }), Z = ({ message: e }) => /* @__PURE__ */ Y("div", {
180
185
  className: "flex flex-col items-center justify-center gap-2 py-12 text-center",
181
- children: [/* @__PURE__ */ J(re, {
186
+ children: [/* @__PURE__ */ J(ie, {
182
187
  size: 32,
183
188
  className: "text-destructive"
184
189
  }), /* @__PURE__ */ J("p", {
@@ -186,38 +191,38 @@ var Se = [
186
191
  children: e
187
192
  })]
188
193
  }), Te = () => {
189
- let { navigate: i, basePath: o, workspaceId: c } = e(), { t: d } = L(), p = (e, t) => {
194
+ let { navigate: i, basePath: o, workspaceId: c } = e(), { t: d } = I(), p = (e, t) => {
190
195
  let n = d(e);
191
196
  return n === e ? t : n;
192
- }, { allowed: h } = te(j.APP_UPDATE), { allowed: _ } = te(j.APP_DELETE), { appId: S } = ve(), [w, T] = I("overview"), [E, D] = I(!1), [O, M] = I(!1), [ne, P] = I(null), [F, R] = I(!1), { data: z, loading: oe, error: B } = s({
197
+ }, { allowed: h } = ne(te.APP_UPDATE), { allowed: _ } = ne(te.APP_DELETE), { appId: S } = ve(), [w, T] = F("overview"), [E, D] = F(!1), [O, j] = F(!1), [re, N] = F(null), [P, L] = F(!1), { data: R, loading: se, error: z } = s({
193
198
  variables: { id: S },
194
199
  skip: !S
195
- }), [V, { loading: le }] = f(), [ue, { loading: U }] = a(), [me, { loading: he }] = u(), [W, { loading: G }] = m(), { data: ge, refetch: K } = l({
200
+ }), [B, { loading: ue }] = f(), [de, { loading: H }] = a(), [U, { loading: he }] = u(), [W, { loading: G }] = m(), { data: ge, refetch: K } = l({
196
201
  variables: {
197
202
  applicationId: S,
198
203
  workspaceId: c ?? void 0
199
204
  },
200
205
  skip: !c || !S,
201
206
  fetchPolicy: "cache-and-network"
202
- }), q = ge?.appInstallations?.edges?.[0]?.node ?? null, X = N((e) => {
207
+ }), q = ge?.appInstallations?.edges?.[0]?.node ?? null, X = M((e) => {
203
208
  i?.(`${o}${e}`);
204
- }, [i, o]), be = N(async () => {
205
- let e = z?.application?.appId;
209
+ }, [i, o]), be = M(async () => {
210
+ let e = R?.application?.appId;
206
211
  if (e) try {
207
- let t = (await V({ variables: { id: e } })).data?.rotateAppSecret.clientSecret;
208
- t && P(t), D(!1);
212
+ let t = (await B({ variables: { id: e } })).data?.rotateAppSecret.clientSecret;
213
+ t && N(t), D(!1);
209
214
  } catch {}
210
- }, [z?.application?.appId, V]), xe = N(async () => {
215
+ }, [R?.application?.appId, B]), xe = M(async () => {
211
216
  if (S) try {
212
- await ue({ variables: { id: S } }), M(!1), X("/apps");
217
+ await de({ variables: { id: S } }), j(!1), X("/apps");
213
218
  } catch {}
214
219
  }, [
215
220
  S,
216
- ue,
221
+ de,
217
222
  X
218
- ]), Ce = N(async () => {
223
+ ]), Ce = M(async () => {
219
224
  if (!(!S || !c)) try {
220
- await me({ variables: { input: {
225
+ await U({ variables: { input: {
221
226
  applicationId: S,
222
227
  scope: "WORKSPACE",
223
228
  workspaceId: c,
@@ -229,24 +234,24 @@ var Se = [
229
234
  }, [
230
235
  S,
231
236
  c,
232
- me,
237
+ U,
233
238
  K
234
- ]), we = N(async (e) => {
239
+ ]), we = M(async (e) => {
235
240
  try {
236
241
  await W({ variables: { id: e } }), K(), C("success");
237
242
  } catch {
238
243
  C("error");
239
244
  }
240
245
  }, [W, K]);
241
- if (oe && !z) return /* @__PURE__ */ J(n, { message: p("devportal.loadingApplication", "Loading application...") });
242
- if (B) return /* @__PURE__ */ J(g, {
246
+ if (se && !R) return /* @__PURE__ */ J(n, { message: p("devportal.loadingApplication", "Loading application...") });
247
+ if (z) return /* @__PURE__ */ J(g, {
243
248
  title: p("devportal.error", "Error"),
244
249
  backLink: `${o}/apps`,
245
250
  backLabel: p("devportal.backToApplications", "Back to Applications"),
246
251
  children: /* @__PURE__ */ Y("div", {
247
252
  className: "flex flex-col items-center justify-center py-12 text-center",
248
253
  children: [
249
- /* @__PURE__ */ J(re, {
254
+ /* @__PURE__ */ J(ie, {
250
255
  size: 48,
251
256
  className: "text-destructive mb-4"
252
257
  }),
@@ -256,12 +261,12 @@ var Se = [
256
261
  }),
257
262
  /* @__PURE__ */ J("p", {
258
263
  className: "text-sm text-muted-foreground",
259
- children: B.message
264
+ children: z.message
260
265
  })
261
266
  ]
262
267
  })
263
268
  });
264
- let Z = ye(z?.application);
269
+ let Z = ye(R?.application);
265
270
  return Z ? /* @__PURE__ */ Y(g, {
266
271
  title: Z.name,
267
272
  description: Z.shortDescription,
@@ -275,24 +280,24 @@ var Se = [
275
280
  disabled: !Z.appId,
276
281
  title: Z.appId ? p("devportal.rotateSecretHint", "Generate a new client secret") : p("devportal.rotateSecretNoClient", "Create an OAuth client first to enable secret rotation"),
277
282
  className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-muted transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
278
- children: [/* @__PURE__ */ J(fe, { size: 16 }), p("devportal.rotateSecret", "Rotate Secret")]
283
+ children: [/* @__PURE__ */ J(pe, { size: 16 }), p("devportal.rotateSecret", "Rotate Secret")]
279
284
  }),
280
285
  /* @__PURE__ */ Y("button", {
281
286
  onClick: () => X(`/apps/${Z.id}/versions`),
282
287
  className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-muted transition-colors",
283
- children: [/* @__PURE__ */ J(ae, { size: 16 }), p("devportal.versions", "Versions")]
288
+ children: [/* @__PURE__ */ J(oe, { size: 16 }), p("devportal.versions", "Versions")]
284
289
  }),
285
290
  Z.status !== "PUBLISHED" && /* @__PURE__ */ Y("button", {
286
291
  onClick: () => T("store-listing"),
287
292
  className: "inline-flex items-center gap-2 rounded-md border border-primary/40 px-4 py-2 text-sm font-medium text-primary hover:bg-primary/10 transition-colors",
288
- children: [/* @__PURE__ */ J(pe, { size: 16 }), p("devportal.submitForReview", "Submit for Review")]
293
+ children: [/* @__PURE__ */ J(me, { size: 16 }), p("devportal.submitForReview", "Submit for Review")]
289
294
  }),
290
295
  q ? /* @__PURE__ */ Y("button", {
291
296
  onClick: () => void we(q.id),
292
297
  disabled: G || !c,
293
298
  title: p("devportal.uninstallFromWorkspace", "Uninstall this app from your current workspace"),
294
299
  className: "inline-flex items-center gap-2 rounded-md border border-destructive/50 px-4 py-2 text-sm font-medium text-destructive hover:bg-destructive/10 transition-colors disabled:opacity-50",
295
- children: [G ? /* @__PURE__ */ J(H, {
300
+ children: [G ? /* @__PURE__ */ J(V, {
296
301
  size: 16,
297
302
  className: "animate-spin"
298
303
  }) : /* @__PURE__ */ J(_e, { size: 16 }), p("devportal.uninstallFromWorkspace", "Uninstall from Workspace")]
@@ -302,33 +307,33 @@ var Se = [
302
307
  "aria-disabled": !c,
303
308
  title: c ? p("devportal.testInWorkspaceHint", "Install this app into your current workspace to test it") : p("devportal.noWorkspaceContext", "No workspace context available"),
304
309
  className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-muted transition-colors disabled:opacity-50",
305
- children: [he ? /* @__PURE__ */ J(H, {
310
+ children: [he ? /* @__PURE__ */ J(V, {
306
311
  size: 16,
307
312
  className: "animate-spin"
308
- }) : /* @__PURE__ */ J(ce, { size: 16 }), p("devportal.testInWorkspace", "Test in Workspace")]
313
+ }) : /* @__PURE__ */ J(le, { size: 16 }), p("devportal.testInWorkspace", "Test in Workspace")]
309
314
  }),
310
315
  /* @__PURE__ */ Y("button", {
311
316
  onClick: () => X(`/apps/${Z.id}/edit`),
312
317
  disabled: !h,
313
318
  "aria-disabled": !h,
314
319
  className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50",
315
- children: [/* @__PURE__ */ J(se, { size: 16 }), p("devportal.editApp", "Edit App")]
320
+ children: [/* @__PURE__ */ J(ce, { size: 16 }), p("devportal.editApp", "Edit App")]
316
321
  }),
317
322
  /* @__PURE__ */ Y("button", {
318
- onClick: () => M(!0),
323
+ onClick: () => j(!0),
319
324
  disabled: !_,
320
325
  "aria-disabled": !_,
321
326
  className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle transition-colors disabled:opacity-50",
322
- children: [/* @__PURE__ */ J(de, { size: 16 }), p("devportal.deactivate", "Deactivate")]
327
+ children: [/* @__PURE__ */ J(fe, { size: 16 }), p("devportal.deactivate", "Deactivate")]
323
328
  })
324
329
  ]
325
330
  }),
326
331
  children: [
327
- ne && /* @__PURE__ */ J(ee, {
332
+ re && /* @__PURE__ */ J(ee, {
328
333
  title: p("devportal.newAppSecretGenerated", "New App Secret Generated"),
329
- secret: ne,
334
+ secret: re,
330
335
  description: p("devportal.appSecretRotatedDescription", "Your app secret has been rotated. The old secret is no longer valid."),
331
- onDismiss: () => P(null)
336
+ onDismiss: () => N(null)
332
337
  }),
333
338
  /* @__PURE__ */ Y("div", {
334
339
  className: "flex flex-wrap items-center gap-2",
@@ -355,7 +360,7 @@ var Se = [
355
360
  className: "-mb-px flex gap-4 overflow-x-auto",
356
361
  role: "tablist",
357
362
  "aria-label": p("devportal.applicationSections", "Application sections"),
358
- children: Se.map((e) => {
363
+ children: Se.filter((e) => !(e.id === "permissions" && (Z.appType === "NODE" || Z.appType === "WORKFLOW"))).map((e) => {
359
364
  let n = e.icon;
360
365
  return /* @__PURE__ */ Y("button", {
361
366
  id: `application-tab-${e.id}`,
@@ -377,6 +382,7 @@ var Se = [
377
382
  tabIndex: 0,
378
383
  children: [
379
384
  w === "overview" && /* @__PURE__ */ J(ke, { app: Z }),
385
+ w === "permissions" && /* @__PURE__ */ J(We, { app: Z }),
380
386
  w === "webhooks" && /* @__PURE__ */ J(Ee, {
381
387
  appId: Z.id,
382
388
  onNavigate: X
@@ -384,7 +390,7 @@ var Se = [
384
390
  w === "delegations" && /* @__PURE__ */ J(De, {
385
391
  authAppId: Z.appId || void 0,
386
392
  appName: Z.name,
387
- onGrantDelegation: () => R(!0),
393
+ onGrantDelegation: () => L(!0),
388
394
  onNavigate: X
389
395
  }),
390
396
  w === "analytics" && /* @__PURE__ */ J(Oe, { appId: Z.id }),
@@ -401,27 +407,27 @@ var Se = [
401
407
  confirmLabel: p("devportal.rotateSecret", "Rotate Secret"),
402
408
  cancelLabel: p("devportal.cancel", "Cancel"),
403
409
  variant: "warning",
404
- loading: le
410
+ loading: ue
405
411
  }),
406
412
  /* @__PURE__ */ J(k, {
407
413
  open: O,
408
- onOpenChange: M,
414
+ onOpenChange: j,
409
415
  onConfirm: xe,
410
416
  title: p("devportal.deactivateApplication", "Deactivate Application"),
411
417
  description: p("devportal.deactivateApplicationDescription", "This will deactivate the application. All OAuth clients, API keys, and webhooks associated with this app will stop functioning. This action can be reversed by reactivating the app."),
412
418
  confirmLabel: p("devportal.deactivate", "Deactivate"),
413
419
  cancelLabel: p("devportal.cancel", "Cancel"),
414
420
  variant: "destructive",
415
- loading: U
421
+ loading: H
416
422
  }),
417
423
  /* @__PURE__ */ J(A, {
418
- open: F,
419
- onOpenChange: R,
424
+ open: P,
425
+ onOpenChange: L,
420
426
  appId: Z.appId || "",
421
427
  appName: Z.name,
422
428
  appScopes: Z.scopes?.map((e) => e.scope) ?? [],
423
429
  onSuccess: () => {
424
- R(!1);
430
+ L(!1);
425
431
  }
426
432
  })
427
433
  ]
@@ -430,13 +436,13 @@ var Se = [
430
436
  backLink: `${o}/apps`,
431
437
  backLabel: p("devportal.backToApplications", "Back to Applications"),
432
438
  children: /* @__PURE__ */ J(r, {
433
- icon: /* @__PURE__ */ J(ie, { size: 48 }),
439
+ icon: /* @__PURE__ */ J(ae, { size: 48 }),
434
440
  title: p("devportal.applicationNotFound", "Application not found"),
435
441
  description: p("devportal.applicationNotFoundDescription", "The application you're looking for doesn't exist or you don't have access to it.")
436
442
  })
437
443
  });
438
444
  }, Ee = ({ appId: e, onNavigate: t }) => {
439
- let { t: n } = L(), r = (e, t) => {
445
+ let { t: n } = I(), r = (e, t) => {
440
446
  let r = n(e);
441
447
  return r === e ? t : r;
442
448
  }, { data: i, loading: a, error: o } = c({ variables: { applicationId: e } });
@@ -446,24 +452,24 @@ var Se = [
446
452
  onNavigate: t
447
453
  });
448
454
  }, De = ({ authAppId: e, appName: t, onGrantDelegation: n, onNavigate: a }) => {
449
- let { t: o } = L(), s = (e, t) => {
455
+ let { t: o } = I(), s = (e, t) => {
450
456
  let n = o(e);
451
457
  return n === e ? t : n;
452
- }, { data: c, loading: l, error: u, refetch: f } = i(), [p] = d(), [m, h] = I([]), [g, _] = I(!1), [v, y] = I(/* @__PURE__ */ new Set()), [b, x] = I(null), S = P(() => c?.currentUserDelegations?.delegations ? c.currentUserDelegations.delegations.filter((t) => t.appId === e).map(xe) : [], [e, c]), C = P(() => S.filter((e) => e.status === "ACTIVE"), [S]), ee = P(() => C.filter((e) => v.has(e.id)), [C, v]), w = C.length > 0 && C.every((e) => v.has(e.id)), T = C.some((e) => v.has(e.id)) && !w, E = N((e, t) => {
458
+ }, { data: c, loading: l, error: u, refetch: f } = i(), [p] = d(), [m, h] = F([]), [g, _] = F(!1), [v, y] = F(/* @__PURE__ */ new Set()), [b, x] = F(null), S = N(() => c?.currentUserDelegations?.delegations ? c.currentUserDelegations.delegations.filter((t) => t.appId === e).map(xe) : [], [e, c]), C = N(() => S.filter((e) => e.status === "ACTIVE"), [S]), ee = N(() => C.filter((e) => v.has(e.id)), [C, v]), w = C.length > 0 && C.every((e) => v.has(e.id)), T = C.some((e) => v.has(e.id)) && !w, E = M((e, t) => {
453
459
  y((n) => {
454
460
  let r = new Set(n);
455
461
  return t ? r.add(e) : r.delete(e), r;
456
462
  });
457
- }, []), D = N((e) => {
463
+ }, []), D = M((e) => {
458
464
  y((t) => {
459
465
  let n = new Set(t);
460
466
  return C.forEach((t) => {
461
467
  e ? n.add(t.id) : n.delete(t.id);
462
468
  }), n;
463
469
  });
464
- }, [C]), O = N(() => {
470
+ }, [C]), O = M(() => {
465
471
  y(/* @__PURE__ */ new Set());
466
- }, []), A = N(async (e) => {
472
+ }, []), A = M(async (e) => {
467
473
  _(!0);
468
474
  try {
469
475
  let t = await Promise.allSettled(e.map((e) => p({ variables: { id: e } }))), n = t.filter((e) => e.status === "fulfilled").length, r = t.length - n;
@@ -516,23 +522,23 @@ var Se = [
516
522
  loading: g
517
523
  })
518
524
  ] }) : /* @__PURE__ */ J(r, {
519
- icon: /* @__PURE__ */ J(me, { size: 32 }),
525
+ icon: /* @__PURE__ */ J(U, { size: 32 }),
520
526
  title: s("devportal.linkAuthAppFirst", "Link an auth app first"),
521
527
  description: s("devportal.linkAuthAppFirstDescription", "Delegations are managed through auth apps. Create or link an auth app before granting app-as-user access."),
522
528
  action: /* @__PURE__ */ Y("button", {
523
529
  onClick: () => a("/oauth"),
524
530
  className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
525
- children: [/* @__PURE__ */ J(B, { size: 16 }), s("devportal.manageOAuthApps", "Manage OAuth Apps")]
531
+ children: [/* @__PURE__ */ J(z, { size: 16 }), s("devportal.manageOAuthApps", "Manage OAuth Apps")]
526
532
  })
527
533
  });
528
534
  }, Oe = ({ appId: e }) => {
529
- let { t } = L(), n = (e, n) => {
535
+ let { t } = I(), n = (e, n) => {
530
536
  let r = t(e);
531
537
  return r === e ? n : r;
532
- }, r = P(() => /* @__PURE__ */ new Date(), []), { data: i, loading: a, error: s } = o({ variables: {
538
+ }, r = N(() => /* @__PURE__ */ new Date(), []), { data: i, loading: a, error: s } = o({ variables: {
533
539
  applicationId: e,
534
540
  period: "daily",
535
- startDate: P(() => {
541
+ startDate: N(() => {
536
542
  let e = new Date(r);
537
543
  return e.setDate(e.getDate() - 30), e;
538
544
  }, [r]).toISOString(),
@@ -540,7 +546,7 @@ var Se = [
540
546
  } });
541
547
  return a ? /* @__PURE__ */ J(we, { message: n("devportal.loadingAnalytics", "Loading analytics...") }) : s ? /* @__PURE__ */ J(Z, { message: s.message }) : /* @__PURE__ */ J(Me, { analytics: (i?.applicationAnalytics ?? []).map(be) });
542
548
  }, ke = ({ app: e }) => {
543
- let { t } = L(), n = (e, n) => {
549
+ let { t } = I(), n = (e, n) => {
544
550
  let r = t(e);
545
551
  return r === e ? n : r;
546
552
  };
@@ -678,7 +684,7 @@ var Se = [
678
684
  })]
679
685
  });
680
686
  }, Ae = ({ appId: e, webhooks: t, onNavigate: n }) => {
681
- let { t: i } = L(), a = (e, t) => {
687
+ let { t: i } = I(), a = (e, t) => {
682
688
  let n = i(e);
683
689
  return n === e ? t : n;
684
690
  };
@@ -698,7 +704,7 @@ var Se = [
698
704
  }), /* @__PURE__ */ Y("button", {
699
705
  onClick: () => n(`/apps/${e}/webhooks/new`),
700
706
  className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
701
- children: [/* @__PURE__ */ J(U, { size: 16 }), a("devportal.addWebhook", "Add Webhook")]
707
+ children: [/* @__PURE__ */ J(H, { size: 16 }), a("devportal.addWebhook", "Add Webhook")]
702
708
  })]
703
709
  }), t.length > 0 ? /* @__PURE__ */ J("div", {
704
710
  className: "space-y-4",
@@ -722,7 +728,7 @@ var Se = [
722
728
  })] }), /* @__PURE__ */ J("button", {
723
729
  onClick: () => n(`/apps/${e}/webhooks/${t.id}`),
724
730
  className: "rounded-md p-1 hover:bg-muted",
725
- children: /* @__PURE__ */ J(ue, { size: 20 })
731
+ children: /* @__PURE__ */ J(de, { size: 20 })
726
732
  })]
727
733
  }),
728
734
  /* @__PURE__ */ Y("div", { children: [/* @__PURE__ */ J("p", {
@@ -784,12 +790,12 @@ var Se = [
784
790
  action: /* @__PURE__ */ Y("button", {
785
791
  onClick: () => n(`/apps/${e}/webhooks/new`),
786
792
  className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
787
- children: [/* @__PURE__ */ J(U, { size: 16 }), a("devportal.addWebhook", "Add Webhook")]
793
+ children: [/* @__PURE__ */ J(H, { size: 16 }), a("devportal.addWebhook", "Add Webhook")]
788
794
  })
789
795
  })]
790
796
  });
791
797
  }, je = ({ appName: e, delegations: n, onGrantDelegation: i, onRevokeDelegation: a, selectedDelegationIds: o, onToggleSelectDelegation: s, onToggleAllDelegations: c, onClearSelection: l, onRevokeSelected: u, allVisibleSelected: d, partiallySelected: f }) => {
792
- let { t: p } = L(), m = (e, t) => {
798
+ let { t: p } = I(), m = (e, t) => {
793
799
  let n = p(e);
794
800
  return n === e ? t : n;
795
801
  }, h = n.filter((e) => e.status === "ACTIVE"), g = n.filter((e) => e.status !== "ACTIVE");
@@ -824,7 +830,7 @@ var Se = [
824
830
  })] }), /* @__PURE__ */ Y("button", {
825
831
  onClick: i,
826
832
  className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
827
- children: [/* @__PURE__ */ J(U, { size: 16 }), m("devportal.grantDelegation", "Grant Delegation")]
833
+ children: [/* @__PURE__ */ J(H, { size: 16 }), m("devportal.grantDelegation", "Grant Delegation")]
828
834
  })]
829
835
  }),
830
836
  h.length > 0 && /* @__PURE__ */ J("div", {
@@ -937,7 +943,7 @@ var Se = [
937
943
  e.expiresAt && /* @__PURE__ */ Y("span", {
938
944
  className: "flex items-center gap-1",
939
945
  children: [
940
- /* @__PURE__ */ J(ae, { size: 12 }),
946
+ /* @__PURE__ */ J(oe, { size: 12 }),
941
947
  m("devportal.expires", "Expires"),
942
948
  " ",
943
949
  new Date(e.expiresAt).toLocaleDateString()
@@ -945,7 +951,7 @@ var Se = [
945
951
  }),
946
952
  !e.expiresAt && e.status === "ACTIVE" && /* @__PURE__ */ Y("span", {
947
953
  className: "flex items-center gap-1",
948
- children: [/* @__PURE__ */ J(z, {
954
+ children: [/* @__PURE__ */ J(R, {
949
955
  size: 12,
950
956
  className: "text-status-success-text"
951
957
  }), m("devportal.noExpiration", "No expiration")]
@@ -973,13 +979,13 @@ var Se = [
973
979
  action: /* @__PURE__ */ Y("button", {
974
980
  onClick: i,
975
981
  className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
976
- children: [/* @__PURE__ */ J(U, { size: 16 }), m("devportal.grantDelegation", "Grant Delegation")]
982
+ children: [/* @__PURE__ */ J(H, { size: 16 }), m("devportal.grantDelegation", "Grant Delegation")]
977
983
  })
978
984
  })
979
985
  ]
980
986
  });
981
987
  }, Me = ({ analytics: e }) => {
982
- let { t } = L(), n = (e, n) => {
988
+ let { t } = I(), n = (e, n) => {
983
989
  let r = t(e);
984
990
  return r === e ? n : r;
985
991
  }, i = e[0], a = e[1], o = (e, t) => t ? (e - t) / t * 100 : 0;
@@ -1052,17 +1058,17 @@ var Se = [
1052
1058
  }
1053
1059
  ]
1054
1060
  }) : /* @__PURE__ */ J(r, {
1055
- icon: /* @__PURE__ */ J(R, { size: 32 }),
1061
+ icon: /* @__PURE__ */ J(L, { size: 32 }),
1056
1062
  title: n("devportal.noAnalyticsData", "No analytics data"),
1057
1063
  description: n("devportal.noAnalyticsDataDescription", "Analytics data will appear here once the application starts receiving traffic.")
1058
1064
  })
1059
1065
  })]
1060
1066
  });
1061
1067
  }, Ne = "# Sample query - modify as needed\nquery IntrospectSchema {\n __schema {\n queryType { name }\n mutationType { name }\n types {\n name\n kind\n }\n }\n}", Pe = ({ app: t }) => {
1062
- let { apiGatewayUrl: n, workspacesGatewayUrl: r, authToken: i } = e(), { t: a } = L(), o = (e, t) => {
1068
+ let { apiGatewayUrl: n, workspacesGatewayUrl: r, authToken: i } = e(), { t: a } = I(), o = (e, t) => {
1063
1069
  let n = a(e);
1064
1070
  return n === e ? t : n;
1065
- }, [s, c] = I(Ne), [l, u] = I("{}"), [d, f] = I(""), [p, m] = I(!1), [h, g] = I(`${n || "https://gw-global.local.burdenoff.com"}/global/graphql`), [_, v] = I(i || ""), [y, b] = I(!1), x = N(async () => {
1071
+ }, [s, c] = F(Ne), [l, u] = F("{}"), [d, f] = F(""), [p, m] = F(!1), [h, g] = F(`${n || "https://gw-global.local.burdenoff.com"}/global/graphql`), [_, v] = F(i || ""), [y, b] = F(!1), x = M(async () => {
1066
1072
  m(!0), f("");
1067
1073
  try {
1068
1074
  let e = {};
@@ -1093,7 +1099,7 @@ var Se = [
1093
1099
  l,
1094
1100
  h,
1095
1101
  _
1096
- ]), S = N(() => {
1102
+ ]), S = M(() => {
1097
1103
  i && v(i), b(!0);
1098
1104
  }, [i]);
1099
1105
  return /* @__PURE__ */ Y("div", {
@@ -1122,7 +1128,7 @@ var Se = [
1122
1128
  })] }), /* @__PURE__ */ Y("button", {
1123
1129
  onClick: S,
1124
1130
  className: "flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-accent transition-colors",
1125
- children: [/* @__PURE__ */ J(le, { size: 14 }), o("devportal.autoFillCredentials", "Auto-fill Credentials")]
1131
+ children: [/* @__PURE__ */ J(ue, { size: 14 }), o("devportal.autoFillCredentials", "Auto-fill Credentials")]
1126
1132
  })]
1127
1133
  }),
1128
1134
  y && /* @__PURE__ */ Y("div", {
@@ -1223,10 +1229,10 @@ var Se = [
1223
1229
  onClick: x,
1224
1230
  disabled: p,
1225
1231
  className: "flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50",
1226
- children: [p ? /* @__PURE__ */ J(H, {
1232
+ children: [p ? /* @__PURE__ */ J(V, {
1227
1233
  size: 16,
1228
1234
  className: "animate-spin"
1229
- }) : /* @__PURE__ */ J(B, { size: 16 }), p ? o("devportal.executing", "Executing...") : o("devportal.executeQuery", "Execute Query")]
1235
+ }) : /* @__PURE__ */ J(z, { size: 16 }), p ? o("devportal.executing", "Executing...") : o("devportal.executeQuery", "Execute Query")]
1230
1236
  }),
1231
1237
  d && /* @__PURE__ */ Y("div", { children: [/* @__PURE__ */ J("label", {
1232
1238
  className: "block text-sm font-medium mb-1",
@@ -1238,7 +1244,7 @@ var Se = [
1238
1244
  ]
1239
1245
  });
1240
1246
  }, Fe = ({ label: e, value: n, onChange: r, hint: i, accept: a = "image/png,image/jpeg,image/webp,image/gif,image/svg+xml", aspectClass: o = "aspect-square", upload: s, uploading: c, progress: l, error: u }) => {
1241
- let d = F(null), f = N(async (e) => {
1247
+ let d = P(null), f = M(async (e) => {
1242
1248
  try {
1243
1249
  r((await s(e)).downloadUrl);
1244
1250
  } catch {}
@@ -1263,7 +1269,7 @@ var Se = [
1263
1269
  className: "text-text-secondary opacity-40"
1264
1270
  }), c && /* @__PURE__ */ Y("div", {
1265
1271
  className: "absolute inset-0 bg-black/40 flex flex-col items-center justify-center gap-1",
1266
- children: [/* @__PURE__ */ J(H, {
1272
+ children: [/* @__PURE__ */ J(V, {
1267
1273
  size: 14,
1268
1274
  className: "animate-spin text-white"
1269
1275
  }), /* @__PURE__ */ Y("span", {
@@ -1312,7 +1318,7 @@ var Se = [
1312
1318
  ]
1313
1319
  });
1314
1320
  }, Ie = ({ urls: e, onChange: n, upload: r, uploading: i, progress: a, error: o }) => {
1315
- let s = F(null), c = N(async (t) => {
1321
+ let s = P(null), c = M(async (t) => {
1316
1322
  try {
1317
1323
  let i = await r(t);
1318
1324
  n([...e, i.downloadUrl]);
@@ -1350,7 +1356,7 @@ var Se = [
1350
1356
  disabled: i,
1351
1357
  onClick: () => s.current?.click(),
1352
1358
  className: t("w-36 aspect-video rounded-lg border-2 border-dashed border-border flex flex-col items-center justify-center gap-1.5 text-text-secondary hover:border-border-strong hover:bg-bg-sunken transition-colors disabled:opacity-50"),
1353
- children: i ? /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(H, {
1359
+ children: i ? /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(V, {
1354
1360
  size: 18,
1355
1361
  className: "animate-spin text-primary"
1356
1362
  }), /* @__PURE__ */ Y("span", {
@@ -1484,13 +1490,13 @@ function Be(e) {
1484
1490
  };
1485
1491
  }
1486
1492
  var Ve = ({ app: n }) => {
1487
- let { workspacesGatewayUrl: r, authToken: i, workspaceId: a, getWorkspaceToken: o } = e(), { t: s } = L(), c = (e, t) => {
1493
+ let { workspacesGatewayUrl: r, authToken: i, workspaceId: a, getWorkspaceToken: o } = e(), { t: s } = I(), c = (e, t) => {
1488
1494
  let n = s(e);
1489
1495
  return n === e ? t : n;
1490
- }, [l, u] = I(() => Be(n)), [d, f] = I(!1), [m, g] = I(!1), v = F(n);
1496
+ }, [l, u] = F(() => Be(n)), [d, f] = F(!1), [m, g] = F(!1), v = P(n);
1491
1497
  v.current = n;
1492
1498
  let [y] = h(), [b, { loading: x }] = p();
1493
- ne(() => {
1499
+ re(() => {
1494
1500
  u(Be(v.current));
1495
1501
  }, [n.id]);
1496
1502
  let S = (e, t) => {
@@ -1550,7 +1556,7 @@ var Ve = ({ app: n }) => {
1550
1556
  } catch {
1551
1557
  C("error");
1552
1558
  }
1553
- }, T = F(null), k = F(null), { upload: A, uploading: j, progress: te, error: P } = M(r, i, a, o), { upload: ie, uploading: R, progress: se, error: B } = M(r, i, a, o, "/DevPortal/Assets"), { upload: ce, uploading: le, progress: ue, error: U } = M(r, i, a, o, "/DevPortal/Assets"), { upload: de, uploading: fe, progress: pe, error: me } = M(r, i, a, o, "/DevPortal/Assets"), G = N(async (e) => {
1559
+ }, T = P(null), k = P(null), { upload: A, uploading: te, progress: ne, error: N } = j(r, i, a, o), { upload: ae, uploading: L, progress: ce, error: z } = j(r, i, a, o, "/DevPortal/Assets"), { upload: le, uploading: ue, progress: de, error: H } = j(r, i, a, o, "/DevPortal/Assets"), { upload: fe, uploading: pe, progress: me, error: U } = j(r, i, a, o, "/DevPortal/Assets"), G = M(async (e) => {
1554
1560
  let t = e.target.files?.[0];
1555
1561
  if (t) {
1556
1562
  e.target.value = "";
@@ -1562,7 +1568,7 @@ var Ve = ({ app: n }) => {
1562
1568
  }));
1563
1569
  } catch {}
1564
1570
  }
1565
- }, [A]), ge = N(async (e) => {
1571
+ }, [A]), ge = M(async (e) => {
1566
1572
  e.preventDefault(), g(!1);
1567
1573
  let t = e.dataTransfer.files?.[0];
1568
1574
  if (t) try {
@@ -1572,7 +1578,7 @@ var Ve = ({ app: n }) => {
1572
1578
  manifestRegistryUrl: e.downloadUrl
1573
1579
  }));
1574
1580
  } catch {}
1575
- }, [A]), K = N((e) => {
1581
+ }, [A]), K = M((e) => {
1576
1582
  let t = e.target.files?.[0];
1577
1583
  if (!t) return;
1578
1584
  let n = new FileReader();
@@ -1591,7 +1597,7 @@ var Ve = ({ app: n }) => {
1591
1597
  }));
1592
1598
  } catch {}
1593
1599
  }, n.readAsText(t), e.target.value = "";
1594
- }, []), _e = N(() => {
1600
+ }, []), _e = M(() => {
1595
1601
  let e = l.manifestPermissionsText.split("\n").map((e) => e.trim()).filter(Boolean), t = Le.has(l.manifestItemType), r = {
1596
1602
  manifestVersion: "1.0",
1597
1603
  itemType: l.manifestItemType || void 0,
@@ -1615,7 +1621,7 @@ var Ve = ({ app: n }) => {
1615
1621
  children: [
1616
1622
  Se ? /* @__PURE__ */ Y("div", {
1617
1623
  className: "flex items-start gap-3 rounded-lg border border-success/30 bg-success/10 px-4 py-3",
1618
- children: [/* @__PURE__ */ J(z, {
1624
+ children: [/* @__PURE__ */ J(R, {
1619
1625
  size: 16,
1620
1626
  className: "text-success mt-0.5 shrink-0"
1621
1627
  }), /* @__PURE__ */ Y("div", {
@@ -1634,7 +1640,7 @@ var Ve = ({ app: n }) => {
1634
1640
  })]
1635
1641
  }) : xe ? /* @__PURE__ */ Y("div", {
1636
1642
  className: "flex items-start gap-3 rounded-lg border border-primary/30 bg-primary/5 px-4 py-3",
1637
- children: [/* @__PURE__ */ J(ae, {
1643
+ children: [/* @__PURE__ */ J(oe, {
1638
1644
  size: 16,
1639
1645
  className: "text-primary mt-0.5 shrink-0"
1640
1646
  }), /* @__PURE__ */ Y("div", {
@@ -1656,7 +1662,7 @@ var Ve = ({ app: n }) => {
1656
1662
  })]
1657
1663
  }) : /* @__PURE__ */ Y("div", {
1658
1664
  className: "flex items-start gap-3 rounded-lg border border-warning/30 bg-warning/5 px-4 py-3",
1659
- children: [/* @__PURE__ */ J(re, {
1665
+ children: [/* @__PURE__ */ J(ie, {
1660
1666
  size: 16,
1661
1667
  className: "text-warning mt-0.5 shrink-0"
1662
1668
  }), /* @__PURE__ */ Y("div", {
@@ -1734,7 +1740,7 @@ var Ve = ({ app: n }) => {
1734
1740
  !ye && /* @__PURE__ */ Y(q, { children: [
1735
1741
  /* @__PURE__ */ Y("div", {
1736
1742
  className: "flex gap-3 rounded-lg border border-border-subtle bg-bg-sunken p-3 text-sm text-text-secondary",
1737
- children: [/* @__PURE__ */ J(V, {
1743
+ children: [/* @__PURE__ */ J(B, {
1738
1744
  size: 15,
1739
1745
  className: "mt-0.5 shrink-0"
1740
1746
  }), /* @__PURE__ */ Y("span", { children: [
@@ -1752,16 +1758,16 @@ var Ve = ({ app: n }) => {
1752
1758
  },
1753
1759
  onDragLeave: () => g(!1),
1754
1760
  onDrop: (e) => void ge(e),
1755
- onClick: () => !j && k.current?.click(),
1756
- className: t("relative flex flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed px-6 py-10 text-center transition-colors cursor-pointer", m ? "border-primary bg-primary/5" : "border-border hover:border-border-strong hover:bg-bg-sunken", j && "pointer-events-none opacity-75"),
1761
+ onClick: () => !te && k.current?.click(),
1762
+ className: t("relative flex flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed px-6 py-10 text-center transition-colors cursor-pointer", m ? "border-primary bg-primary/5" : "border-border hover:border-border-strong hover:bg-bg-sunken", te && "pointer-events-none opacity-75"),
1757
1763
  children: [/* @__PURE__ */ J("input", {
1758
1764
  ref: k,
1759
1765
  type: "file",
1760
1766
  accept: ".zip,application/zip,application/x-zip-compressed",
1761
1767
  className: "hidden",
1762
1768
  onChange: (e) => void G(e)
1763
- }), j ? /* @__PURE__ */ Y(q, { children: [
1764
- /* @__PURE__ */ J(H, {
1769
+ }), te ? /* @__PURE__ */ Y(q, { children: [
1770
+ /* @__PURE__ */ J(V, {
1765
1771
  size: 28,
1766
1772
  className: "animate-spin text-primary"
1767
1773
  }),
@@ -1770,7 +1776,7 @@ var Ve = ({ app: n }) => {
1770
1776
  children: [
1771
1777
  c("devportal.uploading", "Uploading…"),
1772
1778
  " ",
1773
- te,
1779
+ ne,
1774
1780
  "%"
1775
1781
  ]
1776
1782
  }), /* @__PURE__ */ J("p", {
@@ -1781,10 +1787,10 @@ var Ve = ({ app: n }) => {
1781
1787
  className: "w-48 h-1.5 rounded-full bg-muted overflow-hidden",
1782
1788
  children: /* @__PURE__ */ J("div", {
1783
1789
  className: "h-full bg-primary transition-all",
1784
- style: { width: `${te}%` }
1790
+ style: { width: `${ne}%` }
1785
1791
  })
1786
1792
  })
1787
- ] }) : be ? /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(z, {
1793
+ ] }) : be ? /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(R, {
1788
1794
  size: 28,
1789
1795
  className: "text-status-success-text"
1790
1796
  }), /* @__PURE__ */ Y("div", { children: [/* @__PURE__ */ J("p", {
@@ -1804,14 +1810,14 @@ var Ve = ({ app: n }) => {
1804
1810
  children: c("devportal.orClickToBrowse", "or click to browse")
1805
1811
  })] })] })]
1806
1812
  }),
1807
- P && /* @__PURE__ */ J("p", {
1813
+ N && /* @__PURE__ */ J("p", {
1808
1814
  className: "text-xs text-status-error-text",
1809
- children: P
1815
+ children: N
1810
1816
  })
1811
1817
  ] }),
1812
1818
  ye && /* @__PURE__ */ Y("div", {
1813
1819
  className: "flex gap-3 rounded-lg border border-border-subtle bg-bg-sunken p-3 text-sm text-text-secondary",
1814
- children: [/* @__PURE__ */ J(V, {
1820
+ children: [/* @__PURE__ */ J(B, {
1815
1821
  size: 15,
1816
1822
  className: "mt-0.5 shrink-0"
1817
1823
  }), /* @__PURE__ */ J("span", { children: c("devportal.builtinHint", "Built-in items are pre-installed by the platform. No package upload is needed.") })]
@@ -1842,7 +1848,7 @@ var Ve = ({ app: n }) => {
1842
1848
  type: "button",
1843
1849
  onClick: _e,
1844
1850
  className: "inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs font-medium hover:bg-muted transition-colors",
1845
- children: [/* @__PURE__ */ J(oe, { size: 12 }), c("devportal.exportManifest", "Export")]
1851
+ children: [/* @__PURE__ */ J(se, { size: 12 }), c("devportal.exportManifest", "Export")]
1846
1852
  }),
1847
1853
  /* @__PURE__ */ J("span", {
1848
1854
  className: "text-xs text-text-secondary",
@@ -1867,20 +1873,20 @@ var Ve = ({ app: n }) => {
1867
1873
  onChange: (e) => S("iconUrl", e),
1868
1874
  hint: c("devportal.iconUrlHint", "Square, 256×256 px recommended"),
1869
1875
  aspectClass: "aspect-square",
1870
- upload: ie,
1871
- uploading: R,
1872
- progress: se,
1873
- error: B
1876
+ upload: ae,
1877
+ uploading: L,
1878
+ progress: ce,
1879
+ error: z
1874
1880
  }), /* @__PURE__ */ J(Fe, {
1875
1881
  label: c("devportal.bannerUrl", "Banner"),
1876
1882
  value: l.bannerUrl,
1877
1883
  onChange: (e) => S("bannerUrl", e),
1878
1884
  hint: c("devportal.bannerUrlHint", "1280×640 px recommended"),
1879
1885
  aspectClass: "aspect-video",
1880
- upload: ce,
1881
- uploading: le,
1882
- progress: ue,
1883
- error: U
1886
+ upload: le,
1887
+ uploading: ue,
1888
+ progress: de,
1889
+ error: H
1884
1890
  })]
1885
1891
  }),
1886
1892
  /* @__PURE__ */ J(E, {
@@ -1908,10 +1914,10 @@ var Ve = ({ app: n }) => {
1908
1914
  /* @__PURE__ */ J(Ie, {
1909
1915
  urls: l.screenshotsText.split("\n").map((e) => e.trim()).filter(Boolean),
1910
1916
  onChange: (e) => S("screenshotsText", e.join("\n")),
1911
- upload: de,
1912
- uploading: fe,
1913
- progress: pe,
1914
- error: me
1917
+ upload: fe,
1918
+ uploading: pe,
1919
+ progress: me,
1920
+ error: U
1915
1921
  })
1916
1922
  ]
1917
1923
  })
@@ -2003,7 +2009,7 @@ var Ve = ({ app: n }) => {
2003
2009
  onClick: ee,
2004
2010
  disabled: d,
2005
2011
  className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50",
2006
- children: d ? /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(H, {
2012
+ children: d ? /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(V, {
2007
2013
  size: 16,
2008
2014
  className: "animate-spin"
2009
2015
  }), c("devportal.saving", "Saving…")] }) : /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(he, { size: 16 }), c("devportal.saveStoreListing", "Save Store Listing")] })
@@ -2012,16 +2018,16 @@ var Ve = ({ app: n }) => {
2012
2018
  onClick: () => void w(),
2013
2019
  disabled: x || d,
2014
2020
  className: "inline-flex items-center gap-2 rounded-md border border-primary px-4 py-2 text-sm font-medium text-primary hover:bg-primary/5 transition-colors disabled:opacity-50",
2015
- children: x ? /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(H, {
2021
+ children: x ? /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(V, {
2016
2022
  size: 16,
2017
2023
  className: "animate-spin"
2018
- }), c("devportal.submitting", "Submitting…")] }) : /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(z, { size: 16 }), xe ? c("devportal.resubmitForReview", "Resubmit for Review") : c("devportal.submitForReview", "Submit for Review")] })
2024
+ }), c("devportal.submitting", "Submitting…")] }) : /* @__PURE__ */ Y(q, { children: [/* @__PURE__ */ J(R, { size: 16 }), xe ? c("devportal.resubmitForReview", "Resubmit for Review") : c("devportal.submitForReview", "Submit for Review")] })
2019
2025
  })]
2020
2026
  })
2021
2027
  ]
2022
2028
  });
2023
2029
  }, Q = ({ label: e, value: n, trend: r }) => {
2024
- let { t: i } = L();
2030
+ let { t: i } = I();
2025
2031
  return /* @__PURE__ */ Y("div", {
2026
2032
  className: "rounded-lg border bg-card p-4",
2027
2033
  children: [
@@ -2052,8 +2058,191 @@ var Ve = ({ app: n }) => {
2052
2058
  target: "_blank",
2053
2059
  rel: "noopener noreferrer",
2054
2060
  className: "flex items-center gap-2 text-sm text-primary hover:underline",
2055
- children: [/* @__PURE__ */ J(B, { size: 14 }), e]
2056
- });
2061
+ children: [/* @__PURE__ */ J(z, { size: 14 }), e]
2062
+ }), He = [
2063
+ {
2064
+ id: "auth",
2065
+ label: "Authentication",
2066
+ description: "User identity and session management"
2067
+ },
2068
+ {
2069
+ id: "billing",
2070
+ label: "Billing",
2071
+ description: "Billing accounts and subscriptions"
2072
+ },
2073
+ {
2074
+ id: "files",
2075
+ label: "Files",
2076
+ description: "File storage and management"
2077
+ },
2078
+ {
2079
+ id: "tags",
2080
+ label: "Tags",
2081
+ description: "Tags and labels on resources"
2082
+ },
2083
+ {
2084
+ id: "calendar",
2085
+ label: "Calendar",
2086
+ description: "Events and scheduling"
2087
+ },
2088
+ {
2089
+ id: "workflows",
2090
+ label: "Workflows",
2091
+ description: "Automation workflows"
2092
+ },
2093
+ {
2094
+ id: "channels",
2095
+ label: "Channels",
2096
+ description: "Messaging channels"
2097
+ },
2098
+ {
2099
+ id: "notifications",
2100
+ label: "Notifications",
2101
+ description: "Platform notifications"
2102
+ },
2103
+ {
2104
+ id: "users",
2105
+ label: "Users & Members",
2106
+ description: "Workspace members and profiles"
2107
+ },
2108
+ {
2109
+ id: "workspaces",
2110
+ label: "Workspaces",
2111
+ description: "Workspace settings and metadata"
2112
+ },
2113
+ {
2114
+ id: "content",
2115
+ label: "Content",
2116
+ description: "Pages, documents, and content"
2117
+ },
2118
+ {
2119
+ id: "analytics",
2120
+ label: "Analytics",
2121
+ description: "Usage analytics and reporting"
2122
+ },
2123
+ {
2124
+ id: "webhooks",
2125
+ label: "Webhooks",
2126
+ description: "Webhook subscriptions"
2127
+ },
2128
+ {
2129
+ id: "rbac",
2130
+ label: "Roles & Permissions",
2131
+ description: "Access control configuration"
2132
+ }
2133
+ ];
2134
+ function Ue(e) {
2135
+ let t = Object.fromEntries(He.map((e) => [e.id, "none"]));
2136
+ if (!e || !Array.isArray(e.permissions)) return t;
2137
+ for (let n of e.permissions) n.resource in t && (t[n.resource] = n.level === "write" ? "write" : "read");
2138
+ return t;
2139
+ }
2140
+ var We = ({ app: e }) => {
2141
+ let t = e.manifest ?? {}, [n, r] = F(() => Ue(t)), [i, a] = F(!1), [o, s] = F(!1), [c] = h(), l = (e, t) => {
2142
+ s(!1), r((n) => ({
2143
+ ...n,
2144
+ [e]: t
2145
+ }));
2146
+ }, u = async () => {
2147
+ a(!0);
2148
+ try {
2149
+ let r = Object.entries(n).filter(([, e]) => e !== "none").map(([e, t]) => ({
2150
+ resource: e,
2151
+ level: t
2152
+ }));
2153
+ await c({ variables: {
2154
+ id: e.id,
2155
+ input: { manifest: {
2156
+ ...t,
2157
+ permissions: r
2158
+ } }
2159
+ } }), s(!0);
2160
+ } finally {
2161
+ a(!1);
2162
+ }
2163
+ }, d = {
2164
+ none: "No access",
2165
+ read: "Read",
2166
+ write: "Read & Write"
2167
+ }, f = [
2168
+ "none",
2169
+ "read",
2170
+ "write"
2171
+ ];
2172
+ return /* @__PURE__ */ J(_, {
2173
+ title: "Permissions",
2174
+ description: "Define what platform data this app can request access to. Users see these when authorizing the app.",
2175
+ children: /* @__PURE__ */ Y("div", {
2176
+ className: "space-y-4",
2177
+ children: [
2178
+ /* @__PURE__ */ J("div", {
2179
+ className: "overflow-x-auto rounded-lg border border-border",
2180
+ children: /* @__PURE__ */ Y("table", {
2181
+ className: "w-full text-sm",
2182
+ children: [/* @__PURE__ */ J("thead", { children: /* @__PURE__ */ Y("tr", {
2183
+ className: "border-b border-border bg-muted/50",
2184
+ children: [/* @__PURE__ */ J("th", {
2185
+ className: "px-4 py-3 text-left font-medium text-muted-foreground w-1/2",
2186
+ children: "Resource"
2187
+ }), f.map((e) => /* @__PURE__ */ J("th", {
2188
+ className: "px-4 py-3 text-center font-medium text-muted-foreground",
2189
+ children: d[e]
2190
+ }, e))]
2191
+ }) }), /* @__PURE__ */ J("tbody", {
2192
+ className: "divide-y divide-border",
2193
+ children: He.map((e) => /* @__PURE__ */ Y("tr", {
2194
+ className: "hover:bg-muted/30 transition-colors",
2195
+ children: [/* @__PURE__ */ Y("td", {
2196
+ className: "px-4 py-3",
2197
+ children: [/* @__PURE__ */ J("p", {
2198
+ className: "font-medium text-foreground",
2199
+ children: e.label
2200
+ }), /* @__PURE__ */ J("p", {
2201
+ className: "text-xs text-muted-foreground",
2202
+ children: e.description
2203
+ })]
2204
+ }), f.map((t) => /* @__PURE__ */ J("td", {
2205
+ className: "px-4 py-3 text-center",
2206
+ children: /* @__PURE__ */ J("input", {
2207
+ type: "radio",
2208
+ name: `perm-${e.id}`,
2209
+ value: t,
2210
+ checked: n[e.id] === t,
2211
+ onChange: () => l(e.id, t),
2212
+ className: "h-4 w-4 accent-primary cursor-pointer"
2213
+ })
2214
+ }, t))]
2215
+ }, e.id))
2216
+ })]
2217
+ })
2218
+ }),
2219
+ /* @__PURE__ */ Y("div", {
2220
+ className: "rounded-lg border border-border-subtle bg-muted/30 p-3 flex gap-2 text-xs text-muted-foreground",
2221
+ children: [/* @__PURE__ */ J(B, {
2222
+ size: 14,
2223
+ className: "flex-shrink-0 mt-0.5"
2224
+ }), /* @__PURE__ */ Y("span", { children: [/* @__PURE__ */ J("strong", { children: "Read & Write" }), " implies Read. Request only what your app genuinely needs — fewer permissions build more user trust."] })]
2225
+ }),
2226
+ /* @__PURE__ */ Y("div", {
2227
+ className: "flex items-center justify-end gap-3",
2228
+ children: [o && /* @__PURE__ */ Y("span", {
2229
+ className: "flex items-center gap-1.5 text-sm text-status-success-text",
2230
+ children: [/* @__PURE__ */ J(R, { size: 14 }), "Saved"]
2231
+ }), /* @__PURE__ */ Y("button", {
2232
+ type: "button",
2233
+ onClick: () => void u(),
2234
+ disabled: i,
2235
+ className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50",
2236
+ children: [i ? /* @__PURE__ */ J(V, {
2237
+ size: 14,
2238
+ className: "animate-spin"
2239
+ }) : /* @__PURE__ */ J(U, { size: 14 }), "Save Permissions"]
2240
+ })]
2241
+ })
2242
+ ]
2243
+ })
2244
+ });
2245
+ };
2057
2246
  //#endregion
2058
2247
  export { Te as ApplicationDetailPage };
2059
2248