@agent-native/core 0.9.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/a2a/caller-auth.d.ts +12 -0
- package/dist/a2a/caller-auth.d.ts.map +1 -0
- package/dist/a2a/caller-auth.js +54 -0
- package/dist/a2a/caller-auth.js.map +1 -0
- package/dist/action.d.ts +17 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +22 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +5 -4
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +6 -3
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +8 -17
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/production-agent.d.ts +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +60 -30
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +12 -3
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +12 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +96 -0
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +16 -10
- package/dist/cli/create.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +8 -22
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +130 -34
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +21 -7
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +3 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -0
- package/dist/client/agent-sidebar-state.js +24 -0
- package/dist/client/agent-sidebar-state.js.map +1 -0
- package/dist/client/analytics.d.ts +25 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +40 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/client/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/client/components/ui/dropdown-menu.js +34 -0
- package/dist/client/components/ui/dropdown-menu.js.map +1 -0
- package/dist/client/components/ui/tooltip.d.ts +2 -1
- package/dist/client/components/ui/tooltip.d.ts.map +1 -1
- package/dist/client/components/ui/tooltip.js +9 -2
- package/dist/client/components/ui/tooltip.js.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +41 -8
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +30 -0
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +27 -2
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -1
- package/dist/client/dev-overlay/DevOverlay.js +4 -4
- package/dist/client/dev-overlay/DevOverlay.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +6 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +16 -4
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionEditor.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionEditor.js +6 -6
- package/dist/client/extensions/ExtensionEditor.js.map +1 -1
- package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionSlot.js +15 -2
- package/dist/client/extensions/ExtensionSlot.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +41 -19
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/extensions/ExtensionsListPage.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsListPage.js +2 -2
- package/dist/client/extensions/ExtensionsListPage.js.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.js +52 -63
- package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
- package/dist/client/extensions/iframe-bridge.d.ts.map +1 -1
- package/dist/client/extensions/iframe-bridge.js +5 -8
- package/dist/client/extensions/iframe-bridge.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
- package/dist/client/notifications/NotificationsBell.js +42 -6
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/org/InvitationBanner.d.ts.map +1 -1
- package/dist/client/org/InvitationBanner.js +5 -5
- package/dist/client/org/InvitationBanner.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +7 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +8 -3
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +156 -22
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/org/hooks.d.ts +29 -1
- package/dist/client/org/hooks.d.ts.map +1 -1
- package/dist/client/org/hooks.js +39 -2
- package/dist/client/org/hooks.js.map +1 -1
- package/dist/client/org/index.d.ts +2 -1
- package/dist/client/org/index.d.ts.map +1 -1
- package/dist/client/org/index.js +1 -1
- package/dist/client/org/index.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +11 -3
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +62 -12
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts +2 -0
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
- package/dist/client/resources/use-mcp-servers.js +59 -3
- package/dist/client/resources/use-mcp-servers.js.map +1 -1
- package/dist/client/settings/SecretsSection.d.ts.map +1 -1
- package/dist/client/settings/SecretsSection.js +9 -0
- package/dist/client/settings/SecretsSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +50 -12
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js +13 -30
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +27 -1
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +4 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +5 -1
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +14 -7
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +100 -19
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +25 -49
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts.map +1 -1
- package/dist/deploy/route-discovery.js +1 -0
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/deploy/workspace-core.d.ts +1 -1
- package/dist/deploy/workspace-core.d.ts.map +1 -1
- package/dist/deploy/workspace-core.js +1 -0
- package/dist/deploy/workspace-core.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +17 -3
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/routes.js +1 -1
- package/dist/extensions/routes.js.map +1 -1
- package/dist/extensions/schema.d.ts +14 -14
- package/dist/extensions/schema.d.ts.map +1 -1
- package/dist/extensions/schema.js +4 -4
- package/dist/extensions/schema.js.map +1 -1
- package/dist/extensions/store.d.ts.map +1 -1
- package/dist/extensions/store.js +23 -0
- package/dist/extensions/store.js.map +1 -1
- package/dist/extensions/theme.d.ts +8 -1
- package/dist/extensions/theme.d.ts.map +1 -1
- package/dist/extensions/theme.js +43 -34
- package/dist/extensions/theme.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-client/routes.d.ts +1 -0
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +28 -1
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +5 -3
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/free-email-providers.d.ts +18 -0
- package/dist/org/free-email-providers.d.ts.map +1 -0
- package/dist/org/free-email-providers.js +124 -0
- package/dist/org/free-email-providers.js.map +1 -0
- package/dist/org/handlers.d.ts +29 -5
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +178 -37
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/index.d.ts +2 -1
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +2 -1
- package/dist/org/index.js.map +1 -1
- package/dist/org/migrations.d.ts.map +1 -1
- package/dist/org/migrations.js +4 -0
- package/dist/org/migrations.js.map +1 -1
- package/dist/org/plugin.d.ts.map +1 -1
- package/dist/org/plugin.js +13 -4
- package/dist/org/plugin.js.map +1 -1
- package/dist/org/schema.d.ts +19 -0
- package/dist/org/schema.d.ts.map +1 -1
- package/dist/org/schema.js +1 -0
- package/dist/org/schema.js.map +1 -1
- package/dist/org/types.d.ts +1 -0
- package/dist/org/types.d.ts.map +1 -1
- package/dist/org/types.js.map +1 -1
- package/dist/resources/metadata.d.ts +1 -0
- package/dist/resources/metadata.d.ts.map +1 -1
- package/dist/resources/metadata.js +13 -3
- package/dist/resources/metadata.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +44 -6
- package/dist/resources/store.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +115 -113
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +33 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +169 -68
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/credential-provider.d.ts +2 -2
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +31 -12
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +31 -0
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +10 -3
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/google-realtime-session.d.ts.map +1 -1
- package/dist/server/google-realtime-session.js +19 -6
- package/dist/server/google-realtime-session.js.map +1 -1
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +45 -6
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/request-context.d.ts +17 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +40 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/sentry-plugin.d.ts +11 -0
- package/dist/server/sentry-plugin.d.ts.map +1 -0
- package/dist/server/sentry-plugin.js +116 -0
- package/dist/server/sentry-plugin.js.map +1 -0
- package/dist/server/sentry.d.ts +92 -0
- package/dist/server/sentry.d.ts.map +1 -0
- package/dist/server/sentry.js +287 -0
- package/dist/server/sentry.js.map +1 -0
- package/dist/server/transcribe-voice.d.ts +2 -4
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +4 -16
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/server/voice-providers-status.d.ts.map +1 -1
- package/dist/server/voice-providers-status.js +19 -35
- package/dist/server/voice-providers-status.js.map +1 -1
- package/dist/styles/agent-native.css +15 -0
- package/docs/content/cloneable-saas.md +7 -9
- package/docs/content/deployment.md +6 -2
- package/docs/content/dispatch.md +1 -1
- package/docs/content/extensions.md +177 -142
- package/docs/content/faq.md +2 -2
- package/docs/content/getting-started.md +13 -11
- package/docs/content/multi-app-workspace.md +2 -2
- package/docs/content/observability.md +47 -0
- package/docs/content/pure-agent-apps.md +1 -1
- package/docs/content/template-clips.md +3 -3
- package/docs/content/template-design.md +3 -3
- package/docs/content/template-dispatch.md +1 -1
- package/docs/content/template-forms.md +1 -1
- package/docs/content/template-mail.md +1 -1
- package/docs/content/what-is-agent-native.md +4 -4
- package/docs/content/workspace.md +1 -1
- package/package.json +2 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
import { IconBuilding, IconUserPlus, IconTrash, IconCrown, IconShieldCheck, IconLoader2,
|
|
4
|
-
import { useOrg, useOrgMembers, useOrgInvitations, useCreateOrg, useUpdateOrg,
|
|
5
|
-
import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
2
|
+
import { useMemo, useRef, useState } from "react";
|
|
3
|
+
import { IconBuilding, IconUserPlus, IconTrash, IconCrown, IconShieldCheck, IconLoader2, IconCheck, IconPencil, IconAt, IconX, IconKey, IconCopy, IconRefresh, IconEye, IconEyeOff, IconCloudUpload, IconFileImport, IconPlus, IconAlertTriangle, } from "@tabler/icons-react";
|
|
4
|
+
import { useOrg, useOrgMembers, useOrgInvitations, useCreateOrg, useUpdateOrg, useBulkInviteMembers, useChangeMemberRole, useAcceptInvitation, useRemoveMember, useSwitchOrg, useSetOrgDomain, useSetA2ASecret, useSyncA2ASecret, useJoinByDomain, } from "./hooks.js";
|
|
5
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
6
6
|
function RoleIcon({ role }) {
|
|
7
7
|
if (role === "owner")
|
|
8
8
|
return _jsx(IconCrown, { className: "h-3.5 w-3.5 text-amber-500" });
|
|
@@ -79,31 +79,164 @@ function MembersCard() {
|
|
|
79
79
|
const { data: org } = useOrg();
|
|
80
80
|
const { data: membersData, isLoading: isLoadingMembers } = useOrgMembers();
|
|
81
81
|
const { data: invitationsData } = useOrgInvitations();
|
|
82
|
-
const inviteMember = useInviteMember();
|
|
83
82
|
const removeMember = useRemoveMember();
|
|
84
83
|
const switchOrg = useSwitchOrg();
|
|
85
|
-
const [inviteEmail, setInviteEmail] = useState("");
|
|
86
84
|
const [showInviteForm, setShowInviteForm] = useState(false);
|
|
87
85
|
if (!org?.orgId)
|
|
88
86
|
return null;
|
|
89
|
-
const
|
|
87
|
+
const isOwner = org.role === "owner";
|
|
88
|
+
const isOwnerOrAdmin = isOwner || org.role === "admin";
|
|
90
89
|
const members = membersData?.members ?? [];
|
|
91
90
|
const pendingInvites = invitationsData?.invitations ?? [];
|
|
92
91
|
const hasMultipleOrgs = (org.orgs?.length ?? 0) > 1;
|
|
93
|
-
return (_jsxs("section", { className: "rounded-lg border border-border bg-card p-4 space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-9 w-9 items-center justify-center rounded-lg bg-blue-600/10", children: _jsx(IconBuilding, { className: "h-5 w-5 text-blue-600" }) }), _jsxs("div", { children: [_jsx(OrgNameDisplay, { name: org.orgName ?? "", canEdit: isOwnerOrAdmin }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [members.length, " member", members.length !== 1 ? "s" : "", " \u00B7 You are", " ", org.role] })] })] }), hasMultipleOrgs && (_jsx("select", { value: org.orgId ?? "", onChange: (e) => switchOrg.mutate(e.target.value || null), disabled: switchOrg.isPending, className: "rounded-md border border-border bg-background px-2.5 py-1.5 text-xs", children: org.orgs.map((o) => (_jsx("option", { value: o.orgId, children: o.orgName }, o.orgId))) }))] }), _jsxs("div", { className: "border-t border-border pt-3 space-y-1", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2", children: "Members" }), isLoadingMembers && members.length === 0 && (_jsx(_Fragment, { children: [0, 1, 2].map((i) => (_jsx("div", { className: "flex items-center justify-between py-1.5 px-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-3.5 rounded bg-muted animate-pulse", style: { width: `${140 + i * 30}px` } }), _jsx("div", { className: "h-3.5 w-3.5 rounded bg-muted animate-pulse" })] }) }, i))) })), members.map((m) => (
|
|
94
|
-
onSuccess: () => {
|
|
95
|
-
setInviteEmail("");
|
|
96
|
-
setShowInviteForm(false);
|
|
97
|
-
},
|
|
98
|
-
}), className: "rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50", children: inviteMember.isPending ? (_jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(IconCheck, { className: "h-3.5 w-3.5" }), "Send"] })) }), _jsx("button", { type: "button", onClick: () => {
|
|
99
|
-
setShowInviteForm(false);
|
|
100
|
-
setInviteEmail("");
|
|
101
|
-
}, className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] }), _jsx("p", { className: "text-[11px] text-muted-foreground", children: "They'll need to sign in with Google using this exact email to accept the invitation." }), _jsx(ErrorText, { error: inviteMember.error })] })) })), isOwnerOrAdmin && _jsx(DomainSettingsSection, { domain: org.allowedDomain }), isOwnerOrAdmin && _jsx(A2ASecretSection, { secret: org.a2aSecret }), _jsx(ErrorText, { error: removeMember.error }), _jsx(ErrorText, { error: switchOrg.error })] }));
|
|
92
|
+
return (_jsxs("section", { className: "rounded-lg border border-border bg-card p-4 space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-9 w-9 items-center justify-center rounded-lg bg-blue-600/10", children: _jsx(IconBuilding, { className: "h-5 w-5 text-blue-600" }) }), _jsxs("div", { children: [_jsx(OrgNameDisplay, { name: org.orgName ?? "", canEdit: isOwnerOrAdmin }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [members.length, " member", members.length !== 1 ? "s" : "", " \u00B7 You are", " ", org.role] })] })] }), hasMultipleOrgs && (_jsx("select", { value: org.orgId ?? "", onChange: (e) => switchOrg.mutate(e.target.value || null), disabled: switchOrg.isPending, className: "rounded-md border border-border bg-background px-2.5 py-1.5 text-xs", children: org.orgs.map((o) => (_jsx("option", { value: o.orgId, children: o.orgName }, o.orgId))) }))] }), _jsxs("div", { className: "border-t border-border pt-3 space-y-1", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2", children: "Members" }), isLoadingMembers && members.length === 0 && (_jsx(_Fragment, { children: [0, 1, 2].map((i) => (_jsx("div", { className: "flex items-center justify-between py-1.5 px-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-3.5 rounded bg-muted animate-pulse", style: { width: `${140 + i * 30}px` } }), _jsx("div", { className: "h-3.5 w-3.5 rounded bg-muted animate-pulse" })] }) }, i))) })), members.map((m) => (_jsx(MemberRow, { email: m.email, role: m.role, isCurrentUser: m.email === org.email, currentUserRole: org.role ?? null }, m.email))), pendingInvites.map((inv) => (_jsx("div", { className: "flex items-center justify-between py-1.5 px-2 opacity-60", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm", children: inv.email }), _jsx(RoleIcon, { role: inv.role }), _jsxs("span", { className: "rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground", children: ["Invited", inv.role === "admin" ? " · admin" : ""] })] }) }, inv.id)))] }), isOwnerOrAdmin && (_jsx("div", { className: "border-t border-border pt-3", children: !showInviteForm ? (_jsxs("button", { type: "button", onClick: () => setShowInviteForm(true), className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconUserPlus, { className: "h-3.5 w-3.5" }), "Invite members"] })) : (_jsx(BulkInviteForm, { currentUserRole: org.role, onClose: () => setShowInviteForm(false) })) })), isOwnerOrAdmin && (_jsx(DomainSettingsSection, { domain: org.allowedDomain, ownerEmail: org.email })), isOwner && _jsx(A2ASecretSection, { secret: org.a2aSecret }), _jsx(ErrorText, { error: removeMember.error }), _jsx(ErrorText, { error: switchOrg.error })] }));
|
|
102
93
|
}
|
|
103
|
-
function
|
|
94
|
+
function MemberRow({ email, role, isCurrentUser, currentUserRole, }) {
|
|
95
|
+
const removeMember = useRemoveMember();
|
|
96
|
+
const changeRole = useChangeMemberRole();
|
|
97
|
+
const [editing, setEditing] = useState(false);
|
|
98
|
+
// Owners can manage admins + members. Admins can only manage members.
|
|
99
|
+
// Owners themselves are immutable through this UI; current user can't
|
|
100
|
+
// edit their own role here.
|
|
101
|
+
const canManage = role !== "owner" &&
|
|
102
|
+
!isCurrentUser &&
|
|
103
|
+
(currentUserRole === "owner" ||
|
|
104
|
+
(currentUserRole === "admin" && role === "member"));
|
|
105
|
+
return (_jsxs("div", { className: "flex items-center justify-between py-1.5 px-2 rounded hover:bg-accent/30", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm", children: email }), _jsx(RoleIcon, { role: role }), isCurrentUser && (_jsx("span", { className: "rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground", children: "You" })), role === "admin" && (_jsx("span", { className: "rounded border border-border px-1.5 py-0.5 text-[10px] text-blue-600", children: "Admin" }))] }), canManage && (_jsxs("div", { className: "flex items-center gap-1", children: [editing ? (_jsxs("select", { autoFocus: true, value: role, onChange: (e) => {
|
|
106
|
+
const next = e.target.value === "admin" ? "admin" : "member";
|
|
107
|
+
if (next !== role) {
|
|
108
|
+
changeRole.mutate({ email, role: next }, { onSuccess: () => setEditing(false) });
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
setEditing(false);
|
|
112
|
+
}
|
|
113
|
+
}, onBlur: () => setEditing(false), disabled: changeRole.isPending, className: "rounded-md border border-border bg-background px-1.5 py-0.5 text-[11px]", children: [_jsx("option", { value: "member", children: "Member" }), _jsx("option", { value: "admin", children: "Admin" })] })) : (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => setEditing(true), className: "text-muted-foreground hover:text-foreground", children: _jsx(IconPencil, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Change role" })] })), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", disabled: removeMember.isPending, onClick: () => removeMember.mutate(email), className: "text-muted-foreground hover:text-red-500 disabled:opacity-50", children: _jsx(IconTrash, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Remove member" })] })] }))] }));
|
|
114
|
+
}
|
|
115
|
+
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
116
|
+
function parseEmailList(input) {
|
|
117
|
+
return Array.from(new Set(input
|
|
118
|
+
.split(/[\s,;]+/)
|
|
119
|
+
.map((s) => s.trim().toLowerCase())
|
|
120
|
+
.filter(Boolean)));
|
|
121
|
+
}
|
|
122
|
+
function parseCsvEmails(text) {
|
|
123
|
+
// Tolerant CSV parse — split on lines, then on commas, take any cell
|
|
124
|
+
// that looks like an email. Handles "name,email,role" rows or just
|
|
125
|
+
// "email" per line. A robust full CSV parser would be overkill here.
|
|
126
|
+
const cells = [];
|
|
127
|
+
for (const line of text.split(/\r?\n/)) {
|
|
128
|
+
for (const cell of line.split(",")) {
|
|
129
|
+
const trimmed = cell.trim().replace(/^"|"$/g, "");
|
|
130
|
+
if (trimmed)
|
|
131
|
+
cells.push(trimmed);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return Array.from(new Set(cells.filter((c) => EMAIL_RE.test(c)).map((c) => c.toLowerCase())));
|
|
135
|
+
}
|
|
136
|
+
function BulkInviteForm({ currentUserRole, onClose, }) {
|
|
137
|
+
const bulkInvite = useBulkInviteMembers();
|
|
138
|
+
const fileRef = useRef(null);
|
|
139
|
+
const [drafts, setDrafts] = useState([
|
|
140
|
+
{ email: "", role: "member" },
|
|
141
|
+
]);
|
|
142
|
+
const [pasteOpen, setPasteOpen] = useState(false);
|
|
143
|
+
const [pasteValue, setPasteValue] = useState("");
|
|
144
|
+
const [pasteRole, setPasteRole] = useState("member");
|
|
145
|
+
const [resultBanner, setResultBanner] = useState(null);
|
|
146
|
+
const canSetAdmin = currentUserRole === "owner";
|
|
147
|
+
const validDrafts = useMemo(() => drafts
|
|
148
|
+
.map((d) => ({ ...d, email: d.email.trim().toLowerCase() }))
|
|
149
|
+
.filter((d) => EMAIL_RE.test(d.email)), [drafts]);
|
|
150
|
+
function setDraft(index, patch) {
|
|
151
|
+
setDrafts((prev) => prev.map((d, i) => (i === index ? { ...d, ...patch } : d)));
|
|
152
|
+
}
|
|
153
|
+
function appendEmails(emails, role) {
|
|
154
|
+
if (!emails.length)
|
|
155
|
+
return;
|
|
156
|
+
setDrafts((prev) => {
|
|
157
|
+
const existing = new Set(prev.map((d) => d.email.trim().toLowerCase()).filter(Boolean));
|
|
158
|
+
const fresh = [];
|
|
159
|
+
for (const e of emails) {
|
|
160
|
+
if (!existing.has(e)) {
|
|
161
|
+
fresh.push({ email: e, role });
|
|
162
|
+
existing.add(e);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// If the only existing row is an empty placeholder, drop it.
|
|
166
|
+
const cleaned = prev.filter((d, i) => !(i === 0 && !d.email.trim() && prev.length === 1));
|
|
167
|
+
return [...cleaned, ...fresh];
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function handleFile(file) {
|
|
171
|
+
file.text().then((text) => {
|
|
172
|
+
const emails = parseCsvEmails(text);
|
|
173
|
+
if (emails.length) {
|
|
174
|
+
appendEmails(emails, "member");
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
setResultBanner({
|
|
178
|
+
succeeded: 0,
|
|
179
|
+
failed: [{ email: file.name, error: "No valid emails found in CSV" }],
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
async function submit() {
|
|
185
|
+
setResultBanner(null);
|
|
186
|
+
const dedup = new Map();
|
|
187
|
+
for (const d of validDrafts) {
|
|
188
|
+
// canSetAdmin guard mirrors server-side enforcement so an admin-only
|
|
189
|
+
// user editing the form can't even attempt to grant admin (they'd
|
|
190
|
+
// get a 403 anyway).
|
|
191
|
+
const role = canSetAdmin ? d.role : "member";
|
|
192
|
+
dedup.set(d.email, { ...d, role });
|
|
193
|
+
}
|
|
194
|
+
const invites = Array.from(dedup.values());
|
|
195
|
+
if (invites.length === 0)
|
|
196
|
+
return;
|
|
197
|
+
const result = await bulkInvite.mutateAsync(invites);
|
|
198
|
+
setResultBanner({
|
|
199
|
+
succeeded: result.succeeded.length,
|
|
200
|
+
failed: result.failed,
|
|
201
|
+
});
|
|
202
|
+
// Wipe drafts that succeeded; leave failed ones so the user can fix
|
|
203
|
+
// and retry. If everything succeeded, reset to a single blank row.
|
|
204
|
+
const failedEmails = new Set(result.failed.map((f) => f.email));
|
|
205
|
+
setDrafts((prev) => {
|
|
206
|
+
const remaining = prev.filter((d) => failedEmails.has(d.email.trim().toLowerCase()));
|
|
207
|
+
return remaining.length > 0 ? remaining : [{ email: "", role: "member" }];
|
|
208
|
+
});
|
|
209
|
+
// Auto-close on full success.
|
|
210
|
+
if (result.failed.length === 0 && result.succeeded.length > 0) {
|
|
211
|
+
setTimeout(() => onClose(), 1200);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return (_jsxs("div", { className: "space-y-3", children: [_jsx("div", { className: "space-y-2", children: drafts.map((draft, i) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "email", value: draft.email, onChange: (e) => setDraft(i, { email: e.target.value }), placeholder: "colleague@company.com", className: "flex-1 rounded-md border border-border bg-background px-3 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground", autoFocus: i === drafts.length - 1 }), _jsxs("select", { value: draft.role, onChange: (e) => setDraft(i, {
|
|
215
|
+
role: e.target.value === "admin" ? "admin" : "member",
|
|
216
|
+
}), disabled: !canSetAdmin, title: canSetAdmin
|
|
217
|
+
? undefined
|
|
218
|
+
: "Only the organization owner can invite admins", className: "rounded-md border border-border bg-background px-2 py-1.5 text-xs disabled:opacity-50", children: [_jsx("option", { value: "member", children: "Member" }), _jsx("option", { value: "admin", children: "Admin" })] }), drafts.length > 1 && (_jsx("button", { type: "button", onClick: () => setDrafts((prev) => prev.filter((_, j) => j !== i)), className: "text-muted-foreground hover:text-red-500", children: _jsx(IconX, { className: "h-3.5 w-3.5" }) }))] }, i))) }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("button", { type: "button", onClick: () => setDrafts((prev) => [...prev, { email: "", role: "member" }]), className: "inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconPlus, { className: "h-3.5 w-3.5" }), "Add another"] }), _jsxs("button", { type: "button", onClick: () => setPasteOpen((v) => !v), className: "inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconUserPlus, { className: "h-3.5 w-3.5" }), "Paste many"] }), _jsxs("button", { type: "button", onClick: () => fileRef.current?.click(), className: "inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconFileImport, { className: "h-3.5 w-3.5" }), "Import CSV"] }), _jsx("input", { ref: fileRef, type: "file", accept: ".csv,text/csv,text/plain", className: "hidden", onChange: (e) => {
|
|
219
|
+
const file = e.target.files?.[0];
|
|
220
|
+
if (file)
|
|
221
|
+
handleFile(file);
|
|
222
|
+
// reset so re-uploading the same file re-fires onChange
|
|
223
|
+
e.target.value = "";
|
|
224
|
+
} })] }), pasteOpen && (_jsxs("div", { className: "space-y-2 rounded-md border border-border p-3", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground", children: "Paste emails (comma, space, or newline separated)" }), _jsx("textarea", { value: pasteValue, onChange: (e) => setPasteValue(e.target.value), rows: 4, placeholder: "alice@acme.com, bob@acme.com\ncharlie@acme.com", className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-foreground" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("select", { value: pasteRole, onChange: (e) => setPasteRole(e.target.value === "admin" ? "admin" : "member"), disabled: !canSetAdmin, className: "rounded-md border border-border bg-background px-2 py-1.5 text-xs disabled:opacity-50", children: [_jsx("option", { value: "member", children: "Add as members" }), _jsx("option", { value: "admin", children: "Add as admins" })] }), _jsx("button", { type: "button", onClick: () => {
|
|
225
|
+
appendEmails(parseEmailList(pasteValue), pasteRole);
|
|
226
|
+
setPasteValue("");
|
|
227
|
+
setPasteOpen(false);
|
|
228
|
+
}, disabled: parseEmailList(pasteValue).length === 0, className: "rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50", children: "Add" }), _jsx("button", { type: "button", onClick: () => {
|
|
229
|
+
setPasteValue("");
|
|
230
|
+
setPasteOpen(false);
|
|
231
|
+
}, className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] })] })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", disabled: validDrafts.length === 0 || bulkInvite.isPending, onClick: submit, className: "rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50", children: bulkInvite.isPending ? (_jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(IconCheck, { className: "h-3.5 w-3.5" }), "Send ", validDrafts.length || "", " ", validDrafts.length === 1 ? "invite" : "invites"] })) }), _jsx("button", { type: "button", onClick: onClose, className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Close" })] }), _jsxs("p", { className: "text-[11px] text-muted-foreground", children: ["Each invitee signs in with this exact email to accept.", canSetAdmin
|
|
232
|
+
? " Admins can manage members and workspace settings."
|
|
233
|
+
: " Only the organization owner can grant admin access."] }), resultBanner && (_jsxs("div", { className: "space-y-1 rounded-md border border-border bg-accent/30 p-2.5", children: [resultBanner.succeeded > 0 && (_jsxs("p", { className: "text-[11px] text-green-600", children: [_jsx(IconCheck, { className: "inline h-3 w-3 -mt-0.5" }), " Sent", " ", resultBanner.succeeded, " ", resultBanner.succeeded === 1 ? "invite" : "invites", "."] })), resultBanner.failed.length > 0 && (_jsx("ul", { className: "space-y-0.5 text-[11px] text-red-500", children: resultBanner.failed.map((f) => (_jsxs("li", { children: [_jsx(IconAlertTriangle, { className: "inline h-3 w-3 -mt-0.5 mr-1" }), f.email, ": ", f.error] }, f.email))) }))] })), _jsx(ErrorText, { error: bulkInvite.error })] }));
|
|
234
|
+
}
|
|
235
|
+
function DomainSettingsSection({ domain, ownerEmail, }) {
|
|
104
236
|
const setOrgDomain = useSetOrgDomain();
|
|
105
237
|
const [editing, setEditing] = useState(false);
|
|
106
238
|
const [draft, setDraft] = useState(domain ?? "");
|
|
239
|
+
const ownDomain = ownerEmail.split("@")[1]?.toLowerCase() ?? "";
|
|
107
240
|
function save() {
|
|
108
241
|
const trimmed = draft.trim().toLowerCase();
|
|
109
242
|
if (trimmed === (domain ?? "")) {
|
|
@@ -114,18 +247,18 @@ function DomainSettingsSection({ domain }) {
|
|
|
114
247
|
onSuccess: () => setEditing(false),
|
|
115
248
|
});
|
|
116
249
|
}
|
|
117
|
-
return (_jsxs("div", { className: "border-t border-border pt-3 space-y-2", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: "Email domain auto-join" }),
|
|
250
|
+
return (_jsxs("div", { className: "border-t border-border pt-3 space-y-2", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: "Email domain auto-join" }), _jsxs("p", { className: "text-[11px] text-muted-foreground", children: ["Anyone who signs up with an email at this domain will join your organization automatically. You can only set your own email domain (", ownDomain || "—", "); free email providers like gmail.com or outlook.com aren't allowed."] }), !editing ? (_jsx("div", { className: "flex items-center gap-2", children: domain ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm", children: [_jsx(IconAt, { className: "h-3.5 w-3.5 text-muted-foreground" }), domain] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => {
|
|
118
251
|
setDraft(domain);
|
|
119
252
|
setEditing(true);
|
|
120
253
|
}, className: "text-muted-foreground hover:text-foreground", children: _jsx(IconPencil, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Edit domain" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", disabled: setOrgDomain.isPending, onClick: () => setOrgDomain.mutate(null), className: "text-muted-foreground hover:text-red-500 disabled:opacity-50", children: _jsx(IconX, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Remove domain" })] })] })) : (_jsxs("button", { type: "button", onClick: () => {
|
|
121
|
-
setDraft(
|
|
254
|
+
setDraft(ownDomain);
|
|
122
255
|
setEditing(true);
|
|
123
|
-
}, className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconAt, { className: "h-3.5 w-3.5" }), "
|
|
256
|
+
}, className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconAt, { className: "h-3.5 w-3.5" }), "Allow ", ownDomain || "your domain", " to auto-join"] })) })) : (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: draft, onChange: (e) => setDraft(e.target.value), onKeyDown: (e) => {
|
|
124
257
|
if (e.key === "Enter")
|
|
125
258
|
save();
|
|
126
259
|
if (e.key === "Escape")
|
|
127
260
|
setEditing(false);
|
|
128
|
-
}, placeholder: "example.com", className: "rounded-md border border-border bg-background px-2.5 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground", autoFocus: true }), _jsx("button", { type: "button", disabled: setOrgDomain.isPending, onClick: save, className: "rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50", children: setOrgDomain.isPending ? (_jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" })) : ("Save") }), _jsx("button", { type: "button", onClick: () => setEditing(false), className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] })), _jsx(ErrorText, { error: setOrgDomain.error })] }));
|
|
261
|
+
}, placeholder: ownDomain || "example.com", className: "rounded-md border border-border bg-background px-2.5 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground", autoFocus: true }), _jsx("button", { type: "button", disabled: setOrgDomain.isPending, onClick: save, className: "rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50", children: setOrgDomain.isPending ? (_jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" })) : ("Save") }), _jsx("button", { type: "button", onClick: () => setEditing(false), className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] })), _jsx(ErrorText, { error: setOrgDomain.error })] }));
|
|
129
262
|
}
|
|
130
263
|
function A2ASecretSection({ secret }) {
|
|
131
264
|
const setA2ASecret = useSetA2ASecret();
|
|
@@ -201,6 +334,7 @@ function A2ASecretSection({ secret }) {
|
|
|
201
334
|
export function TeamPage({ layout, title = "Team", createOrgDescription, className, }) {
|
|
202
335
|
const { data: org, isLoading } = useOrg();
|
|
203
336
|
const content = (_jsxs("div", { className: `space-y-6 max-w-2xl ${className ?? ""}`, children: [_jsx("h2", { className: "text-2xl font-bold tracking-tight", children: title }), isLoading && (_jsx("section", { className: "rounded-lg border border-border bg-card p-6", children: _jsx("div", { className: "text-sm text-muted-foreground", children: "Loading\u2026" }) })), !isLoading && (_jsxs(_Fragment, { children: [_jsx(PendingInvitationsCard, {}), !org?.orgId ? (_jsxs(_Fragment, { children: [org?.domainMatches && org.domainMatches.length > 0 && (_jsx(JoinByDomainCard, { matches: org.domainMatches })), _jsx(CreateOrgCard, { description: createOrgDescription })] })) : (_jsx(MembersCard, {}))] }))] }));
|
|
204
|
-
|
|
337
|
+
const wrapped = (_jsx(TooltipProvider, { delayDuration: 200, children: content }));
|
|
338
|
+
return layout ? _jsx(_Fragment, { children: layout(wrapped) }) : wrapped;
|
|
205
339
|
}
|
|
206
340
|
//# sourceMappingURL=TeamPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TeamPage.js","sourceRoot":"","sources":["../../../src/client/org/TeamPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState, type ReactNode } from \"react\";\nimport {\n IconBuilding,\n IconUserPlus,\n IconTrash,\n IconCrown,\n IconShieldCheck,\n IconLoader2,\n IconMail,\n IconCheck,\n IconPencil,\n IconAt,\n IconX,\n IconKey,\n IconCopy,\n IconRefresh,\n IconEye,\n IconEyeOff,\n IconCloudUpload,\n} from \"@tabler/icons-react\";\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n useOrg,\n useOrgMembers,\n useOrgInvitations,\n useCreateOrg,\n useUpdateOrg,\n useInviteMember,\n useAcceptInvitation,\n useRemoveMember,\n useSwitchOrg,\n useSetOrgDomain,\n useSetA2ASecret,\n useSyncA2ASecret,\n useJoinByDomain,\n type SyncA2ASecretResult,\n} from \"./hooks.js\";\nimport type { DomainMatchOrg } from \"../../org/types.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\n\nexport interface TeamPageProps {\n /**\n * Optional wrapper around the page contents. Templates pass their own Layout\n * component so the Team page renders inside the template's chrome.\n */\n layout?: (children: ReactNode) => ReactNode;\n /**\n * Title shown at the top of the page. Defaults to \"Team\".\n */\n title?: string;\n /**\n * Description shown on the \"Create an Organization\" card. Defaults to\n * \"Set up a team to collaborate with your colleagues.\"\n */\n createOrgDescription?: string;\n /**\n * Class applied to the outer max-width container. Templates can use this to\n * tweak page width.\n */\n className?: string;\n}\n\nfunction RoleIcon({ role }: { role: string }) {\n if (role === \"owner\")\n return <IconCrown className=\"h-3.5 w-3.5 text-amber-500\" />;\n if (role === \"admin\")\n return <IconShieldCheck className=\"h-3.5 w-3.5 text-blue-500\" />;\n return null;\n}\n\nfunction ErrorText({ error }: { error: unknown }) {\n if (!error) return null;\n return (\n <p className=\"text-xs text-red-500\">\n {error instanceof Error ? error.message : String(error)}\n </p>\n );\n}\n\nfunction PendingInvitationsCard() {\n const { data: org } = useOrg();\n const acceptInvitation = useAcceptInvitation();\n\n if (!org?.pendingInvitations?.length) return null;\n\n return (\n <section className=\"rounded-lg border border-border bg-card p-4 space-y-3\">\n <h3 className=\"text-sm font-medium\">Pending Invitations</h3>\n {org.pendingInvitations.map((inv) => (\n <div\n key={inv.id}\n className=\"flex items-center justify-between rounded-md border border-border p-3\"\n >\n <div>\n <div className=\"text-sm font-medium\">{inv.orgName}</div>\n <div className=\"text-xs text-muted-foreground\">\n Invited by {inv.invitedBy}\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => acceptInvitation.mutate(inv.id)}\n disabled={acceptInvitation.isPending}\n className=\"rounded-md bg-green-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-green-700 disabled:opacity-50\"\n >\n {acceptInvitation.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Accept\"\n )}\n </button>\n </div>\n ))}\n <ErrorText error={acceptInvitation.error} />\n </section>\n );\n}\n\nfunction JoinByDomainCard({ matches }: { matches: DomainMatchOrg[] }) {\n const joinByDomain = useJoinByDomain();\n const [pendingId, setPendingId] = useState<string | null>(null);\n\n return (\n <section className=\"rounded-lg border border-border bg-card p-4 space-y-3\">\n <h3 className=\"text-sm font-medium\">Join your team</h3>\n <p className=\"text-sm text-muted-foreground\">\n {matches.length === 1\n ? `An organization matching your email domain already exists. Join it to collaborate with your teammates.`\n : `Organizations matching your email domain already exist. Join one to collaborate with your teammates.`}\n </p>\n <div className=\"space-y-2\">\n {matches.map((m) => (\n <div\n key={m.orgId}\n className=\"flex items-center justify-between rounded-md border border-border p-3\"\n >\n <div className=\"flex items-center gap-2.5\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-md bg-blue-600/10\">\n <IconBuilding className=\"h-4 w-4 text-blue-600\" />\n </div>\n <div className=\"text-sm font-medium\">{m.orgName}</div>\n </div>\n <button\n type=\"button\"\n disabled={joinByDomain.isPending && pendingId === m.orgId}\n onClick={() => {\n setPendingId(m.orgId);\n joinByDomain.mutate(m.orgId, {\n onSettled: () => setPendingId(null),\n });\n }}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {joinByDomain.isPending && pendingId === m.orgId ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Join\"\n )}\n </button>\n </div>\n ))}\n </div>\n <ErrorText error={joinByDomain.error} />\n </section>\n );\n}\n\nfunction CreateOrgCard({ description }: { description?: string }) {\n const createOrg = useCreateOrg();\n const [name, setName] = useState(\"\");\n const [showForm, setShowForm] = useState(false);\n\n return (\n <section className=\"rounded-lg border border-border bg-card p-4 space-y-3\">\n <h3 className=\"text-sm font-medium\">Create an Organization</h3>\n <p className=\"text-sm text-muted-foreground\">\n {description || \"Set up a team to collaborate with your colleagues.\"}\n </p>\n {!showForm ? (\n <button\n type=\"button\"\n onClick={() => setShowForm(true)}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90\"\n >\n Create organization\n </button>\n ) : (\n <div className=\"space-y-2\">\n <input\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. Acme Inc.\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus\n />\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n disabled={!name.trim() || createOrg.isPending}\n onClick={() =>\n createOrg.mutate(name.trim(), {\n onSuccess: () => {\n setName(\"\");\n setShowForm(false);\n },\n })\n }\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {createOrg.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Create\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setShowForm(false);\n setName(\"\");\n }}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n <ErrorText error={createOrg.error} />\n </div>\n )}\n </section>\n );\n}\n\nfunction OrgNameDisplay({ name, canEdit }: { name: string; canEdit: boolean }) {\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(name);\n const updateOrg = useUpdateOrg();\n\n if (!canEdit) return <div className=\"text-sm font-medium\">{name}</div>;\n\n if (!editing) {\n return (\n <button\n type=\"button\"\n onClick={() => {\n setDraft(name);\n setEditing(true);\n }}\n className=\"group flex items-center gap-1.5 text-sm font-medium hover:text-foreground/80\"\n >\n {name}\n <IconPencil className=\"h-3 w-3 text-muted-foreground opacity-0 group-hover:opacity-100\" />\n </button>\n );\n }\n\n function save() {\n const trimmed = draft.trim();\n if (!trimmed || trimmed === name) {\n setEditing(false);\n return;\n }\n updateOrg.mutate(trimmed, { onSuccess: () => setEditing(false) });\n }\n\n return (\n <div className=\"flex items-center gap-1.5\">\n <input\n type=\"text\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") save();\n if (e.key === \"Escape\") setEditing(false);\n }}\n onBlur={save}\n className=\"rounded border border-border bg-background px-1.5 py-0.5 text-sm font-medium focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus\n />\n <ErrorText error={updateOrg.error} />\n </div>\n );\n}\n\nfunction MembersCard() {\n const { data: org } = useOrg();\n const { data: membersData, isLoading: isLoadingMembers } = useOrgMembers();\n const { data: invitationsData } = useOrgInvitations();\n const inviteMember = useInviteMember();\n const removeMember = useRemoveMember();\n const switchOrg = useSwitchOrg();\n\n const [inviteEmail, setInviteEmail] = useState(\"\");\n const [showInviteForm, setShowInviteForm] = useState(false);\n\n if (!org?.orgId) return null;\n\n const isOwnerOrAdmin = org.role === \"owner\" || org.role === \"admin\";\n const members = membersData?.members ?? [];\n const pendingInvites = invitationsData?.invitations ?? [];\n const hasMultipleOrgs = (org.orgs?.length ?? 0) > 1;\n\n return (\n <section className=\"rounded-lg border border-border bg-card p-4 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-lg bg-blue-600/10\">\n <IconBuilding className=\"h-5 w-5 text-blue-600\" />\n </div>\n <div>\n <OrgNameDisplay name={org.orgName ?? \"\"} canEdit={isOwnerOrAdmin} />\n <div className=\"text-xs text-muted-foreground\">\n {members.length} member{members.length !== 1 ? \"s\" : \"\"} · You are{\" \"}\n {org.role}\n </div>\n </div>\n </div>\n {hasMultipleOrgs && (\n <select\n value={org.orgId ?? \"\"}\n onChange={(e) => switchOrg.mutate(e.target.value || null)}\n disabled={switchOrg.isPending}\n className=\"rounded-md border border-border bg-background px-2.5 py-1.5 text-xs\"\n >\n {org.orgs.map((o) => (\n <option key={o.orgId} value={o.orgId}>\n {o.orgName}\n </option>\n ))}\n </select>\n )}\n </div>\n\n <div className=\"border-t border-border pt-3 space-y-1\">\n <div className=\"text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2\">\n Members\n </div>\n {isLoadingMembers && members.length === 0 && (\n <>\n {[0, 1, 2].map((i) => (\n <div\n key={i}\n className=\"flex items-center justify-between py-1.5 px-2\"\n >\n <div className=\"flex items-center gap-2\">\n <div\n className=\"h-3.5 rounded bg-muted animate-pulse\"\n style={{ width: `${140 + i * 30}px` }}\n />\n <div className=\"h-3.5 w-3.5 rounded bg-muted animate-pulse\" />\n </div>\n </div>\n ))}\n </>\n )}\n {members.map((m) => (\n <div\n key={m.email}\n className=\"flex items-center justify-between py-1.5 px-2 rounded hover:bg-accent/30\"\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">{m.email}</span>\n <RoleIcon role={m.role} />\n {m.email === org.email && (\n <span className=\"rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n You\n </span>\n )}\n </div>\n {isOwnerOrAdmin && m.email !== org.email && m.role !== \"owner\" && (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={removeMember.isPending}\n onClick={() => removeMember.mutate(m.email)}\n className=\"text-muted-foreground hover:text-red-500 disabled:opacity-50\"\n >\n <IconTrash className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Remove member</TooltipContent>\n </Tooltip>\n )}\n </div>\n ))}\n {pendingInvites.map((inv) => (\n <div\n key={inv.id}\n className=\"flex items-center justify-between py-1.5 px-2 opacity-60\"\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">{inv.email}</span>\n <span className=\"rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n Invited\n </span>\n </div>\n </div>\n ))}\n </div>\n\n {isOwnerOrAdmin && (\n <div className=\"border-t border-border pt-3\">\n {!showInviteForm ? (\n <button\n type=\"button\"\n onClick={() => setShowInviteForm(true)}\n className=\"flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50\"\n >\n <IconUserPlus className=\"h-3.5 w-3.5\" />\n Invite member\n </button>\n ) : (\n <div className=\"space-y-2\">\n <div className=\"flex gap-2\">\n <div className=\"relative flex-1\">\n <IconMail className=\"absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground\" />\n <input\n type=\"email\"\n value={inviteEmail}\n onChange={(e) => setInviteEmail(e.target.value)}\n placeholder=\"colleague@company.com\"\n className=\"w-full rounded-md border border-border bg-background pl-8 pr-3 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus\n />\n </div>\n <button\n type=\"button\"\n disabled={!inviteEmail.trim() || inviteMember.isPending}\n onClick={() =>\n inviteMember.mutate(inviteEmail.trim(), {\n onSuccess: () => {\n setInviteEmail(\"\");\n setShowInviteForm(false);\n },\n })\n }\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {inviteMember.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <span className=\"inline-flex items-center gap-1\">\n <IconCheck className=\"h-3.5 w-3.5\" />\n Send\n </span>\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setShowInviteForm(false);\n setInviteEmail(\"\");\n }}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n <p className=\"text-[11px] text-muted-foreground\">\n They'll need to sign in with Google using this exact email\n to accept the invitation.\n </p>\n <ErrorText error={inviteMember.error} />\n </div>\n )}\n </div>\n )}\n\n {isOwnerOrAdmin && <DomainSettingsSection domain={org.allowedDomain} />}\n\n {isOwnerOrAdmin && <A2ASecretSection secret={org.a2aSecret} />}\n\n <ErrorText error={removeMember.error} />\n <ErrorText error={switchOrg.error} />\n </section>\n );\n}\n\nfunction DomainSettingsSection({ domain }: { domain: string | null }) {\n const setOrgDomain = useSetOrgDomain();\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(domain ?? \"\");\n\n function save() {\n const trimmed = draft.trim().toLowerCase();\n if (trimmed === (domain ?? \"\")) {\n setEditing(false);\n return;\n }\n setOrgDomain.mutate(trimmed || null, {\n onSuccess: () => setEditing(false),\n });\n }\n\n return (\n <div className=\"border-t border-border pt-3 space-y-2\">\n <div className=\"text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Email domain auto-join\n </div>\n <p className=\"text-[11px] text-muted-foreground\">\n Anyone who signs up with an email from this domain can join your\n organization without an invitation.\n </p>\n {!editing ? (\n <div className=\"flex items-center gap-2\">\n {domain ? (\n <>\n <span className=\"inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm\">\n <IconAt className=\"h-3.5 w-3.5 text-muted-foreground\" />\n {domain}\n </span>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => {\n setDraft(domain);\n setEditing(true);\n }}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <IconPencil className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Edit domain</TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={setOrgDomain.isPending}\n onClick={() => setOrgDomain.mutate(null)}\n className=\"text-muted-foreground hover:text-red-500 disabled:opacity-50\"\n >\n <IconX className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Remove domain</TooltipContent>\n </Tooltip>\n </>\n ) : (\n <button\n type=\"button\"\n onClick={() => {\n setDraft(\"\");\n setEditing(true);\n }}\n className=\"flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50\"\n >\n <IconAt className=\"h-3.5 w-3.5\" />\n Set allowed domain\n </button>\n )}\n </div>\n ) : (\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") save();\n if (e.key === \"Escape\") setEditing(false);\n }}\n placeholder=\"example.com\"\n className=\"rounded-md border border-border bg-background px-2.5 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus\n />\n <button\n type=\"button\"\n disabled={setOrgDomain.isPending}\n onClick={save}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {setOrgDomain.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Save\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setEditing(false)}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n )}\n <ErrorText error={setOrgDomain.error} />\n </div>\n );\n}\n\nfunction A2ASecretSection({ secret }: { secret: string | null | undefined }) {\n const setA2ASecret = useSetA2ASecret();\n const syncA2ASecret = useSyncA2ASecret();\n const [revealed, setRevealed] = useState(false);\n const [copied, setCopied] = useState(false);\n const [pasteMode, setPasteMode] = useState(false);\n const [pasteValue, setPasteValue] = useState(\"\");\n const [syncResult, setSyncResult] = useState<SyncA2ASecretResult | null>(\n null,\n );\n\n function copyToClipboard() {\n if (!secret) return;\n navigator.clipboard.writeText(secret).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }\n\n // Push the current secret to all connected apps. Optionally pass the\n // PREVIOUS secret as `signSecret` so the receiving apps (which still\n // hold the previous value) can verify the JWT.\n function syncToApps(signSecret?: string) {\n setSyncResult(null);\n syncA2ASecret.mutate(signSecret ? { signSecret } : undefined, {\n onSuccess: (result) => {\n setSyncResult(result);\n },\n });\n }\n\n function regenerate() {\n setA2ASecret.mutate(undefined, {\n onSuccess: (result) => {\n setRevealed(false);\n // Auto-sync the new secret to all connected apps. Sign with the\n // PREVIOUS secret (which peers still hold) so verification on\n // their side succeeds and they accept the new value.\n syncToApps(result.previousSecret ?? undefined);\n },\n });\n }\n\n function saveSecret() {\n const trimmed = pasteValue.trim();\n if (!trimmed) return;\n setA2ASecret.mutate(trimmed, {\n onSuccess: (result) => {\n setPasteMode(false);\n setPasteValue(\"\");\n // Same auto-sync flow as regenerate: peers verify with the\n // previous secret, then update to the new pasted value.\n syncToApps(result.previousSecret ?? undefined);\n },\n });\n }\n\n const masked = secret ? \"****\" + secret.slice(-8) : \"Not set\";\n\n return (\n <div className=\"border-t border-border pt-3 space-y-2\">\n <div className=\"text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Cross-app authentication\n </div>\n <p className=\"text-[11px] text-muted-foreground\">\n This secret authenticates cross-app delegation (e.g. Dispatch to\n Analytics). All apps in your organization need the same secret.\n </p>\n\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm font-mono\">\n <IconKey className=\"h-3.5 w-3.5 text-muted-foreground\" />\n {revealed && secret ? secret : masked}\n </span>\n {secret && (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setRevealed(!revealed)}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n {revealed ? (\n <IconEyeOff className=\"h-3.5 w-3.5\" />\n ) : (\n <IconEye className=\"h-3.5 w-3.5\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent>\n {revealed ? \"Hide secret\" : \"Reveal secret\"}\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={copyToClipboard}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n {copied ? (\n <IconCheck className=\"h-3.5 w-3.5 text-green-500\" />\n ) : (\n <IconCopy className=\"h-3.5 w-3.5\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent>Copy secret</TooltipContent>\n </Tooltip>\n </>\n )}\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={regenerate}\n disabled={setA2ASecret.isPending || syncA2ASecret.isPending}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50 disabled:opacity-50\"\n >\n {setA2ASecret.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <IconRefresh className=\"h-3.5 w-3.5\" />\n )}\n Regenerate\n </button>\n </TooltipTrigger>\n <TooltipContent>\n Regenerate secret and sync to connected apps\n </TooltipContent>\n </Tooltip>\n {secret && (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => syncToApps()}\n disabled={setA2ASecret.isPending || syncA2ASecret.isPending}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50 disabled:opacity-50\"\n >\n {syncA2ASecret.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <IconCloudUpload className=\"h-3.5 w-3.5\" />\n )}\n Sync to apps\n </button>\n </TooltipTrigger>\n <TooltipContent>\n Push this secret to every connected app\n </TooltipContent>\n </Tooltip>\n )}\n </div>\n\n {syncA2ASecret.isPending && (\n <p className=\"text-[11px] text-muted-foreground\">\n Syncing to connected apps…\n </p>\n )}\n\n {syncResult && !syncA2ASecret.isPending && (\n <div className=\"space-y-1\">\n <p className=\"text-[11px] text-muted-foreground\">\n Synced to {syncResult.succeeded}/{syncResult.total} app\n {syncResult.total === 1 ? \"\" : \"s\"}\n {syncResult.failed > 0 ? ` (${syncResult.failed} failed)` : \"\"}.\n </p>\n {syncResult.failed > 0 && (\n <ul className=\"text-[11px] text-red-500 list-disc pl-5 space-y-0.5\">\n {syncResult.results\n .filter((r) => !r.ok)\n .map((r) => (\n <li key={r.id}>\n {r.name}: {r.error || `HTTP ${r.status ?? \"?\"}`}\n </li>\n ))}\n </ul>\n )}\n </div>\n )}\n\n {!pasteMode ? (\n <button\n type=\"button\"\n onClick={() => setPasteMode(true)}\n className=\"flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50\"\n >\n <IconKey className=\"h-3.5 w-3.5\" />\n Paste secret from another app\n </button>\n ) : (\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={pasteValue}\n onChange={(e) => setPasteValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") saveSecret();\n if (e.key === \"Escape\") {\n setPasteMode(false);\n setPasteValue(\"\");\n }\n }}\n placeholder=\"Paste A2A secret\"\n className=\"flex-1 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm font-mono focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus\n />\n <button\n type=\"button\"\n disabled={!pasteValue.trim() || setA2ASecret.isPending}\n onClick={saveSecret}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {setA2ASecret.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Save\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setPasteMode(false);\n setPasteValue(\"\");\n }}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n )}\n\n <ErrorText error={setA2ASecret.error} />\n <ErrorText error={syncA2ASecret.error} />\n </div>\n );\n}\n\n/**\n * Default Team management page. Templates can route directly to this component\n * or wrap it with their own Layout via the `layout` prop.\n */\nexport function TeamPage({\n layout,\n title = \"Team\",\n createOrgDescription,\n className,\n}: TeamPageProps) {\n const { data: org, isLoading } = useOrg();\n\n const content = (\n <div className={`space-y-6 max-w-2xl ${className ?? \"\"}`}>\n <h2 className=\"text-2xl font-bold tracking-tight\">{title}</h2>\n\n {isLoading && (\n <section className=\"rounded-lg border border-border bg-card p-6\">\n <div className=\"text-sm text-muted-foreground\">Loading…</div>\n </section>\n )}\n\n {!isLoading && (\n <>\n <PendingInvitationsCard />\n {!org?.orgId ? (\n <>\n {org?.domainMatches && org.domainMatches.length > 0 && (\n <JoinByDomainCard matches={org.domainMatches} />\n )}\n <CreateOrgCard description={createOrgDescription} />\n </>\n ) : (\n <MembersCard />\n )}\n </>\n )}\n </div>\n );\n\n return layout ? <>{layout(content)}</> : content;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TeamPage.js","sourceRoot":"","sources":["../../../src/client/org/TeamPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useRef, useState, type ReactNode } from \"react\";\nimport {\n IconBuilding,\n IconUserPlus,\n IconTrash,\n IconCrown,\n IconShieldCheck,\n IconLoader2,\n IconCheck,\n IconPencil,\n IconAt,\n IconX,\n IconKey,\n IconCopy,\n IconRefresh,\n IconEye,\n IconEyeOff,\n IconCloudUpload,\n IconFileImport,\n IconPlus,\n IconAlertTriangle,\n} from \"@tabler/icons-react\";\nimport {\n useOrg,\n useOrgMembers,\n useOrgInvitations,\n useCreateOrg,\n useUpdateOrg,\n useBulkInviteMembers,\n useChangeMemberRole,\n useAcceptInvitation,\n useRemoveMember,\n useSwitchOrg,\n useSetOrgDomain,\n useSetA2ASecret,\n useSyncA2ASecret,\n useJoinByDomain,\n type InviteRole,\n type SyncA2ASecretResult,\n} from \"./hooks.js\";\nimport type { DomainMatchOrg } from \"../../org/types.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\n\nexport interface TeamPageProps {\n /**\n * Optional wrapper around the page contents. Templates pass their own Layout\n * component so the Team page renders inside the template's chrome.\n */\n layout?: (children: ReactNode) => ReactNode;\n /**\n * Title shown at the top of the page. Defaults to \"Team\".\n */\n title?: string;\n /**\n * Description shown on the \"Create an Organization\" card. Defaults to\n * \"Set up a team to collaborate with your colleagues.\"\n */\n createOrgDescription?: string;\n /**\n * Class applied to the outer max-width container. Templates can use this to\n * tweak page width.\n */\n className?: string;\n}\n\nfunction RoleIcon({ role }: { role: string }) {\n if (role === \"owner\")\n return <IconCrown className=\"h-3.5 w-3.5 text-amber-500\" />;\n if (role === \"admin\")\n return <IconShieldCheck className=\"h-3.5 w-3.5 text-blue-500\" />;\n return null;\n}\n\nfunction ErrorText({ error }: { error: unknown }) {\n if (!error) return null;\n return (\n <p className=\"text-xs text-red-500\">\n {error instanceof Error ? error.message : String(error)}\n </p>\n );\n}\n\nfunction PendingInvitationsCard() {\n const { data: org } = useOrg();\n const acceptInvitation = useAcceptInvitation();\n\n if (!org?.pendingInvitations?.length) return null;\n\n return (\n <section className=\"rounded-lg border border-border bg-card p-4 space-y-3\">\n <h3 className=\"text-sm font-medium\">Pending Invitations</h3>\n {org.pendingInvitations.map((inv) => (\n <div\n key={inv.id}\n className=\"flex items-center justify-between rounded-md border border-border p-3\"\n >\n <div>\n <div className=\"text-sm font-medium\">{inv.orgName}</div>\n <div className=\"text-xs text-muted-foreground\">\n Invited by {inv.invitedBy}\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => acceptInvitation.mutate(inv.id)}\n disabled={acceptInvitation.isPending}\n className=\"rounded-md bg-green-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-green-700 disabled:opacity-50\"\n >\n {acceptInvitation.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Accept\"\n )}\n </button>\n </div>\n ))}\n <ErrorText error={acceptInvitation.error} />\n </section>\n );\n}\n\nfunction JoinByDomainCard({ matches }: { matches: DomainMatchOrg[] }) {\n const joinByDomain = useJoinByDomain();\n const [pendingId, setPendingId] = useState<string | null>(null);\n\n return (\n <section className=\"rounded-lg border border-border bg-card p-4 space-y-3\">\n <h3 className=\"text-sm font-medium\">Join your team</h3>\n <p className=\"text-sm text-muted-foreground\">\n {matches.length === 1\n ? `An organization matching your email domain already exists. Join it to collaborate with your teammates.`\n : `Organizations matching your email domain already exist. Join one to collaborate with your teammates.`}\n </p>\n <div className=\"space-y-2\">\n {matches.map((m) => (\n <div\n key={m.orgId}\n className=\"flex items-center justify-between rounded-md border border-border p-3\"\n >\n <div className=\"flex items-center gap-2.5\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-md bg-blue-600/10\">\n <IconBuilding className=\"h-4 w-4 text-blue-600\" />\n </div>\n <div className=\"text-sm font-medium\">{m.orgName}</div>\n </div>\n <button\n type=\"button\"\n disabled={joinByDomain.isPending && pendingId === m.orgId}\n onClick={() => {\n setPendingId(m.orgId);\n joinByDomain.mutate(m.orgId, {\n onSettled: () => setPendingId(null),\n });\n }}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {joinByDomain.isPending && pendingId === m.orgId ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Join\"\n )}\n </button>\n </div>\n ))}\n </div>\n <ErrorText error={joinByDomain.error} />\n </section>\n );\n}\n\nfunction CreateOrgCard({ description }: { description?: string }) {\n const createOrg = useCreateOrg();\n const [name, setName] = useState(\"\");\n const [showForm, setShowForm] = useState(false);\n\n return (\n <section className=\"rounded-lg border border-border bg-card p-4 space-y-3\">\n <h3 className=\"text-sm font-medium\">Create an Organization</h3>\n <p className=\"text-sm text-muted-foreground\">\n {description || \"Set up a team to collaborate with your colleagues.\"}\n </p>\n {!showForm ? (\n <button\n type=\"button\"\n onClick={() => setShowForm(true)}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90\"\n >\n Create organization\n </button>\n ) : (\n <div className=\"space-y-2\">\n <input\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. Acme Inc.\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus\n />\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n disabled={!name.trim() || createOrg.isPending}\n onClick={() =>\n createOrg.mutate(name.trim(), {\n onSuccess: () => {\n setName(\"\");\n setShowForm(false);\n },\n })\n }\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {createOrg.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Create\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setShowForm(false);\n setName(\"\");\n }}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n <ErrorText error={createOrg.error} />\n </div>\n )}\n </section>\n );\n}\n\nfunction OrgNameDisplay({ name, canEdit }: { name: string; canEdit: boolean }) {\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(name);\n const updateOrg = useUpdateOrg();\n\n if (!canEdit) return <div className=\"text-sm font-medium\">{name}</div>;\n\n if (!editing) {\n return (\n <button\n type=\"button\"\n onClick={() => {\n setDraft(name);\n setEditing(true);\n }}\n className=\"group flex items-center gap-1.5 text-sm font-medium hover:text-foreground/80\"\n >\n {name}\n <IconPencil className=\"h-3 w-3 text-muted-foreground opacity-0 group-hover:opacity-100\" />\n </button>\n );\n }\n\n function save() {\n const trimmed = draft.trim();\n if (!trimmed || trimmed === name) {\n setEditing(false);\n return;\n }\n updateOrg.mutate(trimmed, { onSuccess: () => setEditing(false) });\n }\n\n return (\n <div className=\"flex items-center gap-1.5\">\n <input\n type=\"text\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") save();\n if (e.key === \"Escape\") setEditing(false);\n }}\n onBlur={save}\n className=\"rounded border border-border bg-background px-1.5 py-0.5 text-sm font-medium focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus\n />\n <ErrorText error={updateOrg.error} />\n </div>\n );\n}\n\nfunction MembersCard() {\n const { data: org } = useOrg();\n const { data: membersData, isLoading: isLoadingMembers } = useOrgMembers();\n const { data: invitationsData } = useOrgInvitations();\n const removeMember = useRemoveMember();\n const switchOrg = useSwitchOrg();\n\n const [showInviteForm, setShowInviteForm] = useState(false);\n\n if (!org?.orgId) return null;\n\n const isOwner = org.role === \"owner\";\n const isOwnerOrAdmin = isOwner || org.role === \"admin\";\n const members = membersData?.members ?? [];\n const pendingInvites = invitationsData?.invitations ?? [];\n const hasMultipleOrgs = (org.orgs?.length ?? 0) > 1;\n\n return (\n <section className=\"rounded-lg border border-border bg-card p-4 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-lg bg-blue-600/10\">\n <IconBuilding className=\"h-5 w-5 text-blue-600\" />\n </div>\n <div>\n <OrgNameDisplay name={org.orgName ?? \"\"} canEdit={isOwnerOrAdmin} />\n <div className=\"text-xs text-muted-foreground\">\n {members.length} member{members.length !== 1 ? \"s\" : \"\"} · You are{\" \"}\n {org.role}\n </div>\n </div>\n </div>\n {hasMultipleOrgs && (\n <select\n value={org.orgId ?? \"\"}\n onChange={(e) => switchOrg.mutate(e.target.value || null)}\n disabled={switchOrg.isPending}\n className=\"rounded-md border border-border bg-background px-2.5 py-1.5 text-xs\"\n >\n {org.orgs.map((o) => (\n <option key={o.orgId} value={o.orgId}>\n {o.orgName}\n </option>\n ))}\n </select>\n )}\n </div>\n\n <div className=\"border-t border-border pt-3 space-y-1\">\n <div className=\"text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2\">\n Members\n </div>\n {isLoadingMembers && members.length === 0 && (\n <>\n {[0, 1, 2].map((i) => (\n <div\n key={i}\n className=\"flex items-center justify-between py-1.5 px-2\"\n >\n <div className=\"flex items-center gap-2\">\n <div\n className=\"h-3.5 rounded bg-muted animate-pulse\"\n style={{ width: `${140 + i * 30}px` }}\n />\n <div className=\"h-3.5 w-3.5 rounded bg-muted animate-pulse\" />\n </div>\n </div>\n ))}\n </>\n )}\n {members.map((m) => (\n <MemberRow\n key={m.email}\n email={m.email}\n role={m.role}\n isCurrentUser={m.email === org.email}\n currentUserRole={org.role ?? null}\n />\n ))}\n {pendingInvites.map((inv) => (\n <div\n key={inv.id}\n className=\"flex items-center justify-between py-1.5 px-2 opacity-60\"\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">{inv.email}</span>\n <RoleIcon role={inv.role} />\n <span className=\"rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n Invited{inv.role === \"admin\" ? \" · admin\" : \"\"}\n </span>\n </div>\n </div>\n ))}\n </div>\n\n {isOwnerOrAdmin && (\n <div className=\"border-t border-border pt-3\">\n {!showInviteForm ? (\n <button\n type=\"button\"\n onClick={() => setShowInviteForm(true)}\n className=\"flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50\"\n >\n <IconUserPlus className=\"h-3.5 w-3.5\" />\n Invite members\n </button>\n ) : (\n <BulkInviteForm\n currentUserRole={org.role}\n onClose={() => setShowInviteForm(false)}\n />\n )}\n </div>\n )}\n\n {isOwnerOrAdmin && (\n <DomainSettingsSection\n domain={org.allowedDomain}\n ownerEmail={org.email}\n />\n )}\n\n {isOwner && <A2ASecretSection secret={org.a2aSecret} />}\n\n <ErrorText error={removeMember.error} />\n <ErrorText error={switchOrg.error} />\n </section>\n );\n}\n\nfunction MemberRow({\n email,\n role,\n isCurrentUser,\n currentUserRole,\n}: {\n email: string;\n role: string;\n isCurrentUser: boolean;\n currentUserRole: string | null;\n}) {\n const removeMember = useRemoveMember();\n const changeRole = useChangeMemberRole();\n const [editing, setEditing] = useState(false);\n\n // Owners can manage admins + members. Admins can only manage members.\n // Owners themselves are immutable through this UI; current user can't\n // edit their own role here.\n const canManage =\n role !== \"owner\" &&\n !isCurrentUser &&\n (currentUserRole === \"owner\" ||\n (currentUserRole === \"admin\" && role === \"member\"));\n\n return (\n <div className=\"flex items-center justify-between py-1.5 px-2 rounded hover:bg-accent/30\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm\">{email}</span>\n <RoleIcon role={role} />\n {isCurrentUser && (\n <span className=\"rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n You\n </span>\n )}\n {role === \"admin\" && (\n <span className=\"rounded border border-border px-1.5 py-0.5 text-[10px] text-blue-600\">\n Admin\n </span>\n )}\n </div>\n {canManage && (\n <div className=\"flex items-center gap-1\">\n {editing ? (\n <select\n autoFocus\n value={role}\n onChange={(e) => {\n const next = e.target.value === \"admin\" ? \"admin\" : \"member\";\n if (next !== role) {\n changeRole.mutate(\n { email, role: next },\n { onSuccess: () => setEditing(false) },\n );\n } else {\n setEditing(false);\n }\n }}\n onBlur={() => setEditing(false)}\n disabled={changeRole.isPending}\n className=\"rounded-md border border-border bg-background px-1.5 py-0.5 text-[11px]\"\n >\n <option value=\"member\">Member</option>\n <option value=\"admin\">Admin</option>\n </select>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setEditing(true)}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <IconPencil className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Change role</TooltipContent>\n </Tooltip>\n )}\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={removeMember.isPending}\n onClick={() => removeMember.mutate(email)}\n className=\"text-muted-foreground hover:text-red-500 disabled:opacity-50\"\n >\n <IconTrash className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Remove member</TooltipContent>\n </Tooltip>\n </div>\n )}\n </div>\n );\n}\n\ninterface DraftInvite {\n email: string;\n role: InviteRole;\n}\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nfunction parseEmailList(input: string): string[] {\n return Array.from(\n new Set(\n input\n .split(/[\\s,;]+/)\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean),\n ),\n );\n}\n\nfunction parseCsvEmails(text: string): string[] {\n // Tolerant CSV parse — split on lines, then on commas, take any cell\n // that looks like an email. Handles \"name,email,role\" rows or just\n // \"email\" per line. A robust full CSV parser would be overkill here.\n const cells: string[] = [];\n for (const line of text.split(/\\r?\\n/)) {\n for (const cell of line.split(\",\")) {\n const trimmed = cell.trim().replace(/^\"|\"$/g, \"\");\n if (trimmed) cells.push(trimmed);\n }\n }\n return Array.from(\n new Set(cells.filter((c) => EMAIL_RE.test(c)).map((c) => c.toLowerCase())),\n );\n}\n\nfunction BulkInviteForm({\n currentUserRole,\n onClose,\n}: {\n currentUserRole: string | null;\n onClose: () => void;\n}) {\n const bulkInvite = useBulkInviteMembers();\n const fileRef = useRef<HTMLInputElement>(null);\n const [drafts, setDrafts] = useState<DraftInvite[]>([\n { email: \"\", role: \"member\" },\n ]);\n const [pasteOpen, setPasteOpen] = useState(false);\n const [pasteValue, setPasteValue] = useState(\"\");\n const [pasteRole, setPasteRole] = useState<InviteRole>(\"member\");\n const [resultBanner, setResultBanner] = useState<{\n succeeded: number;\n failed: { email: string; error: string }[];\n } | null>(null);\n\n const canSetAdmin = currentUserRole === \"owner\";\n\n const validDrafts = useMemo(\n () =>\n drafts\n .map((d) => ({ ...d, email: d.email.trim().toLowerCase() }))\n .filter((d) => EMAIL_RE.test(d.email)),\n [drafts],\n );\n\n function setDraft(index: number, patch: Partial<DraftInvite>) {\n setDrafts((prev) =>\n prev.map((d, i) => (i === index ? { ...d, ...patch } : d)),\n );\n }\n\n function appendEmails(emails: string[], role: InviteRole) {\n if (!emails.length) return;\n setDrafts((prev) => {\n const existing = new Set(\n prev.map((d) => d.email.trim().toLowerCase()).filter(Boolean),\n );\n const fresh: DraftInvite[] = [];\n for (const e of emails) {\n if (!existing.has(e)) {\n fresh.push({ email: e, role });\n existing.add(e);\n }\n }\n // If the only existing row is an empty placeholder, drop it.\n const cleaned = prev.filter(\n (d, i) => !(i === 0 && !d.email.trim() && prev.length === 1),\n );\n return [...cleaned, ...fresh];\n });\n }\n\n function handleFile(file: File) {\n file.text().then((text) => {\n const emails = parseCsvEmails(text);\n if (emails.length) {\n appendEmails(emails, \"member\");\n } else {\n setResultBanner({\n succeeded: 0,\n failed: [{ email: file.name, error: \"No valid emails found in CSV\" }],\n });\n }\n });\n }\n\n async function submit() {\n setResultBanner(null);\n const dedup = new Map<string, DraftInvite>();\n for (const d of validDrafts) {\n // canSetAdmin guard mirrors server-side enforcement so an admin-only\n // user editing the form can't even attempt to grant admin (they'd\n // get a 403 anyway).\n const role = canSetAdmin ? d.role : \"member\";\n dedup.set(d.email, { ...d, role });\n }\n const invites = Array.from(dedup.values());\n if (invites.length === 0) return;\n\n const result = await bulkInvite.mutateAsync(invites);\n setResultBanner({\n succeeded: result.succeeded.length,\n failed: result.failed,\n });\n\n // Wipe drafts that succeeded; leave failed ones so the user can fix\n // and retry. If everything succeeded, reset to a single blank row.\n const failedEmails = new Set(result.failed.map((f) => f.email));\n setDrafts((prev) => {\n const remaining = prev.filter((d) =>\n failedEmails.has(d.email.trim().toLowerCase()),\n );\n return remaining.length > 0 ? remaining : [{ email: \"\", role: \"member\" }];\n });\n\n // Auto-close on full success.\n if (result.failed.length === 0 && result.succeeded.length > 0) {\n setTimeout(() => onClose(), 1200);\n }\n }\n\n return (\n <div className=\"space-y-3\">\n <div className=\"space-y-2\">\n {drafts.map((draft, i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <input\n type=\"email\"\n value={draft.email}\n onChange={(e) => setDraft(i, { email: e.target.value })}\n placeholder=\"colleague@company.com\"\n className=\"flex-1 rounded-md border border-border bg-background px-3 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus={i === drafts.length - 1}\n />\n <select\n value={draft.role}\n onChange={(e) =>\n setDraft(i, {\n role: e.target.value === \"admin\" ? \"admin\" : \"member\",\n })\n }\n disabled={!canSetAdmin}\n title={\n canSetAdmin\n ? undefined\n : \"Only the organization owner can invite admins\"\n }\n className=\"rounded-md border border-border bg-background px-2 py-1.5 text-xs disabled:opacity-50\"\n >\n <option value=\"member\">Member</option>\n <option value=\"admin\">Admin</option>\n </select>\n {drafts.length > 1 && (\n <button\n type=\"button\"\n onClick={() =>\n setDrafts((prev) => prev.filter((_, j) => j !== i))\n }\n className=\"text-muted-foreground hover:text-red-500\"\n >\n <IconX className=\"h-3.5 w-3.5\" />\n </button>\n )}\n </div>\n ))}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() =>\n setDrafts((prev) => [...prev, { email: \"\", role: \"member\" }])\n }\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50\"\n >\n <IconPlus className=\"h-3.5 w-3.5\" />\n Add another\n </button>\n <button\n type=\"button\"\n onClick={() => setPasteOpen((v) => !v)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50\"\n >\n <IconUserPlus className=\"h-3.5 w-3.5\" />\n Paste many\n </button>\n <button\n type=\"button\"\n onClick={() => fileRef.current?.click()}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50\"\n >\n <IconFileImport className=\"h-3.5 w-3.5\" />\n Import CSV\n </button>\n <input\n ref={fileRef}\n type=\"file\"\n accept=\".csv,text/csv,text/plain\"\n className=\"hidden\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) handleFile(file);\n // reset so re-uploading the same file re-fires onChange\n e.target.value = \"\";\n }}\n />\n </div>\n\n {pasteOpen && (\n <div className=\"space-y-2 rounded-md border border-border p-3\">\n <div className=\"text-xs font-medium text-muted-foreground\">\n Paste emails (comma, space, or newline separated)\n </div>\n <textarea\n value={pasteValue}\n onChange={(e) => setPasteValue(e.target.value)}\n rows={4}\n placeholder=\"alice@acme.com, bob@acme.com charlie@acme.com\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-foreground\"\n />\n <div className=\"flex items-center gap-2\">\n <select\n value={pasteRole}\n onChange={(e) =>\n setPasteRole(e.target.value === \"admin\" ? \"admin\" : \"member\")\n }\n disabled={!canSetAdmin}\n className=\"rounded-md border border-border bg-background px-2 py-1.5 text-xs disabled:opacity-50\"\n >\n <option value=\"member\">Add as members</option>\n <option value=\"admin\">Add as admins</option>\n </select>\n <button\n type=\"button\"\n onClick={() => {\n appendEmails(parseEmailList(pasteValue), pasteRole);\n setPasteValue(\"\");\n setPasteOpen(false);\n }}\n disabled={parseEmailList(pasteValue).length === 0}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n Add\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setPasteValue(\"\");\n setPasteOpen(false);\n }}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n </div>\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n disabled={validDrafts.length === 0 || bulkInvite.isPending}\n onClick={submit}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {bulkInvite.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <span className=\"inline-flex items-center gap-1\">\n <IconCheck className=\"h-3.5 w-3.5\" />\n Send {validDrafts.length || \"\"}{\" \"}\n {validDrafts.length === 1 ? \"invite\" : \"invites\"}\n </span>\n )}\n </button>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n Close\n </button>\n </div>\n\n <p className=\"text-[11px] text-muted-foreground\">\n Each invitee signs in with this exact email to accept.\n {canSetAdmin\n ? \" Admins can manage members and workspace settings.\"\n : \" Only the organization owner can grant admin access.\"}\n </p>\n\n {resultBanner && (\n <div className=\"space-y-1 rounded-md border border-border bg-accent/30 p-2.5\">\n {resultBanner.succeeded > 0 && (\n <p className=\"text-[11px] text-green-600\">\n <IconCheck className=\"inline h-3 w-3 -mt-0.5\" /> Sent{\" \"}\n {resultBanner.succeeded}{\" \"}\n {resultBanner.succeeded === 1 ? \"invite\" : \"invites\"}.\n </p>\n )}\n {resultBanner.failed.length > 0 && (\n <ul className=\"space-y-0.5 text-[11px] text-red-500\">\n {resultBanner.failed.map((f) => (\n <li key={f.email}>\n <IconAlertTriangle className=\"inline h-3 w-3 -mt-0.5 mr-1\" />\n {f.email}: {f.error}\n </li>\n ))}\n </ul>\n )}\n </div>\n )}\n\n <ErrorText error={bulkInvite.error} />\n </div>\n );\n}\n\nfunction DomainSettingsSection({\n domain,\n ownerEmail,\n}: {\n domain: string | null;\n ownerEmail: string;\n}) {\n const setOrgDomain = useSetOrgDomain();\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(domain ?? \"\");\n\n const ownDomain = ownerEmail.split(\"@\")[1]?.toLowerCase() ?? \"\";\n\n function save() {\n const trimmed = draft.trim().toLowerCase();\n if (trimmed === (domain ?? \"\")) {\n setEditing(false);\n return;\n }\n setOrgDomain.mutate(trimmed || null, {\n onSuccess: () => setEditing(false),\n });\n }\n\n return (\n <div className=\"border-t border-border pt-3 space-y-2\">\n <div className=\"text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Email domain auto-join\n </div>\n <p className=\"text-[11px] text-muted-foreground\">\n Anyone who signs up with an email at this domain will join your\n organization automatically. You can only set your own email domain (\n {ownDomain || \"—\"}); free email providers like gmail.com or outlook.com\n aren't allowed.\n </p>\n {!editing ? (\n <div className=\"flex items-center gap-2\">\n {domain ? (\n <>\n <span className=\"inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm\">\n <IconAt className=\"h-3.5 w-3.5 text-muted-foreground\" />\n {domain}\n </span>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => {\n setDraft(domain);\n setEditing(true);\n }}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <IconPencil className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Edit domain</TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled={setOrgDomain.isPending}\n onClick={() => setOrgDomain.mutate(null)}\n className=\"text-muted-foreground hover:text-red-500 disabled:opacity-50\"\n >\n <IconX className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Remove domain</TooltipContent>\n </Tooltip>\n </>\n ) : (\n <button\n type=\"button\"\n onClick={() => {\n setDraft(ownDomain);\n setEditing(true);\n }}\n className=\"flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50\"\n >\n <IconAt className=\"h-3.5 w-3.5\" />\n Allow {ownDomain || \"your domain\"} to auto-join\n </button>\n )}\n </div>\n ) : (\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") save();\n if (e.key === \"Escape\") setEditing(false);\n }}\n placeholder={ownDomain || \"example.com\"}\n className=\"rounded-md border border-border bg-background px-2.5 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus\n />\n <button\n type=\"button\"\n disabled={setOrgDomain.isPending}\n onClick={save}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {setOrgDomain.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Save\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setEditing(false)}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n )}\n <ErrorText error={setOrgDomain.error} />\n </div>\n );\n}\n\nfunction A2ASecretSection({ secret }: { secret: string | null | undefined }) {\n const setA2ASecret = useSetA2ASecret();\n const syncA2ASecret = useSyncA2ASecret();\n const [revealed, setRevealed] = useState(false);\n const [copied, setCopied] = useState(false);\n const [pasteMode, setPasteMode] = useState(false);\n const [pasteValue, setPasteValue] = useState(\"\");\n const [syncResult, setSyncResult] = useState<SyncA2ASecretResult | null>(\n null,\n );\n\n function copyToClipboard() {\n if (!secret) return;\n navigator.clipboard.writeText(secret).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }\n\n // Push the current secret to all connected apps. Optionally pass the\n // PREVIOUS secret as `signSecret` so the receiving apps (which still\n // hold the previous value) can verify the JWT.\n function syncToApps(signSecret?: string) {\n setSyncResult(null);\n syncA2ASecret.mutate(signSecret ? { signSecret } : undefined, {\n onSuccess: (result) => {\n setSyncResult(result);\n },\n });\n }\n\n function regenerate() {\n setA2ASecret.mutate(undefined, {\n onSuccess: (result) => {\n setRevealed(false);\n // Auto-sync the new secret to all connected apps. Sign with the\n // PREVIOUS secret (which peers still hold) so verification on\n // their side succeeds and they accept the new value.\n syncToApps(result.previousSecret ?? undefined);\n },\n });\n }\n\n function saveSecret() {\n const trimmed = pasteValue.trim();\n if (!trimmed) return;\n setA2ASecret.mutate(trimmed, {\n onSuccess: (result) => {\n setPasteMode(false);\n setPasteValue(\"\");\n // Same auto-sync flow as regenerate: peers verify with the\n // previous secret, then update to the new pasted value.\n syncToApps(result.previousSecret ?? undefined);\n },\n });\n }\n\n const masked = secret ? \"****\" + secret.slice(-8) : \"Not set\";\n\n return (\n <div className=\"border-t border-border pt-3 space-y-2\">\n <div className=\"text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Cross-app authentication\n </div>\n <p className=\"text-[11px] text-muted-foreground\">\n This secret authenticates cross-app delegation (e.g. Dispatch to\n Analytics). All apps in your organization need the same secret.\n </p>\n\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm font-mono\">\n <IconKey className=\"h-3.5 w-3.5 text-muted-foreground\" />\n {revealed && secret ? secret : masked}\n </span>\n {secret && (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setRevealed(!revealed)}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n {revealed ? (\n <IconEyeOff className=\"h-3.5 w-3.5\" />\n ) : (\n <IconEye className=\"h-3.5 w-3.5\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent>\n {revealed ? \"Hide secret\" : \"Reveal secret\"}\n </TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={copyToClipboard}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n {copied ? (\n <IconCheck className=\"h-3.5 w-3.5 text-green-500\" />\n ) : (\n <IconCopy className=\"h-3.5 w-3.5\" />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent>Copy secret</TooltipContent>\n </Tooltip>\n </>\n )}\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={regenerate}\n disabled={setA2ASecret.isPending || syncA2ASecret.isPending}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50 disabled:opacity-50\"\n >\n {setA2ASecret.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <IconRefresh className=\"h-3.5 w-3.5\" />\n )}\n Regenerate\n </button>\n </TooltipTrigger>\n <TooltipContent>\n Regenerate secret and sync to connected apps\n </TooltipContent>\n </Tooltip>\n {secret && (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => syncToApps()}\n disabled={setA2ASecret.isPending || syncA2ASecret.isPending}\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50 disabled:opacity-50\"\n >\n {syncA2ASecret.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <IconCloudUpload className=\"h-3.5 w-3.5\" />\n )}\n Sync to apps\n </button>\n </TooltipTrigger>\n <TooltipContent>\n Push this secret to every connected app\n </TooltipContent>\n </Tooltip>\n )}\n </div>\n\n {syncA2ASecret.isPending && (\n <p className=\"text-[11px] text-muted-foreground\">\n Syncing to connected apps…\n </p>\n )}\n\n {syncResult && !syncA2ASecret.isPending && (\n <div className=\"space-y-1\">\n <p className=\"text-[11px] text-muted-foreground\">\n Synced to {syncResult.succeeded}/{syncResult.total} app\n {syncResult.total === 1 ? \"\" : \"s\"}\n {syncResult.failed > 0 ? ` (${syncResult.failed} failed)` : \"\"}.\n </p>\n {syncResult.failed > 0 && (\n <ul className=\"text-[11px] text-red-500 list-disc pl-5 space-y-0.5\">\n {syncResult.results\n .filter((r) => !r.ok)\n .map((r) => (\n <li key={r.id}>\n {r.name}: {r.error || `HTTP ${r.status ?? \"?\"}`}\n </li>\n ))}\n </ul>\n )}\n </div>\n )}\n\n {!pasteMode ? (\n <button\n type=\"button\"\n onClick={() => setPasteMode(true)}\n className=\"flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50\"\n >\n <IconKey className=\"h-3.5 w-3.5\" />\n Paste secret from another app\n </button>\n ) : (\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={pasteValue}\n onChange={(e) => setPasteValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") saveSecret();\n if (e.key === \"Escape\") {\n setPasteMode(false);\n setPasteValue(\"\");\n }\n }}\n placeholder=\"Paste A2A secret\"\n className=\"flex-1 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm font-mono focus:outline-none focus:ring-1 focus:ring-foreground\"\n autoFocus\n />\n <button\n type=\"button\"\n disabled={!pasteValue.trim() || setA2ASecret.isPending}\n onClick={saveSecret}\n className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background hover:opacity-90 disabled:opacity-50\"\n >\n {setA2ASecret.isPending ? (\n <IconLoader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n \"Save\"\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setPasteMode(false);\n setPasteValue(\"\");\n }}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n )}\n\n <ErrorText error={setA2ASecret.error} />\n <ErrorText error={syncA2ASecret.error} />\n </div>\n );\n}\n\n/**\n * Default Team management page. Templates can route directly to this component\n * or wrap it with their own Layout via the `layout` prop.\n */\nexport function TeamPage({\n layout,\n title = \"Team\",\n createOrgDescription,\n className,\n}: TeamPageProps) {\n const { data: org, isLoading } = useOrg();\n\n const content = (\n <div className={`space-y-6 max-w-2xl ${className ?? \"\"}`}>\n <h2 className=\"text-2xl font-bold tracking-tight\">{title}</h2>\n\n {isLoading && (\n <section className=\"rounded-lg border border-border bg-card p-6\">\n <div className=\"text-sm text-muted-foreground\">Loading…</div>\n </section>\n )}\n\n {!isLoading && (\n <>\n <PendingInvitationsCard />\n {!org?.orgId ? (\n <>\n {org?.domainMatches && org.domainMatches.length > 0 && (\n <JoinByDomainCard matches={org.domainMatches} />\n )}\n <CreateOrgCard description={createOrgDescription} />\n </>\n ) : (\n <MembersCard />\n )}\n </>\n )}\n </div>\n );\n\n const wrapped = (\n <TooltipProvider delayDuration={200}>{content}</TooltipProvider>\n );\n\n return layout ? <>{layout(wrapped)}</> : wrapped;\n}\n"]}
|