@burdenoff/microfe-devportal 2026.624.18 → 2026.624.20

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