@agent-native/core 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/agent/thread-data-builder.d.ts +1 -0
  2. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  3. package/dist/agent/thread-data-builder.js +1 -0
  4. package/dist/agent/thread-data-builder.js.map +1 -1
  5. package/dist/client/AgentPanel.d.ts.map +1 -1
  6. package/dist/client/AgentPanel.js +8 -45
  7. package/dist/client/AgentPanel.js.map +1 -1
  8. package/dist/client/AssistantChat.d.ts.map +1 -1
  9. package/dist/client/AssistantChat.js +76 -16
  10. package/dist/client/AssistantChat.js.map +1 -1
  11. package/dist/client/builder-frame.d.ts.map +1 -1
  12. package/dist/client/builder-frame.js +10 -3
  13. package/dist/client/builder-frame.js.map +1 -1
  14. package/dist/client/components/ui/dropdown-menu.js +2 -2
  15. package/dist/client/components/ui/dropdown-menu.js.map +1 -1
  16. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  17. package/dist/client/resources/ResourcesPanel.js +6 -6
  18. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  19. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  20. package/dist/client/settings/useBuilderStatus.js +6 -2
  21. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  22. package/dist/client/sharing/ShareButton.d.ts +2 -0
  23. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  24. package/dist/client/sharing/ShareButton.js +84 -24
  25. package/dist/client/sharing/ShareButton.js.map +1 -1
  26. package/dist/client/use-action.d.ts.map +1 -1
  27. package/dist/client/use-action.js +1 -0
  28. package/dist/client/use-action.js.map +1 -1
  29. package/dist/server/action-routes.d.ts.map +1 -1
  30. package/dist/server/action-routes.js +1 -0
  31. package/dist/server/action-routes.js.map +1 -1
  32. package/dist/server/agent-chat-plugin.d.ts +14 -0
  33. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  34. package/dist/server/agent-chat-plugin.js +77 -12
  35. package/dist/server/agent-chat-plugin.js.map +1 -1
  36. package/dist/server/builder-browser.d.ts +8 -6
  37. package/dist/server/builder-browser.d.ts.map +1 -1
  38. package/dist/server/builder-browser.js +54 -32
  39. package/dist/server/builder-browser.js.map +1 -1
  40. package/dist/server/core-routes-plugin.d.ts +7 -0
  41. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  42. package/dist/server/core-routes-plugin.js +100 -74
  43. package/dist/server/core-routes-plugin.js.map +1 -1
  44. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useBuilderStatus.js","sourceRoot":"","sources":["../../../src/client/settings/useBuilderStatus.ts"],"names":[],"mappings":"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","sourcesContent":["import { agentNativePath } from \"../api-path.js\";\nimport { useState, useEffect, useCallback, useRef } from \"react\";\nimport { getCallbackOrigin } from \"../frame.js\";\n\nexport interface BuilderStatus {\n configured: boolean;\n builderEnabled: boolean;\n /**\n * True when `BUILDER_PRIVATE_KEY` is set at the deploy level. Every user\n * of this deploy shares the operator's Builder identity and per-user\n * connect/disconnect is disabled. UIs must hide connect prompts and\n * disconnect buttons when this is true.\n */\n envManaged?: boolean;\n connectUrl: string;\n appHost: string;\n apiHost: string;\n publicKeyConfigured: boolean;\n privateKeyConfigured: boolean;\n userId?: string;\n orgName?: string;\n orgKind?: string;\n /**\n * Set when the OAuth callback ran but failed to persist credentials.\n * Surfaced as a one-shot row by the server so the connect-flow polling\n * can stop with a clear message instead of timing out at 5min.\n */\n connectError?: { message: string; at: number };\n}\n\n/**\n * Fetches Builder connection status from /_agent-native/builder/status.\n * Re-fetches on window focus to detect post-redirect state changes.\n */\nexport function useBuilderStatus() {\n const [status, setStatus] = useState<BuilderStatus | null>(null);\n const [loading, setLoading] = useState(true);\n\n const fetchStatus = useCallback(async () => {\n try {\n const res = await fetch(agentNativePath(\"/_agent-native/builder/status\"));\n if (!res.ok) {\n setStatus(null);\n return;\n }\n setStatus(await res.json());\n } catch {\n setStatus(null);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n fetchStatus();\n\n function onFocus() {\n fetchStatus();\n }\n function onVisibility() {\n if (document.visibilityState === \"visible\") fetchStatus();\n }\n window.addEventListener(\"focus\", onFocus);\n document.addEventListener(\"visibilitychange\", onVisibility);\n // Engine connect/disconnect actions (e.g. the Builder disconnect button)\n // dispatch this event so dependent cards refresh without a full reload.\n window.addEventListener(\"agent-engine:configured-changed\", fetchStatus);\n return () => {\n window.removeEventListener(\"focus\", onFocus);\n document.removeEventListener(\"visibilitychange\", onVisibility);\n window.removeEventListener(\n \"agent-engine:configured-changed\",\n fetchStatus,\n );\n };\n }, [fetchStatus]);\n\n return { status, loading, refetch: fetchStatus };\n}\n\n// ─── useBuilderConnectFlow ──────────────────────────────────────────────────\n//\n// Shared state machine for the \"open Builder CLI-auth popup + poll\n// /builder/status until credentials land\" interaction. Replaces three\n// near-duplicate inline implementations: `BuilderCliAuthMethod` in\n// OnboardingPanel, `ConnectBuilderCard`, and `BuilderConnectCta` in\n// AssistantChat. Each consumer supplies its own popup URL / completion\n// behavior; the hook owns the polling + timeout + focus refresh.\n//\n// `popupUrl` is what we pass to `window.open`. The default\n// `/_agent-native/builder/connect` is a server-side 302 to the real\n// cli-auth URL — using it keeps the click handler synchronous so popup\n// blockers don't downgrade the open to same-tab navigation. Pass an\n// explicit `popupUrl` (e.g. the already-computed cli-auth URL) if your\n// caller already has it in hand.\n\nexport interface BuilderConnectFlowOptions {\n /** URL to synchronously open on start(). Defaults to the 302 shortcut. */\n popupUrl?: string;\n /** Invoked after the status poll first sees `configured: true`. */\n onConnected?: (state: { orgName: string | null }) => void | Promise<void>;\n}\n\nexport interface BuilderConnectFlow {\n configured: boolean;\n /**\n * True when the deploy has BUILDER_PRIVATE_KEY set. UIs should treat\n * Builder as connected for everyone in this mode and hide all connect /\n * disconnect controls — `start()` will be a no-op.\n */\n envManaged: boolean;\n /**\n * True when ENABLE_BUILDER (or a BUILDER_BRANCH_PROJECT_ID) is set on the\n * deploy, gating Builder cloud branch creation. When false, the card\n * surfaces a \"coming soon\" waitlist CTA instead of a Send button.\n */\n builderEnabled: boolean;\n orgName: string | null;\n connecting: boolean;\n error: string | null;\n /**\n * True once the first `/builder/status` fetch has completed (successfully\n * or not). Consumers that accept an `initialConfigured` prop (e.g. agent\n * tool-call results rendered with server-side state) should treat\n * `configured`/`orgName` as authoritative only once this flips true —\n * otherwise the hook's starting `false` defaults would cause a flash\n * back to \"Connect Builder\" on first paint.\n */\n hasFetchedStatus: boolean;\n /** Open the popup and begin polling. Must be called from a user-gesture handler. */\n start: () => void;\n}\n\nconst POLL_INTERVAL_MS = 2000;\nconst POLL_TIMEOUT_MS = 5 * 60 * 1000;\n\nfunction notifyAgentEngineConfiguredChanged(source: string) {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agent-engine:configured-changed\", {\n detail: { source },\n }),\n );\n}\n\nexport function useBuilderConnectFlow(\n opts: BuilderConnectFlowOptions = {},\n): BuilderConnectFlow {\n const { popupUrl, onConnected } = opts;\n const [configured, setConfigured] = useState(false);\n const [envManaged, setEnvManaged] = useState(false);\n const [builderEnabled, setBuilderEnabled] = useState(false);\n const [orgName, setOrgName] = useState<string | null>(null);\n const [connecting, setConnecting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [hasFetchedStatus, setHasFetchedStatus] = useState(false);\n const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const mountedRef = useRef(true);\n const notifiedConnectedRef = useRef(false);\n // Keep onConnected in a ref so start() doesn't need to re-create when the\n // caller passes an inline arrow function.\n const onConnectedRef = useRef(onConnected);\n onConnectedRef.current = onConnected;\n\n const stopPoll = useCallback(() => {\n if (pollRef.current) {\n clearInterval(pollRef.current);\n pollRef.current = null;\n }\n }, []);\n\n const fetchStatus = useCallback(async () => {\n const origin = getCallbackOrigin() || window.location.origin;\n try {\n const r = await fetch(\n new URL(agentNativePath(\"/_agent-native/builder/status\"), origin).href,\n );\n if (!r.ok) return null;\n return (await r.json()) as {\n configured: boolean;\n envManaged?: boolean;\n builderEnabled?: boolean;\n orgName?: string | null;\n connectError?: { message: string; at: number };\n };\n } catch {\n return null;\n }\n }, []);\n\n // Initial fetch + focus/visibility refresh so if the user completed the\n // flow in another tab (or a downgraded same-tab nav) we notice it. Also\n // listen for `agent-engine:configured-changed` so a Disconnect click in\n // Settings propagates to any connect-CTA cards rendered elsewhere in\n // the app without waiting for the next focus event.\n useEffect(() => {\n mountedRef.current = true;\n let cancelled = false;\n const refresh = async () => {\n const s = await fetchStatus();\n if (cancelled || !mountedRef.current) return;\n // Flip `hasFetchedStatus` even when the fetch failed — the caller's\n // \"use initial props until the hook has an answer\" pattern wants to\n // stop waiting after we've tried, regardless of network outcome.\n setHasFetchedStatus(true);\n if (!s) return;\n setConfigured(!!s.configured);\n setEnvManaged(!!s.envManaged);\n setBuilderEnabled(!!s.builderEnabled);\n const org = s.orgName ?? null;\n setOrgName(org);\n if (s.configured && !notifiedConnectedRef.current) {\n notifiedConnectedRef.current = true;\n notifyAgentEngineConfiguredChanged(\"builder-status\");\n try {\n await onConnectedRef.current?.({ orgName: org });\n } catch {\n // The caller's callback is a UI convenience; status is already set.\n }\n } else if (!s.configured) {\n notifiedConnectedRef.current = false;\n }\n };\n refresh();\n const onVisible = () => {\n if (document.visibilityState === \"visible\") refresh();\n };\n window.addEventListener(\"focus\", refresh);\n document.addEventListener(\"visibilitychange\", onVisible);\n window.addEventListener(\"agent-engine:configured-changed\", refresh);\n return () => {\n cancelled = true;\n mountedRef.current = false;\n window.removeEventListener(\"focus\", refresh);\n document.removeEventListener(\"visibilitychange\", onVisible);\n window.removeEventListener(\"agent-engine:configured-changed\", refresh);\n stopPoll();\n };\n }, [fetchStatus, stopPoll]);\n\n const start = useCallback(() => {\n // In env-managed mode, per-user OAuth is disabled — `/builder/connect`\n // returns 409. Skip the popup and just refresh state so the UI flips\n // to its \"connected via deployment\" rendering.\n if (envManaged) return;\n stopPoll();\n setConnecting(true);\n setError(null);\n\n // Open SYNCHRONOUSLY inside the caller's click handler — any await\n // before window.open lets the user-gesture token expire, which causes\n // popup blockers to block entirely or fall back to same-tab navigation.\n const origin = getCallbackOrigin() || window.location.origin;\n const url =\n popupUrl ??\n new URL(agentNativePath(\"/_agent-native/builder/connect\"), origin).href;\n try {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n } catch {\n // Fall through — polling still detects completion if the user\n // opens the URL themselves.\n }\n\n const started = Date.now();\n pollRef.current = setInterval(async () => {\n const s = await fetchStatus();\n if (!mountedRef.current) {\n stopPoll();\n return;\n }\n if (s?.configured) {\n stopPoll();\n setConfigured(true);\n setEnvManaged(!!s.envManaged);\n setBuilderEnabled(!!s.builderEnabled);\n const org = s.orgName ?? null;\n setOrgName(org);\n setConnecting(false);\n notifiedConnectedRef.current = true;\n notifyAgentEngineConfiguredChanged(\"builder-connect\");\n try {\n await onConnectedRef.current?.({ orgName: org });\n } catch {\n // Consumer's callback failed; we've already flipped the UI state\n // to connected. Swallow so we don't re-arm the flow.\n }\n } else if (s?.connectError?.message) {\n // OAuth callback ran but writeBuilderCredentials threw — surface the\n // real error instead of letting the user wait 5 minutes for timeout.\n stopPoll();\n setConnecting(false);\n setError(\n `Couldn't save Builder credentials: ${s.connectError.message}. Try again or contact support.`,\n );\n } else if (Date.now() - started > POLL_TIMEOUT_MS) {\n stopPoll();\n setConnecting(false);\n setError(\n \"Didn't hear back from Builder in 5 minutes. Allow popups and try again.\",\n );\n }\n }, POLL_INTERVAL_MS);\n }, [envManaged, fetchStatus, popupUrl, stopPoll]);\n\n // Popup-side fast path: the error page broadcasts a message so we stop\n // polling immediately rather than waiting for the next 2s tick.\n //\n // We listen on BroadcastChannel (same-origin, works with noopener popups)\n // AND on window.message (legacy path for environments without BC or for\n // popups that still have opener access). Both paths are safe to have open\n // simultaneously \\u2014 the first one to fire wins and the error is deduplicated\n // by the stopPoll() call which is idempotent.\n useEffect(() => {\n let channel: BroadcastChannel | null = null;\n const handleError = (message: string) => {\n stopPoll();\n setConnecting(false);\n setError(`Couldn't save Builder credentials: ${message}.`);\n };\n\n try {\n channel = new BroadcastChannel(`builder-connect:${window.location.host}`);\n channel.onmessage = (e: MessageEvent) => {\n const data = e.data as { type?: string; message?: string } | undefined;\n if (data?.type !== \"builder-connect-error\") return;\n if (typeof data.message !== \"string\" || !data.message) return;\n handleError(data.message);\n };\n } catch {\n // BroadcastChannel not available (rare) \\u2014 fall through to postMessage.\n }\n\n const handler = (e: MessageEvent) => {\n if (e.origin !== window.location.origin) return;\n const data = e.data as { type?: string; message?: string } | undefined;\n if (data?.type !== \"builder-connect-error\") return;\n if (typeof data.message !== \"string\" || !data.message) return;\n handleError(data.message);\n };\n window.addEventListener(\"message\", handler);\n\n return () => {\n channel?.close();\n window.removeEventListener(\"message\", handler);\n };\n }, [stopPoll]);\n\n return {\n configured,\n envManaged,\n builderEnabled,\n orgName,\n connecting,\n error,\n hasFetchedStatus,\n start,\n };\n}\n"]}
1
+ {"version":3,"file":"useBuilderStatus.js","sourceRoot":"","sources":["../../../src/client/settings/useBuilderStatus.ts"],"names":[],"mappings":"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","sourcesContent":["import { agentNativePath } from \"../api-path.js\";\nimport { useState, useEffect, useCallback, useRef } from \"react\";\nimport { getCallbackOrigin } from \"../frame.js\";\n\nexport interface BuilderStatus {\n configured: boolean;\n builderEnabled: boolean;\n /**\n * True when `BUILDER_PRIVATE_KEY` is set at the deploy level. Every user\n * of this deploy shares the operator's Builder identity and per-user\n * connect/disconnect is disabled. UIs must hide connect prompts and\n * disconnect buttons when this is true.\n */\n envManaged?: boolean;\n connectUrl: string;\n appHost: string;\n apiHost: string;\n publicKeyConfigured: boolean;\n privateKeyConfigured: boolean;\n userId?: string;\n orgName?: string;\n orgKind?: string;\n /**\n * Set when the OAuth callback ran but failed to persist credentials.\n * Surfaced as a one-shot row by the server so the connect-flow polling\n * can stop with a clear message instead of timing out at 5min.\n */\n connectError?: { message: string; at: number };\n}\n\n/**\n * Fetches Builder connection status from /_agent-native/builder/status.\n * Re-fetches on window focus to detect post-redirect state changes.\n */\nexport function useBuilderStatus() {\n const [status, setStatus] = useState<BuilderStatus | null>(null);\n const [loading, setLoading] = useState(true);\n\n const fetchStatus = useCallback(async () => {\n try {\n const res = await fetch(agentNativePath(\"/_agent-native/builder/status\"));\n if (!res.ok) {\n setStatus(null);\n return;\n }\n setStatus(await res.json());\n } catch {\n setStatus(null);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n fetchStatus();\n\n function onFocus() {\n fetchStatus();\n }\n function onVisibility() {\n if (document.visibilityState === \"visible\") fetchStatus();\n }\n window.addEventListener(\"focus\", onFocus);\n document.addEventListener(\"visibilitychange\", onVisibility);\n // Engine connect/disconnect actions (e.g. the Builder disconnect button)\n // dispatch this event so dependent cards refresh without a full reload.\n window.addEventListener(\"agent-engine:configured-changed\", fetchStatus);\n return () => {\n window.removeEventListener(\"focus\", onFocus);\n document.removeEventListener(\"visibilitychange\", onVisibility);\n window.removeEventListener(\n \"agent-engine:configured-changed\",\n fetchStatus,\n );\n };\n }, [fetchStatus]);\n\n return { status, loading, refetch: fetchStatus };\n}\n\n// ─── useBuilderConnectFlow ──────────────────────────────────────────────────\n//\n// Shared state machine for the \"open Builder CLI-auth popup + poll\n// /builder/status until credentials land\" interaction. Replaces three\n// near-duplicate inline implementations: `BuilderCliAuthMethod` in\n// OnboardingPanel, `ConnectBuilderCard`, and `BuilderConnectCta` in\n// AssistantChat. Each consumer supplies its own popup URL / completion\n// behavior; the hook owns the polling + timeout + focus refresh.\n//\n// `popupUrl` is what we pass to `window.open`. The default\n// `/_agent-native/builder/connect` is a server-side 302 to the real\n// cli-auth URL — using it keeps the click handler synchronous so popup\n// blockers don't downgrade the open to same-tab navigation. Pass an\n// explicit `popupUrl` (e.g. the already-computed cli-auth URL) if your\n// caller already has it in hand.\n\nexport interface BuilderConnectFlowOptions {\n /** URL to synchronously open on start(). Defaults to the 302 shortcut. */\n popupUrl?: string;\n /** Invoked after the status poll first sees `configured: true`. */\n onConnected?: (state: { orgName: string | null }) => void | Promise<void>;\n}\n\nexport interface BuilderConnectFlow {\n configured: boolean;\n /**\n * True when the deploy has BUILDER_PRIVATE_KEY set. UIs should treat\n * Builder as connected for everyone in this mode and hide all connect /\n * disconnect controls — `start()` will be a no-op.\n */\n envManaged: boolean;\n /**\n * True when ENABLE_BUILDER (or a BUILDER_BRANCH_PROJECT_ID) is set on the\n * deploy, gating Builder cloud branch creation. When false, the card\n * surfaces a \"coming soon\" waitlist CTA instead of a Send button.\n */\n builderEnabled: boolean;\n orgName: string | null;\n connecting: boolean;\n error: string | null;\n /**\n * True once the first `/builder/status` fetch has completed (successfully\n * or not). Consumers that accept an `initialConfigured` prop (e.g. agent\n * tool-call results rendered with server-side state) should treat\n * `configured`/`orgName` as authoritative only once this flips true —\n * otherwise the hook's starting `false` defaults would cause a flash\n * back to \"Connect Builder\" on first paint.\n */\n hasFetchedStatus: boolean;\n /** Open the popup and begin polling. Must be called from a user-gesture handler. */\n start: () => void;\n}\n\nconst POLL_INTERVAL_MS = 2000;\nconst POLL_TIMEOUT_MS = 5 * 60 * 1000;\n\nfunction notifyAgentEngineConfiguredChanged(source: string) {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agent-engine:configured-changed\", {\n detail: { source },\n }),\n );\n}\n\nexport function useBuilderConnectFlow(\n opts: BuilderConnectFlowOptions = {},\n): BuilderConnectFlow {\n const { popupUrl, onConnected } = opts;\n const [configured, setConfigured] = useState(false);\n const [envManaged, setEnvManaged] = useState(false);\n const [builderEnabled, setBuilderEnabled] = useState(false);\n const [orgName, setOrgName] = useState<string | null>(null);\n const [connecting, setConnecting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [hasFetchedStatus, setHasFetchedStatus] = useState(false);\n const [statusConnectUrl, setStatusConnectUrl] = useState<string | null>(null);\n const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const mountedRef = useRef(true);\n const notifiedConnectedRef = useRef(false);\n // Keep onConnected in a ref so start() doesn't need to re-create when the\n // caller passes an inline arrow function.\n const onConnectedRef = useRef(onConnected);\n onConnectedRef.current = onConnected;\n\n const stopPoll = useCallback(() => {\n if (pollRef.current) {\n clearInterval(pollRef.current);\n pollRef.current = null;\n }\n }, []);\n\n const fetchStatus = useCallback(async () => {\n const origin = getCallbackOrigin() || window.location.origin;\n try {\n const r = await fetch(\n new URL(agentNativePath(\"/_agent-native/builder/status\"), origin).href,\n );\n if (!r.ok) return null;\n return (await r.json()) as {\n configured: boolean;\n envManaged?: boolean;\n builderEnabled?: boolean;\n orgName?: string | null;\n connectUrl?: string;\n connectError?: { message: string; at: number };\n };\n } catch {\n return null;\n }\n }, []);\n\n // Initial fetch + focus/visibility refresh so if the user completed the\n // flow in another tab (or a downgraded same-tab nav) we notice it. Also\n // listen for `agent-engine:configured-changed` so a Disconnect click in\n // Settings propagates to any connect-CTA cards rendered elsewhere in\n // the app without waiting for the next focus event.\n useEffect(() => {\n mountedRef.current = true;\n let cancelled = false;\n const refresh = async () => {\n const s = await fetchStatus();\n if (cancelled || !mountedRef.current) return;\n // Flip `hasFetchedStatus` even when the fetch failed — the caller's\n // \"use initial props until the hook has an answer\" pattern wants to\n // stop waiting after we've tried, regardless of network outcome.\n setHasFetchedStatus(true);\n if (!s) return;\n setConfigured(!!s.configured);\n setEnvManaged(!!s.envManaged);\n setBuilderEnabled(!!s.builderEnabled);\n setStatusConnectUrl(s.connectUrl ?? null);\n const org = s.orgName ?? null;\n setOrgName(org);\n if (s.configured && !notifiedConnectedRef.current) {\n notifiedConnectedRef.current = true;\n notifyAgentEngineConfiguredChanged(\"builder-status\");\n try {\n await onConnectedRef.current?.({ orgName: org });\n } catch {\n // The caller's callback is a UI convenience; status is already set.\n }\n } else if (!s.configured) {\n notifiedConnectedRef.current = false;\n }\n };\n refresh();\n const onVisible = () => {\n if (document.visibilityState === \"visible\") refresh();\n };\n window.addEventListener(\"focus\", refresh);\n document.addEventListener(\"visibilitychange\", onVisible);\n window.addEventListener(\"agent-engine:configured-changed\", refresh);\n return () => {\n cancelled = true;\n mountedRef.current = false;\n window.removeEventListener(\"focus\", refresh);\n document.removeEventListener(\"visibilitychange\", onVisible);\n window.removeEventListener(\"agent-engine:configured-changed\", refresh);\n stopPoll();\n };\n }, [fetchStatus, stopPoll]);\n\n const start = useCallback(() => {\n // In env-managed mode, per-user OAuth is disabled — `/builder/connect`\n // returns 409. Skip the popup and just refresh state so the UI flips\n // to its \"connected via deployment\" rendering.\n if (envManaged) return;\n stopPoll();\n setConnecting(true);\n setError(null);\n\n // Open SYNCHRONOUSLY inside the caller's click handler — any await\n // before window.open lets the user-gesture token expire, which causes\n // popup blockers to block entirely or fall back to same-tab navigation.\n const origin = getCallbackOrigin() || window.location.origin;\n const url =\n statusConnectUrl ??\n popupUrl ??\n new URL(agentNativePath(\"/_agent-native/builder/connect\"), origin).href;\n try {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n } catch {\n // Fall through — polling still detects completion if the user\n // opens the URL themselves.\n }\n\n const started = Date.now();\n pollRef.current = setInterval(async () => {\n const s = await fetchStatus();\n if (!mountedRef.current) {\n stopPoll();\n return;\n }\n if (s?.configured) {\n stopPoll();\n setConfigured(true);\n setEnvManaged(!!s.envManaged);\n setBuilderEnabled(!!s.builderEnabled);\n setStatusConnectUrl(s.connectUrl ?? null);\n const org = s.orgName ?? null;\n setOrgName(org);\n setConnecting(false);\n notifiedConnectedRef.current = true;\n notifyAgentEngineConfiguredChanged(\"builder-connect\");\n try {\n await onConnectedRef.current?.({ orgName: org });\n } catch {\n // Consumer's callback failed; we've already flipped the UI state\n // to connected. Swallow so we don't re-arm the flow.\n }\n } else if (s?.connectError?.message) {\n // OAuth callback ran but writeBuilderCredentials threw — surface the\n // real error instead of letting the user wait 5 minutes for timeout.\n stopPoll();\n setConnecting(false);\n setError(\n `Couldn't save Builder credentials: ${s.connectError.message}. Try again or contact support.`,\n );\n } else if (Date.now() - started > POLL_TIMEOUT_MS) {\n stopPoll();\n setConnecting(false);\n setError(\n \"Didn't hear back from Builder in 5 minutes. Allow popups and try again.\",\n );\n }\n }, POLL_INTERVAL_MS);\n }, [envManaged, fetchStatus, popupUrl, statusConnectUrl, stopPoll]);\n\n // Popup-side fast path: the error page broadcasts a message so we stop\n // polling immediately rather than waiting for the next 2s tick.\n //\n // We listen on BroadcastChannel (same-origin, works with noopener popups)\n // AND on window.message (legacy path for environments without BC or for\n // popups that still have opener access). Both paths are safe to have open\n // simultaneously \\u2014 the first one to fire wins and the error is deduplicated\n // by the stopPoll() call which is idempotent.\n useEffect(() => {\n let channel: BroadcastChannel | null = null;\n const handleError = (message: string) => {\n stopPoll();\n setConnecting(false);\n setError(`Couldn't save Builder credentials: ${message}.`);\n };\n\n try {\n channel = new BroadcastChannel(`builder-connect:${window.location.host}`);\n channel.onmessage = (e: MessageEvent) => {\n const data = e.data as { type?: string; message?: string } | undefined;\n if (data?.type !== \"builder-connect-error\") return;\n if (typeof data.message !== \"string\" || !data.message) return;\n handleError(data.message);\n };\n } catch {\n // BroadcastChannel not available (rare) \\u2014 fall through to postMessage.\n }\n\n const handler = (e: MessageEvent) => {\n if (e.origin !== window.location.origin) return;\n const data = e.data as { type?: string; message?: string } | undefined;\n if (data?.type !== \"builder-connect-error\") return;\n if (typeof data.message !== \"string\" || !data.message) return;\n handleError(data.message);\n };\n window.addEventListener(\"message\", handler);\n\n return () => {\n channel?.close();\n window.removeEventListener(\"message\", handler);\n };\n }, [stopPoll]);\n\n return {\n configured,\n envManaged,\n builderEnabled,\n orgName,\n connecting,\n error,\n hasFetchedStatus,\n start,\n };\n}\n"]}
@@ -9,6 +9,8 @@ export interface ShareButtonProps {
9
9
  * button next to an iframe use this to disable the iframe's pointer events
10
10
  * while the popover is open, so popover hover/clicks aren't swallowed. */
11
11
  onOpenChange?: (open: boolean) => void;
12
+ /** Optional public/share URL shown as a copyable link in the popover. */
13
+ shareUrl?: string;
12
14
  }
13
15
  /**
14
16
  * Framework share control. Renders a shadcn-outline-styled trigger that
@@ -1 +1 @@
1
- {"version":3,"file":"ShareButton.d.ts","sourceRoot":"","sources":["../../../src/client/sharing/ShareButton.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;oDACgD;IAChD,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B;;+EAE2E;IAC3E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAqED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CAwDlD"}
1
+ {"version":3,"file":"ShareButton.d.ts","sourceRoot":"","sources":["../../../src/client/sharing/ShareButton.tsx"],"names":[],"mappings":"AA4BA,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;oDACgD;IAChD,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B;;+EAE2E;IAC3E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAqED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CAqHlD"}
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useState } from "react";
3
- import { IconLock, IconBuilding, IconWorld, IconTrash, IconCheck, IconChevronDown, } from "@tabler/icons-react";
4
- import * as Popover from "@radix-ui/react-popover";
2
+ import { useEffect, useMemo, useRef, useState, } from "react";
3
+ import { useQueryClient } from "@tanstack/react-query";
4
+ import { IconLock, IconBuilding, IconWorld, IconTrash, IconCheck, IconChevronDown, IconCopy, } from "@tabler/icons-react";
5
5
  import * as Select from "@radix-ui/react-select";
6
+ import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
6
7
  import { useActionQuery, useActionMutation } from "../use-action.js";
7
8
  import { cn } from "../utils.js";
8
9
  import { agentNativePath } from "../api-path.js";
@@ -25,7 +26,7 @@ const VIS_META = {
25
26
  },
26
27
  public: {
27
28
  label: "Public",
28
- description: "Anyone signed in with the link can view",
29
+ description: "Anyone with the link can view",
29
30
  Icon: IconWorld,
30
31
  },
31
32
  };
@@ -46,26 +47,71 @@ const ROLE_OPTIONS = [
46
47
  */
47
48
  export function ShareButton(props) {
48
49
  const [open, setOpen] = useState(false);
50
+ const [pendingVisibility, setPendingVisibility] = useState(null);
51
+ const visibilityRequestId = useRef(0);
52
+ const queryClient = useQueryClient();
53
+ const shareQueryParams = useMemo(() => ({
54
+ resourceType: props.resourceType,
55
+ resourceId: props.resourceId,
56
+ }), [props.resourceType, props.resourceId]);
57
+ const shareQueryKey = useMemo(() => ["action", "list-resource-shares", shareQueryParams], [shareQueryParams]);
58
+ const setVisibility = useActionMutation("set-resource-visibility");
59
+ const sharesQuery = useActionQuery("list-resource-shares", shareQueryParams);
49
60
  const handleOpenChange = (v) => {
50
61
  setOpen(v);
51
62
  props.onOpenChange?.(v);
63
+ if (v && pendingVisibility === null)
64
+ sharesQuery.refetch();
65
+ };
66
+ const updateCachedVisibility = (visibility) => {
67
+ queryClient.setQueryData(shareQueryKey, (prev) => prev ? { ...prev, visibility } : prev);
68
+ };
69
+ const handleVisibilityChange = (next) => {
70
+ const requestId = ++visibilityRequestId.current;
71
+ const previous = queryClient.getQueryData(shareQueryKey);
72
+ setPendingVisibility(next);
73
+ updateCachedVisibility(next);
74
+ setVisibility.mutate({
75
+ resourceType: props.resourceType,
76
+ resourceId: props.resourceId,
77
+ visibility: next,
78
+ }, {
79
+ onSuccess: (result) => {
80
+ if (requestId !== visibilityRequestId.current)
81
+ return;
82
+ updateCachedVisibility(result?.visibility ?? next);
83
+ sharesQuery.refetch().finally(() => {
84
+ if (requestId === visibilityRequestId.current) {
85
+ setPendingVisibility(null);
86
+ }
87
+ });
88
+ },
89
+ onError: () => {
90
+ if (requestId !== visibilityRequestId.current)
91
+ return;
92
+ setPendingVisibility(null);
93
+ if (previous) {
94
+ queryClient.setQueryData(shareQueryKey, previous);
95
+ }
96
+ else {
97
+ queryClient.invalidateQueries({ queryKey: shareQueryKey });
98
+ }
99
+ },
100
+ });
52
101
  };
53
- const sharesQuery = useActionQuery("list-resource-shares", {
54
- resourceType: props.resourceType,
55
- resourceId: props.resourceId,
56
- });
57
102
  // The trigger always says "Share" — the icon reflects the resource's
58
103
  // current visibility (lock / building / globe), matching Google Docs.
59
104
  // While the query is loading and we don't know the visibility yet,
60
105
  // render a skeleton placeholder in the icon slot instead of guessing.
61
106
  const loaded = sharesQuery.data !== undefined;
62
107
  const serverVisibility = sharesQuery.data?.visibility ?? "private";
63
- const TriggerIcon = serverVisibility === "public"
108
+ const currentVisibility = pendingVisibility ?? serverVisibility;
109
+ const TriggerIcon = currentVisibility === "public"
64
110
  ? IconWorld
65
- : serverVisibility === "org"
111
+ : currentVisibility === "org"
66
112
  ? IconBuilding
67
113
  : IconLock;
68
- return (_jsxs(Popover.Root, { open: open, onOpenChange: handleOpenChange, children: [_jsx(Popover.Trigger, { asChild: true, children: _jsxs("button", { type: "button", className: BUTTON_OUTLINE_SM, children: [loaded ? (_jsx(TriggerIcon, { size: 16, strokeWidth: 1.75 })) : (_jsx("span", { "aria-hidden": true, className: "inline-block h-4 w-4 rounded-sm bg-muted animate-pulse" })), _jsx("span", { children: "Share" })] }) }), _jsx(Popover.Portal, { children: _jsx(Popover.Content, { align: "end", sideOffset: 6, className: "z-[2000] w-[min(460px,92vw)] rounded-lg border border-border bg-popover p-4 text-popover-foreground shadow-lg outline-none", onOpenAutoFocus: (e) => e.preventDefault(), children: _jsx(SharePanel, { ...props, sharesQuery: sharesQuery, onClose: () => handleOpenChange(false) }) }) })] }));
114
+ return (_jsxs(Popover, { open: open, onOpenChange: handleOpenChange, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: BUTTON_OUTLINE_SM, children: [loaded ? (_jsx(TriggerIcon, { size: 16, strokeWidth: 1.75 })) : (_jsx("span", { "aria-hidden": true, className: "inline-block h-4 w-4 rounded-sm bg-muted animate-pulse" })), _jsx("span", { children: "Share" })] }) }), _jsx(PopoverContent, { align: "end", sideOffset: 6, className: "z-[2000] w-[min(460px,92vw)] rounded-lg p-4 shadow-lg", onOpenAutoFocus: (e) => e.preventDefault(), children: _jsx(SharePanel, { ...props, sharesQuery: sharesQuery, visibilityOverride: pendingVisibility, onVisibilityChange: handleVisibilityChange, onClose: () => handleOpenChange(false) }) })] }));
69
115
  }
70
116
  function useOrgMembers() {
71
117
  const [members, setMembers] = useState([]);
@@ -92,8 +138,7 @@ function useOrgMembers() {
92
138
  return members;
93
139
  }
94
140
  function SharePanel(props) {
95
- const { resourceType, resourceId, resourceTitle, sharesQuery, onClose } = props;
96
- const setVisibility = useActionMutation("set-resource-visibility");
141
+ const { resourceType, resourceId, resourceTitle, sharesQuery, visibilityOverride, onVisibilityChange, onClose, } = props;
97
142
  const share = useActionMutation("share-resource");
98
143
  const unshare = useActionMutation("unshare-resource");
99
144
  const [email, setEmail] = useState("");
@@ -101,7 +146,6 @@ function SharePanel(props) {
101
146
  const orgMembers = useOrgMembers();
102
147
  const datalistId = `share-autocomplete-${resourceType}-${resourceId}`;
103
148
  // Optimistic overlays so clicks feel instant.
104
- const [visibilityOverride, setVisibilityOverride] = useState(null);
105
149
  const [pendingAdds, setPendingAdds] = useState([]);
106
150
  const [pendingRemoves, setPendingRemoves] = useState(new Set());
107
151
  const [roleOverrides, setRoleOverrides] = useState({});
@@ -123,8 +167,7 @@ function SharePanel(props) {
123
167
  }, []);
124
168
  const data = sharesQuery.data;
125
169
  const isLoading = data === undefined;
126
- const serverVisibility = data?.visibility ?? "private";
127
- const visibility = visibilityOverride ?? serverVisibility;
170
+ const visibility = visibilityOverride ?? data?.visibility ?? "private";
128
171
  const canManage = data?.role === "owner" || data?.role === "admin";
129
172
  const meta = VIS_META[visibility];
130
173
  const serverShares = data?.shares ?? [];
@@ -137,13 +180,7 @@ function SharePanel(props) {
137
180
  const handleVisibility = (next) => {
138
181
  if (next === visibility)
139
182
  return;
140
- setVisibilityOverride(next);
141
- setVisibility.mutate({ resourceType, resourceId, visibility: next }, {
142
- onSuccess: () => {
143
- sharesQuery.refetch().then(() => setVisibilityOverride(null));
144
- },
145
- onError: () => setVisibilityOverride(null),
146
- });
183
+ onVisibilityChange(next);
147
184
  };
148
185
  const handleAdd = () => {
149
186
  const trimmed = email.trim();
@@ -271,7 +308,30 @@ function SharePanel(props) {
271
308
  ? s.principalId
272
309
  : displayName(s.principalId, orgMembers), org: s.principalType === "org" }), _jsx("span", { className: "flex-1 min-w-0 truncate", children: s.principalType === "org"
273
310
  ? s.principalId
274
- : displayName(s.principalId, orgMembers) }), canManage ? (_jsx(RoleSelect, { value: s.role, onChange: (r) => handleChangeRole(s, r), disabled: inFlight.has(keyOf(s)), plain: true })) : (_jsx("span", { className: "text-xs text-muted-foreground", children: cap(s.role) })), canManage ? (_jsx("button", { type: "button", "aria-label": "Remove", onClick: () => handleRemove(s), disabled: inFlight.has(keyOf(s)), className: BUTTON_GHOST_ICON, children: _jsx(IconTrash, { size: 14 }) })) : null] }, keyOf(s)))), !shares.length && !data?.ownerEmail ? (_jsx("li", { className: "px-1 py-1.5 text-sm text-muted-foreground", children: "No one has access yet." })) : null] }), _jsx("div", { className: "mb-2 text-sm font-semibold", children: "General access" }), _jsxs("div", { className: "mb-4 flex items-center gap-3", children: [_jsx("span", { "aria-hidden": true, className: "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(meta.Icon, { size: 16, strokeWidth: 1.75 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(VisibilitySelect, { value: visibility, onChange: handleVisibility, disabled: !canManage }), _jsx("div", { className: "mt-0.5 text-xs text-muted-foreground", children: meta.description })] })] }), _jsx("div", { className: "mt-2 flex justify-end", children: _jsx("button", { type: "button", onClick: onClose, className: BUTTON_PRIMARY_SM, children: "Done" }) })] }));
311
+ : displayName(s.principalId, orgMembers) }), canManage ? (_jsx(RoleSelect, { value: s.role, onChange: (r) => handleChangeRole(s, r), disabled: inFlight.has(keyOf(s)), plain: true })) : (_jsx("span", { className: "text-xs text-muted-foreground", children: cap(s.role) })), canManage ? (_jsx("button", { type: "button", "aria-label": "Remove", onClick: () => handleRemove(s), disabled: inFlight.has(keyOf(s)), className: BUTTON_GHOST_ICON, children: _jsx(IconTrash, { size: 14 }) })) : null] }, keyOf(s)))), !shares.length && !data?.ownerEmail ? (_jsx("li", { className: "px-1 py-1.5 text-sm text-muted-foreground", children: "No one has access yet." })) : null] }), _jsx("div", { className: "mb-2 text-sm font-semibold", children: "General access" }), _jsxs("div", { className: "mb-4 flex items-center gap-3", children: [_jsx("span", { "aria-hidden": true, className: "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(meta.Icon, { size: 16, strokeWidth: 1.75 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(VisibilitySelect, { value: visibility, onChange: handleVisibility, disabled: !canManage }), _jsx("div", { className: "mt-0.5 text-xs text-muted-foreground", children: meta.description })] })] }), props.shareUrl ? _jsx(CopyLinkField, { value: props.shareUrl }) : null, _jsx("div", { className: "mt-2 flex justify-end", children: _jsx("button", { type: "button", onClick: onClose, className: BUTTON_PRIMARY_SM, children: "Done" }) })] }));
312
+ }
313
+ function CopyLinkField({ value }) {
314
+ const [copied, setCopied] = useState(false);
315
+ const resetRef = useRef(undefined);
316
+ useEffect(() => {
317
+ return () => {
318
+ if (resetRef.current)
319
+ clearTimeout(resetRef.current);
320
+ };
321
+ }, []);
322
+ const handleCopy = async () => {
323
+ try {
324
+ await navigator.clipboard.writeText(value);
325
+ setCopied(true);
326
+ if (resetRef.current)
327
+ clearTimeout(resetRef.current);
328
+ resetRef.current = setTimeout(() => setCopied(false), 1400);
329
+ }
330
+ catch {
331
+ setCopied(false);
332
+ }
333
+ };
334
+ return (_jsxs("div", { className: "mb-4", children: [_jsx("div", { className: "mb-2 text-sm font-semibold", children: "Share link" }), _jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("input", { readOnly: true, value: value, className: "h-9 min-w-0 flex-1 rounded-md border border-input bg-background px-3 text-sm text-muted-foreground outline-none", onFocus: (event) => event.currentTarget.select() }), _jsxs("button", { type: "button", onClick: handleCopy, className: "inline-flex h-9 shrink-0 items-center gap-2 rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground hover:bg-accent", children: [copied ? _jsx(IconCheck, { size: 15 }) : _jsx(IconCopy, { size: 15 }), copied ? "Copied" : "Copy"] })] })] }));
275
335
  }
276
336
  // ---------------------------------------------------------------------------
277
337
  // Radix Select wrappers styled like shadcn Select (no native <select> anywhere)
@@ -1 +1 @@
1
- {"version":3,"file":"ShareButton.js","sourceRoot":"","sources":["../../../src/client/sharing/ShareButton.tsx"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef, useEffect, useState, type ReactNode } from \"react\";\nimport {\n IconLock,\n IconBuilding,\n IconWorld,\n IconTrash,\n IconCheck,\n IconChevronDown,\n} from \"@tabler/icons-react\";\nimport * as Popover from \"@radix-ui/react-popover\";\nimport * as Select from \"@radix-ui/react-select\";\nimport { useActionQuery, useActionMutation } from \"../use-action.js\";\nimport { cn } from \"../utils.js\";\nimport { agentNativePath } from \"../api-path.js\";\n\nexport interface ShareButtonProps {\n resourceType: string;\n resourceId: string;\n resourceTitle?: string;\n /** @deprecated No longer affects rendering — trigger always says\n * \"Share\". Kept for callsite compatibility. */\n variant?: \"compact\" | \"label\";\n /** Notified when the share popover opens or closes. Hosts that render the\n * button next to an iframe use this to disable the iframe's pointer events\n * while the popover is open, so popover hover/clicks aren't swallowed. */\n onOpenChange?: (open: boolean) => void;\n}\n\ntype Visibility = \"private\" | \"org\" | \"public\";\ntype Role = \"viewer\" | \"editor\" | \"admin\";\n\ninterface Share {\n id: string;\n principalType: \"user\" | \"org\";\n principalId: string;\n role: Role;\n}\n\ninterface SharesResponse {\n ownerEmail: string | null;\n orgId: string | null;\n visibility: Visibility | null;\n role?: \"owner\" | Role;\n shares: Share[];\n}\n\n// Mirror shadcn's <Button size=\"sm\" variant=\"outline\"> class string so the\n// trigger sits flush next to other sm outline buttons in the template.\nconst BUTTON_BASE =\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\";\nconst BUTTON_OUTLINE_SM = cn(\n BUTTON_BASE,\n \"h-9 px-3 border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n);\nconst BUTTON_PRIMARY_SM = cn(\n BUTTON_BASE,\n \"h-9 px-4 bg-primary text-primary-foreground hover:bg-primary/90\",\n);\nconst BUTTON_GHOST_ICON = cn(\n BUTTON_BASE,\n \"h-7 w-7 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n);\n\nconst VIS_META: Record<\n Visibility,\n { label: string; description: string; Icon: typeof IconLock }\n> = {\n private: {\n label: \"Private\",\n description: \"Only people with access can view\",\n Icon: IconLock,\n },\n org: {\n label: \"Organization\",\n description: \"Anyone in your organization can view\",\n Icon: IconBuilding,\n },\n public: {\n label: \"Public\",\n description: \"Anyone signed in with the link can view\",\n Icon: IconWorld,\n },\n};\n\nconst ROLE_OPTIONS: Array<{ value: Role; label: string; description: string }> =\n [\n { value: \"viewer\", label: \"Viewer\", description: \"Can view\" },\n { value: \"editor\", label: \"Editor\", description: \"Can edit\" },\n {\n value: \"admin\",\n label: \"Admin\",\n description: \"Can edit and manage access\",\n },\n ];\n\n/**\n * Framework share control. Renders a shadcn-outline-styled trigger that\n * opens a Google-Docs-style popover anchored beneath it. Uses Tailwind\n * + CSS variables so the same component renders natively in light and\n * dark mode in any shadcn template.\n */\nexport function ShareButton(props: ShareButtonProps) {\n const [open, setOpen] = useState(false);\n const handleOpenChange = (v: boolean) => {\n setOpen(v);\n props.onOpenChange?.(v);\n };\n const sharesQuery = useActionQuery<SharesResponse>(\"list-resource-shares\", {\n resourceType: props.resourceType,\n resourceId: props.resourceId,\n });\n\n // The trigger always says \"Share\" — the icon reflects the resource's\n // current visibility (lock / building / globe), matching Google Docs.\n // While the query is loading and we don't know the visibility yet,\n // render a skeleton placeholder in the icon slot instead of guessing.\n const loaded = sharesQuery.data !== undefined;\n const serverVisibility =\n (sharesQuery.data?.visibility as Visibility | null) ?? \"private\";\n const TriggerIcon =\n serverVisibility === \"public\"\n ? IconWorld\n : serverVisibility === \"org\"\n ? IconBuilding\n : IconLock;\n\n return (\n <Popover.Root open={open} onOpenChange={handleOpenChange}>\n <Popover.Trigger asChild>\n <button type=\"button\" className={BUTTON_OUTLINE_SM}>\n {loaded ? (\n <TriggerIcon size={16} strokeWidth={1.75} />\n ) : (\n <span\n aria-hidden\n className=\"inline-block h-4 w-4 rounded-sm bg-muted animate-pulse\"\n />\n )}\n <span>Share</span>\n </button>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n align=\"end\"\n sideOffset={6}\n className=\"z-[2000] w-[min(460px,92vw)] rounded-lg border border-border bg-popover p-4 text-popover-foreground shadow-lg outline-none\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <SharePanel\n {...props}\n sharesQuery={sharesQuery}\n onClose={() => handleOpenChange(false)}\n />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\ninterface OrgMember {\n email: string;\n name?: string | null;\n}\n\nfunction useOrgMembers(): OrgMember[] {\n const [members, setMembers] = useState<OrgMember[]>([]);\n useEffect(() => {\n let cancelled = false;\n fetch(agentNativePath(\"/_agent-native/org/members\"))\n .then((r) => (r.ok ? r.json() : null))\n .then((data) => {\n if (cancelled || !data) return;\n const list = Array.isArray(data?.members) ? data.members : [];\n setMembers(\n list\n .map((m: any) => ({\n email: typeof m?.email === \"string\" ? m.email : \"\",\n name: typeof m?.name === \"string\" ? m.name : null,\n }))\n .filter((m: OrgMember) => m.email),\n );\n })\n .catch(() => {});\n return () => {\n cancelled = true;\n };\n }, []);\n return members;\n}\n\nfunction SharePanel(\n props: ShareButtonProps & {\n sharesQuery: ReturnType<typeof useActionQuery<SharesResponse>>;\n onClose: () => void;\n },\n) {\n const { resourceType, resourceId, resourceTitle, sharesQuery, onClose } =\n props;\n\n const setVisibility = useActionMutation(\"set-resource-visibility\");\n const share = useActionMutation(\"share-resource\");\n const unshare = useActionMutation(\"unshare-resource\");\n\n const [email, setEmail] = useState(\"\");\n const [role, setRole] = useState<Role>(\"viewer\");\n const orgMembers = useOrgMembers();\n const datalistId = `share-autocomplete-${resourceType}-${resourceId}`;\n\n // Optimistic overlays so clicks feel instant.\n const [visibilityOverride, setVisibilityOverride] =\n useState<Visibility | null>(null);\n const [pendingAdds, setPendingAdds] = useState<Share[]>([]);\n const [pendingRemoves, setPendingRemoves] = useState<Set<string>>(new Set());\n const [roleOverrides, setRoleOverrides] = useState<Record<string, Role>>({});\n // Principals with an in-flight share/unshare mutation. We disable the\n // role dropdown and the trash button for any share in this set so a\n // user can't race a role-change against a remove (which would otherwise\n // let the upsert silently re-grant access after the delete landed), and\n // can't rapid-fire two creates for the same pending add.\n const [inFlight, setInFlight] = useState<Set<string>>(new Set());\n const addInFlight = (k: string) =>\n setInFlight((prev) => new Set(prev).add(k));\n const clearInFlight = (k: string) =>\n setInFlight((prev) => {\n const next = new Set(prev);\n next.delete(k);\n return next;\n });\n\n useEffect(() => {\n sharesQuery.refetch();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const data = sharesQuery.data;\n const isLoading = data === undefined;\n const serverVisibility = (data?.visibility as Visibility | null) ?? \"private\";\n const visibility: Visibility = visibilityOverride ?? serverVisibility;\n const canManage = data?.role === \"owner\" || data?.role === \"admin\";\n const meta = VIS_META[visibility];\n\n const serverShares = data?.shares ?? [];\n const shares: Share[] = [\n ...serverShares\n .filter((s) => !pendingRemoves.has(keyOf(s)))\n .map((s) => ({ ...s, role: roleOverrides[keyOf(s)] ?? s.role })),\n ...pendingAdds,\n ];\n\n const handleVisibility = (next: Visibility) => {\n if (next === visibility) return;\n setVisibilityOverride(next);\n setVisibility.mutate(\n { resourceType, resourceId, visibility: next } as any,\n {\n onSuccess: () => {\n sharesQuery.refetch().then(() => setVisibilityOverride(null));\n },\n onError: () => setVisibilityOverride(null),\n },\n );\n };\n\n const handleAdd = () => {\n const trimmed = email.trim();\n if (!trimmed) return;\n const optimistic: Share = {\n id: `pending-${trimmed}`,\n principalType: \"user\",\n principalId: trimmed,\n role,\n };\n const k = keyOf(optimistic);\n // Ignore duplicate submits while an add for the same principal is in flight.\n if (inFlight.has(k)) return;\n setPendingAdds((p) => [...p, optimistic]);\n setEmail(\"\");\n addInFlight(k);\n share.mutate(\n {\n resourceType,\n resourceId,\n principalType: \"user\",\n principalId: trimmed,\n role,\n } as any,\n {\n onSuccess: () => {\n sharesQuery.refetch().then(() => {\n setPendingAdds((p) => p.filter((s) => s.id !== optimistic.id));\n clearInFlight(k);\n });\n },\n onError: () => {\n setPendingAdds((p) => p.filter((s) => s.id !== optimistic.id));\n clearInFlight(k);\n },\n },\n );\n };\n\n const handleChangeRole = (s: Share, next: Role) => {\n if (s.role === next) return;\n const k = keyOf(s);\n // Don't stack a role change on top of an in-flight add/remove/role\n // change for the same principal — it can race with unshare and end up\n // re-granting access after a delete. UI already disables the control,\n // but belt-and-suspenders here too.\n if (inFlight.has(k)) return;\n setRoleOverrides((prev) => ({ ...prev, [k]: next }));\n addInFlight(k);\n // share-resource is upsert: calling with same principal + new role\n // updates the existing share row. See sharing/actions/share-resource.ts.\n share.mutate(\n {\n resourceType,\n resourceId,\n principalType: s.principalType,\n principalId: s.principalId,\n role: next,\n } as any,\n {\n onSuccess: () => {\n sharesQuery.refetch().then(() => {\n setRoleOverrides((prev) => {\n const { [k]: _, ...rest } = prev;\n return rest;\n });\n clearInFlight(k);\n });\n },\n onError: () => {\n setRoleOverrides((prev) => {\n const { [k]: _, ...rest } = prev;\n return rest;\n });\n clearInFlight(k);\n },\n },\n );\n };\n\n const handleRemove = (s: Share) => {\n const k = keyOf(s);\n // If any other mutation is in flight for this principal, don't start a\n // remove — it can interleave with an upsert and leave the row in place.\n // The UI already disables the trash button when inFlight.has(k).\n if (inFlight.has(k)) return;\n setPendingRemoves((prev) => new Set(prev).add(k));\n addInFlight(k);\n unshare.mutate(\n {\n resourceType,\n resourceId,\n principalType: s.principalType,\n principalId: s.principalId,\n } as any,\n {\n onSuccess: () => {\n sharesQuery.refetch().then(() => {\n setPendingRemoves((prev) => {\n const next = new Set(prev);\n next.delete(k);\n return next;\n });\n clearInFlight(k);\n });\n },\n onError: () => {\n setPendingRemoves((prev) => {\n const next = new Set(prev);\n next.delete(k);\n return next;\n });\n clearInFlight(k);\n },\n },\n );\n };\n\n const titleText = resourceTitle\n ? `Share \"${resourceTitle}\"`\n : `Share ${resourceType}`;\n\n if (isLoading) {\n return (\n <div>\n <div\n className=\"mb-3 truncate text-base font-semibold\"\n title={titleText}\n >\n {titleText}\n </div>\n <div className=\"mb-4 h-9 rounded-md bg-muted animate-pulse\" />\n <div className=\"mb-2 text-sm font-semibold\">People with access</div>\n <div className=\"mb-4 h-7 rounded-md bg-muted animate-pulse\" />\n <div className=\"mb-2 text-sm font-semibold\">General access</div>\n <div className=\"mb-4 h-9 rounded-md bg-muted animate-pulse\" />\n <div className=\"mt-2 flex justify-end\">\n <button type=\"button\" onClick={onClose} className={BUTTON_PRIMARY_SM}>\n Done\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div>\n <div className=\"mb-3 truncate text-base font-semibold\" title={titleText}>\n {titleText}\n </div>\n\n {canManage ? (\n <div className=\"mb-4 flex items-stretch gap-2\">\n <input\n type=\"email\"\n placeholder=\"Add people by email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleAdd();\n }}\n list={orgMembers.length > 0 ? datalistId : undefined}\n autoComplete=\"off\"\n className=\"flex-1 min-w-0 h-9 rounded-md border border-input bg-background px-3 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background\"\n />\n {orgMembers.length > 0 ? (\n <datalist id={datalistId}>\n {orgMembers\n .filter(\n (m) =>\n m.email !== sharesQuery.data?.ownerEmail &&\n !(sharesQuery.data?.shares ?? []).some(\n (s) =>\n s.principalType === \"user\" && s.principalId === m.email,\n ),\n )\n .map((m) => (\n <option\n key={m.email}\n value={m.email}\n label={m.name ?? undefined}\n />\n ))}\n </datalist>\n ) : null}\n <RoleSelect value={role} onChange={setRole} />\n </div>\n ) : null}\n\n <div className=\"mb-2 text-sm font-semibold\">People with access</div>\n <ul className=\"mb-4 flex flex-col gap-1 list-none p-0 m-0\">\n {data?.ownerEmail ? (\n <li className=\"flex items-center gap-3 px-1 py-1.5 text-sm\">\n <Avatar label={displayName(data.ownerEmail, orgMembers)} />\n <span className=\"flex-1 min-w-0 truncate\">\n {displayName(data.ownerEmail, orgMembers)}\n </span>\n <span className=\"text-xs text-muted-foreground\">Owner</span>\n </li>\n ) : null}\n {shares.map((s) => (\n <li\n key={keyOf(s)}\n className={cn(\n \"flex items-center gap-3 px-1 py-1.5 text-sm\",\n inFlight.has(keyOf(s)) && \"opacity-60\",\n )}\n >\n <Avatar\n label={\n s.principalType === \"org\"\n ? s.principalId\n : displayName(s.principalId, orgMembers)\n }\n org={s.principalType === \"org\"}\n />\n <span className=\"flex-1 min-w-0 truncate\">\n {s.principalType === \"org\"\n ? s.principalId\n : displayName(s.principalId, orgMembers)}\n </span>\n {canManage ? (\n <RoleSelect\n value={s.role}\n onChange={(r) => handleChangeRole(s, r)}\n disabled={inFlight.has(keyOf(s))}\n plain\n />\n ) : (\n <span className=\"text-xs text-muted-foreground\">\n {cap(s.role)}\n </span>\n )}\n {canManage ? (\n <button\n type=\"button\"\n aria-label=\"Remove\"\n onClick={() => handleRemove(s)}\n disabled={inFlight.has(keyOf(s))}\n className={BUTTON_GHOST_ICON}\n >\n <IconTrash size={14} />\n </button>\n ) : null}\n </li>\n ))}\n {!shares.length && !data?.ownerEmail ? (\n <li className=\"px-1 py-1.5 text-sm text-muted-foreground\">\n No one has access yet.\n </li>\n ) : null}\n </ul>\n\n <div className=\"mb-2 text-sm font-semibold\">General access</div>\n <div className=\"mb-4 flex items-center gap-3\">\n <span\n aria-hidden\n className=\"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground\"\n >\n <meta.Icon size={16} strokeWidth={1.75} />\n </span>\n <div className=\"min-w-0 flex-1\">\n <VisibilitySelect\n value={visibility}\n onChange={handleVisibility}\n disabled={!canManage}\n />\n <div className=\"mt-0.5 text-xs text-muted-foreground\">\n {meta.description}\n </div>\n </div>\n </div>\n\n <div className=\"mt-2 flex justify-end\">\n <button type=\"button\" onClick={onClose} className={BUTTON_PRIMARY_SM}>\n Done\n </button>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Radix Select wrappers styled like shadcn Select (no native <select> anywhere)\n// ---------------------------------------------------------------------------\n\nconst selectContentClass =\n \"z-[2100] min-w-[12rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\";\nconst selectItemClass =\n \"relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm py-2 pl-8 pr-3 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\";\n\ninterface ShadSelectItemProps {\n value: string;\n label: string;\n description?: string;\n}\n\nfunction SelectItems({ items }: { items: ShadSelectItemProps[] }) {\n return (\n <>\n {items.map((it) => (\n <Select.Item\n key={it.value}\n value={it.value}\n className={selectItemClass}\n >\n <span className=\"absolute left-2 top-2 flex h-4 w-4 items-center justify-center\">\n <Select.ItemIndicator>\n <IconCheck size={14} />\n </Select.ItemIndicator>\n </span>\n <span className=\"flex flex-col\">\n <Select.ItemText>{it.label}</Select.ItemText>\n {it.description ? (\n <span className=\"text-xs text-muted-foreground\">\n {it.description}\n </span>\n ) : null}\n </span>\n </Select.Item>\n ))}\n </>\n );\n}\n\nfunction RoleSelect(props: {\n value: Role;\n onChange: (v: Role) => void;\n disabled?: boolean;\n /** When true, render as inline text + chevron (no border / bg) — matches\n * the per-person role picker in Google Docs. */\n plain?: boolean;\n}) {\n const current =\n ROLE_OPTIONS.find((o) => o.value === props.value) ?? ROLE_OPTIONS[0];\n return (\n <Select.Root\n value={props.value}\n onValueChange={(v) => props.onChange(v as Role)}\n disabled={props.disabled}\n >\n <Select.Trigger\n className={\n props.plain\n ? cn(\n BUTTON_BASE,\n \"h-7 px-2 bg-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n )\n : cn(\n BUTTON_BASE,\n \"h-9 px-3 border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n )\n }\n aria-label=\"Role\"\n >\n <Select.Value>{current.label}</Select.Value>\n <Select.Icon>\n <IconChevronDown size={14} />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n className={selectContentClass}\n position=\"popper\"\n sideOffset={4}\n >\n <Select.Viewport>\n <SelectItems items={ROLE_OPTIONS} />\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n}\n\nfunction VisibilitySelect(props: {\n value: Visibility;\n onChange: (v: Visibility) => void;\n disabled?: boolean;\n}) {\n const current = VIS_META[props.value];\n return (\n <Select.Root\n value={props.value}\n onValueChange={(v) => props.onChange(v as Visibility)}\n disabled={props.disabled}\n >\n <Select.Trigger\n className={cn(\n BUTTON_BASE,\n \"h-7 px-1 -ml-1 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground\",\n )}\n aria-label=\"General access\"\n >\n <Select.Value>{current.label}</Select.Value>\n <Select.Icon>\n <IconChevronDown size={14} />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n className={selectContentClass}\n position=\"popper\"\n sideOffset={4}\n >\n <Select.Viewport>\n <SelectItems\n items={(Object.keys(VIS_META) as Visibility[]).map((k) => ({\n value: k,\n label: VIS_META[k].label,\n description: VIS_META[k].description,\n }))}\n />\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n}\n\nfunction Avatar({ label, org }: { label: string; org?: boolean }) {\n return (\n <span\n aria-hidden\n className=\"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-muted text-[11px] font-semibold text-muted-foreground\"\n >\n {org ? <IconBuilding size={14} strokeWidth={1.75} /> : initials(label)}\n </span>\n );\n}\n\nfunction keyOf(s: Share): string {\n return `${s.principalType}:${s.principalId}`;\n}\nfunction cap(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\nfunction initials(s: string): string {\n const name = s.split(\"@\")[0] ?? s;\n return (name[0] ?? \"?\").toUpperCase();\n}\n\nfunction displayName(email: string, members: OrgMember[]): string {\n const match = members.find((m) => m.email === email);\n if (match?.name && match.name.trim()) return match.name;\n return email;\n}\n"]}
1
+ {"version":3,"file":"ShareButton.js","sourceRoot":"","sources":["../../../src/client/sharing/ShareButton.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n forwardRef,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n IconLock,\n IconBuilding,\n IconWorld,\n IconTrash,\n IconCheck,\n IconChevronDown,\n IconCopy,\n} from \"@tabler/icons-react\";\nimport * as Select from \"@radix-ui/react-select\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport { useActionQuery, useActionMutation } from \"../use-action.js\";\nimport { cn } from \"../utils.js\";\nimport { agentNativePath } from \"../api-path.js\";\n\nexport interface ShareButtonProps {\n resourceType: string;\n resourceId: string;\n resourceTitle?: string;\n /** @deprecated No longer affects rendering — trigger always says\n * \"Share\". Kept for callsite compatibility. */\n variant?: \"compact\" | \"label\";\n /** Notified when the share popover opens or closes. Hosts that render the\n * button next to an iframe use this to disable the iframe's pointer events\n * while the popover is open, so popover hover/clicks aren't swallowed. */\n onOpenChange?: (open: boolean) => void;\n /** Optional public/share URL shown as a copyable link in the popover. */\n shareUrl?: string;\n}\n\ntype Visibility = \"private\" | \"org\" | \"public\";\ntype Role = \"viewer\" | \"editor\" | \"admin\";\n\ninterface Share {\n id: string;\n principalType: \"user\" | \"org\";\n principalId: string;\n role: Role;\n}\n\ninterface SharesResponse {\n ownerEmail: string | null;\n orgId: string | null;\n visibility: Visibility | null;\n role?: \"owner\" | Role;\n shares: Share[];\n}\n\n// Mirror shadcn's <Button size=\"sm\" variant=\"outline\"> class string so the\n// trigger sits flush next to other sm outline buttons in the template.\nconst BUTTON_BASE =\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\";\nconst BUTTON_OUTLINE_SM = cn(\n BUTTON_BASE,\n \"h-9 px-3 border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n);\nconst BUTTON_PRIMARY_SM = cn(\n BUTTON_BASE,\n \"h-9 px-4 bg-primary text-primary-foreground hover:bg-primary/90\",\n);\nconst BUTTON_GHOST_ICON = cn(\n BUTTON_BASE,\n \"h-7 w-7 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n);\n\nconst VIS_META: Record<\n Visibility,\n { label: string; description: string; Icon: typeof IconLock }\n> = {\n private: {\n label: \"Private\",\n description: \"Only people with access can view\",\n Icon: IconLock,\n },\n org: {\n label: \"Organization\",\n description: \"Anyone in your organization can view\",\n Icon: IconBuilding,\n },\n public: {\n label: \"Public\",\n description: \"Anyone with the link can view\",\n Icon: IconWorld,\n },\n};\n\nconst ROLE_OPTIONS: Array<{ value: Role; label: string; description: string }> =\n [\n { value: \"viewer\", label: \"Viewer\", description: \"Can view\" },\n { value: \"editor\", label: \"Editor\", description: \"Can edit\" },\n {\n value: \"admin\",\n label: \"Admin\",\n description: \"Can edit and manage access\",\n },\n ];\n\n/**\n * Framework share control. Renders a shadcn-outline-styled trigger that\n * opens a Google-Docs-style popover anchored beneath it. Uses Tailwind\n * + CSS variables so the same component renders natively in light and\n * dark mode in any shadcn template.\n */\nexport function ShareButton(props: ShareButtonProps) {\n const [open, setOpen] = useState(false);\n const [pendingVisibility, setPendingVisibility] = useState<Visibility | null>(\n null,\n );\n const visibilityRequestId = useRef(0);\n const queryClient = useQueryClient();\n const shareQueryParams = useMemo(\n () => ({\n resourceType: props.resourceType,\n resourceId: props.resourceId,\n }),\n [props.resourceType, props.resourceId],\n );\n const shareQueryKey = useMemo(\n () => [\"action\", \"list-resource-shares\", shareQueryParams] as const,\n [shareQueryParams],\n );\n const setVisibility = useActionMutation(\"set-resource-visibility\");\n const sharesQuery = useActionQuery<SharesResponse>(\n \"list-resource-shares\",\n shareQueryParams,\n );\n const handleOpenChange = (v: boolean) => {\n setOpen(v);\n props.onOpenChange?.(v);\n if (v && pendingVisibility === null) sharesQuery.refetch();\n };\n\n const updateCachedVisibility = (visibility: Visibility) => {\n queryClient.setQueryData<SharesResponse>(shareQueryKey, (prev) =>\n prev ? { ...prev, visibility } : prev,\n );\n };\n\n const handleVisibilityChange = (next: Visibility) => {\n const requestId = ++visibilityRequestId.current;\n const previous = queryClient.getQueryData<SharesResponse>(shareQueryKey);\n setPendingVisibility(next);\n updateCachedVisibility(next);\n setVisibility.mutate(\n {\n resourceType: props.resourceType,\n resourceId: props.resourceId,\n visibility: next,\n } as any,\n {\n onSuccess: (result: any) => {\n if (requestId !== visibilityRequestId.current) return;\n updateCachedVisibility(\n (result?.visibility as Visibility | undefined) ?? next,\n );\n sharesQuery.refetch().finally(() => {\n if (requestId === visibilityRequestId.current) {\n setPendingVisibility(null);\n }\n });\n },\n onError: () => {\n if (requestId !== visibilityRequestId.current) return;\n setPendingVisibility(null);\n if (previous) {\n queryClient.setQueryData(shareQueryKey, previous);\n } else {\n queryClient.invalidateQueries({ queryKey: shareQueryKey });\n }\n },\n },\n );\n };\n\n // The trigger always says \"Share\" — the icon reflects the resource's\n // current visibility (lock / building / globe), matching Google Docs.\n // While the query is loading and we don't know the visibility yet,\n // render a skeleton placeholder in the icon slot instead of guessing.\n const loaded = sharesQuery.data !== undefined;\n const serverVisibility =\n (sharesQuery.data?.visibility as Visibility | null) ?? \"private\";\n const currentVisibility = pendingVisibility ?? serverVisibility;\n const TriggerIcon =\n currentVisibility === \"public\"\n ? IconWorld\n : currentVisibility === \"org\"\n ? IconBuilding\n : IconLock;\n\n return (\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n <button type=\"button\" className={BUTTON_OUTLINE_SM}>\n {loaded ? (\n <TriggerIcon size={16} strokeWidth={1.75} />\n ) : (\n <span\n aria-hidden\n className=\"inline-block h-4 w-4 rounded-sm bg-muted animate-pulse\"\n />\n )}\n <span>Share</span>\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n sideOffset={6}\n className=\"z-[2000] w-[min(460px,92vw)] rounded-lg p-4 shadow-lg\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <SharePanel\n {...props}\n sharesQuery={sharesQuery}\n visibilityOverride={pendingVisibility}\n onVisibilityChange={handleVisibilityChange}\n onClose={() => handleOpenChange(false)}\n />\n </PopoverContent>\n </Popover>\n );\n}\n\ninterface OrgMember {\n email: string;\n name?: string | null;\n}\n\nfunction useOrgMembers(): OrgMember[] {\n const [members, setMembers] = useState<OrgMember[]>([]);\n useEffect(() => {\n let cancelled = false;\n fetch(agentNativePath(\"/_agent-native/org/members\"))\n .then((r) => (r.ok ? r.json() : null))\n .then((data) => {\n if (cancelled || !data) return;\n const list = Array.isArray(data?.members) ? data.members : [];\n setMembers(\n list\n .map((m: any) => ({\n email: typeof m?.email === \"string\" ? m.email : \"\",\n name: typeof m?.name === \"string\" ? m.name : null,\n }))\n .filter((m: OrgMember) => m.email),\n );\n })\n .catch(() => {});\n return () => {\n cancelled = true;\n };\n }, []);\n return members;\n}\n\nfunction SharePanel(\n props: ShareButtonProps & {\n sharesQuery: ReturnType<typeof useActionQuery<SharesResponse>>;\n visibilityOverride: Visibility | null;\n onVisibilityChange: (visibility: Visibility) => void;\n onClose: () => void;\n },\n) {\n const {\n resourceType,\n resourceId,\n resourceTitle,\n sharesQuery,\n visibilityOverride,\n onVisibilityChange,\n onClose,\n } = props;\n\n const share = useActionMutation(\"share-resource\");\n const unshare = useActionMutation(\"unshare-resource\");\n\n const [email, setEmail] = useState(\"\");\n const [role, setRole] = useState<Role>(\"viewer\");\n const orgMembers = useOrgMembers();\n const datalistId = `share-autocomplete-${resourceType}-${resourceId}`;\n\n // Optimistic overlays so clicks feel instant.\n const [pendingAdds, setPendingAdds] = useState<Share[]>([]);\n const [pendingRemoves, setPendingRemoves] = useState<Set<string>>(new Set());\n const [roleOverrides, setRoleOverrides] = useState<Record<string, Role>>({});\n // Principals with an in-flight share/unshare mutation. We disable the\n // role dropdown and the trash button for any share in this set so a\n // user can't race a role-change against a remove (which would otherwise\n // let the upsert silently re-grant access after the delete landed), and\n // can't rapid-fire two creates for the same pending add.\n const [inFlight, setInFlight] = useState<Set<string>>(new Set());\n const addInFlight = (k: string) =>\n setInFlight((prev) => new Set(prev).add(k));\n const clearInFlight = (k: string) =>\n setInFlight((prev) => {\n const next = new Set(prev);\n next.delete(k);\n return next;\n });\n\n useEffect(() => {\n sharesQuery.refetch();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const data = sharesQuery.data;\n const isLoading = data === undefined;\n const visibility: Visibility =\n visibilityOverride ?? (data?.visibility as Visibility | null) ?? \"private\";\n const canManage = data?.role === \"owner\" || data?.role === \"admin\";\n const meta = VIS_META[visibility];\n\n const serverShares = data?.shares ?? [];\n const shares: Share[] = [\n ...serverShares\n .filter((s) => !pendingRemoves.has(keyOf(s)))\n .map((s) => ({ ...s, role: roleOverrides[keyOf(s)] ?? s.role })),\n ...pendingAdds,\n ];\n\n const handleVisibility = (next: Visibility) => {\n if (next === visibility) return;\n onVisibilityChange(next);\n };\n\n const handleAdd = () => {\n const trimmed = email.trim();\n if (!trimmed) return;\n const optimistic: Share = {\n id: `pending-${trimmed}`,\n principalType: \"user\",\n principalId: trimmed,\n role,\n };\n const k = keyOf(optimistic);\n // Ignore duplicate submits while an add for the same principal is in flight.\n if (inFlight.has(k)) return;\n setPendingAdds((p) => [...p, optimistic]);\n setEmail(\"\");\n addInFlight(k);\n share.mutate(\n {\n resourceType,\n resourceId,\n principalType: \"user\",\n principalId: trimmed,\n role,\n } as any,\n {\n onSuccess: () => {\n sharesQuery.refetch().then(() => {\n setPendingAdds((p) => p.filter((s) => s.id !== optimistic.id));\n clearInFlight(k);\n });\n },\n onError: () => {\n setPendingAdds((p) => p.filter((s) => s.id !== optimistic.id));\n clearInFlight(k);\n },\n },\n );\n };\n\n const handleChangeRole = (s: Share, next: Role) => {\n if (s.role === next) return;\n const k = keyOf(s);\n // Don't stack a role change on top of an in-flight add/remove/role\n // change for the same principal — it can race with unshare and end up\n // re-granting access after a delete. UI already disables the control,\n // but belt-and-suspenders here too.\n if (inFlight.has(k)) return;\n setRoleOverrides((prev) => ({ ...prev, [k]: next }));\n addInFlight(k);\n // share-resource is upsert: calling with same principal + new role\n // updates the existing share row. See sharing/actions/share-resource.ts.\n share.mutate(\n {\n resourceType,\n resourceId,\n principalType: s.principalType,\n principalId: s.principalId,\n role: next,\n } as any,\n {\n onSuccess: () => {\n sharesQuery.refetch().then(() => {\n setRoleOverrides((prev) => {\n const { [k]: _, ...rest } = prev;\n return rest;\n });\n clearInFlight(k);\n });\n },\n onError: () => {\n setRoleOverrides((prev) => {\n const { [k]: _, ...rest } = prev;\n return rest;\n });\n clearInFlight(k);\n },\n },\n );\n };\n\n const handleRemove = (s: Share) => {\n const k = keyOf(s);\n // If any other mutation is in flight for this principal, don't start a\n // remove — it can interleave with an upsert and leave the row in place.\n // The UI already disables the trash button when inFlight.has(k).\n if (inFlight.has(k)) return;\n setPendingRemoves((prev) => new Set(prev).add(k));\n addInFlight(k);\n unshare.mutate(\n {\n resourceType,\n resourceId,\n principalType: s.principalType,\n principalId: s.principalId,\n } as any,\n {\n onSuccess: () => {\n sharesQuery.refetch().then(() => {\n setPendingRemoves((prev) => {\n const next = new Set(prev);\n next.delete(k);\n return next;\n });\n clearInFlight(k);\n });\n },\n onError: () => {\n setPendingRemoves((prev) => {\n const next = new Set(prev);\n next.delete(k);\n return next;\n });\n clearInFlight(k);\n },\n },\n );\n };\n\n const titleText = resourceTitle\n ? `Share \"${resourceTitle}\"`\n : `Share ${resourceType}`;\n\n if (isLoading) {\n return (\n <div>\n <div\n className=\"mb-3 truncate text-base font-semibold\"\n title={titleText}\n >\n {titleText}\n </div>\n <div className=\"mb-4 h-9 rounded-md bg-muted animate-pulse\" />\n <div className=\"mb-2 text-sm font-semibold\">People with access</div>\n <div className=\"mb-4 h-7 rounded-md bg-muted animate-pulse\" />\n <div className=\"mb-2 text-sm font-semibold\">General access</div>\n <div className=\"mb-4 h-9 rounded-md bg-muted animate-pulse\" />\n <div className=\"mt-2 flex justify-end\">\n <button type=\"button\" onClick={onClose} className={BUTTON_PRIMARY_SM}>\n Done\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div>\n <div className=\"mb-3 truncate text-base font-semibold\" title={titleText}>\n {titleText}\n </div>\n\n {canManage ? (\n <div className=\"mb-4 flex items-stretch gap-2\">\n <input\n type=\"email\"\n placeholder=\"Add people by email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleAdd();\n }}\n list={orgMembers.length > 0 ? datalistId : undefined}\n autoComplete=\"off\"\n className=\"flex-1 min-w-0 h-9 rounded-md border border-input bg-background px-3 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background\"\n />\n {orgMembers.length > 0 ? (\n <datalist id={datalistId}>\n {orgMembers\n .filter(\n (m) =>\n m.email !== sharesQuery.data?.ownerEmail &&\n !(sharesQuery.data?.shares ?? []).some(\n (s) =>\n s.principalType === \"user\" && s.principalId === m.email,\n ),\n )\n .map((m) => (\n <option\n key={m.email}\n value={m.email}\n label={m.name ?? undefined}\n />\n ))}\n </datalist>\n ) : null}\n <RoleSelect value={role} onChange={setRole} />\n </div>\n ) : null}\n\n <div className=\"mb-2 text-sm font-semibold\">People with access</div>\n <ul className=\"mb-4 flex flex-col gap-1 list-none p-0 m-0\">\n {data?.ownerEmail ? (\n <li className=\"flex items-center gap-3 px-1 py-1.5 text-sm\">\n <Avatar label={displayName(data.ownerEmail, orgMembers)} />\n <span className=\"flex-1 min-w-0 truncate\">\n {displayName(data.ownerEmail, orgMembers)}\n </span>\n <span className=\"text-xs text-muted-foreground\">Owner</span>\n </li>\n ) : null}\n {shares.map((s) => (\n <li\n key={keyOf(s)}\n className={cn(\n \"flex items-center gap-3 px-1 py-1.5 text-sm\",\n inFlight.has(keyOf(s)) && \"opacity-60\",\n )}\n >\n <Avatar\n label={\n s.principalType === \"org\"\n ? s.principalId\n : displayName(s.principalId, orgMembers)\n }\n org={s.principalType === \"org\"}\n />\n <span className=\"flex-1 min-w-0 truncate\">\n {s.principalType === \"org\"\n ? s.principalId\n : displayName(s.principalId, orgMembers)}\n </span>\n {canManage ? (\n <RoleSelect\n value={s.role}\n onChange={(r) => handleChangeRole(s, r)}\n disabled={inFlight.has(keyOf(s))}\n plain\n />\n ) : (\n <span className=\"text-xs text-muted-foreground\">\n {cap(s.role)}\n </span>\n )}\n {canManage ? (\n <button\n type=\"button\"\n aria-label=\"Remove\"\n onClick={() => handleRemove(s)}\n disabled={inFlight.has(keyOf(s))}\n className={BUTTON_GHOST_ICON}\n >\n <IconTrash size={14} />\n </button>\n ) : null}\n </li>\n ))}\n {!shares.length && !data?.ownerEmail ? (\n <li className=\"px-1 py-1.5 text-sm text-muted-foreground\">\n No one has access yet.\n </li>\n ) : null}\n </ul>\n\n <div className=\"mb-2 text-sm font-semibold\">General access</div>\n <div className=\"mb-4 flex items-center gap-3\">\n <span\n aria-hidden\n className=\"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground\"\n >\n <meta.Icon size={16} strokeWidth={1.75} />\n </span>\n <div className=\"min-w-0 flex-1\">\n <VisibilitySelect\n value={visibility}\n onChange={handleVisibility}\n disabled={!canManage}\n />\n <div className=\"mt-0.5 text-xs text-muted-foreground\">\n {meta.description}\n </div>\n </div>\n </div>\n\n {props.shareUrl ? <CopyLinkField value={props.shareUrl} /> : null}\n\n <div className=\"mt-2 flex justify-end\">\n <button type=\"button\" onClick={onClose} className={BUTTON_PRIMARY_SM}>\n Done\n </button>\n </div>\n </div>\n );\n}\n\nfunction CopyLinkField({ value }: { value: string }) {\n const [copied, setCopied] = useState(false);\n const resetRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n useEffect(() => {\n return () => {\n if (resetRef.current) clearTimeout(resetRef.current);\n };\n }, []);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n if (resetRef.current) clearTimeout(resetRef.current);\n resetRef.current = setTimeout(() => setCopied(false), 1400);\n } catch {\n setCopied(false);\n }\n };\n\n return (\n <div className=\"mb-4\">\n <div className=\"mb-2 text-sm font-semibold\">Share link</div>\n <div className=\"flex min-w-0 items-center gap-2\">\n <input\n readOnly\n value={value}\n className=\"h-9 min-w-0 flex-1 rounded-md border border-input bg-background px-3 text-sm text-muted-foreground outline-none\"\n onFocus={(event) => event.currentTarget.select()}\n />\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"inline-flex h-9 shrink-0 items-center gap-2 rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground hover:bg-accent\"\n >\n {copied ? <IconCheck size={15} /> : <IconCopy size={15} />}\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Radix Select wrappers styled like shadcn Select (no native <select> anywhere)\n// ---------------------------------------------------------------------------\n\nconst selectContentClass =\n \"z-[2100] min-w-[12rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\";\nconst selectItemClass =\n \"relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm py-2 pl-8 pr-3 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\";\n\ninterface ShadSelectItemProps {\n value: string;\n label: string;\n description?: string;\n}\n\nfunction SelectItems({ items }: { items: ShadSelectItemProps[] }) {\n return (\n <>\n {items.map((it) => (\n <Select.Item\n key={it.value}\n value={it.value}\n className={selectItemClass}\n >\n <span className=\"absolute left-2 top-2 flex h-4 w-4 items-center justify-center\">\n <Select.ItemIndicator>\n <IconCheck size={14} />\n </Select.ItemIndicator>\n </span>\n <span className=\"flex flex-col\">\n <Select.ItemText>{it.label}</Select.ItemText>\n {it.description ? (\n <span className=\"text-xs text-muted-foreground\">\n {it.description}\n </span>\n ) : null}\n </span>\n </Select.Item>\n ))}\n </>\n );\n}\n\nfunction RoleSelect(props: {\n value: Role;\n onChange: (v: Role) => void;\n disabled?: boolean;\n /** When true, render as inline text + chevron (no border / bg) — matches\n * the per-person role picker in Google Docs. */\n plain?: boolean;\n}) {\n const current =\n ROLE_OPTIONS.find((o) => o.value === props.value) ?? ROLE_OPTIONS[0];\n return (\n <Select.Root\n value={props.value}\n onValueChange={(v) => props.onChange(v as Role)}\n disabled={props.disabled}\n >\n <Select.Trigger\n className={\n props.plain\n ? cn(\n BUTTON_BASE,\n \"h-7 px-2 bg-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n )\n : cn(\n BUTTON_BASE,\n \"h-9 px-3 border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n )\n }\n aria-label=\"Role\"\n >\n <Select.Value>{current.label}</Select.Value>\n <Select.Icon>\n <IconChevronDown size={14} />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n className={selectContentClass}\n position=\"popper\"\n sideOffset={4}\n >\n <Select.Viewport>\n <SelectItems items={ROLE_OPTIONS} />\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n}\n\nfunction VisibilitySelect(props: {\n value: Visibility;\n onChange: (v: Visibility) => void;\n disabled?: boolean;\n}) {\n const current = VIS_META[props.value];\n return (\n <Select.Root\n value={props.value}\n onValueChange={(v) => props.onChange(v as Visibility)}\n disabled={props.disabled}\n >\n <Select.Trigger\n className={cn(\n BUTTON_BASE,\n \"h-7 px-1 -ml-1 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground\",\n )}\n aria-label=\"General access\"\n >\n <Select.Value>{current.label}</Select.Value>\n <Select.Icon>\n <IconChevronDown size={14} />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n className={selectContentClass}\n position=\"popper\"\n sideOffset={4}\n >\n <Select.Viewport>\n <SelectItems\n items={(Object.keys(VIS_META) as Visibility[]).map((k) => ({\n value: k,\n label: VIS_META[k].label,\n description: VIS_META[k].description,\n }))}\n />\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n}\n\nfunction Avatar({ label, org }: { label: string; org?: boolean }) {\n return (\n <span\n aria-hidden\n className=\"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-muted text-[11px] font-semibold text-muted-foreground\"\n >\n {org ? <IconBuilding size={14} strokeWidth={1.75} /> : initials(label)}\n </span>\n );\n}\n\nfunction keyOf(s: Share): string {\n return `${s.principalType}:${s.principalId}`;\n}\nfunction cap(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\nfunction initials(s: string): string {\n const name = s.split(\"@\")[0] ?? s;\n return (name[0] ?? \"?\").toUpperCase();\n}\n\nfunction displayName(email: string, members: OrgMember[]): string {\n const match = members.find((m) => m.email === email);\n if (match?.name && match.name.trim()) return match.name;\n return email;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"use-action.d.ts","sourceRoot":"","sources":["../../src/client/use-action.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAS/B;;;;;GAKG;AACH,MAAM,WAAW,cAAc;CAAG;AAElC,2FAA2F;AAC3F,KAAK,UAAU,GAAG,MAAM,cAAc,SAAS,KAAK,GAChD,MAAM,GACN,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEpD,8EAA8E;AAC9E,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,cAAc,GAChE,cAAc,CAAC,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC3C,CAAC,GACD,GAAG,GACL,GAAG,CAAC;AAER,iGAAiG;AACjG,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,cAAc,GAChE,cAAc,CAAC,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC3C,CAAC,GACD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACrB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAuIxB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,OAAO,GAAG,SAAS,EACnB,KAAK,SAAS,UAAU,GAAG,UAAU,EAErC,UAAU,EAAE,KAAK,EACjB,MAAM,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC,EAC5B,OAAO,CAAC,EAAE,IAAI,CACZ,eAAe,CAAC,OAAO,SAAS,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,EAC1E,UAAU,GAAG,SAAS,CACvB,6JAQF;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,GAAG,SAAS,EACjB,UAAU,GAAG,SAAS,EACtB,KAAK,SAAS,UAAU,GAAG,UAAU,EAErC,UAAU,EAAE,KAAK,EACjB,OAAO,CAAC,EAAE,IAAI,CACZ,kBAAkB,CAChB,KAAK,SAAS,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,KAAK,EACrD,KAAK,EACL,UAAU,SAAS,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,UAAU,CAChE,EACD,YAAY,CACb,GAAG;IACF,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;CACpC,6LAuBF"}
1
+ {"version":3,"file":"use-action.d.ts","sourceRoot":"","sources":["../../src/client/use-action.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAS/B;;;;;GAKG;AACH,MAAM,WAAW,cAAc;CAAG;AAElC,2FAA2F;AAC3F,KAAK,UAAU,GAAG,MAAM,cAAc,SAAS,KAAK,GAChD,MAAM,GACN,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEpD,8EAA8E;AAC9E,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,cAAc,GAChE,cAAc,CAAC,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC3C,CAAC,GACD,GAAG,GACL,GAAG,CAAC;AAER,iGAAiG;AACjG,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,cAAc,GAChE,cAAc,CAAC,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC3C,CAAC,GACD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACrB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAwIxB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,OAAO,GAAG,SAAS,EACnB,KAAK,SAAS,UAAU,GAAG,UAAU,EAErC,UAAU,EAAE,KAAK,EACjB,MAAM,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC,EAC5B,OAAO,CAAC,EAAE,IAAI,CACZ,eAAe,CAAC,OAAO,SAAS,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,EAC1E,UAAU,GAAG,SAAS,CACvB,6JAQF;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,GAAG,SAAS,EACjB,UAAU,GAAG,SAAS,EACtB,KAAK,SAAS,UAAU,GAAG,UAAU,EAErC,UAAU,EAAE,KAAK,EACjB,OAAO,CAAC,EAAE,IAAI,CACZ,kBAAkB,CAChB,KAAK,SAAS,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,KAAK,EACrD,KAAK,EACL,UAAU,SAAS,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,UAAU,CAChE,EACD,YAAY,CACb,GAAG;IACF,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;CACpC,6LAuBF"}
@@ -49,6 +49,7 @@ async function actionFetch(name, method, params) {
49
49
  const init = {
50
50
  method,
51
51
  headers,
52
+ cache: "no-store",
52
53
  };
53
54
  if (method === "GET" && params && Object.keys(params).length > 0) {
54
55
  // Skip null/undefined so optional filters don't turn into literal "null"