@flamingo-stack/openframe-frontend-core 0.0.369 → 0.0.370-snapshot.20260706030226
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-JZZ5K6PD.js → chunk-3FCXFT25.js} +2 -2
- package/dist/{chunk-RCCYW5EJ.js → chunk-5N6T2O64.js} +4 -4
- package/dist/{chunk-WG2QLZTD.cjs → chunk-7FTBFI4E.cjs} +15 -15
- package/dist/{chunk-WG2QLZTD.cjs.map → chunk-7FTBFI4E.cjs.map} +1 -1
- package/dist/{chunk-RHKWZHHR.cjs → chunk-7QSHY7TW.cjs} +5 -5
- package/dist/{chunk-RHKWZHHR.cjs.map → chunk-7QSHY7TW.cjs.map} +1 -1
- package/dist/{chunk-2YRPY6CP.cjs → chunk-ANPQSTVG.cjs} +9 -9
- package/dist/{chunk-2YRPY6CP.cjs.map → chunk-ANPQSTVG.cjs.map} +1 -1
- package/dist/{chunk-WNIXFW5I.js → chunk-B6XC2A2D.js} +2 -2
- package/dist/{chunk-KSJLQMTA.js → chunk-ESK47VJE.js} +2 -2
- package/dist/{chunk-RR5VZIWO.cjs → chunk-F5JNT3M6.cjs} +57 -57
- package/dist/{chunk-RR5VZIWO.cjs.map → chunk-F5JNT3M6.cjs.map} +1 -1
- package/dist/{chunk-FYBO6T5N.js → chunk-GLNIVUXO.js} +2 -2
- package/dist/{chunk-JKSLHSGN.cjs → chunk-JDNVPPPM.cjs} +25 -25
- package/dist/{chunk-JKSLHSGN.cjs.map → chunk-JDNVPPPM.cjs.map} +1 -1
- package/dist/{chunk-N7VM7F27.js → chunk-K3EAB7CB.js} +4 -4
- package/dist/{chunk-F7X7FHRU.cjs → chunk-L4MEO7LO.cjs} +62 -62
- package/dist/{chunk-F7X7FHRU.cjs.map → chunk-L4MEO7LO.cjs.map} +1 -1
- package/dist/{chunk-CZVFME5Y.cjs → chunk-L7V3FTQH.cjs} +8 -3
- package/dist/chunk-L7V3FTQH.cjs.map +1 -0
- package/dist/{chunk-3GZU2H2F.cjs → chunk-LIRDSZJZ.cjs} +7 -7
- package/dist/{chunk-3GZU2H2F.cjs.map → chunk-LIRDSZJZ.cjs.map} +1 -1
- package/dist/{chunk-BMD3HYHB.js → chunk-MM3EHJWC.js} +2 -2
- package/dist/{chunk-K65MUKDT.js → chunk-NXXIDL23.js} +2 -2
- package/dist/{chunk-XPVK2FP3.js → chunk-QCP7MOZQ.js} +4 -4
- package/dist/{chunk-YW6KVM7X.cjs → chunk-UOIVXG7F.cjs} +31 -31
- package/dist/{chunk-YW6KVM7X.cjs.map → chunk-UOIVXG7F.cjs.map} +1 -1
- package/dist/{chunk-NQ6FSKSD.cjs → chunk-W6EPGTAZ.cjs} +26 -26
- package/dist/{chunk-NQ6FSKSD.cjs.map → chunk-W6EPGTAZ.cjs.map} +1 -1
- package/dist/{chunk-M4XVYRK5.js → chunk-WASHVPIT.js} +2 -2
- package/dist/{chunk-ARE7STTN.js → chunk-WH2NO3ED.js} +8 -3
- package/dist/chunk-WH2NO3ED.js.map +1 -0
- package/dist/{chunk-KXXSJUOY.js → chunk-WOFRLTI4.js} +4 -4
- package/dist/{chunk-C3CYMFQH.cjs → chunk-WQLYXINK.cjs} +12 -12
- package/dist/{chunk-C3CYMFQH.cjs.map → chunk-WQLYXINK.cjs.map} +1 -1
- package/dist/{chunk-SCKLOLNC.cjs → chunk-XUAGOEEG.cjs} +37 -37
- package/dist/{chunk-SCKLOLNC.cjs.map → chunk-XUAGOEEG.cjs.map} +1 -1
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/chat/quick-action-chip.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +20 -20
- package/dist/components/help-center-pages/index.js +11 -11
- package/dist/components/index.cjs +141 -120
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +31 -10
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +5 -5
- package/dist/components/tickets/index.js +4 -4
- package/dist/components/ui/index.cjs +2 -2
- package/dist/components/ui/index.js +1 -1
- package/dist/components/vendor-tag.d.ts +1 -1
- package/dist/components/vendor-tag.d.ts.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/chat/quick-action-chip.tsx +7 -2
- package/src/components/vendor-tag.tsx +39 -2
- package/dist/chunk-ARE7STTN.js.map +0 -1
- package/dist/chunk-CZVFME5Y.cjs.map +0 -1
- /package/dist/{chunk-JZZ5K6PD.js.map → chunk-3FCXFT25.js.map} +0 -0
- /package/dist/{chunk-RCCYW5EJ.js.map → chunk-5N6T2O64.js.map} +0 -0
- /package/dist/{chunk-WNIXFW5I.js.map → chunk-B6XC2A2D.js.map} +0 -0
- /package/dist/{chunk-KSJLQMTA.js.map → chunk-ESK47VJE.js.map} +0 -0
- /package/dist/{chunk-FYBO6T5N.js.map → chunk-GLNIVUXO.js.map} +0 -0
- /package/dist/{chunk-N7VM7F27.js.map → chunk-K3EAB7CB.js.map} +0 -0
- /package/dist/{chunk-BMD3HYHB.js.map → chunk-MM3EHJWC.js.map} +0 -0
- /package/dist/{chunk-K65MUKDT.js.map → chunk-NXXIDL23.js.map} +0 -0
- /package/dist/{chunk-XPVK2FP3.js.map → chunk-QCP7MOZQ.js.map} +0 -0
- /package/dist/{chunk-M4XVYRK5.js.map → chunk-WASHVPIT.js.map} +0 -0
- /package/dist/{chunk-KXXSJUOY.js.map → chunk-WOFRLTI4.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-2YRPY6CP.cjs","../src/components/shared/doc-search/format-relative-path.ts","../src/components/shared/doc-search/doc-search-result-row.tsx","../src/components/shared/doc-search/doc-search-bar.tsx","../src/components/shared/doc-search/map-doc-search-results.ts","../src/components/shared/doc-search/resolve-search-result-action.ts","../src/components/shared/doc-search/use-doc-search.ts"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-2YRPY6CP.cjs","sourcesContent":[null,"/**\n * Format a full document path as a breadcrumb trail.\n * Shows parent folders only (excludes the last segment / filename).\n *\n * @example\n * formatRelativePath('openframe-oss-tenant/architecture/api-controllers.md')\n * // → 'Openframe oss tenant / Architecture'\n */\nexport function formatRelativePath(fullPath: string): string {\n if (!fullPath) return ''\n const segments = fullPath.replace(/\\.md$/, '').split('/')\n // Show only parent path (exclude the filename itself since the title already shows it)\n const parentSegments = segments.length > 1 ? segments.slice(0, -1) : segments\n return parentSegments\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1).replace(/-/g, ' '))\n .join(' / ')\n}\n","'use client'\n\n/**\n * Single row in the `<SearchInput>` dropdown — the standard layout\n * used by every doc-search-backed surface (company-hub data-room\n * search bar, onboarding-guide catalog search, …). Single source of\n * truth for the row appearance so search dropdowns are visually\n * identical everywhere.\n *\n * Resolves the source icon via the same `resolveSourceIcon()`\n * registry the inline chat-card refs use, so a row pointing at e.g.\n * an onboarding-guide surfaces the SAME `<GraduationCap>` glyph the\n * chat card surfaces — no cross-surface drift.\n */\n\nimport { resolveSourceIcon } from '../../chat/utils/source-row-cta'\nimport { formatRelativePath } from './format-relative-path'\n\n/**\n * Minimal result shape this row renders. Compatible with any\n * doc-search hook whose result type exposes `{ title?, path?,\n * metadata? }`. The two hub consumers (onboarding-guide catalog,\n * data-room sidebar) both satisfy this shape via their\n * `useDocSearch` hook result.\n */\nexport interface DocSearchResultRowEntry {\n title?: string\n path?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface DocSearchResultRowProps {\n result: DocSearchResultRowEntry\n isHighlighted: boolean\n}\n\nexport function DocSearchResultRow({\n result,\n isHighlighted,\n}: DocSearchResultRowProps) {\n const docType = (result.metadata?.documentType as string) || undefined\n const sourceRepo = (result.metadata?.sourceRepo as string) || undefined\n const { Icon: SourceIcon, label: iconLabel } = resolveSourceIcon({\n sourceRepo,\n documentType: docType,\n })\n const isGroup = result.metadata?.isGroup as boolean | undefined\n\n return (\n <div className=\"flex items-center gap-3 w-full min-w-0\">\n <span\n className=\"flex-shrink-0 text-ods-text-secondary\"\n title={iconLabel}\n >\n <SourceIcon className=\"size-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div\n className={`text-sm font-medium leading-5 truncate ${\n isHighlighted ? 'text-ods-accent' : 'text-ods-text-primary'\n }`}\n >\n {result.title || result.path}\n </div>\n {!isGroup && result.path?.includes('/') && (\n <div className=\"text-xs leading-4 text-ods-text-secondary truncate mt-0.5\">\n {formatRelativePath(result.path)}\n </div>\n )}\n </div>\n </div>\n )\n}\n","'use client'\n\n/**\n * `<DocSearchBar>` — the canonical RAG-search dropdown surface.\n *\n * Mounted by every doc-search consumer (data-room sidebar, onboarding-\n * guide catalog, and any future surface that needs typeahead against\n * `/api/docs/search`). Wraps `<SearchInput>` with the lib's standard\n * `<DocSearchResultRow>` so the dropdown looks identical everywhere.\n *\n * ## Why a presentation component, not a \"search bar that owns its\n * own hook\"\n *\n * The data-fetching hook (`useDocSearch`) lives hub-side because it\n * depends on hub-only context (`useDocNavigation`, the rag-table-\n * config registry, the hub's `decideNewTab` helper). Moving the hook\n * would cascade ~5 more file migrations into the lib.\n *\n * Instead, the hook stays hub-side and callers pass its result into\n * this component as plain props. Both consumers shrink to ~5 lines.\n */\n\nimport type { ReactNode } from 'react'\nimport { SearchInput, type SearchResult } from '../../ui/search-input'\nimport { DocSearchResultRow } from './doc-search-result-row'\n\nexport interface DocSearchBarProps {\n placeholder: string\n query: string\n onQueryChange: (value: string) => void\n /** Hook-fetched results. Reuses the lib's `<SearchInput>` `SearchResult`\n * shape directly so callers don't translate. */\n results: SearchResult[]\n isLoading: boolean\n /** Result selection handler. Mirrors `<SearchInput>` — the second\n * `modifiers` argument is preserved so cmd-click / shift-click on\n * a result row still forces new-tab behavior. Hub `useDocSearch`\n * reads these to short-circuit to `window.open()`. */\n onResultSelect: (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => void\n /** Lets the caller's hook force the dropdown open after a recent\n * internal action (e.g. result navigation). `undefined` falls back\n * to `<SearchInput>`'s built-in focus/hover heuristics. */\n showDropdown?: boolean\n /** Defaults to 2 — matches the existing data-room and onboarding-\n * guide consumers. Override only if a surface needs different\n * typeahead semantics. */\n minQueryLength?: number\n /** Defaults to 0 — both existing consumers debounce inside the\n * hook, not the input. */\n debounceMs?: number\n className?: string\n /** Optional row-renderer override. Defaults to the lib's standard\n * `<DocSearchResultRow>` (source icon + title + path breadcrumb).\n * Override only when a surface needs custom row chrome. */\n renderResult?: (result: SearchResult, isHighlighted: boolean) => ReactNode\n}\n\nexport function DocSearchBar({\n placeholder,\n query,\n onQueryChange,\n results,\n isLoading,\n onResultSelect,\n showDropdown,\n minQueryLength = 2,\n debounceMs = 0,\n className = 'w-full',\n renderResult,\n}: DocSearchBarProps) {\n return (\n <SearchInput\n placeholder={placeholder}\n value={query}\n onChange={onQueryChange}\n results={results}\n isLoading={isLoading}\n onResultSelect={onResultSelect}\n showDropdown={showDropdown || undefined}\n debounceMs={debounceMs}\n minQueryLength={minQueryLength}\n className={className}\n renderResult={\n renderResult ??\n ((result, isHighlighted) => (\n <DocSearchResultRow result={result} isHighlighted={isHighlighted} />\n ))\n }\n />\n )\n}\n","/**\n * Map RAG `/api/docs/search` wire results into the `<DocSearchBar>`\n * dropdown's row shape, collapsing entity-table rows into grouped\n * results so the dropdown lists ONE \"Cap Table (12 records)\" row\n * instead of 12 individual rows.\n *\n * Pure transform — no telemetry, no navigation, no React deps. Lifted\n * from the hub's `hooks/use-docs.ts:mapDocSearchResults` (the hub's\n * `traceCompose` call was hub-only telemetry and is intentionally\n * dropped — callers that want logging can wrap this helper).\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { DocSearchResult } from './types'\n\n/** Source repos that should be collapsed into grouped results in the search bar.\n * Only financial tables (all rows link to the same admin page).\n * Content tables (blog, webinar, podcast, etc.) stay individual since each has a unique URL. */\nconst SEARCH_GROUP_REPOS = new Set([\n 'financial-cap-table',\n 'financial-kpis',\n 'financial-pnl',\n 'financial-balance-sheet',\n 'financial-cash-flow',\n])\n\nconst ENTITY_LABELS: Record<string, string> = {\n 'financial-cap-table': 'Cap Table',\n 'financial-kpis': 'Financial KPIs',\n 'financial-pnl': 'Profit & Loss',\n 'financial-balance-sheet': 'Balance Sheets',\n 'financial-cash-flow': 'Cash Flow',\n 'blog-posts': 'Blog Posts',\n 'product-releases': 'Product Releases',\n 'case-studies': 'Case Studies',\n webinars: 'Webinars',\n events: 'Events',\n podcasts: 'Podcasts',\n}\n\nexport function mapDocSearchResults(docs: DocSearchResult[]): SearchResult[] {\n const entityGroups = new Map<string, DocSearchResult[]>()\n // Track insertion order — groups appear where the FIRST row of that\n // repo appeared in the response.\n const order: Array<\n { type: 'entity'; repo: string } | { type: 'doc'; doc: DocSearchResult }\n > = []\n const seenRepos = new Set<string>()\n\n for (const doc of docs) {\n if (doc.sourceRepo && SEARCH_GROUP_REPOS.has(doc.sourceRepo)) {\n const group = entityGroups.get(doc.sourceRepo) || []\n group.push(doc)\n entityGroups.set(doc.sourceRepo, group)\n if (!seenRepos.has(doc.sourceRepo)) {\n seenRepos.add(doc.sourceRepo)\n order.push({ type: 'entity', repo: doc.sourceRepo })\n }\n } else {\n order.push({ type: 'doc', doc })\n }\n }\n\n const results: SearchResult[] = []\n for (const entry of order) {\n if (entry.type === 'entity') {\n const rows = entityGroups.get(entry.repo)!\n const label = ENTITY_LABELS[entry.repo] || entry.repo\n results.push({\n id: `group-${entry.repo}`,\n title: `${label} (${rows.length} ${rows.length === 1 ? 'record' : 'records'})`,\n path: rows[0].path,\n type: 'file',\n metadata: {\n documentType: rows[0].documentType,\n externalUrl: rows[0].externalUrl,\n sourceRepo: entry.repo,\n id: rows[0].entityId,\n isGroup: true,\n items: rows.map((r) => ({\n name: r.name,\n externalUrl: r.externalUrl,\n id: r.entityId,\n sourceRepo: r.sourceRepo,\n documentType: r.documentType,\n })),\n },\n })\n } else {\n const doc = entry.doc\n const isNonMarkdown = doc.documentType && doc.documentType !== 'markdown'\n results.push({\n id: doc.path,\n title: doc.name,\n description: isNonMarkdown ? doc.name : doc.snippet,\n path: doc.path,\n type: doc.type,\n metadata: {\n matchType: doc.matchType,\n ...(doc.documentType ? { documentType: doc.documentType } : {}),\n ...(doc.externalUrl ? { externalUrl: doc.externalUrl } : {}),\n ...(doc.targetPlatform != null\n ? { targetPlatform: doc.targetPlatform }\n : {}),\n ...(doc.sourceRepo ? { sourceRepo: doc.sourceRepo } : {}),\n ...(doc.entityId ? { id: doc.entityId } : {}),\n },\n })\n }\n }\n\n return results\n}\n","/**\n * Resolve what should happen when the user picks a search result.\n * Returns one of five typed actions so the caller is a single switch.\n *\n * Resolution order:\n * 1. `externalUrl` present → use `decideNewTab` to choose same-tab vs\n * new-tab against the row's `targetPlatform`.\n * 2. Row has `id` + `sourceRepo` + `documentType` → synth an Ask-AI\n * action (entity drill-in via primary key, no URL).\n * 3. Row has only `path` → legacy navigation fallback.\n * 4. Nothing actionable → noop.\n *\n * Lifted from the hub's `hooks/use-docs.ts:resolveSearchResultAction`.\n * Pure — no React, no telemetry.\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { ChatRef } from '../../chat/chat-ref.types'\nimport { decideNewTab } from '../../chat/utils/decide-new-tab'\n\nexport type SearchResultAction =\n | { kind: 'navigate-same-tab'; href: string }\n | { kind: 'navigate-new-tab'; href: string }\n | { kind: 'ask-ai'; detail: { source: string; ref: ChatRef } }\n | { kind: 'route'; path: string }\n | { kind: 'noop' }\n\nexport function resolveSearchResultAction(\n result: SearchResult,\n source: string,\n runtimeMode?: 'host' | 'embed',\n): SearchResultAction {\n const meta = result.metadata ?? {}\n const externalUrl = meta.externalUrl as string | undefined\n if (externalUrl) {\n // Same pure helper `useNavLink` and `useUnifiedNav` call — single\n // decision rule across cards, chips, and autocomplete rows. Thread\n // the caller's `source` as `currentSource` so the platform-vs-\n // platform comparison matches the hub's pre-migration behavior.\n const targetPlatform = meta.targetPlatform as string | null | undefined\n const isNewTab = decideNewTab({\n href: externalUrl,\n targetPlatform,\n surface: 'useUnifiedNav',\n runtimeMode,\n currentSource: source,\n })\n return isNewTab\n ? { kind: 'navigate-new-tab', href: externalUrl }\n : { kind: 'navigate-same-tab', href: externalUrl }\n }\n const rowId = meta.id as string | undefined\n const sourceRepo = meta.sourceRepo as string | undefined\n const documentType = meta.documentType as string | undefined\n if (rowId && sourceRepo && documentType) {\n return {\n kind: 'ask-ai',\n detail: {\n source,\n ref: { type: documentType, id: rowId, title: result.title, url: null },\n },\n }\n }\n if (result.path) {\n return { kind: 'route', path: result.path }\n }\n return { kind: 'noop' }\n}\n","'use client'\n\n/**\n * `useDocSearch` — debounced RAG-search hook against `/api/docs/search`.\n *\n * Pure fetch + navigation glue. Embedders can mount this directly\n * (any host with a reverse-proxy that exposes `/api/docs/search` will\n * work). Hub callers wire it into the lib `<DocSearchBar>` for the\n * canonical typeahead dropdown.\n *\n * ## What moved from hub to lib\n *\n * Lifted from `multi-platform-hub/hooks/use-docs.ts:useDocSearch`. Two\n * hub-only concerns are now optional injection points instead of\n * direct imports:\n *\n * - `useDocNavigation()` (hub's in-page doc-tree swap) → optional\n * `onInPageSwap?: (path: string) => boolean` config callback. When\n * present and returns true, the hook treats a same-origin result\n * click as \"handled in-page\"; when absent or returns false, the\n * hook falls back to `onNavigate(path)` (`router.push` on hub,\n * `window.location.assign` on bare embedders).\n * - `traceCompose` (hub-only telemetry) → dropped. The lib has no\n * equivalent runtime-context yet; bring it back when there is one.\n *\n * Everything else (debounce, `useChatRuntime` for embed-mode short-\n * circuit, embed-shim router, the action-resolver + result-mapper) is\n * now lib-resident.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useRouter } from '../../../embed-shims'\nimport { useDebounce } from '../../../hooks/ui/use-debounce'\nimport { useChatRuntime } from '../../../contexts/chat-runtime-context'\nimport { contentFetch } from '../../../utils/embed-content-fetch'\nimport type { SearchResult } from '../../ui/search-input'\nimport {\n resolveExternalNavigation,\n stripSameOriginToPath,\n NEW_TAB_FEATURES,\n} from '../../chat/utils/chat-nav-resolution'\nimport type { DocSearchResult } from './types'\nimport { mapDocSearchResults } from './map-doc-search-results'\nimport { resolveSearchResultAction } from './resolve-search-result-action'\n\nexport interface UseDocSearchConfig {\n /** Discriminator passed to `/api/docs/search?source=` (e.g.\n * `'openframe'`). Embedders set it to whatever discriminator their\n * reverse-proxy expects. */\n source: string\n /** Base route prefix this search lives under (e.g. `'/onboarding-guides'`).\n * When a result's href starts with `${baseRoute}/`, the hook\n * attempts the optional in-page swap path before falling through\n * to a full nav. */\n baseRoute: string\n /** Imperative navigation fallback. Called when no override\n * (in-page swap, new-tab) applies. Hub callers pass\n * `(path) => router.push(path)`; embedders pass an equivalent. */\n onNavigate: (path: string) => void\n /** Optional `RagTableConfig.id` list to narrow the search to specific\n * tables (e.g. `['onboarding-guides']`). Forwarded to\n * `/api/docs/search?tableIds=…` which intersects with the source's\n * standing set. */\n tableIds?: string[]\n /** Optional in-page swap callback. When the result's href is under\n * `baseRoute` AND this callback returns true, the hook treats the\n * click as handled in-page (no router push). Hub's\n * `<DocumentationSection>` wires this to\n * `useDocNavigation().navigate(path)`. */\n onInPageSwap?: (path: string) => boolean\n /** Optional endpoint override. Defaults to `'/api/docs/search'`\n * (the hub's reverse-proxy route). Embedders with a different\n * path can override. */\n searchEndpoint?: string\n}\n\nexport function useDocSearch(config: UseDocSearchConfig) {\n const {\n source,\n baseRoute,\n onNavigate,\n tableIds,\n onInPageSwap,\n searchEndpoint,\n } = config\n const tableIdsKey = tableIds && tableIds.length > 0 ? tableIds.join(',') : ''\n\n const router = useRouter()\n // Optional chat-runtime read — when present and mode='embed' the\n // search-result row click short-circuits to a new-tab open against\n // the absolutized URL. Null/host preserves today's behavior.\n // Also used as the proxy-prefix fallback for `searchEndpoint`, matching\n // how tickets resolves `findTicketUrl`.\n const runtime = useChatRuntime()\n const resolvedSearchEndpoint =\n searchEndpoint ?? runtime?.endpoints.docsSearchUrl ?? '/api/docs/search'\n\n const [query, setQuery] = useState('')\n const [results, setResults] = useState<SearchResult[]>([])\n const [isFetching, setIsFetching] = useState(false)\n const debouncedQuery = useDebounce(query, 300)\n\n useEffect(() => {\n if (!debouncedQuery || debouncedQuery.trim().length < 2) {\n setResults([])\n setIsFetching(false)\n return\n }\n\n let cancelled = false\n\n async function fetchResults() {\n setIsFetching(true)\n try {\n const params = new URLSearchParams({\n q: debouncedQuery,\n source,\n limit: '10',\n })\n if (tableIdsKey) params.set('tableIds', tableIdsKey)\n\n const response = await contentFetch(`${resolvedSearchEndpoint}?${params.toString()}`)\n if (!response.ok) {\n throw new Error(`Search request failed: ${response.status}`)\n }\n\n const json = await response.json()\n\n if (!cancelled && json.success && Array.isArray(json.data)) {\n const mapped = mapDocSearchResults(json.data as DocSearchResult[])\n setResults(mapped)\n }\n } catch (error) {\n console.error('Doc search error:', error)\n if (!cancelled) {\n setResults([])\n }\n } finally {\n if (!cancelled) {\n setIsFetching(false)\n }\n }\n }\n\n fetchResults()\n\n return () => {\n cancelled = true\n }\n }, [debouncedQuery, source, tableIdsKey, resolvedSearchEndpoint])\n\n // Derived loading state — single source of truth for \"should the\n // dropdown show 'Loading...' instead of 'No results found'\":\n const isLoading =\n query.trim().length >= 2 && (query !== debouncedQuery || isFetching)\n\n // Track whether dropdown should stay open (external link opened in new tab).\n const [keepOpen, setKeepOpen] = useState(false)\n\n const handleResultSelect = useCallback(\n (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => {\n const action = resolveSearchResultAction(\n result,\n source,\n runtime?.navigation.mode,\n )\n // Modifier / non-primary mouse click → force new tab regardless of\n // same-tab/new-tab decision. The dropdown row is a `<div>`, not an\n // `<a target=\"_blank\">`, so the browser doesn't background-tab\n // natively on cmd-click. Honor it explicitly here for parity with\n // the anchor-based surfaces (cards, chips, related-content). Plain\n // Enter from the keyboard passes `modifiers === undefined`.\n const wantsNewTab =\n modifiers &&\n (modifiers.metaKey ||\n modifiers.ctrlKey ||\n modifiers.shiftKey ||\n modifiers.altKey ||\n (typeof modifiers.button === 'number' && modifiers.button !== 0))\n switch (action.kind) {\n case 'navigate-same-tab': {\n // Embed-mode short-circuit — autocomplete row clicked while\n // the chat panel is hosted inside an embedding app.\n if (runtime?.navigation.mode === 'embed') {\n setKeepOpen(true)\n const targetPlatform =\n (result.metadata?.targetPlatform as string | null | undefined) ?? null\n resolveExternalNavigation({\n href: action.href,\n targetPlatform,\n runtime,\n }).open()\n return\n }\n if (wantsNewTab) {\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n }\n // Same-origin click:\n // 1. If the href is under the current doc-tree's baseRoute AND\n // an `onInPageSwap` callback is wired AND returns true →\n // consider in-page swap handled.\n // 2. Otherwise → embed-shim `router.push()` (soft RSC nav on\n // Next.js hosts, window.location.assign on bare hosts).\n setKeepOpen(false)\n const path =\n baseRoute && action.href.startsWith(`${baseRoute}/`)\n ? action.href.slice(baseRoute.length + 1)\n : null\n if (path && onInPageSwap?.(path)) return\n router.push(stripSameOriginToPath(action.href))\n return\n }\n case 'navigate-new-tab':\n // Cross-origin (e.g. clicking a flamingo.run release from\n // product-hub) — open in a new tab. Keep dropdown open so the\n // user can pick another result without re-searching.\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n case 'ask-ai':\n // Row is searchable-but-not-openable (cap_table positions,\n // financial-kpi snapshots, anything backed by\n // `resolveUrl: () => null`). Dispatch a CustomEvent that\n // GlobalAskAI listens for — opens chat + drills via\n // `entityIdFilter` (primary-key only, same as inline-card Ask).\n setKeepOpen(false)\n window.dispatchEvent(\n new CustomEvent('ask-ai:open-with-ref', { detail: action.detail }),\n )\n return\n case 'route':\n // Final fallback: legacy navigation by path. Hits when a row\n // has neither URL nor pk metadata — a mapper/API regression.\n setKeepOpen(false)\n onNavigate(action.path)\n return\n case 'noop':\n return\n }\n },\n [onNavigate, source, baseRoute, router, onInPageSwap, runtime],\n )\n\n // Reset keepOpen when query changes.\n useEffect(() => {\n setKeepOpen(false)\n }, [query])\n\n return {\n query,\n setQuery,\n results,\n isLoading,\n handleResultSelect,\n keepDropdownOpen: keepOpen,\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-ANPQSTVG.cjs","../src/components/shared/doc-search/format-relative-path.ts","../src/components/shared/doc-search/doc-search-result-row.tsx","../src/components/shared/doc-search/doc-search-bar.tsx","../src/components/shared/doc-search/map-doc-search-results.ts","../src/components/shared/doc-search/resolve-search-result-action.ts","../src/components/shared/doc-search/use-doc-search.ts"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-ANPQSTVG.cjs","sourcesContent":[null,"/**\n * Format a full document path as a breadcrumb trail.\n * Shows parent folders only (excludes the last segment / filename).\n *\n * @example\n * formatRelativePath('openframe-oss-tenant/architecture/api-controllers.md')\n * // → 'Openframe oss tenant / Architecture'\n */\nexport function formatRelativePath(fullPath: string): string {\n if (!fullPath) return ''\n const segments = fullPath.replace(/\\.md$/, '').split('/')\n // Show only parent path (exclude the filename itself since the title already shows it)\n const parentSegments = segments.length > 1 ? segments.slice(0, -1) : segments\n return parentSegments\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1).replace(/-/g, ' '))\n .join(' / ')\n}\n","'use client'\n\n/**\n * Single row in the `<SearchInput>` dropdown — the standard layout\n * used by every doc-search-backed surface (company-hub data-room\n * search bar, onboarding-guide catalog search, …). Single source of\n * truth for the row appearance so search dropdowns are visually\n * identical everywhere.\n *\n * Resolves the source icon via the same `resolveSourceIcon()`\n * registry the inline chat-card refs use, so a row pointing at e.g.\n * an onboarding-guide surfaces the SAME `<GraduationCap>` glyph the\n * chat card surfaces — no cross-surface drift.\n */\n\nimport { resolveSourceIcon } from '../../chat/utils/source-row-cta'\nimport { formatRelativePath } from './format-relative-path'\n\n/**\n * Minimal result shape this row renders. Compatible with any\n * doc-search hook whose result type exposes `{ title?, path?,\n * metadata? }`. The two hub consumers (onboarding-guide catalog,\n * data-room sidebar) both satisfy this shape via their\n * `useDocSearch` hook result.\n */\nexport interface DocSearchResultRowEntry {\n title?: string\n path?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface DocSearchResultRowProps {\n result: DocSearchResultRowEntry\n isHighlighted: boolean\n}\n\nexport function DocSearchResultRow({\n result,\n isHighlighted,\n}: DocSearchResultRowProps) {\n const docType = (result.metadata?.documentType as string) || undefined\n const sourceRepo = (result.metadata?.sourceRepo as string) || undefined\n const { Icon: SourceIcon, label: iconLabel } = resolveSourceIcon({\n sourceRepo,\n documentType: docType,\n })\n const isGroup = result.metadata?.isGroup as boolean | undefined\n\n return (\n <div className=\"flex items-center gap-3 w-full min-w-0\">\n <span\n className=\"flex-shrink-0 text-ods-text-secondary\"\n title={iconLabel}\n >\n <SourceIcon className=\"size-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div\n className={`text-sm font-medium leading-5 truncate ${\n isHighlighted ? 'text-ods-accent' : 'text-ods-text-primary'\n }`}\n >\n {result.title || result.path}\n </div>\n {!isGroup && result.path?.includes('/') && (\n <div className=\"text-xs leading-4 text-ods-text-secondary truncate mt-0.5\">\n {formatRelativePath(result.path)}\n </div>\n )}\n </div>\n </div>\n )\n}\n","'use client'\n\n/**\n * `<DocSearchBar>` — the canonical RAG-search dropdown surface.\n *\n * Mounted by every doc-search consumer (data-room sidebar, onboarding-\n * guide catalog, and any future surface that needs typeahead against\n * `/api/docs/search`). Wraps `<SearchInput>` with the lib's standard\n * `<DocSearchResultRow>` so the dropdown looks identical everywhere.\n *\n * ## Why a presentation component, not a \"search bar that owns its\n * own hook\"\n *\n * The data-fetching hook (`useDocSearch`) lives hub-side because it\n * depends on hub-only context (`useDocNavigation`, the rag-table-\n * config registry, the hub's `decideNewTab` helper). Moving the hook\n * would cascade ~5 more file migrations into the lib.\n *\n * Instead, the hook stays hub-side and callers pass its result into\n * this component as plain props. Both consumers shrink to ~5 lines.\n */\n\nimport type { ReactNode } from 'react'\nimport { SearchInput, type SearchResult } from '../../ui/search-input'\nimport { DocSearchResultRow } from './doc-search-result-row'\n\nexport interface DocSearchBarProps {\n placeholder: string\n query: string\n onQueryChange: (value: string) => void\n /** Hook-fetched results. Reuses the lib's `<SearchInput>` `SearchResult`\n * shape directly so callers don't translate. */\n results: SearchResult[]\n isLoading: boolean\n /** Result selection handler. Mirrors `<SearchInput>` — the second\n * `modifiers` argument is preserved so cmd-click / shift-click on\n * a result row still forces new-tab behavior. Hub `useDocSearch`\n * reads these to short-circuit to `window.open()`. */\n onResultSelect: (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => void\n /** Lets the caller's hook force the dropdown open after a recent\n * internal action (e.g. result navigation). `undefined` falls back\n * to `<SearchInput>`'s built-in focus/hover heuristics. */\n showDropdown?: boolean\n /** Defaults to 2 — matches the existing data-room and onboarding-\n * guide consumers. Override only if a surface needs different\n * typeahead semantics. */\n minQueryLength?: number\n /** Defaults to 0 — both existing consumers debounce inside the\n * hook, not the input. */\n debounceMs?: number\n className?: string\n /** Optional row-renderer override. Defaults to the lib's standard\n * `<DocSearchResultRow>` (source icon + title + path breadcrumb).\n * Override only when a surface needs custom row chrome. */\n renderResult?: (result: SearchResult, isHighlighted: boolean) => ReactNode\n}\n\nexport function DocSearchBar({\n placeholder,\n query,\n onQueryChange,\n results,\n isLoading,\n onResultSelect,\n showDropdown,\n minQueryLength = 2,\n debounceMs = 0,\n className = 'w-full',\n renderResult,\n}: DocSearchBarProps) {\n return (\n <SearchInput\n placeholder={placeholder}\n value={query}\n onChange={onQueryChange}\n results={results}\n isLoading={isLoading}\n onResultSelect={onResultSelect}\n showDropdown={showDropdown || undefined}\n debounceMs={debounceMs}\n minQueryLength={minQueryLength}\n className={className}\n renderResult={\n renderResult ??\n ((result, isHighlighted) => (\n <DocSearchResultRow result={result} isHighlighted={isHighlighted} />\n ))\n }\n />\n )\n}\n","/**\n * Map RAG `/api/docs/search` wire results into the `<DocSearchBar>`\n * dropdown's row shape, collapsing entity-table rows into grouped\n * results so the dropdown lists ONE \"Cap Table (12 records)\" row\n * instead of 12 individual rows.\n *\n * Pure transform — no telemetry, no navigation, no React deps. Lifted\n * from the hub's `hooks/use-docs.ts:mapDocSearchResults` (the hub's\n * `traceCompose` call was hub-only telemetry and is intentionally\n * dropped — callers that want logging can wrap this helper).\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { DocSearchResult } from './types'\n\n/** Source repos that should be collapsed into grouped results in the search bar.\n * Only financial tables (all rows link to the same admin page).\n * Content tables (blog, webinar, podcast, etc.) stay individual since each has a unique URL. */\nconst SEARCH_GROUP_REPOS = new Set([\n 'financial-cap-table',\n 'financial-kpis',\n 'financial-pnl',\n 'financial-balance-sheet',\n 'financial-cash-flow',\n])\n\nconst ENTITY_LABELS: Record<string, string> = {\n 'financial-cap-table': 'Cap Table',\n 'financial-kpis': 'Financial KPIs',\n 'financial-pnl': 'Profit & Loss',\n 'financial-balance-sheet': 'Balance Sheets',\n 'financial-cash-flow': 'Cash Flow',\n 'blog-posts': 'Blog Posts',\n 'product-releases': 'Product Releases',\n 'case-studies': 'Case Studies',\n webinars: 'Webinars',\n events: 'Events',\n podcasts: 'Podcasts',\n}\n\nexport function mapDocSearchResults(docs: DocSearchResult[]): SearchResult[] {\n const entityGroups = new Map<string, DocSearchResult[]>()\n // Track insertion order — groups appear where the FIRST row of that\n // repo appeared in the response.\n const order: Array<\n { type: 'entity'; repo: string } | { type: 'doc'; doc: DocSearchResult }\n > = []\n const seenRepos = new Set<string>()\n\n for (const doc of docs) {\n if (doc.sourceRepo && SEARCH_GROUP_REPOS.has(doc.sourceRepo)) {\n const group = entityGroups.get(doc.sourceRepo) || []\n group.push(doc)\n entityGroups.set(doc.sourceRepo, group)\n if (!seenRepos.has(doc.sourceRepo)) {\n seenRepos.add(doc.sourceRepo)\n order.push({ type: 'entity', repo: doc.sourceRepo })\n }\n } else {\n order.push({ type: 'doc', doc })\n }\n }\n\n const results: SearchResult[] = []\n for (const entry of order) {\n if (entry.type === 'entity') {\n const rows = entityGroups.get(entry.repo)!\n const label = ENTITY_LABELS[entry.repo] || entry.repo\n results.push({\n id: `group-${entry.repo}`,\n title: `${label} (${rows.length} ${rows.length === 1 ? 'record' : 'records'})`,\n path: rows[0].path,\n type: 'file',\n metadata: {\n documentType: rows[0].documentType,\n externalUrl: rows[0].externalUrl,\n sourceRepo: entry.repo,\n id: rows[0].entityId,\n isGroup: true,\n items: rows.map((r) => ({\n name: r.name,\n externalUrl: r.externalUrl,\n id: r.entityId,\n sourceRepo: r.sourceRepo,\n documentType: r.documentType,\n })),\n },\n })\n } else {\n const doc = entry.doc\n const isNonMarkdown = doc.documentType && doc.documentType !== 'markdown'\n results.push({\n id: doc.path,\n title: doc.name,\n description: isNonMarkdown ? doc.name : doc.snippet,\n path: doc.path,\n type: doc.type,\n metadata: {\n matchType: doc.matchType,\n ...(doc.documentType ? { documentType: doc.documentType } : {}),\n ...(doc.externalUrl ? { externalUrl: doc.externalUrl } : {}),\n ...(doc.targetPlatform != null\n ? { targetPlatform: doc.targetPlatform }\n : {}),\n ...(doc.sourceRepo ? { sourceRepo: doc.sourceRepo } : {}),\n ...(doc.entityId ? { id: doc.entityId } : {}),\n },\n })\n }\n }\n\n return results\n}\n","/**\n * Resolve what should happen when the user picks a search result.\n * Returns one of five typed actions so the caller is a single switch.\n *\n * Resolution order:\n * 1. `externalUrl` present → use `decideNewTab` to choose same-tab vs\n * new-tab against the row's `targetPlatform`.\n * 2. Row has `id` + `sourceRepo` + `documentType` → synth an Ask-AI\n * action (entity drill-in via primary key, no URL).\n * 3. Row has only `path` → legacy navigation fallback.\n * 4. Nothing actionable → noop.\n *\n * Lifted from the hub's `hooks/use-docs.ts:resolveSearchResultAction`.\n * Pure — no React, no telemetry.\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { ChatRef } from '../../chat/chat-ref.types'\nimport { decideNewTab } from '../../chat/utils/decide-new-tab'\n\nexport type SearchResultAction =\n | { kind: 'navigate-same-tab'; href: string }\n | { kind: 'navigate-new-tab'; href: string }\n | { kind: 'ask-ai'; detail: { source: string; ref: ChatRef } }\n | { kind: 'route'; path: string }\n | { kind: 'noop' }\n\nexport function resolveSearchResultAction(\n result: SearchResult,\n source: string,\n runtimeMode?: 'host' | 'embed',\n): SearchResultAction {\n const meta = result.metadata ?? {}\n const externalUrl = meta.externalUrl as string | undefined\n if (externalUrl) {\n // Same pure helper `useNavLink` and `useUnifiedNav` call — single\n // decision rule across cards, chips, and autocomplete rows. Thread\n // the caller's `source` as `currentSource` so the platform-vs-\n // platform comparison matches the hub's pre-migration behavior.\n const targetPlatform = meta.targetPlatform as string | null | undefined\n const isNewTab = decideNewTab({\n href: externalUrl,\n targetPlatform,\n surface: 'useUnifiedNav',\n runtimeMode,\n currentSource: source,\n })\n return isNewTab\n ? { kind: 'navigate-new-tab', href: externalUrl }\n : { kind: 'navigate-same-tab', href: externalUrl }\n }\n const rowId = meta.id as string | undefined\n const sourceRepo = meta.sourceRepo as string | undefined\n const documentType = meta.documentType as string | undefined\n if (rowId && sourceRepo && documentType) {\n return {\n kind: 'ask-ai',\n detail: {\n source,\n ref: { type: documentType, id: rowId, title: result.title, url: null },\n },\n }\n }\n if (result.path) {\n return { kind: 'route', path: result.path }\n }\n return { kind: 'noop' }\n}\n","'use client'\n\n/**\n * `useDocSearch` — debounced RAG-search hook against `/api/docs/search`.\n *\n * Pure fetch + navigation glue. Embedders can mount this directly\n * (any host with a reverse-proxy that exposes `/api/docs/search` will\n * work). Hub callers wire it into the lib `<DocSearchBar>` for the\n * canonical typeahead dropdown.\n *\n * ## What moved from hub to lib\n *\n * Lifted from `multi-platform-hub/hooks/use-docs.ts:useDocSearch`. Two\n * hub-only concerns are now optional injection points instead of\n * direct imports:\n *\n * - `useDocNavigation()` (hub's in-page doc-tree swap) → optional\n * `onInPageSwap?: (path: string) => boolean` config callback. When\n * present and returns true, the hook treats a same-origin result\n * click as \"handled in-page\"; when absent or returns false, the\n * hook falls back to `onNavigate(path)` (`router.push` on hub,\n * `window.location.assign` on bare embedders).\n * - `traceCompose` (hub-only telemetry) → dropped. The lib has no\n * equivalent runtime-context yet; bring it back when there is one.\n *\n * Everything else (debounce, `useChatRuntime` for embed-mode short-\n * circuit, embed-shim router, the action-resolver + result-mapper) is\n * now lib-resident.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useRouter } from '../../../embed-shims'\nimport { useDebounce } from '../../../hooks/ui/use-debounce'\nimport { useChatRuntime } from '../../../contexts/chat-runtime-context'\nimport { contentFetch } from '../../../utils/embed-content-fetch'\nimport type { SearchResult } from '../../ui/search-input'\nimport {\n resolveExternalNavigation,\n stripSameOriginToPath,\n NEW_TAB_FEATURES,\n} from '../../chat/utils/chat-nav-resolution'\nimport type { DocSearchResult } from './types'\nimport { mapDocSearchResults } from './map-doc-search-results'\nimport { resolveSearchResultAction } from './resolve-search-result-action'\n\nexport interface UseDocSearchConfig {\n /** Discriminator passed to `/api/docs/search?source=` (e.g.\n * `'openframe'`). Embedders set it to whatever discriminator their\n * reverse-proxy expects. */\n source: string\n /** Base route prefix this search lives under (e.g. `'/onboarding-guides'`).\n * When a result's href starts with `${baseRoute}/`, the hook\n * attempts the optional in-page swap path before falling through\n * to a full nav. */\n baseRoute: string\n /** Imperative navigation fallback. Called when no override\n * (in-page swap, new-tab) applies. Hub callers pass\n * `(path) => router.push(path)`; embedders pass an equivalent. */\n onNavigate: (path: string) => void\n /** Optional `RagTableConfig.id` list to narrow the search to specific\n * tables (e.g. `['onboarding-guides']`). Forwarded to\n * `/api/docs/search?tableIds=…` which intersects with the source's\n * standing set. */\n tableIds?: string[]\n /** Optional in-page swap callback. When the result's href is under\n * `baseRoute` AND this callback returns true, the hook treats the\n * click as handled in-page (no router push). Hub's\n * `<DocumentationSection>` wires this to\n * `useDocNavigation().navigate(path)`. */\n onInPageSwap?: (path: string) => boolean\n /** Optional endpoint override. Defaults to `'/api/docs/search'`\n * (the hub's reverse-proxy route). Embedders with a different\n * path can override. */\n searchEndpoint?: string\n}\n\nexport function useDocSearch(config: UseDocSearchConfig) {\n const {\n source,\n baseRoute,\n onNavigate,\n tableIds,\n onInPageSwap,\n searchEndpoint,\n } = config\n const tableIdsKey = tableIds && tableIds.length > 0 ? tableIds.join(',') : ''\n\n const router = useRouter()\n // Optional chat-runtime read — when present and mode='embed' the\n // search-result row click short-circuits to a new-tab open against\n // the absolutized URL. Null/host preserves today's behavior.\n // Also used as the proxy-prefix fallback for `searchEndpoint`, matching\n // how tickets resolves `findTicketUrl`.\n const runtime = useChatRuntime()\n const resolvedSearchEndpoint =\n searchEndpoint ?? runtime?.endpoints.docsSearchUrl ?? '/api/docs/search'\n\n const [query, setQuery] = useState('')\n const [results, setResults] = useState<SearchResult[]>([])\n const [isFetching, setIsFetching] = useState(false)\n const debouncedQuery = useDebounce(query, 300)\n\n useEffect(() => {\n if (!debouncedQuery || debouncedQuery.trim().length < 2) {\n setResults([])\n setIsFetching(false)\n return\n }\n\n let cancelled = false\n\n async function fetchResults() {\n setIsFetching(true)\n try {\n const params = new URLSearchParams({\n q: debouncedQuery,\n source,\n limit: '10',\n })\n if (tableIdsKey) params.set('tableIds', tableIdsKey)\n\n const response = await contentFetch(`${resolvedSearchEndpoint}?${params.toString()}`)\n if (!response.ok) {\n throw new Error(`Search request failed: ${response.status}`)\n }\n\n const json = await response.json()\n\n if (!cancelled && json.success && Array.isArray(json.data)) {\n const mapped = mapDocSearchResults(json.data as DocSearchResult[])\n setResults(mapped)\n }\n } catch (error) {\n console.error('Doc search error:', error)\n if (!cancelled) {\n setResults([])\n }\n } finally {\n if (!cancelled) {\n setIsFetching(false)\n }\n }\n }\n\n fetchResults()\n\n return () => {\n cancelled = true\n }\n }, [debouncedQuery, source, tableIdsKey, resolvedSearchEndpoint])\n\n // Derived loading state — single source of truth for \"should the\n // dropdown show 'Loading...' instead of 'No results found'\":\n const isLoading =\n query.trim().length >= 2 && (query !== debouncedQuery || isFetching)\n\n // Track whether dropdown should stay open (external link opened in new tab).\n const [keepOpen, setKeepOpen] = useState(false)\n\n const handleResultSelect = useCallback(\n (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => {\n const action = resolveSearchResultAction(\n result,\n source,\n runtime?.navigation.mode,\n )\n // Modifier / non-primary mouse click → force new tab regardless of\n // same-tab/new-tab decision. The dropdown row is a `<div>`, not an\n // `<a target=\"_blank\">`, so the browser doesn't background-tab\n // natively on cmd-click. Honor it explicitly here for parity with\n // the anchor-based surfaces (cards, chips, related-content). Plain\n // Enter from the keyboard passes `modifiers === undefined`.\n const wantsNewTab =\n modifiers &&\n (modifiers.metaKey ||\n modifiers.ctrlKey ||\n modifiers.shiftKey ||\n modifiers.altKey ||\n (typeof modifiers.button === 'number' && modifiers.button !== 0))\n switch (action.kind) {\n case 'navigate-same-tab': {\n // Embed-mode short-circuit — autocomplete row clicked while\n // the chat panel is hosted inside an embedding app.\n if (runtime?.navigation.mode === 'embed') {\n setKeepOpen(true)\n const targetPlatform =\n (result.metadata?.targetPlatform as string | null | undefined) ?? null\n resolveExternalNavigation({\n href: action.href,\n targetPlatform,\n runtime,\n }).open()\n return\n }\n if (wantsNewTab) {\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n }\n // Same-origin click:\n // 1. If the href is under the current doc-tree's baseRoute AND\n // an `onInPageSwap` callback is wired AND returns true →\n // consider in-page swap handled.\n // 2. Otherwise → embed-shim `router.push()` (soft RSC nav on\n // Next.js hosts, window.location.assign on bare hosts).\n setKeepOpen(false)\n const path =\n baseRoute && action.href.startsWith(`${baseRoute}/`)\n ? action.href.slice(baseRoute.length + 1)\n : null\n if (path && onInPageSwap?.(path)) return\n router.push(stripSameOriginToPath(action.href))\n return\n }\n case 'navigate-new-tab':\n // Cross-origin (e.g. clicking a flamingo.run release from\n // product-hub) — open in a new tab. Keep dropdown open so the\n // user can pick another result without re-searching.\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n case 'ask-ai':\n // Row is searchable-but-not-openable (cap_table positions,\n // financial-kpi snapshots, anything backed by\n // `resolveUrl: () => null`). Dispatch a CustomEvent that\n // GlobalAskAI listens for — opens chat + drills via\n // `entityIdFilter` (primary-key only, same as inline-card Ask).\n setKeepOpen(false)\n window.dispatchEvent(\n new CustomEvent('ask-ai:open-with-ref', { detail: action.detail }),\n )\n return\n case 'route':\n // Final fallback: legacy navigation by path. Hits when a row\n // has neither URL nor pk metadata — a mapper/API regression.\n setKeepOpen(false)\n onNavigate(action.path)\n return\n case 'noop':\n return\n }\n },\n [onNavigate, source, baseRoute, router, onInPageSwap, runtime],\n )\n\n // Reset keepOpen when query changes.\n useEffect(() => {\n setKeepOpen(false)\n }, [query])\n\n return {\n query,\n setQuery,\n results,\n isLoading,\n handleResultSelect,\n keepDropdownOpen: keepOpen,\n }\n}\n"]}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
TASK_TYPE_TEXT_COLORS,
|
|
12
12
|
getStatusColorScheme,
|
|
13
13
|
init_pagination
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-WH2NO3ED.js";
|
|
15
15
|
import {
|
|
16
16
|
init_next_navigation,
|
|
17
17
|
usePathname,
|
|
@@ -460,4 +460,4 @@ export {
|
|
|
460
460
|
DevCardRowSkeletonList,
|
|
461
461
|
DeliveryRow
|
|
462
462
|
};
|
|
463
|
-
//# sourceMappingURL=chunk-
|
|
463
|
+
//# sourceMappingURL=chunk-B6XC2A2D.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
formatFileSize,
|
|
5
5
|
toGoogleSheetsEmbedUrl,
|
|
6
6
|
toGoogleSheetsOriginalUrl
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WH2NO3ED.js";
|
|
8
8
|
import {
|
|
9
9
|
AdobePdfIcon,
|
|
10
10
|
GoogleSheetsIcon
|
|
@@ -141,4 +141,4 @@ export {
|
|
|
141
141
|
GoogleSheetsViewer,
|
|
142
142
|
FileDownloadCard
|
|
143
143
|
};
|
|
144
|
-
//# sourceMappingURL=chunk-
|
|
144
|
+
//# sourceMappingURL=chunk-ESK47VJE.js.map
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunk7FTBFI4Ecjs = require('./chunk-7FTBFI4E.cjs');
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _chunk7QSHY7TWcjs = require('./chunk-7QSHY7TW.cjs');
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
var _chunkLEAQNU26cjs = require('./chunk-LEAQNU26.cjs');
|
|
@@ -40,7 +40,7 @@ var _chunkLEAQNU26cjs = require('./chunk-LEAQNU26.cjs');
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
var
|
|
43
|
+
var _chunkL7V3FTQHcjs = require('./chunk-L7V3FTQH.cjs');
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
|
|
@@ -171,7 +171,7 @@ function PersistentPaginationWrapper({
|
|
|
171
171
|
const displayCurrentPage = hasResults ? currentPage : 1;
|
|
172
172
|
const isPaginationDisabled = isLoading;
|
|
173
173
|
const hasNoResults = !hasResults && !isLoading;
|
|
174
|
-
const PaginationComponent = (
|
|
174
|
+
const PaginationComponent = (_chunk7FTBFI4Ecjs.init_unified_pagination.call(void 0, ), _chunkVRHGVLSLcjs.__toCommonJS.call(void 0, _chunk7FTBFI4Ecjs.unified_pagination_exports)).UnifiedPagination;
|
|
175
175
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
176
176
|
"div",
|
|
177
177
|
{
|
|
@@ -230,8 +230,8 @@ function PersistentPaginationWrapper({
|
|
|
230
230
|
_chunkFIG2RKZFcjs.init_cn.call(void 0, );
|
|
231
231
|
|
|
232
232
|
var DEFAULT_ENDPOINT = "/api/releases";
|
|
233
|
-
var DEFAULT_SEARCH_PARAM_KEY =
|
|
234
|
-
var DEFAULT_STATUS_PARAM_KEY =
|
|
233
|
+
var DEFAULT_SEARCH_PARAM_KEY = _chunkL7V3FTQHcjs.DEV_SECTION_PARAM_KEYS.search;
|
|
234
|
+
var DEFAULT_STATUS_PARAM_KEY = _chunkL7V3FTQHcjs.DEV_SECTION_PARAM_KEYS.releaseStatus;
|
|
235
235
|
var DEFAULT_PAGE_PARAM_KEY = "page";
|
|
236
236
|
function ReleaseRow({
|
|
237
237
|
release,
|
|
@@ -240,17 +240,17 @@ function ReleaseRow({
|
|
|
240
240
|
}) {
|
|
241
241
|
const runtime = _chunk3KEBI6TPcjs.useChatRuntime.call(void 0, );
|
|
242
242
|
const router = _chunkG7UE6RKVcjs.useRouter.call(void 0, );
|
|
243
|
-
const cta =
|
|
243
|
+
const cta = _chunkL7V3FTQHcjs.resolveContentHref.call(void 0, _optionalChain([runtime, 'optionalAccess', _2 => _2.composeContentUrl]), {
|
|
244
244
|
type: "product_release",
|
|
245
245
|
slug: release.slug,
|
|
246
246
|
basePath,
|
|
247
247
|
platforms: release.product_release_platforms
|
|
248
248
|
});
|
|
249
|
-
const { target, rel } =
|
|
249
|
+
const { target, rel } = _chunkL7V3FTQHcjs.useEntityCardLink.call(void 0, { href: cta.href, targetPlatform: cta.targetPlatform });
|
|
250
250
|
const onClick = (e) => {
|
|
251
|
-
if (e.defaultPrevented ||
|
|
251
|
+
if (e.defaultPrevented || _chunkL7V3FTQHcjs.isModifierClick.call(void 0, e) || target === "_blank") return;
|
|
252
252
|
e.preventDefault();
|
|
253
|
-
|
|
253
|
+
_chunkL7V3FTQHcjs.executeNavigationImperative.call(void 0, {
|
|
254
254
|
runtime,
|
|
255
255
|
href: cta.href,
|
|
256
256
|
targetPlatform: cta.targetPlatform,
|
|
@@ -258,7 +258,7 @@ function ReleaseRow({
|
|
|
258
258
|
});
|
|
259
259
|
};
|
|
260
260
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
261
|
-
|
|
261
|
+
_chunkL7V3FTQHcjs.ProductReleaseCard,
|
|
262
262
|
{
|
|
263
263
|
size: "lg",
|
|
264
264
|
title: release.title,
|
|
@@ -274,7 +274,7 @@ function ProductReleasesView({
|
|
|
274
274
|
initialData,
|
|
275
275
|
itemsPerPage = 5,
|
|
276
276
|
basePath = "/releases",
|
|
277
|
-
buildCardProps =
|
|
277
|
+
buildCardProps = _chunkL7V3FTQHcjs.buildProductReleaseCardProps,
|
|
278
278
|
searchParamKey = DEFAULT_SEARCH_PARAM_KEY,
|
|
279
279
|
statusParamKey = DEFAULT_STATUS_PARAM_KEY,
|
|
280
280
|
pageParamKey = DEFAULT_PAGE_PARAM_KEY,
|
|
@@ -312,10 +312,10 @@ function ProductReleasesView({
|
|
|
312
312
|
router.replace(`${pathname}?${params.toString()}`, { scroll: false });
|
|
313
313
|
};
|
|
314
314
|
if (error) {
|
|
315
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "w-full", className), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
315
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "w-full", className), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.LoadError, { message: "Failed to load releases.", onRetry: reload }) });
|
|
316
316
|
}
|
|
317
317
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkFIG2RKZFcjs.cn.call(void 0, "w-full flex flex-col gap-[40px]", className), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-[600px]", children: showEmpty ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[600px] flex items-center justify-center", children: hasActiveFilters ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
318
|
-
|
|
318
|
+
_chunk7FTBFI4Ecjs.EmptyState,
|
|
319
319
|
{
|
|
320
320
|
type: "search",
|
|
321
321
|
title: "No releases found",
|
|
@@ -325,7 +325,7 @@ function ProductReleasesView({
|
|
|
325
325
|
onCtaClick: resetFilters
|
|
326
326
|
}
|
|
327
327
|
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
328
|
-
|
|
328
|
+
_chunk7FTBFI4Ecjs.EmptyState,
|
|
329
329
|
{
|
|
330
330
|
type: "generic",
|
|
331
331
|
title: "No releases available",
|
|
@@ -340,7 +340,7 @@ function ProductReleasesView({
|
|
|
340
340
|
"div",
|
|
341
341
|
{
|
|
342
342
|
style: { visibility: isLoading || hasData ? "visible" : "hidden" },
|
|
343
|
-
children: isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
343
|
+
children: isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.ProductReleaseCardSkeleton, { size: "lg" }) : release ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ReleaseRow, { release, basePath, buildCardProps }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.ProductReleaseCardSkeleton, { size: "lg" })
|
|
344
344
|
},
|
|
345
345
|
_nullishCoalesce(_optionalChain([release, 'optionalAccess', _5 => _5.id]), () => ( `slot-${i}`))
|
|
346
346
|
);
|
|
@@ -388,10 +388,10 @@ function MediaGalleryStrip({ items, className }) {
|
|
|
388
388
|
mediaItem.id || index
|
|
389
389
|
);
|
|
390
390
|
}
|
|
391
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: tileClass, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
391
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: tileClass, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.Video, { url: mediaItem.media_url, layout: "native" }) }, mediaItem.id || index);
|
|
392
392
|
}) }),
|
|
393
393
|
galleryImages.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
394
|
-
|
|
394
|
+
_chunkL7V3FTQHcjs.ImageGalleryModal,
|
|
395
395
|
{
|
|
396
396
|
images: galleryImages,
|
|
397
397
|
isOpen: galleryOpen,
|
|
@@ -408,7 +408,7 @@ _chunkG7UE6RKVcjs.init_next_navigation.call(void 0, );
|
|
|
408
408
|
|
|
409
409
|
var _lucidereact = require('lucide-react');
|
|
410
410
|
|
|
411
|
-
var DefaultMarkdownRenderer =
|
|
411
|
+
var DefaultMarkdownRenderer = _chunkL7V3FTQHcjs.RichMarkdownRenderer;
|
|
412
412
|
function ReleaseDetailPage({
|
|
413
413
|
authorHref,
|
|
414
414
|
slug,
|
|
@@ -426,7 +426,7 @@ function ReleaseDetailPage({
|
|
|
426
426
|
shell = true
|
|
427
427
|
}) {
|
|
428
428
|
const router = _chunkG7UE6RKVcjs.useRouter.call(void 0, );
|
|
429
|
-
const renderShell = (node) => shell ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
429
|
+
const renderShell = (node) => shell ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.PageShell, { children: node }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "page-shell-content", children: node });
|
|
430
430
|
const { data: fetchedRelease, error, isLoading } = useRelease(initialData ? void 0 : slug);
|
|
431
431
|
const release = initialData || fetchedRelease;
|
|
432
432
|
const showBackButton = backButton !== false;
|
|
@@ -470,7 +470,7 @@ function ReleaseDetailPage({
|
|
|
470
470
|
return renderShell(
|
|
471
471
|
// Match the loaded page's top offset (TitleBlock's
|
|
472
472
|
// `pt-[var(--spacing-system-l)]`) so content doesn't jump on load.
|
|
473
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "pt-[var(--spacing-system-l)]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
473
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "pt-[var(--spacing-system-l)]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7QSHY7TWcjs.DetailPageSkeleton, { bare: true, metadataColumns: 4, showImageGallery: true }) })
|
|
474
474
|
);
|
|
475
475
|
}
|
|
476
476
|
if (error || !release) {
|
|
@@ -506,7 +506,7 @@ function ReleaseDetailPage({
|
|
|
506
506
|
const improvements = release.improvements;
|
|
507
507
|
return renderShell(
|
|
508
508
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
509
|
-
|
|
509
|
+
_chunkL7V3FTQHcjs.PageLayout,
|
|
510
510
|
{
|
|
511
511
|
title: releaseTitle,
|
|
512
512
|
subtitle: `Version: ${releaseVersion}`,
|
|
@@ -515,7 +515,7 @@ function ReleaseDetailPage({
|
|
|
515
515
|
backButton: showBackButton ? { label: backLabel, onClick: () => router.push(backHref) } : void 0,
|
|
516
516
|
children: [
|
|
517
517
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6 md:space-y-8", children: [
|
|
518
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
518
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.EntityTagBadges, { tags: release.product_release_tags }),
|
|
519
519
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-1 md:grid-cols-4 border border-ods-border rounded-md overflow-hidden w-full", children: [
|
|
520
520
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-ods-card border-b md:border-b-0 md:border-r border-ods-border p-4 flex flex-col gap-3", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-0", children: [
|
|
521
521
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h4 text-ods-text-primary", children: releaseType.toLocaleUpperCase() }),
|
|
@@ -526,11 +526,11 @@ function ReleaseDetailPage({
|
|
|
526
526
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-['DM_Sans'] font-medium text-[14px] leading-[20px] text-ods-text-secondary", children: "Release Status" })
|
|
527
527
|
] }) }),
|
|
528
528
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-ods-card border-b md:border-b-0 md:border-r border-ods-border p-4 flex flex-col gap-3", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-0", children: [
|
|
529
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h4 text-ods-text-primary", children:
|
|
529
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h4 text-ods-text-primary", children: _chunkL7V3FTQHcjs.formatReleaseDate.call(void 0, releaseDate) }),
|
|
530
530
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-['DM_Sans'] font-medium text-[14px] leading-[20px] text-ods-text-secondary", children: "Release Date" })
|
|
531
531
|
] }) }),
|
|
532
532
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
533
|
-
|
|
533
|
+
_chunkL7V3FTQHcjs.EntityMetadataAuthorCell,
|
|
534
534
|
{
|
|
535
535
|
author: _nullishCoalesce(author, () => ( { full_name: null, avatar_url: null })),
|
|
536
536
|
authorHref: _optionalChain([author, 'optionalAccess', _6 => _6.full_name]) ? authorHref : void 0
|
|
@@ -555,7 +555,7 @@ function ReleaseDetailPage({
|
|
|
555
555
|
}
|
|
556
556
|
) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
557
557
|
youtubeUrl && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
558
|
-
|
|
558
|
+
_chunkL7V3FTQHcjs.Video,
|
|
559
559
|
{
|
|
560
560
|
kind: "youtube",
|
|
561
561
|
url: youtubeUrl,
|
|
@@ -564,7 +564,7 @@ function ReleaseDetailPage({
|
|
|
564
564
|
}
|
|
565
565
|
),
|
|
566
566
|
!youtubeUrl && mainVideoUrl && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
567
|
-
|
|
567
|
+
_chunkL7V3FTQHcjs.Video,
|
|
568
568
|
{
|
|
569
569
|
url: mainVideoUrl,
|
|
570
570
|
srtContent: _optionalChain([release, 'optionalAccess', _9 => _9.srt_content]),
|
|
@@ -573,7 +573,7 @@ function ReleaseDetailPage({
|
|
|
573
573
|
}
|
|
574
574
|
),
|
|
575
575
|
highlightVideoUrl && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
576
|
-
|
|
576
|
+
_chunkL7V3FTQHcjs.Video,
|
|
577
577
|
{
|
|
578
578
|
url: highlightVideoUrl,
|
|
579
579
|
poster: highlightVideoThumbnail,
|
|
@@ -582,7 +582,7 @@ function ReleaseDetailPage({
|
|
|
582
582
|
)
|
|
583
583
|
] }),
|
|
584
584
|
releaseContent && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-h4 text-ods-text-primary", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MarkdownRenderer, { content: releaseContent }) }),
|
|
585
|
-
hasBreakingChanges && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
585
|
+
hasBreakingChanges && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.Card, { className: "border-red-500 bg-red-500/10", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.CardContent, { className: "p-6", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3", children: [
|
|
586
586
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AlertTriangle, { className: "h-6 w-6 text-red-500" }),
|
|
587
587
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
588
588
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-bold text-red-500 text-lg", children: "Breaking Changes" }),
|
|
@@ -590,7 +590,7 @@ function ReleaseDetailPage({
|
|
|
590
590
|
] })
|
|
591
591
|
] }) }) }),
|
|
592
592
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
593
|
-
|
|
593
|
+
_chunkL7V3FTQHcjs.ReleaseChangelogSection,
|
|
594
594
|
{
|
|
595
595
|
title: "Breaking Changes",
|
|
596
596
|
entries: breakingChanges || [],
|
|
@@ -601,7 +601,7 @@ function ReleaseDetailPage({
|
|
|
601
601
|
}
|
|
602
602
|
),
|
|
603
603
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
604
|
-
|
|
604
|
+
_chunkL7V3FTQHcjs.ReleaseChangelogSection,
|
|
605
605
|
{
|
|
606
606
|
title: "Features Added",
|
|
607
607
|
entries: featuresAdded || [],
|
|
@@ -611,7 +611,7 @@ function ReleaseDetailPage({
|
|
|
611
611
|
}
|
|
612
612
|
),
|
|
613
613
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
614
|
-
|
|
614
|
+
_chunkL7V3FTQHcjs.ReleaseChangelogSection,
|
|
615
615
|
{
|
|
616
616
|
title: "Bugs Fixed",
|
|
617
617
|
entries: bugFixed || [],
|
|
@@ -621,7 +621,7 @@ function ReleaseDetailPage({
|
|
|
621
621
|
}
|
|
622
622
|
),
|
|
623
623
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
624
|
-
|
|
624
|
+
_chunkL7V3FTQHcjs.ReleaseChangelogSection,
|
|
625
625
|
{
|
|
626
626
|
title: "Improvements",
|
|
627
627
|
entries: improvements || [],
|
|
@@ -660,7 +660,7 @@ function ReleaseDetailPage({
|
|
|
660
660
|
(() => {
|
|
661
661
|
const deliveryCount = deliveryData ? deliveryData.completed.length + deliveryData.inProgress.length : 0;
|
|
662
662
|
return deliveryLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DeliverySection, { data: deliveryData, isLoading: deliveryLoading }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
663
|
-
|
|
663
|
+
_chunkL7V3FTQHcjs.FadePreview,
|
|
664
664
|
{
|
|
665
665
|
hiddenCount: deliveryCount - 1,
|
|
666
666
|
collapsedHeight: 300,
|
|
@@ -672,7 +672,7 @@ function ReleaseDetailPage({
|
|
|
672
672
|
] }),
|
|
673
673
|
(_optionalChain([githubReleases, 'optionalAccess', _11 => _11.length]) || _optionalChain([knowledgeBaseLinks, 'optionalAccess', _12 => _12.length]) || migrationGuideUrl || documentationUrl) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-1 w-full", children: [
|
|
674
674
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-h5 tracking-[-0.28px] text-ods-text-secondary", children: "Related Links" }),
|
|
675
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
675
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.Card, { className: "bg-ods-card border-ods-border p-6", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-4", children: [
|
|
676
676
|
githubReleases && githubReleases.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: githubReleases.map((ghRelease) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-start gap-1", children: [
|
|
677
677
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkLWNPMLIHcjs.GitHubIcon, { className: "shrink-0", width: 24, height: 24, color: "var(--color-text-secondary)" }),
|
|
678
678
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-h4 text-ods-text-primary", children: "Github Release" }),
|
|
@@ -746,7 +746,7 @@ function ReleaseDetailPage({
|
|
|
746
746
|
// src/components/shared/product-release/release-detail-skeleton.tsx
|
|
747
747
|
|
|
748
748
|
function ReleaseDetailSkeleton() {
|
|
749
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
749
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7QSHY7TWcjs.DetailPageSkeleton, { metadataColumns: 4, showImageGallery: true });
|
|
750
750
|
}
|
|
751
751
|
|
|
752
752
|
// src/components/shared/roadmap/use-roadmap-voting.ts
|
|
@@ -907,10 +907,10 @@ function RoadmapGridSingle({
|
|
|
907
907
|
// `useScrollToHash` in `roadmap-view.tsx` finds the card by id
|
|
908
908
|
// and scrolls.
|
|
909
909
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
910
|
-
|
|
910
|
+
_chunkL7V3FTQHcjs.RoadmapCard,
|
|
911
911
|
{
|
|
912
912
|
item,
|
|
913
|
-
id:
|
|
913
|
+
id: _chunkL7V3FTQHcjs.devSectionAnchorId.call(void 0, "roadmap", item.id),
|
|
914
914
|
userVote: getVote(item.id),
|
|
915
915
|
onVote: (voteType) => onVote(item.id, voteType),
|
|
916
916
|
isVoting: votingTasks.has(item.id)
|
|
@@ -990,7 +990,7 @@ function RoadmapGrid({
|
|
|
990
990
|
}, [hasActiveFilters, sortedQuartersKey, isInitialized, quartersToKeepClosed]);
|
|
991
991
|
if (items.length === 0) {
|
|
992
992
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
993
|
-
|
|
993
|
+
_chunk7FTBFI4Ecjs.EmptyState,
|
|
994
994
|
{
|
|
995
995
|
type: "generic",
|
|
996
996
|
title: "No roadmap items",
|
|
@@ -1011,7 +1011,7 @@ function RoadmapGrid({
|
|
|
1011
1011
|
);
|
|
1012
1012
|
}
|
|
1013
1013
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1014
|
-
|
|
1014
|
+
_chunkL7V3FTQHcjs.Accordion,
|
|
1015
1015
|
{
|
|
1016
1016
|
type: "multiple",
|
|
1017
1017
|
value: expandedQuarters,
|
|
@@ -1021,13 +1021,13 @@ function RoadmapGrid({
|
|
|
1021
1021
|
const itemCount = _optionalChain([itemsByQuarter, 'access', _21 => _21[quarter], 'optionalAccess', _22 => _22.length]) || 0;
|
|
1022
1022
|
const isExpanded = expandedQuarters.includes(quarter);
|
|
1023
1023
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1024
|
-
|
|
1024
|
+
_chunkL7V3FTQHcjs.AccordionItem,
|
|
1025
1025
|
{
|
|
1026
1026
|
value: quarter,
|
|
1027
1027
|
id: `quarter-${quarter.replace(/\s+/g, "-").toLowerCase()}`,
|
|
1028
1028
|
className: "border-0",
|
|
1029
1029
|
children: [
|
|
1030
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1030
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.AccordionTrigger, { className: "w-full p-0 hover:no-underline [&>svg]:h-5 [&>svg]:w-5 [&>svg]:text-ods-text-secondary [&>svg]:ml-auto [&>svg]:shrink-0", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3", children: [
|
|
1031
1031
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1032
1032
|
"h3",
|
|
1033
1033
|
{
|
|
@@ -1057,7 +1057,7 @@ function RoadmapGrid({
|
|
|
1057
1057
|
}
|
|
1058
1058
|
)
|
|
1059
1059
|
] }) }),
|
|
1060
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1060
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.AccordionContent, { className: "pt-4 pb-0 overflow-hidden data-[state=closed]:animate-none data-[state=open]:animate-none", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1061
1061
|
RoadmapGridSingle,
|
|
1062
1062
|
{
|
|
1063
1063
|
items: itemsByQuarter[quarter],
|
|
@@ -1108,8 +1108,8 @@ function RoadmapGridSkeleton({ count = 4, showLeftMargin = true }) {
|
|
|
1108
1108
|
|
|
1109
1109
|
|
|
1110
1110
|
var DEFAULT_ENDPOINT2 = "/api/roadmap";
|
|
1111
|
-
var DEFAULT_SEARCH_PARAM_KEY2 =
|
|
1112
|
-
var DEFAULT_STATUS_PARAM_KEY2 =
|
|
1111
|
+
var DEFAULT_SEARCH_PARAM_KEY2 = _chunkL7V3FTQHcjs.DEV_SECTION_PARAM_KEYS.search;
|
|
1112
|
+
var DEFAULT_STATUS_PARAM_KEY2 = _chunkL7V3FTQHcjs.DEV_SECTION_PARAM_KEYS.status;
|
|
1113
1113
|
function RoadmapView({
|
|
1114
1114
|
endpoint = DEFAULT_ENDPOINT2,
|
|
1115
1115
|
initialItems,
|
|
@@ -1135,7 +1135,7 @@ function RoadmapView({
|
|
|
1135
1135
|
const items = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _23 => _23.items]), () => ( []));
|
|
1136
1136
|
_chunk6PHV4NREcjs.useScrollToHash.call(void 0, data, { headerOffset: _chunk6PHV4NREcjs.STICKY_HEADER_OFFSET_PX });
|
|
1137
1137
|
if (error) {
|
|
1138
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1138
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.LoadError, { message: "Failed to load roadmap.", onRetry: reload });
|
|
1139
1139
|
}
|
|
1140
1140
|
if (isLoading && !data) {
|
|
1141
1141
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RoadmapGridSkeleton, { showLeftMargin });
|
|
@@ -1192,7 +1192,7 @@ function DeliveryTable({ items, isLoading = false }) {
|
|
|
1192
1192
|
"div",
|
|
1193
1193
|
{
|
|
1194
1194
|
className: "border-b border-ods-border last:border-b-0",
|
|
1195
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1195
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7FTBFI4Ecjs.DeliveryRow, { item, id: _chunkL7V3FTQHcjs.devSectionAnchorId.call(void 0, "delivery", item.id) })
|
|
1196
1196
|
},
|
|
1197
1197
|
item.id
|
|
1198
1198
|
)
|
|
@@ -1204,8 +1204,8 @@ function DeliveryTable({ items, isLoading = false }) {
|
|
|
1204
1204
|
|
|
1205
1205
|
var DEFAULT_COMPLETED_ENDPOINT = "/api/delivery/completed";
|
|
1206
1206
|
var DEFAULT_IN_PROGRESS_ENDPOINT = "/api/delivery/in-progress";
|
|
1207
|
-
var DEFAULT_SEARCH_PARAM_KEY3 =
|
|
1208
|
-
var DEFAULT_TASK_TYPE_PARAM_KEY =
|
|
1207
|
+
var DEFAULT_SEARCH_PARAM_KEY3 = _chunkL7V3FTQHcjs.DEV_SECTION_PARAM_KEYS.search;
|
|
1208
|
+
var DEFAULT_TASK_TYPE_PARAM_KEY = _chunkL7V3FTQHcjs.DEV_SECTION_PARAM_KEYS.deliveryTaskType;
|
|
1209
1209
|
function DeliveryLists({
|
|
1210
1210
|
completedApiEndpoint = DEFAULT_COMPLETED_ENDPOINT,
|
|
1211
1211
|
inProgressApiEndpoint = DEFAULT_IN_PROGRESS_ENDPOINT,
|
|
@@ -1266,11 +1266,11 @@ function DeliveryLists({
|
|
|
1266
1266
|
const hasActiveFilters = searchQuery !== "" || taskTypeFilter !== "all";
|
|
1267
1267
|
const hasResults = showCompleted && filteredCompleted.length > 0 || showInProgress && filteredInProgress.length > 0;
|
|
1268
1268
|
if (error) {
|
|
1269
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1269
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.LoadError, { message: error, onRetry: () => window.location.reload() }) });
|
|
1270
1270
|
}
|
|
1271
1271
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "w-full flex flex-col gap-[40px]", children: [
|
|
1272
1272
|
!isLoading && !hasResults && (hasActiveFilters ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1273
|
-
|
|
1273
|
+
_chunk7FTBFI4Ecjs.EmptyState,
|
|
1274
1274
|
{
|
|
1275
1275
|
type: "search",
|
|
1276
1276
|
title: "No tasks found",
|
|
@@ -1285,7 +1285,7 @@ function DeliveryLists({
|
|
|
1285
1285
|
}
|
|
1286
1286
|
}
|
|
1287
1287
|
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1288
|
-
|
|
1288
|
+
_chunk7FTBFI4Ecjs.EmptyState,
|
|
1289
1289
|
{
|
|
1290
1290
|
type: "generic",
|
|
1291
1291
|
title: "No tasks available",
|
|
@@ -1387,7 +1387,7 @@ function LegalDocumentPage({
|
|
|
1387
1387
|
initialData = null,
|
|
1388
1388
|
initialLastUpdatedLabel = null,
|
|
1389
1389
|
apiEndpoint,
|
|
1390
|
-
MarkdownRenderer =
|
|
1390
|
+
MarkdownRenderer = _chunkL7V3FTQHcjs.RichMarkdownRenderer,
|
|
1391
1391
|
backButton,
|
|
1392
1392
|
shell = true
|
|
1393
1393
|
}) {
|
|
@@ -1397,10 +1397,10 @@ function LegalDocumentPage({
|
|
|
1397
1397
|
label: _nullishCoalesce(_optionalChain([backButton, 'optionalAccess', _26 => _26.label]), () => ( "Back to home")),
|
|
1398
1398
|
onClick: () => router.push(_nullishCoalesce(_optionalChain([backButton, 'optionalAccess', _27 => _27.href]), () => ( "/")))
|
|
1399
1399
|
};
|
|
1400
|
-
const fallbackLastUpdatedLabel = _optionalChain([data, 'optionalAccess', _28 => _28.lastSynced]) != null ?
|
|
1400
|
+
const fallbackLastUpdatedLabel = _optionalChain([data, 'optionalAccess', _28 => _28.lastSynced]) != null ? _chunkL7V3FTQHcjs.formatLegalDate.call(void 0, data.lastSynced) : null;
|
|
1401
1401
|
const effectiveLastUpdatedLabel = _nullishCoalesce(initialLastUpdatedLabel, () => ( fallbackLastUpdatedLabel));
|
|
1402
1402
|
const subtitle = effectiveLastUpdatedLabel ? `Last Updated: ${effectiveLastUpdatedLabel}` : fallbackDescription;
|
|
1403
|
-
const inner = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1403
|
+
const inner = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkL7V3FTQHcjs.PageLayout, { title, subtitle, backButton: backCfg, titleSize: "h1", titleWrap: true, children: [
|
|
1404
1404
|
_optionalChain([data, 'optionalAccess', _29 => _29.sourceFile]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "font-['DM_Sans'] text-sm text-ods-text-secondary opacity-75", children: [
|
|
1405
1405
|
"Source: ",
|
|
1406
1406
|
data.sourceFile
|
|
@@ -1447,7 +1447,7 @@ function LegalDocumentPage({
|
|
|
1447
1447
|
] })
|
|
1448
1448
|
] }) }) }) }) })
|
|
1449
1449
|
] });
|
|
1450
|
-
return shell ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1450
|
+
return shell ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkL7V3FTQHcjs.PageShell, { children: inner }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "page-shell-content", children: inner });
|
|
1451
1451
|
}
|
|
1452
1452
|
|
|
1453
1453
|
|
|
@@ -1467,4 +1467,4 @@ function LegalDocumentPage({
|
|
|
1467
1467
|
|
|
1468
1468
|
|
|
1469
1469
|
exports.PersistentPagination = PersistentPagination; exports.usePaginationLoading = usePaginationLoading; exports.PersistentPaginationWrapper = PersistentPaginationWrapper; exports.ProductReleasesView = ProductReleasesView; exports.MediaGalleryStrip = MediaGalleryStrip; exports.ReleaseDetailPage = ReleaseDetailPage; exports.ReleaseDetailSkeleton = ReleaseDetailSkeleton; exports.useRoadmapVoting = useRoadmapVoting; exports.RoadmapGrid = RoadmapGrid; exports.RoadmapGridSkeleton = RoadmapGridSkeleton; exports.RoadmapView = RoadmapView; exports.DeliveryTable = DeliveryTable; exports.DeliveryLists = DeliveryLists; exports.useLegalDocs = useLegalDocs; exports.LegalDocumentPage = LegalDocumentPage;
|
|
1470
|
-
//# sourceMappingURL=chunk-
|
|
1470
|
+
//# sourceMappingURL=chunk-F5JNT3M6.cjs.map
|