@burdenoff/microfe-devportal 2026.717.1 → 2026.720.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/devportal/components/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.js +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/OrganizationsPage.js +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":"ListingPreviewPage.js","names":[],"sources":["../../../src/devportal/pages/ListingPreviewPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Star,\n Download,\n Globe,\n FileText,\n Shield,\n ExternalLink,\n Tag,\n CheckCircle,\n Loader2,\n Eye,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { Alert } from \"../components/ConfirmDialog\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useGetApplicationQuery } from \"../../generated/global-operations\";\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst PRICING_LABELS: Record<string, string> = {\n FREE: \"Free\",\n FREEMIUM: \"Free with in-app purchases\",\n PAID: \"Paid\",\n ONE_TIME: \"One-time purchase\",\n SUBSCRIPTION: \"Subscription\",\n USAGE_BASED: \"Usage-based pricing\",\n ENTERPRISE: \"Enterprise pricing\",\n};\n\nconst APP_TYPE_LABELS: Record<string, string> = {\n WORKFLOW: \"Workflow\",\n WIDGET: \"Widget\",\n BOT: \"Bot / Chatbot\",\n API_INTEGRATION: \"API Integration\",\n INTEGRATION: \"Integration\",\n ANALYST: \"AI Analyst\",\n ASSISTANT: \"AI Assistant\",\n AUTOMATION: \"Automation\",\n SPECIALIST: \"AI Specialist\",\n WEB_APP: \"Web App\",\n MOBILE_APP: \"Mobile App\",\n DESKTOP_APP: \"Desktop App\",\n CLI_TOOL: \"CLI Tool\",\n SERVICE: \"Service\",\n};\n\n// ============================================================================\n// Listing Preview Page\n// ============================================================================\n\nexport const ListingPreviewPage: FC = () => {\n const { appId } = useParams<{ appId: 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 { data, loading, error } = useGetApplicationQuery({\n variables: { id: appId! },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const app = data?.application;\n\n useEffect(() => {\n const name = app?.name;\n if (!appId || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(appId, name);\n return () => reg?.unregister(appId);\n }, [appId, app?.name]);\n\n if (loading) {\n return (\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\"devportal.loading\", \"Loading...\")}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\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.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\n \"devportal.couldNotLoadApplication\",\n \"Could not load application\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <Alert\n variant=\"error\"\n title={tr(\n \"devportal.failedToLoadApplication\",\n \"Failed to load application\",\n )}\n >\n {error?.message ??\n tr(\"devportal.applicationNotFound\", \"Application not found\")}\n </Alert>\n </PageLayout>\n );\n }\n\n const screenshots = Array.isArray(app.screenshots)\n ? (app.screenshots as string[])\n : [];\n\n const isPublished = app.status === \"PUBLISHED\";\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.APP_READ}>\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\n \"devportal.marketplacePreviewDescription\",\n \"Preview how your app will appear in the marketplace\",\n )}\n purpose={tr(\n \"devportal.marketplacePreviewPurpose\",\n \"See exactly how shoppers will experience your store listing — icon, screenshots, description, and pricing — before it goes live. Use it to catch missing assets or typos, then submit for review when the listing looks right.\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n !isPublished ? (\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/publish`)}\n 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\"\n >\n <Eye size={16} />\n {tr(\"devportal.submitForReview\", \"Submit for Review\")}\n </button>\n ) : undefined\n }\n >\n {/* Preview banner */}\n <div className=\"flex items-center gap-2 rounded-lg border border-border-subtle bg-status-warning-bg-subtle px-4 py-3 text-sm text-status-warning-text\">\n <Eye size={16} className=\"flex-shrink-0\" />\n <span>\n {tr(\n \"devportal.previewBannerText\",\n \"This is a preview of your marketplace listing. It shows how your app will appear to users after publication.\",\n )}\n </span>\n </div>\n\n {/* === Simulated marketplace product page === */}\n <div className=\"rounded-xl border bg-bg-surface overflow-hidden\">\n {/* Banner */}\n {app.bannerUrl ? (\n <div className=\"h-48 w-full overflow-hidden\">\n <img\n src={app.bannerUrl}\n alt={tr(\"devportal.appBannerAlt\", \"App banner\")}\n className=\"h-full w-full object-cover\"\n />\n </div>\n ) : (\n <div className=\"h-32 w-full bg-gradient-to-r from-primary/20 to-primary/5\" />\n )}\n\n {/* Hero */}\n <div className=\"p-6\">\n <div className=\"flex items-start gap-5\">\n {app.iconUrl ? (\n <img\n src={app.iconUrl}\n alt={app.name}\n className=\"h-20 w-20 rounded-2xl border object-cover flex-shrink-0 shadow-sm\"\n />\n ) : (\n <div className=\"h-20 w-20 rounded-2xl border bg-bg-sunken flex items-center justify-center flex-shrink-0\">\n <span\n className=\"text-3xl font-bold text-text-secondary\"\n aria-label={tr(\n \"devportal.appIconFallbackAriaLabel\",\n \"App icon\",\n )}\n >\n {app.name.charAt(0).toUpperCase()}\n </span>\n </div>\n )}\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"text-2xl font-bold\">{app.name}</h1>\n {app.isVerified && (\n <CheckCircle size={20} className=\"text-primary\" />\n )}\n {app.isFeatured && (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n {tr(\"devportal.featured\", \"Featured\")}\n </span>\n )}\n </div>\n\n <p className=\"mt-1 text-text-secondary\">\n {app.shortDescription ??\n app.description ??\n tr(\"devportal.noDescription\", \"No description\")}\n </p>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-4 text-sm text-text-secondary\">\n {app.averageRating != null && (\n <div className=\"flex items-center gap-1\">\n <Star\n size={14}\n className=\"text-status-warning-text fill-status-warning-text\"\n />\n <span className=\"font-medium text-text-primary\">\n {app.averageRating.toFixed(1)}\n </span>\n <span>\n ({app.reviewCount ?? 0}{\" \"}\n {tr(\"devportal.reviews\", \"reviews\")})\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-1\">\n <Download size={14} />\n <span>\n {(app.installCount ?? 0).toLocaleString()}{\" \"}\n {tr(\"devportal.installs\", \"installs\")}\n </span>\n </div>\n {app.category && (\n <span className=\"rounded-full border px-2 py-0.5 text-xs\">\n {app.category}\n </span>\n )}\n <span className=\"rounded-full border px-2 py-0.5 text-xs\">\n {APP_TYPE_LABELS[app.appType] ?? app.appType}\n </span>\n </div>\n </div>\n\n {/* Install CTA (simulated) */}\n <div className=\"flex-shrink-0 text-right space-y-2\">\n <div className=\"text-lg font-semibold\">\n {PRICING_LABELS[app.pricingType ?? \"FREE\"] ?? \"Free\"}\n </div>\n <button\n disabled\n className=\"w-full rounded-lg bg-action-primary-bg px-6 py-2 text-sm font-semibold text-action-primary-text opacity-60 cursor-not-allowed\"\n title={tr(\"devportal.previewOnly\", \"Preview only\")}\n >\n {tr(\"devportal.install\", \"Install\")}\n </button>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.previewOnly\", \"Preview only\")}\n </p>\n </div>\n </div>\n </div>\n\n {/* Screenshots */}\n {screenshots.length > 0 && (\n <div className=\"border-t px-6 py-5\">\n <h2 className=\"text-base font-semibold mb-3\">\n {tr(\"devportal.screenshots\", \"Screenshots\")}\n </h2>\n <div className=\"flex gap-3 overflow-x-auto pb-2\">\n {screenshots.map((url, i) => (\n <img\n key={i}\n src={url}\n alt={`${tr(\"devportal.screenshotAlt\", \"Screenshot\")} ${i + 1}`}\n className=\"h-44 w-auto rounded-lg border object-cover flex-shrink-0\"\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Description */}\n <div className=\"border-t px-6 py-5\">\n <h2 className=\"text-base font-semibold mb-2\">\n {tr(\"devportal.about\", \"About\")}\n </h2>\n <p className=\"text-sm text-text-secondary whitespace-pre-wrap\">\n {app.description ??\n app.shortDescription ??\n tr(\n \"devportal.noDetailedDescription\",\n \"No detailed description provided.\",\n )}\n </p>\n </div>\n\n {/* Tags */}\n {Array.isArray(app.tags) && app.tags.length > 0 && (\n <div className=\"border-t px-6 py-4\">\n <div className=\"flex flex-wrap gap-2\">\n {(app.tags as string[]).map((tag) => (\n <span\n key={tag}\n className=\"inline-flex items-center gap-1 rounded-full border px-3 py-1 text-xs text-text-secondary\"\n >\n <Tag size={10} />\n {tag}\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Links & Compliance */}\n <div className=\"border-t px-6 py-5 grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n {app.websiteUrl && (\n <a\n href={app.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <Globe size={14} />\n {tr(\"devportal.website\", \"Website\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.documentationUrl && (\n <a\n href={app.documentationUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <FileText size={14} />\n {tr(\"devportal.documentation\", \"Documentation\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.privacyPolicyUrl && (\n <a\n href={app.privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <Shield size={14} />\n {tr(\"devportal.privacyPolicy\", \"Privacy Policy\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.termsOfServiceUrl && (\n <a\n href={app.termsOfServiceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <FileText size={14} />\n {tr(\"devportal.termsOfService\", \"Terms of Service\")}\n <ExternalLink size={12} />\n </a>\n )}\n </div>\n </div>\n\n {/* Completeness tips */}\n <PageSection\n title={tr(\"devportal.listingCompleteness\", \"Listing Completeness\")}\n >\n <div className=\"space-y-2\">\n {[\n {\n label: tr(\"devportal.completenessAppIcon\", \"App icon\"),\n ok: !!app.iconUrl,\n },\n {\n label: tr(\"devportal.completenessBannerImage\", \"Banner image\"),\n ok: !!app.bannerUrl,\n },\n {\n label: tr(\n \"devportal.completenessShortDescription\",\n \"Short description\",\n ),\n ok: !!app.shortDescription,\n },\n {\n label: tr(\n \"devportal.completenessFullDescription\",\n \"Full description\",\n ),\n ok: !!app.description,\n },\n {\n label: tr(\n \"devportal.completenessScreenshots\",\n \"Screenshots (3+)\",\n ),\n ok: screenshots.length >= 3,\n },\n {\n label: tr(\"devportal.completenessCategory\", \"Category\"),\n ok: !!app.category,\n },\n {\n label: tr(\"devportal.completenessTags\", \"Tags\"),\n ok:\n Array.isArray(app.tags) && (app.tags as string[]).length > 0,\n },\n {\n label: tr(\n \"devportal.completenessPrivacyPolicy\",\n \"Privacy policy URL\",\n ),\n ok: !!app.privacyPolicyUrl,\n },\n {\n label: tr(\n \"devportal.completenessTermsOfService\",\n \"Terms of service URL\",\n ),\n ok: !!app.termsOfServiceUrl,\n },\n ].map(({ label, ok }) => (\n <div key={label} className=\"flex items-center gap-3 text-sm\">\n {ok ? (\n <CheckCircle\n size={16}\n className=\"text-status-success-text flex-shrink-0\"\n />\n ) : (\n <div className=\"h-4 w-4 rounded-full border-2 border-muted-foreground flex-shrink-0\" />\n )}\n <span\n className={ok ? \"text-text-primary\" : \"text-text-secondary\"}\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n {!isPublished && (\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/edit`)}\n className=\"mt-4 rounded-md border px-3 py-1.5 text-sm hover:bg-bg-sunken\"\n >\n {tr(\n \"devportal.editToImproveListing\",\n \"Edit to improve listing →\",\n )}\n </button>\n )}\n </PageSection>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ListingPreviewPage.js","names":[],"sources":["../../../src/devportal/pages/ListingPreviewPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Star,\n Download,\n Globe,\n FileText,\n Shield,\n ExternalLink,\n Tag,\n CheckCircle,\n Loader2,\n Eye,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { Alert } from \"../components/ConfirmDialog\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { useGetApplicationQuery } from \"../../generated/global-operations\";\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst PRICING_LABELS: Record<string, string> = {\n FREE: \"Free\",\n FREEMIUM: \"Free with in-app purchases\",\n PAID: \"Paid\",\n ONE_TIME: \"One-time purchase\",\n SUBSCRIPTION: \"Subscription\",\n USAGE_BASED: \"Usage-based pricing\",\n ENTERPRISE: \"Enterprise pricing\",\n};\n\nconst APP_TYPE_LABELS: Record<string, string> = {\n WORKFLOW: \"Workflow\",\n WIDGET: \"Widget\",\n BOT: \"Bot / Chatbot\",\n API_INTEGRATION: \"API Integration\",\n INTEGRATION: \"Integration\",\n ANALYST: \"AI Analyst\",\n ASSISTANT: \"AI Assistant\",\n AUTOMATION: \"Automation\",\n SPECIALIST: \"AI Specialist\",\n WEB_APP: \"Web App\",\n MOBILE_APP: \"Mobile App\",\n DESKTOP_APP: \"Desktop App\",\n CLI_TOOL: \"CLI Tool\",\n SERVICE: \"Service\",\n};\n\n// ============================================================================\n// Listing Preview Page\n// ============================================================================\n\nexport const ListingPreviewPage: FC = () => {\n const { appId } = useParams<{ appId: 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 { data, loading, error } = useGetApplicationQuery({\n variables: { id: appId! },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const app = data?.application;\n\n useEffect(() => {\n const name = app?.name;\n if (!appId || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(appId, name);\n return () => reg?.unregister(appId);\n }, [appId, app?.name]);\n\n if (loading) {\n return (\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\"devportal.loading\", \"Loading...\")}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\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.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\n \"devportal.couldNotLoadApplication\",\n \"Could not load application\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <Alert\n variant=\"error\"\n title={tr(\n \"devportal.failedToLoadApplication\",\n \"Failed to load application\",\n )}\n >\n {error?.message ??\n tr(\"devportal.applicationNotFound\", \"Application not found\")}\n </Alert>\n </PageLayout>\n );\n }\n\n const screenshots = Array.isArray(app.screenshots)\n ? (app.screenshots as string[])\n : [];\n\n const isPublished = app.status === \"PUBLISHED\";\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\n \"devportal.marketplacePreviewDescription\",\n \"Preview how your app will appear in the marketplace\",\n )}\n purpose={tr(\n \"devportal.marketplacePreviewPurpose\",\n \"See exactly how shoppers will experience your store listing — icon, screenshots, description, and pricing — before it goes live. Use it to catch missing assets or typos, then submit for review when the listing looks right.\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n !isPublished ? (\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/publish`)}\n 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\"\n >\n <Eye size={16} />\n {tr(\"devportal.submitForReview\", \"Submit for Review\")}\n </button>\n ) : undefined\n }\n >\n {/* Preview banner */}\n <div className=\"flex items-center gap-2 rounded-lg border border-border-subtle bg-status-warning-bg-subtle px-4 py-3 text-sm text-status-warning-text\">\n <Eye size={16} className=\"flex-shrink-0\" />\n <span>\n {tr(\n \"devportal.previewBannerText\",\n \"This is a preview of your marketplace listing. It shows how your app will appear to users after publication.\",\n )}\n </span>\n </div>\n\n {/* === Simulated marketplace product page === */}\n <div className=\"rounded-xl border bg-bg-surface overflow-hidden\">\n {/* Banner */}\n {app.bannerUrl ? (\n <div className=\"h-48 w-full overflow-hidden\">\n <img\n src={app.bannerUrl}\n alt={tr(\"devportal.appBannerAlt\", \"App banner\")}\n className=\"h-full w-full object-cover\"\n />\n </div>\n ) : (\n <div className=\"h-32 w-full bg-gradient-to-r from-primary/20 to-primary/5\" />\n )}\n\n {/* Hero */}\n <div className=\"p-6\">\n <div className=\"flex items-start gap-5\">\n {app.iconUrl ? (\n <img\n src={app.iconUrl}\n alt={app.name}\n className=\"h-20 w-20 rounded-2xl border object-cover flex-shrink-0 shadow-sm\"\n />\n ) : (\n <div className=\"h-20 w-20 rounded-2xl border bg-bg-sunken flex items-center justify-center flex-shrink-0\">\n <span\n className=\"text-3xl font-bold text-text-secondary\"\n aria-label={tr(\n \"devportal.appIconFallbackAriaLabel\",\n \"App icon\",\n )}\n >\n {app.name.charAt(0).toUpperCase()}\n </span>\n </div>\n )}\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"text-2xl font-bold\">{app.name}</h1>\n {app.isVerified && (\n <CheckCircle size={20} className=\"text-primary\" />\n )}\n {app.isFeatured && (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n {tr(\"devportal.featured\", \"Featured\")}\n </span>\n )}\n </div>\n\n <p className=\"mt-1 text-text-secondary\">\n {app.shortDescription ??\n app.description ??\n tr(\"devportal.noDescription\", \"No description\")}\n </p>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-4 text-sm text-text-secondary\">\n {app.averageRating != null && (\n <div className=\"flex items-center gap-1\">\n <Star\n size={14}\n className=\"text-status-warning-text fill-status-warning-text\"\n />\n <span className=\"font-medium text-text-primary\">\n {app.averageRating.toFixed(1)}\n </span>\n <span>\n ({app.reviewCount ?? 0}{\" \"}\n {tr(\"devportal.reviews\", \"reviews\")})\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-1\">\n <Download size={14} />\n <span>\n {(app.installCount ?? 0).toLocaleString()}{\" \"}\n {tr(\"devportal.installs\", \"installs\")}\n </span>\n </div>\n {app.category && (\n <span className=\"rounded-full border px-2 py-0.5 text-xs\">\n {app.category}\n </span>\n )}\n <span className=\"rounded-full border px-2 py-0.5 text-xs\">\n {APP_TYPE_LABELS[app.appType] ?? app.appType}\n </span>\n </div>\n </div>\n\n {/* Install CTA (simulated) */}\n <div className=\"flex-shrink-0 text-right space-y-2\">\n <div className=\"text-lg font-semibold\">\n {PRICING_LABELS[app.pricingType ?? \"FREE\"] ?? \"Free\"}\n </div>\n <button\n disabled\n className=\"w-full rounded-lg bg-action-primary-bg px-6 py-2 text-sm font-semibold text-action-primary-text opacity-60 cursor-not-allowed\"\n title={tr(\"devportal.previewOnly\", \"Preview only\")}\n >\n {tr(\"devportal.install\", \"Install\")}\n </button>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.previewOnly\", \"Preview only\")}\n </p>\n </div>\n </div>\n </div>\n\n {/* Screenshots */}\n {screenshots.length > 0 && (\n <div className=\"border-t px-6 py-5\">\n <h2 className=\"text-base font-semibold mb-3\">\n {tr(\"devportal.screenshots\", \"Screenshots\")}\n </h2>\n <div className=\"flex gap-3 overflow-x-auto pb-2\">\n {screenshots.map((url, i) => (\n <img\n key={i}\n src={url}\n alt={`${tr(\"devportal.screenshotAlt\", \"Screenshot\")} ${i + 1}`}\n className=\"h-44 w-auto rounded-lg border object-cover flex-shrink-0\"\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Description */}\n <div className=\"border-t px-6 py-5\">\n <h2 className=\"text-base font-semibold mb-2\">\n {tr(\"devportal.about\", \"About\")}\n </h2>\n <p className=\"text-sm text-text-secondary whitespace-pre-wrap\">\n {app.description ??\n app.shortDescription ??\n tr(\n \"devportal.noDetailedDescription\",\n \"No detailed description provided.\",\n )}\n </p>\n </div>\n\n {/* Tags */}\n {Array.isArray(app.tags) && app.tags.length > 0 && (\n <div className=\"border-t px-6 py-4\">\n <div className=\"flex flex-wrap gap-2\">\n {(app.tags as string[]).map((tag) => (\n <span\n key={tag}\n className=\"inline-flex items-center gap-1 rounded-full border px-3 py-1 text-xs text-text-secondary\"\n >\n <Tag size={10} />\n {tag}\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Links & Compliance */}\n <div className=\"border-t px-6 py-5 grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n {app.websiteUrl && (\n <a\n href={app.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <Globe size={14} />\n {tr(\"devportal.website\", \"Website\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.documentationUrl && (\n <a\n href={app.documentationUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <FileText size={14} />\n {tr(\"devportal.documentation\", \"Documentation\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.privacyPolicyUrl && (\n <a\n href={app.privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <Shield size={14} />\n {tr(\"devportal.privacyPolicy\", \"Privacy Policy\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.termsOfServiceUrl && (\n <a\n href={app.termsOfServiceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <FileText size={14} />\n {tr(\"devportal.termsOfService\", \"Terms of Service\")}\n <ExternalLink size={12} />\n </a>\n )}\n </div>\n </div>\n\n {/* Completeness tips */}\n <PageSection\n title={tr(\"devportal.listingCompleteness\", \"Listing Completeness\")}\n >\n <div className=\"space-y-2\">\n {[\n {\n label: tr(\"devportal.completenessAppIcon\", \"App icon\"),\n ok: !!app.iconUrl,\n },\n {\n label: tr(\"devportal.completenessBannerImage\", \"Banner image\"),\n ok: !!app.bannerUrl,\n },\n {\n label: tr(\n \"devportal.completenessShortDescription\",\n \"Short description\",\n ),\n ok: !!app.shortDescription,\n },\n {\n label: tr(\n \"devportal.completenessFullDescription\",\n \"Full description\",\n ),\n ok: !!app.description,\n },\n {\n label: tr(\n \"devportal.completenessScreenshots\",\n \"Screenshots (3+)\",\n ),\n ok: screenshots.length >= 3,\n },\n {\n label: tr(\"devportal.completenessCategory\", \"Category\"),\n ok: !!app.category,\n },\n {\n label: tr(\"devportal.completenessTags\", \"Tags\"),\n ok:\n Array.isArray(app.tags) && (app.tags as string[]).length > 0,\n },\n {\n label: tr(\n \"devportal.completenessPrivacyPolicy\",\n \"Privacy policy URL\",\n ),\n ok: !!app.privacyPolicyUrl,\n },\n {\n label: tr(\n \"devportal.completenessTermsOfService\",\n \"Terms of service URL\",\n ),\n ok: !!app.termsOfServiceUrl,\n },\n ].map(({ label, ok }) => (\n <div key={label} className=\"flex items-center gap-3 text-sm\">\n {ok ? (\n <CheckCircle\n size={16}\n className=\"text-status-success-text flex-shrink-0\"\n />\n ) : (\n <div className=\"h-4 w-4 rounded-full border-2 border-muted-foreground flex-shrink-0\" />\n )}\n <span\n className={ok ? \"text-text-primary\" : \"text-text-secondary\"}\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n {!isPublished && (\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/edit`)}\n className=\"mt-4 rounded-md border px-3 py-1.5 text-sm hover:bg-bg-sunken\"\n >\n {tr(\n \"devportal.editToImproveListing\",\n \"Edit to improve listing →\",\n )}\n </button>\n )}\n </PageSection>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OAuthClientDetailPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OAuthClientDetailPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"OAuthClientDetailPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OAuthClientDetailPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AA6ChC;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,EA8ZnC,CAAC"}
|
|
@@ -1,304 +1,303 @@
|
|
|
1
1
|
import { useDevportal as e } from "../providers/DevportalProvider.js";
|
|
2
2
|
import { cn as t } from "../utils/cn.js";
|
|
3
|
-
import { useDeactivateAppMutation as n, useGetAuthAppQuery as
|
|
4
|
-
import { getErrorMessage as
|
|
3
|
+
import { useDeactivateAppMutation as n, useGetAuthAppQuery as r, useRotateAppSecretMutation as i, useUpdateAuthAppMutation as a } from "../../generated/global-operations.js";
|
|
4
|
+
import { getErrorMessage as ee } from "../hooks/useGraphQL.js";
|
|
5
5
|
import { PageLayout as o } from "../components/PageLayout.js";
|
|
6
6
|
import { ActiveIndicator as te } from "../components/StatusBadge.js";
|
|
7
|
-
import { nativeCopyText as
|
|
8
|
-
import { PermissionGuard as
|
|
7
|
+
import { nativeCopyText as s, nativeImpact as c, nativeNotify as l } from "../../utils/nativeBridge.js";
|
|
8
|
+
import { PermissionGuard as ne } from "../components/PermissionGuard.js";
|
|
9
9
|
import "../components/index.js";
|
|
10
|
-
import { DEVPORTAL_PERMISSIONS as s } from "../constants/permissions.js";
|
|
11
10
|
import "../hooks/index.js";
|
|
12
|
-
import { useState as
|
|
13
|
-
import { useI18n as
|
|
14
|
-
import { AlertCircle as
|
|
15
|
-
import { useParams as
|
|
16
|
-
import { jsx as
|
|
17
|
-
import { AlertDialog as
|
|
11
|
+
import { useState as u } from "react";
|
|
12
|
+
import { useI18n as re } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
13
|
+
import { AlertCircle as ie, ArrowLeft as ae, Copy as d, Eye as f, EyeOff as p, Loader2 as m, RefreshCw as h, Trash2 as g } from "lucide-react";
|
|
14
|
+
import { useParams as _ } from "react-router-dom";
|
|
15
|
+
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
16
|
+
import { AlertDialog as b, AlertDialogAction as x, AlertDialogCancel as S, AlertDialogContent as C, AlertDialogDescription as w, AlertDialogFooter as T, AlertDialogHeader as E, AlertDialogTitle as D, CTAOverflowMenu as O, GlassCard as k } from "@burdenoff/fe-libs/ui";
|
|
18
17
|
//#region src/devportal/pages/OAuthClientDetailPage.tsx
|
|
19
|
-
var
|
|
20
|
-
let { clientId:
|
|
21
|
-
let n =
|
|
18
|
+
var A = () => {
|
|
19
|
+
let { clientId: A } = _(), { navigate: j, basePath: M } = e(), { t: N } = re(), P = (e, t) => {
|
|
20
|
+
let n = N(e);
|
|
22
21
|
return n === e ? t : n;
|
|
23
|
-
}, [
|
|
24
|
-
variables: { id:
|
|
25
|
-
skip: !
|
|
22
|
+
}, [F, I] = u(!1), [L, R] = u(null), [z, B] = u(!1), [V, H] = u(!1), { data: U, loading: W, error: G, refetch: K } = r({
|
|
23
|
+
variables: { id: A || "" },
|
|
24
|
+
skip: !A,
|
|
26
25
|
fetchPolicy: "cache-and-network"
|
|
27
|
-
}), [
|
|
28
|
-
id:
|
|
29
|
-
name:
|
|
30
|
-
description:
|
|
31
|
-
clientId:
|
|
32
|
-
type:
|
|
33
|
-
status:
|
|
34
|
-
scopes:
|
|
35
|
-
redirectUris:
|
|
36
|
-
ownerUserId:
|
|
37
|
-
tenantId:
|
|
38
|
-
createdAt:
|
|
39
|
-
updatedAt:
|
|
40
|
-
} : null,
|
|
41
|
-
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
},
|
|
45
|
-
if (
|
|
46
|
-
let e = (await
|
|
47
|
-
e && (
|
|
26
|
+
}), [q, { loading: J }] = i(), [Y, { loading: X }] = n(), [oe] = a(), Z = U?.app ? {
|
|
27
|
+
id: U.app.id,
|
|
28
|
+
name: U.app.name,
|
|
29
|
+
description: U.app.description ?? void 0,
|
|
30
|
+
clientId: U.app.clientId,
|
|
31
|
+
type: U.app.type,
|
|
32
|
+
status: U.app.status,
|
|
33
|
+
scopes: U.app.scopes ?? [],
|
|
34
|
+
redirectUris: U.app.redirectUris ?? [],
|
|
35
|
+
ownerUserId: U.app.ownerUserId,
|
|
36
|
+
tenantId: U.app.tenantId,
|
|
37
|
+
createdAt: U.app.createdAt,
|
|
38
|
+
updatedAt: U.app.updatedAt
|
|
39
|
+
} : null, Q = (e) => {
|
|
40
|
+
j?.(`${M}${e}`);
|
|
41
|
+
}, $ = async (e) => {
|
|
42
|
+
c("light"), l(await s(e) ? "success" : "error");
|
|
43
|
+
}, se = async () => {
|
|
44
|
+
if (A) try {
|
|
45
|
+
let e = (await q({ variables: { id: A } })).data?.rotateAppSecret?.clientSecret;
|
|
46
|
+
e && (R(e), I(!0)), H(!1), K();
|
|
48
47
|
} catch {}
|
|
49
|
-
},
|
|
50
|
-
if (
|
|
51
|
-
await
|
|
48
|
+
}, ce = async () => {
|
|
49
|
+
if (A) try {
|
|
50
|
+
await Y({ variables: { id: A } }), B(!1), Q("/oauth");
|
|
52
51
|
} catch {}
|
|
53
52
|
};
|
|
54
|
-
return
|
|
55
|
-
title:
|
|
56
|
-
description:
|
|
53
|
+
return W && !U ? /* @__PURE__ */ v(o, {
|
|
54
|
+
title: P("devportal.appDetails", "App Details"),
|
|
55
|
+
description: P("devportal.loadingDots", "Loading..."),
|
|
57
56
|
backLink: "/oauth",
|
|
58
|
-
backLabel:
|
|
59
|
-
children: /* @__PURE__ */
|
|
57
|
+
backLabel: P("devportal.backToApps", "Back to Apps"),
|
|
58
|
+
children: /* @__PURE__ */ v("div", {
|
|
60
59
|
className: "flex items-center justify-center py-12",
|
|
61
|
-
children: /* @__PURE__ */
|
|
60
|
+
children: /* @__PURE__ */ v(m, { className: "h-8 w-8 animate-spin text-text-secondary" })
|
|
62
61
|
})
|
|
63
|
-
}) :
|
|
64
|
-
title:
|
|
65
|
-
description:
|
|
62
|
+
}) : G || !Z ? /* @__PURE__ */ v(o, {
|
|
63
|
+
title: P("devportal.appDetails", "App Details"),
|
|
64
|
+
description: P("devportal.failedToLoad", "Failed to load"),
|
|
66
65
|
backLink: "/oauth",
|
|
67
|
-
backLabel:
|
|
68
|
-
children: /* @__PURE__ */
|
|
66
|
+
backLabel: P("devportal.backToApps", "Back to Apps"),
|
|
67
|
+
children: /* @__PURE__ */ y("div", {
|
|
69
68
|
className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center",
|
|
70
69
|
children: [
|
|
71
|
-
/* @__PURE__ */
|
|
72
|
-
/* @__PURE__ */
|
|
70
|
+
/* @__PURE__ */ v(ie, { className: "mx-auto h-8 w-8 text-status-error-text" }),
|
|
71
|
+
/* @__PURE__ */ v("h3", {
|
|
73
72
|
className: "mt-2 font-medium text-status-error-text",
|
|
74
|
-
children:
|
|
73
|
+
children: G ? P("devportal.failedToLoadApp", "Failed to load app") : P("devportal.appNotFound", "App not found")
|
|
75
74
|
}),
|
|
76
|
-
|
|
75
|
+
G && /* @__PURE__ */ v("p", {
|
|
77
76
|
className: "mt-1 text-sm text-text-secondary",
|
|
78
|
-
children:
|
|
77
|
+
children: ee(G)
|
|
79
78
|
}),
|
|
80
|
-
/* @__PURE__ */
|
|
81
|
-
onClick: () =>
|
|
79
|
+
/* @__PURE__ */ y("button", {
|
|
80
|
+
onClick: () => Q("/oauth"),
|
|
82
81
|
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",
|
|
83
|
-
children: [/* @__PURE__ */
|
|
82
|
+
children: [/* @__PURE__ */ v(ae, { size: 16 }), P("devportal.backToApps", "Back to Apps")]
|
|
84
83
|
})
|
|
85
84
|
]
|
|
86
85
|
})
|
|
87
|
-
}) : /* @__PURE__ */
|
|
88
|
-
|
|
89
|
-
children: /* @__PURE__ */
|
|
90
|
-
title:
|
|
91
|
-
description:
|
|
92
|
-
purpose:
|
|
86
|
+
}) : /* @__PURE__ */ v(ne, {
|
|
87
|
+
authOnly: !0,
|
|
88
|
+
children: /* @__PURE__ */ y(o, {
|
|
89
|
+
title: Z.name,
|
|
90
|
+
description: Z.description || P("devportal.oauthAppDetailsAndCredentials", "OAuth App details and credentials"),
|
|
91
|
+
purpose: P("devportal.oauthAppDetailPurpose", "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."),
|
|
93
92
|
backLink: "/oauth",
|
|
94
|
-
backLabel:
|
|
95
|
-
actions: /* @__PURE__ */
|
|
93
|
+
backLabel: P("devportal.backToApps", "Back to Apps"),
|
|
94
|
+
actions: /* @__PURE__ */ v(O, {
|
|
96
95
|
primary: {
|
|
97
|
-
label:
|
|
96
|
+
label: Z.status === "ACTIVE" ? P("devportal.deactivate", "Deactivate") : P("devportal.activate", "Activate"),
|
|
98
97
|
onSelect: async () => {
|
|
99
|
-
if (!
|
|
100
|
-
let e =
|
|
98
|
+
if (!A || !Z) return;
|
|
99
|
+
let e = Z.status === "ACTIVE" ? "INACTIVE" : "ACTIVE";
|
|
101
100
|
try {
|
|
102
|
-
await
|
|
103
|
-
id:
|
|
101
|
+
await oe({ variables: {
|
|
102
|
+
id: A,
|
|
104
103
|
input: { status: e }
|
|
105
|
-
} }),
|
|
104
|
+
} }), K();
|
|
106
105
|
} catch {}
|
|
107
106
|
}
|
|
108
107
|
},
|
|
109
108
|
actions: [{
|
|
110
|
-
label:
|
|
111
|
-
icon: /* @__PURE__ */
|
|
109
|
+
label: P("devportal.delete", "Delete"),
|
|
110
|
+
icon: /* @__PURE__ */ v(g, { size: 16 }),
|
|
112
111
|
intent: "destructive",
|
|
113
|
-
onSelect: () =>
|
|
112
|
+
onSelect: () => B(!0)
|
|
114
113
|
}]
|
|
115
114
|
}),
|
|
116
115
|
children: [
|
|
117
|
-
/* @__PURE__ */
|
|
116
|
+
/* @__PURE__ */ y("div", {
|
|
118
117
|
className: "grid gap-6 md:grid-cols-2",
|
|
119
|
-
children: [/* @__PURE__ */
|
|
118
|
+
children: [/* @__PURE__ */ y("div", {
|
|
120
119
|
className: "rounded-card border border-border-seam bg-bg-surface p-6",
|
|
121
|
-
children: [/* @__PURE__ */
|
|
120
|
+
children: [/* @__PURE__ */ v("h3", {
|
|
122
121
|
className: "text-sm font-medium text-text-secondary mb-4",
|
|
123
|
-
children:
|
|
124
|
-
}), /* @__PURE__ */
|
|
122
|
+
children: P("devportal.statusAndConfiguration", "Status & Configuration")
|
|
123
|
+
}), /* @__PURE__ */ y("div", {
|
|
125
124
|
className: "space-y-3",
|
|
126
125
|
children: [
|
|
127
|
-
/* @__PURE__ */
|
|
126
|
+
/* @__PURE__ */ y("div", {
|
|
128
127
|
className: "flex justify-between",
|
|
129
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ v("span", {
|
|
130
129
|
className: "text-sm text-text-secondary",
|
|
131
|
-
children:
|
|
132
|
-
}), /* @__PURE__ */
|
|
130
|
+
children: P("devportal.status", "Status")
|
|
131
|
+
}), /* @__PURE__ */ y("div", {
|
|
133
132
|
className: "flex items-center gap-2",
|
|
134
|
-
children: [/* @__PURE__ */
|
|
133
|
+
children: [/* @__PURE__ */ v(te, { active: Z.status === "ACTIVE" }), /* @__PURE__ */ v("span", {
|
|
135
134
|
className: "text-sm font-medium",
|
|
136
|
-
children:
|
|
135
|
+
children: Z.status
|
|
137
136
|
})]
|
|
138
137
|
})]
|
|
139
138
|
}),
|
|
140
|
-
/* @__PURE__ */
|
|
139
|
+
/* @__PURE__ */ y("div", {
|
|
141
140
|
className: "flex justify-between",
|
|
142
|
-
children: [/* @__PURE__ */
|
|
141
|
+
children: [/* @__PURE__ */ v("span", {
|
|
143
142
|
className: "text-sm text-text-secondary",
|
|
144
|
-
children:
|
|
145
|
-
}), /* @__PURE__ */
|
|
146
|
-
className: t("rounded px-2 py-0.5 text-xs font-medium",
|
|
147
|
-
children:
|
|
143
|
+
children: P("devportal.type", "Type")
|
|
144
|
+
}), /* @__PURE__ */ v("span", {
|
|
145
|
+
className: t("rounded px-2 py-0.5 text-xs font-medium", Z.type === "SERVICE" ? "bg-accent-purple-subtle text-accent-purple" : Z.type === "INTEGRATION" || Z.type === "API_INTEGRATION" ? "bg-status-info-bg-subtle text-status-info-text" : "bg-status-success-bg-subtle text-status-success-text"),
|
|
146
|
+
children: Z.type
|
|
148
147
|
})]
|
|
149
148
|
}),
|
|
150
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ y("div", {
|
|
151
150
|
className: "flex justify-between",
|
|
152
|
-
children: [/* @__PURE__ */
|
|
151
|
+
children: [/* @__PURE__ */ v("span", {
|
|
153
152
|
className: "text-sm text-text-secondary",
|
|
154
|
-
children:
|
|
155
|
-
}), /* @__PURE__ */
|
|
153
|
+
children: P("devportal.created", "Created")
|
|
154
|
+
}), /* @__PURE__ */ v("span", {
|
|
156
155
|
className: "text-sm",
|
|
157
|
-
children: new Date(
|
|
156
|
+
children: new Date(Z.createdAt).toLocaleDateString()
|
|
158
157
|
})]
|
|
159
158
|
})
|
|
160
159
|
]
|
|
161
160
|
})]
|
|
162
|
-
}), /* @__PURE__ */
|
|
161
|
+
}), /* @__PURE__ */ y(k, {
|
|
163
162
|
treatment: "glass",
|
|
164
163
|
glow: !0,
|
|
165
164
|
className: "p-6",
|
|
166
|
-
children: [/* @__PURE__ */
|
|
165
|
+
children: [/* @__PURE__ */ v("h3", {
|
|
167
166
|
className: "text-sm font-medium text-text-secondary mb-4",
|
|
168
|
-
children:
|
|
169
|
-
}), /* @__PURE__ */
|
|
167
|
+
children: P("devportal.credentials", "Credentials")
|
|
168
|
+
}), /* @__PURE__ */ y("div", {
|
|
170
169
|
className: "space-y-3",
|
|
171
170
|
children: [
|
|
172
|
-
/* @__PURE__ */
|
|
171
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
173
172
|
className: "text-xs text-text-secondary",
|
|
174
|
-
children:
|
|
175
|
-
}), /* @__PURE__ */
|
|
173
|
+
children: P("devportal.clientId", "Client ID")
|
|
174
|
+
}), /* @__PURE__ */ y("div", {
|
|
176
175
|
className: "mt-1 flex items-center gap-2",
|
|
177
|
-
children: [/* @__PURE__ */
|
|
176
|
+
children: [/* @__PURE__ */ v("code", {
|
|
178
177
|
className: "flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono",
|
|
179
|
-
children:
|
|
180
|
-
}), /* @__PURE__ */
|
|
181
|
-
onClick: () =>
|
|
178
|
+
children: Z.clientId
|
|
179
|
+
}), /* @__PURE__ */ v("button", {
|
|
180
|
+
onClick: () => $(Z.clientId),
|
|
182
181
|
className: "rounded p-1.5 hover:bg-bg-sunken transition-colors",
|
|
183
182
|
title: "Copy",
|
|
184
|
-
children: /* @__PURE__ */
|
|
183
|
+
children: /* @__PURE__ */ v(d, { size: 14 })
|
|
185
184
|
})]
|
|
186
185
|
})] }),
|
|
187
|
-
|
|
186
|
+
L && /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
188
187
|
className: "text-xs text-status-error-text font-medium",
|
|
189
|
-
children:
|
|
190
|
-
}), /* @__PURE__ */
|
|
188
|
+
children: P("devportal.newClientSecretShownOnce", "New Client Secret (shown only once!)")
|
|
189
|
+
}), /* @__PURE__ */ y("div", {
|
|
191
190
|
className: "mt-1 flex items-center gap-2",
|
|
192
191
|
children: [
|
|
193
|
-
/* @__PURE__ */
|
|
192
|
+
/* @__PURE__ */ v("code", {
|
|
194
193
|
className: "flex-1 rounded bg-status-error-bg/10 border border-status-error-border/30 px-3 py-1.5 text-sm font-mono",
|
|
195
|
-
children:
|
|
194
|
+
children: F ? L : "••••••••••••••••"
|
|
196
195
|
}),
|
|
197
|
-
/* @__PURE__ */
|
|
198
|
-
onClick: () =>
|
|
196
|
+
/* @__PURE__ */ v("button", {
|
|
197
|
+
onClick: () => I(!F),
|
|
199
198
|
className: "rounded p-1.5 hover:bg-bg-sunken transition-colors",
|
|
200
|
-
children:
|
|
199
|
+
children: v(F ? p : f, { size: 14 })
|
|
201
200
|
}),
|
|
202
|
-
/* @__PURE__ */
|
|
203
|
-
onClick: () =>
|
|
201
|
+
/* @__PURE__ */ v("button", {
|
|
202
|
+
onClick: () => $(L),
|
|
204
203
|
className: "rounded p-1.5 hover:bg-bg-sunken transition-colors",
|
|
205
|
-
children: /* @__PURE__ */
|
|
204
|
+
children: /* @__PURE__ */ v(d, { size: 14 })
|
|
206
205
|
})
|
|
207
206
|
]
|
|
208
207
|
})] }),
|
|
209
|
-
/* @__PURE__ */
|
|
210
|
-
onClick: () =>
|
|
208
|
+
/* @__PURE__ */ y("button", {
|
|
209
|
+
onClick: () => H(!0),
|
|
211
210
|
disabled: J,
|
|
212
211
|
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",
|
|
213
|
-
children: [/* @__PURE__ */
|
|
212
|
+
children: [/* @__PURE__ */ v(h, {
|
|
214
213
|
size: 14,
|
|
215
214
|
className: J ? "animate-spin" : ""
|
|
216
|
-
}),
|
|
215
|
+
}), P("devportal.rotateSecret", "Rotate Secret")]
|
|
217
216
|
})
|
|
218
217
|
]
|
|
219
218
|
})]
|
|
220
219
|
})]
|
|
221
220
|
}),
|
|
222
|
-
/* @__PURE__ */
|
|
221
|
+
/* @__PURE__ */ y("div", {
|
|
223
222
|
className: "rounded-card border border-border-seam bg-bg-surface p-6",
|
|
224
|
-
children: [/* @__PURE__ */
|
|
223
|
+
children: [/* @__PURE__ */ y("h3", {
|
|
225
224
|
className: "text-sm font-medium text-text-secondary mb-3",
|
|
226
225
|
children: [
|
|
227
|
-
|
|
226
|
+
P("devportal.scopes", "Scopes"),
|
|
228
227
|
" (",
|
|
229
|
-
|
|
228
|
+
Z.scopes.length,
|
|
230
229
|
")"
|
|
231
230
|
]
|
|
232
|
-
}),
|
|
231
|
+
}), Z.scopes.length > 0 ? /* @__PURE__ */ v("div", {
|
|
233
232
|
className: "flex flex-wrap gap-2",
|
|
234
|
-
children:
|
|
233
|
+
children: Z.scopes.map((e) => /* @__PURE__ */ v("span", {
|
|
235
234
|
className: "rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary",
|
|
236
235
|
children: e
|
|
237
236
|
}, e))
|
|
238
|
-
}) : /* @__PURE__ */
|
|
237
|
+
}) : /* @__PURE__ */ v("p", {
|
|
239
238
|
className: "text-sm text-text-secondary",
|
|
240
|
-
children:
|
|
239
|
+
children: P("devportal.noScopesConfigured", "No scopes configured")
|
|
241
240
|
})]
|
|
242
241
|
}),
|
|
243
|
-
/* @__PURE__ */
|
|
242
|
+
/* @__PURE__ */ y("div", {
|
|
244
243
|
className: "rounded-card border border-border-seam bg-bg-surface p-6",
|
|
245
|
-
children: [/* @__PURE__ */
|
|
244
|
+
children: [/* @__PURE__ */ y("h3", {
|
|
246
245
|
className: "text-sm font-medium text-text-secondary mb-3",
|
|
247
246
|
children: [
|
|
248
|
-
|
|
247
|
+
P("devportal.redirectUris", "Redirect URIs"),
|
|
249
248
|
" (",
|
|
250
|
-
|
|
249
|
+
Z.redirectUris.length,
|
|
251
250
|
")"
|
|
252
251
|
]
|
|
253
|
-
}),
|
|
252
|
+
}), Z.redirectUris.length > 0 ? /* @__PURE__ */ v("div", {
|
|
254
253
|
className: "space-y-2",
|
|
255
|
-
children:
|
|
254
|
+
children: Z.redirectUris.map((e) => /* @__PURE__ */ y("div", {
|
|
256
255
|
className: "flex items-center gap-2",
|
|
257
|
-
children: [/* @__PURE__ */
|
|
256
|
+
children: [/* @__PURE__ */ v("code", {
|
|
258
257
|
className: "rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono",
|
|
259
258
|
children: e
|
|
260
|
-
}), /* @__PURE__ */
|
|
261
|
-
onClick: () =>
|
|
259
|
+
}), /* @__PURE__ */ v("button", {
|
|
260
|
+
onClick: () => $(e),
|
|
262
261
|
className: "rounded p-1 hover:bg-bg-sunken transition-colors",
|
|
263
|
-
children: /* @__PURE__ */
|
|
262
|
+
children: /* @__PURE__ */ v(d, { size: 12 })
|
|
264
263
|
})]
|
|
265
264
|
}, e))
|
|
266
|
-
}) : /* @__PURE__ */
|
|
265
|
+
}) : /* @__PURE__ */ v("p", {
|
|
267
266
|
className: "text-sm text-text-secondary",
|
|
268
|
-
children:
|
|
267
|
+
children: P("devportal.noRedirectUrisConfigured", "No redirect URIs configured")
|
|
269
268
|
})]
|
|
270
269
|
}),
|
|
271
|
-
/* @__PURE__ */
|
|
272
|
-
open:
|
|
273
|
-
onOpenChange:
|
|
274
|
-
children: /* @__PURE__ */
|
|
270
|
+
/* @__PURE__ */ v(b, {
|
|
271
|
+
open: V,
|
|
272
|
+
onOpenChange: H,
|
|
273
|
+
children: /* @__PURE__ */ y(C, { children: [/* @__PURE__ */ y(E, { children: [/* @__PURE__ */ v(D, { children: P("devportal.rotateClientSecretQuestion", "Rotate Client Secret?") }), /* @__PURE__ */ v(w, { children: P("devportal.rotateSecretWarning", "This will invalidate the current client secret. All integrations using the old secret will stop working immediately.") })] }), /* @__PURE__ */ y(T, { children: [/* @__PURE__ */ v(S, {
|
|
275
274
|
disabled: J,
|
|
276
|
-
children:
|
|
277
|
-
}), /* @__PURE__ */
|
|
275
|
+
children: P("devportal.cancel", "Cancel")
|
|
276
|
+
}), /* @__PURE__ */ v(x, {
|
|
278
277
|
onClick: (e) => {
|
|
279
|
-
e.preventDefault(),
|
|
278
|
+
e.preventDefault(), se();
|
|
280
279
|
},
|
|
281
280
|
disabled: J,
|
|
282
281
|
className: "bg-status-warning-bg text-white hover:bg-status-warning-bg/90",
|
|
283
|
-
children: J ?
|
|
282
|
+
children: J ? P("devportal.rotating", "Rotating...") : P("devportal.rotateSecret", "Rotate Secret")
|
|
284
283
|
})] })] })
|
|
285
284
|
}),
|
|
286
|
-
/* @__PURE__ */
|
|
287
|
-
open:
|
|
288
|
-
onOpenChange:
|
|
289
|
-
children: /* @__PURE__ */
|
|
285
|
+
/* @__PURE__ */ v(b, {
|
|
286
|
+
open: z,
|
|
287
|
+
onOpenChange: B,
|
|
288
|
+
children: /* @__PURE__ */ y(C, { children: [/* @__PURE__ */ y(E, { children: [/* @__PURE__ */ v(D, {
|
|
290
289
|
className: "text-status-error-text",
|
|
291
|
-
children:
|
|
292
|
-
}), /* @__PURE__ */
|
|
293
|
-
disabled:
|
|
294
|
-
children:
|
|
295
|
-
}), /* @__PURE__ */
|
|
290
|
+
children: P("devportal.deactivateAppQuestion", "Deactivate App?")
|
|
291
|
+
}), /* @__PURE__ */ v(w, { children: P("devportal.deactivateAppWarning", "This will deactivate the app and revoke all tokens. This action cannot be undone easily.") })] }), /* @__PURE__ */ y(T, { children: [/* @__PURE__ */ v(S, {
|
|
292
|
+
disabled: X,
|
|
293
|
+
children: P("devportal.cancel", "Cancel")
|
|
294
|
+
}), /* @__PURE__ */ v(x, {
|
|
296
295
|
onClick: (e) => {
|
|
297
|
-
e.preventDefault(),
|
|
296
|
+
e.preventDefault(), ce();
|
|
298
297
|
},
|
|
299
|
-
disabled:
|
|
298
|
+
disabled: X,
|
|
300
299
|
className: "bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90",
|
|
301
|
-
children:
|
|
300
|
+
children: X ? P("devportal.deactivating", "Deactivating...") : P("devportal.deactivate", "Deactivate")
|
|
302
301
|
})] })] })
|
|
303
302
|
})
|
|
304
303
|
]
|
|
@@ -306,6 +305,6 @@ var j = () => {
|
|
|
306
305
|
});
|
|
307
306
|
};
|
|
308
307
|
//#endregion
|
|
309
|
-
export {
|
|
308
|
+
export { A as OAuthClientDetailPage };
|
|
310
309
|
|
|
311
310
|
//# sourceMappingURL=OAuthClientDetailPage.js.map
|