@burdenoff/microfe-devportal 2026.623.5 → 2026.623.6

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.
Files changed (45) hide show
  1. package/dist/devportal/DevportalRoutes.js +101 -94
  2. package/dist/devportal/DevportalRoutes.js.map +1 -1
  3. package/dist/devportal/components/SectionNav.js +71 -5
  4. package/dist/devportal/components/SectionNav.js.map +1 -0
  5. package/dist/devportal/components/index.js +1 -1
  6. package/dist/devportal/hooks/useGraphQL.js +1 -1
  7. package/dist/devportal/pages/AdminReviewPage.js +39 -39
  8. package/dist/devportal/pages/AnalyticsDashboardPage.js +54 -54
  9. package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
  10. package/dist/devportal/pages/ApiKeysPage.js +53 -53
  11. package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
  12. package/dist/devportal/pages/AppLogsPage.js +9 -9
  13. package/dist/devportal/pages/ApplicationDetailPage.js +462 -462
  14. package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
  15. package/dist/devportal/pages/ApplicationVersionsPage.js +120 -120
  16. package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
  17. package/dist/devportal/pages/ApplicationsPage.js +73 -73
  18. package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
  19. package/dist/devportal/pages/CreateApiKeyPage.js +20 -20
  20. package/dist/devportal/pages/CreateApplicationPage.js +32 -32
  21. package/dist/devportal/pages/CreateOAuthClientPage.js +18 -18
  22. package/dist/devportal/pages/CreateOrganizationPage.js +12 -12
  23. package/dist/devportal/pages/CreateWebhookPage.js +23 -23
  24. package/dist/devportal/pages/DashboardPage.js +23 -23
  25. package/dist/devportal/pages/DelegationsPage.js +22 -22
  26. package/dist/devportal/pages/EditApplicationPage.js +283 -283
  27. package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
  28. package/dist/devportal/pages/ListingPreviewPage.js +9 -9
  29. package/dist/devportal/pages/OAuthClientDetailPage.js +15 -15
  30. package/dist/devportal/pages/OAuthClientsPage.js +14 -14
  31. package/dist/devportal/pages/OrganizationDetailPage.js +84 -84
  32. package/dist/devportal/pages/OrganizationMembersPage.js +260 -260
  33. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  34. package/dist/devportal/pages/OrganizationsPage.js +16 -16
  35. package/dist/devportal/pages/PublishPage.js +16 -16
  36. package/dist/devportal/pages/PublisherProfilePage.js +18 -18
  37. package/dist/devportal/pages/RevenueDashboardPage.js +29 -29
  38. package/dist/devportal/pages/SettingsPage.js +17 -17
  39. package/dist/devportal/pages/SetupPage.js +99 -99
  40. package/dist/devportal/pages/SetupPage.js.map +1 -1
  41. package/dist/devportal/pages/WebhookDetailPage.js +143 -143
  42. package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
  43. package/dist/devportal/pages/WebhooksPage.js +133 -133
  44. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  45. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ApplicationVersionsPage.js","names":[],"sources":["../../../src/devportal/pages/ApplicationVersionsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport {\n Plus,\n Package,\n CheckCircle,\n Clock,\n Archive,\n Loader2,\n AlertCircle,\n Upload,\n FileJson,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { InputField, TextareaField } from \"../components/FormField\";\nimport { ConfirmDialog } from \"../components/ConfirmDialog\";\nimport { SelectionCheckbox } from \"../components/SelectionCheckbox\";\nimport { format } from \"date-fns\";\nimport {\n useGetApplicationQuery,\n useGetApplicationVersionsQuery,\n useCreateApplicationVersionMutation,\n usePublishApplicationVersionMutation,\n useDeprecateApplicationVersionMutation,\n type ApplicationVersionFieldsFragment,\n} from \"../hooks\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { usePackageUpload } from \"../hooks/usePackageUpload\";\n\nexport const ApplicationVersionsPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { allowed: canCreate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_CREATE,\n );\n const { allowed: canPublish } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_PUBLISH,\n );\n const { allowed: canDeprecate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_DEPRECATE,\n );\n const { appId } = useParams<{ appId: string }>();\n const { workspacesGatewayUrl, authToken, workspaceId, getWorkspaceToken } =\n useDevportal();\n const {\n upload: uploadZip,\n uploading: zipUploading,\n progress: zipProgress,\n error: zipUploadError,\n } = usePackageUpload(\n workspacesGatewayUrl,\n authToken,\n workspaceId,\n getWorkspaceToken,\n );\n const zipInputRef = useRef<HTMLInputElement>(null);\n const [showCreateDialog, setShowCreateDialog] = useState(false);\n const [newVersion, setNewVersion] = useState({\n version: \"\",\n releaseNotes: \"\",\n changelog: \"\",\n packageUrl: \"\",\n packageSize: \"\",\n manifestJson: \"\",\n });\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 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 let parsedManifest: Record<string, unknown> | undefined;\n if (uploadMode === \"manifest\" && 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:\n uploadMode === \"file\"\n ? newVersion.packageUrl || undefined\n : undefined,\n packageSize:\n uploadMode === \"file\"\n ? newVersion.packageSize || undefined\n : 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 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 handlePublish = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await publishVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionPublishedSuccess\",\n \"Version published successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.versionPublishFailed\", \"Failed to publish version\"),\n );\n }\n };\n\n const handleDeprecate = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await deprecateVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionDeprecatedSuccess\",\n \"Version deprecated successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.versionDeprecateFailed\",\n \"Failed to deprecate version\",\n ),\n );\n }\n };\n\n const getStatusIcon = (version: ApplicationVersionFieldsFragment) => {\n const statusUp = version.status?.toUpperCase();\n if (statusUp === \"PUBLISHED\" && version.isLatest) {\n return <CheckCircle size={16} className=\"text-status-success-text\" />;\n }\n if (statusUp === \"DRAFT\") {\n return <Clock size={16} className=\"text-status-warning-text\" />;\n }\n if (statusUp === \"DEPRECATED\") {\n return <Archive size={16} className=\"text-text-secondary\" />;\n }\n return <Package size={16} className=\"text-accent-blue\" />;\n };\n\n const toggleVersionSelection = (versionId: string, checked: boolean) => {\n setSelectedVersionIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(versionId);\n } else {\n next.delete(versionId);\n }\n return next;\n });\n };\n\n const toggleAllVisibleVersions = (checked: boolean) => {\n setSelectedVersionIds((prev) => {\n const next = new Set(prev);\n versions.forEach((version) => {\n if (checked) {\n next.add(version.id);\n } else {\n next.delete(version.id);\n }\n });\n return next;\n });\n };\n\n const clearSelection = () => setSelectedVersionIds(new Set());\n\n const handleBulkPublish = async () => {\n if (publishableVersions.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n publishableVersions.map((version) =>\n publishVersion({ variables: { id: version.id } }),\n ),\n );\n const succeeded = results.filter(\n (result: PromiseSettledResult<unknown>) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `Published ${succeeded} version${succeeded === 1 ? \"\" : \"s\"}${failed > 0 ? ` • ${failed} failed` : \"\"}`,\n );\n clearSelection();\n setBulkAction(null);\n };\n\n const handleBulkDeprecate = async () => {\n if (deprecatableVersions.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n deprecatableVersions.map((version) =>\n deprecateVersion({ variables: { id: version.id } }),\n ),\n );\n const succeeded = results.filter(\n (result: PromiseSettledResult<unknown>) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `Deprecated ${succeeded} version${succeeded === 1 ? \"\" : \"s\"}${failed > 0 ? ` • ${failed} failed` : \"\"}`,\n );\n clearSelection();\n setBulkAction(null);\n };\n\n // Loading state\n if (versionsLoading && !versionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <div className=\"flex items-center justify-center py-16\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (versionsError && !versionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.failedToLoadVersions\",\n \"Failed to load versions\",\n )}\n description={\n versionsError.message ||\n tr(\n \"devportal.versionsLoadError\",\n \"An error occurred while loading versions\",\n )\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.APP_READ}>\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n <button\n onClick={() => setShowCreateDialog(true)}\n disabled={!canCreate}\n aria-disabled={!canCreate}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50\"\n >\n <Plus size={16} />\n {tr(\"devportal.newVersion\", \"New Version\")}\n </button>\n }\n >\n {/* Action Error Banner */}\n {actionError && (\n <div className=\"rounded-lg border border-border-subtle bg-status-error-bg-subtle p-3 flex items-center gap-2 text-sm text-status-error-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionError}\n <button\n onClick={() => setActionError(null)}\n className=\"ml-auto text-status-error-text hover:text-status-error-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {actionSuccess && (\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-3 flex items-center gap-2 text-sm text-status-success-text\">\n <CheckCircle size={16} className=\"flex-shrink-0\" />\n {actionSuccess}\n <button\n onClick={() => setActionSuccess(null)}\n className=\"ml-auto text-status-success-text hover:text-status-success-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {versions.length > 0 && (\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVersions}\n ariaLabel=\"Select all visible versions\"\n />\n <span className=\"text-sm font-medium\">\n {tr(\"devportal.selectAllVisible\", \"Select all visible\")}\n </span>\n </div>\n {selectedVersionIds.size > 0 && (\n <button\n onClick={clearSelection}\n className=\"text-sm text-muted-foreground hover:text-foreground\"\n >\n {tr(\"devportal.clearSelection\", \"Clear selection\")}\n </button>\n )}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-muted px-3 py-1 text-sm font-medium text-muted-foreground\">\n {selectedVersionIds.size} selected\n </span>\n <button\n onClick={() => setBulkAction(\"publish\")}\n disabled={publishableVersions.length === 0 || !canPublish}\n aria-disabled={!canPublish}\n className=\"rounded-md border border-status-success-bg px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.publishSelected\", \"Publish Selected\")}\n {publishableVersions.length > 0\n ? ` (${publishableVersions.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setBulkAction(\"deprecate\")}\n disabled={deprecatableVersions.length === 0 || !canDeprecate}\n aria-disabled={!canDeprecate}\n className=\"rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.deprecateSelected\", \"Deprecate Selected\")}\n {deprecatableVersions.length > 0\n ? ` (${deprecatableVersions.length})`\n : \"\"}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {versions.length > 0 ? (\n <DataTable\n data={versions}\n keyField=\"id\"\n columns={[\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVersions}\n ariaLabel=\"Select all visible versions\"\n />\n ),\n className: \"w-12\",\n render: (v) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedVersionIds.has(v.id)}\n onChange={(checked) =>\n toggleVersionSelection(v.id, checked)\n }\n ariaLabel={`Select version ${v.version}`}\n />\n </div>\n ),\n },\n {\n key: \"version\",\n header: tr(\"devportal.version\", \"Version\"),\n render: (v) => (\n <div className=\"flex items-center gap-2\">\n {getStatusIcon(v)}\n <span className=\"font-mono font-medium\">{v.version}</span>\n {v.isLatest && (\n <span className=\"rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-xs text-status-success-text\">\n {tr(\"devportal.latest\", \"Latest\")}\n </span>\n )}\n {!v.isStable && (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs text-status-warning-text\">\n {tr(\"devportal.beta\", \"Beta\")}\n </span>\n )}\n </div>\n ),\n },\n {\n key: \"releaseNotes\",\n header: tr(\"devportal.releaseNotes\", \"Release Notes\"),\n render: (v) => (\n <p className=\"max-w-md truncate text-sm text-muted-foreground\">\n {v.releaseNotes ||\n tr(\"devportal.noReleaseNotes\", \"No release notes\")}\n </p>\n ),\n },\n {\n key: \"status\",\n header: tr(\"devportal.status\", \"Status\"),\n render: (v) => <StatusBadge status={v.status} />,\n },\n {\n key: \"publishedAt\",\n header: tr(\"devportal.published\", \"Published\"),\n render: (v) =>\n v.publishedAt\n ? format(new Date(v.publishedAt), \"MMM d, yyyy\")\n : \"-\",\n },\n {\n key: \"actions\",\n header: \"\",\n className: \"w-32\",\n render: (v) => (\n <div className=\"flex gap-2\">\n {v.status?.toUpperCase() === \"DRAFT\" && (\n <button\n className=\"text-xs text-primary hover:underline disabled:opacity-50\"\n disabled={!canPublish}\n aria-disabled={!canPublish}\n onClick={() => handlePublish(v.id)}\n >\n {tr(\"devportal.publish\", \"Publish\")}\n </button>\n )}\n {v.status?.toUpperCase() === \"PUBLISHED\" && !v.isLatest && (\n <button\n className=\"text-xs text-status-warning-text hover:underline disabled:opacity-50\"\n disabled={!canDeprecate}\n aria-disabled={!canDeprecate}\n onClick={() => handleDeprecate(v.id)}\n >\n {tr(\"devportal.deprecate\", \"Deprecate\")}\n </button>\n )}\n </div>\n ),\n },\n ]}\n />\n ) : (\n <EmptyState\n icon={<Package size={32} />}\n title={tr(\"devportal.noVersionsYet\", \"No versions yet\")}\n description={tr(\n \"devportal.noVersionsYetDescription\",\n \"Create your first version to start distributing your app\",\n )}\n action={\n <button\n onClick={() => setShowCreateDialog(true)}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createVersion\", \"Create Version\")}\n </button>\n }\n />\n )}\n\n {/* Create Version Dialog */}\n {showCreateDialog && (\n <ConfirmDialog\n open={showCreateDialog}\n onOpenChange={setShowCreateDialog}\n onConfirm={handleCreate}\n title={tr(\"devportal.createNewVersion\", \"Create New Version\")}\n 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 mode toggle */}\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 <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 { useParams } from \"react-router-dom\";\nimport {\n Plus,\n Package,\n CheckCircle,\n Clock,\n Archive,\n Loader2,\n AlertCircle,\n Upload,\n FileJson,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { InputField, TextareaField } from \"../components/FormField\";\nimport { ConfirmDialog } from \"../components/ConfirmDialog\";\nimport { SelectionCheckbox } from \"../components/SelectionCheckbox\";\nimport { format } from \"date-fns\";\nimport {\n useGetApplicationQuery,\n useGetApplicationVersionsQuery,\n useCreateApplicationVersionMutation,\n usePublishApplicationVersionMutation,\n useDeprecateApplicationVersionMutation,\n type ApplicationVersionFieldsFragment,\n} from \"../hooks\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { usePackageUpload } from \"../hooks/usePackageUpload\";\n\nexport const ApplicationVersionsPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { allowed: canCreate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_CREATE,\n );\n const { allowed: canPublish } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_PUBLISH,\n );\n const { allowed: canDeprecate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.APP_VERSION_DEPRECATE,\n );\n const { appId } = useParams<{ appId: string }>();\n const { workspacesGatewayUrl, authToken, workspaceId, getWorkspaceToken } =\n useDevportal();\n const {\n upload: uploadZip,\n uploading: zipUploading,\n progress: zipProgress,\n error: zipUploadError,\n } = usePackageUpload(\n workspacesGatewayUrl,\n authToken,\n workspaceId,\n getWorkspaceToken,\n );\n const zipInputRef = useRef<HTMLInputElement>(null);\n const [showCreateDialog, setShowCreateDialog] = useState(false);\n const [newVersion, setNewVersion] = useState({\n version: \"\",\n releaseNotes: \"\",\n changelog: \"\",\n packageUrl: \"\",\n packageSize: \"\",\n manifestJson: \"\",\n });\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 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 let parsedManifest: Record<string, unknown> | undefined;\n if (uploadMode === \"manifest\" && 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:\n uploadMode === \"file\"\n ? newVersion.packageUrl || undefined\n : undefined,\n packageSize:\n uploadMode === \"file\"\n ? newVersion.packageSize || undefined\n : 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 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 handlePublish = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await publishVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionPublishedSuccess\",\n \"Version published successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.versionPublishFailed\", \"Failed to publish version\"),\n );\n }\n };\n\n const handleDeprecate = async (versionId: string) => {\n setActionError(null);\n setActionSuccess(null);\n try {\n await deprecateVersion({ variables: { id: versionId } });\n setActionSuccess(\n tr(\n \"devportal.versionDeprecatedSuccess\",\n \"Version deprecated successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.versionDeprecateFailed\",\n \"Failed to deprecate version\",\n ),\n );\n }\n };\n\n const getStatusIcon = (version: ApplicationVersionFieldsFragment) => {\n const statusUp = version.status?.toUpperCase();\n if (statusUp === \"PUBLISHED\" && version.isLatest) {\n return <CheckCircle size={16} className=\"text-status-success-text\" />;\n }\n if (statusUp === \"DRAFT\") {\n return <Clock size={16} className=\"text-status-warning-text\" />;\n }\n if (statusUp === \"DEPRECATED\") {\n return <Archive size={16} className=\"text-text-secondary\" />;\n }\n return <Package size={16} className=\"text-accent-blue\" />;\n };\n\n const toggleVersionSelection = (versionId: string, checked: boolean) => {\n setSelectedVersionIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(versionId);\n } else {\n next.delete(versionId);\n }\n return next;\n });\n };\n\n const toggleAllVisibleVersions = (checked: boolean) => {\n setSelectedVersionIds((prev) => {\n const next = new Set(prev);\n versions.forEach((version) => {\n if (checked) {\n next.add(version.id);\n } else {\n next.delete(version.id);\n }\n });\n return next;\n });\n };\n\n const clearSelection = () => setSelectedVersionIds(new Set());\n\n const handleBulkPublish = async () => {\n if (publishableVersions.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n publishableVersions.map((version) =>\n publishVersion({ variables: { id: version.id } }),\n ),\n );\n const succeeded = results.filter(\n (result: PromiseSettledResult<unknown>) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `Published ${succeeded} version${succeeded === 1 ? \"\" : \"s\"}${failed > 0 ? ` • ${failed} failed` : \"\"}`,\n );\n clearSelection();\n setBulkAction(null);\n };\n\n const handleBulkDeprecate = async () => {\n if (deprecatableVersions.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n deprecatableVersions.map((version) =>\n deprecateVersion({ variables: { id: version.id } }),\n ),\n );\n const succeeded = results.filter(\n (result: PromiseSettledResult<unknown>) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `Deprecated ${succeeded} version${succeeded === 1 ? \"\" : \"s\"}${failed > 0 ? ` • ${failed} failed` : \"\"}`,\n );\n clearSelection();\n setBulkAction(null);\n };\n\n // Loading state\n if (versionsLoading && !versionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <div className=\"flex items-center justify-center py-16\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (versionsError && !versionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.failedToLoadVersions\",\n \"Failed to load versions\",\n )}\n description={\n versionsError.message ||\n tr(\n \"devportal.versionsLoadError\",\n \"An error occurred while loading versions\",\n )\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.APP_READ}>\n <PageLayout\n title={tr(\"devportal.versionManagement\", \"Version Management\")}\n description={tr(\n \"devportal.versionManagementDescription\",\n \"Manage your application versions\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n <button\n onClick={() => setShowCreateDialog(true)}\n disabled={!canCreate}\n aria-disabled={!canCreate}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50\"\n >\n <Plus size={16} />\n {tr(\"devportal.newVersion\", \"New Version\")}\n </button>\n }\n >\n {/* Action Error Banner */}\n {actionError && (\n <div className=\"rounded-lg border border-border-subtle bg-status-error-bg-subtle p-3 flex items-center gap-2 text-sm text-status-error-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionError}\n <button\n onClick={() => setActionError(null)}\n className=\"ml-auto text-status-error-text hover:text-status-error-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {actionSuccess && (\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-3 flex items-center gap-2 text-sm text-status-success-text\">\n <CheckCircle size={16} className=\"flex-shrink-0\" />\n {actionSuccess}\n <button\n onClick={() => setActionSuccess(null)}\n className=\"ml-auto text-status-success-text hover:text-status-success-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {versions.length > 0 && (\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVersions}\n ariaLabel=\"Select all visible versions\"\n />\n <span className=\"text-sm font-medium\">\n {tr(\"devportal.selectAllVisible\", \"Select all visible\")}\n </span>\n </div>\n {selectedVersionIds.size > 0 && (\n <button\n onClick={clearSelection}\n className=\"text-sm text-muted-foreground hover:text-foreground\"\n >\n {tr(\"devportal.clearSelection\", \"Clear selection\")}\n </button>\n )}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-muted px-3 py-1 text-sm font-medium text-muted-foreground\">\n {selectedVersionIds.size} selected\n </span>\n <button\n onClick={() => setBulkAction(\"publish\")}\n disabled={publishableVersions.length === 0 || !canPublish}\n aria-disabled={!canPublish}\n className=\"rounded-md border border-status-success-bg px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.publishSelected\", \"Publish Selected\")}\n {publishableVersions.length > 0\n ? ` (${publishableVersions.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setBulkAction(\"deprecate\")}\n disabled={deprecatableVersions.length === 0 || !canDeprecate}\n aria-disabled={!canDeprecate}\n className=\"rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.deprecateSelected\", \"Deprecate Selected\")}\n {deprecatableVersions.length > 0\n ? ` (${deprecatableVersions.length})`\n : \"\"}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {versions.length > 0 ? (\n <DataTable\n data={versions}\n keyField=\"id\"\n columns={[\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVersions}\n ariaLabel=\"Select all visible versions\"\n />\n ),\n className: \"w-12\",\n render: (v) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedVersionIds.has(v.id)}\n onChange={(checked) =>\n toggleVersionSelection(v.id, checked)\n }\n ariaLabel={`Select version ${v.version}`}\n />\n </div>\n ),\n },\n {\n key: \"version\",\n header: tr(\"devportal.version\", \"Version\"),\n render: (v) => (\n <div className=\"flex items-center gap-2\">\n {getStatusIcon(v)}\n <span className=\"font-mono font-medium\">{v.version}</span>\n {v.isLatest && (\n <span className=\"rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-xs text-status-success-text\">\n {tr(\"devportal.latest\", \"Latest\")}\n </span>\n )}\n {!v.isStable && (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs text-status-warning-text\">\n {tr(\"devportal.beta\", \"Beta\")}\n </span>\n )}\n </div>\n ),\n },\n {\n key: \"releaseNotes\",\n header: tr(\"devportal.releaseNotes\", \"Release Notes\"),\n render: (v) => (\n <p className=\"max-w-md truncate text-sm text-muted-foreground\">\n {v.releaseNotes ||\n tr(\"devportal.noReleaseNotes\", \"No release notes\")}\n </p>\n ),\n },\n {\n key: \"status\",\n header: tr(\"devportal.status\", \"Status\"),\n render: (v) => <StatusBadge status={v.status} />,\n },\n {\n key: \"publishedAt\",\n header: tr(\"devportal.published\", \"Published\"),\n render: (v) =>\n v.publishedAt\n ? format(new Date(v.publishedAt), \"MMM d, yyyy\")\n : \"-\",\n },\n {\n key: \"actions\",\n header: \"\",\n className: \"w-32\",\n render: (v) => (\n <div className=\"flex gap-2\">\n {v.status?.toUpperCase() === \"DRAFT\" && (\n <button\n className=\"text-xs text-primary hover:underline disabled:opacity-50\"\n disabled={!canPublish}\n aria-disabled={!canPublish}\n onClick={() => handlePublish(v.id)}\n >\n {tr(\"devportal.publish\", \"Publish\")}\n </button>\n )}\n {v.status?.toUpperCase() === \"PUBLISHED\" && !v.isLatest && (\n <button\n className=\"text-xs text-status-warning-text hover:underline disabled:opacity-50\"\n disabled={!canDeprecate}\n aria-disabled={!canDeprecate}\n onClick={() => handleDeprecate(v.id)}\n >\n {tr(\"devportal.deprecate\", \"Deprecate\")}\n </button>\n )}\n </div>\n ),\n },\n ]}\n />\n ) : (\n <EmptyState\n icon={<Package size={32} />}\n title={tr(\"devportal.noVersionsYet\", \"No versions yet\")}\n description={tr(\n \"devportal.noVersionsYetDescription\",\n \"Create your first version to start distributing your app\",\n )}\n action={\n <button\n onClick={() => setShowCreateDialog(true)}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createVersion\", \"Create Version\")}\n </button>\n }\n />\n )}\n\n {/* Create Version Dialog */}\n {showCreateDialog && (\n <ConfirmDialog\n open={showCreateDialog}\n onOpenChange={setShowCreateDialog}\n onConfirm={handleCreate}\n title={tr(\"devportal.createNewVersion\", \"Create New Version\")}\n 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 mode toggle */}\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 <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,26 +1,26 @@
1
1
  import { useDevportal as e } from "../providers/DevportalProvider.js";
2
2
  import { EmptyState as t } from "../components/EmptyState.js";
3
- import { PageLayout as n } from "../components/PageLayout.js";
4
- import { APP_STATUS_COLORS as r, APP_TYPE_LABELS as ee } from "../utils/constants.js";
5
- import { SelectionCheckbox as i } from "../components/SelectionCheckbox.js";
6
- import { AppCard as a, AppListItem as o } from "../components/AppCard.js";
7
- import { ConfirmDialog as s } from "../components/ConfirmDialog.js";
8
- import { useDeactivateAppMutation as te, useDeleteApplicationMutation as ne, useGetApplicationsQuery as re } from "../../generated/global-operations.js";
9
- import { PermissionGuard as ie } from "../components/PermissionGuard.js";
10
- import { getErrorMessage as ae } from "../hooks/useGraphQL.js";
3
+ import { useDeactivateAppMutation as n, useDeleteApplicationMutation as r, useGetApplicationsQuery as ee } from "../../generated/global-operations.js";
4
+ import { getErrorMessage as te } from "../hooks/useGraphQL.js";
5
+ import { PageLayout as i } from "../components/PageLayout.js";
6
+ import { APP_STATUS_COLORS as ne, APP_TYPE_LABELS as a } from "../utils/constants.js";
7
+ import { SelectionCheckbox as re } from "../components/SelectionCheckbox.js";
8
+ import { AppCard as ie, AppListItem as ae } from "../components/AppCard.js";
9
+ import { ConfirmDialog as o } from "../components/ConfirmDialog.js";
10
+ import { PermissionGuard as oe } from "../components/PermissionGuard.js";
11
11
  import "../components/index.js";
12
- import { DEVPORTAL_PERMISSIONS as c } from "../constants/permissions.js";
13
- import { useDevportalPermission as l } from "../hooks/usePermission.js";
12
+ import { DEVPORTAL_PERMISSIONS as s } from "../constants/permissions.js";
13
+ import { useDevportalPermission as c } from "../hooks/usePermission.js";
14
14
  import "../hooks/index.js";
15
- import { useMemo as u, useState as d } from "react";
16
- import { useI18n as f } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
17
- import { AlertCircle as p, AppWindow as m, Archive as h, Grid as g, List as oe, Loader2 as se, Plus as _, Search as ce, Trash2 as le } from "lucide-react";
15
+ import { useMemo as l, useState as u } from "react";
16
+ import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
17
+ import { AlertCircle as f, AppWindow as p, Archive as m, Grid as h, List as g, Loader2 as se, Plus as _, Search as ce, Trash2 as le } from "lucide-react";
18
18
  import { jsx as v, jsxs as y } from "react/jsx-runtime";
19
19
  //#region src/devportal/pages/ApplicationsPage.tsx
20
20
  function b(e, t, n) {
21
21
  return `${e} ${t} application${t === 1 ? "" : "s"}${n > 0 ? ` • ${n} failed` : ""}`;
22
22
  }
23
- function x(e) {
23
+ function ue(e) {
24
24
  let t = Array.isArray(e.screenshots) ? e.screenshots.length > 0 ? e.screenshots : void 0 : e.screenshots, n = e.pricingDetails && typeof e.pricingDetails == "object" ? e.pricingDetails : void 0;
25
25
  return {
26
26
  id: e.id,
@@ -66,36 +66,36 @@ function x(e) {
66
66
  updatedAt: e.updatedAt
67
67
  };
68
68
  }
69
- var S = () => {
70
- let { navigate: S, basePath: ue, activeOrgId: C } = e(), { t: w } = f(), T = (e, t) => {
69
+ var x = () => {
70
+ let { navigate: x, basePath: S, activeOrgId: C } = e(), { t: w } = d(), T = (e, t) => {
71
71
  let n = w(e);
72
72
  return n === e ? t : n;
73
- }, E = l(c.APP_CREATE), D = l(c.APP_DELETE), O = l(c.APP_UPDATE), [k, A] = d("grid"), [j, M] = d(""), [N, P] = d(""), [F, I] = d(""), [L, R] = d(/* @__PURE__ */ new Set()), [z, B] = d(null), [V, H] = d(null), { data: U, loading: de, error: W, refetch: G } = re({
73
+ }, E = c(s.APP_CREATE), D = c(s.APP_DELETE), O = c(s.APP_UPDATE), [k, A] = u("grid"), [j, de] = u(""), [M, N] = u(""), [P, F] = u(""), [I, L] = u(/* @__PURE__ */ new Set()), [R, z] = u(null), [B, V] = u(null), { data: H, loading: fe, error: U, refetch: W } = ee({
74
74
  variables: {
75
75
  limit: 50,
76
76
  offset: 0,
77
- status: N || void 0
77
+ status: M || void 0
78
78
  },
79
79
  fetchPolicy: "cache-and-network"
80
- }), K = u(() => U?.applications?.edges?.map((e) => x(e.node)) ?? [], [U?.applications?.edges]), [fe] = ne(), [pe] = te(), q = (e) => {
81
- S?.(`${ue}${e}`);
82
- }, J = K.filter((e) => {
83
- let t = !C || e.developerOrganizationId === C, n = !j || e.name.toLowerCase().includes(j.toLowerCase()) || e.shortDescription?.toLowerCase().includes(j.toLowerCase()), r = !F || e.appType === F;
80
+ }), G = l(() => H?.applications?.edges?.map((e) => ue(e.node)) ?? [], [H?.applications?.edges]), [pe] = r(), [K] = n(), q = (e) => {
81
+ x?.(`${S}${e}`);
82
+ }, J = G.filter((e) => {
83
+ let t = !C || e.developerOrganizationId === C, n = !j || e.name.toLowerCase().includes(j.toLowerCase()) || e.shortDescription?.toLowerCase().includes(j.toLowerCase()), r = !P || e.appType === P;
84
84
  return t && n && r;
85
- }), Y = u(() => K.filter((e) => L.has(e.id)), [K, L]), X = u(() => Y.filter((e) => e.status !== "INACTIVE" && e.status !== "REVOKED"), [Y]), Z = J.length > 0 && J.every((e) => L.has(e.id)), me = J.some((e) => L.has(e.id)) && !Z, Q = (e, t) => {
86
- R((n) => {
85
+ }), Y = l(() => G.filter((e) => I.has(e.id)), [G, I]), X = l(() => Y.filter((e) => e.status !== "INACTIVE" && e.status !== "REVOKED"), [Y]), Z = J.length > 0 && J.every((e) => I.has(e.id)), me = J.some((e) => I.has(e.id)) && !Z, Q = (e, t) => {
86
+ L((n) => {
87
87
  let r = new Set(n);
88
88
  return t ? r.add(e) : r.delete(e), r;
89
89
  });
90
90
  }, he = (e) => {
91
- R((t) => {
91
+ L((t) => {
92
92
  let n = new Set(t);
93
93
  return J.forEach((t) => {
94
94
  e ? n.add(t.id) : n.delete(t.id);
95
95
  }), n;
96
96
  });
97
- }, $ = () => R(/* @__PURE__ */ new Set());
98
- return de && !U ? /* @__PURE__ */ v(n, {
97
+ }, $ = () => L(/* @__PURE__ */ new Set());
98
+ return fe && !H ? /* @__PURE__ */ v(i, {
99
99
  title: T("devportal.myApplications", "My Applications"),
100
100
  description: T("devportal.manageYourApps", "Manage your developer applications"),
101
101
  children: /* @__PURE__ */ y("div", {
@@ -105,31 +105,31 @@ var S = () => {
105
105
  children: T("devportal.loadingApplications", "Loading applications...")
106
106
  })]
107
107
  })
108
- }) : W ? /* @__PURE__ */ v(n, {
108
+ }) : U ? /* @__PURE__ */ v(i, {
109
109
  title: T("devportal.myApplications", "My Applications"),
110
110
  description: T("devportal.manageYourApps", "Manage your developer applications"),
111
111
  children: /* @__PURE__ */ y("div", {
112
112
  className: "rounded-lg border border-destructive/50 bg-destructive/10 p-6 text-center",
113
113
  children: [
114
- /* @__PURE__ */ v(p, { className: "mx-auto h-8 w-8 text-destructive" }),
114
+ /* @__PURE__ */ v(f, { className: "mx-auto h-8 w-8 text-destructive" }),
115
115
  /* @__PURE__ */ v("h3", {
116
116
  className: "mt-2 font-medium text-destructive",
117
117
  children: T("devportal.failedToLoadApplications", "Failed to load applications")
118
118
  }),
119
119
  /* @__PURE__ */ v("p", {
120
120
  className: "mt-1 text-sm text-muted-foreground",
121
- children: ae(W)
121
+ children: te(U)
122
122
  }),
123
123
  /* @__PURE__ */ v("button", {
124
- onClick: () => G(),
124
+ onClick: () => W(),
125
125
  className: "mt-4 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
126
126
  children: T("devportal.tryAgain", "Try Again")
127
127
  })
128
128
  ]
129
129
  })
130
- }) : /* @__PURE__ */ v(ie, {
131
- permission: c.APP_READ,
132
- children: /* @__PURE__ */ y(n, {
130
+ }) : /* @__PURE__ */ v(oe, {
131
+ permission: s.APP_READ,
132
+ children: /* @__PURE__ */ y(i, {
133
133
  title: T("devportal.myApplications", "My Applications"),
134
134
  description: T("devportal.manageYourApps", "Manage your developer applications"),
135
135
  actions: /* @__PURE__ */ y("button", {
@@ -158,30 +158,30 @@ var S = () => {
158
158
  type: "text",
159
159
  placeholder: T("devportal.searchApplications", "Search applications..."),
160
160
  value: j,
161
- onChange: (e) => M(e.target.value),
161
+ onChange: (e) => de(e.target.value),
162
162
  className: "w-full rounded-md border bg-background pl-9 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary"
163
163
  })]
164
164
  }),
165
165
  /* @__PURE__ */ y("select", {
166
- value: N,
167
- onChange: (e) => P(e.target.value),
166
+ value: M,
167
+ onChange: (e) => N(e.target.value),
168
168
  className: "rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary",
169
169
  children: [/* @__PURE__ */ v("option", {
170
170
  value: "",
171
171
  children: T("devportal.allStatus", "All Status")
172
- }), Object.keys(r).map((e) => /* @__PURE__ */ v("option", {
172
+ }), Object.keys(ne).map((e) => /* @__PURE__ */ v("option", {
173
173
  value: e,
174
174
  children: e.replace(/_/g, " ")
175
175
  }, e))]
176
176
  }),
177
177
  /* @__PURE__ */ y("select", {
178
- value: F,
179
- onChange: (e) => I(e.target.value),
178
+ value: P,
179
+ onChange: (e) => F(e.target.value),
180
180
  className: "rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary",
181
181
  children: [/* @__PURE__ */ v("option", {
182
182
  value: "",
183
183
  children: T("devportal.allTypes", "All Types")
184
- }), Object.entries(ee).map(([e, t]) => /* @__PURE__ */ v("option", {
184
+ }), Object.entries(a).map(([e, t]) => /* @__PURE__ */ v("option", {
185
185
  value: e,
186
186
  children: t
187
187
  }, e))]
@@ -193,21 +193,21 @@ var S = () => {
193
193
  onClick: () => A("grid"),
194
194
  className: `rounded p-1.5 ${k === "grid" ? "bg-muted" : "hover:bg-muted/50"}`,
195
195
  title: "Grid view",
196
- children: /* @__PURE__ */ v(g, { size: 16 })
196
+ children: /* @__PURE__ */ v(h, { size: 16 })
197
197
  }), /* @__PURE__ */ v("button", {
198
198
  onClick: () => A("list"),
199
199
  className: `rounded p-1.5 ${k === "list" ? "bg-muted" : "hover:bg-muted/50"}`,
200
200
  title: "List view",
201
- children: /* @__PURE__ */ v(oe, { size: 16 })
201
+ children: /* @__PURE__ */ v(g, { size: 16 })
202
202
  })]
203
203
  })]
204
204
  }),
205
- V && /* @__PURE__ */ v("div", {
206
- className: `rounded-lg border px-4 py-3 text-sm ${V.type === "success" ? "border-border-subtle bg-status-success-bg-subtle text-status-success-text" : "border-destructive/40 bg-destructive/10 text-destructive"}`,
205
+ B && /* @__PURE__ */ v("div", {
206
+ className: `rounded-lg border px-4 py-3 text-sm ${B.type === "success" ? "border-border-subtle bg-status-success-bg-subtle text-status-success-text" : "border-destructive/40 bg-destructive/10 text-destructive"}`,
207
207
  children: /* @__PURE__ */ y("div", {
208
208
  className: "flex items-center justify-between gap-3",
209
- children: [/* @__PURE__ */ v("span", { children: V.message }), /* @__PURE__ */ v("button", {
210
- onClick: () => H(null),
209
+ children: [/* @__PURE__ */ v("span", { children: B.message }), /* @__PURE__ */ v("button", {
210
+ onClick: () => V(null),
211
211
  className: "text-xs font-medium underline underline-offset-2",
212
212
  children: "Dismiss"
213
213
  })]
@@ -221,7 +221,7 @@ var S = () => {
221
221
  className: "flex flex-wrap items-center gap-3",
222
222
  children: [/* @__PURE__ */ y("div", {
223
223
  className: "flex items-center gap-2",
224
- children: [/* @__PURE__ */ v(i, {
224
+ children: [/* @__PURE__ */ v(re, {
225
225
  checked: Z,
226
226
  indeterminate: me,
227
227
  onChange: he,
@@ -230,7 +230,7 @@ var S = () => {
230
230
  className: "text-sm font-medium",
231
231
  children: "Select all visible"
232
232
  })]
233
- }), L.size > 0 && /* @__PURE__ */ v("button", {
233
+ }), I.size > 0 && /* @__PURE__ */ v("button", {
234
234
  onClick: $,
235
235
  className: "text-sm text-muted-foreground hover:text-foreground",
236
236
  children: "Clear selection"
@@ -240,16 +240,16 @@ var S = () => {
240
240
  children: [
241
241
  /* @__PURE__ */ y("span", {
242
242
  className: "rounded-full bg-muted px-3 py-1 text-sm font-medium text-muted-foreground",
243
- children: [L.size, " selected"]
243
+ children: [I.size, " selected"]
244
244
  }),
245
245
  /* @__PURE__ */ y("button", {
246
- onClick: () => B("deactivate"),
246
+ onClick: () => z("deactivate"),
247
247
  disabled: X.length === 0 || !O.allowed,
248
248
  "aria-disabled": X.length === 0 || !O.allowed,
249
249
  title: O.allowed ? void 0 : T("devportal.common.noPermission", "You do not have permission to perform this action"),
250
250
  className: "inline-flex items-center gap-2 rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text transition-colors hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary",
251
251
  children: [
252
- /* @__PURE__ */ v(h, {
252
+ /* @__PURE__ */ v(m, {
253
253
  size: 16,
254
254
  "aria-hidden": "true"
255
255
  }),
@@ -258,7 +258,7 @@ var S = () => {
258
258
  ]
259
259
  }),
260
260
  /* @__PURE__ */ y("button", {
261
- onClick: () => B("delete"),
261
+ onClick: () => z("delete"),
262
262
  disabled: Y.length === 0 || !D.allowed,
263
263
  "aria-disabled": Y.length === 0 || !D.allowed,
264
264
  title: D.allowed ? void 0 : T("devportal.common.noPermission", "You do not have permission to perform this action"),
@@ -287,40 +287,40 @@ var S = () => {
287
287
  }),
288
288
  J.length > 0 ? k === "grid" ? /* @__PURE__ */ v("div", {
289
289
  className: "grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
290
- children: J.map((e) => /* @__PURE__ */ v(a, {
290
+ children: J.map((e) => /* @__PURE__ */ v(ie, {
291
291
  app: e,
292
- selected: L.has(e.id),
292
+ selected: I.has(e.id),
293
293
  onToggleSelect: (t) => Q(e.id, t)
294
294
  }, e.id))
295
295
  }) : /* @__PURE__ */ v("div", {
296
296
  className: "space-y-2",
297
- children: J.map((e) => /* @__PURE__ */ v(o, {
297
+ children: J.map((e) => /* @__PURE__ */ v(ae, {
298
298
  app: e,
299
- selected: L.has(e.id),
299
+ selected: I.has(e.id),
300
300
  onToggleSelect: (t) => Q(e.id, t)
301
301
  }, e.id))
302
302
  }) : /* @__PURE__ */ v(t, {
303
- icon: /* @__PURE__ */ v(m, { size: 32 }),
303
+ icon: /* @__PURE__ */ v(p, { size: 32 }),
304
304
  title: T("devportal.noApplicationsFound", "No applications found"),
305
- description: j || N || F ? T("devportal.tryAdjustingFilters", "Try adjusting your filters") : T("devportal.createFirstApp", "Create your first application to get started"),
306
- action: !j && !N && !F ? /* @__PURE__ */ y("button", {
305
+ description: j || M || P ? T("devportal.tryAdjustingFilters", "Try adjusting your filters") : T("devportal.createFirstApp", "Create your first application to get started"),
306
+ action: !j && !M && !P ? /* @__PURE__ */ y("button", {
307
307
  onClick: () => q("/apps/new"),
308
308
  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",
309
309
  children: [/* @__PURE__ */ v(_, { size: 16 }), T("devportal.createApp", "Create App")]
310
310
  }) : void 0
311
311
  }),
312
- /* @__PURE__ */ v(s, {
313
- open: z === "deactivate",
312
+ /* @__PURE__ */ v(o, {
313
+ open: R === "deactivate",
314
314
  onOpenChange: (e) => {
315
- e || B(null);
315
+ e || z(null);
316
316
  },
317
317
  onConfirm: async () => {
318
318
  if (X.length === 0) return;
319
- let e = await Promise.allSettled(X.map((e) => pe({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
320
- H({
319
+ let e = await Promise.allSettled(X.map((e) => K({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
320
+ V({
321
321
  type: n === 0 ? "success" : "error",
322
322
  message: b("Deactivated", t, n)
323
- }), $(), B(null), await G();
323
+ }), $(), z(null), await W();
324
324
  },
325
325
  title: "Deactivate selected applications",
326
326
  description: `Deactivate ${X.length} selected application${X.length === 1 ? "" : "s"}? Users and integrations may lose access until these apps are re-enabled.`,
@@ -328,18 +328,18 @@ var S = () => {
328
328
  cancelLabel: "Cancel",
329
329
  variant: "warning"
330
330
  }),
331
- /* @__PURE__ */ v(s, {
332
- open: z === "delete",
331
+ /* @__PURE__ */ v(o, {
332
+ open: R === "delete",
333
333
  onOpenChange: (e) => {
334
- e || B(null);
334
+ e || z(null);
335
335
  },
336
336
  onConfirm: async () => {
337
337
  if (Y.length === 0) return;
338
- let e = await Promise.allSettled(Y.map((e) => fe({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
339
- H({
338
+ let e = await Promise.allSettled(Y.map((e) => pe({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
339
+ V({
340
340
  type: n === 0 ? "success" : "error",
341
341
  message: b("Deleted", t, n)
342
- }), $(), B(null), await G();
342
+ }), $(), z(null), await W();
343
343
  },
344
344
  title: "Delete selected applications",
345
345
  description: `Delete ${Y.length} selected application${Y.length === 1 ? "" : "s"}? This cannot be undone.`,
@@ -352,6 +352,6 @@ var S = () => {
352
352
  });
353
353
  };
354
354
  //#endregion
355
- export { S as ApplicationsPage };
355
+ export { x as ApplicationsPage };
356
356
 
357
357
  //# sourceMappingURL=ApplicationsPage.js.map