@burdenoff/microfe-devportal 2026.717.1 → 2026.720.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/devportal/components/PermissionGuard.d.ts +14 -1
  2. package/dist/devportal/components/PermissionGuard.d.ts.map +1 -1
  3. package/dist/devportal/components/PermissionGuard.js +16 -13
  4. package/dist/devportal/components/PermissionGuard.js.map +1 -1
  5. package/dist/devportal/pages/AdminReviewPage.js +9 -9
  6. package/dist/devportal/pages/ApiKeysPage.js +180 -181
  7. package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
  8. package/dist/devportal/pages/ApplicationDetailPage.js +3 -3
  9. package/dist/devportal/pages/ApplicationVersionsPage.js +4 -4
  10. package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
  11. package/dist/devportal/pages/ApplicationsPage.js +4 -4
  12. package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
  13. package/dist/devportal/pages/CreateApiKeyPage.js +1 -1
  14. package/dist/devportal/pages/CreateOAuthClientPage.js +1 -1
  15. package/dist/devportal/pages/CreateOrganizationPage.d.ts.map +1 -1
  16. package/dist/devportal/pages/CreateOrganizationPage.js +97 -98
  17. package/dist/devportal/pages/CreateOrganizationPage.js.map +1 -1
  18. package/dist/devportal/pages/CreateWebhookPage.js +25 -25
  19. package/dist/devportal/pages/DashboardPage.d.ts.map +1 -1
  20. package/dist/devportal/pages/DashboardPage.js +110 -111
  21. package/dist/devportal/pages/DashboardPage.js.map +1 -1
  22. package/dist/devportal/pages/DelegationsPage.js +1 -1
  23. package/dist/devportal/pages/EditApplicationPage.js +4 -4
  24. package/dist/devportal/pages/ListingPreviewPage.d.ts.map +1 -1
  25. package/dist/devportal/pages/ListingPreviewPage.js +160 -161
  26. package/dist/devportal/pages/ListingPreviewPage.js.map +1 -1
  27. package/dist/devportal/pages/OAuthClientDetailPage.d.ts.map +1 -1
  28. package/dist/devportal/pages/OAuthClientDetailPage.js +166 -167
  29. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  30. package/dist/devportal/pages/OAuthClientsPage.d.ts.map +1 -1
  31. package/dist/devportal/pages/OAuthClientsPage.js +121 -122
  32. package/dist/devportal/pages/OAuthClientsPage.js.map +1 -1
  33. package/dist/devportal/pages/OrganizationDetailPage.js +3 -3
  34. package/dist/devportal/pages/OrganizationMembersPage.js +4 -4
  35. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  36. package/dist/devportal/pages/OrganizationsPage.d.ts.map +1 -1
  37. package/dist/devportal/pages/OrganizationsPage.js +97 -98
  38. package/dist/devportal/pages/OrganizationsPage.js.map +1 -1
  39. package/dist/devportal/pages/PublishPage.js +246 -246
  40. package/dist/devportal/pages/PublishPage.js.map +1 -1
  41. package/dist/devportal/pages/PublisherProfilePage.js +4 -4
  42. package/dist/devportal/pages/PublisherProfilePage.js.map +1 -1
  43. package/dist/devportal/pages/StoreSubmissionPage.js +3 -3
  44. package/dist/devportal/pages/WebhookDetailPage.js +3 -3
  45. package/dist/devportal/pages/WebhooksPage.js +129 -129
  46. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  47. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"OAuthClientsPage.js","names":[],"sources":["../../../src/devportal/pages/OAuthClientsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { Plus, Search, Shield, Loader2, AlertCircle } from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { ActiveIndicator } from \"../components/StatusBadge\";\nimport { EmptyState } from \"../components/EmptyState\";\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 { useCurrentUserAppsQuery, getErrorMessage } from \"../hooks\";\n\n/**\n * OAuth Apps listing page\n *\n * Displays the current user's OAuth apps from auth-svc.\n * Previously showed devportal-svc OAuthClients per application;\n * now shows all user-owned apps centrally.\n */\nexport const OAuthClientsPage: FC = () => {\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 [searchQuery, setSearchQuery] = useState(\"\");\n const [typeFilter, setTypeFilter] = useState<string>(\"\");\n\n // Fetch apps from auth-svc (user-scoped, no applicationId needed)\n const { data, loading, error, refetch } = useCurrentUserAppsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const apps: AuthApp[] =\n data?.currentUserApps?.apps.map(\n (app: (typeof data.currentUserApps.apps)[number]) => ({\n id: app.id,\n name: app.name,\n description: app.description ?? undefined,\n clientId: app.clientId,\n type: app.type as AuthApp[\"type\"],\n status: app.status as AuthApp[\"status\"],\n scopes: app.scopes ?? [],\n redirectUris: app.redirectUris ?? [],\n ownerUserId: app.ownerUserId,\n tenantId: app.tenantId ?? \"\",\n createdAt: app.createdAt,\n updatedAt: app.updatedAt,\n }),\n ) ?? [];\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Filter apps\n const filteredApps = apps.filter((app) => {\n const matchesSearch =\n !searchQuery ||\n app.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n app.clientId.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesType = !typeFilter || app.type === typeFilter;\n return matchesSearch && matchesType;\n });\n\n // Loading state\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\"devportal.oauthApps\", \"OAuth Apps\")}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingApps\", \"Loading apps...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error) {\n return (\n <PageLayout\n title={tr(\"devportal.oauthApps\", \"OAuth Apps\")}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\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 {tr(\"devportal.failedToLoadApps\", \"Failed to load apps\")}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n <button\n onClick={() => refetch()}\n 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\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n const columns = [\n {\n key: \"name\",\n header: \"App\",\n render: (app: AuthApp) => (\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n \"flex h-10 w-10 items-center justify-center rounded-lg\",\n app.status === \"ACTIVE\"\n ? \"bg-action-primary-bg/10 text-primary\"\n : \"bg-bg-sunken text-text-tertiary\",\n )}\n >\n <Shield size={20} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <p className=\"font-medium\">{app.name}</p>\n <span\n className={cn(\n \"rounded px-1.5 py-0.5 text-xs\",\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 <code className=\"text-xs text-text-secondary\">{app.clientId}</code>\n </div>\n </div>\n ),\n },\n {\n key: \"scopes\",\n header: \"Scopes\",\n render: (app: AuthApp) => (\n <div className=\"flex flex-wrap gap-1\">\n {app.scopes.slice(0, 3).map((scope) => (\n <span\n key={scope}\n className=\"inline-flex rounded bg-bg-sunken px-1.5 py-0.5 text-xs\"\n >\n {scope}\n </span>\n ))}\n {app.scopes.length > 3 && (\n <span className=\"text-xs text-text-secondary\">\n +{app.scopes.length - 3}\n </span>\n )}\n </div>\n ),\n },\n {\n key: \"redirectUris\",\n header: \"Redirect URIs\",\n render: (app: AuthApp) => (\n <span className=\"text-sm\">\n {app.redirectUris.length} URI\n {app.redirectUris.length !== 1 ? \"s\" : \"\"}\n </span>\n ),\n },\n {\n key: \"status\",\n header: \"Status\",\n render: (app: AuthApp) => (\n <div className=\"flex items-center gap-2\">\n <ActiveIndicator active={app.status === \"ACTIVE\"} />\n <span className=\"text-sm\">{app.status}</span>\n </div>\n ),\n },\n ];\n\n // Stats\n const stats = {\n total: apps.length,\n active: apps.filter((a) => a.status === \"ACTIVE\").length,\n integration: apps.filter(\n (a) => a.type === \"INTEGRATION\" || a.type === \"API_INTEGRATION\",\n ).length,\n service: apps.filter((a) => a.type === \"SERVICE\").length,\n };\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.APP_READ}>\n <PageLayout\n title={tr(\"devportal.oauthApps\", \"OAuth Apps\")}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n purpose={tr(\n \"devportal.oauthAppsPurpose\",\n \"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.\",\n )}\n actions={\n <button\n onClick={() => handleNavigate(\"/oauth/new\")}\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 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n </button>\n }\n >\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-1 items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n />\n <input\n type=\"text\"\n placeholder={tr(\n \"devportal.searchByNameOrClientId\",\n \"Search by name or client ID...\",\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n 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\"\n />\n </div>\n <select\n value={typeFilter}\n onChange={(e) => setTypeFilter(e.target.value)}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"\">{tr(\"devportal.allTypes\", \"All Types\")}</option>\n <option value=\"SERVICE\">\n {tr(\"devportal.service\", \"Service\")}\n </option>\n <option value=\"INTEGRATION\">\n {tr(\"devportal.integration\", \"Integration\")}\n </option>\n <option value=\"BOT\">{tr(\"devportal.bot\", \"Bot\")}</option>\n <option value=\"WEB_APP\">\n {tr(\"devportal.webApp\", \"Web App\")}\n </option>\n <option value=\"AUTOMATION\">\n {tr(\"devportal.automation\", \"Automation\")}\n </option>\n </select>\n </div>\n </div>\n\n {/* Summary Stats — primary emphasis zone */}\n <EmphasisPanel>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-text-secondary\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.totalApps\", \"Total Apps\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.total}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-status-success-text\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.active\", \"Active\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.active}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-accent-blue\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.integration\", \"Integration\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.integration}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-accent-purple\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.service\", \"Service\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.service}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n\n <p className=\"text-sm text-text-secondary\">\n {filteredApps.length}{\" \"}\n {filteredApps.length !== 1\n ? tr(\"devportal.appsFound\", \"apps found\")\n : tr(\"devportal.appFound\", \"app found\")}\n </p>\n\n {/* Apps Table */}\n {filteredApps.length > 0 ? (\n <DataTable\n data={filteredApps}\n columns={columns}\n keyField=\"id\"\n onRowClick={(app) => handleNavigate(`/oauth/${app.id}`)}\n />\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={tr(\"devportal.noOAuthAppsFound\", \"No OAuth apps found\")}\n description={\n searchQuery || typeFilter\n ? tr(\n \"devportal.tryAdjustingFilters\",\n \"Try adjusting your filters\",\n )\n : tr(\n \"devportal.createFirstOAuthApp\",\n \"Create your first OAuth app to enable authentication\",\n )\n }\n action={\n !searchQuery && !typeFilter ? (\n <button\n onClick={() => handleNavigate(\"/oauth/new\")}\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 <Plus size={16} />\n {tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n </button>\n ) : undefined\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OAuthClientsPage.js","names":[],"sources":["../../../src/devportal/pages/OAuthClientsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { Plus, Search, Shield, Loader2, AlertCircle } from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { ActiveIndicator } from \"../components/StatusBadge\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport type { AuthApp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { useCurrentUserAppsQuery, getErrorMessage } from \"../hooks\";\n\n/**\n * OAuth Apps listing page\n *\n * Displays the current user's OAuth apps from auth-svc.\n * Previously showed devportal-svc OAuthClients per application;\n * now shows all user-owned apps centrally.\n */\nexport const OAuthClientsPage: FC = () => {\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 [searchQuery, setSearchQuery] = useState(\"\");\n const [typeFilter, setTypeFilter] = useState<string>(\"\");\n\n // Fetch apps from auth-svc (user-scoped, no applicationId needed)\n const { data, loading, error, refetch } = useCurrentUserAppsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const apps: AuthApp[] =\n data?.currentUserApps?.apps.map(\n (app: (typeof data.currentUserApps.apps)[number]) => ({\n id: app.id,\n name: app.name,\n description: app.description ?? undefined,\n clientId: app.clientId,\n type: app.type as AuthApp[\"type\"],\n status: app.status as AuthApp[\"status\"],\n scopes: app.scopes ?? [],\n redirectUris: app.redirectUris ?? [],\n ownerUserId: app.ownerUserId,\n tenantId: app.tenantId ?? \"\",\n createdAt: app.createdAt,\n updatedAt: app.updatedAt,\n }),\n ) ?? [];\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Filter apps\n const filteredApps = apps.filter((app) => {\n const matchesSearch =\n !searchQuery ||\n app.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n app.clientId.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesType = !typeFilter || app.type === typeFilter;\n return matchesSearch && matchesType;\n });\n\n // Loading state\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\"devportal.oauthApps\", \"OAuth Apps\")}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingApps\", \"Loading apps...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error) {\n return (\n <PageLayout\n title={tr(\"devportal.oauthApps\", \"OAuth Apps\")}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\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 {tr(\"devportal.failedToLoadApps\", \"Failed to load apps\")}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n <button\n onClick={() => refetch()}\n 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\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n const columns = [\n {\n key: \"name\",\n header: \"App\",\n render: (app: AuthApp) => (\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n \"flex h-10 w-10 items-center justify-center rounded-lg\",\n app.status === \"ACTIVE\"\n ? \"bg-action-primary-bg/10 text-primary\"\n : \"bg-bg-sunken text-text-tertiary\",\n )}\n >\n <Shield size={20} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <p className=\"font-medium\">{app.name}</p>\n <span\n className={cn(\n \"rounded px-1.5 py-0.5 text-xs\",\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 <code className=\"text-xs text-text-secondary\">{app.clientId}</code>\n </div>\n </div>\n ),\n },\n {\n key: \"scopes\",\n header: \"Scopes\",\n render: (app: AuthApp) => (\n <div className=\"flex flex-wrap gap-1\">\n {app.scopes.slice(0, 3).map((scope) => (\n <span\n key={scope}\n className=\"inline-flex rounded bg-bg-sunken px-1.5 py-0.5 text-xs\"\n >\n {scope}\n </span>\n ))}\n {app.scopes.length > 3 && (\n <span className=\"text-xs text-text-secondary\">\n +{app.scopes.length - 3}\n </span>\n )}\n </div>\n ),\n },\n {\n key: \"redirectUris\",\n header: \"Redirect URIs\",\n render: (app: AuthApp) => (\n <span className=\"text-sm\">\n {app.redirectUris.length} URI\n {app.redirectUris.length !== 1 ? \"s\" : \"\"}\n </span>\n ),\n },\n {\n key: \"status\",\n header: \"Status\",\n render: (app: AuthApp) => (\n <div className=\"flex items-center gap-2\">\n <ActiveIndicator active={app.status === \"ACTIVE\"} />\n <span className=\"text-sm\">{app.status}</span>\n </div>\n ),\n },\n ];\n\n // Stats\n const stats = {\n total: apps.length,\n active: apps.filter((a) => a.status === \"ACTIVE\").length,\n integration: apps.filter(\n (a) => a.type === \"INTEGRATION\" || a.type === \"API_INTEGRATION\",\n ).length,\n service: apps.filter((a) => a.type === \"SERVICE\").length,\n };\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.oauthApps\", \"OAuth Apps\")}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n purpose={tr(\n \"devportal.oauthAppsPurpose\",\n \"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.\",\n )}\n actions={\n <button\n onClick={() => handleNavigate(\"/oauth/new\")}\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 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n </button>\n }\n >\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-1 items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n />\n <input\n type=\"text\"\n placeholder={tr(\n \"devportal.searchByNameOrClientId\",\n \"Search by name or client ID...\",\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n 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\"\n />\n </div>\n <select\n value={typeFilter}\n onChange={(e) => setTypeFilter(e.target.value)}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"\">{tr(\"devportal.allTypes\", \"All Types\")}</option>\n <option value=\"SERVICE\">\n {tr(\"devportal.service\", \"Service\")}\n </option>\n <option value=\"INTEGRATION\">\n {tr(\"devportal.integration\", \"Integration\")}\n </option>\n <option value=\"BOT\">{tr(\"devportal.bot\", \"Bot\")}</option>\n <option value=\"WEB_APP\">\n {tr(\"devportal.webApp\", \"Web App\")}\n </option>\n <option value=\"AUTOMATION\">\n {tr(\"devportal.automation\", \"Automation\")}\n </option>\n </select>\n </div>\n </div>\n\n {/* Summary Stats — primary emphasis zone */}\n <EmphasisPanel>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-text-secondary\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.totalApps\", \"Total Apps\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.total}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-status-success-text\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.active\", \"Active\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.active}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-accent-blue\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.integration\", \"Integration\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.integration}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-accent-purple\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.service\", \"Service\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.service}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n\n <p className=\"text-sm text-text-secondary\">\n {filteredApps.length}{\" \"}\n {filteredApps.length !== 1\n ? tr(\"devportal.appsFound\", \"apps found\")\n : tr(\"devportal.appFound\", \"app found\")}\n </p>\n\n {/* Apps Table */}\n {filteredApps.length > 0 ? (\n <DataTable\n data={filteredApps}\n columns={columns}\n keyField=\"id\"\n onRowClick={(app) => handleNavigate(`/oauth/${app.id}`)}\n />\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={tr(\"devportal.noOAuthAppsFound\", \"No OAuth apps found\")}\n description={\n searchQuery || typeFilter\n ? tr(\n \"devportal.tryAdjustingFilters\",\n \"Try adjusting your filters\",\n )\n : tr(\n \"devportal.createFirstOAuthApp\",\n \"Create your first OAuth app to enable authentication\",\n )\n }\n action={\n !searchQuery && !typeFilter ? (\n <button\n onClick={() => handleNavigate(\"/oauth/new\")}\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 <Plus size={16} />\n {tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n </button>\n ) : undefined\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
@@ -8,8 +8,8 @@ import { AppListItem as d } from "../components/AppCard.js";
8
8
  import { StatCard as f, StatCardGrid as p } from "../components/StatCard.js";
9
9
  import { DataTable as m, DetailList as h } from "../components/DataTable.js";
10
10
  import { InputField as g, TextareaField as _ } from "../components/FormField.js";
11
- import { DEVPORTAL_PERMISSIONS as v } from "../constants/permissions.js";
12
- import { useDevportalPermission as y } from "../hooks/usePermission.js";
11
+ import { useDevportalPermission as v } from "../hooks/usePermission.js";
12
+ import { DEVPORTAL_PERMISSIONS as y } from "../constants/permissions.js";
13
13
  import { useEffect as b, useState as x } from "react";
14
14
  import { useI18n as S } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
15
  import { AlertCircle as C, AppWindow as w, ArrowRight as T, BarChart3 as E, Building2 as ee, CheckCircle as D, DollarSign as O, ExternalLink as k, Loader2 as A, Plus as j, Settings as M, Shield as N, TrendingUp as P, Users as F } from "lucide-react";
@@ -530,7 +530,7 @@ var Y = {
530
530
  })]
531
531
  });
532
532
  }, ne = ({ org: e }) => {
533
- let { t } = S(), { allowed: n } = y(v.ORG_UPDATE), r = (e, n) => {
533
+ let { t } = S(), { allowed: n } = v(y.ORG_UPDATE), r = (e, n) => {
534
534
  let r = t(e);
535
535
  return r === e ? n : r;
536
536
  }, [i, c] = x({
@@ -10,9 +10,9 @@ import { InputField as ue, SelectField as de, TextareaField as fe } from "../com
10
10
  import { ConfirmDialog as l } from "../components/ConfirmDialog.js";
11
11
  import { PermissionGuard as pe } from "../components/PermissionGuard.js";
12
12
  import "../components/index.js";
13
- import { DEVPORTAL_PERMISSIONS as u } from "../constants/permissions.js";
14
- import { useDevportalPermission as d } from "../hooks/usePermission.js";
13
+ import { useDevportalPermission as u } from "../hooks/usePermission.js";
15
14
  import "../hooks/index.js";
15
+ import { DEVPORTAL_PERMISSIONS as d } from "../constants/permissions.js";
16
16
  import me from "../../node_modules/date-fns/format.js";
17
17
  import { useEffect as he, useMemo as f, useState as p } from "react";
18
18
  import { useI18n as ge } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
@@ -26,7 +26,7 @@ var we = {
26
26
  ADMIN: 2,
27
27
  OWNER: 3
28
28
  }, _ = () => {
29
- let { orgId: _ } = Ce(), { currentUser: v } = e(), { allowed: Te } = d(u.ORG_INVITATION_CREATE), { allowed: Ee } = d(u.ORG_MEMBER_UPDATE), { allowed: De } = d(u.ORG_MEMBER_DELETE), { allowed: Oe } = d(u.ORG_MEMBER_ACTIVATE), { allowed: ke } = d(u.ORG_MEMBER_DEACTIVATE), y = (e) => e.email ? e.email : v?.id === e.userId && v.email ? v.email : e.userId, { t: Ae } = ge(), b = (e, t) => {
29
+ let { orgId: _ } = Ce(), { currentUser: v } = e(), { allowed: Te } = u(d.ORG_INVITATION_CREATE), { allowed: Ee } = u(d.ORG_MEMBER_UPDATE), { allowed: De } = u(d.ORG_MEMBER_DELETE), { allowed: Oe } = u(d.ORG_MEMBER_ACTIVATE), { allowed: ke } = u(d.ORG_MEMBER_DEACTIVATE), y = (e) => e.email ? e.email : v?.id === e.userId && v.email ? v.email : e.userId, { t: Ae } = ge(), b = (e, t) => {
30
30
  let n = Ae(e);
31
31
  return n === e ? t : n;
32
32
  }, [x, S] = p(!1), [C, w] = p(""), [T, E] = p("DEVELOPER"), [je, Me] = p(""), [Ne, D] = p(null), [Pe, O] = p(null), [k, A] = p(/* @__PURE__ */ new Set()), [j, M] = p(/* @__PURE__ */ new Set()), [Fe, N] = p(!1), [Ie, P] = p(!1), [F, I] = p(null), { data: Le } = te({
@@ -207,7 +207,7 @@ var we = {
207
207
  description: ze?.message || Ze?.message || b("devportal.anErrorOccurredWhileLoadingTeamData", "An error occurred while loading team data")
208
208
  })
209
209
  }) : /* @__PURE__ */ h(pe, {
210
- permission: u.ORG_MEMBER_READ,
210
+ authOnly: !0,
211
211
  children: /* @__PURE__ */ g(i, {
212
212
  title: b("devportal.teamMembers", "Team Members"),
213
213
  description: b("devportal.manageYourOrganizationsTeam", "Manage your organization's team"),
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationMembersPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationMembersPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Plus,\n Users,\n Mail,\n Shield,\n UserMinus,\n RefreshCw,\n Loader2,\n AlertCircle,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport { ConfirmDialog } from \"../components/ConfirmDialog\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport {\n InputField,\n SelectField,\n TextareaField,\n} from \"../components/FormField\";\nimport { SelectionCheckbox } from \"../components/SelectionCheckbox\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport type { DeveloperOrgRole } from \"../types\";\nimport { ORG_ROLE_LABELS } from \"../utils/constants\";\nimport { format } from \"date-fns\";\nimport {\n useGetOrganizationQuery,\n useGetOrganizationMembersQuery,\n useGetOrganizationInvitationsQuery,\n useInviteMemberMutation,\n useRemoveMemberMutation,\n useSuspendMemberMutation,\n useReactivateMemberMutation,\n useUpdateMemberRoleMutation,\n useTransferOwnershipMutation,\n useCancelInvitationMutation,\n useResendInvitationMutation,\n type OrgMemberFieldsFragment,\n type OrgInvitationFieldsFragment,\n} from \"../hooks\";\n\nconst ORG_ROLE_PRIORITY: Record<DeveloperOrgRole, number> = {\n VIEWER: 0,\n DEVELOPER: 1,\n ADMIN: 2,\n OWNER: 3,\n};\n\nexport const OrganizationMembersPage: FC = () => {\n const { orgId } = useParams<{ orgId: string }>();\n const { currentUser } = useDevportal();\n const { allowed: canInviteByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_INVITATION_CREATE,\n );\n const { allowed: canManageMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_UPDATE,\n );\n const { allowed: canRemoveMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_DELETE,\n );\n const { allowed: canActivateMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_ACTIVATE,\n );\n const { allowed: canDeactivateMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_DEACTIVATE,\n );\n const resolveMemberLabel = (member: {\n userId: string;\n email?: string | null;\n }): string => {\n if (member.email) return member.email;\n if (currentUser?.id === member.userId && currentUser.email)\n return currentUser.email;\n return member.userId;\n };\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 [showInviteDialog, setShowInviteDialog] = useState(false);\n const [inviteEmail, setInviteEmail] = useState(\"\");\n const [inviteRole, setInviteRole] = useState<DeveloperOrgRole>(\"DEVELOPER\");\n const [inviteMessage, setInviteMessage] = useState(\"\");\n const [actionError, setActionError] = useState<string | null>(null);\n const [actionSuccess, setActionSuccess] = useState<string | null>(null);\n const [selectedMemberIds, setSelectedMemberIds] = useState<Set<string>>(\n new Set(),\n );\n const [selectedInvitationIds, setSelectedInvitationIds] = useState<\n Set<string>\n >(new Set());\n const [showBulkRemoveMembersDialog, setShowBulkRemoveMembersDialog] =\n useState(false);\n const [showBulkCancelInvitationsDialog, setShowBulkCancelInvitationsDialog] =\n useState(false);\n const [transferOwnershipMember, setTransferOwnershipMember] =\n useState<OrgMemberFieldsFragment | null>(null);\n\n const { data: orgData } = useGetOrganizationQuery({\n variables: { id: orgId ?? \"\" },\n skip: !orgId,\n fetchPolicy: \"cache-first\",\n });\n useEffect(() => {\n const name = orgData?.developerOrganization?.name;\n if (!orgId || !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(orgId, name);\n return () => reg?.unregister(orgId);\n }, [orgId, orgData?.developerOrganization?.name]);\n\n // Queries\n const {\n data: membersData,\n loading: membersLoading,\n error: membersError,\n } = useGetOrganizationMembersQuery({\n variables: { organizationId: orgId! },\n skip: !orgId,\n fetchPolicy: \"cache-and-network\",\n });\n\n // Mutations\n const [inviteMember, { loading: inviting }] = useInviteMemberMutation({\n refetchQueries: [\"GetOrganizationInvitations\"],\n });\n\n const [removeMember] = useRemoveMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [suspendMember] = useSuspendMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [reactivateMember] = useReactivateMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [updateMemberRole] = useUpdateMemberRoleMutation({\n refetchQueries: [\"GetOrganizationMembers\", \"GetOrganization\"],\n });\n\n const [transferOwnership] = useTransferOwnershipMutation({\n refetchQueries: [\"GetOrganizationMembers\", \"GetOrganization\"],\n });\n\n const [cancelInvitation] = useCancelInvitationMutation({\n refetchQueries: [\"GetOrganizationInvitations\"],\n });\n\n const [resendInvitation] = useResendInvitationMutation();\n\n // Derived data\n const members: OrgMemberFieldsFragment[] = useMemo(\n () =>\n membersData?.developerOrgMembers?.edges?.map(\n (e: { node: OrgMemberFieldsFragment }) => e.node,\n ) ?? [],\n [membersData?.developerOrgMembers?.edges],\n );\n\n const currentMembership = currentUser\n ? members.find((member) => member.userId === currentUser.id)\n : undefined;\n const currentRole = currentMembership?.role as DeveloperOrgRole | undefined;\n const canManageOrg =\n currentRole !== undefined &&\n ORG_ROLE_PRIORITY[currentRole] >= ORG_ROLE_PRIORITY.ADMIN;\n const canInvite = canManageOrg && canInviteByPermission;\n const canManageMembers = canManageOrg && canManageMembersByPermission;\n const canRemoveMembers = canManageOrg && canRemoveMembersByPermission;\n const canActivateMembers = canManageOrg && canActivateMembersByPermission;\n const canDeactivateMembers = canManageOrg && canDeactivateMembersByPermission;\n\n const {\n data: invitationsData,\n loading: invitationsLoading,\n error: invitationsError,\n } = useGetOrganizationInvitationsQuery({\n variables: { organizationId: orgId!, status: \"PENDING\" as never },\n skip: !orgId || !canManageOrg,\n fetchPolicy: \"cache-and-network\",\n });\n\n const invitations: OrgInvitationFieldsFragment[] = useMemo(\n () =>\n invitationsData?.developerOrgInvitations?.edges?.map(\n (e: { node: OrgInvitationFieldsFragment }) => e.node,\n ) ?? [],\n [invitationsData?.developerOrgInvitations?.edges],\n );\n\n const membersCount = membersData?.developerOrgMembers?.totalCount ?? 0;\n const invitationsCount =\n invitationsData?.developerOrgInvitations?.totalCount ?? 0;\n\n const selectedMembers = useMemo(\n () => members.filter((member) => selectedMemberIds.has(member.id)),\n [members, selectedMemberIds],\n );\n const selectedInvitations = useMemo(\n () =>\n invitations.filter((invitation) =>\n selectedInvitationIds.has(invitation.id),\n ),\n [invitations, selectedInvitationIds],\n );\n\n const selectableMembers = members.filter((member) => member.role !== \"OWNER\");\n const allMembersSelected =\n selectableMembers.length > 0 &&\n selectableMembers.every((member) => selectedMemberIds.has(member.id));\n const partiallySelectedMembers =\n selectableMembers.some((member) => selectedMemberIds.has(member.id)) &&\n !allMembersSelected;\n\n const allInvitationsSelected =\n invitations.length > 0 &&\n invitations.every((invitation) => selectedInvitationIds.has(invitation.id));\n const partiallySelectedInvitations =\n invitations.some((invitation) =>\n selectedInvitationIds.has(invitation.id),\n ) && !allInvitationsSelected;\n\n const suspendableMembers = selectedMembers.filter(\n (member) => member.role !== \"OWNER\" && !member.isSuspended,\n );\n const reactivatableMembers = selectedMembers.filter(\n (member) => member.isSuspended,\n );\n const removableMembers = selectedMembers.filter(\n (member) => member.role !== \"OWNER\",\n );\n\n const handleInvite = async () => {\n if (!orgId || !inviteEmail.trim()) return;\n setActionError(null);\n\n try {\n await inviteMember({\n variables: {\n organizationId: orgId,\n input: {\n email: inviteEmail,\n role: inviteRole as never,\n message: inviteMessage || undefined,\n },\n },\n });\n setShowInviteDialog(false);\n setInviteEmail(\"\");\n setInviteRole(\"DEVELOPER\");\n setInviteMessage(\"\");\n setActionSuccess(\n tr(\n \"devportal.invitationSent\",\n \"Invitation created and email sent to the team member.\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToSendInvitation\", \"Failed to send invitation\"),\n );\n }\n };\n\n const handleRemoveMember = async (memberId: string) => {\n setActionError(null);\n try {\n await removeMember({ variables: { id: memberId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToRemoveMember\", \"Failed to remove member\"),\n );\n }\n };\n\n const handleSuspendMember = async (memberId: string, reason?: string) => {\n setActionError(null);\n try {\n await suspendMember({\n variables: { id: memberId, reason: reason || undefined },\n });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToSuspendMember\", \"Failed to suspend member\"),\n );\n }\n };\n\n const handleReactivateMember = async (memberId: string) => {\n setActionError(null);\n try {\n await reactivateMember({ variables: { id: memberId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToReactivateMember\",\n \"Failed to reactivate member\",\n ),\n );\n }\n };\n\n const handleUpdateMemberRole = async (\n memberId: string,\n role: DeveloperOrgRole,\n ) => {\n setActionError(null);\n try {\n await updateMemberRole({\n variables: {\n id: memberId,\n role: role as never,\n permissions: undefined,\n },\n });\n setActionSuccess(\n tr(\"devportal.memberRoleUpdated\", \"Member role updated successfully\"),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToUpdateMemberRole\",\n \"Failed to update member role\",\n ),\n );\n }\n };\n\n const handleTransferOwnership = async () => {\n const member = transferOwnershipMember;\n if (!orgId || !member) return;\n setActionError(null);\n\n try {\n await transferOwnership({\n variables: { organizationId: orgId, newOwnerId: member.userId },\n });\n setTransferOwnershipMember(null);\n setActionSuccess(\n tr(\n \"devportal.organizationOwnershipTransferred\",\n \"Organization ownership transferred successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToTransferOwnership\",\n \"Failed to transfer organization ownership\",\n ),\n );\n }\n };\n\n const handleCancelInvitation = async (invitationId: string) => {\n setActionError(null);\n try {\n await cancelInvitation({ variables: { id: invitationId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToCancelInvitation\",\n \"Failed to cancel invitation\",\n ),\n );\n }\n };\n\n const handleResendInvitation = async (invitationId: string) => {\n setActionError(null);\n try {\n await resendInvitation({ variables: { id: invitationId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToResendInvitation\",\n \"Failed to resend invitation\",\n ),\n );\n }\n };\n\n const clearSelections = () => {\n setSelectedMemberIds(new Set());\n setSelectedInvitationIds(new Set());\n };\n\n const toggleMemberSelection = (memberId: string, checked: boolean) => {\n setSelectedMemberIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(memberId);\n } else {\n next.delete(memberId);\n }\n return next;\n });\n };\n\n const toggleAllMembers = (checked: boolean) => {\n setSelectedMemberIds((prev) => {\n const next = new Set(prev);\n selectableMembers.forEach((member) => {\n if (checked) {\n next.add(member.id);\n } else {\n next.delete(member.id);\n }\n });\n return next;\n });\n };\n\n const toggleInvitationSelection = (\n invitationId: string,\n checked: boolean,\n ) => {\n setSelectedInvitationIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(invitationId);\n } else {\n next.delete(invitationId);\n }\n return next;\n });\n };\n\n const toggleAllInvitations = (checked: boolean) => {\n setSelectedInvitationIds((prev) => {\n const next = new Set(prev);\n invitations.forEach((invitation) => {\n if (checked) {\n next.add(invitation.id);\n } else {\n next.delete(invitation.id);\n }\n });\n return next;\n });\n };\n\n const handleBulkSuspendMembers = async () => {\n if (suspendableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n suspendableMembers.map((member) =>\n suspendMember({ variables: { id: member.id, reason: undefined } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.suspended\", \"Suspended\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkReactivateMembers = async () => {\n if (reactivatableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n reactivatableMembers.map((member) =>\n reactivateMember({ variables: { id: member.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.reactivated\", \"Reactivated\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkRemoveMembers = async () => {\n if (removableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n removableMembers.map((member) =>\n removeMember({ variables: { id: member.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.removed\", \"Removed\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setShowBulkRemoveMembersDialog(false);\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkResendInvitations = async () => {\n if (selectedInvitations.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n selectedInvitations.map((invitation) =>\n resendInvitation({ variables: { id: invitation.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.resent\", \"Resent\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.invitationLower\", \"invitation\") : tr(\"devportal.invitationsLower\", \"invitations\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedInvitationIds(new Set());\n };\n\n const handleBulkCancelInvitations = async () => {\n if (selectedInvitations.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n selectedInvitations.map((invitation) =>\n cancelInvitation({ variables: { id: invitation.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.cancelled\", \"Cancelled\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.invitationLower\", \"invitation\") : tr(\"devportal.invitationsLower\", \"invitations\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setShowBulkCancelInvitationsDialog(false);\n setSelectedInvitationIds(new Set());\n };\n\n const isLoading = membersLoading || invitationsLoading;\n const hasError = membersError || invitationsError;\n\n if (isLoading && !membersData && !invitationsData) {\n return (\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n >\n <div className=\"flex items-center justify-center py-16\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (hasError && !membersData && !invitationsData) {\n return (\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\"devportal.failedToLoadMembers\", \"Failed to load members\")}\n description={\n membersError?.message ||\n invitationsError?.message ||\n tr(\n \"devportal.anErrorOccurredWhileLoadingTeamData\",\n \"An error occurred while loading team data\",\n )\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.ORG_MEMBER_READ}>\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n purpose={tr(\n \"devportal.teamMembersPurpose\",\n \"Control who can work on this organization's apps and what they can do. Invite teammates by email, assign roles to grant the right level of access, and suspend or remove anyone who should no longer have it.\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n actions={\n canInvite ? (\n <button\n onClick={() => setShowInviteDialog(true)}\n disabled={!canInvite}\n aria-disabled={!canInvite}\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 disabled:opacity-50\"\n >\n <Plus size={16} />\n {tr(\"devportal.inviteMember\", \"Invite Member\")}\n </button>\n ) : undefined\n }\n >\n {/* Action Error Banner */}\n {actionError && (\n <div className=\"rounded-lg border border-border-subtle bg-status-error-bg-subtle p-3 flex items-center gap-2 text-sm text-status-error-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionError}\n <button\n onClick={() => setActionError(null)}\n className=\"ml-auto text-status-error-text hover:text-status-error-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {actionSuccess && (\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-3 flex items-center gap-2 text-sm text-status-success-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionSuccess}\n <button\n onClick={() => setActionSuccess(null)}\n className=\"ml-auto text-status-success-text hover:text-status-success-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {(selectedMemberIds.size > 0 || selectedInvitationIds.size > 0) && (\n <div className=\"flex flex-wrap items-center gap-3 rounded-card border border-border-seam bg-bg-surface p-4\">\n <span className=\"rounded-full bg-bg-sunken px-3 py-1 text-sm font-medium text-text-secondary\">\n {selectedMemberIds.size + selectedInvitationIds.size}{\" \"}\n {tr(\"devportal.selected\", \"selected\")}\n </span>\n <button\n onClick={clearSelections}\n className=\"text-sm text-text-secondary hover:text-text-primary\"\n >\n {tr(\"devportal.clearAllSelections\", \"Clear all selections\")}\n </button>\n </div>\n )}\n\n {/* Current Members */}\n <PageSection\n title={`${tr(\"devportal.members\", \"Members\")} (${membersCount})`}\n actions={\n members.length > 0 && canManageOrg ? (\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={handleBulkSuspendMembers}\n disabled={\n suspendableMembers.length === 0 || !canDeactivateMembers\n }\n aria-disabled={!canDeactivateMembers}\n className=\"rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.suspendSelected\", \"Suspend Selected\")}\n {suspendableMembers.length > 0\n ? ` (${suspendableMembers.length})`\n : \"\"}\n </button>\n <button\n onClick={handleBulkReactivateMembers}\n disabled={\n reactivatableMembers.length === 0 || !canActivateMembers\n }\n aria-disabled={!canActivateMembers}\n className=\"rounded-md border border-status-success-bg px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.reactivateSelected\", \"Reactivate Selected\")}\n {reactivatableMembers.length > 0\n ? ` (${reactivatableMembers.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setShowBulkRemoveMembersDialog(true)}\n disabled={removableMembers.length === 0 || !canRemoveMembers}\n aria-disabled={!canRemoveMembers}\n className=\"rounded-md border border-status-error-bg px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.removeSelected\", \"Remove Selected\")}\n {removableMembers.length > 0\n ? ` (${removableMembers.length})`\n : \"\"}\n </button>\n </div>\n ) : null\n }\n >\n {members.length > 0 ? (\n <DataTable\n data={members}\n keyField=\"id\"\n columns={[\n ...(canManageOrg\n ? [\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allMembersSelected}\n indeterminate={partiallySelectedMembers}\n onChange={toggleAllMembers}\n ariaLabel={tr(\n \"devportal.selectAllMembers\",\n \"Select all members\",\n )}\n />\n ),\n className: \"w-12\",\n render: (member: OrgMemberFieldsFragment) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedMemberIds.has(member.id)}\n disabled={member.role === \"OWNER\"}\n onChange={(checked) =>\n toggleMemberSelection(member.id, checked)\n }\n ariaLabel={`Select member ${resolveMemberLabel(member)}`}\n />\n </div>\n ),\n },\n ]\n : []),\n {\n key: \"email\",\n header: tr(\"devportal.memberColumn\", \"Member\"),\n render: (member) => {\n const label = resolveMemberLabel(member);\n return (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-action-primary-bg/10 text-primary text-sm font-medium\">\n {label.charAt(0).toUpperCase()}\n </div>\n <div>\n <p className=\"font-medium\">{label}</p>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.joined\", \"Joined\")}{\" \"}\n {format(new Date(member.joinedAt), \"MMM d, yyyy\")}\n </p>\n </div>\n </div>\n );\n },\n },\n {\n key: \"role\",\n header: tr(\"devportal.roleColumn\", \"Role\"),\n render: (member) => (\n <div className=\"flex items-center gap-2\">\n <Shield size={14} className=\"text-text-secondary\" />\n {member.role === \"OWNER\" || !canManageMembers ? (\n <span>\n {ORG_ROLE_LABELS[member.role as DeveloperOrgRole] ??\n member.role}\n </span>\n ) : (\n <select\n value={member.role}\n onChange={(event) =>\n void handleUpdateMemberRole(\n member.id,\n event.target.value as DeveloperOrgRole,\n )\n }\n className=\"rounded-md border border-border-subtle bg-bg-surface px-2 py-1 text-xs text-text-primary\"\n >\n {Object.entries(ORG_ROLE_LABELS)\n .filter(([value]) => value !== \"OWNER\")\n .map(([value, label]) => (\n <option key={value} value={value}>\n {label}\n </option>\n ))}\n </select>\n )}\n </div>\n ),\n },\n {\n key: \"status\",\n header: tr(\"devportal.statusColumn\", \"Status\"),\n render: (member) =>\n member.isSuspended ? (\n <StatusBadge status=\"SUSPENDED\" type=\"app\" />\n ) : member.isActive ? (\n <StatusBadge status=\"ACTIVE\" type=\"app\" />\n ) : (\n <StatusBadge status=\"INACTIVE\" type=\"app\" />\n ),\n },\n ...(canManageOrg\n ? [\n {\n key: \"actions\",\n header: \"\",\n className: \"w-32\",\n render: (member: OrgMemberFieldsFragment) =>\n member.role !== \"OWNER\" && (\n <div className=\"flex gap-1\">\n {member.isSuspended ? (\n <button\n className=\"text-xs text-status-success-text hover:underline disabled:opacity-50\"\n disabled={!canActivateMembers}\n aria-disabled={!canActivateMembers}\n title={tr(\n \"devportal.reactivateMember\",\n \"Reactivate member\",\n )}\n onClick={() =>\n handleReactivateMember(member.id)\n }\n >\n {tr(\"devportal.reactivate\", \"Reactivate\")}\n </button>\n ) : (\n <button\n className=\"text-xs text-status-warning-text hover:underline disabled:opacity-50\"\n disabled={!canDeactivateMembers}\n aria-disabled={!canDeactivateMembers}\n title={tr(\n \"devportal.suspendMember\",\n \"Suspend member\",\n )}\n onClick={() => handleSuspendMember(member.id)}\n >\n {tr(\"devportal.suspend\", \"Suspend\")}\n </button>\n )}\n <button\n className=\"text-xs text-status-error-text hover:underline disabled:opacity-50\"\n disabled={!canRemoveMembers}\n aria-disabled={!canRemoveMembers}\n title={tr(\n \"devportal.removeMember\",\n \"Remove member\",\n )}\n onClick={() => handleRemoveMember(member.id)}\n >\n {tr(\"devportal.remove\", \"Remove\")}\n </button>\n <button\n className=\"text-xs text-primary hover:underline disabled:opacity-50\"\n disabled={!canManageMembers}\n aria-disabled={!canManageMembers}\n title={tr(\n \"devportal.transferOwnership\",\n \"Transfer ownership\",\n )}\n onClick={() =>\n setTransferOwnershipMember(member)\n }\n >\n {tr(\"devportal.makeOwner\", \"Make Owner\")}\n </button>\n </div>\n ),\n },\n ]\n : []),\n ]}\n />\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title={tr(\"devportal.noMembers\", \"No members\")}\n description={tr(\n \"devportal.inviteTeamMembersToCollaborate\",\n \"Invite team members to collaborate\",\n )}\n />\n )}\n </PageSection>\n\n {/* Pending Invitations */}\n {canManageOrg && invitations.length > 0 && (\n <PageSection\n title={`${tr(\"devportal.pendingInvitations\", \"Pending Invitations\")} (${invitationsCount})`}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={handleBulkResendInvitations}\n disabled={selectedInvitations.length === 0}\n className=\"rounded-md border border-primary/30 px-3 py-2 text-sm font-medium text-primary hover:bg-action-primary-bg/5 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.resendSelected\", \"Resend Selected\")}\n {selectedInvitations.length > 0\n ? ` (${selectedInvitations.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setShowBulkCancelInvitationsDialog(true)}\n disabled={selectedInvitations.length === 0}\n className=\"rounded-md border border-status-error-bg px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.cancelSelected\", \"Cancel Selected\")}\n {selectedInvitations.length > 0\n ? ` (${selectedInvitations.length})`\n : \"\"}\n </button>\n </div>\n }\n >\n <DataTable\n data={invitations}\n keyField=\"id\"\n columns={[\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allInvitationsSelected}\n indeterminate={partiallySelectedInvitations}\n onChange={toggleAllInvitations}\n ariaLabel={tr(\n \"devportal.selectAllInvitations\",\n \"Select all invitations\",\n )}\n />\n ),\n className: \"w-12\",\n render: (invitation) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedInvitationIds.has(invitation.id)}\n onChange={(checked) =>\n toggleInvitationSelection(invitation.id, checked)\n }\n ariaLabel={`Select invitation ${invitation.invitedEmail}`}\n />\n </div>\n ),\n },\n {\n key: \"invitedEmail\",\n header: tr(\"devportal.emailColumn\", \"Email\"),\n render: (inv) => (\n <div className=\"flex items-center gap-2\">\n <Mail size={16} className=\"text-text-secondary\" />\n {inv.invitedEmail}\n </div>\n ),\n },\n {\n key: \"role\",\n header: tr(\"devportal.invitedRoleColumn\", \"Invited Role\"),\n render: (inv) =>\n ORG_ROLE_LABELS[inv.role as DeveloperOrgRole] ?? inv.role,\n },\n {\n key: \"status\",\n header: tr(\"devportal.statusColumn\", \"Status\"),\n render: (inv) => (\n <StatusBadge status={inv.status} type=\"invitation\" />\n ),\n },\n {\n key: \"expiresAt\",\n header: tr(\"devportal.expiresColumn\", \"Expires\"),\n render: (inv) =>\n format(new Date(inv.expiresAt), \"MMM d, yyyy\"),\n },\n {\n key: \"actions\",\n header: \"\",\n className: \"w-24\",\n render: (inv) => (\n <div className=\"flex gap-1\">\n <button\n className=\"rounded p-1 hover:bg-bg-sunken\"\n title={tr(\"devportal.resend\", \"Resend\")}\n onClick={() => handleResendInvitation(inv.id)}\n >\n <RefreshCw size={14} />\n </button>\n <button\n className=\"rounded p-1 hover:bg-bg-sunken text-status-error-text\"\n title={tr(\"devportal.cancel\", \"Cancel\")}\n onClick={() => handleCancelInvitation(inv.id)}\n >\n <UserMinus size={14} />\n </button>\n </div>\n ),\n },\n ]}\n />\n </PageSection>\n )}\n\n {/* Invite Dialog */}\n {showInviteDialog && (\n <ConfirmDialog\n open={showInviteDialog}\n onOpenChange={setShowInviteDialog}\n onConfirm={handleInvite}\n title={tr(\"devportal.inviteTeamMember\", \"Invite Team Member\")}\n confirmLabel={\n inviting\n ? tr(\"devportal.sendingDots\", \"Sending...\")\n : tr(\"devportal.sendInvitation\", \"Send Invitation\")\n }\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\"devportal.emailAddress\", \"Email Address\")}\n type=\"email\"\n value={inviteEmail}\n onChange={(e) => setInviteEmail(e.target.value)}\n placeholder=\"colleague@example.com\"\n hint={tr(\n \"devportal.mustBeExistingVerifiedUser\",\n \"Must be an existing verified user\",\n )}\n required\n />\n <SelectField\n label={tr(\"devportal.roleColumn\", \"Role\")}\n value={inviteRole}\n onChange={(e) =>\n setInviteRole(e.target.value as DeveloperOrgRole)\n }\n options={[\n {\n value: \"ADMIN\",\n label: tr(\n \"devportal.adminFullAccess\",\n \"Admin - Full access\",\n ),\n },\n {\n value: \"DEVELOPER\",\n label: tr(\n \"devportal.developerCreateAndManageApps\",\n \"Developer - Create and manage apps\",\n ),\n },\n {\n value: \"VIEWER\",\n label: tr(\n \"devportal.viewerReadOnlyAccess\",\n \"Viewer - Read-only access\",\n ),\n },\n ]}\n required\n />\n <TextareaField\n label={tr(\"devportal.personalMessage\", \"Personal Message\")}\n value={inviteMessage}\n onChange={(e) => setInviteMessage(e.target.value)}\n placeholder={tr(\n \"devportal.personalMessagePlaceholder\",\n \"Add a short note to include in the invitation email\",\n )}\n rows={3}\n />\n </div>\n </ConfirmDialog>\n )}\n\n <ConfirmDialog\n open={showBulkRemoveMembersDialog}\n onOpenChange={setShowBulkRemoveMembersDialog}\n onConfirm={handleBulkRemoveMembers}\n title={tr(\n \"devportal.removeSelectedMembers\",\n \"Remove selected members\",\n )}\n description={`${tr(\"devportal.removeNSelectedMembers\", \"Remove\")} ${removableMembers.length} ${tr(\"devportal.selectedMembersFromOrg\", \"selected member(s) from this organization? This action cannot be undone.\")}`}\n confirmLabel={tr(\"devportal.removeMembers\", \"Remove Members\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"danger\"\n />\n\n <ConfirmDialog\n open={showBulkCancelInvitationsDialog}\n onOpenChange={setShowBulkCancelInvitationsDialog}\n onConfirm={handleBulkCancelInvitations}\n title={tr(\n \"devportal.cancelSelectedInvitations\",\n \"Cancel selected invitations\",\n )}\n description={`${tr(\"devportal.cancelNPendingInvitations\", \"Cancel\")} ${selectedInvitations.length} ${tr(\"devportal.pendingInvitationsQuestion\", \"pending invitation(s)?\")}`}\n confirmLabel={tr(\"devportal.cancelInvitations\", \"Cancel Invitations\")}\n cancelLabel={tr(\"devportal.keepInvitations\", \"Keep Invitations\")}\n variant=\"danger\"\n />\n\n <ConfirmDialog\n open={transferOwnershipMember !== null}\n onOpenChange={(open) => {\n if (!open) setTransferOwnershipMember(null);\n }}\n onConfirm={handleTransferOwnership}\n title={tr(\"devportal.transferOwnership\", \"Transfer ownership\")}\n description={\n transferOwnershipMember\n ? tr(\n \"devportal.transferOwnershipConfirmation\",\n `Transfer organization ownership to ${resolveMemberLabel(transferOwnershipMember)}?`,\n )\n : undefined\n }\n confirmLabel={tr(\"devportal.makeOwner\", \"Make Owner\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"warning\"\n />\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OrganizationMembersPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationMembersPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Plus,\n Users,\n Mail,\n Shield,\n UserMinus,\n RefreshCw,\n Loader2,\n AlertCircle,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport { ConfirmDialog } from \"../components/ConfirmDialog\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport {\n InputField,\n SelectField,\n TextareaField,\n} from \"../components/FormField\";\nimport { SelectionCheckbox } from \"../components/SelectionCheckbox\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport type { DeveloperOrgRole } from \"../types\";\nimport { ORG_ROLE_LABELS } from \"../utils/constants\";\nimport { format } from \"date-fns\";\nimport {\n useGetOrganizationQuery,\n useGetOrganizationMembersQuery,\n useGetOrganizationInvitationsQuery,\n useInviteMemberMutation,\n useRemoveMemberMutation,\n useSuspendMemberMutation,\n useReactivateMemberMutation,\n useUpdateMemberRoleMutation,\n useTransferOwnershipMutation,\n useCancelInvitationMutation,\n useResendInvitationMutation,\n type OrgMemberFieldsFragment,\n type OrgInvitationFieldsFragment,\n} from \"../hooks\";\n\nconst ORG_ROLE_PRIORITY: Record<DeveloperOrgRole, number> = {\n VIEWER: 0,\n DEVELOPER: 1,\n ADMIN: 2,\n OWNER: 3,\n};\n\nexport const OrganizationMembersPage: FC = () => {\n const { orgId } = useParams<{ orgId: string }>();\n const { currentUser } = useDevportal();\n const { allowed: canInviteByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_INVITATION_CREATE,\n );\n const { allowed: canManageMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_UPDATE,\n );\n const { allowed: canRemoveMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_DELETE,\n );\n const { allowed: canActivateMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_ACTIVATE,\n );\n const { allowed: canDeactivateMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_DEACTIVATE,\n );\n const resolveMemberLabel = (member: {\n userId: string;\n email?: string | null;\n }): string => {\n if (member.email) return member.email;\n if (currentUser?.id === member.userId && currentUser.email)\n return currentUser.email;\n return member.userId;\n };\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 [showInviteDialog, setShowInviteDialog] = useState(false);\n const [inviteEmail, setInviteEmail] = useState(\"\");\n const [inviteRole, setInviteRole] = useState<DeveloperOrgRole>(\"DEVELOPER\");\n const [inviteMessage, setInviteMessage] = useState(\"\");\n const [actionError, setActionError] = useState<string | null>(null);\n const [actionSuccess, setActionSuccess] = useState<string | null>(null);\n const [selectedMemberIds, setSelectedMemberIds] = useState<Set<string>>(\n new Set(),\n );\n const [selectedInvitationIds, setSelectedInvitationIds] = useState<\n Set<string>\n >(new Set());\n const [showBulkRemoveMembersDialog, setShowBulkRemoveMembersDialog] =\n useState(false);\n const [showBulkCancelInvitationsDialog, setShowBulkCancelInvitationsDialog] =\n useState(false);\n const [transferOwnershipMember, setTransferOwnershipMember] =\n useState<OrgMemberFieldsFragment | null>(null);\n\n const { data: orgData } = useGetOrganizationQuery({\n variables: { id: orgId ?? \"\" },\n skip: !orgId,\n fetchPolicy: \"cache-first\",\n });\n useEffect(() => {\n const name = orgData?.developerOrganization?.name;\n if (!orgId || !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(orgId, name);\n return () => reg?.unregister(orgId);\n }, [orgId, orgData?.developerOrganization?.name]);\n\n // Queries\n const {\n data: membersData,\n loading: membersLoading,\n error: membersError,\n } = useGetOrganizationMembersQuery({\n variables: { organizationId: orgId! },\n skip: !orgId,\n fetchPolicy: \"cache-and-network\",\n });\n\n // Mutations\n const [inviteMember, { loading: inviting }] = useInviteMemberMutation({\n refetchQueries: [\"GetOrganizationInvitations\"],\n });\n\n const [removeMember] = useRemoveMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [suspendMember] = useSuspendMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [reactivateMember] = useReactivateMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [updateMemberRole] = useUpdateMemberRoleMutation({\n refetchQueries: [\"GetOrganizationMembers\", \"GetOrganization\"],\n });\n\n const [transferOwnership] = useTransferOwnershipMutation({\n refetchQueries: [\"GetOrganizationMembers\", \"GetOrganization\"],\n });\n\n const [cancelInvitation] = useCancelInvitationMutation({\n refetchQueries: [\"GetOrganizationInvitations\"],\n });\n\n const [resendInvitation] = useResendInvitationMutation();\n\n // Derived data\n const members: OrgMemberFieldsFragment[] = useMemo(\n () =>\n membersData?.developerOrgMembers?.edges?.map(\n (e: { node: OrgMemberFieldsFragment }) => e.node,\n ) ?? [],\n [membersData?.developerOrgMembers?.edges],\n );\n\n const currentMembership = currentUser\n ? members.find((member) => member.userId === currentUser.id)\n : undefined;\n const currentRole = currentMembership?.role as DeveloperOrgRole | undefined;\n const canManageOrg =\n currentRole !== undefined &&\n ORG_ROLE_PRIORITY[currentRole] >= ORG_ROLE_PRIORITY.ADMIN;\n const canInvite = canManageOrg && canInviteByPermission;\n const canManageMembers = canManageOrg && canManageMembersByPermission;\n const canRemoveMembers = canManageOrg && canRemoveMembersByPermission;\n const canActivateMembers = canManageOrg && canActivateMembersByPermission;\n const canDeactivateMembers = canManageOrg && canDeactivateMembersByPermission;\n\n const {\n data: invitationsData,\n loading: invitationsLoading,\n error: invitationsError,\n } = useGetOrganizationInvitationsQuery({\n variables: { organizationId: orgId!, status: \"PENDING\" as never },\n skip: !orgId || !canManageOrg,\n fetchPolicy: \"cache-and-network\",\n });\n\n const invitations: OrgInvitationFieldsFragment[] = useMemo(\n () =>\n invitationsData?.developerOrgInvitations?.edges?.map(\n (e: { node: OrgInvitationFieldsFragment }) => e.node,\n ) ?? [],\n [invitationsData?.developerOrgInvitations?.edges],\n );\n\n const membersCount = membersData?.developerOrgMembers?.totalCount ?? 0;\n const invitationsCount =\n invitationsData?.developerOrgInvitations?.totalCount ?? 0;\n\n const selectedMembers = useMemo(\n () => members.filter((member) => selectedMemberIds.has(member.id)),\n [members, selectedMemberIds],\n );\n const selectedInvitations = useMemo(\n () =>\n invitations.filter((invitation) =>\n selectedInvitationIds.has(invitation.id),\n ),\n [invitations, selectedInvitationIds],\n );\n\n const selectableMembers = members.filter((member) => member.role !== \"OWNER\");\n const allMembersSelected =\n selectableMembers.length > 0 &&\n selectableMembers.every((member) => selectedMemberIds.has(member.id));\n const partiallySelectedMembers =\n selectableMembers.some((member) => selectedMemberIds.has(member.id)) &&\n !allMembersSelected;\n\n const allInvitationsSelected =\n invitations.length > 0 &&\n invitations.every((invitation) => selectedInvitationIds.has(invitation.id));\n const partiallySelectedInvitations =\n invitations.some((invitation) =>\n selectedInvitationIds.has(invitation.id),\n ) && !allInvitationsSelected;\n\n const suspendableMembers = selectedMembers.filter(\n (member) => member.role !== \"OWNER\" && !member.isSuspended,\n );\n const reactivatableMembers = selectedMembers.filter(\n (member) => member.isSuspended,\n );\n const removableMembers = selectedMembers.filter(\n (member) => member.role !== \"OWNER\",\n );\n\n const handleInvite = async () => {\n if (!orgId || !inviteEmail.trim()) return;\n setActionError(null);\n\n try {\n await inviteMember({\n variables: {\n organizationId: orgId,\n input: {\n email: inviteEmail,\n role: inviteRole as never,\n message: inviteMessage || undefined,\n },\n },\n });\n setShowInviteDialog(false);\n setInviteEmail(\"\");\n setInviteRole(\"DEVELOPER\");\n setInviteMessage(\"\");\n setActionSuccess(\n tr(\n \"devportal.invitationSent\",\n \"Invitation created and email sent to the team member.\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToSendInvitation\", \"Failed to send invitation\"),\n );\n }\n };\n\n const handleRemoveMember = async (memberId: string) => {\n setActionError(null);\n try {\n await removeMember({ variables: { id: memberId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToRemoveMember\", \"Failed to remove member\"),\n );\n }\n };\n\n const handleSuspendMember = async (memberId: string, reason?: string) => {\n setActionError(null);\n try {\n await suspendMember({\n variables: { id: memberId, reason: reason || undefined },\n });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToSuspendMember\", \"Failed to suspend member\"),\n );\n }\n };\n\n const handleReactivateMember = async (memberId: string) => {\n setActionError(null);\n try {\n await reactivateMember({ variables: { id: memberId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToReactivateMember\",\n \"Failed to reactivate member\",\n ),\n );\n }\n };\n\n const handleUpdateMemberRole = async (\n memberId: string,\n role: DeveloperOrgRole,\n ) => {\n setActionError(null);\n try {\n await updateMemberRole({\n variables: {\n id: memberId,\n role: role as never,\n permissions: undefined,\n },\n });\n setActionSuccess(\n tr(\"devportal.memberRoleUpdated\", \"Member role updated successfully\"),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToUpdateMemberRole\",\n \"Failed to update member role\",\n ),\n );\n }\n };\n\n const handleTransferOwnership = async () => {\n const member = transferOwnershipMember;\n if (!orgId || !member) return;\n setActionError(null);\n\n try {\n await transferOwnership({\n variables: { organizationId: orgId, newOwnerId: member.userId },\n });\n setTransferOwnershipMember(null);\n setActionSuccess(\n tr(\n \"devportal.organizationOwnershipTransferred\",\n \"Organization ownership transferred successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToTransferOwnership\",\n \"Failed to transfer organization ownership\",\n ),\n );\n }\n };\n\n const handleCancelInvitation = async (invitationId: string) => {\n setActionError(null);\n try {\n await cancelInvitation({ variables: { id: invitationId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToCancelInvitation\",\n \"Failed to cancel invitation\",\n ),\n );\n }\n };\n\n const handleResendInvitation = async (invitationId: string) => {\n setActionError(null);\n try {\n await resendInvitation({ variables: { id: invitationId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToResendInvitation\",\n \"Failed to resend invitation\",\n ),\n );\n }\n };\n\n const clearSelections = () => {\n setSelectedMemberIds(new Set());\n setSelectedInvitationIds(new Set());\n };\n\n const toggleMemberSelection = (memberId: string, checked: boolean) => {\n setSelectedMemberIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(memberId);\n } else {\n next.delete(memberId);\n }\n return next;\n });\n };\n\n const toggleAllMembers = (checked: boolean) => {\n setSelectedMemberIds((prev) => {\n const next = new Set(prev);\n selectableMembers.forEach((member) => {\n if (checked) {\n next.add(member.id);\n } else {\n next.delete(member.id);\n }\n });\n return next;\n });\n };\n\n const toggleInvitationSelection = (\n invitationId: string,\n checked: boolean,\n ) => {\n setSelectedInvitationIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(invitationId);\n } else {\n next.delete(invitationId);\n }\n return next;\n });\n };\n\n const toggleAllInvitations = (checked: boolean) => {\n setSelectedInvitationIds((prev) => {\n const next = new Set(prev);\n invitations.forEach((invitation) => {\n if (checked) {\n next.add(invitation.id);\n } else {\n next.delete(invitation.id);\n }\n });\n return next;\n });\n };\n\n const handleBulkSuspendMembers = async () => {\n if (suspendableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n suspendableMembers.map((member) =>\n suspendMember({ variables: { id: member.id, reason: undefined } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.suspended\", \"Suspended\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkReactivateMembers = async () => {\n if (reactivatableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n reactivatableMembers.map((member) =>\n reactivateMember({ variables: { id: member.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.reactivated\", \"Reactivated\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkRemoveMembers = async () => {\n if (removableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n removableMembers.map((member) =>\n removeMember({ variables: { id: member.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.removed\", \"Removed\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setShowBulkRemoveMembersDialog(false);\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkResendInvitations = async () => {\n if (selectedInvitations.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n selectedInvitations.map((invitation) =>\n resendInvitation({ variables: { id: invitation.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.resent\", \"Resent\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.invitationLower\", \"invitation\") : tr(\"devportal.invitationsLower\", \"invitations\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedInvitationIds(new Set());\n };\n\n const handleBulkCancelInvitations = async () => {\n if (selectedInvitations.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n selectedInvitations.map((invitation) =>\n cancelInvitation({ variables: { id: invitation.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.cancelled\", \"Cancelled\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.invitationLower\", \"invitation\") : tr(\"devportal.invitationsLower\", \"invitations\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setShowBulkCancelInvitationsDialog(false);\n setSelectedInvitationIds(new Set());\n };\n\n const isLoading = membersLoading || invitationsLoading;\n const hasError = membersError || invitationsError;\n\n if (isLoading && !membersData && !invitationsData) {\n return (\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n >\n <div className=\"flex items-center justify-center py-16\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (hasError && !membersData && !invitationsData) {\n return (\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\"devportal.failedToLoadMembers\", \"Failed to load members\")}\n description={\n membersError?.message ||\n invitationsError?.message ||\n tr(\n \"devportal.anErrorOccurredWhileLoadingTeamData\",\n \"An error occurred while loading team data\",\n )\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n purpose={tr(\n \"devportal.teamMembersPurpose\",\n \"Control who can work on this organization's apps and what they can do. Invite teammates by email, assign roles to grant the right level of access, and suspend or remove anyone who should no longer have it.\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n actions={\n canInvite ? (\n <button\n onClick={() => setShowInviteDialog(true)}\n disabled={!canInvite}\n aria-disabled={!canInvite}\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 disabled:opacity-50\"\n >\n <Plus size={16} />\n {tr(\"devportal.inviteMember\", \"Invite Member\")}\n </button>\n ) : undefined\n }\n >\n {/* Action Error Banner */}\n {actionError && (\n <div className=\"rounded-lg border border-border-subtle bg-status-error-bg-subtle p-3 flex items-center gap-2 text-sm text-status-error-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionError}\n <button\n onClick={() => setActionError(null)}\n className=\"ml-auto text-status-error-text hover:text-status-error-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {actionSuccess && (\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-3 flex items-center gap-2 text-sm text-status-success-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionSuccess}\n <button\n onClick={() => setActionSuccess(null)}\n className=\"ml-auto text-status-success-text hover:text-status-success-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {(selectedMemberIds.size > 0 || selectedInvitationIds.size > 0) && (\n <div className=\"flex flex-wrap items-center gap-3 rounded-card border border-border-seam bg-bg-surface p-4\">\n <span className=\"rounded-full bg-bg-sunken px-3 py-1 text-sm font-medium text-text-secondary\">\n {selectedMemberIds.size + selectedInvitationIds.size}{\" \"}\n {tr(\"devportal.selected\", \"selected\")}\n </span>\n <button\n onClick={clearSelections}\n className=\"text-sm text-text-secondary hover:text-text-primary\"\n >\n {tr(\"devportal.clearAllSelections\", \"Clear all selections\")}\n </button>\n </div>\n )}\n\n {/* Current Members */}\n <PageSection\n title={`${tr(\"devportal.members\", \"Members\")} (${membersCount})`}\n actions={\n members.length > 0 && canManageOrg ? (\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={handleBulkSuspendMembers}\n disabled={\n suspendableMembers.length === 0 || !canDeactivateMembers\n }\n aria-disabled={!canDeactivateMembers}\n className=\"rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.suspendSelected\", \"Suspend Selected\")}\n {suspendableMembers.length > 0\n ? ` (${suspendableMembers.length})`\n : \"\"}\n </button>\n <button\n onClick={handleBulkReactivateMembers}\n disabled={\n reactivatableMembers.length === 0 || !canActivateMembers\n }\n aria-disabled={!canActivateMembers}\n className=\"rounded-md border border-status-success-bg px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.reactivateSelected\", \"Reactivate Selected\")}\n {reactivatableMembers.length > 0\n ? ` (${reactivatableMembers.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setShowBulkRemoveMembersDialog(true)}\n disabled={removableMembers.length === 0 || !canRemoveMembers}\n aria-disabled={!canRemoveMembers}\n className=\"rounded-md border border-status-error-bg px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.removeSelected\", \"Remove Selected\")}\n {removableMembers.length > 0\n ? ` (${removableMembers.length})`\n : \"\"}\n </button>\n </div>\n ) : null\n }\n >\n {members.length > 0 ? (\n <DataTable\n data={members}\n keyField=\"id\"\n columns={[\n ...(canManageOrg\n ? [\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allMembersSelected}\n indeterminate={partiallySelectedMembers}\n onChange={toggleAllMembers}\n ariaLabel={tr(\n \"devportal.selectAllMembers\",\n \"Select all members\",\n )}\n />\n ),\n className: \"w-12\",\n render: (member: OrgMemberFieldsFragment) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedMemberIds.has(member.id)}\n disabled={member.role === \"OWNER\"}\n onChange={(checked) =>\n toggleMemberSelection(member.id, checked)\n }\n ariaLabel={`Select member ${resolveMemberLabel(member)}`}\n />\n </div>\n ),\n },\n ]\n : []),\n {\n key: \"email\",\n header: tr(\"devportal.memberColumn\", \"Member\"),\n render: (member) => {\n const label = resolveMemberLabel(member);\n return (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-action-primary-bg/10 text-primary text-sm font-medium\">\n {label.charAt(0).toUpperCase()}\n </div>\n <div>\n <p className=\"font-medium\">{label}</p>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.joined\", \"Joined\")}{\" \"}\n {format(new Date(member.joinedAt), \"MMM d, yyyy\")}\n </p>\n </div>\n </div>\n );\n },\n },\n {\n key: \"role\",\n header: tr(\"devportal.roleColumn\", \"Role\"),\n render: (member) => (\n <div className=\"flex items-center gap-2\">\n <Shield size={14} className=\"text-text-secondary\" />\n {member.role === \"OWNER\" || !canManageMembers ? (\n <span>\n {ORG_ROLE_LABELS[member.role as DeveloperOrgRole] ??\n member.role}\n </span>\n ) : (\n <select\n value={member.role}\n onChange={(event) =>\n void handleUpdateMemberRole(\n member.id,\n event.target.value as DeveloperOrgRole,\n )\n }\n className=\"rounded-md border border-border-subtle bg-bg-surface px-2 py-1 text-xs text-text-primary\"\n >\n {Object.entries(ORG_ROLE_LABELS)\n .filter(([value]) => value !== \"OWNER\")\n .map(([value, label]) => (\n <option key={value} value={value}>\n {label}\n </option>\n ))}\n </select>\n )}\n </div>\n ),\n },\n {\n key: \"status\",\n header: tr(\"devportal.statusColumn\", \"Status\"),\n render: (member) =>\n member.isSuspended ? (\n <StatusBadge status=\"SUSPENDED\" type=\"app\" />\n ) : member.isActive ? (\n <StatusBadge status=\"ACTIVE\" type=\"app\" />\n ) : (\n <StatusBadge status=\"INACTIVE\" type=\"app\" />\n ),\n },\n ...(canManageOrg\n ? [\n {\n key: \"actions\",\n header: \"\",\n className: \"w-32\",\n render: (member: OrgMemberFieldsFragment) =>\n member.role !== \"OWNER\" && (\n <div className=\"flex gap-1\">\n {member.isSuspended ? (\n <button\n className=\"text-xs text-status-success-text hover:underline disabled:opacity-50\"\n disabled={!canActivateMembers}\n aria-disabled={!canActivateMembers}\n title={tr(\n \"devportal.reactivateMember\",\n \"Reactivate member\",\n )}\n onClick={() =>\n handleReactivateMember(member.id)\n }\n >\n {tr(\"devportal.reactivate\", \"Reactivate\")}\n </button>\n ) : (\n <button\n className=\"text-xs text-status-warning-text hover:underline disabled:opacity-50\"\n disabled={!canDeactivateMembers}\n aria-disabled={!canDeactivateMembers}\n title={tr(\n \"devportal.suspendMember\",\n \"Suspend member\",\n )}\n onClick={() => handleSuspendMember(member.id)}\n >\n {tr(\"devportal.suspend\", \"Suspend\")}\n </button>\n )}\n <button\n className=\"text-xs text-status-error-text hover:underline disabled:opacity-50\"\n disabled={!canRemoveMembers}\n aria-disabled={!canRemoveMembers}\n title={tr(\n \"devportal.removeMember\",\n \"Remove member\",\n )}\n onClick={() => handleRemoveMember(member.id)}\n >\n {tr(\"devportal.remove\", \"Remove\")}\n </button>\n <button\n className=\"text-xs text-primary hover:underline disabled:opacity-50\"\n disabled={!canManageMembers}\n aria-disabled={!canManageMembers}\n title={tr(\n \"devportal.transferOwnership\",\n \"Transfer ownership\",\n )}\n onClick={() =>\n setTransferOwnershipMember(member)\n }\n >\n {tr(\"devportal.makeOwner\", \"Make Owner\")}\n </button>\n </div>\n ),\n },\n ]\n : []),\n ]}\n />\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title={tr(\"devportal.noMembers\", \"No members\")}\n description={tr(\n \"devportal.inviteTeamMembersToCollaborate\",\n \"Invite team members to collaborate\",\n )}\n />\n )}\n </PageSection>\n\n {/* Pending Invitations */}\n {canManageOrg && invitations.length > 0 && (\n <PageSection\n title={`${tr(\"devportal.pendingInvitations\", \"Pending Invitations\")} (${invitationsCount})`}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={handleBulkResendInvitations}\n disabled={selectedInvitations.length === 0}\n className=\"rounded-md border border-primary/30 px-3 py-2 text-sm font-medium text-primary hover:bg-action-primary-bg/5 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.resendSelected\", \"Resend Selected\")}\n {selectedInvitations.length > 0\n ? ` (${selectedInvitations.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setShowBulkCancelInvitationsDialog(true)}\n disabled={selectedInvitations.length === 0}\n className=\"rounded-md border border-status-error-bg px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.cancelSelected\", \"Cancel Selected\")}\n {selectedInvitations.length > 0\n ? ` (${selectedInvitations.length})`\n : \"\"}\n </button>\n </div>\n }\n >\n <DataTable\n data={invitations}\n keyField=\"id\"\n columns={[\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allInvitationsSelected}\n indeterminate={partiallySelectedInvitations}\n onChange={toggleAllInvitations}\n ariaLabel={tr(\n \"devportal.selectAllInvitations\",\n \"Select all invitations\",\n )}\n />\n ),\n className: \"w-12\",\n render: (invitation) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedInvitationIds.has(invitation.id)}\n onChange={(checked) =>\n toggleInvitationSelection(invitation.id, checked)\n }\n ariaLabel={`Select invitation ${invitation.invitedEmail}`}\n />\n </div>\n ),\n },\n {\n key: \"invitedEmail\",\n header: tr(\"devportal.emailColumn\", \"Email\"),\n render: (inv) => (\n <div className=\"flex items-center gap-2\">\n <Mail size={16} className=\"text-text-secondary\" />\n {inv.invitedEmail}\n </div>\n ),\n },\n {\n key: \"role\",\n header: tr(\"devportal.invitedRoleColumn\", \"Invited Role\"),\n render: (inv) =>\n ORG_ROLE_LABELS[inv.role as DeveloperOrgRole] ?? inv.role,\n },\n {\n key: \"status\",\n header: tr(\"devportal.statusColumn\", \"Status\"),\n render: (inv) => (\n <StatusBadge status={inv.status} type=\"invitation\" />\n ),\n },\n {\n key: \"expiresAt\",\n header: tr(\"devportal.expiresColumn\", \"Expires\"),\n render: (inv) =>\n format(new Date(inv.expiresAt), \"MMM d, yyyy\"),\n },\n {\n key: \"actions\",\n header: \"\",\n className: \"w-24\",\n render: (inv) => (\n <div className=\"flex gap-1\">\n <button\n className=\"rounded p-1 hover:bg-bg-sunken\"\n title={tr(\"devportal.resend\", \"Resend\")}\n onClick={() => handleResendInvitation(inv.id)}\n >\n <RefreshCw size={14} />\n </button>\n <button\n className=\"rounded p-1 hover:bg-bg-sunken text-status-error-text\"\n title={tr(\"devportal.cancel\", \"Cancel\")}\n onClick={() => handleCancelInvitation(inv.id)}\n >\n <UserMinus size={14} />\n </button>\n </div>\n ),\n },\n ]}\n />\n </PageSection>\n )}\n\n {/* Invite Dialog */}\n {showInviteDialog && (\n <ConfirmDialog\n open={showInviteDialog}\n onOpenChange={setShowInviteDialog}\n onConfirm={handleInvite}\n title={tr(\"devportal.inviteTeamMember\", \"Invite Team Member\")}\n confirmLabel={\n inviting\n ? tr(\"devportal.sendingDots\", \"Sending...\")\n : tr(\"devportal.sendInvitation\", \"Send Invitation\")\n }\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\"devportal.emailAddress\", \"Email Address\")}\n type=\"email\"\n value={inviteEmail}\n onChange={(e) => setInviteEmail(e.target.value)}\n placeholder=\"colleague@example.com\"\n hint={tr(\n \"devportal.mustBeExistingVerifiedUser\",\n \"Must be an existing verified user\",\n )}\n required\n />\n <SelectField\n label={tr(\"devportal.roleColumn\", \"Role\")}\n value={inviteRole}\n onChange={(e) =>\n setInviteRole(e.target.value as DeveloperOrgRole)\n }\n options={[\n {\n value: \"ADMIN\",\n label: tr(\n \"devportal.adminFullAccess\",\n \"Admin - Full access\",\n ),\n },\n {\n value: \"DEVELOPER\",\n label: tr(\n \"devportal.developerCreateAndManageApps\",\n \"Developer - Create and manage apps\",\n ),\n },\n {\n value: \"VIEWER\",\n label: tr(\n \"devportal.viewerReadOnlyAccess\",\n \"Viewer - Read-only access\",\n ),\n },\n ]}\n required\n />\n <TextareaField\n label={tr(\"devportal.personalMessage\", \"Personal Message\")}\n value={inviteMessage}\n onChange={(e) => setInviteMessage(e.target.value)}\n placeholder={tr(\n \"devportal.personalMessagePlaceholder\",\n \"Add a short note to include in the invitation email\",\n )}\n rows={3}\n />\n </div>\n </ConfirmDialog>\n )}\n\n <ConfirmDialog\n open={showBulkRemoveMembersDialog}\n onOpenChange={setShowBulkRemoveMembersDialog}\n onConfirm={handleBulkRemoveMembers}\n title={tr(\n \"devportal.removeSelectedMembers\",\n \"Remove selected members\",\n )}\n description={`${tr(\"devportal.removeNSelectedMembers\", \"Remove\")} ${removableMembers.length} ${tr(\"devportal.selectedMembersFromOrg\", \"selected member(s) from this organization? This action cannot be undone.\")}`}\n confirmLabel={tr(\"devportal.removeMembers\", \"Remove Members\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"danger\"\n />\n\n <ConfirmDialog\n open={showBulkCancelInvitationsDialog}\n onOpenChange={setShowBulkCancelInvitationsDialog}\n onConfirm={handleBulkCancelInvitations}\n title={tr(\n \"devportal.cancelSelectedInvitations\",\n \"Cancel selected invitations\",\n )}\n description={`${tr(\"devportal.cancelNPendingInvitations\", \"Cancel\")} ${selectedInvitations.length} ${tr(\"devportal.pendingInvitationsQuestion\", \"pending invitation(s)?\")}`}\n confirmLabel={tr(\"devportal.cancelInvitations\", \"Cancel Invitations\")}\n cancelLabel={tr(\"devportal.keepInvitations\", \"Keep Invitations\")}\n variant=\"danger\"\n />\n\n <ConfirmDialog\n open={transferOwnershipMember !== null}\n onOpenChange={(open) => {\n if (!open) setTransferOwnershipMember(null);\n }}\n onConfirm={handleTransferOwnership}\n title={tr(\"devportal.transferOwnership\", \"Transfer ownership\")}\n description={\n transferOwnershipMember\n ? tr(\n \"devportal.transferOwnershipConfirmation\",\n `Transfer organization ownership to ${resolveMemberLabel(transferOwnershipMember)}?`,\n )\n : undefined\n }\n confirmLabel={tr(\"devportal.makeOwner\", \"Make Owner\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"warning\"\n />\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationsPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OrganizationsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AA0BhC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,EA8K/B,CAAC"}
1
+ {"version":3,"file":"OrganizationsPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OrganizationsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAyBhC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,EA8K/B,CAAC"}