@burdenoff/microfe-devportal 2026.611.2 → 2026.616.1
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.
- package/dist/devportal/components/SectionNav.js +105 -41
- package/dist/devportal/components/SectionNav.js.map +1 -1
- package/dist/devportal/hooks/useGraphQL.js +1 -1
- package/dist/devportal/pages/AdminReviewPage.js +36 -36
- package/dist/devportal/pages/AnalyticsDashboardPage.js +150 -150
- package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
- package/dist/devportal/pages/ApiKeysPage.js +184 -172
- package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
- package/dist/devportal/pages/AppLogsPage.js +9 -9
- package/dist/devportal/pages/ApplicationDetailPage.js +414 -414
- package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
- package/dist/devportal/pages/ApplicationVersionsPage.js +44 -44
- package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
- package/dist/devportal/pages/ApplicationsPage.js +118 -118
- package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
- package/dist/devportal/pages/CreateApiKeyPage.js +20 -20
- package/dist/devportal/pages/CreateApplicationPage.js +46 -66
- package/dist/devportal/pages/CreateApplicationPage.js.map +1 -1
- package/dist/devportal/pages/CreateOAuthClientPage.js +20 -20
- package/dist/devportal/pages/CreateOrganizationPage.js +125 -442
- package/dist/devportal/pages/CreateOrganizationPage.js.map +1 -1
- package/dist/devportal/pages/CreateWebhookPage.js +25 -25
- package/dist/devportal/pages/DashboardPage.js +160 -145
- package/dist/devportal/pages/DashboardPage.js.map +1 -1
- package/dist/devportal/pages/DelegationsPage.js +22 -22
- package/dist/devportal/pages/EditApplicationPage.js +297 -317
- package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
- package/dist/devportal/pages/ListingPreviewPage.js +9 -9
- package/dist/devportal/pages/OAuthClientDetailPage.js +17 -17
- package/dist/devportal/pages/OAuthClientsPage.js +16 -16
- package/dist/devportal/pages/OrganizationDetailPage.js +78 -78
- package/dist/devportal/pages/OrganizationMembersPage.js +260 -260
- package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
- package/dist/devportal/pages/OrganizationsPage.js +18 -18
- package/dist/devportal/pages/PublishPage.js +16 -16
- package/dist/devportal/pages/PublisherProfilePage.js +156 -146
- package/dist/devportal/pages/PublisherProfilePage.js.map +1 -1
- package/dist/devportal/pages/RevenueDashboardPage.js +512 -362
- package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
- package/dist/devportal/pages/SettingsPage.js +17 -17
- package/dist/devportal/pages/SetupPage.js +99 -99
- package/dist/devportal/pages/SetupPage.js.map +1 -1
- package/dist/devportal/pages/WebhookDetailPage.js +143 -143
- package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
- package/dist/devportal/pages/WebhooksPage.js +140 -140
- package/dist/devportal/pages/WebhooksPage.js.map +1 -1
- package/dist/devportal/providers/DevportalProvider.js +46 -33
- package/dist/devportal/providers/DevportalProvider.js.map +1 -1
- package/dist/generated/global-operations.js +69 -55
- package/dist/generated/global-operations.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
import { EmptyState as e } from "../components/EmptyState.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { PermissionGuard as
|
|
2
|
+
import { useCreateApplicationVersionMutation as t, useDeprecateApplicationVersionMutation as n, useGetApplicationQuery as r, useGetApplicationVersionsQuery as ee, usePublishApplicationVersionMutation as te } from "../../generated/global-operations.js";
|
|
3
|
+
import { PageLayout as i } from "../components/PageLayout.js";
|
|
4
|
+
import { StatusBadge as a } from "../components/StatusBadge.js";
|
|
5
|
+
import { SelectionCheckbox as o } from "../components/SelectionCheckbox.js";
|
|
6
|
+
import { DataTable as ne } from "../components/DataTable.js";
|
|
7
|
+
import { InputField as re, TextareaField as s } from "../components/FormField.js";
|
|
8
|
+
import { ConfirmDialog as c } from "../components/ConfirmDialog.js";
|
|
9
|
+
import { PermissionGuard as ie } from "../components/PermissionGuard.js";
|
|
10
10
|
import "../components/index.js";
|
|
11
|
-
import { DEVPORTAL_PERMISSIONS as
|
|
12
|
-
import { useDevportalPermission as
|
|
11
|
+
import { DEVPORTAL_PERMISSIONS as l } from "../constants/permissions.js";
|
|
12
|
+
import { useDevportalPermission as u } from "../hooks/usePermission.js";
|
|
13
13
|
import "../hooks/index.js";
|
|
14
|
-
import
|
|
15
|
-
import { useEffect as
|
|
16
|
-
import { useI18n as
|
|
17
|
-
import { AlertCircle as
|
|
14
|
+
import ae from "../../node_modules/date-fns/format.js";
|
|
15
|
+
import { useEffect as oe, useMemo as d, useState as f } from "react";
|
|
16
|
+
import { useI18n as p } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
17
|
+
import { AlertCircle as m, Archive as se, CheckCircle as h, Clock as ce, Loader2 as g, Package as _, Plus as v } from "lucide-react";
|
|
18
18
|
import { useParams as le } from "react-router-dom";
|
|
19
19
|
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
20
20
|
//#region src/devportal/pages/ApplicationVersionsPage.tsx
|
|
21
21
|
var x = () => {
|
|
22
|
-
let { t: x } =
|
|
22
|
+
let { t: x } = p(), S = (e, t) => {
|
|
23
23
|
let n = x(e);
|
|
24
24
|
return n === e ? t : n;
|
|
25
|
-
}, { allowed: C } = l
|
|
25
|
+
}, { allowed: C } = u(l.APP_VERSION_CREATE), { allowed: w } = u(l.APP_VERSION_PUBLISH), { allowed: T } = u(l.APP_VERSION_DEPRECATE), { appId: E } = le(), [D, O] = f(!1), [k, A] = f({
|
|
26
26
|
version: "",
|
|
27
27
|
releaseNotes: "",
|
|
28
28
|
changelog: ""
|
|
29
|
-
}), [j, M] =
|
|
29
|
+
}), [j, M] = f(null), [N, P] = f(null), [F, I] = f(/* @__PURE__ */ new Set()), [L, R] = f(null), { data: z } = r({
|
|
30
30
|
variables: { id: E ?? "" },
|
|
31
31
|
skip: !E,
|
|
32
32
|
fetchPolicy: "cache-first"
|
|
33
33
|
});
|
|
34
|
-
|
|
34
|
+
oe(() => {
|
|
35
35
|
let e = z?.application?.name;
|
|
36
36
|
if (!E || !e) return;
|
|
37
37
|
let t = window.__breadcrumbRegistry;
|
|
38
38
|
return t?.register(E, e), () => t?.unregister(E);
|
|
39
39
|
}, [E, z?.application?.name]);
|
|
40
|
-
let { data: B, loading: V, error: H } =
|
|
40
|
+
let { data: B, loading: V, error: H } = ee({
|
|
41
41
|
variables: { applicationId: E },
|
|
42
42
|
skip: !E,
|
|
43
43
|
fetchPolicy: "cache-and-network"
|
|
44
|
-
}), [U, { loading: ue }] =
|
|
44
|
+
}), [U, { loading: ue }] = t({ refetchQueries: ["GetApplicationVersions"] }), [W] = te({ refetchQueries: ["GetApplicationVersions"] }), [G] = n({ refetchQueries: ["GetApplicationVersions"] }), K = d(() => B?.application?.versions?.edges?.map((e) => e.node) ?? [], [B?.application?.versions]), q = d(() => K.filter((e) => F.has(e.id)), [K, F]), J = d(() => q.filter((e) => e.status === "DRAFT"), [q]), Y = d(() => q.filter((e) => e.status === "PUBLISHED" && !e.isLatest), [q]), X = K.length > 0 && K.every((e) => F.has(e.id)), Z = K.some((e) => F.has(e.id)) && !X, de = async () => {
|
|
45
45
|
if (!(!E || !k.version.trim())) {
|
|
46
46
|
M(null);
|
|
47
47
|
try {
|
|
@@ -75,13 +75,13 @@ var x = () => {
|
|
|
75
75
|
} catch (e) {
|
|
76
76
|
M(e instanceof Error ? e.message : S("devportal.versionDeprecateFailed", "Failed to deprecate version"));
|
|
77
77
|
}
|
|
78
|
-
}, me = (e) => e.status === "PUBLISHED" && e.isLatest ? /* @__PURE__ */ y(
|
|
78
|
+
}, me = (e) => e.status === "PUBLISHED" && e.isLatest ? /* @__PURE__ */ y(h, {
|
|
79
79
|
size: 16,
|
|
80
80
|
className: "text-status-success-text"
|
|
81
|
-
}) : e.status === "DRAFT" ? /* @__PURE__ */ y(
|
|
81
|
+
}) : e.status === "DRAFT" ? /* @__PURE__ */ y(ce, {
|
|
82
82
|
size: 16,
|
|
83
83
|
className: "text-status-warning-text"
|
|
84
|
-
}) : e.status === "DEPRECATED" ? /* @__PURE__ */ y(
|
|
84
|
+
}) : e.status === "DEPRECATED" ? /* @__PURE__ */ y(se, {
|
|
85
85
|
size: 16,
|
|
86
86
|
className: "text-text-secondary"
|
|
87
87
|
}) : /* @__PURE__ */ y(_, {
|
|
@@ -100,31 +100,31 @@ var x = () => {
|
|
|
100
100
|
}), n;
|
|
101
101
|
});
|
|
102
102
|
}, $ = () => I(/* @__PURE__ */ new Set());
|
|
103
|
-
return V && !B ? /* @__PURE__ */ y(
|
|
103
|
+
return V && !B ? /* @__PURE__ */ y(i, {
|
|
104
104
|
title: S("devportal.versionManagement", "Version Management"),
|
|
105
105
|
description: S("devportal.versionManagementDescription", "Manage your application versions"),
|
|
106
106
|
backLink: `/apps/${E}`,
|
|
107
107
|
backLabel: S("devportal.backToApplication", "Back to Application"),
|
|
108
108
|
children: /* @__PURE__ */ y("div", {
|
|
109
109
|
className: "flex items-center justify-center py-16",
|
|
110
|
-
children: /* @__PURE__ */ y(
|
|
110
|
+
children: /* @__PURE__ */ y(g, { className: "h-8 w-8 animate-spin text-muted-foreground" })
|
|
111
111
|
})
|
|
112
|
-
}) : H && !B ? /* @__PURE__ */ y(
|
|
112
|
+
}) : H && !B ? /* @__PURE__ */ y(i, {
|
|
113
113
|
title: S("devportal.versionManagement", "Version Management"),
|
|
114
114
|
description: S("devportal.versionManagementDescription", "Manage your application versions"),
|
|
115
115
|
backLink: `/apps/${E}`,
|
|
116
116
|
backLabel: S("devportal.backToApplication", "Back to Application"),
|
|
117
117
|
children: /* @__PURE__ */ y(e, {
|
|
118
|
-
icon: /* @__PURE__ */ y(
|
|
118
|
+
icon: /* @__PURE__ */ y(m, {
|
|
119
119
|
size: 32,
|
|
120
120
|
className: "text-status-error-text"
|
|
121
121
|
}),
|
|
122
122
|
title: S("devportal.failedToLoadVersions", "Failed to load versions"),
|
|
123
123
|
description: H.message || S("devportal.versionsLoadError", "An error occurred while loading versions")
|
|
124
124
|
})
|
|
125
|
-
}) : /* @__PURE__ */ y(
|
|
126
|
-
permission:
|
|
127
|
-
children: /* @__PURE__ */ b(
|
|
125
|
+
}) : /* @__PURE__ */ y(ie, {
|
|
126
|
+
permission: l.APP_READ,
|
|
127
|
+
children: /* @__PURE__ */ b(i, {
|
|
128
128
|
title: S("devportal.versionManagement", "Version Management"),
|
|
129
129
|
description: S("devportal.versionManagementDescription", "Manage your application versions"),
|
|
130
130
|
backLink: `/apps/${E}`,
|
|
@@ -140,7 +140,7 @@ var x = () => {
|
|
|
140
140
|
j && /* @__PURE__ */ b("div", {
|
|
141
141
|
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",
|
|
142
142
|
children: [
|
|
143
|
-
/* @__PURE__ */ y(
|
|
143
|
+
/* @__PURE__ */ y(m, {
|
|
144
144
|
size: 16,
|
|
145
145
|
className: "flex-shrink-0"
|
|
146
146
|
}),
|
|
@@ -155,7 +155,7 @@ var x = () => {
|
|
|
155
155
|
N && /* @__PURE__ */ b("div", {
|
|
156
156
|
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",
|
|
157
157
|
children: [
|
|
158
|
-
/* @__PURE__ */ y(
|
|
158
|
+
/* @__PURE__ */ y(h, {
|
|
159
159
|
size: 16,
|
|
160
160
|
className: "flex-shrink-0"
|
|
161
161
|
}),
|
|
@@ -175,7 +175,7 @@ var x = () => {
|
|
|
175
175
|
className: "flex flex-wrap items-center gap-3",
|
|
176
176
|
children: [/* @__PURE__ */ b("div", {
|
|
177
177
|
className: "flex items-center gap-2",
|
|
178
|
-
children: [/* @__PURE__ */ y(
|
|
178
|
+
children: [/* @__PURE__ */ y(o, {
|
|
179
179
|
checked: X,
|
|
180
180
|
indeterminate: Z,
|
|
181
181
|
onChange: Q,
|
|
@@ -214,13 +214,13 @@ var x = () => {
|
|
|
214
214
|
})]
|
|
215
215
|
})
|
|
216
216
|
}),
|
|
217
|
-
K.length > 0 ? /* @__PURE__ */ y(
|
|
217
|
+
K.length > 0 ? /* @__PURE__ */ y(ne, {
|
|
218
218
|
data: K,
|
|
219
219
|
keyField: "id",
|
|
220
220
|
columns: [
|
|
221
221
|
{
|
|
222
222
|
key: "select",
|
|
223
|
-
header: /* @__PURE__ */ y(
|
|
223
|
+
header: /* @__PURE__ */ y(o, {
|
|
224
224
|
checked: X,
|
|
225
225
|
indeterminate: Z,
|
|
226
226
|
onChange: Q,
|
|
@@ -229,7 +229,7 @@ var x = () => {
|
|
|
229
229
|
className: "w-12",
|
|
230
230
|
render: (e) => /* @__PURE__ */ y("div", {
|
|
231
231
|
onClick: (e) => e.stopPropagation(),
|
|
232
|
-
children: /* @__PURE__ */ y(
|
|
232
|
+
children: /* @__PURE__ */ y(o, {
|
|
233
233
|
checked: F.has(e.id),
|
|
234
234
|
onChange: (t) => he(e.id, t),
|
|
235
235
|
ariaLabel: `Select version ${e.version}`
|
|
@@ -269,12 +269,12 @@ var x = () => {
|
|
|
269
269
|
{
|
|
270
270
|
key: "status",
|
|
271
271
|
header: S("devportal.status", "Status"),
|
|
272
|
-
render: (e) => /* @__PURE__ */ y(
|
|
272
|
+
render: (e) => /* @__PURE__ */ y(a, { status: e.status })
|
|
273
273
|
},
|
|
274
274
|
{
|
|
275
275
|
key: "publishedAt",
|
|
276
276
|
header: S("devportal.published", "Published"),
|
|
277
|
-
render: (e) => e.publishedAt ?
|
|
277
|
+
render: (e) => e.publishedAt ? ae(new Date(e.publishedAt), "MMM d, yyyy") : "-"
|
|
278
278
|
},
|
|
279
279
|
{
|
|
280
280
|
key: "actions",
|
|
@@ -308,7 +308,7 @@ var x = () => {
|
|
|
308
308
|
children: [/* @__PURE__ */ y(v, { size: 16 }), S("devportal.createVersion", "Create Version")]
|
|
309
309
|
})
|
|
310
310
|
}),
|
|
311
|
-
D && /* @__PURE__ */ y(
|
|
311
|
+
D && /* @__PURE__ */ y(c, {
|
|
312
312
|
open: D,
|
|
313
313
|
onOpenChange: O,
|
|
314
314
|
onConfirm: de,
|
|
@@ -317,7 +317,7 @@ var x = () => {
|
|
|
317
317
|
children: /* @__PURE__ */ b("div", {
|
|
318
318
|
className: "space-y-4",
|
|
319
319
|
children: [
|
|
320
|
-
/* @__PURE__ */ y(
|
|
320
|
+
/* @__PURE__ */ y(re, {
|
|
321
321
|
label: S("devportal.versionNumber", "Version Number"),
|
|
322
322
|
value: k.version,
|
|
323
323
|
onChange: (e) => A({
|
|
@@ -328,7 +328,7 @@ var x = () => {
|
|
|
328
328
|
hint: S("devportal.versionHint", "Use semantic versioning (major.minor.patch)"),
|
|
329
329
|
required: !0
|
|
330
330
|
}),
|
|
331
|
-
/* @__PURE__ */ y(
|
|
331
|
+
/* @__PURE__ */ y(s, {
|
|
332
332
|
label: S("devportal.releaseNotes", "Release Notes"),
|
|
333
333
|
value: k.releaseNotes,
|
|
334
334
|
onChange: (e) => A({
|
|
@@ -338,7 +338,7 @@ var x = () => {
|
|
|
338
338
|
placeholder: S("devportal.releaseNotesPlaceholder", "Brief description of this release"),
|
|
339
339
|
rows: 2
|
|
340
340
|
}),
|
|
341
|
-
/* @__PURE__ */ y(
|
|
341
|
+
/* @__PURE__ */ y(s, {
|
|
342
342
|
label: S("devportal.changelog", "Changelog"),
|
|
343
343
|
value: k.changelog,
|
|
344
344
|
onChange: (e) => A({
|
|
@@ -351,7 +351,7 @@ var x = () => {
|
|
|
351
351
|
]
|
|
352
352
|
})
|
|
353
353
|
}),
|
|
354
|
-
/* @__PURE__ */ y(
|
|
354
|
+
/* @__PURE__ */ y(c, {
|
|
355
355
|
open: L === "publish",
|
|
356
356
|
onOpenChange: (e) => {
|
|
357
357
|
e || R(null);
|
|
@@ -368,7 +368,7 @@ var x = () => {
|
|
|
368
368
|
cancelLabel: S("devportal.cancel", "Cancel"),
|
|
369
369
|
variant: "success"
|
|
370
370
|
}),
|
|
371
|
-
/* @__PURE__ */ y(
|
|
371
|
+
/* @__PURE__ */ y(c, {
|
|
372
372
|
open: L === "deprecate",
|
|
373
373
|
onOpenChange: (e) => {
|
|
374
374
|
e || R(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationVersionsPage.js","names":[],"sources":["../../../src/devportal/pages/ApplicationVersionsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport {\n Plus,\n Package,\n CheckCircle,\n Clock,\n Archive,\n Loader2,\n AlertCircle,\n} 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\";\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 [showCreateDialog, setShowCreateDialog] = useState(false);\n const [newVersion, setNewVersion] = useState({\n version: \"\",\n releaseNotes: \"\",\n changelog: \"\",\n });\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 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 () => selectedVersions.filter((version) => version.status === \"DRAFT\"),\n [selectedVersions],\n );\n const deprecatableVersions = useMemo(\n () =>\n selectedVersions.filter(\n (version) => version.status === \"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 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 },\n },\n });\n setShowCreateDialog(false);\n setNewVersion({ version: \"\", releaseNotes: \"\", changelog: \"\" });\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 handlePublish = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await publishVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionPublishedSuccess\",\n \"Version published successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.versionPublishFailed\", \"Failed to publish version\"),\n );\n }\n };\n\n const handleDeprecate = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await deprecateVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionDeprecatedSuccess\",\n \"Version deprecated successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.versionDeprecateFailed\",\n \"Failed to deprecate version\",\n ),\n );\n }\n };\n\n const getStatusIcon = (version: ApplicationVersionFieldsFragment) => {\n if (version.status === \"PUBLISHED\" && version.isLatest) {\n return <CheckCircle size={16} className=\"text-status-success-text\" />;\n }\n if (version.status === \"DRAFT\") {\n return <Clock size={16} className=\"text-status-warning-text\" />;\n }\n if (version.status === \"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 === \"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 === \"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 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 <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 \"Brief description of this release\",\n )}\n rows={2}\n />\n <TextareaField\n label={tr(\"devportal.changelog\", \"Changelog\")}\n value={newVersion.changelog}\n onChange={(e) =>\n setNewVersion({ ...newVersion, changelog: e.target.value })\n }\n placeholder=\"- Added feature X - Fixed bug Y - Improved performance\"\n rows={4}\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 { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport {\n Plus,\n Package,\n CheckCircle,\n Clock,\n Archive,\n Loader2,\n AlertCircle,\n} 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\";\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 [showCreateDialog, setShowCreateDialog] = useState(false);\n const [newVersion, setNewVersion] = useState({\n version: \"\",\n releaseNotes: \"\",\n changelog: \"\",\n });\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 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 () => selectedVersions.filter((version) => version.status === \"DRAFT\"),\n [selectedVersions],\n );\n const deprecatableVersions = useMemo(\n () =>\n selectedVersions.filter(\n (version) => version.status === \"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 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 },\n },\n });\n setShowCreateDialog(false);\n setNewVersion({ version: \"\", releaseNotes: \"\", changelog: \"\" });\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 handlePublish = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await publishVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionPublishedSuccess\",\n \"Version published successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.versionPublishFailed\", \"Failed to publish version\"),\n );\n }\n };\n\n const handleDeprecate = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await deprecateVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionDeprecatedSuccess\",\n \"Version deprecated successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.versionDeprecateFailed\",\n \"Failed to deprecate version\",\n ),\n );\n }\n };\n\n const getStatusIcon = (version: ApplicationVersionFieldsFragment) => {\n if (version.status === \"PUBLISHED\" && version.isLatest) {\n return <CheckCircle size={16} className=\"text-status-success-text\" />;\n }\n if (version.status === \"DRAFT\") {\n return <Clock size={16} className=\"text-status-warning-text\" />;\n }\n if (version.status === \"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 === \"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 === \"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 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 <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 \"Brief description of this release\",\n )}\n rows={2}\n />\n <TextareaField\n label={tr(\"devportal.changelog\", \"Changelog\")}\n value={newVersion.changelog}\n onChange={(e) =>\n setNewVersion({ ...newVersion, changelog: e.target.value })\n }\n placeholder=\"- Added feature X - Fixed bug Y - Improved performance\"\n rows={4}\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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"}
|