@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.
- package/dist/devportal/components/PermissionGuard.d.ts +14 -1
- package/dist/devportal/components/PermissionGuard.d.ts.map +1 -1
- package/dist/devportal/components/PermissionGuard.js +16 -13
- package/dist/devportal/components/PermissionGuard.js.map +1 -1
- package/dist/devportal/pages/AdminReviewPage.js +9 -9
- package/dist/devportal/pages/ApiKeysPage.js +180 -181
- package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
- package/dist/devportal/pages/ApplicationDetailPage.js +3 -3
- package/dist/devportal/pages/ApplicationVersionsPage.js +4 -4
- package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
- package/dist/devportal/pages/ApplicationsPage.js +4 -4
- package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
- package/dist/devportal/pages/CreateApiKeyPage.js +1 -1
- package/dist/devportal/pages/CreateOAuthClientPage.js +1 -1
- package/dist/devportal/pages/CreateOrganizationPage.d.ts.map +1 -1
- package/dist/devportal/pages/CreateOrganizationPage.js +97 -98
- package/dist/devportal/pages/CreateOrganizationPage.js.map +1 -1
- package/dist/devportal/pages/CreateWebhookPage.js +25 -25
- package/dist/devportal/pages/DashboardPage.d.ts.map +1 -1
- package/dist/devportal/pages/DashboardPage.js +110 -111
- package/dist/devportal/pages/DashboardPage.js.map +1 -1
- package/dist/devportal/pages/DelegationsPage.js +1 -1
- package/dist/devportal/pages/EditApplicationPage.js +4 -4
- package/dist/devportal/pages/ListingPreviewPage.d.ts.map +1 -1
- package/dist/devportal/pages/ListingPreviewPage.js +160 -161
- package/dist/devportal/pages/ListingPreviewPage.js.map +1 -1
- package/dist/devportal/pages/OAuthClientDetailPage.d.ts.map +1 -1
- package/dist/devportal/pages/OAuthClientDetailPage.js +166 -167
- package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
- package/dist/devportal/pages/OAuthClientsPage.d.ts.map +1 -1
- package/dist/devportal/pages/OAuthClientsPage.js +121 -122
- package/dist/devportal/pages/OAuthClientsPage.js.map +1 -1
- package/dist/devportal/pages/OrganizationDetailPage.js +3 -3
- package/dist/devportal/pages/OrganizationMembersPage.js +4 -4
- package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
- package/dist/devportal/pages/OrganizationsPage.d.ts.map +1 -1
- package/dist/devportal/pages/OrganizationsPage.js +97 -98
- package/dist/devportal/pages/OrganizationsPage.js.map +1 -1
- package/dist/devportal/pages/PublishPage.js +246 -246
- package/dist/devportal/pages/PublishPage.js.map +1 -1
- package/dist/devportal/pages/PublisherProfilePage.js +4 -4
- package/dist/devportal/pages/PublisherProfilePage.js.map +1 -1
- package/dist/devportal/pages/StoreSubmissionPage.js +3 -3
- package/dist/devportal/pages/WebhookDetailPage.js +3 -3
- package/dist/devportal/pages/WebhooksPage.js +129 -129
- package/dist/devportal/pages/WebhooksPage.js.map +1 -1
- 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":"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"}
|
|
@@ -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;
|
|
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
|
|
14
|
-
import { useI18n as
|
|
15
|
-
import { AlertCircle as
|
|
16
|
-
import { jsx as
|
|
17
|
-
import { EmphasisPanel as
|
|
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
|
|
20
|
-
let { navigate:
|
|
21
|
-
let n =
|
|
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
|
-
}, [
|
|
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
|
-
})) ?? [],
|
|
37
|
-
|
|
38
|
-
},
|
|
39
|
-
let t = !
|
|
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 (
|
|
43
|
-
title:
|
|
44
|
-
description:
|
|
45
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
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:
|
|
48
|
+
children: C("devportal.loadingApps", "Loading apps...")
|
|
50
49
|
})]
|
|
51
50
|
})
|
|
52
51
|
});
|
|
53
|
-
if (
|
|
54
|
-
title:
|
|
55
|
-
description:
|
|
56
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
60
|
-
/* @__PURE__ */
|
|
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:
|
|
61
|
+
children: C("devportal.failedToLoadApps", "Failed to load apps")
|
|
63
62
|
}),
|
|
64
|
-
/* @__PURE__ */
|
|
63
|
+
/* @__PURE__ */ g("p", {
|
|
65
64
|
className: "mt-1 text-sm text-text-secondary",
|
|
66
|
-
children: i(
|
|
65
|
+
children: i(A)
|
|
67
66
|
}),
|
|
68
|
-
/* @__PURE__ */
|
|
69
|
-
onClick: () =>
|
|
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:
|
|
70
|
+
children: C("devportal.tryAgain", "Try Again")
|
|
72
71
|
})
|
|
73
72
|
]
|
|
74
73
|
})
|
|
75
74
|
});
|
|
76
|
-
let
|
|
75
|
+
let F = [
|
|
77
76
|
{
|
|
78
77
|
key: "name",
|
|
79
78
|
header: "App",
|
|
80
|
-
render: (e) => /* @__PURE__ */
|
|
79
|
+
render: (e) => /* @__PURE__ */ _("div", {
|
|
81
80
|
className: "flex items-center gap-3",
|
|
82
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
85
|
-
}), /* @__PURE__ */
|
|
83
|
+
children: /* @__PURE__ */ g(h, { size: 20 })
|
|
84
|
+
}), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("div", {
|
|
86
85
|
className: "flex items-center gap-2",
|
|
87
|
-
children: [/* @__PURE__ */
|
|
86
|
+
children: [/* @__PURE__ */ g("p", {
|
|
88
87
|
className: "font-medium",
|
|
89
88
|
children: e.name
|
|
90
|
-
}), /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
102
|
+
render: (e) => /* @__PURE__ */ _("div", {
|
|
104
103
|
className: "flex flex-wrap gap-1",
|
|
105
|
-
children: [e.scopes.slice(0, 3).map((e) => /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
128
|
+
render: (e) => /* @__PURE__ */ _("div", {
|
|
130
129
|
className: "flex items-center gap-2",
|
|
131
|
-
children: [/* @__PURE__ */
|
|
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
|
-
],
|
|
138
|
-
total:
|
|
139
|
-
active:
|
|
140
|
-
integration:
|
|
141
|
-
service:
|
|
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__ */
|
|
144
|
-
|
|
145
|
-
children: /* @__PURE__ */
|
|
146
|
-
title:
|
|
147
|
-
description:
|
|
148
|
-
purpose:
|
|
149
|
-
actions: /* @__PURE__ */
|
|
150
|
-
onClick: () =>
|
|
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__ */
|
|
151
|
+
children: [/* @__PURE__ */ g(p, { size: 16 }), C("devportal.createOAuthApp", "Create OAuth App")]
|
|
153
152
|
}),
|
|
154
153
|
children: [
|
|
155
|
-
/* @__PURE__ */
|
|
154
|
+
/* @__PURE__ */ g("div", {
|
|
156
155
|
className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
|
|
157
|
-
children: /* @__PURE__ */
|
|
156
|
+
children: /* @__PURE__ */ _("div", {
|
|
158
157
|
className: "flex flex-1 items-center gap-4",
|
|
159
|
-
children: [/* @__PURE__ */
|
|
158
|
+
children: [/* @__PURE__ */ _("div", {
|
|
160
159
|
className: "relative flex-1 max-w-md",
|
|
161
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
163
|
+
}), /* @__PURE__ */ g("input", {
|
|
165
164
|
type: "text",
|
|
166
|
-
placeholder:
|
|
167
|
-
value:
|
|
168
|
-
onChange: (e) =>
|
|
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__ */
|
|
172
|
-
value:
|
|
173
|
-
onChange: (e) =>
|
|
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__ */
|
|
175
|
+
/* @__PURE__ */ g("option", {
|
|
177
176
|
value: "",
|
|
178
|
-
children:
|
|
177
|
+
children: C("devportal.allTypes", "All Types")
|
|
179
178
|
}),
|
|
180
|
-
/* @__PURE__ */
|
|
179
|
+
/* @__PURE__ */ g("option", {
|
|
181
180
|
value: "SERVICE",
|
|
182
|
-
children:
|
|
181
|
+
children: C("devportal.service", "Service")
|
|
183
182
|
}),
|
|
184
|
-
/* @__PURE__ */
|
|
183
|
+
/* @__PURE__ */ g("option", {
|
|
185
184
|
value: "INTEGRATION",
|
|
186
|
-
children:
|
|
185
|
+
children: C("devportal.integration", "Integration")
|
|
187
186
|
}),
|
|
188
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ g("option", {
|
|
189
188
|
value: "BOT",
|
|
190
|
-
children:
|
|
189
|
+
children: C("devportal.bot", "Bot")
|
|
191
190
|
}),
|
|
192
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ g("option", {
|
|
193
192
|
value: "WEB_APP",
|
|
194
|
-
children:
|
|
193
|
+
children: C("devportal.webApp", "Web App")
|
|
195
194
|
}),
|
|
196
|
-
/* @__PURE__ */
|
|
195
|
+
/* @__PURE__ */ g("option", {
|
|
197
196
|
value: "AUTOMATION",
|
|
198
|
-
children:
|
|
197
|
+
children: C("devportal.automation", "Automation")
|
|
199
198
|
})
|
|
200
199
|
]
|
|
201
200
|
})]
|
|
202
201
|
})
|
|
203
202
|
}),
|
|
204
|
-
/* @__PURE__ */
|
|
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__ */
|
|
206
|
+
/* @__PURE__ */ _(y, {
|
|
208
207
|
treatment: "metric",
|
|
209
208
|
className: "p-4",
|
|
210
|
-
children: [/* @__PURE__ */
|
|
209
|
+
children: [/* @__PURE__ */ _("div", {
|
|
211
210
|
className: "flex items-center gap-2 text-text-secondary",
|
|
212
|
-
children: [/* @__PURE__ */
|
|
211
|
+
children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
|
|
213
212
|
className: "text-sm",
|
|
214
|
-
children:
|
|
213
|
+
children: C("devportal.totalApps", "Total Apps")
|
|
215
214
|
})]
|
|
216
|
-
}), /* @__PURE__ */
|
|
215
|
+
}), /* @__PURE__ */ g("p", {
|
|
217
216
|
className: "mt-1 text-2xl font-semibold tabular-nums",
|
|
218
|
-
children:
|
|
217
|
+
children: I.total
|
|
219
218
|
})]
|
|
220
219
|
}),
|
|
221
|
-
/* @__PURE__ */
|
|
220
|
+
/* @__PURE__ */ _(y, {
|
|
222
221
|
treatment: "metric",
|
|
223
222
|
className: "p-4",
|
|
224
|
-
children: [/* @__PURE__ */
|
|
223
|
+
children: [/* @__PURE__ */ _("div", {
|
|
225
224
|
className: "flex items-center gap-2 text-status-success-text",
|
|
226
|
-
children: [/* @__PURE__ */
|
|
225
|
+
children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
|
|
227
226
|
className: "text-sm",
|
|
228
|
-
children:
|
|
227
|
+
children: C("devportal.active", "Active")
|
|
229
228
|
})]
|
|
230
|
-
}), /* @__PURE__ */
|
|
229
|
+
}), /* @__PURE__ */ g("p", {
|
|
231
230
|
className: "mt-1 text-2xl font-semibold tabular-nums",
|
|
232
|
-
children:
|
|
231
|
+
children: I.active
|
|
233
232
|
})]
|
|
234
233
|
}),
|
|
235
|
-
/* @__PURE__ */
|
|
234
|
+
/* @__PURE__ */ _(y, {
|
|
236
235
|
treatment: "metric",
|
|
237
236
|
className: "p-4",
|
|
238
|
-
children: [/* @__PURE__ */
|
|
237
|
+
children: [/* @__PURE__ */ _("div", {
|
|
239
238
|
className: "flex items-center gap-2 text-accent-blue",
|
|
240
|
-
children: [/* @__PURE__ */
|
|
239
|
+
children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
|
|
241
240
|
className: "text-sm",
|
|
242
|
-
children:
|
|
241
|
+
children: C("devportal.integration", "Integration")
|
|
243
242
|
})]
|
|
244
|
-
}), /* @__PURE__ */
|
|
243
|
+
}), /* @__PURE__ */ g("p", {
|
|
245
244
|
className: "mt-1 text-2xl font-semibold tabular-nums",
|
|
246
|
-
children:
|
|
245
|
+
children: I.integration
|
|
247
246
|
})]
|
|
248
247
|
}),
|
|
249
|
-
/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ _(y, {
|
|
250
249
|
treatment: "metric",
|
|
251
250
|
className: "p-4",
|
|
252
|
-
children: [/* @__PURE__ */
|
|
251
|
+
children: [/* @__PURE__ */ _("div", {
|
|
253
252
|
className: "flex items-center gap-2 text-accent-purple",
|
|
254
|
-
children: [/* @__PURE__ */
|
|
253
|
+
children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
|
|
255
254
|
className: "text-sm",
|
|
256
|
-
children:
|
|
255
|
+
children: C("devportal.service", "Service")
|
|
257
256
|
})]
|
|
258
|
-
}), /* @__PURE__ */
|
|
257
|
+
}), /* @__PURE__ */ g("p", {
|
|
259
258
|
className: "mt-1 text-2xl font-semibold tabular-nums",
|
|
260
|
-
children:
|
|
259
|
+
children: I.service
|
|
261
260
|
})]
|
|
262
261
|
})
|
|
263
262
|
]
|
|
264
263
|
}) }),
|
|
265
|
-
/* @__PURE__ */
|
|
264
|
+
/* @__PURE__ */ _("p", {
|
|
266
265
|
className: "text-sm text-text-secondary",
|
|
267
266
|
children: [
|
|
268
|
-
|
|
267
|
+
P.length,
|
|
269
268
|
" ",
|
|
270
|
-
|
|
269
|
+
P.length === 1 ? C("devportal.appFound", "app found") : C("devportal.appsFound", "apps found")
|
|
271
270
|
]
|
|
272
271
|
}),
|
|
273
|
-
|
|
274
|
-
data:
|
|
275
|
-
columns:
|
|
272
|
+
P.length > 0 ? /* @__PURE__ */ g(s, {
|
|
273
|
+
data: P,
|
|
274
|
+
columns: F,
|
|
276
275
|
keyField: "id",
|
|
277
|
-
onRowClick: (e) =>
|
|
278
|
-
}) : /* @__PURE__ */
|
|
276
|
+
onRowClick: (e) => N(`/oauth/${e.id}`)
|
|
277
|
+
}) : /* @__PURE__ */ g(n, {
|
|
279
278
|
illustration: "empty-generic",
|
|
280
|
-
title:
|
|
281
|
-
description:
|
|
282
|
-
action: !
|
|
283
|
-
onClick: () =>
|
|
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__ */
|
|
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 {
|
|
292
|
+
export { b as OAuthClientsPage };
|
|
294
293
|
|
|
295
294
|
//# sourceMappingURL=OAuthClientsPage.js.map
|