@burdenoff/microfe-devportal 2026.624.11 → 2026.624.12

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.
@@ -14,134 +14,168 @@ import { useDevportalPermission as c } from "../hooks/usePermission.js";
14
14
  import "../hooks/index.js";
15
15
  import ce from "../../node_modules/.bun/date-fns@3.6.0/node_modules/date-fns/format.js";
16
16
  import { usePackageUpload as le } from "../hooks/usePackageUpload.js";
17
- import { useCallback as ue, useEffect as de, useMemo as l, useRef as u, useState as d } from "react";
18
- import { useI18n as fe } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
19
- import { AlertCircle as f, Archive as pe, CheckCircle as p, Clock as me, FileJson as m, Loader2 as h, Package as he, Plus as ge, Upload as g } from "lucide-react";
17
+ import { useCallback as l, useEffect as ue, useMemo as u, useRef as d, useState as f } from "react";
18
+ import { useI18n as de } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
19
+ import { AlertCircle as p, Archive as fe, CheckCircle as m, Clock as pe, FileJson as me, Loader2 as h, Package as he, Plus as ge, Upload as g } from "lucide-react";
20
20
  import { useParams as _e } from "react-router-dom";
21
21
  import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
22
+ import { gql as ve } from "@apollo/client";
23
+ import { useMutation as ye, useQuery as be } from "@apollo/client/react";
22
24
  //#region src/devportal/pages/ApplicationVersionsPage.tsx
23
- var ve = () => {
24
- let { t: ve } = fe(), b = (e, t) => {
25
- let n = ve(e);
25
+ var xe = () => {
26
+ let { t: xe } = de(), b = (e, t) => {
27
+ let n = xe(e);
26
28
  return n === e ? t : n;
27
- }, { allowed: ye } = c(s.APP_VERSION_CREATE), { allowed: x } = c(s.APP_VERSION_PUBLISH), { allowed: S } = c(s.APP_VERSION_DEPRECATE), { appId: C } = _e(), { workspacesGatewayUrl: be, authToken: xe, workspaceId: Se, getWorkspaceToken: Ce } = e(), { upload: w, uploading: T, progress: E, error: D } = le(be, xe, Se, Ce), O = u(null), k = u(null), [A, j] = d(!1), [M, N] = d({
29
+ }, { allowed: Se } = c(s.APP_VERSION_CREATE), { allowed: x } = c(s.APP_VERSION_PUBLISH), { allowed: S } = c(s.APP_VERSION_DEPRECATE), { appId: C } = _e(), { workspacesGatewayUrl: Ce, authToken: we, workspaceId: Te, getWorkspaceToken: Ee } = e(), { data: De } = be(ve`query MyPublisherProductsVersions { myPublisher { id products { id productId } } }`, { fetchPolicy: "cache-first" }), w = De?.myPublisher?.products.find((e) => e.productId === C)?.id ?? null, [Oe] = ye(ve`
30
+ mutation UpdateStoreProductVersion($input: UpdateProductInput!) {
31
+ updateProduct(input: $input) { id manifestVersion }
32
+ }
33
+ `), { upload: T, uploading: E, progress: D, error: O } = le(Ce, we, Te, Ee), k = d(null), A = d(null), [j, M] = f(!1), [N, P] = f({
28
34
  version: "",
29
35
  releaseNotes: "",
30
36
  changelog: "",
31
37
  packageUrl: "",
32
38
  packageSize: "",
33
39
  manifestJson: ""
34
- }), [P, F] = d(null), [I, L] = d("file"), [R, z] = d(null), [we, B] = d(null), [V, H] = d(/* @__PURE__ */ new Set()), [Te, U] = d(null), { data: W } = ee({
40
+ }), [F, I] = f(null), [L, R] = f("file"), [ke, z] = f(null), [Ae, B] = f(null), [V, H] = f(/* @__PURE__ */ new Set()), [je, U] = f(null), { data: W } = ee({
35
41
  variables: { id: C ?? "" },
36
42
  skip: !C,
37
43
  fetchPolicy: "cache-first"
38
- }), Ee = W?.application?.appType === "NODE" || W?.application?.appType === "WORKFLOW";
39
- de(() => {
44
+ }), Me = W?.application?.appType === "NODE" || W?.application?.appType === "WORKFLOW";
45
+ ue(() => {
40
46
  let e = W?.application?.name;
41
47
  if (!C || !e) return;
42
48
  let t = window.__breadcrumbRegistry;
43
49
  return t?.register(C, e), () => t?.unregister(C);
44
50
  }, [C, W?.application?.name]);
45
- let { data: G, loading: De, error: Oe } = te({
51
+ let { data: G, loading: Ne, error: Pe } = te({
46
52
  variables: { applicationId: C },
47
53
  skip: !C,
48
54
  fetchPolicy: "cache-and-network"
49
- }), [ke, { loading: Ae }] = n({ refetchQueries: ["GetApplicationVersions"] }), [je] = ne({ refetchQueries: ["GetApplicationVersions"] }), [Me] = r({ refetchQueries: ["GetApplicationVersions"] }), K = l(() => G?.application?.versions?.edges?.map((e) => e.node) ?? [], [G?.application?.versions]), q = l(() => K.filter((e) => V.has(e.id)), [K, V]), J = l(() => q.filter((e) => e.status?.toUpperCase() === "DRAFT"), [q]), Y = l(() => q.filter((e) => e.status?.toUpperCase() === "PUBLISHED" && !e.isLatest), [q]), X = K.length > 0 && K.every((e) => V.has(e.id)), Z = K.some((e) => V.has(e.id)) && !X, Ne = async () => {
50
- if (!C || !M.version.trim()) return;
51
- if (z(null), Ee) {
52
- if (!M.packageUrl) {
55
+ }), [Fe, { loading: Ie }] = n({ refetchQueries: ["GetApplicationVersions"] }), [Le] = ne({ refetchQueries: ["GetApplicationVersions"] }), [K] = r({ refetchQueries: ["GetApplicationVersions"] }), q = u(() => G?.application?.versions?.edges?.map((e) => e.node) ?? [], [G?.application?.versions]), J = u(() => q.filter((e) => V.has(e.id)), [q, V]), Y = u(() => J.filter((e) => e.status?.toUpperCase() === "DRAFT"), [J]), X = u(() => J.filter((e) => e.status?.toUpperCase() === "PUBLISHED" && !e.isLatest), [J]), Z = q.length > 0 && q.every((e) => V.has(e.id)), Re = q.some((e) => V.has(e.id)) && !Z, ze = async () => {
56
+ if (!C || !N.version.trim()) return;
57
+ if (z(null), Me) {
58
+ if (!N.packageUrl) {
53
59
  z("A ZIP package is required for this app type.");
54
60
  return;
55
61
  }
56
- if (!M.manifestJson.trim()) {
62
+ if (!N.manifestJson.trim()) {
57
63
  z("A manifest JSON is required for this app type.");
58
64
  return;
59
65
  }
60
66
  }
61
67
  let e;
62
- if (M.manifestJson.trim()) try {
63
- e = JSON.parse(M.manifestJson);
68
+ if (N.manifestJson.trim()) try {
69
+ e = JSON.parse(N.manifestJson);
64
70
  } catch {
65
71
  z("Invalid JSON in manifest — please check your input.");
66
72
  return;
67
73
  }
68
74
  try {
69
- await ke({ variables: {
75
+ await Fe({ variables: {
70
76
  applicationId: C,
71
77
  input: {
72
- version: M.version,
73
- releaseNotes: M.releaseNotes || void 0,
74
- changelog: M.changelog || void 0,
75
- packageUrl: M.packageUrl || void 0,
76
- packageSize: M.packageSize || void 0,
78
+ version: N.version,
79
+ releaseNotes: N.releaseNotes || void 0,
80
+ changelog: N.changelog || void 0,
81
+ packageUrl: N.packageUrl || void 0,
82
+ packageSize: N.packageSize || void 0,
77
83
  manifest: e
78
84
  }
79
- } }), j(!1), N({
85
+ } }), M(!1), P({
80
86
  version: "",
81
87
  releaseNotes: "",
82
88
  changelog: "",
83
89
  packageUrl: "",
84
90
  packageSize: "",
85
91
  manifestJson: ""
86
- }), F(null), L("file"), B(b("devportal.versionCreatedSuccess", "Version created successfully"));
92
+ }), I(null), R("file"), B(b("devportal.versionCreatedSuccess", "Version created successfully"));
87
93
  } catch (e) {
88
94
  z(e instanceof Error ? e.message : b("devportal.versionCreateFailed", "Failed to create version"));
89
95
  }
90
- }, Pe = ue(async (e) => {
96
+ }, Be = l(async (e) => {
91
97
  let t = e.target.files?.[0];
92
98
  if (t) {
93
99
  e.target.value = "";
94
100
  try {
95
- let e = await w(t);
96
- N((n) => ({
101
+ let e = await T(t);
102
+ P((n) => ({
97
103
  ...n,
98
104
  packageUrl: e.downloadUrl,
99
105
  packageSize: String(t.size)
100
106
  }));
101
107
  } catch {}
102
108
  }
103
- }, [w]), Fe = ue((e) => {
109
+ }, [T]), Ve = l((e) => {
104
110
  let t = e.target.files?.[0];
105
111
  if (!t) return;
106
112
  e.target.value = "";
107
113
  let n = new FileReader();
108
114
  n.onload = (e) => {
109
115
  let n = e.target?.result;
110
- typeof n == "string" && (F(t.name), N((e) => ({
116
+ typeof n == "string" && (I(t.name), P((e) => ({
111
117
  ...e,
112
118
  manifestJson: n
113
119
  })));
114
120
  }, n.readAsText(t);
115
- }, []), Ie = async (e) => {
121
+ }, []), He = async (e) => {
116
122
  z(null), B(null);
117
123
  try {
118
- await je({ variables: { id: e } }), B(b("devportal.versionPublishedSuccess", "Version published successfully"));
124
+ if (await Le({ variables: { id: e } }), w) {
125
+ let t = q.find((t) => t.id === e);
126
+ t && await Oe({ variables: { input: {
127
+ id: w,
128
+ manifestVersion: t.version,
129
+ manifest: {
130
+ manifestVersion: "1.0",
131
+ name: W?.application?.slug ?? "",
132
+ version: t.version,
133
+ itemType: W?.application?.appType?.toLowerCase() ?? "node",
134
+ identity: {
135
+ name: W?.application?.slug ?? "",
136
+ version: t.version,
137
+ displayName: W?.application?.name ?? "",
138
+ description: W?.application?.shortDescription ?? W?.application?.description ?? ""
139
+ },
140
+ publisher: {
141
+ id: W?.application?.developerId ?? "",
142
+ name: "Burdenoff"
143
+ },
144
+ pricing: {
145
+ currency: "USD",
146
+ model: "FREE"
147
+ },
148
+ permissions: []
149
+ }
150
+ } } }).catch(() => {});
151
+ }
152
+ B(b("devportal.versionPublishedSuccess", "Version published successfully"));
119
153
  } catch (e) {
120
154
  z(e instanceof Error ? e.message : b("devportal.versionPublishFailed", "Failed to publish version"));
121
155
  }
122
- }, Le = async (e) => {
156
+ }, Ue = async (e) => {
123
157
  z(null), B(null);
124
158
  try {
125
- await Me({ variables: { id: e } }), B(b("devportal.versionDeprecatedSuccess", "Version deprecated successfully"));
159
+ await K({ variables: { id: e } }), B(b("devportal.versionDeprecatedSuccess", "Version deprecated successfully"));
126
160
  } catch (e) {
127
161
  z(e instanceof Error ? e.message : b("devportal.versionDeprecateFailed", "Failed to deprecate version"));
128
162
  }
129
- }, Re = (e) => {
163
+ }, We = (e) => {
130
164
  let t = e.status?.toUpperCase();
131
- return t === "PUBLISHED" && e.isLatest ? /* @__PURE__ */ v(p, {
165
+ return t === "PUBLISHED" && e.isLatest ? /* @__PURE__ */ v(m, {
132
166
  size: 16,
133
167
  className: "text-status-success-text"
134
- }) : t === "DRAFT" ? /* @__PURE__ */ v(me, {
168
+ }) : t === "DRAFT" ? /* @__PURE__ */ v(pe, {
135
169
  size: 16,
136
170
  className: "text-status-warning-text"
137
- }) : t === "DEPRECATED" ? /* @__PURE__ */ v(pe, {
171
+ }) : t === "DEPRECATED" ? /* @__PURE__ */ v(fe, {
138
172
  size: 16,
139
173
  className: "text-text-secondary"
140
174
  }) : /* @__PURE__ */ v(he, {
141
175
  size: 16,
142
176
  className: "text-accent-blue"
143
177
  });
144
- }, ze = (e, t) => {
178
+ }, Ge = (e, t) => {
145
179
  H((n) => {
146
180
  let r = new Set(n);
147
181
  return t ? r.add(e) : r.delete(e), r;
@@ -149,12 +183,12 @@ var ve = () => {
149
183
  }, Q = (e) => {
150
184
  H((t) => {
151
185
  let n = new Set(t);
152
- return K.forEach((t) => {
186
+ return q.forEach((t) => {
153
187
  e ? n.add(t.id) : n.delete(t.id);
154
188
  }), n;
155
189
  });
156
190
  }, $ = () => H(/* @__PURE__ */ new Set());
157
- return De && !G ? /* @__PURE__ */ v(i, {
191
+ return Ne && !G ? /* @__PURE__ */ v(i, {
158
192
  title: b("devportal.versionManagement", "Version Management"),
159
193
  description: b("devportal.versionManagementDescription", "Manage your application versions"),
160
194
  backLink: `/apps/${C}`,
@@ -163,18 +197,18 @@ var ve = () => {
163
197
  className: "flex items-center justify-center py-16",
164
198
  children: /* @__PURE__ */ v(h, { className: "h-8 w-8 animate-spin text-muted-foreground" })
165
199
  })
166
- }) : Oe && !G ? /* @__PURE__ */ v(i, {
200
+ }) : Pe && !G ? /* @__PURE__ */ v(i, {
167
201
  title: b("devportal.versionManagement", "Version Management"),
168
202
  description: b("devportal.versionManagementDescription", "Manage your application versions"),
169
203
  backLink: `/apps/${C}`,
170
204
  backLabel: b("devportal.backToApplication", "Back to Application"),
171
205
  children: /* @__PURE__ */ v(t, {
172
- icon: /* @__PURE__ */ v(f, {
206
+ icon: /* @__PURE__ */ v(p, {
173
207
  size: 32,
174
208
  className: "text-status-error-text"
175
209
  }),
176
210
  title: b("devportal.failedToLoadVersions", "Failed to load versions"),
177
- description: Oe.message || b("devportal.versionsLoadError", "An error occurred while loading versions")
211
+ description: Pe.message || b("devportal.versionsLoadError", "An error occurred while loading versions")
178
212
  })
179
213
  }) : /* @__PURE__ */ v(se, {
180
214
  permission: s.APP_READ,
@@ -184,21 +218,21 @@ var ve = () => {
184
218
  backLink: `/apps/${C}`,
185
219
  backLabel: b("devportal.backToApplication", "Back to Application"),
186
220
  actions: /* @__PURE__ */ y("button", {
187
- onClick: () => j(!0),
188
- disabled: !ye,
189
- "aria-disabled": !ye,
221
+ onClick: () => M(!0),
222
+ disabled: !Se,
223
+ "aria-disabled": !Se,
190
224
  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 disabled:opacity-50",
191
225
  children: [/* @__PURE__ */ v(ge, { size: 16 }), b("devportal.newVersion", "New Version")]
192
226
  }),
193
227
  children: [
194
- R && /* @__PURE__ */ y("div", {
228
+ ke && /* @__PURE__ */ y("div", {
195
229
  className: "rounded-lg border border-border-subtle bg-status-error-bg-subtle p-3 flex items-center gap-2 text-sm text-status-error-text",
196
230
  children: [
197
- /* @__PURE__ */ v(f, {
231
+ /* @__PURE__ */ v(p, {
198
232
  size: 16,
199
233
  className: "flex-shrink-0"
200
234
  }),
201
- R,
235
+ ke,
202
236
  /* @__PURE__ */ v("button", {
203
237
  onClick: () => z(null),
204
238
  className: "ml-auto text-status-error-text hover:text-status-error-text",
@@ -206,14 +240,14 @@ var ve = () => {
206
240
  })
207
241
  ]
208
242
  }),
209
- we && /* @__PURE__ */ y("div", {
243
+ Ae && /* @__PURE__ */ y("div", {
210
244
  className: "rounded-lg border border-border-subtle bg-status-success-bg-subtle p-3 flex items-center gap-2 text-sm text-status-success-text",
211
245
  children: [
212
- /* @__PURE__ */ v(p, {
246
+ /* @__PURE__ */ v(m, {
213
247
  size: 16,
214
248
  className: "flex-shrink-0"
215
249
  }),
216
- we,
250
+ Ae,
217
251
  /* @__PURE__ */ v("button", {
218
252
  onClick: () => B(null),
219
253
  className: "ml-auto text-status-success-text hover:text-status-success-text",
@@ -221,7 +255,7 @@ var ve = () => {
221
255
  })
222
256
  ]
223
257
  }),
224
- K.length > 0 && /* @__PURE__ */ v("div", {
258
+ q.length > 0 && /* @__PURE__ */ v("div", {
225
259
  className: "rounded-lg border bg-card p-4",
226
260
  children: /* @__PURE__ */ y("div", {
227
261
  className: "flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between",
@@ -230,8 +264,8 @@ var ve = () => {
230
264
  children: [/* @__PURE__ */ y("div", {
231
265
  className: "flex items-center gap-2",
232
266
  children: [/* @__PURE__ */ v(a, {
233
- checked: X,
234
- indeterminate: Z,
267
+ checked: Z,
268
+ indeterminate: Re,
235
269
  onChange: Q,
236
270
  ariaLabel: "Select all visible versions"
237
271
  }), /* @__PURE__ */ v("span", {
@@ -252,31 +286,31 @@ var ve = () => {
252
286
  }),
253
287
  /* @__PURE__ */ y("button", {
254
288
  onClick: () => U("publish"),
255
- disabled: J.length === 0 || !x,
289
+ disabled: Y.length === 0 || !x,
256
290
  "aria-disabled": !x,
257
291
  className: "rounded-md border border-status-success-bg px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle disabled:cursor-not-allowed disabled:opacity-50",
258
- children: [b("devportal.publishSelected", "Publish Selected"), J.length > 0 ? ` (${J.length})` : ""]
292
+ children: [b("devportal.publishSelected", "Publish Selected"), Y.length > 0 ? ` (${Y.length})` : ""]
259
293
  }),
260
294
  /* @__PURE__ */ y("button", {
261
295
  onClick: () => U("deprecate"),
262
- disabled: Y.length === 0 || !S,
296
+ disabled: X.length === 0 || !S,
263
297
  "aria-disabled": !S,
264
298
  className: "rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50",
265
- children: [b("devportal.deprecateSelected", "Deprecate Selected"), Y.length > 0 ? ` (${Y.length})` : ""]
299
+ children: [b("devportal.deprecateSelected", "Deprecate Selected"), X.length > 0 ? ` (${X.length})` : ""]
266
300
  })
267
301
  ]
268
302
  })]
269
303
  })
270
304
  }),
271
- K.length > 0 ? /* @__PURE__ */ v(ie, {
272
- data: K,
305
+ q.length > 0 ? /* @__PURE__ */ v(ie, {
306
+ data: q,
273
307
  keyField: "id",
274
308
  columns: [
275
309
  {
276
310
  key: "select",
277
311
  header: /* @__PURE__ */ v(a, {
278
- checked: X,
279
- indeterminate: Z,
312
+ checked: Z,
313
+ indeterminate: Re,
280
314
  onChange: Q,
281
315
  ariaLabel: "Select all visible versions"
282
316
  }),
@@ -285,7 +319,7 @@ var ve = () => {
285
319
  onClick: (e) => e.stopPropagation(),
286
320
  children: /* @__PURE__ */ v(a, {
287
321
  checked: V.has(e.id),
288
- onChange: (t) => ze(e.id, t),
322
+ onChange: (t) => Ge(e.id, t),
289
323
  ariaLabel: `Select version ${e.version}`
290
324
  })
291
325
  })
@@ -296,7 +330,7 @@ var ve = () => {
296
330
  render: (e) => /* @__PURE__ */ y("div", {
297
331
  className: "flex items-center gap-2",
298
332
  children: [
299
- Re(e),
333
+ We(e),
300
334
  /* @__PURE__ */ v("span", {
301
335
  className: "font-mono font-medium",
302
336
  children: e.version
@@ -340,13 +374,13 @@ var ve = () => {
340
374
  className: "text-xs text-primary hover:underline disabled:opacity-50",
341
375
  disabled: !x,
342
376
  "aria-disabled": !x,
343
- onClick: () => Ie(e.id),
377
+ onClick: () => He(e.id),
344
378
  children: b("devportal.publish", "Publish")
345
379
  }), e.status?.toUpperCase() === "PUBLISHED" && !e.isLatest && /* @__PURE__ */ v("button", {
346
380
  className: "text-xs text-status-warning-text hover:underline disabled:opacity-50",
347
381
  disabled: !S,
348
382
  "aria-disabled": !S,
349
- onClick: () => Le(e.id),
383
+ onClick: () => Ue(e.id),
350
384
  children: b("devportal.deprecate", "Deprecate")
351
385
  })]
352
386
  })
@@ -357,33 +391,33 @@ var ve = () => {
357
391
  title: b("devportal.noVersionsYet", "No versions yet"),
358
392
  description: b("devportal.noVersionsYetDescription", "Create your first version to start distributing your app"),
359
393
  action: /* @__PURE__ */ y("button", {
360
- onClick: () => j(!0),
394
+ onClick: () => M(!0),
361
395
  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",
362
396
  children: [/* @__PURE__ */ v(ge, { size: 16 }), b("devportal.createVersion", "Create Version")]
363
397
  })
364
398
  }),
365
- A && /* @__PURE__ */ v(o, {
366
- open: A,
367
- onOpenChange: j,
368
- onConfirm: Ne,
399
+ j && /* @__PURE__ */ v(o, {
400
+ open: j,
401
+ onOpenChange: M,
402
+ onConfirm: ze,
369
403
  title: b("devportal.createNewVersion", "Create New Version"),
370
404
  size: "lg",
371
- confirmLabel: Ae ? b("devportal.creating", "Creating...") : b("devportal.createVersion", "Create Version"),
405
+ confirmLabel: Ie ? b("devportal.creating", "Creating...") : b("devportal.createVersion", "Create Version"),
372
406
  children: /* @__PURE__ */ y("div", {
373
407
  className: "space-y-4",
374
408
  children: [
375
409
  /* @__PURE__ */ v(ae, {
376
410
  label: b("devportal.versionNumber", "Version Number"),
377
- value: M.version,
378
- onChange: (e) => N({
379
- ...M,
411
+ value: N.version,
412
+ onChange: (e) => P({
413
+ ...N,
380
414
  version: e.target.value
381
415
  }),
382
416
  placeholder: "e.g., 2.2.0",
383
417
  hint: b("devportal.versionHint", "Use semantic versioning (major.minor.patch)"),
384
418
  required: !0
385
419
  }),
386
- Ee ? /* @__PURE__ */ y("div", {
420
+ Me ? /* @__PURE__ */ y("div", {
387
421
  className: "space-y-3",
388
422
  children: [
389
423
  /* @__PURE__ */ v("div", {
@@ -404,41 +438,41 @@ var ve = () => {
404
438
  className: "flex gap-2 items-center",
405
439
  children: [
406
440
  /* @__PURE__ */ v("input", {
407
- ref: O,
441
+ ref: k,
408
442
  type: "file",
409
443
  accept: ".zip",
410
444
  className: "hidden",
411
- onChange: Pe
445
+ onChange: Be
412
446
  }),
413
447
  /* @__PURE__ */ v("button", {
414
448
  type: "button",
415
- disabled: T,
416
- onClick: () => O.current?.click(),
449
+ disabled: E,
450
+ onClick: () => k.current?.click(),
417
451
  className: "inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors disabled:opacity-50",
418
- children: T ? /* @__PURE__ */ y(_, { children: [
452
+ children: E ? /* @__PURE__ */ y(_, { children: [
419
453
  /* @__PURE__ */ v(h, {
420
454
  size: 14,
421
455
  className: "animate-spin"
422
456
  }),
423
457
  " ",
424
458
  "Uploading… ",
425
- E,
459
+ D,
426
460
  "%"
427
461
  ] }) : /* @__PURE__ */ y(_, { children: [
428
462
  /* @__PURE__ */ v(g, { size: 14 }),
429
463
  " ",
430
- M.packageUrl ? "Replace zip" : "Upload zip"
464
+ N.packageUrl ? "Replace zip" : "Upload zip"
431
465
  ] })
432
466
  }),
433
- M.packageUrl && !T && /* @__PURE__ */ v("span", {
467
+ N.packageUrl && !E && /* @__PURE__ */ v("span", {
434
468
  className: "text-xs text-status-success-text",
435
469
  children: "✓ Uploaded"
436
470
  })
437
471
  ]
438
472
  }),
439
- D && /* @__PURE__ */ v("p", {
473
+ O && /* @__PURE__ */ v("p", {
440
474
  className: "text-xs text-destructive",
441
- children: D
475
+ children: O
442
476
  })
443
477
  ]
444
478
  }),
@@ -453,27 +487,27 @@ var ve = () => {
453
487
  })]
454
488
  }),
455
489
  /* @__PURE__ */ v("input", {
456
- ref: k,
490
+ ref: A,
457
491
  type: "file",
458
492
  accept: ".json,application/json",
459
493
  className: "hidden",
460
- onChange: Fe
494
+ onChange: Ve
461
495
  }),
462
496
  /* @__PURE__ */ y("div", {
463
497
  className: "flex gap-2 items-center",
464
498
  children: [/* @__PURE__ */ y("button", {
465
499
  type: "button",
466
- onClick: () => k.current?.click(),
500
+ onClick: () => A.current?.click(),
467
501
  className: "inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors",
468
- children: [/* @__PURE__ */ v(m, { size: 14 }), P ? "Replace manifest.json" : "Upload manifest.json"]
469
- }), P && /* @__PURE__ */ y("span", {
502
+ children: [/* @__PURE__ */ v(me, { size: 14 }), F ? "Replace manifest.json" : "Upload manifest.json"]
503
+ }), F && /* @__PURE__ */ y("span", {
470
504
  className: "text-xs text-status-success-text",
471
- children: ["✓ ", P]
505
+ children: ["✓ ", F]
472
506
  })]
473
507
  }),
474
- P && M.manifestJson && (() => {
508
+ F && N.manifestJson && (() => {
475
509
  try {
476
- let e = JSON.parse(M.manifestJson), t = typeof e.name == "string" ? e.name : null, n = typeof e.version == "string" ? e.version : null, r = typeof e.itemType == "string" ? e.itemType : null;
510
+ let e = JSON.parse(N.manifestJson), t = typeof e.name == "string" ? e.name : null, n = typeof e.version == "string" ? e.version : null, r = typeof e.itemType == "string" ? e.itemType : null;
477
511
  return /* @__PURE__ */ y("div", {
478
512
  className: "rounded-md border bg-muted/40 px-3 py-2 text-xs font-mono space-y-0.5",
479
513
  children: [
@@ -513,66 +547,66 @@ var ve = () => {
513
547
  className: "flex gap-1 rounded-md border p-0.5 w-fit",
514
548
  children: [/* @__PURE__ */ y("button", {
515
549
  type: "button",
516
- onClick: () => L("file"),
517
- className: `inline-flex items-center gap-1.5 rounded px-3 py-1 text-xs font-medium transition-colors ${I === "file" ? "bg-primary text-primary-foreground" : "hover:bg-muted"}`,
550
+ onClick: () => R("file"),
551
+ className: `inline-flex items-center gap-1.5 rounded px-3 py-1 text-xs font-medium transition-colors ${L === "file" ? "bg-primary text-primary-foreground" : "hover:bg-muted"}`,
518
552
  children: [/* @__PURE__ */ v(g, { size: 12 }), " Upload zip"]
519
553
  }), /* @__PURE__ */ y("button", {
520
554
  type: "button",
521
- onClick: () => L("manifest"),
522
- className: `inline-flex items-center gap-1.5 rounded px-3 py-1 text-xs font-medium transition-colors ${I === "manifest" ? "bg-primary text-primary-foreground" : "hover:bg-muted"}`,
523
- children: [/* @__PURE__ */ v(m, { size: 12 }), " Paste manifest JSON"]
555
+ onClick: () => R("manifest"),
556
+ className: `inline-flex items-center gap-1.5 rounded px-3 py-1 text-xs font-medium transition-colors ${L === "manifest" ? "bg-primary text-primary-foreground" : "hover:bg-muted"}`,
557
+ children: [/* @__PURE__ */ v(me, { size: 12 }), " Paste manifest JSON"]
524
558
  })]
525
559
  }),
526
- I === "file" && /* @__PURE__ */ y("div", {
560
+ L === "file" && /* @__PURE__ */ y("div", {
527
561
  className: "space-y-1",
528
562
  children: [/* @__PURE__ */ y("div", {
529
563
  className: "flex gap-2 items-center",
530
564
  children: [
531
565
  /* @__PURE__ */ v("input", {
532
- ref: O,
566
+ ref: k,
533
567
  type: "file",
534
568
  accept: ".zip",
535
569
  className: "hidden",
536
- onChange: Pe
570
+ onChange: Be
537
571
  }),
538
572
  /* @__PURE__ */ v("button", {
539
573
  type: "button",
540
- disabled: T,
541
- onClick: () => O.current?.click(),
574
+ disabled: E,
575
+ onClick: () => k.current?.click(),
542
576
  className: "inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors disabled:opacity-50",
543
- children: T ? /* @__PURE__ */ y(_, { children: [
577
+ children: E ? /* @__PURE__ */ y(_, { children: [
544
578
  /* @__PURE__ */ v(h, {
545
579
  size: 14,
546
580
  className: "animate-spin"
547
581
  }),
548
582
  " ",
549
583
  "Uploading… ",
550
- E,
584
+ D,
551
585
  "%"
552
586
  ] }) : /* @__PURE__ */ y(_, { children: [
553
587
  /* @__PURE__ */ v(g, { size: 14 }),
554
588
  " ",
555
- M.packageUrl ? "Replace zip" : "Upload zip"
589
+ N.packageUrl ? "Replace zip" : "Upload zip"
556
590
  ] })
557
591
  }),
558
- M.packageUrl && !T && /* @__PURE__ */ v("span", {
592
+ N.packageUrl && !E && /* @__PURE__ */ v("span", {
559
593
  className: "text-xs text-status-success-text",
560
594
  children: "✓ Uploaded"
561
595
  })
562
596
  ]
563
- }), D && /* @__PURE__ */ v("p", {
597
+ }), O && /* @__PURE__ */ v("p", {
564
598
  className: "text-xs text-destructive",
565
- children: D
599
+ children: O
566
600
  })]
567
601
  }),
568
- I === "manifest" && /* @__PURE__ */ y("div", {
602
+ L === "manifest" && /* @__PURE__ */ y("div", {
569
603
  className: "space-y-1",
570
604
  children: [/* @__PURE__ */ v("textarea", {
571
605
  rows: 6,
572
606
  placeholder: "{\n \"name\": \"my-workflow\",\n \"version\": \"1.0.0\",\n \"steps\": []\n}",
573
- value: M.manifestJson,
574
- onChange: (e) => N({
575
- ...M,
607
+ value: N.manifestJson,
608
+ onChange: (e) => P({
609
+ ...N,
576
610
  manifestJson: e.target.value
577
611
  }),
578
612
  className: "w-full rounded-md border bg-transparent px-3 py-2 text-xs font-mono resize-y placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring"
@@ -585,9 +619,9 @@ var ve = () => {
585
619
  }),
586
620
  /* @__PURE__ */ v(oe, {
587
621
  label: b("devportal.releaseNotes", "Release Notes"),
588
- value: M.releaseNotes,
589
- onChange: (e) => N({
590
- ...M,
622
+ value: N.releaseNotes,
623
+ onChange: (e) => P({
624
+ ...N,
591
625
  releaseNotes: e.target.value
592
626
  }),
593
627
  placeholder: b("devportal.releaseNotesPlaceholder", "What changed in this release?"),
@@ -597,35 +631,35 @@ var ve = () => {
597
631
  })
598
632
  }),
599
633
  /* @__PURE__ */ v(o, {
600
- open: Te === "publish",
634
+ open: je === "publish",
601
635
  onOpenChange: (e) => {
602
636
  e || U(null);
603
637
  },
604
638
  onConfirm: async () => {
605
- if (J.length === 0) return;
639
+ if (Y.length === 0) return;
606
640
  z(null);
607
- let e = await Promise.allSettled(J.map((e) => je({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
641
+ let e = await Promise.allSettled(Y.map((e) => Le({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
608
642
  B(`Published ${t} version${t === 1 ? "" : "s"}${n > 0 ? ` • ${n} failed` : ""}`), $(), U(null);
609
643
  },
610
644
  title: b("devportal.publishSelectedVersions", "Publish selected versions"),
611
- description: `${b("devportal.publish", "Publish")} ${J.length} selected version${J.length === 1 ? "" : "s"}?`,
645
+ description: `${b("devportal.publish", "Publish")} ${Y.length} selected version${Y.length === 1 ? "" : "s"}?`,
612
646
  confirmLabel: b("devportal.publish", "Publish"),
613
647
  cancelLabel: b("devportal.cancel", "Cancel"),
614
648
  variant: "success"
615
649
  }),
616
650
  /* @__PURE__ */ v(o, {
617
- open: Te === "deprecate",
651
+ open: je === "deprecate",
618
652
  onOpenChange: (e) => {
619
653
  e || U(null);
620
654
  },
621
655
  onConfirm: async () => {
622
- if (Y.length === 0) return;
656
+ if (X.length === 0) return;
623
657
  z(null);
624
- let e = await Promise.allSettled(Y.map((e) => Me({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
658
+ let e = await Promise.allSettled(X.map((e) => K({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
625
659
  B(`Deprecated ${t} version${t === 1 ? "" : "s"}${n > 0 ? ` • ${n} failed` : ""}`), $(), U(null);
626
660
  },
627
661
  title: b("devportal.deprecateSelectedVersions", "Deprecate selected versions"),
628
- description: `${b("devportal.deprecate", "Deprecate")} ${Y.length} selected version${Y.length === 1 ? "" : "s"}? ${b("devportal.deprecateVersionsWarning", "Deprecated versions remain visible but should no longer be promoted.")}`,
662
+ description: `${b("devportal.deprecate", "Deprecate")} ${X.length} selected version${X.length === 1 ? "" : "s"}? ${b("devportal.deprecateVersionsWarning", "Deprecated versions remain visible but should no longer be promoted.")}`,
629
663
  confirmLabel: b("devportal.deprecate", "Deprecate"),
630
664
  cancelLabel: b("devportal.cancel", "Cancel"),
631
665
  variant: "warning"
@@ -635,6 +669,6 @@ var ve = () => {
635
669
  });
636
670
  };
637
671
  //#endregion
638
- export { ve as ApplicationVersionsPage };
672
+ export { xe as ApplicationVersionsPage };
639
673
 
640
674
  //# sourceMappingURL=ApplicationVersionsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ApplicationVersionsPage.js","names":[],"sources":["../../../src/devportal/pages/ApplicationVersionsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport {\n Plus,\n Package,\n CheckCircle,\n Clock,\n Archive,\n Loader2,\n AlertCircle,\n Upload,\n FileJson,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { InputField, TextareaField } from \"../components/FormField\";\nimport { ConfirmDialog } from \"../components/ConfirmDialog\";\nimport { SelectionCheckbox } from \"../components/SelectionCheckbox\";\nimport { format } from \"date-fns\";\nimport {\n useGetApplicationQuery,\n useGetApplicationVersionsQuery,\n useCreateApplicationVersionMutation,\n usePublishApplicationVersionMutation,\n useDeprecateApplicationVersionMutation,\n type ApplicationVersionFieldsFragment,\n} from \"../hooks\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { usePackageUpload } from \"../hooks/usePackageUpload\";\n\nexport const ApplicationVersionsPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { allowed: canCreate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_CREATE,\n );\n const { allowed: canPublish } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_PUBLISH,\n );\n const { allowed: canDeprecate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_DEPRECATE,\n );\n const { appId } = useParams<{ appId: string }>();\n const { workspacesGatewayUrl, authToken, workspaceId, getWorkspaceToken } =\n useDevportal();\n const {\n upload: uploadZip,\n uploading: zipUploading,\n progress: zipProgress,\n error: zipUploadError,\n } = usePackageUpload(\n workspacesGatewayUrl,\n authToken,\n workspaceId,\n getWorkspaceToken,\n );\n const zipInputRef = useRef<HTMLInputElement>(null);\n const manifestJsonRef = useRef<HTMLInputElement>(null);\n const [showCreateDialog, setShowCreateDialog] = useState(false);\n const [newVersion, setNewVersion] = useState({\n version: \"\",\n releaseNotes: \"\",\n changelog: \"\",\n packageUrl: \"\",\n packageSize: \"\",\n manifestJson: \"\",\n });\n const [manifestFileName, setManifestFileName] = useState<string | null>(null);\n const [uploadMode, setUploadMode] = useState<\"file\" | \"manifest\">(\"file\");\n const [actionError, setActionError] = useState<string | null>(null);\n const [actionSuccess, setActionSuccess] = useState<string | null>(null);\n const [selectedVersionIds, setSelectedVersionIds] = useState<Set<string>>(\n new Set(),\n );\n const [bulkAction, setBulkAction] = useState<\"publish\" | \"deprecate\" | null>(\n null,\n );\n\n const { data: appData } = useGetApplicationQuery({\n variables: { id: appId ?? \"\" },\n skip: !appId,\n fetchPolicy: \"cache-first\",\n });\n\n const isPackageType =\n appData?.application?.appType === \"NODE\" ||\n appData?.application?.appType === \"WORKFLOW\";\n useEffect(() => {\n const name = appData?.application?.name;\n if (!appId || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(appId, name);\n return () => reg?.unregister(appId);\n }, [appId, appData?.application?.name]);\n\n // Query\n const {\n data: versionsData,\n loading: versionsLoading,\n error: versionsError,\n } = useGetApplicationVersionsQuery({\n variables: { applicationId: appId! },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n // Mutations\n const [createVersion, { loading: creating }] =\n useCreateApplicationVersionMutation({\n refetchQueries: [\"GetApplicationVersions\"],\n });\n\n const [publishVersion] = usePublishApplicationVersionMutation({\n refetchQueries: [\"GetApplicationVersions\"],\n });\n\n const [deprecateVersion] = useDeprecateApplicationVersionMutation({\n refetchQueries: [\"GetApplicationVersions\"],\n });\n\n const versions: ApplicationVersionFieldsFragment[] = useMemo(\n () =>\n versionsData?.application?.versions?.edges?.map(\n (edge: { node: ApplicationVersionFieldsFragment }) => edge.node,\n ) ?? [],\n [versionsData?.application?.versions],\n );\n\n const selectedVersions = useMemo(\n () => versions.filter((version) => selectedVersionIds.has(version.id)),\n [versions, selectedVersionIds],\n );\n const publishableVersions = useMemo(\n () =>\n selectedVersions.filter(\n (version) => version.status?.toUpperCase() === \"DRAFT\",\n ),\n [selectedVersions],\n );\n const deprecatableVersions = useMemo(\n () =>\n selectedVersions.filter(\n (version) =>\n version.status?.toUpperCase() === \"PUBLISHED\" && !version.isLatest,\n ),\n [selectedVersions],\n );\n const allVisibleSelected =\n versions.length > 0 &&\n versions.every((version) => selectedVersionIds.has(version.id));\n const partiallySelected =\n versions.some((version) => selectedVersionIds.has(version.id)) &&\n !allVisibleSelected;\n\n const handleCreate = async () => {\n if (!appId || !newVersion.version.trim()) return;\n setActionError(null);\n\n if (isPackageType) {\n if (!newVersion.packageUrl) {\n setActionError(\"A ZIP package is required for this app type.\");\n return;\n }\n if (!newVersion.manifestJson.trim()) {\n setActionError(\"A manifest JSON is required for this app type.\");\n return;\n }\n }\n\n let parsedManifest: Record<string, unknown> | undefined;\n if (newVersion.manifestJson.trim()) {\n try {\n parsedManifest = JSON.parse(newVersion.manifestJson) as Record<\n string,\n unknown\n >;\n } catch {\n setActionError(\"Invalid JSON in manifest — please check your input.\");\n return;\n }\n }\n\n try {\n await createVersion({\n variables: {\n applicationId: appId,\n input: {\n version: newVersion.version,\n releaseNotes: newVersion.releaseNotes || undefined,\n changelog: newVersion.changelog || undefined,\n packageUrl: newVersion.packageUrl || undefined,\n packageSize: newVersion.packageSize || undefined,\n manifest: parsedManifest,\n },\n },\n });\n setShowCreateDialog(false);\n setNewVersion({\n version: \"\",\n releaseNotes: \"\",\n changelog: \"\",\n packageUrl: \"\",\n packageSize: \"\",\n manifestJson: \"\",\n });\n setManifestFileName(null);\n setUploadMode(\"file\");\n setActionSuccess(\n tr(\"devportal.versionCreatedSuccess\", \"Version created successfully\"),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.versionCreateFailed\", \"Failed to create version\"),\n );\n }\n };\n\n const handleZipUpload = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n e.target.value = \"\";\n try {\n const result = await uploadZip(file);\n setNewVersion((prev) => ({\n ...prev,\n packageUrl: result.downloadUrl,\n packageSize: String(file.size),\n }));\n } catch {\n // error shown via zipUploadError prop\n }\n },\n [uploadZip],\n );\n\n const handleManifestJsonUpload = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n e.target.value = \"\";\n const reader = new FileReader();\n reader.onload = (ev) => {\n const text = ev.target?.result;\n if (typeof text !== \"string\") return;\n setManifestFileName(file.name);\n setNewVersion((prev) => ({ ...prev, manifestJson: text }));\n };\n reader.readAsText(file);\n },\n [],\n );\n\n const handlePublish = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await publishVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionPublishedSuccess\",\n \"Version published successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.versionPublishFailed\", \"Failed to publish version\"),\n );\n }\n };\n\n const handleDeprecate = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await deprecateVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionDeprecatedSuccess\",\n \"Version deprecated successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.versionDeprecateFailed\",\n \"Failed to deprecate version\",\n ),\n );\n }\n };\n\n const getStatusIcon = (version: ApplicationVersionFieldsFragment) => {\n const statusUp = version.status?.toUpperCase();\n if (statusUp === \"PUBLISHED\" && version.isLatest) {\n return <CheckCircle size={16} className=\"text-status-success-text\" />;\n }\n if (statusUp === \"DRAFT\") {\n return <Clock size={16} className=\"text-status-warning-text\" />;\n }\n if (statusUp === \"DEPRECATED\") {\n return <Archive size={16} className=\"text-text-secondary\" />;\n }\n return <Package size={16} className=\"text-accent-blue\" />;\n };\n\n const toggleVersionSelection = (versionId: string, checked: boolean) => {\n setSelectedVersionIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(versionId);\n } else {\n next.delete(versionId);\n }\n return next;\n });\n };\n\n const toggleAllVisibleVersions = (checked: boolean) => {\n setSelectedVersionIds((prev) => {\n const next = new Set(prev);\n versions.forEach((version) => {\n if (checked) {\n next.add(version.id);\n } else {\n next.delete(version.id);\n }\n });\n return next;\n });\n };\n\n const clearSelection = () => setSelectedVersionIds(new Set());\n\n const handleBulkPublish = async () => {\n if (publishableVersions.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n publishableVersions.map((version) =>\n publishVersion({ variables: { id: version.id } }),\n ),\n );\n const succeeded = results.filter(\n (result: PromiseSettledResult<unknown>) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `Published ${succeeded} version${succeeded === 1 ? \"\" : \"s\"}${failed > 0 ? ` • ${failed} failed` : \"\"}`,\n );\n clearSelection();\n setBulkAction(null);\n };\n\n const handleBulkDeprecate = async () => {\n if (deprecatableVersions.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n deprecatableVersions.map((version) =>\n deprecateVersion({ variables: { id: version.id } }),\n ),\n );\n const succeeded = results.filter(\n (result: PromiseSettledResult<unknown>) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `Deprecated ${succeeded} version${succeeded === 1 ? \"\" : \"s\"}${failed > 0 ? ` • ${failed} failed` : \"\"}`,\n );\n clearSelection();\n setBulkAction(null);\n };\n\n // Loading state\n if (versionsLoading && !versionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <div className=\"flex items-center justify-center py-16\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (versionsError && !versionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.failedToLoadVersions\",\n \"Failed to load versions\",\n )}\n description={\n versionsError.message ||\n tr(\n \"devportal.versionsLoadError\",\n \"An error occurred while loading versions\",\n )\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.APP_READ}>\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n <button\n onClick={() => setShowCreateDialog(true)}\n disabled={!canCreate}\n aria-disabled={!canCreate}\n 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 disabled:opacity-50\"\n >\n <Plus size={16} />\n {tr(\"devportal.newVersion\", \"New Version\")}\n </button>\n }\n >\n {/* Action Error Banner */}\n {actionError && (\n <div className=\"rounded-lg border border-border-subtle bg-status-error-bg-subtle p-3 flex items-center gap-2 text-sm text-status-error-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionError}\n <button\n onClick={() => setActionError(null)}\n className=\"ml-auto text-status-error-text hover:text-status-error-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {actionSuccess && (\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-3 flex items-center gap-2 text-sm text-status-success-text\">\n <CheckCircle size={16} className=\"flex-shrink-0\" />\n {actionSuccess}\n <button\n onClick={() => setActionSuccess(null)}\n className=\"ml-auto text-status-success-text hover:text-status-success-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {versions.length > 0 && (\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVersions}\n ariaLabel=\"Select all visible versions\"\n />\n <span className=\"text-sm font-medium\">\n {tr(\"devportal.selectAllVisible\", \"Select all visible\")}\n </span>\n </div>\n {selectedVersionIds.size > 0 && (\n <button\n onClick={clearSelection}\n className=\"text-sm text-muted-foreground hover:text-foreground\"\n >\n {tr(\"devportal.clearSelection\", \"Clear selection\")}\n </button>\n )}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-muted px-3 py-1 text-sm font-medium text-muted-foreground\">\n {selectedVersionIds.size} selected\n </span>\n <button\n onClick={() => setBulkAction(\"publish\")}\n disabled={publishableVersions.length === 0 || !canPublish}\n aria-disabled={!canPublish}\n className=\"rounded-md border border-status-success-bg px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.publishSelected\", \"Publish Selected\")}\n {publishableVersions.length > 0\n ? ` (${publishableVersions.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setBulkAction(\"deprecate\")}\n disabled={deprecatableVersions.length === 0 || !canDeprecate}\n aria-disabled={!canDeprecate}\n className=\"rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.deprecateSelected\", \"Deprecate Selected\")}\n {deprecatableVersions.length > 0\n ? ` (${deprecatableVersions.length})`\n : \"\"}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {versions.length > 0 ? (\n <DataTable\n data={versions}\n keyField=\"id\"\n columns={[\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVersions}\n ariaLabel=\"Select all visible versions\"\n />\n ),\n className: \"w-12\",\n render: (v) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedVersionIds.has(v.id)}\n onChange={(checked) =>\n toggleVersionSelection(v.id, checked)\n }\n ariaLabel={`Select version ${v.version}`}\n />\n </div>\n ),\n },\n {\n key: \"version\",\n header: tr(\"devportal.version\", \"Version\"),\n render: (v) => (\n <div className=\"flex items-center gap-2\">\n {getStatusIcon(v)}\n <span className=\"font-mono font-medium\">{v.version}</span>\n {v.isLatest && (\n <span className=\"rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-xs text-status-success-text\">\n {tr(\"devportal.latest\", \"Latest\")}\n </span>\n )}\n {!v.isStable && (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs text-status-warning-text\">\n {tr(\"devportal.beta\", \"Beta\")}\n </span>\n )}\n </div>\n ),\n },\n {\n key: \"releaseNotes\",\n header: tr(\"devportal.releaseNotes\", \"Release Notes\"),\n render: (v) => (\n <p className=\"max-w-md truncate text-sm text-muted-foreground\">\n {v.releaseNotes ||\n tr(\"devportal.noReleaseNotes\", \"No release notes\")}\n </p>\n ),\n },\n {\n key: \"status\",\n header: tr(\"devportal.status\", \"Status\"),\n render: (v) => <StatusBadge status={v.status} />,\n },\n {\n key: \"publishedAt\",\n header: tr(\"devportal.published\", \"Published\"),\n render: (v) =>\n v.publishedAt\n ? format(new Date(v.publishedAt), \"MMM d, yyyy\")\n : \"-\",\n },\n {\n key: \"actions\",\n header: \"\",\n className: \"w-32\",\n render: (v) => (\n <div className=\"flex gap-2\">\n {v.status?.toUpperCase() === \"DRAFT\" && (\n <button\n className=\"text-xs text-primary hover:underline disabled:opacity-50\"\n disabled={!canPublish}\n aria-disabled={!canPublish}\n onClick={() => handlePublish(v.id)}\n >\n {tr(\"devportal.publish\", \"Publish\")}\n </button>\n )}\n {v.status?.toUpperCase() === \"PUBLISHED\" && !v.isLatest && (\n <button\n className=\"text-xs text-status-warning-text hover:underline disabled:opacity-50\"\n disabled={!canDeprecate}\n aria-disabled={!canDeprecate}\n onClick={() => handleDeprecate(v.id)}\n >\n {tr(\"devportal.deprecate\", \"Deprecate\")}\n </button>\n )}\n </div>\n ),\n },\n ]}\n />\n ) : (\n <EmptyState\n icon={<Package size={32} />}\n title={tr(\"devportal.noVersionsYet\", \"No versions yet\")}\n description={tr(\n \"devportal.noVersionsYetDescription\",\n \"Create your first version to start distributing your app\",\n )}\n action={\n <button\n onClick={() => setShowCreateDialog(true)}\n 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\"\n >\n <Plus size={16} />\n {tr(\"devportal.createVersion\", \"Create Version\")}\n </button>\n }\n />\n )}\n\n {/* Create Version Dialog */}\n {showCreateDialog && (\n <ConfirmDialog\n open={showCreateDialog}\n onOpenChange={setShowCreateDialog}\n onConfirm={handleCreate}\n title={tr(\"devportal.createNewVersion\", \"Create New Version\")}\n size=\"lg\"\n confirmLabel={\n creating\n ? tr(\"devportal.creating\", \"Creating...\")\n : tr(\"devportal.createVersion\", \"Create Version\")\n }\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\"devportal.versionNumber\", \"Version Number\")}\n value={newVersion.version}\n onChange={(e) =>\n setNewVersion({ ...newVersion, version: e.target.value })\n }\n placeholder=\"e.g., 2.2.0\"\n hint={tr(\n \"devportal.versionHint\",\n \"Use semantic versioning (major.minor.patch)\",\n )}\n required\n />\n {/* Package upload */}\n {isPackageType ? (\n <div className=\"space-y-3\">\n <div className=\"rounded-md border border-status-warning-bg bg-status-warning-bg-subtle px-3 py-2 text-xs text-status-warning-text\">\n Both a ZIP package and a manifest JSON are required for this\n app type.\n </div>\n {/* ZIP upload — required */}\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n ZIP Package <span className=\"text-destructive\">*</span>\n </label>\n <div className=\"flex gap-2 items-center\">\n <input\n ref={zipInputRef}\n type=\"file\"\n accept=\".zip\"\n className=\"hidden\"\n onChange={handleZipUpload}\n />\n <button\n type=\"button\"\n disabled={zipUploading}\n onClick={() => zipInputRef.current?.click()}\n className=\"inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors disabled:opacity-50\"\n >\n {zipUploading ? (\n <>\n <Loader2 size={14} className=\"animate-spin\" />{\" \"}\n Uploading… {zipProgress}%\n </>\n ) : (\n <>\n <Upload size={14} />{\" \"}\n {newVersion.packageUrl\n ? \"Replace zip\"\n : \"Upload zip\"}\n </>\n )}\n </button>\n {newVersion.packageUrl && !zipUploading && (\n <span className=\"text-xs text-status-success-text\">\n ✓ Uploaded\n </span>\n )}\n </div>\n {zipUploadError && (\n <p className=\"text-xs text-destructive\">\n {zipUploadError}\n </p>\n )}\n </div>\n {/* Manifest JSON — upload required */}\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n Manifest JSON <span className=\"text-destructive\">*</span>\n </label>\n <input\n ref={manifestJsonRef}\n type=\"file\"\n accept=\".json,application/json\"\n className=\"hidden\"\n onChange={handleManifestJsonUpload}\n />\n <div className=\"flex gap-2 items-center\">\n <button\n type=\"button\"\n onClick={() => manifestJsonRef.current?.click()}\n className=\"inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors\"\n >\n <FileJson size={14} />\n {manifestFileName ? \"Replace manifest.json\" : \"Upload manifest.json\"}\n </button>\n {manifestFileName && (\n <span className=\"text-xs text-status-success-text\">✓ {manifestFileName}</span>\n )}\n </div>\n {manifestFileName && newVersion.manifestJson && (() => {\n try {\n const parsed = JSON.parse(newVersion.manifestJson) as Record<string, unknown>;\n const name = typeof parsed.name === \"string\" ? parsed.name : null;\n const version = typeof parsed.version === \"string\" ? parsed.version : null;\n const itemType = typeof parsed.itemType === \"string\" ? parsed.itemType : null;\n return (\n <div className=\"rounded-md border bg-muted/40 px-3 py-2 text-xs font-mono space-y-0.5\">\n {name && <div><span className=\"text-muted-foreground\">name: </span>{name}</div>}\n {version && <div><span className=\"text-muted-foreground\">version: </span>{version}</div>}\n {itemType && <div><span className=\"text-muted-foreground\">itemType: </span>{itemType}</div>}\n </div>\n );\n } catch { return null; }\n })()}\n <p className=\"text-xs text-muted-foreground\">\n Upload your manifest.json — defines the node&apos;s inputs, outputs, and configuration schema.\n </p>\n </div>\n </div>\n ) : (\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">Package</label>\n <div className=\"flex gap-1 rounded-md border p-0.5 w-fit\">\n <button\n type=\"button\"\n onClick={() => setUploadMode(\"file\")}\n className={`inline-flex items-center gap-1.5 rounded px-3 py-1 text-xs font-medium transition-colors ${uploadMode === \"file\" ? \"bg-primary text-primary-foreground\" : \"hover:bg-muted\"}`}\n >\n <Upload size={12} /> Upload zip\n </button>\n <button\n type=\"button\"\n onClick={() => setUploadMode(\"manifest\")}\n className={`inline-flex items-center gap-1.5 rounded px-3 py-1 text-xs font-medium transition-colors ${uploadMode === \"manifest\" ? \"bg-primary text-primary-foreground\" : \"hover:bg-muted\"}`}\n >\n <FileJson size={12} /> Paste manifest JSON\n </button>\n </div>\n\n {uploadMode === \"file\" && (\n <div className=\"space-y-1\">\n <div className=\"flex gap-2 items-center\">\n <input\n ref={zipInputRef}\n type=\"file\"\n accept=\".zip\"\n className=\"hidden\"\n onChange={handleZipUpload}\n />\n <button\n type=\"button\"\n disabled={zipUploading}\n onClick={() => zipInputRef.current?.click()}\n className=\"inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors disabled:opacity-50\"\n >\n {zipUploading ? (\n <>\n <Loader2 size={14} className=\"animate-spin\" />{\" \"}\n Uploading… {zipProgress}%\n </>\n ) : (\n <>\n <Upload size={14} />{\" \"}\n {newVersion.packageUrl\n ? \"Replace zip\"\n : \"Upload zip\"}\n </>\n )}\n </button>\n {newVersion.packageUrl && !zipUploading && (\n <span className=\"text-xs text-status-success-text\">\n ✓ Uploaded\n </span>\n )}\n </div>\n {zipUploadError && (\n <p className=\"text-xs text-destructive\">\n {zipUploadError}\n </p>\n )}\n </div>\n )}\n\n {uploadMode === \"manifest\" && (\n <div className=\"space-y-1\">\n <textarea\n rows={6}\n placeholder={`{\\n \"name\": \"my-workflow\",\\n \"version\": \"1.0.0\",\\n \"steps\": []\\n}`}\n value={newVersion.manifestJson}\n onChange={(e) =>\n setNewVersion({\n ...newVersion,\n manifestJson: e.target.value,\n })\n }\n className=\"w-full rounded-md border bg-transparent px-3 py-2 text-xs font-mono resize-y placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n <p className=\"text-xs text-muted-foreground\">\n Paste your workflow or configuration JSON here. No zip\n required.\n </p>\n </div>\n )}\n </div>\n )}\n <TextareaField\n label={tr(\"devportal.releaseNotes\", \"Release Notes\")}\n value={newVersion.releaseNotes}\n onChange={(e) =>\n setNewVersion({ ...newVersion, releaseNotes: e.target.value })\n }\n placeholder={tr(\n \"devportal.releaseNotesPlaceholder\",\n \"What changed in this release?\",\n )}\n rows={2}\n />\n </div>\n </ConfirmDialog>\n )}\n\n <ConfirmDialog\n open={bulkAction === \"publish\"}\n onOpenChange={(open) => {\n if (!open) setBulkAction(null);\n }}\n onConfirm={handleBulkPublish}\n title={tr(\n \"devportal.publishSelectedVersions\",\n \"Publish selected versions\",\n )}\n description={`${tr(\"devportal.publish\", \"Publish\")} ${publishableVersions.length} selected version${publishableVersions.length === 1 ? \"\" : \"s\"}?`}\n confirmLabel={tr(\"devportal.publish\", \"Publish\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"success\"\n />\n\n <ConfirmDialog\n open={bulkAction === \"deprecate\"}\n onOpenChange={(open) => {\n if (!open) setBulkAction(null);\n }}\n onConfirm={handleBulkDeprecate}\n title={tr(\n \"devportal.deprecateSelectedVersions\",\n \"Deprecate selected versions\",\n )}\n description={`${tr(\"devportal.deprecate\", \"Deprecate\")} ${deprecatableVersions.length} selected version${deprecatableVersions.length === 1 ? \"\" : \"s\"}? ${tr(\"devportal.deprecateVersionsWarning\", \"Deprecated versions remain visible but should no longer be promoted.\")}`}\n confirmLabel={tr(\"devportal.deprecate\", \"Deprecate\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"warning\"\n />\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ApplicationVersionsPage.js","names":[],"sources":["../../../src/devportal/pages/ApplicationVersionsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { gql } from \"@apollo/client\";\nimport { useMutation, useQuery } from \"@apollo/client/react\";\nimport { useParams } from \"react-router-dom\";\nimport {\n Plus,\n Package,\n CheckCircle,\n Clock,\n Archive,\n Loader2,\n AlertCircle,\n Upload,\n FileJson,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { InputField, TextareaField } from \"../components/FormField\";\nimport { ConfirmDialog } from \"../components/ConfirmDialog\";\nimport { SelectionCheckbox } from \"../components/SelectionCheckbox\";\nimport { format } from \"date-fns\";\nimport {\n useGetApplicationQuery,\n useGetApplicationVersionsQuery,\n useCreateApplicationVersionMutation,\n usePublishApplicationVersionMutation,\n useDeprecateApplicationVersionMutation,\n type ApplicationVersionFieldsFragment,\n} from \"../hooks\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { usePackageUpload } from \"../hooks/usePackageUpload\";\n\nexport const ApplicationVersionsPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { allowed: canCreate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_CREATE,\n );\n const { allowed: canPublish } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_PUBLISH,\n );\n const { allowed: canDeprecate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_DEPRECATE,\n );\n const { appId } = useParams<{ appId: string }>();\n const { workspacesGatewayUrl, authToken, workspaceId, getWorkspaceToken } =\n useDevportal();\n\n const { data: publisherData } = useQuery<{\n myPublisher: { id: string; products: { id: string; productId: string }[] } | null;\n }>(gql`query MyPublisherProductsVersions { myPublisher { id products { id productId } } }`, {\n fetchPolicy: \"cache-first\",\n });\n const linkedStoreProductId = publisherData?.myPublisher?.products.find(\n (p) => p.productId === appId,\n )?.id ?? null;\n const [updateStoreProduct] = useMutation(gql`\n mutation UpdateStoreProductVersion($input: UpdateProductInput!) {\n updateProduct(input: $input) { id manifestVersion }\n }\n `);\n const {\n upload: uploadZip,\n uploading: zipUploading,\n progress: zipProgress,\n error: zipUploadError,\n } = usePackageUpload(\n workspacesGatewayUrl,\n authToken,\n workspaceId,\n getWorkspaceToken,\n );\n const zipInputRef = useRef<HTMLInputElement>(null);\n const manifestJsonRef = useRef<HTMLInputElement>(null);\n const [showCreateDialog, setShowCreateDialog] = useState(false);\n const [newVersion, setNewVersion] = useState({\n version: \"\",\n releaseNotes: \"\",\n changelog: \"\",\n packageUrl: \"\",\n packageSize: \"\",\n manifestJson: \"\",\n });\n const [manifestFileName, setManifestFileName] = useState<string | null>(null);\n const [uploadMode, setUploadMode] = useState<\"file\" | \"manifest\">(\"file\");\n const [actionError, setActionError] = useState<string | null>(null);\n const [actionSuccess, setActionSuccess] = useState<string | null>(null);\n const [selectedVersionIds, setSelectedVersionIds] = useState<Set<string>>(\n new Set(),\n );\n const [bulkAction, setBulkAction] = useState<\"publish\" | \"deprecate\" | null>(\n null,\n );\n\n const { data: appData } = useGetApplicationQuery({\n variables: { id: appId ?? \"\" },\n skip: !appId,\n fetchPolicy: \"cache-first\",\n });\n\n const isPackageType =\n appData?.application?.appType === \"NODE\" ||\n appData?.application?.appType === \"WORKFLOW\";\n useEffect(() => {\n const name = appData?.application?.name;\n if (!appId || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(appId, name);\n return () => reg?.unregister(appId);\n }, [appId, appData?.application?.name]);\n\n // Query\n const {\n data: versionsData,\n loading: versionsLoading,\n error: versionsError,\n } = useGetApplicationVersionsQuery({\n variables: { applicationId: appId! },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n // Mutations\n const [createVersion, { loading: creating }] =\n useCreateApplicationVersionMutation({\n refetchQueries: [\"GetApplicationVersions\"],\n });\n\n const [publishVersion] = usePublishApplicationVersionMutation({\n refetchQueries: [\"GetApplicationVersions\"],\n });\n\n const [deprecateVersion] = useDeprecateApplicationVersionMutation({\n refetchQueries: [\"GetApplicationVersions\"],\n });\n\n const versions: ApplicationVersionFieldsFragment[] = useMemo(\n () =>\n versionsData?.application?.versions?.edges?.map(\n (edge: { node: ApplicationVersionFieldsFragment }) => edge.node,\n ) ?? [],\n [versionsData?.application?.versions],\n );\n\n const selectedVersions = useMemo(\n () => versions.filter((version) => selectedVersionIds.has(version.id)),\n [versions, selectedVersionIds],\n );\n const publishableVersions = useMemo(\n () =>\n selectedVersions.filter(\n (version) => version.status?.toUpperCase() === \"DRAFT\",\n ),\n [selectedVersions],\n );\n const deprecatableVersions = useMemo(\n () =>\n selectedVersions.filter(\n (version) =>\n version.status?.toUpperCase() === \"PUBLISHED\" && !version.isLatest,\n ),\n [selectedVersions],\n );\n const allVisibleSelected =\n versions.length > 0 &&\n versions.every((version) => selectedVersionIds.has(version.id));\n const partiallySelected =\n versions.some((version) => selectedVersionIds.has(version.id)) &&\n !allVisibleSelected;\n\n const handleCreate = async () => {\n if (!appId || !newVersion.version.trim()) return;\n setActionError(null);\n\n if (isPackageType) {\n if (!newVersion.packageUrl) {\n setActionError(\"A ZIP package is required for this app type.\");\n return;\n }\n if (!newVersion.manifestJson.trim()) {\n setActionError(\"A manifest JSON is required for this app type.\");\n return;\n }\n }\n\n let parsedManifest: Record<string, unknown> | undefined;\n if (newVersion.manifestJson.trim()) {\n try {\n parsedManifest = JSON.parse(newVersion.manifestJson) as Record<\n string,\n unknown\n >;\n } catch {\n setActionError(\"Invalid JSON in manifest — please check your input.\");\n return;\n }\n }\n\n try {\n await createVersion({\n variables: {\n applicationId: appId,\n input: {\n version: newVersion.version,\n releaseNotes: newVersion.releaseNotes || undefined,\n changelog: newVersion.changelog || undefined,\n packageUrl: newVersion.packageUrl || undefined,\n packageSize: newVersion.packageSize || undefined,\n manifest: parsedManifest,\n },\n },\n });\n setShowCreateDialog(false);\n setNewVersion({\n version: \"\",\n releaseNotes: \"\",\n changelog: \"\",\n packageUrl: \"\",\n packageSize: \"\",\n manifestJson: \"\",\n });\n setManifestFileName(null);\n setUploadMode(\"file\");\n setActionSuccess(\n tr(\"devportal.versionCreatedSuccess\", \"Version created successfully\"),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.versionCreateFailed\", \"Failed to create version\"),\n );\n }\n };\n\n const handleZipUpload = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n e.target.value = \"\";\n try {\n const result = await uploadZip(file);\n setNewVersion((prev) => ({\n ...prev,\n packageUrl: result.downloadUrl,\n packageSize: String(file.size),\n }));\n } catch {\n // error shown via zipUploadError prop\n }\n },\n [uploadZip],\n );\n\n const handleManifestJsonUpload = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n e.target.value = \"\";\n const reader = new FileReader();\n reader.onload = (ev) => {\n const text = ev.target?.result;\n if (typeof text !== \"string\") return;\n setManifestFileName(file.name);\n setNewVersion((prev) => ({ ...prev, manifestJson: text }));\n };\n reader.readAsText(file);\n },\n [],\n );\n\n const handlePublish = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await publishVersion({ variables: { id: versionId } });\n\n // Sync version info to linked StoreProduct if one exists\n if (linkedStoreProductId) {\n const ver = versions.find((v) => v.id === versionId);\n if (ver) {\n await updateStoreProduct({\n variables: {\n input: {\n id: linkedStoreProductId,\n manifestVersion: ver.version,\n manifest: {\n manifestVersion: \"1.0\",\n name: appData?.application?.slug ?? \"\",\n version: ver.version,\n itemType: appData?.application?.appType?.toLowerCase() ?? \"node\",\n identity: {\n name: appData?.application?.slug ?? \"\",\n version: ver.version,\n displayName: appData?.application?.name ?? \"\",\n description: appData?.application?.shortDescription ?? appData?.application?.description ?? \"\",\n },\n publisher: {\n id: appData?.application?.developerId ?? \"\",\n name: \"Burdenoff\",\n },\n pricing: { currency: \"USD\", model: \"FREE\" },\n permissions: [],\n },\n },\n },\n }).catch(() => {\n // StoreProduct sync failure is non-fatal\n });\n }\n }\n\n setActionSuccess(\n tr(\n \"devportal.versionPublishedSuccess\",\n \"Version published successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.versionPublishFailed\", \"Failed to publish version\"),\n );\n }\n };\n\n const handleDeprecate = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await deprecateVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionDeprecatedSuccess\",\n \"Version deprecated successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.versionDeprecateFailed\",\n \"Failed to deprecate version\",\n ),\n );\n }\n };\n\n const getStatusIcon = (version: ApplicationVersionFieldsFragment) => {\n const statusUp = version.status?.toUpperCase();\n if (statusUp === \"PUBLISHED\" && version.isLatest) {\n return <CheckCircle size={16} className=\"text-status-success-text\" />;\n }\n if (statusUp === \"DRAFT\") {\n return <Clock size={16} className=\"text-status-warning-text\" />;\n }\n if (statusUp === \"DEPRECATED\") {\n return <Archive size={16} className=\"text-text-secondary\" />;\n }\n return <Package size={16} className=\"text-accent-blue\" />;\n };\n\n const toggleVersionSelection = (versionId: string, checked: boolean) => {\n setSelectedVersionIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(versionId);\n } else {\n next.delete(versionId);\n }\n return next;\n });\n };\n\n const toggleAllVisibleVersions = (checked: boolean) => {\n setSelectedVersionIds((prev) => {\n const next = new Set(prev);\n versions.forEach((version) => {\n if (checked) {\n next.add(version.id);\n } else {\n next.delete(version.id);\n }\n });\n return next;\n });\n };\n\n const clearSelection = () => setSelectedVersionIds(new Set());\n\n const handleBulkPublish = async () => {\n if (publishableVersions.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n publishableVersions.map((version) =>\n publishVersion({ variables: { id: version.id } }),\n ),\n );\n const succeeded = results.filter(\n (result: PromiseSettledResult<unknown>) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `Published ${succeeded} version${succeeded === 1 ? \"\" : \"s\"}${failed > 0 ? ` • ${failed} failed` : \"\"}`,\n );\n clearSelection();\n setBulkAction(null);\n };\n\n const handleBulkDeprecate = async () => {\n if (deprecatableVersions.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n deprecatableVersions.map((version) =>\n deprecateVersion({ variables: { id: version.id } }),\n ),\n );\n const succeeded = results.filter(\n (result: PromiseSettledResult<unknown>) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `Deprecated ${succeeded} version${succeeded === 1 ? \"\" : \"s\"}${failed > 0 ? ` • ${failed} failed` : \"\"}`,\n );\n clearSelection();\n setBulkAction(null);\n };\n\n // Loading state\n if (versionsLoading && !versionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <div className=\"flex items-center justify-center py-16\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (versionsError && !versionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.failedToLoadVersions\",\n \"Failed to load versions\",\n )}\n description={\n versionsError.message ||\n tr(\n \"devportal.versionsLoadError\",\n \"An error occurred while loading versions\",\n )\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.APP_READ}>\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n <button\n onClick={() => setShowCreateDialog(true)}\n disabled={!canCreate}\n aria-disabled={!canCreate}\n 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 disabled:opacity-50\"\n >\n <Plus size={16} />\n {tr(\"devportal.newVersion\", \"New Version\")}\n </button>\n }\n >\n {/* Action Error Banner */}\n {actionError && (\n <div className=\"rounded-lg border border-border-subtle bg-status-error-bg-subtle p-3 flex items-center gap-2 text-sm text-status-error-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionError}\n <button\n onClick={() => setActionError(null)}\n className=\"ml-auto text-status-error-text hover:text-status-error-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {actionSuccess && (\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-3 flex items-center gap-2 text-sm text-status-success-text\">\n <CheckCircle size={16} className=\"flex-shrink-0\" />\n {actionSuccess}\n <button\n onClick={() => setActionSuccess(null)}\n className=\"ml-auto text-status-success-text hover:text-status-success-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {versions.length > 0 && (\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVersions}\n ariaLabel=\"Select all visible versions\"\n />\n <span className=\"text-sm font-medium\">\n {tr(\"devportal.selectAllVisible\", \"Select all visible\")}\n </span>\n </div>\n {selectedVersionIds.size > 0 && (\n <button\n onClick={clearSelection}\n className=\"text-sm text-muted-foreground hover:text-foreground\"\n >\n {tr(\"devportal.clearSelection\", \"Clear selection\")}\n </button>\n )}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-muted px-3 py-1 text-sm font-medium text-muted-foreground\">\n {selectedVersionIds.size} selected\n </span>\n <button\n onClick={() => setBulkAction(\"publish\")}\n disabled={publishableVersions.length === 0 || !canPublish}\n aria-disabled={!canPublish}\n className=\"rounded-md border border-status-success-bg px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.publishSelected\", \"Publish Selected\")}\n {publishableVersions.length > 0\n ? ` (${publishableVersions.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setBulkAction(\"deprecate\")}\n disabled={deprecatableVersions.length === 0 || !canDeprecate}\n aria-disabled={!canDeprecate}\n className=\"rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.deprecateSelected\", \"Deprecate Selected\")}\n {deprecatableVersions.length > 0\n ? ` (${deprecatableVersions.length})`\n : \"\"}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {versions.length > 0 ? (\n <DataTable\n data={versions}\n keyField=\"id\"\n columns={[\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVersions}\n ariaLabel=\"Select all visible versions\"\n />\n ),\n className: \"w-12\",\n render: (v) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedVersionIds.has(v.id)}\n onChange={(checked) =>\n toggleVersionSelection(v.id, checked)\n }\n ariaLabel={`Select version ${v.version}`}\n />\n </div>\n ),\n },\n {\n key: \"version\",\n header: tr(\"devportal.version\", \"Version\"),\n render: (v) => (\n <div className=\"flex items-center gap-2\">\n {getStatusIcon(v)}\n <span className=\"font-mono font-medium\">{v.version}</span>\n {v.isLatest && (\n <span className=\"rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-xs text-status-success-text\">\n {tr(\"devportal.latest\", \"Latest\")}\n </span>\n )}\n {!v.isStable && (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs text-status-warning-text\">\n {tr(\"devportal.beta\", \"Beta\")}\n </span>\n )}\n </div>\n ),\n },\n {\n key: \"releaseNotes\",\n header: tr(\"devportal.releaseNotes\", \"Release Notes\"),\n render: (v) => (\n <p className=\"max-w-md truncate text-sm text-muted-foreground\">\n {v.releaseNotes ||\n tr(\"devportal.noReleaseNotes\", \"No release notes\")}\n </p>\n ),\n },\n {\n key: \"status\",\n header: tr(\"devportal.status\", \"Status\"),\n render: (v) => <StatusBadge status={v.status} />,\n },\n {\n key: \"publishedAt\",\n header: tr(\"devportal.published\", \"Published\"),\n render: (v) =>\n v.publishedAt\n ? format(new Date(v.publishedAt), \"MMM d, yyyy\")\n : \"-\",\n },\n {\n key: \"actions\",\n header: \"\",\n className: \"w-32\",\n render: (v) => (\n <div className=\"flex gap-2\">\n {v.status?.toUpperCase() === \"DRAFT\" && (\n <button\n className=\"text-xs text-primary hover:underline disabled:opacity-50\"\n disabled={!canPublish}\n aria-disabled={!canPublish}\n onClick={() => handlePublish(v.id)}\n >\n {tr(\"devportal.publish\", \"Publish\")}\n </button>\n )}\n {v.status?.toUpperCase() === \"PUBLISHED\" && !v.isLatest && (\n <button\n className=\"text-xs text-status-warning-text hover:underline disabled:opacity-50\"\n disabled={!canDeprecate}\n aria-disabled={!canDeprecate}\n onClick={() => handleDeprecate(v.id)}\n >\n {tr(\"devportal.deprecate\", \"Deprecate\")}\n </button>\n )}\n </div>\n ),\n },\n ]}\n />\n ) : (\n <EmptyState\n icon={<Package size={32} />}\n title={tr(\"devportal.noVersionsYet\", \"No versions yet\")}\n description={tr(\n \"devportal.noVersionsYetDescription\",\n \"Create your first version to start distributing your app\",\n )}\n action={\n <button\n onClick={() => setShowCreateDialog(true)}\n 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\"\n >\n <Plus size={16} />\n {tr(\"devportal.createVersion\", \"Create Version\")}\n </button>\n }\n />\n )}\n\n {/* Create Version Dialog */}\n {showCreateDialog && (\n <ConfirmDialog\n open={showCreateDialog}\n onOpenChange={setShowCreateDialog}\n onConfirm={handleCreate}\n title={tr(\"devportal.createNewVersion\", \"Create New Version\")}\n size=\"lg\"\n confirmLabel={\n creating\n ? tr(\"devportal.creating\", \"Creating...\")\n : tr(\"devportal.createVersion\", \"Create Version\")\n }\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\"devportal.versionNumber\", \"Version Number\")}\n value={newVersion.version}\n onChange={(e) =>\n setNewVersion({ ...newVersion, version: e.target.value })\n }\n placeholder=\"e.g., 2.2.0\"\n hint={tr(\n \"devportal.versionHint\",\n \"Use semantic versioning (major.minor.patch)\",\n )}\n required\n />\n {/* Package upload */}\n {isPackageType ? (\n <div className=\"space-y-3\">\n <div className=\"rounded-md border border-status-warning-bg bg-status-warning-bg-subtle px-3 py-2 text-xs text-status-warning-text\">\n Both a ZIP package and a manifest JSON are required for this\n app type.\n </div>\n {/* ZIP upload — required */}\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n ZIP Package <span className=\"text-destructive\">*</span>\n </label>\n <div className=\"flex gap-2 items-center\">\n <input\n ref={zipInputRef}\n type=\"file\"\n accept=\".zip\"\n className=\"hidden\"\n onChange={handleZipUpload}\n />\n <button\n type=\"button\"\n disabled={zipUploading}\n onClick={() => zipInputRef.current?.click()}\n className=\"inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors disabled:opacity-50\"\n >\n {zipUploading ? (\n <>\n <Loader2 size={14} className=\"animate-spin\" />{\" \"}\n Uploading… {zipProgress}%\n </>\n ) : (\n <>\n <Upload size={14} />{\" \"}\n {newVersion.packageUrl\n ? \"Replace zip\"\n : \"Upload zip\"}\n </>\n )}\n </button>\n {newVersion.packageUrl && !zipUploading && (\n <span className=\"text-xs text-status-success-text\">\n ✓ Uploaded\n </span>\n )}\n </div>\n {zipUploadError && (\n <p className=\"text-xs text-destructive\">\n {zipUploadError}\n </p>\n )}\n </div>\n {/* Manifest JSON — upload required */}\n <div className=\"space-y-1\">\n <label className=\"text-sm font-medium\">\n Manifest JSON <span className=\"text-destructive\">*</span>\n </label>\n <input\n ref={manifestJsonRef}\n type=\"file\"\n accept=\".json,application/json\"\n className=\"hidden\"\n onChange={handleManifestJsonUpload}\n />\n <div className=\"flex gap-2 items-center\">\n <button\n type=\"button\"\n onClick={() => manifestJsonRef.current?.click()}\n className=\"inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors\"\n >\n <FileJson size={14} />\n {manifestFileName ? \"Replace manifest.json\" : \"Upload manifest.json\"}\n </button>\n {manifestFileName && (\n <span className=\"text-xs text-status-success-text\">✓ {manifestFileName}</span>\n )}\n </div>\n {manifestFileName && newVersion.manifestJson && (() => {\n try {\n const parsed = JSON.parse(newVersion.manifestJson) as Record<string, unknown>;\n const name = typeof parsed.name === \"string\" ? parsed.name : null;\n const version = typeof parsed.version === \"string\" ? parsed.version : null;\n const itemType = typeof parsed.itemType === \"string\" ? parsed.itemType : null;\n return (\n <div className=\"rounded-md border bg-muted/40 px-3 py-2 text-xs font-mono space-y-0.5\">\n {name && <div><span className=\"text-muted-foreground\">name: </span>{name}</div>}\n {version && <div><span className=\"text-muted-foreground\">version: </span>{version}</div>}\n {itemType && <div><span className=\"text-muted-foreground\">itemType: </span>{itemType}</div>}\n </div>\n );\n } catch { return null; }\n })()}\n <p className=\"text-xs text-muted-foreground\">\n Upload your manifest.json — defines the node&apos;s inputs, outputs, and configuration schema.\n </p>\n </div>\n </div>\n ) : (\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">Package</label>\n <div className=\"flex gap-1 rounded-md border p-0.5 w-fit\">\n <button\n type=\"button\"\n onClick={() => setUploadMode(\"file\")}\n className={`inline-flex items-center gap-1.5 rounded px-3 py-1 text-xs font-medium transition-colors ${uploadMode === \"file\" ? \"bg-primary text-primary-foreground\" : \"hover:bg-muted\"}`}\n >\n <Upload size={12} /> Upload zip\n </button>\n <button\n type=\"button\"\n onClick={() => setUploadMode(\"manifest\")}\n className={`inline-flex items-center gap-1.5 rounded px-3 py-1 text-xs font-medium transition-colors ${uploadMode === \"manifest\" ? \"bg-primary text-primary-foreground\" : \"hover:bg-muted\"}`}\n >\n <FileJson size={12} /> Paste manifest JSON\n </button>\n </div>\n\n {uploadMode === \"file\" && (\n <div className=\"space-y-1\">\n <div className=\"flex gap-2 items-center\">\n <input\n ref={zipInputRef}\n type=\"file\"\n accept=\".zip\"\n className=\"hidden\"\n onChange={handleZipUpload}\n />\n <button\n type=\"button\"\n disabled={zipUploading}\n onClick={() => zipInputRef.current?.click()}\n className=\"inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-muted transition-colors disabled:opacity-50\"\n >\n {zipUploading ? (\n <>\n <Loader2 size={14} className=\"animate-spin\" />{\" \"}\n Uploading… {zipProgress}%\n </>\n ) : (\n <>\n <Upload size={14} />{\" \"}\n {newVersion.packageUrl\n ? \"Replace zip\"\n : \"Upload zip\"}\n </>\n )}\n </button>\n {newVersion.packageUrl && !zipUploading && (\n <span className=\"text-xs text-status-success-text\">\n ✓ Uploaded\n </span>\n )}\n </div>\n {zipUploadError && (\n <p className=\"text-xs text-destructive\">\n {zipUploadError}\n </p>\n )}\n </div>\n )}\n\n {uploadMode === \"manifest\" && (\n <div className=\"space-y-1\">\n <textarea\n rows={6}\n placeholder={`{\\n \"name\": \"my-workflow\",\\n \"version\": \"1.0.0\",\\n \"steps\": []\\n}`}\n value={newVersion.manifestJson}\n onChange={(e) =>\n setNewVersion({\n ...newVersion,\n manifestJson: e.target.value,\n })\n }\n className=\"w-full rounded-md border bg-transparent px-3 py-2 text-xs font-mono resize-y placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n <p className=\"text-xs text-muted-foreground\">\n Paste your workflow or configuration JSON here. No zip\n required.\n </p>\n </div>\n )}\n </div>\n )}\n <TextareaField\n label={tr(\"devportal.releaseNotes\", \"Release Notes\")}\n value={newVersion.releaseNotes}\n onChange={(e) =>\n setNewVersion({ ...newVersion, releaseNotes: e.target.value })\n }\n placeholder={tr(\n \"devportal.releaseNotesPlaceholder\",\n \"What changed in this release?\",\n )}\n rows={2}\n />\n </div>\n </ConfirmDialog>\n )}\n\n <ConfirmDialog\n open={bulkAction === \"publish\"}\n onOpenChange={(open) => {\n if (!open) setBulkAction(null);\n }}\n onConfirm={handleBulkPublish}\n title={tr(\n \"devportal.publishSelectedVersions\",\n \"Publish selected versions\",\n )}\n description={`${tr(\"devportal.publish\", \"Publish\")} ${publishableVersions.length} selected version${publishableVersions.length === 1 ? \"\" : \"s\"}?`}\n confirmLabel={tr(\"devportal.publish\", \"Publish\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"success\"\n />\n\n <ConfirmDialog\n open={bulkAction === \"deprecate\"}\n onOpenChange={(open) => {\n if (!open) setBulkAction(null);\n }}\n onConfirm={handleBulkDeprecate}\n title={tr(\n \"devportal.deprecateSelectedVersions\",\n \"Deprecate selected versions\",\n )}\n description={`${tr(\"devportal.deprecate\", \"Deprecate\")} ${deprecatableVersions.length} selected version${deprecatableVersions.length === 1 ? \"\" : \"s\"}? ${tr(\"devportal.deprecateVersionsWarning\", \"Deprecated versions remain visible but should no longer be promoted.\")}`}\n confirmLabel={tr(\"devportal.deprecate\", \"Deprecate\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"warning\"\n />\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-devportal",
3
- "version": "2026.624.11",
3
+ "version": "2026.624.12",
4
4
  "description": "Burdenoff Developer Portal Microfrontend - Complete developer operations interface",
5
5
  "type": "module",
6
6
  "files": [