@burdenoff/microfe-devportal 2026.717.1 → 2026.720.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/devportal/components/PermissionGuard.d.ts +14 -1
  2. package/dist/devportal/components/PermissionGuard.d.ts.map +1 -1
  3. package/dist/devportal/components/PermissionGuard.js +16 -13
  4. package/dist/devportal/components/PermissionGuard.js.map +1 -1
  5. package/dist/devportal/pages/AdminReviewPage.js +9 -9
  6. package/dist/devportal/pages/ApiKeysPage.js +180 -181
  7. package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
  8. package/dist/devportal/pages/ApplicationDetailPage.js +3 -3
  9. package/dist/devportal/pages/ApplicationVersionsPage.js +4 -4
  10. package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
  11. package/dist/devportal/pages/ApplicationsPage.js +4 -4
  12. package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
  13. package/dist/devportal/pages/CreateApiKeyPage.js +1 -1
  14. package/dist/devportal/pages/CreateOAuthClientPage.js +1 -1
  15. package/dist/devportal/pages/CreateOrganizationPage.d.ts.map +1 -1
  16. package/dist/devportal/pages/CreateOrganizationPage.js +97 -98
  17. package/dist/devportal/pages/CreateOrganizationPage.js.map +1 -1
  18. package/dist/devportal/pages/CreateWebhookPage.js +25 -25
  19. package/dist/devportal/pages/DashboardPage.d.ts.map +1 -1
  20. package/dist/devportal/pages/DashboardPage.js +110 -111
  21. package/dist/devportal/pages/DashboardPage.js.map +1 -1
  22. package/dist/devportal/pages/DelegationsPage.js +1 -1
  23. package/dist/devportal/pages/EditApplicationPage.js +4 -4
  24. package/dist/devportal/pages/ListingPreviewPage.d.ts.map +1 -1
  25. package/dist/devportal/pages/ListingPreviewPage.js +160 -161
  26. package/dist/devportal/pages/ListingPreviewPage.js.map +1 -1
  27. package/dist/devportal/pages/OAuthClientDetailPage.d.ts.map +1 -1
  28. package/dist/devportal/pages/OAuthClientDetailPage.js +166 -167
  29. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  30. package/dist/devportal/pages/OAuthClientsPage.d.ts.map +1 -1
  31. package/dist/devportal/pages/OAuthClientsPage.js +121 -122
  32. package/dist/devportal/pages/OAuthClientsPage.js.map +1 -1
  33. package/dist/devportal/pages/OrganizationDetailPage.js +3 -3
  34. package/dist/devportal/pages/OrganizationMembersPage.js +4 -4
  35. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  36. package/dist/devportal/pages/OrganizationsPage.d.ts.map +1 -1
  37. package/dist/devportal/pages/OrganizationsPage.js +97 -98
  38. package/dist/devportal/pages/OrganizationsPage.js.map +1 -1
  39. package/dist/devportal/pages/PublishPage.js +246 -246
  40. package/dist/devportal/pages/PublishPage.js.map +1 -1
  41. package/dist/devportal/pages/PublisherProfilePage.js +4 -4
  42. package/dist/devportal/pages/PublisherProfilePage.js.map +1 -1
  43. package/dist/devportal/pages/StoreSubmissionPage.js +3 -3
  44. package/dist/devportal/pages/WebhookDetailPage.js +3 -3
  45. package/dist/devportal/pages/WebhooksPage.js +129 -129
  46. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  47. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"OAuthClientDetailPage.js","names":[],"sources":["../../../src/devportal/pages/OAuthClientDetailPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport {\n Copy,\n Eye,\n EyeOff,\n Loader2,\n AlertCircle,\n RefreshCw,\n Trash2,\n ArrowLeft,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n CTAOverflowMenu,\n GlassCard,\n} from \"@burdenoff/fe-libs/ui\";\nimport { useParams } from \"react-router-dom\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { ActiveIndicator } from \"../components/StatusBadge\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport type { AuthApp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport {\n nativeCopyText,\n nativeImpact,\n nativeNotify,\n} from \"../../utils/nativeBridge\";\nimport {\n useGetAuthAppQuery,\n useRotateAppSecretMutation,\n useDeactivateAppMutation,\n useUpdateAuthAppMutation,\n getErrorMessage,\n} from \"../hooks\";\n\n/**\n * OAuth App Detail page\n *\n * Shows details for an auth-svc App (replaces devportal-svc OAuthClient detail).\n * Supports secret rotation, deactivation, and status toggle.\n */\nexport const OAuthClientDetailPage: FC = () => {\n const { clientId: appId } = useParams<{ clientId: string }>();\n const { navigate, basePath } = useDevportal();\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 [showSecret, setShowSecret] = useState(false);\n const [newSecret, setNewSecret] = useState<string | null>(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [confirmRotate, setConfirmRotate] = useState(false);\n\n const { data, loading, error, refetch } = useGetAuthAppQuery({\n variables: { id: appId || \"\" },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const [rotateSecret, { loading: rotating }] = useRotateAppSecretMutation();\n const [deactivateApp, { loading: deactivating }] = useDeactivateAppMutation();\n const [updateApp] = useUpdateAuthAppMutation();\n\n const app: AuthApp | null = data?.app\n ? {\n id: data.app.id,\n name: data.app.name,\n description: data.app.description ?? undefined,\n clientId: data.app.clientId,\n type: data.app.type as AuthApp[\"type\"],\n status: data.app.status as AuthApp[\"status\"],\n scopes: data.app.scopes ?? [],\n redirectUris: data.app.redirectUris ?? [],\n ownerUserId: data.app.ownerUserId,\n tenantId: data.app.tenantId,\n createdAt: data.app.createdAt,\n updatedAt: data.app.updatedAt,\n }\n : null;\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const handleCopy = async (text: string) => {\n void nativeImpact(\"light\");\n const ok = await nativeCopyText(text);\n void nativeNotify(ok ? \"success\" : \"error\");\n };\n\n const handleRotateSecret = async () => {\n if (!appId) return;\n try {\n const result = await rotateSecret({ variables: { id: appId } });\n const secret = result.data?.rotateAppSecret?.clientSecret;\n if (secret) {\n setNewSecret(secret);\n setShowSecret(true);\n }\n setConfirmRotate(false);\n refetch();\n } catch {\n // error handled by Apollo\n }\n };\n\n const handleDeactivate = async () => {\n if (!appId) return;\n try {\n await deactivateApp({ variables: { id: appId } });\n setConfirmDelete(false);\n handleNavigate(\"/oauth\");\n } catch {\n // error handled by Apollo\n }\n };\n\n const handleToggleStatus = async () => {\n if (!appId || !app) return;\n const newStatus = app.status === \"ACTIVE\" ? \"INACTIVE\" : \"ACTIVE\";\n try {\n await updateApp({\n variables: { id: appId, input: { status: newStatus } },\n });\n refetch();\n } catch {\n // error handled by Apollo\n }\n };\n\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\"devportal.appDetails\", \"App Details\")}\n description={tr(\"devportal.loadingDots\", \"Loading...\")}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !app) {\n return (\n <PageLayout\n title={tr(\"devportal.appDetails\", \"App Details\")}\n description={tr(\"devportal.failedToLoad\", \"Failed to load\")}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {error\n ? tr(\"devportal.failedToLoadApp\", \"Failed to load app\")\n : tr(\"devportal.appNotFound\", \"App not found\")}\n </h3>\n {error && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n )}\n <button\n onClick={() => handleNavigate(\"/oauth\")}\n className=\"mt-4 inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <ArrowLeft size={16} />\n {tr(\"devportal.backToApps\", \"Back to Apps\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.APP_READ}>\n <PageLayout\n title={app.name}\n description={\n app.description ||\n tr(\n \"devportal.oauthAppDetailsAndCredentials\",\n \"OAuth App details and credentials\",\n )\n }\n purpose={tr(\n \"devportal.oauthAppDetailPurpose\",\n \"These are this OAuth app's credentials and the scopes it may request. Copy the client ID for your integration, rotate the secret if it leaks, and keep scopes minimal so users only grant what the app truly needs.\",\n )}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n actions={\n <CTAOverflowMenu\n primary={{\n label:\n app.status === \"ACTIVE\"\n ? tr(\"devportal.deactivate\", \"Deactivate\")\n : tr(\"devportal.activate\", \"Activate\"),\n onSelect: handleToggleStatus,\n }}\n actions={[\n {\n label: tr(\"devportal.delete\", \"Delete\"),\n icon: <Trash2 size={16} />,\n intent: \"destructive\",\n onSelect: () => setConfirmDelete(true),\n },\n ]}\n />\n }\n >\n {/* Status & Type */}\n <div className=\"grid gap-6 md:grid-cols-2\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">\n {tr(\"devportal.statusAndConfiguration\", \"Status & Configuration\")}\n </h3>\n <div className=\"space-y-3\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.status\", \"Status\")}\n </span>\n <div className=\"flex items-center gap-2\">\n <ActiveIndicator active={app.status === \"ACTIVE\"} />\n <span className=\"text-sm font-medium\">{app.status}</span>\n </div>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.type\", \"Type\")}\n </span>\n <span\n className={cn(\n \"rounded px-2 py-0.5 text-xs font-medium\",\n app.type === \"SERVICE\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : app.type === \"INTEGRATION\" ||\n app.type === \"API_INTEGRATION\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : \"bg-status-success-bg-subtle text-status-success-text\",\n )}\n >\n {app.type}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.created\", \"Created\")}\n </span>\n <span className=\"text-sm\">\n {new Date(app.createdAt).toLocaleDateString()}\n </span>\n </div>\n </div>\n </div>\n\n {/* Credentials — primary emphasis zone */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">\n {tr(\"devportal.credentials\", \"Credentials\")}\n </h3>\n <div className=\"space-y-3\">\n <div>\n <label className=\"text-xs text-text-secondary\">\n {tr(\"devportal.clientId\", \"Client ID\")}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {app.clientId}\n </code>\n <button\n onClick={() => handleCopy(app.clientId)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n title=\"Copy\"\n >\n <Copy size={14} />\n </button>\n </div>\n </div>\n {newSecret && (\n <div>\n <label className=\"text-xs text-status-error-text font-medium\">\n {tr(\n \"devportal.newClientSecretShownOnce\",\n \"New Client Secret (shown only once!)\",\n )}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-status-error-bg/10 border border-status-error-border/30 px-3 py-1.5 text-sm font-mono\">\n {showSecret\n ? newSecret\n : \"\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\"}\n </code>\n <button\n onClick={() => setShowSecret(!showSecret)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n >\n {showSecret ? <EyeOff size={14} /> : <Eye size={14} />}\n </button>\n <button\n onClick={() => handleCopy(newSecret)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n >\n <Copy size={14} />\n </button>\n </div>\n </div>\n )}\n <button\n onClick={() => setConfirmRotate(true)}\n disabled={rotating}\n className=\"mt-2 inline-flex items-center gap-2 rounded-md bg-status-warning-bg-subtle px-3 py-1.5 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle transition-colors disabled:opacity-50\"\n >\n <RefreshCw\n size={14}\n className={rotating ? \"animate-spin\" : \"\"}\n />\n {tr(\"devportal.rotateSecret\", \"Rotate Secret\")}\n </button>\n </div>\n </GlassCard>\n </div>\n\n {/* Scopes */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-3\">\n {tr(\"devportal.scopes\", \"Scopes\")} ({app.scopes.length})\n </h3>\n {app.scopes.length > 0 ? (\n <div className=\"flex flex-wrap gap-2\">\n {app.scopes.map((scope) => (\n <span\n key={scope}\n className=\"rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary\"\n >\n {scope}\n </span>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.noScopesConfigured\", \"No scopes configured\")}\n </p>\n )}\n </div>\n\n {/* Redirect URIs */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-3\">\n {tr(\"devportal.redirectUris\", \"Redirect URIs\")} (\n {app.redirectUris.length})\n </h3>\n {app.redirectUris.length > 0 ? (\n <div className=\"space-y-2\">\n {app.redirectUris.map((uri) => (\n <div key={uri} className=\"flex items-center gap-2\">\n <code className=\"rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {uri}\n </code>\n <button\n onClick={() => handleCopy(uri)}\n className=\"rounded p-1 hover:bg-bg-sunken transition-colors\"\n >\n <Copy size={12} />\n </button>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.noRedirectUrisConfigured\",\n \"No redirect URIs configured\",\n )}\n </p>\n )}\n </div>\n\n {/* Confirm Rotate Dialog */}\n <AlertDialog open={confirmRotate} onOpenChange={setConfirmRotate}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {tr(\n \"devportal.rotateClientSecretQuestion\",\n \"Rotate Client Secret?\",\n )}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tr(\n \"devportal.rotateSecretWarning\",\n \"This will invalidate the current client secret. All integrations using the old secret will stop working immediately.\",\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={rotating}>\n {tr(\"devportal.cancel\", \"Cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault();\n void handleRotateSecret();\n }}\n disabled={rotating}\n className=\"bg-status-warning-bg text-white hover:bg-status-warning-bg/90\"\n >\n {rotating\n ? tr(\"devportal.rotating\", \"Rotating...\")\n : tr(\"devportal.rotateSecret\", \"Rotate Secret\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {/* Confirm Deactivate Dialog */}\n <AlertDialog open={confirmDelete} onOpenChange={setConfirmDelete}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle className=\"text-status-error-text\">\n {tr(\"devportal.deactivateAppQuestion\", \"Deactivate App?\")}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tr(\n \"devportal.deactivateAppWarning\",\n \"This will deactivate the app and revoke all tokens. This action cannot be undone easily.\",\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deactivating}>\n {tr(\"devportal.cancel\", \"Cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault();\n void handleDeactivate();\n }}\n disabled={deactivating}\n className=\"bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90\"\n >\n {deactivating\n ? tr(\"devportal.deactivating\", \"Deactivating...\")\n : tr(\"devportal.deactivate\", \"Deactivate\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OAuthClientDetailPage.js","names":[],"sources":["../../../src/devportal/pages/OAuthClientDetailPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport {\n Copy,\n Eye,\n EyeOff,\n Loader2,\n AlertCircle,\n RefreshCw,\n Trash2,\n ArrowLeft,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n CTAOverflowMenu,\n GlassCard,\n} from \"@burdenoff/fe-libs/ui\";\nimport { useParams } from \"react-router-dom\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { ActiveIndicator } from \"../components/StatusBadge\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport type { AuthApp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport {\n nativeCopyText,\n nativeImpact,\n nativeNotify,\n} from \"../../utils/nativeBridge\";\nimport {\n useGetAuthAppQuery,\n useRotateAppSecretMutation,\n useDeactivateAppMutation,\n useUpdateAuthAppMutation,\n getErrorMessage,\n} from \"../hooks\";\n\n/**\n * OAuth App Detail page\n *\n * Shows details for an auth-svc App (replaces devportal-svc OAuthClient detail).\n * Supports secret rotation, deactivation, and status toggle.\n */\nexport const OAuthClientDetailPage: FC = () => {\n const { clientId: appId } = useParams<{ clientId: string }>();\n const { navigate, basePath } = useDevportal();\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 [showSecret, setShowSecret] = useState(false);\n const [newSecret, setNewSecret] = useState<string | null>(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [confirmRotate, setConfirmRotate] = useState(false);\n\n const { data, loading, error, refetch } = useGetAuthAppQuery({\n variables: { id: appId || \"\" },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const [rotateSecret, { loading: rotating }] = useRotateAppSecretMutation();\n const [deactivateApp, { loading: deactivating }] = useDeactivateAppMutation();\n const [updateApp] = useUpdateAuthAppMutation();\n\n const app: AuthApp | null = data?.app\n ? {\n id: data.app.id,\n name: data.app.name,\n description: data.app.description ?? undefined,\n clientId: data.app.clientId,\n type: data.app.type as AuthApp[\"type\"],\n status: data.app.status as AuthApp[\"status\"],\n scopes: data.app.scopes ?? [],\n redirectUris: data.app.redirectUris ?? [],\n ownerUserId: data.app.ownerUserId,\n tenantId: data.app.tenantId,\n createdAt: data.app.createdAt,\n updatedAt: data.app.updatedAt,\n }\n : null;\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const handleCopy = async (text: string) => {\n void nativeImpact(\"light\");\n const ok = await nativeCopyText(text);\n void nativeNotify(ok ? \"success\" : \"error\");\n };\n\n const handleRotateSecret = async () => {\n if (!appId) return;\n try {\n const result = await rotateSecret({ variables: { id: appId } });\n const secret = result.data?.rotateAppSecret?.clientSecret;\n if (secret) {\n setNewSecret(secret);\n setShowSecret(true);\n }\n setConfirmRotate(false);\n refetch();\n } catch {\n // error handled by Apollo\n }\n };\n\n const handleDeactivate = async () => {\n if (!appId) return;\n try {\n await deactivateApp({ variables: { id: appId } });\n setConfirmDelete(false);\n handleNavigate(\"/oauth\");\n } catch {\n // error handled by Apollo\n }\n };\n\n const handleToggleStatus = async () => {\n if (!appId || !app) return;\n const newStatus = app.status === \"ACTIVE\" ? \"INACTIVE\" : \"ACTIVE\";\n try {\n await updateApp({\n variables: { id: appId, input: { status: newStatus } },\n });\n refetch();\n } catch {\n // error handled by Apollo\n }\n };\n\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\"devportal.appDetails\", \"App Details\")}\n description={tr(\"devportal.loadingDots\", \"Loading...\")}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !app) {\n return (\n <PageLayout\n title={tr(\"devportal.appDetails\", \"App Details\")}\n description={tr(\"devportal.failedToLoad\", \"Failed to load\")}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {error\n ? tr(\"devportal.failedToLoadApp\", \"Failed to load app\")\n : tr(\"devportal.appNotFound\", \"App not found\")}\n </h3>\n {error && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n )}\n <button\n onClick={() => handleNavigate(\"/oauth\")}\n className=\"mt-4 inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <ArrowLeft size={16} />\n {tr(\"devportal.backToApps\", \"Back to Apps\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={app.name}\n description={\n app.description ||\n tr(\n \"devportal.oauthAppDetailsAndCredentials\",\n \"OAuth App details and credentials\",\n )\n }\n purpose={tr(\n \"devportal.oauthAppDetailPurpose\",\n \"These are this OAuth app's credentials and the scopes it may request. Copy the client ID for your integration, rotate the secret if it leaks, and keep scopes minimal so users only grant what the app truly needs.\",\n )}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n actions={\n <CTAOverflowMenu\n primary={{\n label:\n app.status === \"ACTIVE\"\n ? tr(\"devportal.deactivate\", \"Deactivate\")\n : tr(\"devportal.activate\", \"Activate\"),\n onSelect: handleToggleStatus,\n }}\n actions={[\n {\n label: tr(\"devportal.delete\", \"Delete\"),\n icon: <Trash2 size={16} />,\n intent: \"destructive\",\n onSelect: () => setConfirmDelete(true),\n },\n ]}\n />\n }\n >\n {/* Status & Type */}\n <div className=\"grid gap-6 md:grid-cols-2\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">\n {tr(\"devportal.statusAndConfiguration\", \"Status & Configuration\")}\n </h3>\n <div className=\"space-y-3\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.status\", \"Status\")}\n </span>\n <div className=\"flex items-center gap-2\">\n <ActiveIndicator active={app.status === \"ACTIVE\"} />\n <span className=\"text-sm font-medium\">{app.status}</span>\n </div>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.type\", \"Type\")}\n </span>\n <span\n className={cn(\n \"rounded px-2 py-0.5 text-xs font-medium\",\n app.type === \"SERVICE\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : app.type === \"INTEGRATION\" ||\n app.type === \"API_INTEGRATION\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : \"bg-status-success-bg-subtle text-status-success-text\",\n )}\n >\n {app.type}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.created\", \"Created\")}\n </span>\n <span className=\"text-sm\">\n {new Date(app.createdAt).toLocaleDateString()}\n </span>\n </div>\n </div>\n </div>\n\n {/* Credentials — primary emphasis zone */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">\n {tr(\"devportal.credentials\", \"Credentials\")}\n </h3>\n <div className=\"space-y-3\">\n <div>\n <label className=\"text-xs text-text-secondary\">\n {tr(\"devportal.clientId\", \"Client ID\")}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {app.clientId}\n </code>\n <button\n onClick={() => handleCopy(app.clientId)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n title=\"Copy\"\n >\n <Copy size={14} />\n </button>\n </div>\n </div>\n {newSecret && (\n <div>\n <label className=\"text-xs text-status-error-text font-medium\">\n {tr(\n \"devportal.newClientSecretShownOnce\",\n \"New Client Secret (shown only once!)\",\n )}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-status-error-bg/10 border border-status-error-border/30 px-3 py-1.5 text-sm font-mono\">\n {showSecret\n ? newSecret\n : \"\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\"}\n </code>\n <button\n onClick={() => setShowSecret(!showSecret)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n >\n {showSecret ? <EyeOff size={14} /> : <Eye size={14} />}\n </button>\n <button\n onClick={() => handleCopy(newSecret)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n >\n <Copy size={14} />\n </button>\n </div>\n </div>\n )}\n <button\n onClick={() => setConfirmRotate(true)}\n disabled={rotating}\n className=\"mt-2 inline-flex items-center gap-2 rounded-md bg-status-warning-bg-subtle px-3 py-1.5 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle transition-colors disabled:opacity-50\"\n >\n <RefreshCw\n size={14}\n className={rotating ? \"animate-spin\" : \"\"}\n />\n {tr(\"devportal.rotateSecret\", \"Rotate Secret\")}\n </button>\n </div>\n </GlassCard>\n </div>\n\n {/* Scopes */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-3\">\n {tr(\"devportal.scopes\", \"Scopes\")} ({app.scopes.length})\n </h3>\n {app.scopes.length > 0 ? (\n <div className=\"flex flex-wrap gap-2\">\n {app.scopes.map((scope) => (\n <span\n key={scope}\n className=\"rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary\"\n >\n {scope}\n </span>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.noScopesConfigured\", \"No scopes configured\")}\n </p>\n )}\n </div>\n\n {/* Redirect URIs */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-3\">\n {tr(\"devportal.redirectUris\", \"Redirect URIs\")} (\n {app.redirectUris.length})\n </h3>\n {app.redirectUris.length > 0 ? (\n <div className=\"space-y-2\">\n {app.redirectUris.map((uri) => (\n <div key={uri} className=\"flex items-center gap-2\">\n <code className=\"rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {uri}\n </code>\n <button\n onClick={() => handleCopy(uri)}\n className=\"rounded p-1 hover:bg-bg-sunken transition-colors\"\n >\n <Copy size={12} />\n </button>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.noRedirectUrisConfigured\",\n \"No redirect URIs configured\",\n )}\n </p>\n )}\n </div>\n\n {/* Confirm Rotate Dialog */}\n <AlertDialog open={confirmRotate} onOpenChange={setConfirmRotate}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {tr(\n \"devportal.rotateClientSecretQuestion\",\n \"Rotate Client Secret?\",\n )}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tr(\n \"devportal.rotateSecretWarning\",\n \"This will invalidate the current client secret. All integrations using the old secret will stop working immediately.\",\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={rotating}>\n {tr(\"devportal.cancel\", \"Cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault();\n void handleRotateSecret();\n }}\n disabled={rotating}\n className=\"bg-status-warning-bg text-white hover:bg-status-warning-bg/90\"\n >\n {rotating\n ? tr(\"devportal.rotating\", \"Rotating...\")\n : tr(\"devportal.rotateSecret\", \"Rotate Secret\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {/* Confirm Deactivate Dialog */}\n <AlertDialog open={confirmDelete} onOpenChange={setConfirmDelete}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle className=\"text-status-error-text\">\n {tr(\"devportal.deactivateAppQuestion\", \"Deactivate App?\")}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tr(\n \"devportal.deactivateAppWarning\",\n \"This will deactivate the app and revoke all tokens. This action cannot be undone easily.\",\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deactivating}>\n {tr(\"devportal.cancel\", \"Cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault();\n void handleDeactivate();\n }}\n disabled={deactivating}\n className=\"bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90\"\n >\n {deactivating\n ? tr(\"devportal.deactivating\", \"Deactivating...\")\n : tr(\"devportal.deactivate\", \"Deactivate\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAmDA,IAAa,UAAkC;CAC7C,IAAM,EAAE,UAAU,MAAU,GAAiC,EACvD,EAAE,aAAU,gBAAa,GAAc,EACvC,EAAE,SAAM,IAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAQ,EAAE,EAAI;AACpB,SAAO,MAAU,IAAM,IAAW;IAE9B,CAAC,GAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,GAAW,KAAgB,EAAwB,KAAK,EACzD,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAe,KAAoB,EAAS,GAAM,EAEnD,EAAE,SAAM,YAAS,UAAO,eAAY,EAAmB;EAC3D,WAAW,EAAE,IAAI,KAAS,IAAI;EAC9B,MAAM,CAAC;EACP,aAAa;EACd,CAAC,EAEI,CAAC,GAAc,EAAE,SAAS,OAAc,GAA4B,EACpE,CAAC,GAAe,EAAE,SAAS,OAAkB,GAA0B,EACvE,CAAC,MAAa,GAA0B,EAExC,IAAsB,GAAM,MAC9B;EACE,IAAI,EAAK,IAAI;EACb,MAAM,EAAK,IAAI;EACf,aAAa,EAAK,IAAI,eAAe,KAAA;EACrC,UAAU,EAAK,IAAI;EACnB,MAAM,EAAK,IAAI;EACf,QAAQ,EAAK,IAAI;EACjB,QAAQ,EAAK,IAAI,UAAU,EAAE;EAC7B,cAAc,EAAK,IAAI,gBAAgB,EAAE;EACzC,aAAa,EAAK,IAAI;EACtB,UAAU,EAAK,IAAI;EACnB,WAAW,EAAK,IAAI;EACpB,WAAW,EAAK,IAAI;EACrB,GACD,MAEE,KAAkB,MAAiB;AACvC,MAAW,GAAG,IAAW,IAAO;IAG5B,IAAa,OAAO,MAAiB;AAGpC,EAFA,EAAa,QAAQ,EAErB,EADM,MAAM,EAAe,EAAK,GACd,YAAY,QAAQ;IAGvC,KAAqB,YAAY;AAChC,QACL,KAAI;GAEF,IAAM,KADS,MAAM,EAAa,EAAE,WAAW,EAAE,IAAI,GAAO,EAAE,CAAC,EACzC,MAAM,iBAAiB;AAM7C,GALI,MACF,EAAa,EAAO,EACpB,EAAc,GAAK,GAErB,EAAiB,GAAM,EACvB,GAAS;UACH;IAKJ,KAAmB,YAAY;AAC9B,QACL,KAAI;AAGF,GAFA,MAAM,EAAc,EAAE,WAAW,EAAE,IAAI,GAAO,EAAE,CAAC,EACjD,EAAiB,GAAM,EACvB,EAAe,SAAS;UAClB;;AAiEV,QA/CI,KAAW,CAAC,IAEZ,kBAAC,GAAD;EACE,OAAO,EAAG,wBAAwB,cAAc;EAChD,aAAa,EAAG,yBAAyB,aAAa;EACtD,UAAS;EACT,WAAW,EAAG,wBAAwB,eAAe;YAErD,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA;GAC5D,CAAA;EACK,CAAA,GAIb,KAAS,CAAC,IAEV,kBAAC,GAAD;EACE,OAAO,EAAG,wBAAwB,cAAc;EAChD,aAAa,EAAG,0BAA0B,iBAAiB;EAC3D,UAAS;EACT,WAAW,EAAG,wBAAwB,eAAe;YAErD,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,IAAD,EAAa,WAAU,0CAA2C,CAAA;IAClE,kBAAC,MAAD;KAAI,WAAU;eACX,IACG,EAAG,6BAA6B,qBAAqB,GACrD,EAAG,yBAAyB,gBAAgB;KAC7C,CAAA;IACJ,KACC,kBAAC,KAAD;KAAG,WAAU;eACV,GAAgB,EAAM;KACrB,CAAA;IAEN,kBAAC,UAAD;KACE,eAAe,EAAe,SAAS;KACvC,WAAU;eAFZ,CAIE,kBAAC,IAAD,EAAW,MAAM,IAAM,CAAA,EACtB,EAAG,wBAAwB,eAAe,CACpC;;IACL;;EACK,CAAA,GAKf,kBAAC,IAAD;EAAiB,UAAA;YACf,kBAAC,GAAD;GACE,OAAO,EAAI;GACX,aACE,EAAI,eACJ,EACE,2CACA,oCACD;GAEH,SAAS,EACP,mCACA,sNACD;GACD,UAAS;GACT,WAAW,EAAG,wBAAwB,eAAe;GACrD,SACE,kBAAC,GAAD;IACE,SAAS;KACP,OACE,EAAI,WAAW,WACX,EAAG,wBAAwB,aAAa,GACxC,EAAG,sBAAsB,WAAW;KAC1C,UApFe,YAAY;AACrC,UAAI,CAAC,KAAS,CAAC,EAAK;MACpB,IAAM,IAAY,EAAI,WAAW,WAAW,aAAa;AACzD,UAAI;AAIF,OAHA,MAAM,GAAU,EACd,WAAW;QAAE,IAAI;QAAO,OAAO,EAAE,QAAQ,GAAW;QAAE,EACvD,CAAC,EACF,GAAS;cACH;;KA6EC;IACD,SAAS,CACP;KACE,OAAO,EAAG,oBAAoB,SAAS;KACvC,MAAM,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;KAC1B,QAAQ;KACR,gBAAgB,EAAiB,GAAK;KACvC,CACF;IACD,CAAA;aAhCN;IAoCE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,oCAAoC,yBAAyB;OAC9D,CAAA,EACL,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAG,oBAAoB,SAAS;UAC5B,CAAA,EACP,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,IAAD,EAAiB,QAAQ,EAAI,WAAW,UAAY,CAAA,EACpD,kBAAC,QAAD;WAAM,WAAU;qBAAuB,EAAI;WAAc,CAAA,CACrD;YACF;;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAG,kBAAkB,OAAO;UACxB,CAAA,EACP,kBAAC,QAAD;UACE,WAAW,EACT,2CACA,EAAI,SAAS,YACT,+CACA,EAAI,SAAS,iBACX,EAAI,SAAS,oBACb,mDACA,uDACP;oBAEA,EAAI;UACA,CAAA,CACH;;QACN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAG,qBAAqB,UAAU;UAC9B,CAAA,EACP,kBAAC,QAAD;UAAM,WAAU;oBACb,IAAI,KAAK,EAAI,UAAU,CAAC,oBAAoB;UACxC,CAAA,CACH;;QACF;SACF;SAGN,kBAAC,GAAD;MAAW,WAAU;MAAQ,MAAA;MAAK,WAAU;gBAA5C,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,yBAAyB,cAAc;OACxC,CAAA,EACL,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,WAAU;mBACd,EAAG,sBAAsB,YAAY;SAChC,CAAA,EACR,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAI;UACA,CAAA,EACP,kBAAC,UAAD;UACE,eAAe,EAAW,EAAI,SAAS;UACvC,WAAU;UACV,OAAM;oBAEN,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;UACX,CAAA,CACL;WACF,EAAA,CAAA;QACL,KACC,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,WAAU;mBACd,EACC,sCACA,uCACD;SACK,CAAA,EACR,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,QAAD;WAAM,WAAU;qBACb,IACG,IACA;WACC,CAAA;UACP,kBAAC,UAAD;WACE,eAAe,EAAc,CAAC,EAAW;WACzC,WAAU;qBAEI,EAAb,IAAc,IAAuB,GAAxB,EAAQ,MAAM,IAAM,CAAoB;WAC/C,CAAA;UACT,kBAAC,UAAD;WACE,eAAe,EAAW,EAAU;WACpC,WAAU;qBAEV,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;WACX,CAAA;UACL;WACF,EAAA,CAAA;QAER,kBAAC,UAAD;SACE,eAAe,EAAiB,GAAK;SACrC,UAAU;SACV,WAAU;mBAHZ,CAKE,kBAAC,GAAD;UACE,MAAM;UACN,WAAW,IAAW,iBAAiB;UACvC,CAAA,EACD,EAAG,0BAA0B,gBAAgB,CACvC;;QACL;SACI;QACR;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACG,EAAG,oBAAoB,SAAS;OAAC;OAAG,EAAI,OAAO;OAAO;OACpD;SACJ,EAAI,OAAO,SAAS,IACnB,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAI,OAAO,KAAK,MACf,kBAAC,QAAD;OAEE,WAAU;iBAET;OACI,EAJA,EAIA,CACP;MACE,CAAA,GAEN,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAG,gCAAgC,uBAAuB;MACzD,CAAA,CAEF;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACG,EAAG,0BAA0B,gBAAgB;OAAC;OAC9C,EAAI,aAAa;OAAO;OACtB;SACJ,EAAI,aAAa,SAAS,IACzB,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAI,aAAa,KAAK,MACrB,kBAAC,OAAD;OAAe,WAAU;iBAAzB,CACE,kBAAC,QAAD;QAAM,WAAU;kBACb;QACI,CAAA,EACP,kBAAC,UAAD;QACE,eAAe,EAAW,EAAI;QAC9B,WAAU;kBAEV,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;QACX,CAAA,CACL;SAVI,EAUJ,CACN;MACE,CAAA,GAEN,kBAAC,KAAD;MAAG,WAAU;gBACV,EACC,sCACA,8BACD;MACC,CAAA,CAEF;;IAGN,kBAAC,GAAD;KAAa,MAAM;KAAe,cAAc;eAC9C,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACG,EACC,wCACA,wBACD,EACgB,CAAA,EACnB,kBAAC,GAAD,EAAA,UACG,EACC,iCACA,uHACD,EACsB,CAAA,CACP,EAAA,CAAA,EACpB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAmB,UAAU;gBAC1B,EAAG,oBAAoB,SAAS;MACf,CAAA,EACpB,kBAAC,GAAD;MACE,UAAU,MAAM;AAET,OADL,EAAE,gBAAgB,EACb,IAAoB;;MAE3B,UAAU;MACV,WAAU;gBAET,IACG,EAAG,sBAAsB,cAAc,GACvC,EAAG,0BAA0B,gBAAgB;MAC/B,CAAA,CACF,EAAA,CAAA,CACD,EAAA,CAAA;KACT,CAAA;IAGd,kBAAC,GAAD;KAAa,MAAM;KAAe,cAAc;eAC9C,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAkB,WAAU;gBACzB,EAAG,mCAAmC,kBAAkB;MACxC,CAAA,EACnB,kBAAC,GAAD,EAAA,UACG,EACC,kCACA,2FACD,EACsB,CAAA,CACP,EAAA,CAAA,EACpB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAmB,UAAU;gBAC1B,EAAG,oBAAoB,SAAS;MACf,CAAA,EACpB,kBAAC,GAAD;MACE,UAAU,MAAM;AAET,OADL,EAAE,gBAAgB,EACb,IAAkB;;MAEzB,UAAU;MACV,WAAU;gBAET,IACG,EAAG,0BAA0B,kBAAkB,GAC/C,EAAG,wBAAwB,aAAa;MAC1B,CAAA,CACF,EAAA,CAAA,CACD,EAAA,CAAA;KACT,CAAA;IACH;;EACG,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"OAuthClientsPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OAuthClientsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAgBhC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,EA2V9B,CAAC"}
1
+ {"version":3,"file":"OAuthClientsPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OAuthClientsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAehC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,EA2V9B,CAAC"}
@@ -8,19 +8,18 @@ import { ActiveIndicator as o } from "../components/StatusBadge.js";
8
8
  import { DataTable as s } from "../components/DataTable.js";
9
9
  import { PermissionGuard as c } from "../components/PermissionGuard.js";
10
10
  import "../components/index.js";
11
- import { DEVPORTAL_PERMISSIONS as l } from "../constants/permissions.js";
12
11
  import "../hooks/index.js";
13
- import { useState as u } from "react";
14
- import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
- import { AlertCircle as f, Loader2 as p, Plus as m, Search as h, Shield as g } from "lucide-react";
16
- import { jsx as _, jsxs as v } from "react/jsx-runtime";
17
- import { EmphasisPanel as y, GlassCard as b } from "@burdenoff/fe-libs/ui";
12
+ import { useState as l } from "react";
13
+ import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
+ import { AlertCircle as d, Loader2 as f, Plus as p, Search as m, Shield as h } from "lucide-react";
15
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
16
+ import { EmphasisPanel as v, GlassCard as y } from "@burdenoff/fe-libs/ui";
18
17
  //#region src/devportal/pages/OAuthClientsPage.tsx
19
- var x = () => {
20
- let { navigate: x, basePath: S } = e(), { t: C } = d(), w = (e, t) => {
21
- let n = C(e);
18
+ var b = () => {
19
+ let { navigate: b, basePath: x } = e(), { t: S } = u(), C = (e, t) => {
20
+ let n = S(e);
22
21
  return n === e ? t : n;
23
- }, [T, E] = u(""), [D, O] = u(""), { data: k, loading: A, error: j, refetch: M } = r({ fetchPolicy: "cache-and-network" }), N = k?.currentUserApps?.apps.map((e) => ({
22
+ }, [w, T] = l(""), [E, D] = l(""), { data: O, loading: k, error: A, refetch: j } = r({ fetchPolicy: "cache-and-network" }), M = O?.currentUserApps?.apps.map((e) => ({
24
23
  id: e.id,
25
24
  name: e.name,
26
25
  description: e.description ?? void 0,
@@ -33,65 +32,65 @@ var x = () => {
33
32
  tenantId: e.tenantId ?? "",
34
33
  createdAt: e.createdAt,
35
34
  updatedAt: e.updatedAt
36
- })) ?? [], P = (e) => {
37
- x?.(`${S}${e}`);
38
- }, F = N.filter((e) => {
39
- let t = !T || e.name.toLowerCase().includes(T.toLowerCase()) || e.clientId.toLowerCase().includes(T.toLowerCase()), n = !D || e.type === D;
35
+ })) ?? [], N = (e) => {
36
+ b?.(`${x}${e}`);
37
+ }, P = M.filter((e) => {
38
+ let t = !w || e.name.toLowerCase().includes(w.toLowerCase()) || e.clientId.toLowerCase().includes(w.toLowerCase()), n = !E || e.type === E;
40
39
  return t && n;
41
40
  });
42
- if (A && !k) return /* @__PURE__ */ _(a, {
43
- title: w("devportal.oauthApps", "OAuth Apps"),
44
- description: w("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
45
- children: /* @__PURE__ */ v("div", {
41
+ if (k && !O) return /* @__PURE__ */ g(a, {
42
+ title: C("devportal.oauthApps", "OAuth Apps"),
43
+ description: C("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
44
+ children: /* @__PURE__ */ _("div", {
46
45
  className: "flex items-center justify-center py-12",
47
- children: [/* @__PURE__ */ _(p, { className: "h-8 w-8 animate-spin text-text-secondary" }), /* @__PURE__ */ _("span", {
46
+ children: [/* @__PURE__ */ g(f, { className: "h-8 w-8 animate-spin text-text-secondary" }), /* @__PURE__ */ g("span", {
48
47
  className: "ml-2 text-text-secondary",
49
- children: w("devportal.loadingApps", "Loading apps...")
48
+ children: C("devportal.loadingApps", "Loading apps...")
50
49
  })]
51
50
  })
52
51
  });
53
- if (j) return /* @__PURE__ */ _(a, {
54
- title: w("devportal.oauthApps", "OAuth Apps"),
55
- description: w("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
56
- children: /* @__PURE__ */ v("div", {
52
+ if (A) return /* @__PURE__ */ g(a, {
53
+ title: C("devportal.oauthApps", "OAuth Apps"),
54
+ description: C("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
55
+ children: /* @__PURE__ */ _("div", {
57
56
  className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center",
58
57
  children: [
59
- /* @__PURE__ */ _(f, { className: "mx-auto h-8 w-8 text-status-error-text" }),
60
- /* @__PURE__ */ _("h3", {
58
+ /* @__PURE__ */ g(d, { className: "mx-auto h-8 w-8 text-status-error-text" }),
59
+ /* @__PURE__ */ g("h3", {
61
60
  className: "mt-2 font-medium text-status-error-text",
62
- children: w("devportal.failedToLoadApps", "Failed to load apps")
61
+ children: C("devportal.failedToLoadApps", "Failed to load apps")
63
62
  }),
64
- /* @__PURE__ */ _("p", {
63
+ /* @__PURE__ */ g("p", {
65
64
  className: "mt-1 text-sm text-text-secondary",
66
- children: i(j)
65
+ children: i(A)
67
66
  }),
68
- /* @__PURE__ */ _("button", {
69
- onClick: () => M(),
67
+ /* @__PURE__ */ g("button", {
68
+ onClick: () => j(),
70
69
  className: "mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
71
- children: w("devportal.tryAgain", "Try Again")
70
+ children: C("devportal.tryAgain", "Try Again")
72
71
  })
73
72
  ]
74
73
  })
75
74
  });
76
- let I = [
75
+ let F = [
77
76
  {
78
77
  key: "name",
79
78
  header: "App",
80
- render: (e) => /* @__PURE__ */ v("div", {
79
+ render: (e) => /* @__PURE__ */ _("div", {
81
80
  className: "flex items-center gap-3",
82
- children: [/* @__PURE__ */ _("div", {
81
+ children: [/* @__PURE__ */ g("div", {
83
82
  className: t("flex h-10 w-10 items-center justify-center rounded-lg", e.status === "ACTIVE" ? "bg-action-primary-bg/10 text-primary" : "bg-bg-sunken text-text-tertiary"),
84
- children: /* @__PURE__ */ _(g, { size: 20 })
85
- }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ v("div", {
83
+ children: /* @__PURE__ */ g(h, { size: 20 })
84
+ }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("div", {
86
85
  className: "flex items-center gap-2",
87
- children: [/* @__PURE__ */ _("p", {
86
+ children: [/* @__PURE__ */ g("p", {
88
87
  className: "font-medium",
89
88
  children: e.name
90
- }), /* @__PURE__ */ _("span", {
89
+ }), /* @__PURE__ */ g("span", {
91
90
  className: t("rounded px-1.5 py-0.5 text-xs", e.type === "SERVICE" ? "bg-accent-purple-subtle text-accent-purple" : e.type === "INTEGRATION" || e.type === "API_INTEGRATION" ? "bg-status-info-bg-subtle text-status-info-text" : "bg-status-success-bg-subtle text-status-success-text"),
92
91
  children: e.type
93
92
  })]
94
- }), /* @__PURE__ */ _("code", {
93
+ }), /* @__PURE__ */ g("code", {
95
94
  className: "text-xs text-text-secondary",
96
95
  children: e.clientId
97
96
  })] })]
@@ -100,12 +99,12 @@ var x = () => {
100
99
  {
101
100
  key: "scopes",
102
101
  header: "Scopes",
103
- render: (e) => /* @__PURE__ */ v("div", {
102
+ render: (e) => /* @__PURE__ */ _("div", {
104
103
  className: "flex flex-wrap gap-1",
105
- children: [e.scopes.slice(0, 3).map((e) => /* @__PURE__ */ _("span", {
104
+ children: [e.scopes.slice(0, 3).map((e) => /* @__PURE__ */ g("span", {
106
105
  className: "inline-flex rounded bg-bg-sunken px-1.5 py-0.5 text-xs",
107
106
  children: e
108
- }, e)), e.scopes.length > 3 && /* @__PURE__ */ v("span", {
107
+ }, e)), e.scopes.length > 3 && /* @__PURE__ */ _("span", {
109
108
  className: "text-xs text-text-secondary",
110
109
  children: ["+", e.scopes.length - 3]
111
110
  })]
@@ -114,7 +113,7 @@ var x = () => {
114
113
  {
115
114
  key: "redirectUris",
116
115
  header: "Redirect URIs",
117
- render: (e) => /* @__PURE__ */ v("span", {
116
+ render: (e) => /* @__PURE__ */ _("span", {
118
117
  className: "text-sm",
119
118
  children: [
120
119
  e.redirectUris.length,
@@ -126,163 +125,163 @@ var x = () => {
126
125
  {
127
126
  key: "status",
128
127
  header: "Status",
129
- render: (e) => /* @__PURE__ */ v("div", {
128
+ render: (e) => /* @__PURE__ */ _("div", {
130
129
  className: "flex items-center gap-2",
131
- children: [/* @__PURE__ */ _(o, { active: e.status === "ACTIVE" }), /* @__PURE__ */ _("span", {
130
+ children: [/* @__PURE__ */ g(o, { active: e.status === "ACTIVE" }), /* @__PURE__ */ g("span", {
132
131
  className: "text-sm",
133
132
  children: e.status
134
133
  })]
135
134
  })
136
135
  }
137
- ], L = {
138
- total: N.length,
139
- active: N.filter((e) => e.status === "ACTIVE").length,
140
- integration: N.filter((e) => e.type === "INTEGRATION" || e.type === "API_INTEGRATION").length,
141
- service: N.filter((e) => e.type === "SERVICE").length
136
+ ], I = {
137
+ total: M.length,
138
+ active: M.filter((e) => e.status === "ACTIVE").length,
139
+ integration: M.filter((e) => e.type === "INTEGRATION" || e.type === "API_INTEGRATION").length,
140
+ service: M.filter((e) => e.type === "SERVICE").length
142
141
  };
143
- return /* @__PURE__ */ _(c, {
144
- permission: l.APP_READ,
145
- children: /* @__PURE__ */ v(a, {
146
- title: w("devportal.oauthApps", "OAuth Apps"),
147
- description: w("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
148
- purpose: w("devportal.oauthAppsPurpose", "OAuth apps let external services sign in users and call the API on their behalf. Register one here to get a client ID and secret, set redirect URIs, and choose the scopes your integration may request."),
149
- actions: /* @__PURE__ */ v("button", {
150
- onClick: () => P("/oauth/new"),
142
+ return /* @__PURE__ */ g(c, {
143
+ authOnly: !0,
144
+ children: /* @__PURE__ */ _(a, {
145
+ title: C("devportal.oauthApps", "OAuth Apps"),
146
+ description: C("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
147
+ purpose: C("devportal.oauthAppsPurpose", "OAuth apps let external services sign in users and call the API on their behalf. Register one here to get a client ID and secret, set redirect URIs, and choose the scopes your integration may request."),
148
+ actions: /* @__PURE__ */ _("button", {
149
+ onClick: () => N("/oauth/new"),
151
150
  className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors",
152
- children: [/* @__PURE__ */ _(m, { size: 16 }), w("devportal.createOAuthApp", "Create OAuth App")]
151
+ children: [/* @__PURE__ */ g(p, { size: 16 }), C("devportal.createOAuthApp", "Create OAuth App")]
153
152
  }),
154
153
  children: [
155
- /* @__PURE__ */ _("div", {
154
+ /* @__PURE__ */ g("div", {
156
155
  className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
157
- children: /* @__PURE__ */ v("div", {
156
+ children: /* @__PURE__ */ _("div", {
158
157
  className: "flex flex-1 items-center gap-4",
159
- children: [/* @__PURE__ */ v("div", {
158
+ children: [/* @__PURE__ */ _("div", {
160
159
  className: "relative flex-1 max-w-md",
161
- children: [/* @__PURE__ */ _(h, {
160
+ children: [/* @__PURE__ */ g(m, {
162
161
  size: 16,
163
162
  className: "absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary"
164
- }), /* @__PURE__ */ _("input", {
163
+ }), /* @__PURE__ */ g("input", {
165
164
  type: "text",
166
- placeholder: w("devportal.searchByNameOrClientId", "Search by name or client ID..."),
167
- value: T,
168
- onChange: (e) => E(e.target.value),
165
+ placeholder: C("devportal.searchByNameOrClientId", "Search by name or client ID..."),
166
+ value: w,
167
+ onChange: (e) => T(e.target.value),
169
168
  className: "w-full rounded-md border bg-bg-surface pl-9 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary"
170
169
  })]
171
- }), /* @__PURE__ */ v("select", {
172
- value: D,
173
- onChange: (e) => O(e.target.value),
170
+ }), /* @__PURE__ */ _("select", {
171
+ value: E,
172
+ onChange: (e) => D(e.target.value),
174
173
  className: "rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary",
175
174
  children: [
176
- /* @__PURE__ */ _("option", {
175
+ /* @__PURE__ */ g("option", {
177
176
  value: "",
178
- children: w("devportal.allTypes", "All Types")
177
+ children: C("devportal.allTypes", "All Types")
179
178
  }),
180
- /* @__PURE__ */ _("option", {
179
+ /* @__PURE__ */ g("option", {
181
180
  value: "SERVICE",
182
- children: w("devportal.service", "Service")
181
+ children: C("devportal.service", "Service")
183
182
  }),
184
- /* @__PURE__ */ _("option", {
183
+ /* @__PURE__ */ g("option", {
185
184
  value: "INTEGRATION",
186
- children: w("devportal.integration", "Integration")
185
+ children: C("devportal.integration", "Integration")
187
186
  }),
188
- /* @__PURE__ */ _("option", {
187
+ /* @__PURE__ */ g("option", {
189
188
  value: "BOT",
190
- children: w("devportal.bot", "Bot")
189
+ children: C("devportal.bot", "Bot")
191
190
  }),
192
- /* @__PURE__ */ _("option", {
191
+ /* @__PURE__ */ g("option", {
193
192
  value: "WEB_APP",
194
- children: w("devportal.webApp", "Web App")
193
+ children: C("devportal.webApp", "Web App")
195
194
  }),
196
- /* @__PURE__ */ _("option", {
195
+ /* @__PURE__ */ g("option", {
197
196
  value: "AUTOMATION",
198
- children: w("devportal.automation", "Automation")
197
+ children: C("devportal.automation", "Automation")
199
198
  })
200
199
  ]
201
200
  })]
202
201
  })
203
202
  }),
204
- /* @__PURE__ */ _(y, { children: /* @__PURE__ */ v("div", {
203
+ /* @__PURE__ */ g(v, { children: /* @__PURE__ */ _("div", {
205
204
  className: "grid grid-cols-2 gap-4 sm:grid-cols-4",
206
205
  children: [
207
- /* @__PURE__ */ v(b, {
206
+ /* @__PURE__ */ _(y, {
208
207
  treatment: "metric",
209
208
  className: "p-4",
210
- children: [/* @__PURE__ */ v("div", {
209
+ children: [/* @__PURE__ */ _("div", {
211
210
  className: "flex items-center gap-2 text-text-secondary",
212
- children: [/* @__PURE__ */ _(g, { size: 16 }), /* @__PURE__ */ _("span", {
211
+ children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
213
212
  className: "text-sm",
214
- children: w("devportal.totalApps", "Total Apps")
213
+ children: C("devportal.totalApps", "Total Apps")
215
214
  })]
216
- }), /* @__PURE__ */ _("p", {
215
+ }), /* @__PURE__ */ g("p", {
217
216
  className: "mt-1 text-2xl font-semibold tabular-nums",
218
- children: L.total
217
+ children: I.total
219
218
  })]
220
219
  }),
221
- /* @__PURE__ */ v(b, {
220
+ /* @__PURE__ */ _(y, {
222
221
  treatment: "metric",
223
222
  className: "p-4",
224
- children: [/* @__PURE__ */ v("div", {
223
+ children: [/* @__PURE__ */ _("div", {
225
224
  className: "flex items-center gap-2 text-status-success-text",
226
- children: [/* @__PURE__ */ _(g, { size: 16 }), /* @__PURE__ */ _("span", {
225
+ children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
227
226
  className: "text-sm",
228
- children: w("devportal.active", "Active")
227
+ children: C("devportal.active", "Active")
229
228
  })]
230
- }), /* @__PURE__ */ _("p", {
229
+ }), /* @__PURE__ */ g("p", {
231
230
  className: "mt-1 text-2xl font-semibold tabular-nums",
232
- children: L.active
231
+ children: I.active
233
232
  })]
234
233
  }),
235
- /* @__PURE__ */ v(b, {
234
+ /* @__PURE__ */ _(y, {
236
235
  treatment: "metric",
237
236
  className: "p-4",
238
- children: [/* @__PURE__ */ v("div", {
237
+ children: [/* @__PURE__ */ _("div", {
239
238
  className: "flex items-center gap-2 text-accent-blue",
240
- children: [/* @__PURE__ */ _(g, { size: 16 }), /* @__PURE__ */ _("span", {
239
+ children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
241
240
  className: "text-sm",
242
- children: w("devportal.integration", "Integration")
241
+ children: C("devportal.integration", "Integration")
243
242
  })]
244
- }), /* @__PURE__ */ _("p", {
243
+ }), /* @__PURE__ */ g("p", {
245
244
  className: "mt-1 text-2xl font-semibold tabular-nums",
246
- children: L.integration
245
+ children: I.integration
247
246
  })]
248
247
  }),
249
- /* @__PURE__ */ v(b, {
248
+ /* @__PURE__ */ _(y, {
250
249
  treatment: "metric",
251
250
  className: "p-4",
252
- children: [/* @__PURE__ */ v("div", {
251
+ children: [/* @__PURE__ */ _("div", {
253
252
  className: "flex items-center gap-2 text-accent-purple",
254
- children: [/* @__PURE__ */ _(g, { size: 16 }), /* @__PURE__ */ _("span", {
253
+ children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
255
254
  className: "text-sm",
256
- children: w("devportal.service", "Service")
255
+ children: C("devportal.service", "Service")
257
256
  })]
258
- }), /* @__PURE__ */ _("p", {
257
+ }), /* @__PURE__ */ g("p", {
259
258
  className: "mt-1 text-2xl font-semibold tabular-nums",
260
- children: L.service
259
+ children: I.service
261
260
  })]
262
261
  })
263
262
  ]
264
263
  }) }),
265
- /* @__PURE__ */ v("p", {
264
+ /* @__PURE__ */ _("p", {
266
265
  className: "text-sm text-text-secondary",
267
266
  children: [
268
- F.length,
267
+ P.length,
269
268
  " ",
270
- F.length === 1 ? w("devportal.appFound", "app found") : w("devportal.appsFound", "apps found")
269
+ P.length === 1 ? C("devportal.appFound", "app found") : C("devportal.appsFound", "apps found")
271
270
  ]
272
271
  }),
273
- F.length > 0 ? /* @__PURE__ */ _(s, {
274
- data: F,
275
- columns: I,
272
+ P.length > 0 ? /* @__PURE__ */ g(s, {
273
+ data: P,
274
+ columns: F,
276
275
  keyField: "id",
277
- onRowClick: (e) => P(`/oauth/${e.id}`)
278
- }) : /* @__PURE__ */ _(n, {
276
+ onRowClick: (e) => N(`/oauth/${e.id}`)
277
+ }) : /* @__PURE__ */ g(n, {
279
278
  illustration: "empty-generic",
280
- title: w("devportal.noOAuthAppsFound", "No OAuth apps found"),
281
- description: T || D ? w("devportal.tryAdjustingFilters", "Try adjusting your filters") : w("devportal.createFirstOAuthApp", "Create your first OAuth app to enable authentication"),
282
- action: !T && !D ? /* @__PURE__ */ v("button", {
283
- onClick: () => P("/oauth/new"),
279
+ title: C("devportal.noOAuthAppsFound", "No OAuth apps found"),
280
+ description: w || E ? C("devportal.tryAdjustingFilters", "Try adjusting your filters") : C("devportal.createFirstOAuthApp", "Create your first OAuth app to enable authentication"),
281
+ action: !w && !E ? /* @__PURE__ */ _("button", {
282
+ onClick: () => N("/oauth/new"),
284
283
  className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
285
- children: [/* @__PURE__ */ _(m, { size: 16 }), w("devportal.createOAuthApp", "Create OAuth App")]
284
+ children: [/* @__PURE__ */ g(p, { size: 16 }), C("devportal.createOAuthApp", "Create OAuth App")]
286
285
  }) : void 0
287
286
  })
288
287
  ]
@@ -290,6 +289,6 @@ var x = () => {
290
289
  });
291
290
  };
292
291
  //#endregion
293
- export { x as OAuthClientsPage };
292
+ export { b as OAuthClientsPage };
294
293
 
295
294
  //# sourceMappingURL=OAuthClientsPage.js.map