@bikdotai/bik-component-library 0.0.850-beta.2 → 0.0.850-beta.4
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/cjs/assets/icons/ShipStation.svg.js +1 -1
- package/dist/cjs/assets/icons/ShipStation.svg.js.map +1 -1
- package/dist/cjs/components/agent-builder/AgentBuilder.styled.js +0 -1
- package/dist/cjs/components/agent-builder/AgentBuilder.styled.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/DiscardModal.js +1 -1
- package/dist/cjs/components/agent-builder/components/DiscardModal.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/GoLiveModal.js +1 -1
- package/dist/cjs/components/agent-builder/components/GoLiveModal.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionEditor.js +1 -1
- package/dist/cjs/components/agent-builder/components/MentionEditor.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionPicker.js +32 -24
- package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/cjs/components/agent-listing/AgentListing.js +1 -1
- package/dist/cjs/components/agent-listing/AgentListing.js.map +1 -1
- package/dist/cjs/components/agent-listing/AiAgentsEmptyState.js +2 -0
- package/dist/cjs/components/agent-listing/AiAgentsEmptyState.js.map +1 -0
- package/dist/cjs/editor/BikEditor.js +1 -1
- package/dist/cjs/editor/BikEditor.js.map +1 -1
- package/dist/cjs/editor/BikEditor.styles.js +17 -12
- package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
- package/dist/cjs/editor/BikEditor.types.js.map +1 -1
- package/dist/cjs/editor/extensions/buildExtensions.js +2 -2
- package/dist/cjs/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/cjs/editor/extensions/characterLimit/CharacterLimitExtension.js +3 -3
- package/dist/cjs/editor/extensions/characterLimit/CharacterLimitExtension.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/assets/icons/ShipStation.svg.js +2 -2
- package/dist/esm/assets/icons/ShipStation.svg.js.map +1 -1
- package/dist/esm/assets/icons/index.d.ts +1 -0
- package/dist/esm/components/agent-builder/AgentBuilder.styled.js +4 -5
- package/dist/esm/components/agent-builder/AgentBuilder.styled.js.map +1 -1
- package/dist/esm/components/agent-builder/components/DiscardModal.js +57 -49
- package/dist/esm/components/agent-builder/components/DiscardModal.js.map +1 -1
- package/dist/esm/components/agent-builder/components/GoLiveModal.js +26 -22
- package/dist/esm/components/agent-builder/components/GoLiveModal.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionEditor.js +24 -23
- package/dist/esm/components/agent-builder/components/MentionEditor.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionPicker.js +81 -73
- package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/esm/components/agent-listing/AgentListing.js +68 -74
- package/dist/esm/components/agent-listing/AgentListing.js.map +1 -1
- package/dist/esm/components/agent-listing/AiAgentsEmptyState.d.ts +22 -0
- package/dist/esm/components/agent-listing/AiAgentsEmptyState.js +22 -0
- package/dist/esm/components/agent-listing/AiAgentsEmptyState.js.map +1 -0
- package/dist/esm/editor/BikEditor.js +70 -68
- package/dist/esm/editor/BikEditor.js.map +1 -1
- package/dist/esm/editor/BikEditor.styles.js +20 -15
- package/dist/esm/editor/BikEditor.styles.js.map +1 -1
- package/dist/esm/editor/BikEditor.types.d.ts +10 -0
- package/dist/esm/editor/BikEditor.types.js.map +1 -1
- package/dist/esm/editor/extensions/buildExtensions.d.ts +6 -0
- package/dist/esm/editor/extensions/buildExtensions.js +20 -15
- package/dist/esm/editor/extensions/buildExtensions.js.map +1 -1
- package/dist/esm/editor/extensions/characterLimit/CharacterLimitExtension.d.ts +20 -3
- package/dist/esm/editor/extensions/characterLimit/CharacterLimitExtension.js +40 -25
- package/dist/esm/editor/extensions/characterLimit/CharacterLimitExtension.js.map +1 -1
- package/dist/esm/index.js +761 -759
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MentionPicker.js","sources":["../../../../../src/components/agent-builder/components/MentionPicker.tsx"],"sourcesContent":["// import ChevronLeft from '@src/assets/icons/chevronLeft.svg';\nimport ChevronRight from '@src/assets/icons/chevronRight.svg';\nimport SearchIcon from '@src/assets/icons/searchIcon.svg';\nimport type { MentionDropdownRenderProps, MentionItem } from '@src/editor';\nimport { Shield } from '@src/icons';\nimport SvgArrowLeft from '@src/icons/Arrows/Normal arrows/ArrowLeft';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tCATEGORIES,\n\tCONFIG_TOOL_SOURCES,\n\tINTEGRATIONS_RANK,\n\tisIntegrationSource,\n\ttoolSourceRank,\n} from '../constants/tools';\nimport type { Category, ToolAction, ToolSource } from '../constants/tools';\nimport {\n\tMentionKindMeta,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport { renderSourceIcon, sourceIcon, SourceIcon } from '../utils/sourceIcons';\n\nconst metaOf = (item: MentionItem): MentionKindMeta | undefined =>\n\titem.meta as unknown as MentionKindMeta | undefined;\n\nconst rowLabel = (item: MentionItem): string =>\n\tmetaOf(item)?.plainLabel ?? item.label;\n\n/** One navigable row in the picker's current view. */\ntype PickerRowModel = {\n\tid: string;\n\tlabel: string;\n\t/** Drill-in rows show a chevron; leaf (selectable) rows do not. */\n\tdrillsIn: boolean;\n\t/** Leading brand glyph (source rows only). */\n\ticon?: SourceIcon;\n\t/** Brand-coloured \"Create new\" action row (not a selectable item). */\n\tisCreate?: boolean;\n\t/**\n\t * Brand-coloured right-aligned action text (e.g. \"Connect\") shown in place of\n\t * the drill-in chevron — used for an unconnected integration source.\n\t */\n\trightLabel?: string;\n\t/** Tool leaf touches customer-private data → shows a shield glyph. */\n\tauthRequired?: boolean;\n\tonActivate: () => void;\n};\n\n/** Sentinel id for the sub-agent \"Create new\" row. */\nconst CREATE_SUBAGENT_ID = '__bik_create_subagent__';\n\ntype MentionPickerProps = MentionDropdownRenderProps & {\n\t/** Opens the create-sub-agent drawer (shows a \"Create new\" row in the Sub-agent view). */\n\tonCreateSubAgent?: () => void;\n\t/**\n\t * Open already drilled into this tool source (e.g. `'shopify'`) — its tool list\n\t * is shown immediately. */\n\tinitialSource?: string;\n\t/**\n\t * Built-in tool actions (Rest API / Handover to email) shown in the Tools view.\n\t * Picking one opens its config drawer (via `onSelect`) and dismisses the picker\n\t * — it never inserts a mention into the text.\n\t */\n\ttoolActions?: ToolAction[];\n\t/**\n\t * Per-source integration connection state. A source whose value is `false`\n\t * renders a \"Connect\" row (like an unconnected action) instead of drilling in —\n\t * so native source groups (Shopify / BigCommerce / ShipStation) show \"Connect\"\n\t * consistently with the config actions (Slack).\n\t */\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\t/** Open the connect flow for an unconnected source (used by the Connect row). */\n\tonConnectIntegration?: (source: ToolSource) => void;\n};\n\n/**\n * `@` reference picker. Drills:\n * root → Tools → <source> (Manifest / Shopify / …) → tool\n * → Sub-agent → sub-agent\n * (\"Add condition\" and \"Variables\" are intentionally not shown yet.)\n *\n * Owns keyboard navigation (↑/↓ move, →/Enter activate, ← go back) over the\n * CURRENTLY visible rows — registered with the editor via `registerKeyHandler`.\n */\nexport const MentionPicker: React.FC<MentionPickerProps> = ({\n\titems,\n\tonSelect,\n\tregisterKeyHandler,\n\tonClose,\n\tonCreateSubAgent,\n\tinitialSource,\n\ttoolActions,\n\tintegrationStatus,\n\tonConnectIntegration,\n}) => {\n\tconst [category, setCategory] = useState<Category | null>(null);\n\tconst [source, setSource] = useState<string | null>(initialSource ?? null);\n\t// Non-null when drilled into the consolidated \"Integrations\" group (its member\n\t// sources are shown; picking one drills into that source's tools as usual).\n\tconst [group, setGroup] = useState<'integrations' | null>(null);\n\t// -1 = nothing highlighted; rows highlight only on hover / arrow keys\n\t// (a default highlight reads as a stuck hover state).\n\tconst [activeIndex, setActiveIndex] = useState(-1);\n\t// Search box shown inside a source's tool list (Manifest / Shopify); filters\n\t// that source's tools by name.\n\tconst [search, setSearch] = useState('');\n\n\tconst tools = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'tool'),\n\t\t[items],\n\t);\n\tconst subAgents = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'subagent'),\n\t\t[items],\n\t);\n\tconst sources = useMemo(() => {\n\t\tconst acc: string[] = [];\n\t\ttools.forEach((t) => {\n\t\t\tconst s = metaOf(t)?.source ?? 'other';\n\t\t\tif (!acc.includes(s)) {\n\t\t\t\tacc.push(s);\n\t\t\t}\n\t\t});\n\t\treturn acc;\n\t}, [tools]);\n\t// The built-in \"create\" action per source (Rest API / email / Slack). A source\n\t// with an action drills into [its instances + a \"Create new\" row] — like the\n\t// Sub-agent category — instead of showing a duplicate flat \"create\" row.\n\tconst actionBySource = useMemo(\n\t\t() =>\n\t\t\tnew Map<string, ToolAction>(\n\t\t\t\t(toolActions ?? []).map((a) => [a.source, a]),\n\t\t\t),\n\t\t[toolActions],\n\t);\n\n\t// Show a category when it has items — and ALWAYS show Sub-agent when creating\n\t// one is possible, so an agent with no sub-agents yet still gets the root\n\t// \"Tools / Sub-agent\" choice (with a \"Create new\" inside). When only one is\n\t// available (e.g. the sub-agent drawer offers tools only) the selector is skipped.\n\tconst availableCategories = useMemo(\n\t\t() =>\n\t\t\tCATEGORIES.filter((c) =>\n\t\t\t\tc.key === 'tool'\n\t\t\t\t\t? tools.length > 0 || (toolActions?.length ?? 0) > 0\n\t\t\t\t\t: subAgents.length > 0 || !!onCreateSubAgent,\n\t\t\t),\n\t\t[tools.length, subAgents.length, onCreateSubAgent, toolActions?.length],\n\t);\n\tconst soleCategory =\n\t\tavailableCategories.length === 1 ? availableCategories[0].key : null;\n\tconst activeCategory = category ?? soleCategory;\n\n\t// Title shown above the current view. `onBack` is omitted at a root level (a\n\t// sole category has nowhere to go back to) — the header then shows as a plain\n\t// title. When `onBack` is set the header leads with a back arrow, followed by\n\t// the source icon in a source detail view: `[← back][icon][title]`.\n\tconst header: {\n\t\ttitle: string;\n\t\tonBack?: () => void;\n\t\ticon?: SourceIcon;\n\t} | null = !activeCategory\n\t\t? null\n\t\t: activeCategory === 'subagent'\n\t\t? // Always titled — with a back arrow only when the category chooser is above.\n\t\t {\n\t\t\t\ttitle: 'Sub-agent',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t }\n\t\t: source\n\t\t? {\n\t\t\t\ttitle: toolSourceLabel(source),\n\t\t\t\t// Deep-linked to a source (opened from a right-panel source button):\n\t\t\t\t// that source IS the root, so no back arrow. Otherwise back clears the\n\t\t\t\t// source — returning to the Integrations group if we came via it (its\n\t\t\t\t// `group` state is untouched), else to the source chooser.\n\t\t\t\tonBack: initialSource ? undefined : () => setSource(null),\n\t\t\t\ticon: sourceIcon(source),\n\t\t }\n\t\t: group === 'integrations'\n\t\t? { title: 'Integrations', onBack: () => setGroup(null) }\n\t\t: // Always titled — matches the Sub-agent header; back arrow only when the\n\t\t // category chooser is above (i.e. not the sole category).\n\t\t {\n\t\t\t\ttitle: 'Tools',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t };\n\n\t// Build the navigable rows for the current view.\n\tconst rows: PickerRowModel[] = useMemo(() => {\n\t\tif (!activeCategory) {\n\t\t\treturn availableCategories.map((c) => ({\n\t\t\t\tid: c.key,\n\t\t\t\tlabel: c.label,\n\t\t\t\tdrillsIn: true,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tsetCategory(c.key);\n\t\t\t\t\tsetSource(null);\n\t\t\t\t\tsetGroup(null);\n\t\t\t\t},\n\t\t\t}));\n\t\t}\n\t\tif (activeCategory === 'subagent') {\n\t\t\tconst sq = search.trim().toLowerCase();\n\t\t\tconst leaves: PickerRowModel[] = subAgents\n\t\t\t\t.filter((item) => !sq || rowLabel(item).toLowerCase().includes(sq))\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tlabel: rowLabel(item),\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t\t}));\n\t\t\t// \"Create new\" opens the drawer — first dismiss the menu (strips the \"@\").\n\t\t\tif (onCreateSubAgent) {\n\t\t\t\tleaves.push({\n\t\t\t\t\tid: CREATE_SUBAGENT_ID,\n\t\t\t\t\tlabel: 'Create new',\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tisCreate: true,\n\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\tonCreateSubAgent();\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn leaves;\n\t\t}\n\t\tif (!source) {\n\t\t\t// The real sources (from instances) plus any action source (Rest API /\n\t\t\t// email / Slack) with no instances yet, so it still appears for first-time\n\t\t\t// creation. Deduped — no more twin rows.\n\t\t\tconst actionOnly = (toolActions ?? [])\n\t\t\t\t.map((a) => a.source)\n\t\t\t\t.filter((s) => !sources.includes(s));\n\t\t\tconst combined = [...sources, ...actionOnly];\n\n\t\t\t// One drill-in row per source: Connect (unconnected) / a single collapsed\n\t\t\t// leaf / a drill-in. Reused at the top level AND inside the Integrations\n\t\t\t// group so both behave identically.\n\t\t\tconst buildSourceRow = (s: string): PickerRowModel => {\n\t\t\t\tconst action = actionBySource.get(s);\n\t\t\t\t// Not connected → a \"Connect\" row (no drill-in / no instances / no\n\t\t\t\t// \"Create new\"); clicking dismisses the picker and runs the connect\n\t\t\t\t// flow. Applies to config actions (their own `connected`) AND native\n\t\t\t\t// source groups (via `integrationStatus`), so both look consistent.\n\t\t\t\tconst connected =\n\t\t\t\t\taction !== undefined\n\t\t\t\t\t\t? action.connected\n\t\t\t\t\t\t: integrationStatus?.[s as ToolSource];\n\t\t\t\tif (connected === false) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: s,\n\t\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\t\trightLabel: 'Connect',\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\tif (action?.onConnect) {\n\t\t\t\t\t\t\t\taction.onConnect();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonConnectIntegration?.(s as ToolSource);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// A source whose drill-in view would hold exactly one leaf is pointless\n\t\t\t\t// to drill into — surface that single leaf right here (its function name\n\t\t\t\t// + the same source icon). Covers \"no Rest API added yet\" (→ open the\n\t\t\t\t// create modal directly) and a config tool's single capability (Slack →\n\t\t\t\t// \"Send Slack message\", email → \"Send email\").\n\t\t\t\tconst instances = tools.filter(\n\t\t\t\t\t(t) => (metaOf(t)?.source ?? 'other') === s,\n\t\t\t\t);\n\t\t\t\tif (instances.length + (action ? 1 : 0) === 1) {\n\t\t\t\t\tconst icon = sourceIcon(s) ?? action?.icon;\n\t\t\t\t\tif (action) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: s,\n\t\t\t\t\t\t\tlabel: action.label,\n\t\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\t\ticon,\n\t\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\t\taction.onSelect();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst only = instances[0];\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: String(only.id),\n\t\t\t\t\t\tlabel: rowLabel(only),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon,\n\t\t\t\t\t\tauthRequired: metaOf(only)?.authRequired,\n\t\t\t\t\t\tonActivate: () => onSelect(only),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tid: s,\n\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\tonActivate: () => setSource(s),\n\t\t\t\t};\n\t\t\t};\n\n\t\t\t// Inside the Integrations group: just its member sources, ranked.\n\t\t\tif (group === 'integrations') {\n\t\t\t\treturn combined\n\t\t\t\t\t.filter(isIntegrationSource)\n\t\t\t\t\t.sort((a, b) => toolSourceRank(a) - toolSourceRank(b))\n\t\t\t\t\t.map(buildSourceRow);\n\t\t\t}\n\n\t\t\t// Top level: non-integration sources as their own rows, plus ONE\n\t\t\t// \"Integrations\" drill-in row (only when a member exists). Fixed rank order\n\t\t\t// so adding/updating a tool never reshuffles the picker rows.\n\t\t\tconst topRows = combined\n\t\t\t\t.filter((s) => !isIntegrationSource(s))\n\t\t\t\t.map((s) => ({ rank: toolSourceRank(s), row: buildSourceRow(s) }));\n\t\t\tif (combined.some(isIntegrationSource)) {\n\t\t\t\ttopRows.push({\n\t\t\t\t\trank: INTEGRATIONS_RANK,\n\t\t\t\t\trow: {\n\t\t\t\t\t\tid: '__integrations__',\n\t\t\t\t\t\tlabel: 'Integrations',\n\t\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tsetGroup('integrations');\n\t\t\t\t\t\t\tsetSource(null);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn topRows.sort((a, b) => a.rank - b.rank).map((x) => x.row);\n\t\t}\n\t\tconst q = search.trim().toLowerCase();\n\t\tconst leaves: PickerRowModel[] = tools\n\t\t\t.filter((t) => (metaOf(t)?.source ?? 'other') === source)\n\t\t\t.filter((t) => !q || rowLabel(t).toLowerCase().includes(q))\n\t\t\t.map((item) => ({\n\t\t\t\tid: String(item.id),\n\t\t\t\tlabel: rowLabel(item),\n\t\t\t\tdrillsIn: false,\n\t\t\t\tauthRequired: metaOf(item)?.authRequired,\n\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t}));\n\t\t// A configurable source's add row, below any existing instances, opening\n\t\t// its drawer. Config tools (Slack / email) are a single fixed capability →\n\t\t// render like a normal tool leaf (label only, no icon — matching the tool\n\t\t// rows). Rest API instances are user-created, so its \"add\" stays a\n\t\t// brand-coloured create row.\n\t\tconst action = actionBySource.get(source);\n\t\tif (action) {\n\t\t\tconst isConfigTool = source in CONFIG_TOOL_SOURCES;\n\t\t\tleaves.push({\n\t\t\t\tid: `create:${source}`,\n\t\t\t\tlabel: action.label,\n\t\t\t\tdrillsIn: false,\n\t\t\t\tisCreate: !isConfigTool,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tonClose?.();\n\t\t\t\t\taction.onSelect();\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn leaves;\n\t}, [\n\t\tactiveCategory,\n\t\tavailableCategories,\n\t\tsource,\n\t\tgroup,\n\t\tsearch,\n\t\ttools,\n\t\tsubAgents,\n\t\tsources,\n\t\tonSelect,\n\t\tonClose,\n\t\tonCreateSubAgent,\n\t\ttoolActions,\n\t\tactionBySource,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t]);\n\n\t// Reset highlight whenever the view (or filtered result set) changes.\n\tuseEffect(\n\t\t() => setActiveIndex(-1),\n\t\t[activeCategory, source, group, search, items],\n\t);\n\t// Clear the search box when leaving a source view.\n\tuseEffect(() => setSearch(''), [activeCategory, source, group]);\n\n\t// Keep the latest rows/index reachable from the stable key handler.\n\tconst navRef = useRef({ rows, activeIndex, header });\n\tnavRef.current = { rows, activeIndex, header };\n\n\tuseEffect(() => {\n\t\tif (!registerKeyHandler) {\n\t\t\treturn;\n\t\t}\n\t\tregisterKeyHandler((event) => {\n\t\t\tconst { rows: r, activeIndex: i, header: h } = navRef.current;\n\t\t\tswitch (event.key) {\n\t\t\t\tcase 'ArrowDown':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowUp':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + r.length - 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowRight':\n\t\t\t\tcase 'Enter':\n\t\t\t\t\t// Nothing highlighted yet → treat the first row as the target so\n\t\t\t\t\t// the editor's @-flow (type, then Enter) still works.\n\t\t\t\t\t(r[i] ?? r[0])?.onActivate();\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowLeft':\n\t\t\t\t\tif (h?.onBack) {\n\t\t\t\t\t\th.onBack();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\treturn () => registerKeyHandler(null);\n\t}, [registerKeyHandler]);\n\n\tconst variant = !activeCategory\n\t\t? 'categories'\n\t\t: rows.length && !rows[0].drillsIn\n\t\t? 'items'\n\t\t: 'sources';\n\n\t// Search lives inside a source's tool list (Manifest / Shopify) and in the\n\t// sub-agent list.\n\tconst showSearch =\n\t\t(activeCategory === 'tool' && !!source) || activeCategory === 'subagent';\n\n\treturn (\n\t\t<PickerCard className={`bik-mention-picker bik-mention-picker--${variant}`}>\n\t\t\t{header && (\n\t\t\t\t<PickerBack\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={header.onBack}\n\t\t\t\t\tdisabled={!header.onBack}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: COLORS.surface.subdued,\n\t\t\t\t\t\tcursor: header.onBack ? 'pointer' : 'default',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{header.onBack && (\n\t\t\t\t\t\t<SvgArrowLeft\n\t\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\t\theight={20}\n\t\t\t\t\t\t\tcolor={COLORS.content.primary}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{header.icon && renderSourceIcon(header.icon)}\n\t\t\t\t\t<TitleSmall> {header.title}</TitleSmall>\n\t\t\t\t</PickerBack>\n\t\t\t)}\n\t\t\t{showSearch && (\n\t\t\t\t<PickerSearchRow>\n\t\t\t\t\t<SearchIcon\n\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\theight={20}\n\t\t\t\t\t\tcolor={COLORS.content.placeholder}\n\t\t\t\t\t/>\n\t\t\t\t\t<PickerSearchInput\n\t\t\t\t\t\t// Focus on open so the user can type immediately (appears only\n\t\t\t\t\t\t// after they drill into a source).\n\t\t\t\t\t\t// eslint-disable-next-line jsx-a11y/no-autofocus\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\tdata-test=\"mention-picker-search\"\n\t\t\t\t\t\tonChange={(e) => setSearch(e.target.value)}\n\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\tif (!rows.length) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (e.key === 'ArrowDown') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'ArrowUp') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + rows.length - 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'Enter') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t(rows[activeIndex] ?? rows[0])?.onActivate();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</PickerSearchRow>\n\t\t\t)}\n\t\t\t{rows.length === 0 ? (\n\t\t\t\t<PickerEmpty>\n\t\t\t\t\t{activeCategory === 'subagent' ? null : 'No tools available'}\n\t\t\t\t</PickerEmpty>\n\t\t\t) : (\n\t\t\t\trows.map((row, i) => (\n\t\t\t\t\t<PickerRow\n\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t$active={i === activeIndex}\n\t\t\t\t\t\tonMouseEnter={() => setActiveIndex(i)}\n\t\t\t\t\t\tonMouseLeave={() => setActiveIndex(-1)}\n\t\t\t\t\t\tonClick={row.onActivate}\n\t\t\t\t\t>\n\t\t\t\t\t\t{row.isCreate ? (\n\t\t\t\t\t\t\t<CreateRowText>{row.label}</CreateRowText>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<PickerRowMain>\n\t\t\t\t\t\t\t\t\t{renderSourceIcon(row.icon)}\n\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t\t{row.label}\n\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t\t{row.authRequired && (\n\t\t\t\t\t\t\t\t\t\t<Shield\n\t\t\t\t\t\t\t\t\t\t\tsize={14}\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"This tool requires customer verification\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</PickerRowMain>\n\t\t\t\t\t\t\t\t{row.rightLabel ? (\n\t\t\t\t\t\t\t\t\t<RightActionText>{row.rightLabel}</RightActionText>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\trow.drillsIn && <ChevronRight width={12} height={12} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</PickerRow>\n\t\t\t\t))\n\t\t\t)}\n\t\t\t{rows.some((row) => row.authRequired) && (\n\t\t\t\t<PickerLegend>\n\t\t\t\t\t<Shield size={14} />\n\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\tThis tool requires customer verification\n\t\t\t\t\t</BodyCaption>\n\t\t\t\t</PickerLegend>\n\t\t\t)}\n\t\t</PickerCard>\n\t);\n};\n\nconst PickerCard = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tmin-width: 240px;\n\tmax-height: 301px;\n\toverflow-y: auto;\n\tbackground: ${COLORS.surface.standard};\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbox-shadow: 0px -2px 8px 0px #0000001f;\n`;\n\n// Search box at the top of a source's tool list (Manifest / Shopify).\nconst PickerSearchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 10px 12px;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n`;\n\nconst PickerSearchInput = styled.input`\n\tflex: 1;\n\tmin-width: 0;\n\tborder: none;\n\toutline: none;\n\tbackground: transparent;\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.placeholder};\n\t}\n`;\n\nconst PickerRow = styled.button<{ $active?: boolean }>`\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\tgap: 2px;\n\twidth: 100%;\n\tpadding: 8px 10px;\n\theight: 48px;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: ${(p) => (p.$active ? COLORS.surface.subdued : 'transparent')};\n\tcursor: pointer;\n\ttext-align: left;\n\n\t&:hover {\n\t\tbackground: ${COLORS.surface.hovered};\n\t}\n`;\n\n// Left cluster: leading source glyph + label (chevron stays right via PickerRow).\nconst PickerRowMain = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tmin-width: 0;\n`;\n\n// Footer legend, shown when the list holds any auth-required tool.\nconst PickerLegend = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 8px 12px;\n\tborder-top: 1px solid ${COLORS.stroke.primary};\n`;\n\n// Right-aligned brand action text (e.g. \"Connect\") in place of the chevron.\nconst RightActionText = styled.span`\n\tflex-shrink: 0;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n`;\n\n// \"Create new\" — centered brand text, no icon (matches the side-panel dropdown).\nconst CreateRowText = styled.div`\n\twidth: 100%;\n\ttext-align: center;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n`;\n\nconst PickerBack = styled.button`\n\tdisplay: flex;\n\talign-items: center;\n\tpadding: 12px 16px;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: transparent;\n\tcursor: pointer;\n\tfont-family: Inter;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\theight: 48px;\n\tgap: 4px;\n`;\n\nconst PickerEmpty = styled.div`\n\tpadding: 12px 10px;\n\tfont-family: Inter;\n\tfont-size: 13px;\n\tcolor: ${COLORS.content.secondary};\n`;\n"],"names":["metaOf","item","rowLabel","CREATE_SUBAGENT_ID","MentionPicker","items","onSelect","registerKeyHandler","onClose","onCreateSubAgent","initialSource","toolActions","integrationStatus","onConnectIntegration","category","setCategory","useState","source","setSource","group","setGroup","activeIndex","setActiveIndex","search","setSearch","tools","useMemo","i","subAgents","sources","acc","t","s","actionBySource","a","availableCategories","CATEGORIES","c","soleCategory","activeCategory","header","toolSourceLabel","sourceIcon","rows","sq","leaves","actionOnly","combined","buildSourceRow","action","instances","icon","only","isIntegrationSource","b","toolSourceRank","topRows","INTEGRATIONS_RANK","x","q","isConfigTool","CONFIG_TOOL_SOURCES","useEffect","navRef","useRef","event","h","variant","showSearch","jsxs","PickerCard","PickerBack","COLORS","jsx","SvgArrowLeft","renderSourceIcon","TitleSmall","PickerSearchRow","SearchIcon","PickerSearchInput","p","PickerEmpty","row","PickerRow","CreateRowText","Fragment","PickerRowMain","BodySecondary","Shield","RightActionText","ChevronRight","PickerLegend","BodyCaption","styled"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MentionPicker.js","sources":["../../../../../src/components/agent-builder/components/MentionPicker.tsx"],"sourcesContent":["// import ChevronLeft from '@src/assets/icons/chevronLeft.svg';\nimport ChevronRight from '@src/assets/icons/chevronRight.svg';\nimport SearchIcon from '@src/assets/icons/searchIcon.svg';\nimport type { MentionDropdownRenderProps, MentionItem } from '@src/editor';\nimport { Shield } from '@src/icons';\nimport SvgArrowLeft from '@src/icons/Arrows/Normal arrows/ArrowLeft';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tCATEGORIES,\n\tCONFIG_TOOL_SOURCES,\n\tINTEGRATIONS_RANK,\n\tisIntegrationSource,\n\ttoolSourceRank,\n} from '../constants/tools';\nimport type { Category, ToolAction, ToolSource } from '../constants/tools';\nimport {\n\tMentionKindMeta,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport { renderSourceIcon, sourceIcon, SourceIcon } from '../utils/sourceIcons';\n\nconst metaOf = (item: MentionItem): MentionKindMeta | undefined =>\n\titem.meta as unknown as MentionKindMeta | undefined;\n\nconst rowLabel = (item: MentionItem): string =>\n\tmetaOf(item)?.plainLabel ?? item.label;\n\n/** One navigable row in the picker's current view. */\ntype PickerRowModel = {\n\tid: string;\n\tlabel: string;\n\t/** Drill-in rows show a chevron; leaf (selectable) rows do not. */\n\tdrillsIn: boolean;\n\t/** Leading brand glyph (source rows only). */\n\ticon?: SourceIcon;\n\t/** Brand-coloured \"Create new\" action row (not a selectable item). */\n\tisCreate?: boolean;\n\t/**\n\t * Brand-coloured right-aligned action text (e.g. \"Connect\") shown in place of\n\t * the drill-in chevron — used for an unconnected integration source.\n\t */\n\trightLabel?: string;\n\t/** Tool leaf touches customer-private data → shows a shield glyph. */\n\tauthRequired?: boolean;\n\tonActivate: () => void;\n};\n\n/** Sentinel id for the sub-agent \"Create new\" row. */\nconst CREATE_SUBAGENT_ID = '__bik_create_subagent__';\n\ntype MentionPickerProps = MentionDropdownRenderProps & {\n\t/** Opens the create-sub-agent drawer (shows a \"Create new\" row in the Sub-agent view). */\n\tonCreateSubAgent?: () => void;\n\t/**\n\t * Open already drilled into this tool source (e.g. `'shopify'`) — its tool list\n\t * is shown immediately. */\n\tinitialSource?: string;\n\t/**\n\t * Built-in tool actions (Rest API / Handover to email) shown in the Tools view.\n\t * Picking one opens its config drawer (via `onSelect`) and dismisses the picker\n\t * — it never inserts a mention into the text.\n\t */\n\ttoolActions?: ToolAction[];\n\t/**\n\t * Per-source integration connection state. A source whose value is `false`\n\t * renders a \"Connect\" row (like an unconnected action) instead of drilling in —\n\t * so native source groups (Shopify / BigCommerce / ShipStation) show \"Connect\"\n\t * consistently with the config actions (Slack).\n\t */\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\t/** Open the connect flow for an unconnected source (used by the Connect row). */\n\tonConnectIntegration?: (source: ToolSource) => void;\n};\n\n/**\n * `@` reference picker. Drills:\n * root → Tools → <source> (Manifest / Shopify / …) → tool\n * → Sub-agent → sub-agent\n * (\"Add condition\" and \"Variables\" are intentionally not shown yet.)\n *\n * Owns keyboard navigation (↑/↓ move, →/Enter activate, ← go back) over the\n * CURRENTLY visible rows — registered with the editor via `registerKeyHandler`.\n */\nexport const MentionPicker: React.FC<MentionPickerProps> = ({\n\titems,\n\tonSelect,\n\tregisterKeyHandler,\n\tonClose,\n\tonCreateSubAgent,\n\tinitialSource,\n\ttoolActions,\n\tintegrationStatus,\n\tonConnectIntegration,\n}) => {\n\tconst [category, setCategory] = useState<Category | null>(null);\n\tconst [source, setSource] = useState<string | null>(initialSource ?? null);\n\t// Non-null when drilled into the consolidated \"Integrations\" group (its member\n\t// sources are shown; picking one drills into that source's tools as usual).\n\tconst [group, setGroup] = useState<'integrations' | null>(null);\n\t// -1 = nothing highlighted; rows highlight only on hover / arrow keys\n\t// (a default highlight reads as a stuck hover state).\n\tconst [activeIndex, setActiveIndex] = useState(-1);\n\t// Search box shown inside a source's tool list (Manifest / Shopify); filters\n\t// that source's tools by name.\n\tconst [search, setSearch] = useState('');\n\n\tconst tools = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'tool'),\n\t\t[items],\n\t);\n\tconst subAgents = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'subagent'),\n\t\t[items],\n\t);\n\tconst sources = useMemo(() => {\n\t\tconst acc: string[] = [];\n\t\ttools.forEach((t) => {\n\t\t\tconst s = metaOf(t)?.source ?? 'other';\n\t\t\tif (!acc.includes(s)) {\n\t\t\t\tacc.push(s);\n\t\t\t}\n\t\t});\n\t\treturn acc;\n\t}, [tools]);\n\t// The built-in \"create\" action per source (Rest API / email / Slack). A source\n\t// with an action drills into [its instances + a \"Create new\" row] — like the\n\t// Sub-agent category — instead of showing a duplicate flat \"create\" row.\n\tconst actionBySource = useMemo(\n\t\t() =>\n\t\t\tnew Map<string, ToolAction>(\n\t\t\t\t(toolActions ?? []).map((a) => [a.source, a]),\n\t\t\t),\n\t\t[toolActions],\n\t);\n\n\t// Show a category when it has items — and ALWAYS show Sub-agent when creating\n\t// one is possible, so an agent with no sub-agents yet still gets the root\n\t// \"Tools / Sub-agent\" choice (with a \"Create new\" inside). When only one is\n\t// available (e.g. the sub-agent drawer offers tools only) the selector is skipped.\n\tconst availableCategories = useMemo(\n\t\t() =>\n\t\t\tCATEGORIES.filter((c) =>\n\t\t\t\tc.key === 'tool'\n\t\t\t\t\t? tools.length > 0 || (toolActions?.length ?? 0) > 0\n\t\t\t\t\t: subAgents.length > 0 || !!onCreateSubAgent,\n\t\t\t),\n\t\t[tools.length, subAgents.length, onCreateSubAgent, toolActions?.length],\n\t);\n\tconst soleCategory =\n\t\tavailableCategories.length === 1 ? availableCategories[0].key : null;\n\tconst activeCategory = category ?? soleCategory;\n\n\t// Title shown above the current view. `onBack` is omitted at a root level (a\n\t// sole category has nowhere to go back to) — the header then shows as a plain\n\t// title. When `onBack` is set the header leads with a back arrow, followed by\n\t// the source icon in a source detail view: `[← back][icon][title]`.\n\tconst header: {\n\t\ttitle: string;\n\t\tonBack?: () => void;\n\t\ticon?: SourceIcon;\n\t} | null = !activeCategory\n\t\t? null\n\t\t: activeCategory === 'subagent'\n\t\t? // Always titled — with a back arrow only when the category chooser is above.\n\t\t {\n\t\t\t\ttitle: 'Sub-agent',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t }\n\t\t: source\n\t\t? {\n\t\t\t\ttitle: toolSourceLabel(source),\n\t\t\t\t// Deep-linked to a source (opened from a right-panel source button):\n\t\t\t\t// that source IS the root, so no back arrow. Otherwise back clears the\n\t\t\t\t// source — returning to the Integrations group if we came via it (its\n\t\t\t\t// `group` state is untouched), else to the source chooser.\n\t\t\t\tonBack: initialSource ? undefined : () => setSource(null),\n\t\t\t\ticon: sourceIcon(source),\n\t\t }\n\t\t: group === 'integrations'\n\t\t? { title: 'Integrations', onBack: () => setGroup(null) }\n\t\t: // Always titled — matches the Sub-agent header; back arrow only when the\n\t\t // category chooser is above (i.e. not the sole category).\n\t\t {\n\t\t\t\ttitle: 'Tools',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t };\n\n\t// Build the navigable rows for the current view.\n\tconst rows: PickerRowModel[] = useMemo(() => {\n\t\tif (!activeCategory) {\n\t\t\treturn availableCategories.map((c) => ({\n\t\t\t\tid: c.key,\n\t\t\t\tlabel: c.label,\n\t\t\t\tdrillsIn: true,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tsetCategory(c.key);\n\t\t\t\t\tsetSource(null);\n\t\t\t\t\tsetGroup(null);\n\t\t\t\t},\n\t\t\t}));\n\t\t}\n\t\tif (activeCategory === 'subagent') {\n\t\t\tconst sq = search.trim().toLowerCase();\n\t\t\tconst leaves: PickerRowModel[] = subAgents\n\t\t\t\t.filter((item) => !sq || rowLabel(item).toLowerCase().includes(sq))\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tlabel: rowLabel(item),\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t\t}));\n\t\t\t// \"Create new\" opens the drawer — first dismiss the menu (strips the \"@\").\n\t\t\tif (onCreateSubAgent) {\n\t\t\t\tleaves.push({\n\t\t\t\t\tid: CREATE_SUBAGENT_ID,\n\t\t\t\t\tlabel: 'Create new',\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tisCreate: true,\n\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\tonCreateSubAgent();\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn leaves;\n\t\t}\n\t\tif (!source) {\n\t\t\t// The real sources (from instances) plus any action source (Rest API /\n\t\t\t// email / Slack) with no instances yet, so it still appears for first-time\n\t\t\t// creation. Deduped — no more twin rows.\n\t\t\tconst actionOnly = (toolActions ?? [])\n\t\t\t\t.map((a) => a.source)\n\t\t\t\t.filter((s) => !sources.includes(s));\n\t\t\tconst combined = [...sources, ...actionOnly];\n\n\t\t\t// One drill-in row per source: Connect (unconnected) / a single collapsed\n\t\t\t// leaf / a drill-in. Reused at the top level AND inside the Integrations\n\t\t\t// group so both behave identically.\n\t\t\tconst buildSourceRow = (s: string): PickerRowModel => {\n\t\t\t\tconst action = actionBySource.get(s);\n\t\t\t\t// Not connected → a \"Connect\" row (no drill-in / no instances / no\n\t\t\t\t// \"Create new\"); clicking dismisses the picker and runs the connect\n\t\t\t\t// flow. Applies to config actions (their own `connected`) AND native\n\t\t\t\t// source groups (via `integrationStatus`), so both look consistent.\n\t\t\t\tconst connected =\n\t\t\t\t\taction !== undefined\n\t\t\t\t\t\t? action.connected\n\t\t\t\t\t\t: integrationStatus?.[s as ToolSource];\n\t\t\t\tif (connected === false) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: s,\n\t\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\t\trightLabel: 'Connect',\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\tif (action?.onConnect) {\n\t\t\t\t\t\t\t\taction.onConnect();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonConnectIntegration?.(s as ToolSource);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// A source whose drill-in view would hold exactly one leaf is pointless\n\t\t\t\t// to drill into — surface that single leaf right here (its function name\n\t\t\t\t// + the same source icon). Covers \"no Rest API added yet\" (→ open the\n\t\t\t\t// create modal directly) and a config tool's single capability (Slack →\n\t\t\t\t// \"Send Slack message\", email → \"Send email\").\n\t\t\t\tconst instances = tools.filter(\n\t\t\t\t\t(t) => (metaOf(t)?.source ?? 'other') === s,\n\t\t\t\t);\n\t\t\t\tif (instances.length + (action ? 1 : 0) === 1) {\n\t\t\t\t\tconst icon = sourceIcon(s) ?? action?.icon;\n\t\t\t\t\tif (action) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: s,\n\t\t\t\t\t\t\tlabel: action.label,\n\t\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\t\ticon,\n\t\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\t\taction.onSelect();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst only = instances[0];\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: String(only.id),\n\t\t\t\t\t\tlabel: rowLabel(only),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon,\n\t\t\t\t\t\tauthRequired: metaOf(only)?.authRequired,\n\t\t\t\t\t\tonActivate: () => onSelect(only),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tid: s,\n\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\tonActivate: () => setSource(s),\n\t\t\t\t};\n\t\t\t};\n\n\t\t\t// Inside the Integrations group: just its member sources, ranked.\n\t\t\tif (group === 'integrations') {\n\t\t\t\treturn combined\n\t\t\t\t\t.filter(isIntegrationSource)\n\t\t\t\t\t.sort((a, b) => toolSourceRank(a) - toolSourceRank(b))\n\t\t\t\t\t.map(buildSourceRow);\n\t\t\t}\n\n\t\t\t// Top level: non-integration sources as their own rows, plus ONE\n\t\t\t// \"Integrations\" drill-in row (only when a member exists). Fixed rank order\n\t\t\t// so adding/updating a tool never reshuffles the picker rows.\n\t\t\tconst topRows = combined\n\t\t\t\t.filter((s) => !isIntegrationSource(s))\n\t\t\t\t.map((s) => ({ rank: toolSourceRank(s), row: buildSourceRow(s) }));\n\t\t\tif (combined.some(isIntegrationSource)) {\n\t\t\t\ttopRows.push({\n\t\t\t\t\trank: INTEGRATIONS_RANK,\n\t\t\t\t\trow: {\n\t\t\t\t\t\tid: '__integrations__',\n\t\t\t\t\t\tlabel: 'Integrations',\n\t\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tsetGroup('integrations');\n\t\t\t\t\t\t\tsetSource(null);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn topRows.sort((a, b) => a.rank - b.rank).map((x) => x.row);\n\t\t}\n\t\tconst q = search.trim().toLowerCase();\n\t\tconst leaves: PickerRowModel[] = tools\n\t\t\t.filter((t) => (metaOf(t)?.source ?? 'other') === source)\n\t\t\t.filter((t) => !q || rowLabel(t).toLowerCase().includes(q))\n\t\t\t.map((item) => ({\n\t\t\t\tid: String(item.id),\n\t\t\t\tlabel: rowLabel(item),\n\t\t\t\tdrillsIn: false,\n\t\t\t\tauthRequired: metaOf(item)?.authRequired,\n\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t}));\n\t\t// A configurable source's add row, below any existing instances, opening\n\t\t// its drawer. Config tools (Slack / email) are a single fixed capability →\n\t\t// render like a normal tool leaf (label only, no icon — matching the tool\n\t\t// rows). Rest API instances are user-created, so its \"add\" stays a\n\t\t// brand-coloured create row.\n\t\tconst action = actionBySource.get(source);\n\t\tif (action) {\n\t\t\tconst isConfigTool = source in CONFIG_TOOL_SOURCES;\n\t\t\tleaves.push({\n\t\t\t\tid: `create:${source}`,\n\t\t\t\tlabel: action.label,\n\t\t\t\tdrillsIn: false,\n\t\t\t\tisCreate: !isConfigTool,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tonClose?.();\n\t\t\t\t\taction.onSelect();\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn leaves;\n\t}, [\n\t\tactiveCategory,\n\t\tavailableCategories,\n\t\tsource,\n\t\tgroup,\n\t\tsearch,\n\t\ttools,\n\t\tsubAgents,\n\t\tsources,\n\t\tonSelect,\n\t\tonClose,\n\t\tonCreateSubAgent,\n\t\ttoolActions,\n\t\tactionBySource,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t]);\n\n\t// Reset highlight whenever the view (or filtered result set) changes.\n\tuseEffect(\n\t\t() => setActiveIndex(-1),\n\t\t[activeCategory, source, group, search, items],\n\t);\n\t// Clear the search box when leaving a source view.\n\tuseEffect(() => setSearch(''), [activeCategory, source, group]);\n\n\t// Keep the latest rows/index reachable from the stable key handler.\n\tconst navRef = useRef({ rows, activeIndex, header });\n\tnavRef.current = { rows, activeIndex, header };\n\n\tuseEffect(() => {\n\t\tif (!registerKeyHandler) {\n\t\t\treturn;\n\t\t}\n\t\tregisterKeyHandler((event) => {\n\t\t\tconst { rows: r, activeIndex: i, header: h } = navRef.current;\n\t\t\tswitch (event.key) {\n\t\t\t\tcase 'ArrowDown':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowUp':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + r.length - 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowRight':\n\t\t\t\tcase 'Enter':\n\t\t\t\t\t// Nothing highlighted yet → treat the first row as the target so\n\t\t\t\t\t// the editor's @-flow (type, then Enter) still works.\n\t\t\t\t\t(r[i] ?? r[0])?.onActivate();\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowLeft':\n\t\t\t\t\tif (h?.onBack) {\n\t\t\t\t\t\th.onBack();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\treturn () => registerKeyHandler(null);\n\t}, [registerKeyHandler]);\n\n\tconst variant = !activeCategory\n\t\t? 'categories'\n\t\t: rows.length && !rows[0].drillsIn\n\t\t? 'items'\n\t\t: 'sources';\n\n\t// Search lives inside a source's tool list (Manifest / Shopify) and in the\n\t// sub-agent list.\n\tconst showSearch =\n\t\t(activeCategory === 'tool' && !!source) || activeCategory === 'subagent';\n\n\treturn (\n\t\t<PickerCard className={`bik-mention-picker bik-mention-picker--${variant}`}>\n\t\t\t{header && (\n\t\t\t\t<PickerBack\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={header.onBack}\n\t\t\t\t\tdisabled={!header.onBack}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: COLORS.surface.subdued,\n\t\t\t\t\t\tcursor: header.onBack ? 'pointer' : 'default',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{header.onBack && (\n\t\t\t\t\t\t<SvgArrowLeft\n\t\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\t\theight={20}\n\t\t\t\t\t\t\tcolor={COLORS.content.primary}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{header.icon && renderSourceIcon(header.icon)}\n\t\t\t\t\t<TitleSmall> {header.title}</TitleSmall>\n\t\t\t\t</PickerBack>\n\t\t\t)}\n\t\t\t{showSearch && (\n\t\t\t\t<PickerSearchRow>\n\t\t\t\t\t<SearchIcon\n\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\theight={20}\n\t\t\t\t\t\tcolor={COLORS.content.placeholder}\n\t\t\t\t\t/>\n\t\t\t\t\t<PickerSearchInput\n\t\t\t\t\t\t// Focus on open so the user can type immediately (appears only\n\t\t\t\t\t\t// after they drill into a source).\n\t\t\t\t\t\t// eslint-disable-next-line jsx-a11y/no-autofocus\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\tdata-test=\"mention-picker-search\"\n\t\t\t\t\t\tonChange={(e) => setSearch(e.target.value)}\n\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\tif (!rows.length) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (e.key === 'ArrowDown') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'ArrowUp') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + rows.length - 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'Enter') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t(rows[activeIndex] ?? rows[0])?.onActivate();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</PickerSearchRow>\n\t\t\t)}\n\t\t\t{rows.length === 0 ? (\n\t\t\t\t<PickerEmpty>\n\t\t\t\t\t{activeCategory === 'subagent' ? null : 'No tools available'}\n\t\t\t\t</PickerEmpty>\n\t\t\t) : (\n\t\t\t\trows.map((row, i) => (\n\t\t\t\t\t<PickerRow\n\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t$active={i === activeIndex}\n\t\t\t\t\t\tonMouseEnter={() => setActiveIndex(i)}\n\t\t\t\t\t\tonMouseLeave={() => setActiveIndex(-1)}\n\t\t\t\t\t\tonClick={row.onActivate}\n\t\t\t\t\t>\n\t\t\t\t\t\t{row.isCreate ? (\n\t\t\t\t\t\t\t<CreateRowText>{row.label}</CreateRowText>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<PickerRowMain>\n\t\t\t\t\t\t\t\t\t{renderSourceIcon(row.icon)}\n\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t\t{row.label}\n\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t\t{row.authRequired && (\n\t\t\t\t\t\t\t\t\t\t<Shield\n\t\t\t\t\t\t\t\t\t\t\tsize={14}\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"This tool requires customer verification\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</PickerRowMain>\n\t\t\t\t\t\t\t\t{row.rightLabel ? (\n\t\t\t\t\t\t\t\t\t<RightActionText>{row.rightLabel}</RightActionText>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\trow.drillsIn && <ChevronRight width={12} height={12} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</PickerRow>\n\t\t\t\t))\n\t\t\t)}\n\t\t\t{rows.some((row) => row.authRequired) && (\n\t\t\t\t<PickerLegend>\n\t\t\t\t\t<Shield size={14} />\n\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\tThis tool requires customer verification\n\t\t\t\t\t</BodyCaption>\n\t\t\t\t</PickerLegend>\n\t\t\t)}\n\t\t</PickerCard>\n\t);\n};\n\nconst PickerCard = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tmin-width: 240px;\n\tmax-height: 301px;\n\toverflow-y: auto;\n\tbackground: ${COLORS.surface.standard};\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbox-shadow: 0px -2px 8px 0px #0000001f;\n`;\n\n// Search box at the top of a source's tool list (Manifest / Shopify).\nconst PickerSearchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 10px 12px;\n\tflex-shrink: 0;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n`;\n\nconst PickerSearchInput = styled.input`\n\tflex: 1;\n\tmin-width: 0;\n\tborder: none;\n\toutline: none;\n\tbackground: transparent;\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.placeholder};\n\t}\n`;\n\nconst PickerRow = styled.button<{ $active?: boolean }>`\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\tgap: 2px;\n\twidth: 100%;\n\tpadding: 8px 10px;\n\theight: 48px;\n\t/* The card is a flex column with a max-height; without these a long list\n\t compresses its rows below 48px (why only the short first step looked right)\n\t instead of scrolling. Pin the row so the card scrolls instead. */\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: ${(p) => (p.$active ? COLORS.surface.subdued : 'transparent')};\n\tcursor: pointer;\n\ttext-align: left;\n\n\t&:hover {\n\t\tbackground: ${COLORS.surface.hovered};\n\t}\n`;\n\n// Left cluster: leading source glyph + label (chevron stays right via PickerRow).\nconst PickerRowMain = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tmin-width: 0;\n`;\n\n// Footer legend, shown when the list holds any auth-required tool.\nconst PickerLegend = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 8px 12px;\n\tborder-top: 1px solid ${COLORS.stroke.primary};\n`;\n\n// Right-aligned brand action text (e.g. \"Connect\") in place of the chevron.\nconst RightActionText = styled.span`\n\tflex-shrink: 0;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n`;\n\n// \"Create new\" — centered brand text, no icon (matches the side-panel dropdown).\nconst CreateRowText = styled.div`\n\twidth: 100%;\n\ttext-align: center;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n`;\n\nconst PickerBack = styled.button`\n\tdisplay: flex;\n\talign-items: center;\n\tpadding: 12px 16px;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: transparent;\n\tcursor: pointer;\n\tfont-family: Inter;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\theight: 48px;\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tgap: 4px;\n`;\n\nconst PickerEmpty = styled.div`\n\tpadding: 12px 10px;\n\tfont-family: Inter;\n\tfont-size: 13px;\n\tcolor: ${COLORS.content.secondary};\n`;\n"],"names":["metaOf","item","rowLabel","CREATE_SUBAGENT_ID","MentionPicker","items","onSelect","registerKeyHandler","onClose","onCreateSubAgent","initialSource","toolActions","integrationStatus","onConnectIntegration","category","setCategory","useState","source","setSource","group","setGroup","activeIndex","setActiveIndex","search","setSearch","tools","useMemo","i","subAgents","sources","acc","t","s","actionBySource","a","availableCategories","CATEGORIES","c","soleCategory","activeCategory","header","toolSourceLabel","sourceIcon","rows","sq","leaves","actionOnly","combined","buildSourceRow","action","instances","icon","only","isIntegrationSource","b","toolSourceRank","topRows","INTEGRATIONS_RANK","x","q","isConfigTool","CONFIG_TOOL_SOURCES","useEffect","navRef","useRef","event","h","p","variant","showSearch","jsxs","PickerCard","PickerBack","COLORS","jsx","SvgArrowLeft","renderSourceIcon","TitleSmall","PickerSearchRow","SearchIcon","PickerSearchInput","PickerEmpty","row","PickerRow","CreateRowText","Fragment","PickerRowMain","BodySecondary","Shield","RightActionText","ChevronRight","PickerLegend","BodyCaption","styled"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),n=require("react"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),n=require("react"),U=require("../TablePagination/TablePagination.js"),A=require("./AgentListing.styled.js"),W=require("./AgentListingFilters.js"),X=require("./AgentListingHeader.js"),Y=require("./AgentTable.js"),Z=require("./AgentTableShimmer.js"),ee=require("./AiAgentsEmptyState.js"),te=require("./DeleteAgentModal.js"),ne=require("../dropdown/utils.js"),q=({config:x,onSearchChange:b,onSearchSubmit:r,onFilterChange:g,onSortChange:c,onNewAgent:m,onBrowseTemplates:d,onRunAgent:p,onEditAgent:C,onDeleteAgent:l,onRowClick:u,...L})=>{const[i,h]=n.useState(null),[S,j]=n.useState(!1),{agents:k,isLoading:w,triggerCountsLoading:N,searchValue:f,searchPlaceholder:R="Search",filterOptions:D,filterPlaceholder:T="Filters",sortOptions:z,selectedSort:v,title:E="AI Agents",headerActions:F,pagination:s,emptyState:O,debugLog:y}=x,M=!w&&k.length===0,t=n.useCallback((e,...o)=>{y&&console.log(`[AgentListing] ${e}`,...o)},[y]),H=n.useCallback(e=>{t("onSearchChange",e),b(e)},[t,b]),B=n.useCallback(e=>{t("onSearchSubmit",e),r?.(e)},[t,r]),I=n.useCallback(e=>{t("onFilterChange",e),g?.(e)},[t,g]),V=n.useCallback(e=>{t("onSortChange",e),c?.(e)},[t,c]),P=n.useCallback(()=>{t("onNewAgent"),m()},[t,m]),_=n.useCallback(()=>{t("onBrowseTemplates"),d?.()},[t,d]),$=n.useCallback(e=>{t("onRunAgent",e.id),p(e)},[t,p]),G=n.useCallback(e=>{t("onEditAgent",e.id),C(e)},[t,C]),J=n.useCallback(e=>{t("onRowClick",e.id),u?.(e)},[t,u]),K=n.useCallback(e=>{t("onDeleteAgent",e.id),h(e)},[t]),Q=n.useCallback(async()=>{if(!(!i||!l)){j(!0);try{await l(i),h(null)}finally{j(!1)}}},[i,l]);return a.jsxs(A.Page,{"data-test":L["data-test"]??"agent-listing",children:[a.jsx(X.AgentListingHeader,{title:E,onNewAgent:P,onBrowseTemplates:d?_:void 0,headerActions:F}),a.jsx(W.AgentListingFilters,{searchValue:f,onSearchChange:H,onSearchSubmit:r?B:void 0,searchPlaceholder:R,filterOptions:D,onFilterChange:g?I:void 0,filterPlaceholder:T,sortOptions:z,selectedSort:v,onSortChange:c?V:void 0}),a.jsx(A.Body,{children:w?a.jsx(Z.AgentTableShimmer,{rows:Math.min(s?.pageSize??5,10)}):M?a.jsx(A.EmptyHolder,{children:a.jsx(ee.AiAgentsEmptyState,{emptyState:O,onNewAgent:P})}):a.jsxs(a.Fragment,{children:[a.jsx(Y.AgentTable,{agents:k,triggerCountsLoading:N,onRunAgent:$,onEditAgent:G,onDeleteAgent:l?K:void 0,onRowClick:u?J:void 0}),s&&s.totalRows>0&&a.jsx(U.TablePagination,{pageNumber:s.pageNumber,pageSize:s.pageSize,totalRows:s.totalRows,hidePageSizeOptions:s.hidePageSizeOptions,updatePageNumber:s.onPageChange,updatePageSize:e=>{const o=Number(ne.unwrapDropdownValue(e));Number.isNaN(o)||s.onPageSizeChange(o)}})]})}),i&&a.jsx(te.DeleteAgentModal,{agentName:i.name,isDeleting:S,onClose:()=>S?void 0:h(null),onConfirm:Q})]})};q.displayName="AgentListing";exports.AgentListing=q;
|
|
2
2
|
//# sourceMappingURL=AgentListing.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentListing.js","sources":["../../../../src/components/agent-listing/AgentListing.tsx"],"sourcesContent":["import React, { useCallback, useState } from 'react';\nimport { unwrapDropdownValue } from '@src/components/dropdown';\nimport { DropdownOption } from '@src/components/dropdown/type';\nimport { TablePagination } from '@src/components/TablePagination/TablePagination';\nimport { ZeroState } from '@src/components/zeroState/ZeroState';\nimport { AgentListingProps, AgentListItem } from './AgentListing.model';\nimport { Body, EmptyHolder, Page } from './AgentListing.styled';\nimport { AgentListingFilters } from './AgentListingFilters';\nimport { AgentListingHeader } from './AgentListingHeader';\nimport { AgentTable } from './AgentTable';\nimport { AgentTableShimmer } from './AgentTableShimmer';\nimport { DeleteAgentModal } from './DeleteAgentModal';\n\n/**\n * Full body of the \"AI Agents\" listing screen (header + filters + table).\n * Presentational and fully controlled — the consumer owns data, search, sort,\n * pagination and routing. Render it inside your app shell (next to the sidebar).\n *\n * @example\n * <AgentListing\n * agents={rows}\n * searchValue={search}\n * onSearchChange={setSearch}\n * onNewAgent={() => router.push('/agents/new')}\n * onRunAgent={runAgent}\n * onEditAgent={(a) => router.push(`/agents/${a.id}`)}\n * />\n */\nexport const AgentListing: React.FC<AgentListingProps> = ({\n\tconfig,\n\tonSearchChange,\n\tonSearchSubmit,\n\tonFilterChange,\n\tonSortChange,\n\tonNewAgent,\n\tonBrowseTemplates,\n\tonRunAgent,\n\tonEditAgent,\n\tonDeleteAgent,\n\tonRowClick,\n\t...rest\n}) => {\n\t// Agent pending delete-confirmation (null = dialog closed).\n\tconst [pendingDelete, setPendingDelete] = useState<AgentListItem | null>(\n\t\tnull,\n\t);\n\tconst [isDeleting, setIsDeleting] = useState(false);\n\tconst {\n\t\tagents,\n\t\tisLoading,\n\t\ttriggerCountsLoading,\n\t\tsearchValue,\n\t\tsearchPlaceholder = 'Search',\n\t\tfilterOptions,\n\t\tfilterPlaceholder = 'Filters',\n\t\tsortOptions,\n\t\tselectedSort,\n\t\ttitle = 'AI Agents',\n\t\theaderActions,\n\t\tpagination,\n\t\temptyState,\n\t\tdebugLog,\n\t} = config;\n\n\tconst showEmpty = !isLoading && agents.length === 0;\n\n\t// Gated debug logging: each handler logs at its start only when `debugLog`.\n\tconst logAction = useCallback(\n\t\t(action: string, ...args: unknown[]) => {\n\t\t\tif (debugLog) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log(`[AgentListing] ${action}`, ...args);\n\t\t\t}\n\t\t},\n\t\t[debugLog],\n\t);\n\n\tconst handleSearchChange = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSearchChange', v);\n\t\t\tonSearchChange(v);\n\t\t},\n\t\t[logAction, onSearchChange],\n\t);\n\tconst handleSearchSubmit = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSearchSubmit', v);\n\t\t\tonSearchSubmit?.(v);\n\t\t},\n\t\t[logAction, onSearchSubmit],\n\t);\n\tconst handleFilterChange = useCallback(\n\t\t(selected: DropdownOption | DropdownOption[]) => {\n\t\t\tlogAction('onFilterChange', selected);\n\t\t\tonFilterChange?.(selected);\n\t\t},\n\t\t[logAction, onFilterChange],\n\t);\n\tconst handleSortChange = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSortChange', v);\n\t\t\tonSortChange?.(v);\n\t\t},\n\t\t[logAction, onSortChange],\n\t);\n\tconst handleNewAgent = useCallback(() => {\n\t\tlogAction('onNewAgent');\n\t\tonNewAgent();\n\t}, [logAction, onNewAgent]);\n\tconst handleBrowseTemplates = useCallback(() => {\n\t\tlogAction('onBrowseTemplates');\n\t\tonBrowseTemplates?.();\n\t}, [logAction, onBrowseTemplates]);\n\tconst handleRunAgent = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onRunAgent', agent.id);\n\t\t\tonRunAgent(agent);\n\t\t},\n\t\t[logAction, onRunAgent],\n\t);\n\tconst handleEditAgent = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onEditAgent', agent.id);\n\t\t\tonEditAgent(agent);\n\t\t},\n\t\t[logAction, onEditAgent],\n\t);\n\tconst handleRowClick = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onRowClick', agent.id);\n\t\t\tonRowClick?.(agent);\n\t\t},\n\t\t[logAction, onRowClick],\n\t);\n\t// Row delete just opens the confirm dialog; the actual delete runs on confirm.\n\tconst handleDeleteRequest = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onDeleteAgent', agent.id);\n\t\t\tsetPendingDelete(agent);\n\t\t},\n\t\t[logAction],\n\t);\n\tconst handleConfirmDelete = useCallback(async () => {\n\t\tif (!pendingDelete || !onDeleteAgent) {\n\t\t\treturn;\n\t\t}\n\t\tsetIsDeleting(true);\n\t\ttry {\n\t\t\tawait onDeleteAgent(pendingDelete);\n\t\t\tsetPendingDelete(null);\n\t\t} finally {\n\t\t\tsetIsDeleting(false);\n\t\t}\n\t}, [pendingDelete, onDeleteAgent]);\n\n\treturn (\n\t\t<Page data-test={rest['data-test'] ?? 'agent-listing'}>\n\t\t\t<AgentListingHeader\n\t\t\t\ttitle={title}\n\t\t\t\tonNewAgent={handleNewAgent}\n\t\t\t\tonBrowseTemplates={\n\t\t\t\t\tonBrowseTemplates ? handleBrowseTemplates : undefined\n\t\t\t\t}\n\t\t\t\theaderActions={headerActions}\n\t\t\t/>\n\n\t\t\t<AgentListingFilters\n\t\t\t\tsearchValue={searchValue}\n\t\t\t\tonSearchChange={handleSearchChange}\n\t\t\t\tonSearchSubmit={onSearchSubmit ? handleSearchSubmit : undefined}\n\t\t\t\tsearchPlaceholder={searchPlaceholder}\n\t\t\t\tfilterOptions={filterOptions}\n\t\t\t\tonFilterChange={onFilterChange ? handleFilterChange : undefined}\n\t\t\t\tfilterPlaceholder={filterPlaceholder}\n\t\t\t\tsortOptions={sortOptions}\n\t\t\t\tselectedSort={selectedSort}\n\t\t\t\tonSortChange={onSortChange ? handleSortChange : undefined}\n\t\t\t/>\n\n\t\t\t<Body>\n\t\t\t\t{isLoading ? (\n\t\t\t\t\t<AgentTableShimmer rows={Math.min(pagination?.pageSize ?? 5, 10)} />\n\t\t\t\t) : showEmpty ? (\n\t\t\t\t\t<EmptyHolder>\n\t\t\t\t\t\t<ZeroState\n\t\t\t\t\t\t\ttitle={emptyState?.title ?? 'No agents yet'}\n\t\t\t\t\t\t\tsubTitle={\n\t\t\t\t\t\t\t\temptyState?.subTitle ??\n\t\t\t\t\t\t\t\t'Create your first AI agent to start automating conversations.'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tactionButton={\n\t\t\t\t\t\t\t\temptyState?.actionButton ?? {\n\t\t\t\t\t\t\t\t\tbuttonText: 'New AI agent',\n\t\t\t\t\t\t\t\t\tbuttonType: 'primary',\n\t\t\t\t\t\t\t\t\tsize: 'small',\n\t\t\t\t\t\t\t\t\tonClick: handleNewAgent,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</EmptyHolder>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<AgentTable\n\t\t\t\t\t\t\tagents={agents}\n\t\t\t\t\t\t\ttriggerCountsLoading={triggerCountsLoading}\n\t\t\t\t\t\t\tonRunAgent={handleRunAgent}\n\t\t\t\t\t\t\tonEditAgent={handleEditAgent}\n\t\t\t\t\t\t\tonDeleteAgent={onDeleteAgent ? handleDeleteRequest : undefined}\n\t\t\t\t\t\t\tonRowClick={onRowClick ? handleRowClick : undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{pagination && pagination.totalRows > 0 && (\n\t\t\t\t\t\t\t<TablePagination\n\t\t\t\t\t\t\t\tpageNumber={pagination.pageNumber}\n\t\t\t\t\t\t\t\tpageSize={pagination.pageSize}\n\t\t\t\t\t\t\t\ttotalRows={pagination.totalRows}\n\t\t\t\t\t\t\t\thidePageSizeOptions={pagination.hidePageSizeOptions}\n\t\t\t\t\t\t\t\tupdatePageNumber={pagination.onPageChange}\n\t\t\t\t\t\t\t\tupdatePageSize={(opt) => {\n\t\t\t\t\t\t\t\t\tconst value = Number(unwrapDropdownValue(opt));\n\t\t\t\t\t\t\t\t\tif (!Number.isNaN(value)) {\n\t\t\t\t\t\t\t\t\t\tpagination.onPageSizeChange(value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</Body>\n\n\t\t\t{pendingDelete && (\n\t\t\t\t<DeleteAgentModal\n\t\t\t\t\tagentName={pendingDelete.name}\n\t\t\t\t\tisDeleting={isDeleting}\n\t\t\t\t\tonClose={() => (isDeleting ? undefined : setPendingDelete(null))}\n\t\t\t\t\tonConfirm={handleConfirmDelete}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Page>\n\t);\n};\n\nAgentListing.displayName = 'AgentListing';\n"],"names":["AgentListing","config","onSearchChange","onSearchSubmit","onFilterChange","onSortChange","onNewAgent","onBrowseTemplates","onRunAgent","onEditAgent","onDeleteAgent","onRowClick","rest","pendingDelete","setPendingDelete","useState","isDeleting","setIsDeleting","agents","isLoading","triggerCountsLoading","searchValue","searchPlaceholder","filterOptions","filterPlaceholder","sortOptions","selectedSort","title","headerActions","pagination","emptyState","debugLog","showEmpty","logAction","useCallback","action","args","handleSearchChange","v","handleSearchSubmit","handleFilterChange","selected","handleSortChange","handleNewAgent","handleBrowseTemplates","handleRunAgent","agent","handleEditAgent","handleRowClick","handleDeleteRequest","handleConfirmDelete","Page","jsx","AgentListingHeader","AgentListingFilters","Body","AgentTableShimmer","EmptyHolder","ZeroState","jsxs","Fragment","AgentTable","TablePagination","opt","value","unwrapDropdownValue","DeleteAgentModal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentListing.js","sources":["../../../../src/components/agent-listing/AgentListing.tsx"],"sourcesContent":["import React, { useCallback, useState } from 'react';\nimport { unwrapDropdownValue } from '@src/components/dropdown';\nimport { DropdownOption } from '@src/components/dropdown/type';\nimport { TablePagination } from '@src/components/TablePagination/TablePagination';\nimport { AgentListingProps, AgentListItem } from './AgentListing.model';\nimport { Body, EmptyHolder, Page } from './AgentListing.styled';\nimport { AgentListingFilters } from './AgentListingFilters';\nimport { AgentListingHeader } from './AgentListingHeader';\nimport { AgentTable } from './AgentTable';\nimport { AgentTableShimmer } from './AgentTableShimmer';\nimport { AiAgentsEmptyState } from './AiAgentsEmptyState';\nimport { DeleteAgentModal } from './DeleteAgentModal';\n\n/**\n * Full body of the \"AI Agents\" listing screen (header + filters + table).\n * Presentational and fully controlled — the consumer owns data, search, sort,\n * pagination and routing. Render it inside your app shell (next to the sidebar).\n *\n * @example\n * <AgentListing\n * agents={rows}\n * searchValue={search}\n * onSearchChange={setSearch}\n * onNewAgent={() => router.push('/agents/new')}\n * onRunAgent={runAgent}\n * onEditAgent={(a) => router.push(`/agents/${a.id}`)}\n * />\n */\nexport const AgentListing: React.FC<AgentListingProps> = ({\n\tconfig,\n\tonSearchChange,\n\tonSearchSubmit,\n\tonFilterChange,\n\tonSortChange,\n\tonNewAgent,\n\tonBrowseTemplates,\n\tonRunAgent,\n\tonEditAgent,\n\tonDeleteAgent,\n\tonRowClick,\n\t...rest\n}) => {\n\t// Agent pending delete-confirmation (null = dialog closed).\n\tconst [pendingDelete, setPendingDelete] = useState<AgentListItem | null>(\n\t\tnull,\n\t);\n\tconst [isDeleting, setIsDeleting] = useState(false);\n\tconst {\n\t\tagents,\n\t\tisLoading,\n\t\ttriggerCountsLoading,\n\t\tsearchValue,\n\t\tsearchPlaceholder = 'Search',\n\t\tfilterOptions,\n\t\tfilterPlaceholder = 'Filters',\n\t\tsortOptions,\n\t\tselectedSort,\n\t\ttitle = 'AI Agents',\n\t\theaderActions,\n\t\tpagination,\n\t\temptyState,\n\t\tdebugLog,\n\t} = config;\n\n\tconst showEmpty = !isLoading && agents.length === 0;\n\n\t// Gated debug logging: each handler logs at its start only when `debugLog`.\n\tconst logAction = useCallback(\n\t\t(action: string, ...args: unknown[]) => {\n\t\t\tif (debugLog) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log(`[AgentListing] ${action}`, ...args);\n\t\t\t}\n\t\t},\n\t\t[debugLog],\n\t);\n\n\tconst handleSearchChange = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSearchChange', v);\n\t\t\tonSearchChange(v);\n\t\t},\n\t\t[logAction, onSearchChange],\n\t);\n\tconst handleSearchSubmit = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSearchSubmit', v);\n\t\t\tonSearchSubmit?.(v);\n\t\t},\n\t\t[logAction, onSearchSubmit],\n\t);\n\tconst handleFilterChange = useCallback(\n\t\t(selected: DropdownOption | DropdownOption[]) => {\n\t\t\tlogAction('onFilterChange', selected);\n\t\t\tonFilterChange?.(selected);\n\t\t},\n\t\t[logAction, onFilterChange],\n\t);\n\tconst handleSortChange = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSortChange', v);\n\t\t\tonSortChange?.(v);\n\t\t},\n\t\t[logAction, onSortChange],\n\t);\n\tconst handleNewAgent = useCallback(() => {\n\t\tlogAction('onNewAgent');\n\t\tonNewAgent();\n\t}, [logAction, onNewAgent]);\n\tconst handleBrowseTemplates = useCallback(() => {\n\t\tlogAction('onBrowseTemplates');\n\t\tonBrowseTemplates?.();\n\t}, [logAction, onBrowseTemplates]);\n\tconst handleRunAgent = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onRunAgent', agent.id);\n\t\t\tonRunAgent(agent);\n\t\t},\n\t\t[logAction, onRunAgent],\n\t);\n\tconst handleEditAgent = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onEditAgent', agent.id);\n\t\t\tonEditAgent(agent);\n\t\t},\n\t\t[logAction, onEditAgent],\n\t);\n\tconst handleRowClick = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onRowClick', agent.id);\n\t\t\tonRowClick?.(agent);\n\t\t},\n\t\t[logAction, onRowClick],\n\t);\n\t// Row delete just opens the confirm dialog; the actual delete runs on confirm.\n\tconst handleDeleteRequest = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onDeleteAgent', agent.id);\n\t\t\tsetPendingDelete(agent);\n\t\t},\n\t\t[logAction],\n\t);\n\tconst handleConfirmDelete = useCallback(async () => {\n\t\tif (!pendingDelete || !onDeleteAgent) {\n\t\t\treturn;\n\t\t}\n\t\tsetIsDeleting(true);\n\t\ttry {\n\t\t\tawait onDeleteAgent(pendingDelete);\n\t\t\tsetPendingDelete(null);\n\t\t} finally {\n\t\t\tsetIsDeleting(false);\n\t\t}\n\t}, [pendingDelete, onDeleteAgent]);\n\n\treturn (\n\t\t<Page data-test={rest['data-test'] ?? 'agent-listing'}>\n\t\t\t<AgentListingHeader\n\t\t\t\ttitle={title}\n\t\t\t\tonNewAgent={handleNewAgent}\n\t\t\t\tonBrowseTemplates={\n\t\t\t\t\tonBrowseTemplates ? handleBrowseTemplates : undefined\n\t\t\t\t}\n\t\t\t\theaderActions={headerActions}\n\t\t\t/>\n\n\t\t\t<AgentListingFilters\n\t\t\t\tsearchValue={searchValue}\n\t\t\t\tonSearchChange={handleSearchChange}\n\t\t\t\tonSearchSubmit={onSearchSubmit ? handleSearchSubmit : undefined}\n\t\t\t\tsearchPlaceholder={searchPlaceholder}\n\t\t\t\tfilterOptions={filterOptions}\n\t\t\t\tonFilterChange={onFilterChange ? handleFilterChange : undefined}\n\t\t\t\tfilterPlaceholder={filterPlaceholder}\n\t\t\t\tsortOptions={sortOptions}\n\t\t\t\tselectedSort={selectedSort}\n\t\t\t\tonSortChange={onSortChange ? handleSortChange : undefined}\n\t\t\t/>\n\n\t\t\t<Body>\n\t\t\t\t{isLoading ? (\n\t\t\t\t\t<AgentTableShimmer rows={Math.min(pagination?.pageSize ?? 5, 10)} />\n\t\t\t\t) : showEmpty ? (\n\t\t\t\t\t<EmptyHolder>\n\t\t\t\t\t\t<AiAgentsEmptyState\n\t\t\t\t\t\t\temptyState={emptyState}\n\t\t\t\t\t\t\tonNewAgent={handleNewAgent}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</EmptyHolder>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<AgentTable\n\t\t\t\t\t\t\tagents={agents}\n\t\t\t\t\t\t\ttriggerCountsLoading={triggerCountsLoading}\n\t\t\t\t\t\t\tonRunAgent={handleRunAgent}\n\t\t\t\t\t\t\tonEditAgent={handleEditAgent}\n\t\t\t\t\t\t\tonDeleteAgent={onDeleteAgent ? handleDeleteRequest : undefined}\n\t\t\t\t\t\t\tonRowClick={onRowClick ? handleRowClick : undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{pagination && pagination.totalRows > 0 && (\n\t\t\t\t\t\t\t<TablePagination\n\t\t\t\t\t\t\t\tpageNumber={pagination.pageNumber}\n\t\t\t\t\t\t\t\tpageSize={pagination.pageSize}\n\t\t\t\t\t\t\t\ttotalRows={pagination.totalRows}\n\t\t\t\t\t\t\t\thidePageSizeOptions={pagination.hidePageSizeOptions}\n\t\t\t\t\t\t\t\tupdatePageNumber={pagination.onPageChange}\n\t\t\t\t\t\t\t\tupdatePageSize={(opt) => {\n\t\t\t\t\t\t\t\t\tconst value = Number(unwrapDropdownValue(opt));\n\t\t\t\t\t\t\t\t\tif (!Number.isNaN(value)) {\n\t\t\t\t\t\t\t\t\t\tpagination.onPageSizeChange(value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</Body>\n\n\t\t\t{pendingDelete && (\n\t\t\t\t<DeleteAgentModal\n\t\t\t\t\tagentName={pendingDelete.name}\n\t\t\t\t\tisDeleting={isDeleting}\n\t\t\t\t\tonClose={() => (isDeleting ? undefined : setPendingDelete(null))}\n\t\t\t\t\tonConfirm={handleConfirmDelete}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Page>\n\t);\n};\n\nAgentListing.displayName = 'AgentListing';\n"],"names":["AgentListing","config","onSearchChange","onSearchSubmit","onFilterChange","onSortChange","onNewAgent","onBrowseTemplates","onRunAgent","onEditAgent","onDeleteAgent","onRowClick","rest","pendingDelete","setPendingDelete","useState","isDeleting","setIsDeleting","agents","isLoading","triggerCountsLoading","searchValue","searchPlaceholder","filterOptions","filterPlaceholder","sortOptions","selectedSort","title","headerActions","pagination","emptyState","debugLog","showEmpty","logAction","useCallback","action","args","handleSearchChange","v","handleSearchSubmit","handleFilterChange","selected","handleSortChange","handleNewAgent","handleBrowseTemplates","handleRunAgent","agent","handleEditAgent","handleRowClick","handleDeleteRequest","handleConfirmDelete","Page","jsx","AgentListingHeader","AgentListingFilters","Body","AgentTableShimmer","EmptyHolder","AiAgentsEmptyState","jsxs","Fragment","AgentTable","TablePagination","opt","value","unwrapDropdownValue","DeleteAgentModal"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),n=require("../zeroState/ZeroState.js"),i=({emptyState:t,onNewAgent:e})=>o.jsx(n.ZeroState,{title:t?.title??"No agents yet",subTitle:t?.subTitle??"Create your first AI agent to start automating conversations.",actionButton:t?.actionButton??{buttonText:"New AI agent",buttonType:"primary",size:"small",onClick:e}});exports.AiAgentsEmptyState=i;
|
|
2
|
+
//# sourceMappingURL=AiAgentsEmptyState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiAgentsEmptyState.js","sources":["../../../../src/components/agent-listing/AiAgentsEmptyState.tsx"],"sourcesContent":["import React from 'react';\nimport { ButtonProps } from '@src/components/button/model';\nimport { ZeroState } from '@src/components/zeroState/ZeroState';\n\nexport interface AiAgentsEmptyStateProps {\n\t/**\n\t * Overrides for the default copy / CTA — e.g. the search-miss variant passes\n\t * \"No results found …\". Any omitted field falls back to the \"no agents yet\"\n\t * defaults below.\n\t */\n\temptyState?: {\n\t\ttitle?: string;\n\t\tsubTitle?: string;\n\t\tactionButton?: ButtonProps;\n\t};\n\t/** Runs the default \"New AI agent\" CTA when no override button is supplied. */\n\tonNewAgent: () => void;\n}\n\n/**\n * Zero state for the AI Agents listing — shown when there are no agents yet or a\n * search returns no hits. Renders the shared {@link ZeroState} with AI-agents\n * defaults; a consumer-supplied `emptyState` overrides any of the copy / CTA.\n */\nexport const AiAgentsEmptyState: React.FC<AiAgentsEmptyStateProps> = ({\n\temptyState,\n\tonNewAgent,\n}) => (\n\t<ZeroState\n\t\ttitle={emptyState?.title ?? 'No agents yet'}\n\t\tsubTitle={\n\t\t\temptyState?.subTitle ??\n\t\t\t'Create your first AI agent to start automating conversations.'\n\t\t}\n\t\tactionButton={\n\t\t\temptyState?.actionButton ?? {\n\t\t\t\tbuttonText: 'New AI agent',\n\t\t\t\tbuttonType: 'primary',\n\t\t\t\tsize: 'small',\n\t\t\t\tonClick: onNewAgent,\n\t\t\t}\n\t\t}\n\t/>\n);\n"],"names":["AiAgentsEmptyState","emptyState","onNewAgent","jsx","ZeroState"],"mappings":"4JAwBaA,EAAwD,CAAC,CACrE,WAAAC,EACA,WAAAC,CACD,IACCC,EAAAA,IAACC,EAAAA,UAAA,CACA,MAAOH,GAAY,OAAS,gBAC5B,SACCA,GAAY,UACZ,gEAED,aACCA,GAAY,cAAgB,CAC3B,WAAY,eACZ,WAAY,UACZ,KAAM,QACN,QAASC,CAAA,CACV,CAEF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),ge=require("../node_modules/@tiptap/core/dist/index.js"),T=require("@tiptap/react"),a=require("react"),Q=require("../components/TypographyStyle.js"),k=require("./BikEditor.styles.js"),Z=require("./BikEditor.types.js"),s=require("./BikEditor.utils.js"),he=require("./extensions/buildExtensions.js"),pe=require("./floating/LinkBubbleMenu.js"),Ce=require("../icons/BIK AI specific/WandSparkles.js"),ke=require("../icons/Actions/Formatting/Copy.js"),Se=require("../icons/Actions/Common actions/Code.js"),xe=require("../icons/Informational/General/Info.js");function ye(p){return Object.entries(p).map(([x,g])=>`${x.replace(/([A-Z])/g,C=>`-${C.toLowerCase()}`)}:${g}`).join(";")}const Be=(p,x)=>{const{initialContent:g,sections:C,features:S,disabled:K,maxCharacters:b,characterLimit:X,shortcuts:Y,sendShortcut:ee,mentions:d,slashCommands:h,link:te,onPaste:ne,onReady:E,onChange:R,onSend:y,onFocus:j,onBlur:v,onSelectionChange:z,minHeight:oe,maxHeight:se,style:re,className:ie,editorClassName:A,editorStyle:H,renderJsonError:J}=p,u=!!S?.jsonMode,[m,I]=a.useState(null),[ce,M]=a.useState(!1),[ae,L]=a.useState(u&&!(g??"").trim()),le=u?s.buildJsonCodeBlockHtml(g??""):C?.length?s.buildSectionedContent(s.normalizeHtml(g??""),C.map(e=>({...e,content:s.normalizeHtml(e.content)}))):s.normalizeHtml(g??""),B=a.useRef([]),O=a.useRef(!1),q=a.useRef(E);q.current=E;const F=a.useRef(R);F.current=R;const N=a.useRef(z);N.current=z;const P=a.useRef(Z.DEFAULT_FORMAT_STATE),w=a.useRef(j);w.current=j;const D=a.useRef(v);D.current=v;const U=a.useRef(y);U.current=y;const _=a.useRef(d?.agents??[]);_.current=d?.agents??[];const $=a.useRef(d?.teams??[]);$.current=d?.teams??[];const W=a.useRef(h?.items??[]);W.current=h?.items??[];const n=T.useEditor({extensions:he.buildExtensions({features:S,placeholder:p.placeholder,maxCharacters:b,characterLimit:X,hasSections:(C?.length??0)>0,mentions:{agents:d?_:void 0,teams:d?$:void 0},slashCommands:h?W:void 0,onPaste:ne,onSend:y?e=>U.current?.(e):void 0,sendShortcut:ee,shortcuts:Y,onMentionSelected:d?.onSelect,onSlashCommandSelected:h?.onSelect,renderMentionItem:d?.renderItem,renderMentionDropdown:d?.renderDropdown,removeMentionTriggerOnDismiss:d?.removeTriggerOnDismiss,renderMentionChipIcon:d?.renderChipIcon,renderSlashCommandItem:h?.renderItem,renderSlashCommandDropdown:h?.renderDropdown}),content:le,editable:!K,immediatelyRender:!1,editorProps:{attributes:{...A?{class:A}:{},...H?{style:ye(H)}:{}}},onUpdate:({editor:e})=>{if(F.current?.(s.extractContent(e)),u){const t=s.getCodeBlockText(e),o=s.parseJson(t);I(o.valid?null:o),L(!t.trim())}},onTransaction:({editor:e})=>{const t=s.extractActiveFormats(e),o=P.current;(o.bold!==t.bold||o.italic!==t.italic||o.underline!==t.underline||o.strike!==t.strike||o.bulletList!==t.bulletList||o.orderedList!==t.orderedList||o.blockquote!==t.blockquote||o.codeBlock!==t.codeBlock||o.superscript!==t.superscript||o.subscript!==t.subscript||o.textAlign!==t.textAlign||o.fontFamily!==t.fontFamily||o.fontSize!==t.fontSize||o.color!==t.color||o.highlight!==t.highlight||o.link?.href!==t.link?.href)&&(P.current=t,N.current?.(t))},onFocus:()=>w.current?.(),onBlur:()=>D.current?.()});function i(e){n?e(n):B.current.push(e)}a.useEffect(()=>{if(n&&(B.current.length>0&&B.current.splice(0).forEach(t=>t(n)),O.current||(O.current=!0,q.current?.()),u)){const e=s.getCodeBlockText(n),t=s.parseJson(e);I(t.valid?null:t),L(!e.trim())}},[n,u]),a.useImperativeHandle(x,()=>({focus:e=>i(t=>t.commands.focus(e)),blur:()=>i(e=>e.commands.blur()),clearContent:()=>i(e=>e.commands.clearContent(!0)),setContent:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.setContent(t,{emitUpdate:!0}))},insertContent:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContent(t))},insertInlineContent:e=>{i(t=>s.insertInlineHtml(t,e))},insertAtStart:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContentAt(1,t))},insertBlock:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContentAt(o.state.doc.content.size,t))},appendInline:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContentAt(o.state.doc.content.size-1,t))},insertAtEnd(e){this.insertBlock(e)},appendContent(e){this.appendInline(e)},getContent:()=>n?s.extractContent(n):{html:"",text:"",isEmpty:!0,characterCount:0},getJSON:()=>n?.getJSON()??null,getMentions:()=>{const e=new Set,t=new Set;return n?(n.state.doc.descendants(o=>{o.type.name==="mentionAgent"&&o.attrs.id!=null?e.add(String(o.attrs.id)):o.type.name==="mentionTeam"&&o.attrs.id!=null&&t.add(String(o.attrs.id))}),{agentIds:Array.from(e),teamIds:Array.from(t)}):{agentIds:[],teamIds:[]}},getCursorPosition:()=>{if(!n)return{from:0,to:0};const{from:e,to:t}=n.state.selection;return{from:e,to:t}},insertAtPosition:(e,t)=>{const o=s.normalizeHtml(t);i(r=>r.commands.insertContentAt(e,o))},getSelectedText:()=>{if(!n)return"";const{state:e}=n,{from:t,to:o,empty:r}=e.selection;if(!r)return e.doc.textBetween(t,o," ");const l=e.schema.marks.link;if(l){const f=ge.getMarkRange(e.doc.resolve(t),l);if(f)return e.doc.textBetween(f.from,f.to," ")}return""},getCharacterCount:()=>({count:n?.storage.characterCount?.characters?.()??n?.getText().length??0,limit:b??null}),getSectionContent:e=>n?s.extractSectionContent(n,e):{html:"",text:"",isEmpty:!0,characterCount:0},setSectionContent:(e,t)=>{const o=s.normalizeHtml(t);i(r=>s.setSectionContentInEditor(r,e,o))},focusSection:e=>{i(t=>{if(e==="body"){let r=t.state.doc.content.size-1;t.state.doc.descendants((l,f)=>(l.type.name==="sectionDivider"&&r===t.state.doc.content.size-1&&(r=f-1),r===t.state.doc.content.size-1)),r<1&&(r=1),t.chain().focus().setTextSelection(r).run();return}let o=-1;t.state.doc.descendants((r,l)=>{if(o!==-1)return!1;r.type.name==="sectionDivider"&&r.attrs.sectionId===e&&(o=l+r.nodeSize+1)}),o!==-1&&t.chain().focus().setTextSelection(o).run()})},clearSection:e=>{i(t=>s.setSectionContentInEditor(t,e,"<p></p>"))},getBodyContent:()=>n?s.extractBodyContent(n):{html:"",text:"",isEmpty:!0,characterCount:0},setBodyContent:e=>{const t=s.normalizeHtml(e);i(o=>s.setSectionContentInEditor(o,"body",t))},setBodyAndSections:(e,t)=>{const o=s.buildSectionedContent(s.normalizeHtml(e),t.map(r=>({id:r.id,content:s.normalizeHtml(r.content)})));i(r=>r.commands.setContent(o,{emitUpdate:!0}))},appendBodyContent:e=>{const t=s.normalizeHtml(e);i(o=>{const r=s.findSectionEndPos(o,"body");o.commands.insertContentAt(r-1,t,{parseOptions:{preserveWhitespace:!0}})})},insertAtSectionStart:(e,t)=>{const o=s.normalizeHtml(t);i(r=>{const l=s.findSectionStartPos(r,e);l!==-1&&r.commands.insertContentAt(l,o,{parseOptions:{preserveWhitespace:!0}})})},insertAtSectionEnd:(e,t)=>{const o=s.normalizeHtml(t);i(r=>{const l=s.findSectionEndPos(r,e);r.commands.insertContentAt(l,o,{parseOptions:{preserveWhitespace:!0}})})},getActiveFormats:()=>n?s.extractActiveFormats(n):Z.DEFAULT_FORMAT_STATE,actions:{toggleBold:()=>n?.chain().focus().toggleBold().run(),toggleItalic:()=>n?.chain().focus().toggleItalic().run(),toggleUnderline:()=>n?.chain().focus().toggleUnderline().run(),toggleStrike:()=>n?.chain().focus().toggleStrike().run(),toggleBulletList:()=>n?.chain().focus().toggleBulletList().run(),toggleOrderedList:()=>n?.chain().focus().toggleOrderedList().run(),toggleBlockquote:()=>n?.chain().focus().toggleBlockquote().run(),toggleCodeBlock:()=>n?.chain().focus().toggleCodeBlock().run(),setTextAlign:e=>n?.chain().focus().setTextAlign(e).run(),setFontFamily:e=>n?.chain().focus().setFontFamily(e).run(),setFontSize:e=>n?.chain().focus().setFontSize(e).run(),setColor:e=>n?.chain().focus().setColor(e).run(),setHighlight:e=>n?.chain().focus().toggleHighlight({color:e}).run(),unsetColor:()=>n?.chain().focus().unsetColor().run(),unsetHighlight:()=>n?.chain().focus().unsetHighlight().run(),setLink:(e,t)=>{n&&(t!==void 0?n.chain().focus().extendMarkRange("link").command(({tr:o,state:r})=>{const{from:l,to:f}=o.selection,V=r.schema.marks.link;if(!V)return!1;const me=r.schema.text(t,[V.create({href:e})]),fe=r.schema.text(" ");return o.replaceWith(l,f,[me,fe]),!0}).run():n.chain().focus().extendMarkRange("link").setLink({href:e}).insertContent(" ").run())},updateLink:e=>n?.chain().focus().extendMarkRange("link").setLink({href:e}).run(),removeLink:()=>n?.chain().focus().extendMarkRange("link").unsetLink().run(),insertEmoji:e=>n?.chain().focus().insertContent(e).run(),insertVariable:e=>n?.chain().focus().insertContent(`{{${e}}}`).run(),insertHtml:e=>n?.commands.insertContent(s.normalizeHtml(e)),undo:()=>n?.chain().focus().undo().run(),redo:()=>n?.chain().focus().redo().run(),canUndo:()=>n?.can().undo()??!1,canRedo:()=>n?.can().redo()??!1,toggleSuperscript:()=>n?.chain().focus().toggleSuperscript().run(),toggleSubscript:()=>n?.chain().focus().toggleSubscript().run(),insertImage:e=>n?.chain().focus().setImage({src:e}).run()},json:S?.jsonMode?{getText:()=>n?s.getCodeBlockText(n):"",setText:e=>i(t=>s.setCodeBlockText(t,e)),parse:()=>s.parseJson(n?s.getCodeBlockText(n):""),isValid:()=>s.parseJson(n?s.getCodeBlockText(n):"").valid,format:(e=2)=>i(t=>{const{valid:o,value:r}=s.parseJson(s.getCodeBlockText(t));!o||r===null||s.setCodeBlockText(t,JSON.stringify(r,null,e))}),minify:()=>i(e=>{const{valid:t,value:o}=s.parseJson(s.getCodeBlockText(e));!t||o===null||s.setCodeBlockText(e,JSON.stringify(o))})}:void 0}),[n]);const de=()=>{if(!n)return;const{valid:e,value:t}=s.parseJson(s.getCodeBlockText(n));!e||t===null||s.setCodeBlockText(n,JSON.stringify(t,null,2))},ue=()=>{n&&(navigator.clipboard?.writeText(s.getCodeBlockText(n)),M(!0),setTimeout(()=>M(!1),1500))};return n?c.jsxs(k.BikEditorShell,{minHeight:oe,maxHeight:se,tightParagraphs:!S?.richPaste,jsonMode:u,style:re,className:ie,children:[u&&c.jsxs(k.BikJsonHeader,{children:[c.jsx("span",{className:"bik-json-header-label",children:"JSON"}),c.jsxs("div",{className:"bik-json-header-actions",children:[c.jsxs("button",{type:"button",onClick:de,disabled:!!m,title:"Format JSON",children:[c.jsx(Ce.default,{size:16}),c.jsx(Q.BodyCaption,{children:"Beautify"})]}),c.jsxs("button",{type:"button",onClick:ue,title:"Copy JSON",children:[c.jsx(ke.default,{size:16}),ce&&c.jsx(Q.BodyCaption,{children:"Copied"})]})]})]}),u?c.jsxs(k.BikJsonBody,{$error:!!m,children:[c.jsx(T.EditorContent,{editor:n}),ae&&c.jsxs(k.BikJsonEmptyState,{"aria-hidden":!0,children:[c.jsx(Se.default,{size:20}),c.jsx("span",{children:p.placeholder??"Type or paste JSON here"})]})]}):c.jsx(T.EditorContent,{editor:n}),c.jsx(pe.LinkBubbleMenu,{editor:n,renderLinkTooltip:te?.renderTooltip}),u&&m?J?J(m):c.jsxs(k.BikJsonError,{children:[c.jsx(xe.default,{size:16}),c.jsxs("span",{children:[m.line!=null&&c.jsxs("strong",{children:["Line ",m.line,m.column!=null?`, column ${m.column}`:"",":"," "]}),m.error]})]}):null]}):null},G=a.forwardRef(Be);G.displayName="BikEditor";exports.BikEditor=G;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),he=require("../node_modules/@tiptap/core/dist/index.js"),T=require("@tiptap/react"),a=require("react"),Q=require("../components/TypographyStyle.js"),k=require("./BikEditor.styles.js"),Z=require("./BikEditor.types.js"),s=require("./BikEditor.utils.js"),pe=require("./extensions/buildExtensions.js"),Ce=require("./floating/LinkBubbleMenu.js"),ke=require("../icons/BIK AI specific/WandSparkles.js"),Se=require("../icons/Actions/Formatting/Copy.js"),xe=require("../icons/Actions/Common actions/Code.js"),ye=require("../icons/Informational/General/Info.js");function Be(p){return Object.entries(p).map(([x,g])=>`${x.replace(/([A-Z])/g,C=>`-${C.toLowerCase()}`)}:${g}`).join(";")}const Te=(p,x)=>{const{initialContent:g,sections:C,features:S,disabled:K,maxCharacters:b,characterLimit:X,characterLimitHard:Y,shortcuts:ee,sendShortcut:te,mentions:d,slashCommands:h,link:ne,onPaste:oe,onReady:E,onChange:R,onSend:y,onFocus:j,onBlur:v,onSelectionChange:z,minHeight:se,maxHeight:re,style:ie,className:ce,editorClassName:A,editorStyle:H,renderJsonError:J}=p,u=!!S?.jsonMode,[m,I]=a.useState(null),[ae,M]=a.useState(!1),[le,L]=a.useState(u&&!(g??"").trim()),de=u?s.buildJsonCodeBlockHtml(g??""):C?.length?s.buildSectionedContent(s.normalizeHtml(g??""),C.map(e=>({...e,content:s.normalizeHtml(e.content)}))):s.normalizeHtml(g??""),B=a.useRef([]),O=a.useRef(!1),q=a.useRef(E);q.current=E;const F=a.useRef(R);F.current=R;const N=a.useRef(z);N.current=z;const P=a.useRef(Z.DEFAULT_FORMAT_STATE),w=a.useRef(j);w.current=j;const D=a.useRef(v);D.current=v;const U=a.useRef(y);U.current=y;const _=a.useRef(d?.agents??[]);_.current=d?.agents??[];const $=a.useRef(d?.teams??[]);$.current=d?.teams??[];const W=a.useRef(h?.items??[]);W.current=h?.items??[];const n=T.useEditor({extensions:pe.buildExtensions({features:S,placeholder:p.placeholder,maxCharacters:b,characterLimit:X,characterLimitHard:Y,hasSections:(C?.length??0)>0,mentions:{agents:d?_:void 0,teams:d?$:void 0},slashCommands:h?W:void 0,onPaste:oe,onSend:y?e=>U.current?.(e):void 0,sendShortcut:te,shortcuts:ee,onMentionSelected:d?.onSelect,onSlashCommandSelected:h?.onSelect,renderMentionItem:d?.renderItem,renderMentionDropdown:d?.renderDropdown,removeMentionTriggerOnDismiss:d?.removeTriggerOnDismiss,renderMentionChipIcon:d?.renderChipIcon,renderSlashCommandItem:h?.renderItem,renderSlashCommandDropdown:h?.renderDropdown}),content:de,editable:!K,immediatelyRender:!1,editorProps:{attributes:{...A?{class:A}:{},...H?{style:Be(H)}:{}}},onUpdate:({editor:e})=>{if(F.current?.(s.extractContent(e)),u){const t=s.getCodeBlockText(e),o=s.parseJson(t);I(o.valid?null:o),L(!t.trim())}},onTransaction:({editor:e})=>{const t=s.extractActiveFormats(e),o=P.current;(o.bold!==t.bold||o.italic!==t.italic||o.underline!==t.underline||o.strike!==t.strike||o.bulletList!==t.bulletList||o.orderedList!==t.orderedList||o.blockquote!==t.blockquote||o.codeBlock!==t.codeBlock||o.superscript!==t.superscript||o.subscript!==t.subscript||o.textAlign!==t.textAlign||o.fontFamily!==t.fontFamily||o.fontSize!==t.fontSize||o.color!==t.color||o.highlight!==t.highlight||o.link?.href!==t.link?.href)&&(P.current=t,N.current?.(t))},onFocus:()=>w.current?.(),onBlur:()=>D.current?.()});function i(e){n?e(n):B.current.push(e)}a.useEffect(()=>{if(n&&(B.current.length>0&&B.current.splice(0).forEach(t=>t(n)),O.current||(O.current=!0,q.current?.()),u)){const e=s.getCodeBlockText(n),t=s.parseJson(e);I(t.valid?null:t),L(!e.trim())}},[n,u]),a.useImperativeHandle(x,()=>({focus:e=>i(t=>t.commands.focus(e)),blur:()=>i(e=>e.commands.blur()),clearContent:()=>i(e=>e.commands.clearContent(!0)),setContent:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.setContent(t,{emitUpdate:!0}))},insertContent:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContent(t))},insertInlineContent:e=>{i(t=>s.insertInlineHtml(t,e))},insertAtStart:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContentAt(1,t))},insertBlock:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContentAt(o.state.doc.content.size,t))},appendInline:e=>{const t=s.normalizeHtml(e);i(o=>o.commands.insertContentAt(o.state.doc.content.size-1,t))},insertAtEnd(e){this.insertBlock(e)},appendContent(e){this.appendInline(e)},getContent:()=>n?s.extractContent(n):{html:"",text:"",isEmpty:!0,characterCount:0},getJSON:()=>n?.getJSON()??null,getMentions:()=>{const e=new Set,t=new Set;return n?(n.state.doc.descendants(o=>{o.type.name==="mentionAgent"&&o.attrs.id!=null?e.add(String(o.attrs.id)):o.type.name==="mentionTeam"&&o.attrs.id!=null&&t.add(String(o.attrs.id))}),{agentIds:Array.from(e),teamIds:Array.from(t)}):{agentIds:[],teamIds:[]}},getCursorPosition:()=>{if(!n)return{from:0,to:0};const{from:e,to:t}=n.state.selection;return{from:e,to:t}},insertAtPosition:(e,t)=>{const o=s.normalizeHtml(t);i(r=>r.commands.insertContentAt(e,o))},getSelectedText:()=>{if(!n)return"";const{state:e}=n,{from:t,to:o,empty:r}=e.selection;if(!r)return e.doc.textBetween(t,o," ");const l=e.schema.marks.link;if(l){const f=he.getMarkRange(e.doc.resolve(t),l);if(f)return e.doc.textBetween(f.from,f.to," ")}return""},getCharacterCount:()=>({count:n?.storage.characterCount?.characters?.()??n?.getText().length??0,limit:b??null}),getSectionContent:e=>n?s.extractSectionContent(n,e):{html:"",text:"",isEmpty:!0,characterCount:0},setSectionContent:(e,t)=>{const o=s.normalizeHtml(t);i(r=>s.setSectionContentInEditor(r,e,o))},focusSection:e=>{i(t=>{if(e==="body"){let r=t.state.doc.content.size-1;t.state.doc.descendants((l,f)=>(l.type.name==="sectionDivider"&&r===t.state.doc.content.size-1&&(r=f-1),r===t.state.doc.content.size-1)),r<1&&(r=1),t.chain().focus().setTextSelection(r).run();return}let o=-1;t.state.doc.descendants((r,l)=>{if(o!==-1)return!1;r.type.name==="sectionDivider"&&r.attrs.sectionId===e&&(o=l+r.nodeSize+1)}),o!==-1&&t.chain().focus().setTextSelection(o).run()})},clearSection:e=>{i(t=>s.setSectionContentInEditor(t,e,"<p></p>"))},getBodyContent:()=>n?s.extractBodyContent(n):{html:"",text:"",isEmpty:!0,characterCount:0},setBodyContent:e=>{const t=s.normalizeHtml(e);i(o=>s.setSectionContentInEditor(o,"body",t))},setBodyAndSections:(e,t)=>{const o=s.buildSectionedContent(s.normalizeHtml(e),t.map(r=>({id:r.id,content:s.normalizeHtml(r.content)})));i(r=>r.commands.setContent(o,{emitUpdate:!0}))},appendBodyContent:e=>{const t=s.normalizeHtml(e);i(o=>{const r=s.findSectionEndPos(o,"body");o.commands.insertContentAt(r-1,t,{parseOptions:{preserveWhitespace:!0}})})},insertAtSectionStart:(e,t)=>{const o=s.normalizeHtml(t);i(r=>{const l=s.findSectionStartPos(r,e);l!==-1&&r.commands.insertContentAt(l,o,{parseOptions:{preserveWhitespace:!0}})})},insertAtSectionEnd:(e,t)=>{const o=s.normalizeHtml(t);i(r=>{const l=s.findSectionEndPos(r,e);r.commands.insertContentAt(l,o,{parseOptions:{preserveWhitespace:!0}})})},getActiveFormats:()=>n?s.extractActiveFormats(n):Z.DEFAULT_FORMAT_STATE,actions:{toggleBold:()=>n?.chain().focus().toggleBold().run(),toggleItalic:()=>n?.chain().focus().toggleItalic().run(),toggleUnderline:()=>n?.chain().focus().toggleUnderline().run(),toggleStrike:()=>n?.chain().focus().toggleStrike().run(),toggleBulletList:()=>n?.chain().focus().toggleBulletList().run(),toggleOrderedList:()=>n?.chain().focus().toggleOrderedList().run(),toggleBlockquote:()=>n?.chain().focus().toggleBlockquote().run(),toggleCodeBlock:()=>n?.chain().focus().toggleCodeBlock().run(),setTextAlign:e=>n?.chain().focus().setTextAlign(e).run(),setFontFamily:e=>n?.chain().focus().setFontFamily(e).run(),setFontSize:e=>n?.chain().focus().setFontSize(e).run(),setColor:e=>n?.chain().focus().setColor(e).run(),setHighlight:e=>n?.chain().focus().toggleHighlight({color:e}).run(),unsetColor:()=>n?.chain().focus().unsetColor().run(),unsetHighlight:()=>n?.chain().focus().unsetHighlight().run(),setLink:(e,t)=>{n&&(t!==void 0?n.chain().focus().extendMarkRange("link").command(({tr:o,state:r})=>{const{from:l,to:f}=o.selection,V=r.schema.marks.link;if(!V)return!1;const fe=r.schema.text(t,[V.create({href:e})]),ge=r.schema.text(" ");return o.replaceWith(l,f,[fe,ge]),!0}).run():n.chain().focus().extendMarkRange("link").setLink({href:e}).insertContent(" ").run())},updateLink:e=>n?.chain().focus().extendMarkRange("link").setLink({href:e}).run(),removeLink:()=>n?.chain().focus().extendMarkRange("link").unsetLink().run(),insertEmoji:e=>n?.chain().focus().insertContent(e).run(),insertVariable:e=>n?.chain().focus().insertContent(`{{${e}}}`).run(),insertHtml:e=>n?.commands.insertContent(s.normalizeHtml(e)),undo:()=>n?.chain().focus().undo().run(),redo:()=>n?.chain().focus().redo().run(),canUndo:()=>n?.can().undo()??!1,canRedo:()=>n?.can().redo()??!1,toggleSuperscript:()=>n?.chain().focus().toggleSuperscript().run(),toggleSubscript:()=>n?.chain().focus().toggleSubscript().run(),insertImage:e=>n?.chain().focus().setImage({src:e}).run()},json:S?.jsonMode?{getText:()=>n?s.getCodeBlockText(n):"",setText:e=>i(t=>s.setCodeBlockText(t,e)),parse:()=>s.parseJson(n?s.getCodeBlockText(n):""),isValid:()=>s.parseJson(n?s.getCodeBlockText(n):"").valid,format:(e=2)=>i(t=>{const{valid:o,value:r}=s.parseJson(s.getCodeBlockText(t));!o||r===null||s.setCodeBlockText(t,JSON.stringify(r,null,e))}),minify:()=>i(e=>{const{valid:t,value:o}=s.parseJson(s.getCodeBlockText(e));!t||o===null||s.setCodeBlockText(e,JSON.stringify(o))})}:void 0}),[n]);const ue=()=>{if(!n)return;const{valid:e,value:t}=s.parseJson(s.getCodeBlockText(n));!e||t===null||s.setCodeBlockText(n,JSON.stringify(t,null,2))},me=()=>{n&&(navigator.clipboard?.writeText(s.getCodeBlockText(n)),M(!0),setTimeout(()=>M(!1),1500))};return n?c.jsxs(k.BikEditorShell,{minHeight:se,maxHeight:re,tightParagraphs:!S?.richPaste,jsonMode:u,style:ie,className:ce,children:[u&&c.jsxs(k.BikJsonHeader,{children:[c.jsx("span",{className:"bik-json-header-label",children:"JSON"}),c.jsxs("div",{className:"bik-json-header-actions",children:[c.jsxs("button",{type:"button",onClick:ue,disabled:!!m,title:"Format JSON",children:[c.jsx(ke.default,{size:16}),c.jsx(Q.BodyCaption,{children:"Beautify"})]}),c.jsxs("button",{type:"button",onClick:me,title:"Copy JSON",children:[c.jsx(Se.default,{size:16}),ae&&c.jsx(Q.BodyCaption,{children:"Copied"})]})]})]}),u?c.jsxs(k.BikJsonBody,{$error:!!m,children:[c.jsx(T.EditorContent,{editor:n}),le&&c.jsxs(k.BikJsonEmptyState,{"aria-hidden":!0,children:[c.jsx(xe.default,{size:20}),c.jsx("span",{children:p.placeholder??"Type or paste JSON here"})]})]}):c.jsx(T.EditorContent,{editor:n}),c.jsx(Ce.LinkBubbleMenu,{editor:n,renderLinkTooltip:ne?.renderTooltip}),u&&m?J?J(m):c.jsxs(k.BikJsonError,{children:[c.jsx(ye.default,{size:16}),c.jsxs("span",{children:[m.line!=null&&c.jsxs("strong",{children:["Line ",m.line,m.column!=null?`, column ${m.column}`:"",":"," "]}),m.error]})]}):null]}):null},G=a.forwardRef(Te);G.displayName="BikEditor";exports.BikEditor=G;
|
|
2
2
|
//# sourceMappingURL=BikEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport { BodyCaption } from '@src/components/TypographyStyle';\nimport { Code, Copy, Info, WandSparkles } from '../icons';\nimport {\n\tBikEditorShell,\n\tBikJsonBody,\n\tBikJsonEmptyState,\n\tBikJsonError,\n\tBikJsonHeader,\n} from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n\tJsonParseResult,\n} from './BikEditor.types';\nimport {\n\tbuildJsonCodeBlockHtml,\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tgetCodeBlockText,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tparseJson,\n\tsetCodeBlockText,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tcharacterLimit,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t\trenderJsonError,\n\t} = props;\n\n\tconst isJsonMode = !!features?.jsonMode;\n\n\t// Live JSON parse error, shown inside the editor when jsonMode is on.\n\t// null = valid (or not applicable) → nothing rendered.\n\tconst [jsonError, setJsonError] = useState<JsonParseResult | null>(null);\n\t// Transient \"Copied\" state for the jsonMode copy button.\n\tconst [jsonCopied, setJsonCopied] = useState(false);\n\t// jsonMode: no content yet → centered code-glyph + placeholder overlay.\n\tconst [jsonEmpty, setJsonEmpty] = useState(\n\t\tisJsonMode && !(initialContent ?? '').trim(),\n\t);\n\n\t// JSON body mode: treat initialContent as raw JSON text and wrap it in a code\n\t// block. Skips section/HTML normalisation entirely.\n\tconst initialEditorContent = isJsonMode\n\t\t? buildJsonCodeBlockHtml(initialContent ?? '')\n\t\t: sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\tcharacterLimit,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\tremoveMentionTriggerOnDismiss: mentions?.removeTriggerOnDismiss,\n\t\t\trenderMentionChipIcon: mentions?.renderChipIcon,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t\tif (isJsonMode) {\n\t\t\t\tconst text = getCodeBlockText(e);\n\t\t\t\tconst result = parseJson(text);\n\t\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\t\tsetJsonEmpty(!text.trim());\n\t\t\t}\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t\t// Surface an error for invalid initialContent immediately on mount.\n\t\tif (isJsonMode) {\n\t\t\tconst text = getCodeBlockText(editor);\n\t\t\tconst result = parseJson(text);\n\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\tsetJsonEmpty(!text.trim());\n\t\t}\n\t}, [editor, isJsonMode]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1)\n\t\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\n\t\t\t// ── JSON body ─────────────────────────────────────────────────────\n\t\t\tjson: features?.jsonMode\n\t\t\t\t? {\n\t\t\t\t\t\tgetText: () => (editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tsetText: (raw) => enqueue((e) => setCodeBlockText(e, raw)),\n\t\t\t\t\t\tparse: () => parseJson(editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tisValid: () =>\n\t\t\t\t\t\t\tparseJson(editor ? getCodeBlockText(editor) : '').valid,\n\t\t\t\t\t\tformat: (indent = 2) =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value, null, indent));\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tminify: () =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value));\n\t\t\t\t\t\t\t}),\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\t// ── jsonMode floating actions ────────────────────────────────────────────\n\t// Beautify pretty-prints in place (no-op / disabled while the JSON is broken);\n\t// Copy writes the raw text to the clipboard with transient feedback.\n\tconst handleJsonBeautify = () => {\n\t\tif (!editor) return;\n\t\tconst { valid, value } = parseJson(getCodeBlockText(editor));\n\t\tif (!valid || value === null) return;\n\t\tsetCodeBlockText(editor, JSON.stringify(value, null, 2));\n\t};\n\tconst handleJsonCopy = () => {\n\t\tif (!editor) return;\n\t\tvoid navigator.clipboard?.writeText(getCodeBlockText(editor));\n\t\tsetJsonCopied(true);\n\t\tsetTimeout(() => setJsonCopied(false), 1500);\n\t};\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tjsonMode={isJsonMode}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t{isJsonMode && (\n\t\t\t\t<BikJsonHeader>\n\t\t\t\t\t<span className=\"bik-json-header-label\">JSON</span>\n\t\t\t\t\t<div className=\"bik-json-header-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleJsonBeautify}\n\t\t\t\t\t\t\tdisabled={!!jsonError}\n\t\t\t\t\t\t\ttitle=\"Format JSON\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<WandSparkles size={16} />\n\t\t\t\t\t\t\t<BodyCaption>Beautify</BodyCaption>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button type=\"button\" onClick={handleJsonCopy} title=\"Copy JSON\">\n\t\t\t\t\t\t\t<Copy size={16} />\n\t\t\t\t\t\t\t{jsonCopied && <BodyCaption>Copied</BodyCaption>}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</BikJsonHeader>\n\t\t\t)}\n\t\t\t{isJsonMode ? (\n\t\t\t\t<BikJsonBody $error={!!jsonError}>\n\t\t\t\t\t<EditorContent editor={editor} />\n\t\t\t\t\t{jsonEmpty && (\n\t\t\t\t\t\t<BikJsonEmptyState aria-hidden>\n\t\t\t\t\t\t\t<Code size={20} />\n\t\t\t\t\t\t\t<span>{props.placeholder ?? 'Type or paste JSON here'}</span>\n\t\t\t\t\t\t</BikJsonEmptyState>\n\t\t\t\t\t)}\n\t\t\t\t</BikJsonBody>\n\t\t\t) : (\n\t\t\t\t<EditorContent editor={editor} />\n\t\t\t)}\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t\t{isJsonMode && jsonError ? (\n\t\t\t\trenderJsonError ? (\n\t\t\t\t\trenderJsonError(jsonError)\n\t\t\t\t) : (\n\t\t\t\t\t<BikJsonError>\n\t\t\t\t\t\t<Info size={16} />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t{jsonError.line != null && (\n\t\t\t\t\t\t\t\t<strong>\n\t\t\t\t\t\t\t\t\tLine {jsonError.line}\n\t\t\t\t\t\t\t\t\t{jsonError.column != null\n\t\t\t\t\t\t\t\t\t\t? `, column ${jsonError.column}`\n\t\t\t\t\t\t\t\t\t\t: ''}\n\t\t\t\t\t\t\t\t\t:{' '}\n\t\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{jsonError.error}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</BikJsonError>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","k","v","c","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","characterLimit","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","renderJsonError","isJsonMode","jsonError","setJsonError","useState","jsonCopied","setJsonCopied","jsonEmpty","setJsonEmpty","initialEditorContent","buildJsonCodeBlockHtml","buildSectionedContent","normalizeHtml","s","pendingQueue","useRef","hasCalledOnReady","onReadyRef","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","teamMentionsRef","slashCommandsRef","editor","useEditor","buildExtensions","snapshot","extractContent","text","getCodeBlockText","result","parseJson","next","extractActiveFormats","prev","enqueue","op","useEffect","useImperativeHandle","position","e","html","normalised","insertInlineHtml","agentIds","teamIds","node","from","to","pos","state","empty","linkMarkType","range","getMarkRange","sectionId","extractSectionContent","setSectionContentInEditor","endOfBody","targetPos","extractBodyContent","body","boundaryPos","findSectionEndPos","findSectionStartPos","align","font","size","color","href","tr","linkNode","space","emoji","variableName","src","raw","setCodeBlockText","indent","valid","value","handleJsonBeautify","handleJsonCopy","jsxs","BikEditorShell","BikJsonHeader","jsx","WandSparkles","BodyCaption","Copy","BikJsonBody","EditorContent","BikJsonEmptyState","Code","LinkBubbleMenu","BikJsonError","Info","BikEditor","forwardRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport { BodyCaption } from '@src/components/TypographyStyle';\nimport { Code, Copy, Info, WandSparkles } from '../icons';\nimport {\n\tBikEditorShell,\n\tBikJsonBody,\n\tBikJsonEmptyState,\n\tBikJsonError,\n\tBikJsonHeader,\n} from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n\tJsonParseResult,\n} from './BikEditor.types';\nimport {\n\tbuildJsonCodeBlockHtml,\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tgetCodeBlockText,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tparseJson,\n\tsetCodeBlockText,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tcharacterLimit,\n\t\tcharacterLimitHard,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t\trenderJsonError,\n\t} = props;\n\n\tconst isJsonMode = !!features?.jsonMode;\n\n\t// Live JSON parse error, shown inside the editor when jsonMode is on.\n\t// null = valid (or not applicable) → nothing rendered.\n\tconst [jsonError, setJsonError] = useState<JsonParseResult | null>(null);\n\t// Transient \"Copied\" state for the jsonMode copy button.\n\tconst [jsonCopied, setJsonCopied] = useState(false);\n\t// jsonMode: no content yet → centered code-glyph + placeholder overlay.\n\tconst [jsonEmpty, setJsonEmpty] = useState(\n\t\tisJsonMode && !(initialContent ?? '').trim(),\n\t);\n\n\t// JSON body mode: treat initialContent as raw JSON text and wrap it in a code\n\t// block. Skips section/HTML normalisation entirely.\n\tconst initialEditorContent = isJsonMode\n\t\t? buildJsonCodeBlockHtml(initialContent ?? '')\n\t\t: sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\tcharacterLimit,\n\t\t\tcharacterLimitHard,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\tremoveMentionTriggerOnDismiss: mentions?.removeTriggerOnDismiss,\n\t\t\trenderMentionChipIcon: mentions?.renderChipIcon,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t\tif (isJsonMode) {\n\t\t\t\tconst text = getCodeBlockText(e);\n\t\t\t\tconst result = parseJson(text);\n\t\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\t\tsetJsonEmpty(!text.trim());\n\t\t\t}\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t\t// Surface an error for invalid initialContent immediately on mount.\n\t\tif (isJsonMode) {\n\t\t\tconst text = getCodeBlockText(editor);\n\t\t\tconst result = parseJson(text);\n\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\tsetJsonEmpty(!text.trim());\n\t\t}\n\t}, [editor, isJsonMode]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1)\n\t\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\n\t\t\t// ── JSON body ─────────────────────────────────────────────────────\n\t\t\tjson: features?.jsonMode\n\t\t\t\t? {\n\t\t\t\t\t\tgetText: () => (editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tsetText: (raw) => enqueue((e) => setCodeBlockText(e, raw)),\n\t\t\t\t\t\tparse: () => parseJson(editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tisValid: () =>\n\t\t\t\t\t\t\tparseJson(editor ? getCodeBlockText(editor) : '').valid,\n\t\t\t\t\t\tformat: (indent = 2) =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value, null, indent));\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tminify: () =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value));\n\t\t\t\t\t\t\t}),\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\t// ── jsonMode floating actions ────────────────────────────────────────────\n\t// Beautify pretty-prints in place (no-op / disabled while the JSON is broken);\n\t// Copy writes the raw text to the clipboard with transient feedback.\n\tconst handleJsonBeautify = () => {\n\t\tif (!editor) return;\n\t\tconst { valid, value } = parseJson(getCodeBlockText(editor));\n\t\tif (!valid || value === null) return;\n\t\tsetCodeBlockText(editor, JSON.stringify(value, null, 2));\n\t};\n\tconst handleJsonCopy = () => {\n\t\tif (!editor) return;\n\t\tvoid navigator.clipboard?.writeText(getCodeBlockText(editor));\n\t\tsetJsonCopied(true);\n\t\tsetTimeout(() => setJsonCopied(false), 1500);\n\t};\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tjsonMode={isJsonMode}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t{isJsonMode && (\n\t\t\t\t<BikJsonHeader>\n\t\t\t\t\t<span className=\"bik-json-header-label\">JSON</span>\n\t\t\t\t\t<div className=\"bik-json-header-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleJsonBeautify}\n\t\t\t\t\t\t\tdisabled={!!jsonError}\n\t\t\t\t\t\t\ttitle=\"Format JSON\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<WandSparkles size={16} />\n\t\t\t\t\t\t\t<BodyCaption>Beautify</BodyCaption>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button type=\"button\" onClick={handleJsonCopy} title=\"Copy JSON\">\n\t\t\t\t\t\t\t<Copy size={16} />\n\t\t\t\t\t\t\t{jsonCopied && <BodyCaption>Copied</BodyCaption>}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</BikJsonHeader>\n\t\t\t)}\n\t\t\t{isJsonMode ? (\n\t\t\t\t<BikJsonBody $error={!!jsonError}>\n\t\t\t\t\t<EditorContent editor={editor} />\n\t\t\t\t\t{jsonEmpty && (\n\t\t\t\t\t\t<BikJsonEmptyState aria-hidden>\n\t\t\t\t\t\t\t<Code size={20} />\n\t\t\t\t\t\t\t<span>{props.placeholder ?? 'Type or paste JSON here'}</span>\n\t\t\t\t\t\t</BikJsonEmptyState>\n\t\t\t\t\t)}\n\t\t\t\t</BikJsonBody>\n\t\t\t) : (\n\t\t\t\t<EditorContent editor={editor} />\n\t\t\t)}\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t\t{isJsonMode && jsonError ? (\n\t\t\t\trenderJsonError ? (\n\t\t\t\t\trenderJsonError(jsonError)\n\t\t\t\t) : (\n\t\t\t\t\t<BikJsonError>\n\t\t\t\t\t\t<Info size={16} />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t{jsonError.line != null && (\n\t\t\t\t\t\t\t\t<strong>\n\t\t\t\t\t\t\t\t\tLine {jsonError.line}\n\t\t\t\t\t\t\t\t\t{jsonError.column != null\n\t\t\t\t\t\t\t\t\t\t? `, column ${jsonError.column}`\n\t\t\t\t\t\t\t\t\t\t: ''}\n\t\t\t\t\t\t\t\t\t:{' '}\n\t\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{jsonError.error}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</BikJsonError>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","k","v","c","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","characterLimit","characterLimitHard","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","renderJsonError","isJsonMode","jsonError","setJsonError","useState","jsonCopied","setJsonCopied","jsonEmpty","setJsonEmpty","initialEditorContent","buildJsonCodeBlockHtml","buildSectionedContent","normalizeHtml","s","pendingQueue","useRef","hasCalledOnReady","onReadyRef","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","teamMentionsRef","slashCommandsRef","editor","useEditor","buildExtensions","snapshot","extractContent","text","getCodeBlockText","result","parseJson","next","extractActiveFormats","prev","enqueue","op","useEffect","useImperativeHandle","position","e","html","normalised","insertInlineHtml","agentIds","teamIds","node","from","to","pos","state","empty","linkMarkType","range","getMarkRange","sectionId","extractSectionContent","setSectionContentInEditor","endOfBody","targetPos","extractBodyContent","body","boundaryPos","findSectionEndPos","findSectionStartPos","align","font","size","color","href","tr","linkNode","space","emoji","variableName","src","raw","setCodeBlockText","indent","valid","value","handleJsonBeautify","handleJsonCopy","jsxs","BikEditorShell","BikJsonHeader","jsx","WandSparkles","BodyCaption","Copy","BikJsonBody","EditorContent","BikJsonEmptyState","Code","LinkBubbleMenu","BikJsonError","Info","BikEditor","forwardRef"],"mappings":"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"}
|