/** * Lib-side entity-card dispatch — single switch over canonical chat cards. * * Lib-portable refactor of the hub's `components/shared/entity-card-dispatch.tsx`. * Drops the hub-only imports: * - `useNavLink` → click routing flows through `` * (reads `useRequiredChatRuntime` internally) or * the chat-runtime's `handleChatNavClick` helper. * - `currentPlatform` → runtime.source supplies the identifier. * - `buildContentURL` → URLs arrive pre-composed by the server's * RAG mapper (`ref.url`); the card just renders. * - `tableIdForDocumentType` → only relevant for the hub-side ContentRef * reverse-projection — not needed for chat * inline cards. * - hub `program-configs` → host provides via `ChatCardRenderOptions.extras`. * - `buildProductReleaseCardProps` → ditto, host provides via `extras`. * * Adding a new chat-inline card type: * 1. Implement the `size='sm'` branch + skeleton in `./.tsx` (pure * presentation, accepts `href` + `targetPlatform`). * 2. Add one entry to `CHAT_CARD_REGISTRY` below. * * Public entry points consumed by the chat shell: * - `renderChatInlineEntityCard(ref, opts)` — top-level marker dispatch * (block-card hoist for video refs, otherwise compact card). * - `` — fetch + skeleton + render the compact card for * fetch-mode entries. */ import React from 'react'; import type { ChatRef } from '../chat-ref.types'; import { NavLinkAnchorViaRuntime } from '../nav-link-anchor-via-runtime'; import { type ProductReleaseCardProps } from './product-release-card'; import type { ProgramConfig } from '../types/entities/program-types'; /** Optional host-side extras threaded through to render functions whose * derived props can't be computed in lib alone (program configs and the * product-release prop builder live in hub land). When omitted, the * affected card types render `null` from the dispatch — the chat shell's * fallback path takes over. */ export interface ChatCardDispatchExtras { /** Per-program-type config map. Keyed by chat documentType * (`podcast` / `webinar` / `event`). Each entry is the canonical * `` the `` expects. */ programConfigs?: { podcast?: ProgramConfig; webinar?: ProgramConfig; event?: ProgramConfig; }; /** Derive the `` prop bundle from a hydrated * release row. Hub callers wire `buildProductReleaseCardProps` from * `lib/utils/product-release-card-props.ts`. */ buildProductReleaseCardProps?: (release: any) => Omit; /** Build a branded OG placeholder URL from an entity title. Compact chat- * inline cards (`size='sm'` for blog/case-study/customer-interview/ * investor-update/onboarding-guide) pass the result as `placeholderUrl` * so the card's image slot renders the OG fallback instead of an empty * span when the entity has no `featured_image`. Hub callers wire * `buildOgPlaceholderUrl` from `lib/utils/entity-image.ts`. Optional — * when omitted, the compact cards keep the existing empty-slot * behavior. */ buildOgPlaceholderUrl?: (title: string) => string | null; } /** Per-card render options threaded through from the chat shell. */ export interface ChatCardRenderOptions { baseRoute?: string; chipBasePlatform?: string; /** Host-supplied builders for cards whose derived props live in hub * land (programs + product_release). When omitted, these card types * render `null` and the shell falls back to title text. */ extras?: ChatCardDispatchExtras; /** Pre-computed new-tab decision for the inner anchor's `target` * attribute. Required — always computed by `ChatCardLoader` via the * same rule source chips use, so the rendered `` matches * whatever `ChatCardNavWrap` + `handleChatNavClick` decide at click * time. */ isNewTab: boolean; /** Host-provided "Ask Mingo"/"Display" affordance for this card, resolved * once by `ChatCardLoader`. Each wrapper threads it into its "⋯" menu via * `cardMenuGroups`. Undefined when the host supplied no `onDiscuss`/ * `onDisplay` (then the menu shows only "Open in new tab"). */ discuss?: CardDiscussAction; } /** The host-provided "Ask Mingo" / "Display" affordance, resolved once per * card in `ChatCardLoader` and threaded through `renderOpts.discuss`. Mirrors * the legacy `ChatCardWithDiscuss` source-row button, relocated into the "⋯" * menu. */ export interface CardDiscussAction { label: string; icon: React.ReactNode; run: () => void; } /** External-app deep-link row for a card's "⋯" menu (e.g. "Open in ClickUp"). * Always opens in a new tab — the destination is a third-party app, never a * hub route. */ export interface CardExternalLink { label: string; icon: React.ReactNode; href: string; } interface ChatCardLoaderProps { chatRef: ChatRef; onDiscuss?: (ref: ChatRef) => void; onDisplay?: (ref: ChatRef) => void; baseRoute?: string; chipBasePlatform?: string; extras?: ChatCardDispatchExtras; } /** * Generic fetch-mode card loader. Looks up the registry entry by * `chatRef.type`, fetches the full item via `useChatCardItem`, and * routes through skeleton / null / card-render. * * SINGLE URL-RESOLUTION POINT — same code path source chips already * had. Before render dispatch: * - Pass the ref through `resolveSourceRowCTA` to compute the * canonical `{href, targetPlatform}` (externalUrl → in-app path * fallback → null, with embedder `baseRoute` / `chipBasePlatform` * awareness). * - Pre-resolve href against `runtime.navigation.defaultContentOrigin` * in embed mode (so modifier-click + copy-link land on the hub). * - Re-attach the resolved values onto the ref so EVERY downstream * card — whether it renders an inner `` from `href` prop * (BlogCard, ProgramCard, …) or pulls `anchorProps` from * `computeIsNewTab` — sees the SAME canonical URL the * chip would render. * * Eliminates the entire "chip works, inline card doesn't" class of bug. */ export declare function ChatCardLoader({ chatRef, onDiscuss, onDisplay, baseRoute, chipBasePlatform, extras, }: ChatCardLoaderProps): React.JSX.Element | null; /** * Render the chat-inline card for a `[card://:]` marker. * * Single dispatch through `CHAT_CARD_REGISTRY`. The function mirrors the * hub's `renderChatInlineEntityCard` behavior: * - Video-bearing refs return a `` sentinel so the * `chat-message-enhanced` pre-scan hoists the player out of the * assistant paragraph. * - Other refs render the compact card, optionally wrapped in a * close-on-anchor-click span when `onClose` is supplied. */ export declare function renderChatInlineEntityCard(chatRef: ChatRef, options?: { onDiscuss?: (ref: ChatRef) => void; onDisplay?: (ref: ChatRef) => void; baseRoute?: string; chipBasePlatform?: string; extras?: ChatCardDispatchExtras; }): React.ReactNode; /** Re-export so call sites can wrap any subtree with chat-runtime * routing in a single import. */ export { NavLinkAnchorViaRuntime }; //# sourceMappingURL=dispatch.d.ts.map