@bikdotai/bik-component-library 0.0.866 → 0.0.867
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/components/agent-builder/AgentBuilder.js +1 -1
- package/dist/cjs/components/agent-builder/AgentBuilder.js.map +1 -1
- package/dist/cjs/components/agent-builder/AgentBuilder.styled.js +151 -29
- package/dist/cjs/components/agent-builder/AgentBuilder.styled.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/ChannelSelectModal.js +2 -0
- package/dist/cjs/components/agent-builder/components/ChannelSelectModal.js.map +1 -0
- package/dist/cjs/components/agent-builder/components/ChannelsSection.js +2 -0
- package/dist/cjs/components/agent-builder/components/ChannelsSection.js.map +1 -0
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +5 -5
- package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.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 +2 -2
- package/dist/cjs/components/agent-builder/components/MentionEditor.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionField.js +1 -1
- package/dist/cjs/components/agent-builder/components/MentionField.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/MentionPicker.js +13 -13
- package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/cjs/components/agent-builder/components/SelectableListSection.js +3 -3
- package/dist/cjs/components/agent-builder/components/SelectableListSection.js.map +1 -1
- package/dist/cjs/components/agent-builder/constants/channels.js +2 -0
- package/dist/cjs/components/agent-builder/constants/channels.js.map +1 -0
- package/dist/cjs/components/agent-builder/constants/steps.js +1 -1
- package/dist/cjs/components/agent-builder/constants/steps.js.map +1 -1
- package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js +1 -1
- package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
- package/dist/cjs/components/agent-builder/steps/Step1About.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step1About.js.map +1 -1
- package/dist/cjs/components/agent-builder/steps/Step2WhenItStepsIn.js +2 -2
- package/dist/cjs/components/agent-builder/steps/Step2WhenItStepsIn.js.map +1 -1
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/cjs/components/agent-builder/steps/Step4HandoverRules.js +1 -1
- package/dist/cjs/components/agent-builder/steps/Step4HandoverRules.js.map +1 -1
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.js +2 -2
- package/dist/cjs/components/agent-builder/utils/mentionSerialization.js.map +1 -1
- package/dist/cjs/components/agent-builder/utils/sourceIcons.js +1 -1
- package/dist/cjs/components/agent-builder/utils/sourceIcons.js.map +1 -1
- package/dist/cjs/icons/Social/Channels/ManifestGlass.js +2 -0
- package/dist/cjs/icons/Social/Channels/ManifestGlass.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/ShipStation.js +2 -0
- package/dist/cjs/icons/Social/Channels/ShipStation.js.map +1 -0
- package/dist/cjs/icons/Social/Channels/Skio.js +2 -0
- package/dist/cjs/icons/Social/Channels/Skio.js.map +1 -0
- package/dist/cjs/icons/index.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/agent-builder/AgentBuilder.js +103 -97
- package/dist/esm/components/agent-builder/AgentBuilder.js.map +1 -1
- package/dist/esm/components/agent-builder/AgentBuilder.model.d.ts +76 -0
- package/dist/esm/components/agent-builder/AgentBuilder.styled.d.ts +68 -0
- package/dist/esm/components/agent-builder/AgentBuilder.styled.js +224 -59
- package/dist/esm/components/agent-builder/AgentBuilder.styled.js.map +1 -1
- package/dist/esm/components/agent-builder/components/ChannelSelectModal.d.ts +26 -0
- package/dist/esm/components/agent-builder/components/ChannelSelectModal.js +121 -0
- package/dist/esm/components/agent-builder/components/ChannelSelectModal.js.map +1 -0
- package/dist/esm/components/agent-builder/components/ChannelsSection.d.ts +10 -0
- package/dist/esm/components/agent-builder/components/ChannelsSection.js +183 -0
- package/dist/esm/components/agent-builder/components/ChannelsSection.js.map +1 -0
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +135 -132
- package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
- package/dist/esm/components/agent-builder/components/GoLiveModal.js +12 -12
- package/dist/esm/components/agent-builder/components/GoLiveModal.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionEditor.d.ts +2 -0
- package/dist/esm/components/agent-builder/components/MentionEditor.js +47 -45
- package/dist/esm/components/agent-builder/components/MentionEditor.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionField.js +52 -51
- package/dist/esm/components/agent-builder/components/MentionField.js.map +1 -1
- package/dist/esm/components/agent-builder/components/MentionPicker.d.ts +5 -0
- package/dist/esm/components/agent-builder/components/MentionPicker.js +134 -132
- package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
- package/dist/esm/components/agent-builder/components/SelectableListSection.d.ts +2 -0
- package/dist/esm/components/agent-builder/components/SelectableListSection.js +48 -46
- package/dist/esm/components/agent-builder/components/SelectableListSection.js.map +1 -1
- package/dist/esm/components/agent-builder/constants/channels.d.ts +56 -0
- package/dist/esm/components/agent-builder/constants/channels.js +41 -0
- package/dist/esm/components/agent-builder/constants/channels.js.map +1 -0
- package/dist/esm/components/agent-builder/constants/steps.d.ts +31 -1
- package/dist/esm/components/agent-builder/constants/steps.js +15 -6
- package/dist/esm/components/agent-builder/constants/steps.js.map +1 -1
- package/dist/esm/components/agent-builder/context/AgentBuilderContext.d.ts +13 -1
- package/dist/esm/components/agent-builder/context/AgentBuilderContext.js +157 -148
- package/dist/esm/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
- package/dist/esm/components/agent-builder/index.d.ts +5 -2
- package/dist/esm/components/agent-builder/steps/Step1About.js +15 -13
- package/dist/esm/components/agent-builder/steps/Step1About.js.map +1 -1
- package/dist/esm/components/agent-builder/steps/Step2WhenItStepsIn.js +55 -48
- package/dist/esm/components/agent-builder/steps/Step2WhenItStepsIn.js.map +1 -1
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +158 -157
- package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
- package/dist/esm/components/agent-builder/steps/Step4HandoverRules.d.ts +11 -0
- package/dist/esm/components/agent-builder/steps/Step4HandoverRules.js +127 -23
- package/dist/esm/components/agent-builder/steps/Step4HandoverRules.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/mentionSerialization.d.ts +10 -3
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js +31 -23
- package/dist/esm/components/agent-builder/utils/mentionSerialization.js.map +1 -1
- package/dist/esm/components/agent-builder/utils/sourceIcons.d.ts +7 -5
- package/dist/esm/components/agent-builder/utils/sourceIcons.js +26 -26
- package/dist/esm/components/agent-builder/utils/sourceIcons.js.map +1 -1
- package/dist/esm/icons/Social/Channels/ManifestGlass.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/ManifestGlass.js +252 -0
- package/dist/esm/icons/Social/Channels/ManifestGlass.js.map +1 -0
- package/dist/esm/icons/Social/Channels/ShipStation.d.ts +6 -0
- package/dist/esm/icons/Social/Channels/ShipStation.js +31 -0
- package/dist/esm/icons/Social/Channels/ShipStation.js.map +1 -0
- package/dist/esm/icons/Social/Channels/Skio.d.ts +6 -0
- package/dist/{cjs/assets/icons/Skio.svg.js → esm/icons/Social/Channels/Skio.js} +31 -2
- package/dist/esm/icons/Social/Channels/Skio.js.map +1 -0
- package/dist/esm/icons/Social/Channels/index.d.ts +3 -0
- package/dist/esm/icons/index.d.ts +25 -25
- package/dist/esm/icons/index.js +330 -324
- package/dist/esm/icons/index.js.map +1 -1
- package/dist/esm/index.js +671 -663
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/assets/icons/BigCommerce.svg.js +0 -2
- package/dist/cjs/assets/icons/BigCommerce.svg.js.map +0 -1
- package/dist/cjs/assets/icons/Gorgias.svg.js +0 -2
- package/dist/cjs/assets/icons/Gorgias.svg.js.map +0 -1
- package/dist/cjs/assets/icons/ManifestGlass.svg.js +0 -2
- package/dist/cjs/assets/icons/ManifestGlass.svg.js.map +0 -1
- package/dist/cjs/assets/icons/ShipStation.svg.js +0 -2
- package/dist/cjs/assets/icons/ShipStation.svg.js.map +0 -1
- package/dist/cjs/assets/icons/Shopify.svg.js +0 -2
- package/dist/cjs/assets/icons/Shopify.svg.js.map +0 -1
- package/dist/cjs/assets/icons/Skio.svg.js.map +0 -1
- package/dist/esm/assets/icons/BigCommerce.svg.js +0 -6
- package/dist/esm/assets/icons/BigCommerce.svg.js.map +0 -1
- package/dist/esm/assets/icons/Gorgias.svg.js +0 -6
- package/dist/esm/assets/icons/Gorgias.svg.js.map +0 -1
- package/dist/esm/assets/icons/ManifestGlass.svg.js +0 -6
- package/dist/esm/assets/icons/ManifestGlass.svg.js.map +0 -1
- package/dist/esm/assets/icons/ShipStation.svg.js +0 -6
- package/dist/esm/assets/icons/ShipStation.svg.js.map +0 -1
- package/dist/esm/assets/icons/Shopify.svg.js +0 -6
- package/dist/esm/assets/icons/Shopify.svg.js.map +0 -1
- package/dist/esm/assets/icons/Skio.svg.js +0 -6
- package/dist/esm/assets/icons/Skio.svg.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectableListSection.js","sources":["../../../../../src/components/agent-builder/components/SelectableListSection.tsx"],"sourcesContent":["import DeleteIcon from '@src/assets/icons/delete.svg';\nimport EditIcon from '@src/assets/icons/edit.svg';\nimport PlusIcon from '@src/assets/icons/plus.svg';\nimport { MentionItem } from '@src/editor';\nimport { Shield } from '@src/icons';\nimport React, { useEffect, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { Dropdown, unwrapDropdownValue } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { DeleteConfirmationModal } from '@src/components/states-modal';\nimport { Tooltip } from '@src/components/tooltips';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tAddIconButton,\n\tRowActionDivider,\n\tRowActions,\n\tRowLabel,\n\tRowMenuButton,\n\tRowText,\n\tSelectableRow,\n\tSideSection,\n\tSideSectionHeader,\n\tSourceButton,\n\tSourceButtonRow,\n} from '../AgentBuilder.styled';\nimport { isIntegrationSource, ToolAction } from '../constants/tools';\nimport { renderSourceIcon, sourceIcon, SourceIcon } from '../utils/sourceIcons';\nimport { MentionPicker } from './MentionPicker';\n\nexport interface SelectableItem {\n\tid: string;\n\tlabel: string;\n\t/** Leading brand glyph (e.g. a tool's source icon). */\n\ticon?: SourceIcon;\n\t/**\n\t * True when the tool touches customer-private data and the agent must verify\n\t * the customer first (backend `auth_required`). Shows a shield glyph on the row.\n\t */\n\tauthRequired?: boolean;\n\t/**\n\t * When set, this row shows an edit (Configure) icon that calls this instead of\n\t * the section-level `onConfigure`. Use for rows that open their own drawer\n\t * (e.g. a configured Rest API / email-handover tool). A pending promise\n\t * disables the row's edit button until it settles (e.g. while the consumer\n\t * fetches the sub-agent's data before opening its drawer).\n\t */\n\tonConfigure?: () => void | Promise<void>;\n}\n\n/** A tool source for the empty-state picker (Tools): a button → its searchable list. */\nexport interface SourceGroup {\n\tsource: string;\n\tlabel: string;\n\toptions: SingleOption[];\n\t/**\n\t * Integration connection state for this source. `false` = the store hasn't\n\t * connected it → clicking the source button calls {@link onConnect} instead of\n\t * opening its tool list. `true`/absent → opens normally.\n\t */\n\tconnected?: boolean;\n\t/** Open the connect flow for this source (used when `connected === false`). */\n\tonConnect?: () => void;\n}\n\n/** Sentinel value for the \"create new\" entry in the add dropdown. */\nconst CREATE_OPTION_VALUE = '__bik_create_new__';\n\ninterface SelectableListSectionProps {\n\ttitle: string;\n\thelper?: string;\n\titems: SelectableItem[];\n\t/**\n\t * Options shown in the add dropdown. Pass ALL items (not just unselected\n\t * ones) when re-picking an already-added item is allowed (e.g. to insert its\n\t * mention again) — the chip list still shows each item only once.\n\t */\n\taddableOptions: SingleOption[];\n\tonAdd: (id: string) => void;\n\tonRemove: (id: string) => void;\n\tdataTestPrefix: string;\n\temptyText: string;\n\t/**\n\t * Adds a \"create new\" entry at the top of the add dropdown (e.g. \"Create\n\t * sub-agent\"). Selecting it calls `onSelect` instead of `onAdd`.\n\t */\n\tcreateOption?: { label: string; onSelect: () => void };\n\t/**\n\t * When provided, each row shows an edit (Configure) icon next to Delete.\n\t * Omit for tools (Delete only). A pending promise disables the edit buttons\n\t * until it settles.\n\t */\n\tonConfigure?: (id: string) => void | Promise<void>;\n\t/**\n\t * Tool sources (e.g. Manifest / Shopify). When set, the empty state shows a\n\t * button per source; clicking one reveals a searchable dropdown of just that\n\t * source's options. Selecting calls `onAdd`. Takes precedence over the plain\n\t * `addableOptions` dropdown.\n\t */\n\tsourceGroups?: SourceGroup[];\n\t/**\n\t * When provided, the header \"+\" opens the same `@` reference picker used in the\n\t * Instructions editor (a {@link MentionPicker} popover) instead of the inline\n\t * select dropdown. Pass the items for THIS section only (tools OR sub-agents) —\n\t * the picker auto-drills into the single category. Selecting a row calls\n\t * `onAdd(id)`; the picker's \"Create new\" row (sub-agents) calls\n\t * `createOption.onSelect`.\n\t */\n\tmentionItems?: MentionItem[];\n\t/**\n\t * Built-in \"action\" tools (e.g. Rest API / Handover to email) that open a\n\t * config drawer via `onSelect` instead of adding a mention. Shown as\n\t * empty-state source buttons (only while no items exist, alongside\n\t * `sourceGroups`) AND as rows inside the `@` picker's Tools view.\n\t */\n\tactionSources?: ToolAction[];\n\t/**\n\t * When set, the row Delete icon opens a confirmation modal (instead of\n\t * removing immediately); `onRemove` runs only on confirm. `noun` fills the one\n\t * shared message template (\"Delete this <noun>?\" …); `zIndex` raises the modal\n\t * above a parent drawer. Omit to delete directly.\n\t */\n\tconfirmDelete?: { noun: string; zIndex?: number };\n\t/**\n\t * Open the `@` picker popover above the trigger instead of below. Use inside\n\t * a drawer where the section sits near the bottom — opening downward\n\t * stretches the drawer and leaves a gap.\n\t */\n\tpickerOpensUp?: boolean;\n}\n\nexport const SelectableListSection: React.FC<SelectableListSectionProps> = ({\n\ttitle,\n\thelper,\n\titems,\n\taddableOptions,\n\tonAdd,\n\tonRemove,\n\tdataTestPrefix,\n\temptyText,\n\tcreateOption,\n\tonConfigure,\n\tsourceGroups,\n\tmentionItems,\n\tactionSources,\n\tconfirmDelete,\n\tpickerOpensUp,\n}) => {\n\tconst [adding, setAdding] = useState(false);\n\t// Row id awaiting delete confirmation (null = modal closed).\n\tconst [pendingDeleteId, setPendingDeleteId] = useState<string | null>(null);\n\t// Row id whose configure handler is in flight (async fetch before its drawer\n\t// opens) — all edit buttons are disabled meanwhile so the UI isn't\n\t// unresponsive to double clicks.\n\tconst [configuringId, setConfiguringId] = useState<string | null>(null);\n\t// Tools: which source's searchable list is open (null = just show the buttons).\n\tconst [activeSource, setActiveSource] = useState<string | null>(null);\n\tconst hasSourceGroups = !!sourceGroups && sourceGroups.length > 0;\n\tconst activeGroup = sourceGroups?.find((g) => g.source === activeSource);\n\t// When set, \"+\" opens the `@` MentionPicker popover instead of a select input.\n\tconst usePicker = mentionItems !== undefined;\n\t// Separate anchors for the header \"+\" popover and the empty-state source-button\n\t// popover — when empty both render at once, so a shared ref would misfire the\n\t// outside-click check (closing the header picker when a source row is clicked).\n\tconst headerPickerRef = useRef<HTMLDivElement>(null);\n\tconst sourcePickerRef = useRef<HTMLDivElement>(null);\n\t// Source (Shopify / Manifest) the empty-state button opened the picker into;\n\t// null when \"+\" opened it at the root source list.\n\tconst [pickerSource, setPickerSource] = useState<string | null>(null);\n\n\t// Dismiss the picker popover on outside click / Escape.\n\tuseEffect(() => {\n\t\tif (!usePicker || !adding) {\n\t\t\treturn;\n\t\t}\n\t\tconst onDocMouseDown = (e: MouseEvent) => {\n\t\t\tconst target = e.target as Node;\n\t\t\tif (\n\t\t\t\t!headerPickerRef.current?.contains(target) &&\n\t\t\t\t!sourcePickerRef.current?.contains(target)\n\t\t\t) {\n\t\t\t\tsetAdding(false);\n\t\t\t}\n\t\t};\n\t\tconst onKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tsetAdding(false);\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('mousedown', onDocMouseDown);\n\t\tdocument.addEventListener('keydown', onKeyDown);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('mousedown', onDocMouseDown);\n\t\t\tdocument.removeEventListener('keydown', onKeyDown);\n\t\t};\n\t}, [usePicker, adding]);\n\n\t// Header \"+\" picks an EXISTING item (and, once some exist, re-creates via the\n\t// dropdown's footer row). With an empty list + a createOption the body shows a\n\t// dedicated \"Create new\" button instead, so the header \"+\" would be redundant.\n\t// In picker mode the \"+\" always shows (even empty) — for tools it sits next to\n\t// the empty-state source buttons; the create flow lives inside the picker.\n\tconst showAddButton = hasSourceGroups\n\t\t? usePicker || items.length > 0\n\t\t: usePicker ||\n\t\t addableOptions.length > 0 ||\n\t\t (!!createOption && items.length > 0);\n\t// Empty state offers a one-click \"Create new\" (sub-agents) rather than burying\n\t// it behind a single-item dropdown. In picker mode the \"+\" opens the picker\n\t// (with its own \"Create new\" row) instead, so skip the standalone button.\n\tconst showEmptyCreate =\n\t\titems.length === 0 && !!createOption && !hasSourceGroups && !usePicker;\n\tconst hasActionSources = !!actionSources && actionSources.length > 0;\n\t// Source buttons ONLY while no item is added — the tool sources (Manifest /\n\t// Shopify …) plus the built-in action tools (Rest API / Handover to email).\n\t// Once an item exists, adding more uses the header \"+\" → picker (the buttons\n\t// never come back); the action tools still live inside that picker.\n\tconst showSourceButtons =\n\t\t(hasSourceGroups || hasActionSources) && items.length === 0;\n\t// Nothing existing to pick → skip the 1-item dropdown and create directly.\n\tconst handleAddClick = () => {\n\t\tif (usePicker) {\n\t\t\t// Nothing to pick yet and a create flow exists (e.g. Sub-agents with none\n\t\t\t// added) → skip the empty picker and open the create drawer directly,\n\t\t\t// mirroring the single-tool \"one level up\" collapse.\n\t\t\tif ((mentionItems?.length ?? 0) === 0 && createOption) {\n\t\t\t\tcreateOption.onSelect();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Toggle the `@` reference-picker popover (rendered under the \"+\"), opened\n\t\t\t// at the root source list (no pre-drilled source).\n\t\t\tsetPickerSource(null);\n\t\t\tsetAdding((v) => !v);\n\t\t\treturn;\n\t\t}\n\t\tif (hasSourceGroups) {\n\t\t\tsetActiveSource(null);\n\t\t\tsetAdding((v) => !v);\n\t\t\treturn;\n\t\t}\n\t\tif (addableOptions.length === 0 && createOption) {\n\t\t\tcreateOption.onSelect();\n\t\t\treturn;\n\t\t}\n\t\tsetAdding((v) => !v);\n\t};\n\n\t// Run a row's configure handler; a returned promise disables the edit\n\t// buttons until it settles (same promise-sniff as the drawer Save buttons).\n\tconst handleConfigureClick = (\n\t\tid: string,\n\t\tconfigure: () => void | Promise<void>,\n\t) => {\n\t\tif (configuringId) {\n\t\t\treturn;\n\t\t}\n\t\tconst result = configure();\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetConfiguringId(id);\n\t\t\tvoid (result as Promise<void>).finally(() => setConfiguringId(null));\n\t\t}\n\t};\n\n\tconst renderChipRows = () =>\n\t\titems.map((item) => {\n\t\t\t// Per-item configure wins; otherwise fall back to the section-level one.\n\t\t\tconst configure =\n\t\t\t\titem.onConfigure ??\n\t\t\t\t(onConfigure ? () => onConfigure(item.id) : undefined);\n\t\t\treturn (\n\t\t\t\t<SelectableRow\n\t\t\t\t\tkey={item.id}\n\t\t\t\t\tdata-test={`${dataTestPrefix}-row-${item.id}`}\n\t\t\t\t>\n\t\t\t\t\t{renderSourceIcon(item.icon)}\n\t\t\t\t\t{/* Label + verification shield on one row: label truncates, the shield\n\t\t\t\t\t sits just after the text. */}\n\t\t\t\t\t<RowLabel>\n\t\t\t\t\t\t{/* Row label truncates to one line; tooltip surfaces the full name. */}\n\t\t\t\t\t\t<Tooltip body={item.label} placement=\"top\">\n\t\t\t\t\t\t\t<RowText>\n\t\t\t\t\t\t\t\t<BodySecondary numberOfLines={1} color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t</RowText>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t{item.authRequired && (\n\t\t\t\t\t\t\t// Order tools touch customer-private data — the shield flags that\n\t\t\t\t\t\t\t// this agent must verify the customer before the tool can run.\n\t\t\t\t\t\t\t<Tooltip body=\"Requires customer verification\" placement=\"top\">\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-auth-${item.id}`}\n\t\t\t\t\t\t\t\t\tstyle={{ display: 'inline-flex', flexShrink: 0 }}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Shield size={16} />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</RowLabel>\n\t\t\t\t\t<RowActions>\n\t\t\t\t\t\t{configure && (\n\t\t\t\t\t\t\t// Configurable rows (sub-agents, Rest API / email tools) get an\n\t\t\t\t\t\t\t// always-visible edit icon.\n\t\t\t\t\t\t\t<Tooltip body=\"Edit\" placement=\"top\">\n\t\t\t\t\t\t\t\t<RowMenuButton\n\t\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-edit-${item.id}`}\n\t\t\t\t\t\t\t\t\taria-label={`Edit ${item.label}`}\n\t\t\t\t\t\t\t\t\tdisabled={configuringId !== null}\n\t\t\t\t\t\t\t\t\tonClick={() => handleConfigureClick(item.id, configure)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<EditIcon\n\t\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</RowMenuButton>\n\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{configure && <RowActionDivider aria-hidden />}\n\t\t\t\t\t\t<Tooltip body=\"Delete\" placement=\"top\">\n\t\t\t\t\t\t\t<RowMenuButton\n\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-delete-${item.id}`}\n\t\t\t\t\t\t\t\taria-label={`Delete ${item.label}`}\n\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\tconfirmDelete\n\t\t\t\t\t\t\t\t\t\t? setPendingDeleteId(item.id)\n\t\t\t\t\t\t\t\t\t\t: onRemove(item.id)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<DeleteIcon\n\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</RowMenuButton>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t</RowActions>\n\t\t\t\t</SelectableRow>\n\t\t\t);\n\t\t});\n\t// \"Create new\" is a brand-coloured footer row at the BOTTOM of the dropdown,\n\t// separated from the selectable items by a divider.\n\tconst dropdownOptions: SingleOption[] = createOption\n\t\t? [\n\t\t\t\t...addableOptions,\n\t\t\t\t{\n\t\t\t\t\tlabel: createOption.label,\n\t\t\t\t\tvalue: CREATE_OPTION_VALUE,\n\t\t\t\t\tsearchKey: createOption.label,\n\t\t\t\t\tcustomComponent: (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\twidth: '100%',\n\t\t\t\t\t\t\t\ttextAlign: 'center',\n\t\t\t\t\t\t\t\tcolor: COLORS.content.brand,\n\t\t\t\t\t\t\t\tfontFamily: 'Inter',\n\t\t\t\t\t\t\t\tfontSize: 14,\n\t\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{createOption.label}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t ]\n\t\t: addableOptions;\n\n\t// One picker instance reused by the header \"+\" and the empty-state source\n\t// buttons. `key` remounts it so a source button re-drills into its own tools\n\t// (the initial drill-in level is read once, on mount).\n\tconst pickerNode = usePicker ? (\n\t\t<MentionPicker\n\t\t\tkey={pickerSource ?? '__root__'}\n\t\t\titems={mentionItems ?? []}\n\t\t\tquery=\"\"\n\t\t\tactiveIndex={0}\n\t\t\tinitialSource={pickerSource ?? undefined}\n\t\t\tonSelect={(item) => {\n\t\t\t\tsetAdding(false);\n\t\t\t\tonAdd(String(item.id));\n\t\t\t}}\n\t\t\tonClose={() => setAdding(false)}\n\t\t\tonCreateSubAgent={\n\t\t\t\tcreateOption\n\t\t\t\t\t? () => {\n\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\tcreateOption.onSelect();\n\t\t\t\t\t }\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\ttoolActions={\n\t\t\t\thasActionSources\n\t\t\t\t\t? actionSources?.map((a) => ({\n\t\t\t\t\t\t\t...a,\n\t\t\t\t\t\t\tonSelect: () => {\n\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\ta.onSelect();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t }))\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\t// Gate native source rows in the picker on their connected state, derived\n\t\t\t// from the source groups (which already carry connected/onConnect). This is\n\t\t\t// what makes the \"+\" dropdown show \"Connect\" for unconnected vendors,\n\t\t\t// consistent with the empty-state buttons.\n\t\t\tintegrationStatus={Object.fromEntries(\n\t\t\t\t(sourceGroups ?? [])\n\t\t\t\t\t.filter((g) => g.connected !== undefined)\n\t\t\t\t\t.map((g) => [g.source, g.connected]),\n\t\t\t)}\n\t\t\tonConnectIntegration={(source) => {\n\t\t\t\tsetAdding(false);\n\t\t\t\tsourceGroups?.find((g) => g.source === source)?.onConnect?.();\n\t\t\t}}\n\t\t/>\n\t) : null;\n\n\treturn (\n\t\t<SideSection>\n\t\t\t<SideSectionHeader>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>{title}</TitleSmall>\n\t\t\t\t{showAddButton && (\n\t\t\t\t\t<AddButtonWrap ref={headerPickerRef}>\n\t\t\t\t\t\t<AddIconButton\n\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-add`}\n\t\t\t\t\t\t\tonClick={handleAddClick}\n\t\t\t\t\t\t\taria-label={`Add ${title}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<PlusIcon width={16} height={16} color={COLORS.content.primary} />\n\t\t\t\t\t\t</AddIconButton>\n\t\t\t\t\t\t{usePicker && adding && pickerSource === null && (\n\t\t\t\t\t\t\t<PickerPopover\n\t\t\t\t\t\t\t\t$up={pickerOpensUp}\n\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-picker`}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{pickerNode}\n\t\t\t\t\t\t\t</PickerPopover>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</AddButtonWrap>\n\t\t\t\t)}\n\t\t\t</SideSectionHeader>\n\n\t\t\t{helper && (\n\t\t\t\t<BodyCaption color={COLORS.content.secondary}>{helper}</BodyCaption>\n\t\t\t)}\n\n\t\t\t{showSourceButtons ? (\n\t\t\t\t<SourcePickerAnchor ref={usePicker ? sourcePickerRef : undefined}>\n\t\t\t\t\t{/* No tools yet: one button per source (never shown once a tool exists). */}\n\t\t\t\t\t<SourceButtonRow data-test={`${dataTestPrefix}-sources`}>\n\t\t\t\t\t\t{sourceGroups?.map((g) => {\n\t\t\t\t\t\t\t// A connected source with exactly one tool is pointless to drill\n\t\t\t\t\t\t\t// into — surface that single tool right here (its name + the source\n\t\t\t\t\t\t\t// icon) and add it on click, mirroring the `@` picker's single-leaf\n\t\t\t\t\t\t\t// collapse. Connect still wins when the source isn't connected.\n\t\t\t\t\t\t\t// Vendor integrations are exempt (same carve-out the picker makes):\n\t\t\t\t\t\t\t// each stays its own drill-in group so it reads as a discoverable,\n\t\t\t\t\t\t\t// connectable unit even when it serves a single tool.\n\t\t\t\t\t\t\tconst soleTool =\n\t\t\t\t\t\t\t\tg.connected !== false &&\n\t\t\t\t\t\t\t\tg.options.length === 1 &&\n\t\t\t\t\t\t\t\t!isIntegrationSource(g.source)\n\t\t\t\t\t\t\t\t\t? g.options[0]\n\t\t\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<SourceButton\n\t\t\t\t\t\t\t\t\tkey={g.source}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-source-${g.source}`}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t// Not connected → open the connect flow instead of the tools.\n\t\t\t\t\t\t\t\t\t\tif (g.connected === false) {\n\t\t\t\t\t\t\t\t\t\t\tg.onConnect?.();\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (soleTool) {\n\t\t\t\t\t\t\t\t\t\t\t// Single tool → add it directly (no drill-in).\n\t\t\t\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\t\t\t\tonAdd(soleTool.value);\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (usePicker) {\n\t\t\t\t\t\t\t\t\t\t\t// Open the `@` picker drilled straight into this source's tools.\n\t\t\t\t\t\t\t\t\t\t\tsetPickerSource(g.source);\n\t\t\t\t\t\t\t\t\t\t\tsetAdding(true);\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tsetActiveSource(g.source);\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\t\t{renderSourceIcon(sourceIcon(g.source), -4)}\n\t\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t\t{soleTool ? soleTool.label : g.label}\n\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t\t{g.connected === false && (\n\t\t\t\t\t\t\t\t\t\t// Not connected → show \"Connect\" upfront (consistent with\n\t\t\t\t\t\t\t\t\t\t// the `@` picker); clicking runs the connect flow.\n\t\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.brand}>\n\t\t\t\t\t\t\t\t\t\t\tConnect\n\t\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</SourceButton>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t\t{actionSources?.map((a) => (\n\t\t\t\t\t\t\t<SourceButton\n\t\t\t\t\t\t\t\tkey={a.source}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-action-${a.source}`}\n\t\t\t\t\t\t\t\t// Not connected → connect flow; otherwise close any open source\n\t\t\t\t\t\t\t\t// picker before opening this drawer, else the previous source's\n\t\t\t\t\t\t\t\t// popup lingers behind it.\n\t\t\t\t\t\t\t\tonClick={\n\t\t\t\t\t\t\t\t\ta.connected === false\n\t\t\t\t\t\t\t\t\t\t? () => a.onConnect?.()\n\t\t\t\t\t\t\t\t\t\t: () => {\n\t\t\t\t\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\t\t\t\t\ta.onSelect();\n\t\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\t\t{renderSourceIcon(a.icon, -4)}\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t{a.label}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t{a.connected === false && (\n\t\t\t\t\t\t\t\t\t// Not connected → \"Connect\" upfront (consistent with the\n\t\t\t\t\t\t\t\t\t// source buttons and the `@` picker).\n\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.brand}>\n\t\t\t\t\t\t\t\t\t\tConnect\n\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</SourceButton>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</SourceButtonRow>\n\n\t\t\t\t\t{/* Picker mode: clicking a source opens its tools in the `@` picker. */}\n\t\t\t\t\t{usePicker && adding && pickerSource !== null && (\n\t\t\t\t\t\t<PickerPopover\n\t\t\t\t\t\t\t$align=\"left\"\n\t\t\t\t\t\t\t$up={pickerOpensUp}\n\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-picker`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{pickerNode}\n\t\t\t\t\t\t</PickerPopover>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* Legacy (non-picker) mode: chosen source → its searchable tool list. */}\n\t\t\t\t\t{!usePicker && activeGroup && (\n\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-dropdown`}\n\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\tisSearchable\n\t\t\t\t\t\t\tplaceHolder={`Search ${activeGroup.label} tools`}\n\t\t\t\t\t\t\toptions={activeGroup.options}\n\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\t\t\tsetActiveSource(null);\n\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\t\t\tonAdd(v);\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</SourcePickerAnchor>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t{!usePicker && adding && dropdownOptions.length > 0 && (\n\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-dropdown`}\n\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\tisSearchable\n\t\t\t\t\t\t\tplaceHolder={`Select ${title.toLowerCase()}`}\n\t\t\t\t\t\t\toptions={dropdownOptions}\n\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\tif (!v) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (v === CREATE_OPTION_VALUE) {\n\t\t\t\t\t\t\t\t\tcreateOption?.onSelect();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tonAdd(v);\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\n\t\t\t\t\t{items.length === 0 && !adding ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.placeholder}>\n\t\t\t\t\t\t\t\t{emptyText}\n\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t{showEmptyCreate && createOption && (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-create`}\n\t\t\t\t\t\t\t\t\tbuttonType=\"secondary\"\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\tmatchParentWidth\n\t\t\t\t\t\t\t\t\tLeadingIcon={PlusIcon}\n\t\t\t\t\t\t\t\t\tbuttonText={createOption.label}\n\t\t\t\t\t\t\t\t\tonClick={createOption.onSelect}\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\t\trenderChipRows()\n\t\t\t\t\t)}\n\t\t\t\t</>\n\t\t\t)}\n\t\t\t{confirmDelete && pendingDeleteId && (\n\t\t\t\t<DeleteConfirmationModal\n\t\t\t\t\tdata-test={`${dataTestPrefix}-delete-confirm`}\n\t\t\t\t\theader={`Delete this ${confirmDelete.noun}?`}\n\t\t\t\t\tsubHeader={`Deleting this ${confirmDelete.noun} will also remove it from your instructions, wherever it's referenced.`}\n\t\t\t\t\tconfirmationText=\"Delete\"\n\t\t\t\t\tzIndex={confirmDelete.zIndex}\n\t\t\t\t\tonDeleteConfirmed={() => {\n\t\t\t\t\t\tonRemove(pendingDeleteId);\n\t\t\t\t\t\tsetPendingDeleteId(null);\n\t\t\t\t\t}}\n\t\t\t\t\tonCancelClicked={() => setPendingDeleteId(null)}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</SideSection>\n\t);\n};\n\n// Anchors the `@`-picker popover to the header \"+\" button.\nconst AddButtonWrap = styled.div`\n\tposition: relative;\n\tdisplay: flex;\n`;\n\n// Anchors the `@`-picker popover to the empty-state source buttons.\nconst SourcePickerAnchor = styled.div`\n\tposition: relative;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n`;\n\n// Floating card under the trigger. Aligns to the \"+\" (right) or the source\n// buttons (left) so it stays inside the side panel.\nconst PickerPopover = styled.div<{ $align?: 'left' | 'right'; $up?: boolean }>`\n\tposition: absolute;\n\t${(p) => (p.$up ? 'bottom: calc(100% + 4px);' : 'top: calc(100% + 4px);')}\n\t${(p) => (p.$align === 'left' ? 'left: 0;' : 'right: 0;')}\n\tz-index: 30;\n`;\n"],"names":["CREATE_OPTION_VALUE","SelectableListSection","title","helper","items","addableOptions","onAdd","onRemove","dataTestPrefix","emptyText","createOption","onConfigure","sourceGroups","mentionItems","actionSources","confirmDelete","pickerOpensUp","adding","setAdding","useState","pendingDeleteId","setPendingDeleteId","configuringId","setConfiguringId","activeSource","setActiveSource","hasSourceGroups","activeGroup","g","usePicker","headerPickerRef","useRef","sourcePickerRef","pickerSource","setPickerSource","useEffect","onDocMouseDown","e","target","onKeyDown","showAddButton","showEmptyCreate","hasActionSources","showSourceButtons","handleAddClick","v","handleConfigureClick","id","configure","result","renderChipRows","item","jsxs","SelectableRow","renderSourceIcon","RowLabel","jsx","Tooltip","RowText","BodySecondary","COLORS","Shield","RowActions","RowMenuButton","EditIcon","RowActionDivider","DeleteIcon","dropdownOptions","pickerNode","MentionPicker","a","source","SideSection","SideSectionHeader","TitleSmall","AddButtonWrap","AddIconButton","PlusIcon","PickerPopover","BodyCaption","SourcePickerAnchor","SourceButtonRow","soleTool","isIntegrationSource","SourceButton","sourceIcon","Dropdown","opt","unwrapDropdownValue","Fragment","Button","DeleteConfirmationModal","styled","p"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SelectableListSection.js","sources":["../../../../../src/components/agent-builder/components/SelectableListSection.tsx"],"sourcesContent":["import DeleteIcon from '@src/assets/icons/delete.svg';\nimport EditIcon from '@src/assets/icons/edit.svg';\nimport PlusIcon from '@src/assets/icons/plus.svg';\nimport { MentionItem } from '@src/editor';\nimport { Shield } from '@src/icons';\nimport React, { useEffect, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@src/components/button';\nimport { Dropdown, unwrapDropdownValue } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { DeleteConfirmationModal } from '@src/components/states-modal';\nimport { Tooltip } from '@src/components/tooltips';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tAddIconButton,\n\tRowActionDivider,\n\tRowActions,\n\tRowLabel,\n\tRowMenuButton,\n\tRowText,\n\tSelectableRow,\n\tSideSection,\n\tSideSectionHeader,\n\tSourceButton,\n\tSourceButtonRow,\n} from '../AgentBuilder.styled';\nimport { isIntegrationSource, ToolAction } from '../constants/tools';\nimport { renderSourceIcon, sourceIcon, SourceIcon } from '../utils/sourceIcons';\nimport { MentionPicker } from './MentionPicker';\n\nexport interface SelectableItem {\n\tid: string;\n\tlabel: string;\n\t/** Leading brand glyph (e.g. a tool's source icon). */\n\ticon?: SourceIcon;\n\t/**\n\t * True when the tool touches customer-private data and the agent must verify\n\t * the customer first (backend `auth_required`). Shows a shield glyph on the row.\n\t */\n\tauthRequired?: boolean;\n\t/**\n\t * When set, this row shows an edit (Configure) icon that calls this instead of\n\t * the section-level `onConfigure`. Use for rows that open their own drawer\n\t * (e.g. a configured Rest API / email-handover tool). A pending promise\n\t * disables the row's edit button until it settles (e.g. while the consumer\n\t * fetches the sub-agent's data before opening its drawer).\n\t */\n\tonConfigure?: () => void | Promise<void>;\n}\n\n/** A tool source for the empty-state picker (Tools): a button → its searchable list. */\nexport interface SourceGroup {\n\tsource: string;\n\tlabel: string;\n\toptions: SingleOption[];\n\t/**\n\t * Integration connection state for this source. `false` = the store hasn't\n\t * connected it → clicking the source button calls {@link onConnect} instead of\n\t * opening its tool list. `true`/absent → opens normally.\n\t */\n\tconnected?: boolean;\n\t/** Open the connect flow for this source (used when `connected === false`). */\n\tonConnect?: () => void;\n}\n\n/** Sentinel value for the \"create new\" entry in the add dropdown. */\nconst CREATE_OPTION_VALUE = '__bik_create_new__';\n\ninterface SelectableListSectionProps {\n\ttitle: string;\n\thelper?: string;\n\titems: SelectableItem[];\n\t/**\n\t * Options shown in the add dropdown. Pass ALL items (not just unselected\n\t * ones) when re-picking an already-added item is allowed (e.g. to insert its\n\t * mention again) — the chip list still shows each item only once.\n\t */\n\taddableOptions: SingleOption[];\n\tonAdd: (id: string) => void;\n\tonRemove: (id: string) => void;\n\tdataTestPrefix: string;\n\temptyText: string;\n\t/**\n\t * Adds a \"create new\" entry at the top of the add dropdown (e.g. \"Create\n\t * sub-agent\"). Selecting it calls `onSelect` instead of `onAdd`.\n\t */\n\tcreateOption?: { label: string; onSelect: () => void };\n\t/**\n\t * When provided, each row shows an edit (Configure) icon next to Delete.\n\t * Omit for tools (Delete only). A pending promise disables the edit buttons\n\t * until it settles.\n\t */\n\tonConfigure?: (id: string) => void | Promise<void>;\n\t/**\n\t * Tool sources (e.g. Manifest / Shopify). When set, the empty state shows a\n\t * button per source; clicking one reveals a searchable dropdown of just that\n\t * source's options. Selecting calls `onAdd`. Takes precedence over the plain\n\t * `addableOptions` dropdown.\n\t */\n\tsourceGroups?: SourceGroup[];\n\t/**\n\t * When provided, the header \"+\" opens the same `@` reference picker used in the\n\t * Instructions editor (a {@link MentionPicker} popover) instead of the inline\n\t * select dropdown. Pass the items for THIS section only (tools OR sub-agents) —\n\t * the picker auto-drills into the single category. Selecting a row calls\n\t * `onAdd(id)`; the picker's \"Create new\" row (sub-agents) calls\n\t * `createOption.onSelect`.\n\t */\n\tmentionItems?: MentionItem[];\n\t/**\n\t * Built-in \"action\" tools (e.g. Rest API / Handover to email) that open a\n\t * config drawer via `onSelect` instead of adding a mention. Shown as\n\t * empty-state source buttons (only while no items exist, alongside\n\t * `sourceGroups`) AND as rows inside the `@` picker's Tools view.\n\t */\n\tactionSources?: ToolAction[];\n\t/**\n\t * When set, the row Delete icon opens a confirmation modal (instead of\n\t * removing immediately); `onRemove` runs only on confirm. `noun` fills the one\n\t * shared message template (\"Delete this <noun>?\" …); `zIndex` raises the modal\n\t * above a parent drawer. Omit to delete directly.\n\t */\n\tconfirmDelete?: { noun: string; zIndex?: number };\n\t/**\n\t * Open the `@` picker popover above the trigger instead of below. Use inside\n\t * a drawer where the section sits near the bottom — opening downward\n\t * stretches the drawer and leaves a gap.\n\t */\n\tpickerOpensUp?: boolean;\n\t/** Host-app name for the native tool group (source buttons + `@` picker). */\n\tappLabel?: string;\n}\n\nexport const SelectableListSection: React.FC<SelectableListSectionProps> = ({\n\ttitle,\n\thelper,\n\titems,\n\taddableOptions,\n\tonAdd,\n\tonRemove,\n\tdataTestPrefix,\n\temptyText,\n\tcreateOption,\n\tonConfigure,\n\tsourceGroups,\n\tmentionItems,\n\tactionSources,\n\tconfirmDelete,\n\tpickerOpensUp,\n\tappLabel,\n}) => {\n\tconst [adding, setAdding] = useState(false);\n\t// Row id awaiting delete confirmation (null = modal closed).\n\tconst [pendingDeleteId, setPendingDeleteId] = useState<string | null>(null);\n\t// Row id whose configure handler is in flight (async fetch before its drawer\n\t// opens) — all edit buttons are disabled meanwhile so the UI isn't\n\t// unresponsive to double clicks.\n\tconst [configuringId, setConfiguringId] = useState<string | null>(null);\n\t// Tools: which source's searchable list is open (null = just show the buttons).\n\tconst [activeSource, setActiveSource] = useState<string | null>(null);\n\tconst hasSourceGroups = !!sourceGroups && sourceGroups.length > 0;\n\tconst activeGroup = sourceGroups?.find((g) => g.source === activeSource);\n\t// When set, \"+\" opens the `@` MentionPicker popover instead of a select input.\n\tconst usePicker = mentionItems !== undefined;\n\t// Separate anchors for the header \"+\" popover and the empty-state source-button\n\t// popover — when empty both render at once, so a shared ref would misfire the\n\t// outside-click check (closing the header picker when a source row is clicked).\n\tconst headerPickerRef = useRef<HTMLDivElement>(null);\n\tconst sourcePickerRef = useRef<HTMLDivElement>(null);\n\t// Source (Shopify / Manifest) the empty-state button opened the picker into;\n\t// null when \"+\" opened it at the root source list.\n\tconst [pickerSource, setPickerSource] = useState<string | null>(null);\n\n\t// Dismiss the picker popover on outside click / Escape.\n\tuseEffect(() => {\n\t\tif (!usePicker || !adding) {\n\t\t\treturn;\n\t\t}\n\t\tconst onDocMouseDown = (e: MouseEvent) => {\n\t\t\tconst target = e.target as Node;\n\t\t\tif (\n\t\t\t\t!headerPickerRef.current?.contains(target) &&\n\t\t\t\t!sourcePickerRef.current?.contains(target)\n\t\t\t) {\n\t\t\t\tsetAdding(false);\n\t\t\t}\n\t\t};\n\t\tconst onKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tsetAdding(false);\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('mousedown', onDocMouseDown);\n\t\tdocument.addEventListener('keydown', onKeyDown);\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('mousedown', onDocMouseDown);\n\t\t\tdocument.removeEventListener('keydown', onKeyDown);\n\t\t};\n\t}, [usePicker, adding]);\n\n\t// Header \"+\" picks an EXISTING item (and, once some exist, re-creates via the\n\t// dropdown's footer row). With an empty list + a createOption the body shows a\n\t// dedicated \"Create new\" button instead, so the header \"+\" would be redundant.\n\t// In picker mode the \"+\" always shows (even empty) — for tools it sits next to\n\t// the empty-state source buttons; the create flow lives inside the picker.\n\tconst showAddButton = hasSourceGroups\n\t\t? usePicker || items.length > 0\n\t\t: usePicker ||\n\t\t addableOptions.length > 0 ||\n\t\t (!!createOption && items.length > 0);\n\t// Empty state offers a one-click \"Create new\" (sub-agents) rather than burying\n\t// it behind a single-item dropdown. In picker mode the \"+\" opens the picker\n\t// (with its own \"Create new\" row) instead, so skip the standalone button.\n\tconst showEmptyCreate =\n\t\titems.length === 0 && !!createOption && !hasSourceGroups && !usePicker;\n\tconst hasActionSources = !!actionSources && actionSources.length > 0;\n\t// Source buttons ONLY while no item is added — the tool sources (Manifest /\n\t// Shopify …) plus the built-in action tools (Rest API / Handover to email).\n\t// Once an item exists, adding more uses the header \"+\" → picker (the buttons\n\t// never come back); the action tools still live inside that picker.\n\tconst showSourceButtons =\n\t\t(hasSourceGroups || hasActionSources) && items.length === 0;\n\t// Nothing existing to pick → skip the 1-item dropdown and create directly.\n\tconst handleAddClick = () => {\n\t\tif (usePicker) {\n\t\t\t// Nothing to pick yet and a create flow exists (e.g. Sub-agents with none\n\t\t\t// added) → skip the empty picker and open the create drawer directly,\n\t\t\t// mirroring the single-tool \"one level up\" collapse.\n\t\t\tif ((mentionItems?.length ?? 0) === 0 && createOption) {\n\t\t\t\tcreateOption.onSelect();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Toggle the `@` reference-picker popover (rendered under the \"+\"), opened\n\t\t\t// at the root source list (no pre-drilled source).\n\t\t\tsetPickerSource(null);\n\t\t\tsetAdding((v) => !v);\n\t\t\treturn;\n\t\t}\n\t\tif (hasSourceGroups) {\n\t\t\tsetActiveSource(null);\n\t\t\tsetAdding((v) => !v);\n\t\t\treturn;\n\t\t}\n\t\tif (addableOptions.length === 0 && createOption) {\n\t\t\tcreateOption.onSelect();\n\t\t\treturn;\n\t\t}\n\t\tsetAdding((v) => !v);\n\t};\n\n\t// Run a row's configure handler; a returned promise disables the edit\n\t// buttons until it settles (same promise-sniff as the drawer Save buttons).\n\tconst handleConfigureClick = (\n\t\tid: string,\n\t\tconfigure: () => void | Promise<void>,\n\t) => {\n\t\tif (configuringId) {\n\t\t\treturn;\n\t\t}\n\t\tconst result = configure();\n\t\tif (result && typeof (result as Promise<void>).then === 'function') {\n\t\t\tsetConfiguringId(id);\n\t\t\tvoid (result as Promise<void>).finally(() => setConfiguringId(null));\n\t\t}\n\t};\n\n\tconst renderChipRows = () =>\n\t\titems.map((item) => {\n\t\t\t// Per-item configure wins; otherwise fall back to the section-level one.\n\t\t\tconst configure =\n\t\t\t\titem.onConfigure ??\n\t\t\t\t(onConfigure ? () => onConfigure(item.id) : undefined);\n\t\t\treturn (\n\t\t\t\t<SelectableRow\n\t\t\t\t\tkey={item.id}\n\t\t\t\t\tdata-test={`${dataTestPrefix}-row-${item.id}`}\n\t\t\t\t>\n\t\t\t\t\t{renderSourceIcon(item.icon)}\n\t\t\t\t\t{/* Label + verification shield on one row: label truncates, the shield\n\t\t\t\t\t sits just after the text. */}\n\t\t\t\t\t<RowLabel>\n\t\t\t\t\t\t{/* Row label truncates to one line; tooltip surfaces the full name. */}\n\t\t\t\t\t\t<Tooltip body={item.label} placement=\"top\">\n\t\t\t\t\t\t\t<RowText>\n\t\t\t\t\t\t\t\t<BodySecondary numberOfLines={1} color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t</RowText>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t{item.authRequired && (\n\t\t\t\t\t\t\t// Order tools touch customer-private data — the shield flags that\n\t\t\t\t\t\t\t// this agent must verify the customer before the tool can run.\n\t\t\t\t\t\t\t<Tooltip body=\"Requires customer verification\" placement=\"top\">\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-auth-${item.id}`}\n\t\t\t\t\t\t\t\t\tstyle={{ display: 'inline-flex', flexShrink: 0 }}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Shield size={16} />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</RowLabel>\n\t\t\t\t\t<RowActions>\n\t\t\t\t\t\t{configure && (\n\t\t\t\t\t\t\t// Configurable rows (sub-agents, Rest API / email tools) get an\n\t\t\t\t\t\t\t// always-visible edit icon.\n\t\t\t\t\t\t\t<Tooltip body=\"Edit\" placement=\"top\">\n\t\t\t\t\t\t\t\t<RowMenuButton\n\t\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-edit-${item.id}`}\n\t\t\t\t\t\t\t\t\taria-label={`Edit ${item.label}`}\n\t\t\t\t\t\t\t\t\tdisabled={configuringId !== null}\n\t\t\t\t\t\t\t\t\tonClick={() => handleConfigureClick(item.id, configure)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<EditIcon\n\t\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</RowMenuButton>\n\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{configure && <RowActionDivider aria-hidden />}\n\t\t\t\t\t\t<Tooltip body=\"Delete\" placement=\"top\">\n\t\t\t\t\t\t\t<RowMenuButton\n\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-delete-${item.id}`}\n\t\t\t\t\t\t\t\taria-label={`Delete ${item.label}`}\n\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\tconfirmDelete\n\t\t\t\t\t\t\t\t\t\t? setPendingDeleteId(item.id)\n\t\t\t\t\t\t\t\t\t\t: onRemove(item.id)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<DeleteIcon\n\t\t\t\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\t\t\t\theight={16}\n\t\t\t\t\t\t\t\t\tcolor={COLORS.content.secondary}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</RowMenuButton>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t</RowActions>\n\t\t\t\t</SelectableRow>\n\t\t\t);\n\t\t});\n\t// \"Create new\" is a brand-coloured footer row at the BOTTOM of the dropdown,\n\t// separated from the selectable items by a divider.\n\tconst dropdownOptions: SingleOption[] = createOption\n\t\t? [\n\t\t\t\t...addableOptions,\n\t\t\t\t{\n\t\t\t\t\tlabel: createOption.label,\n\t\t\t\t\tvalue: CREATE_OPTION_VALUE,\n\t\t\t\t\tsearchKey: createOption.label,\n\t\t\t\t\tcustomComponent: (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\twidth: '100%',\n\t\t\t\t\t\t\t\ttextAlign: 'center',\n\t\t\t\t\t\t\t\tcolor: COLORS.content.brand,\n\t\t\t\t\t\t\t\tfontFamily: 'Inter',\n\t\t\t\t\t\t\t\tfontSize: 14,\n\t\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{createOption.label}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t ]\n\t\t: addableOptions;\n\n\t// One picker instance reused by the header \"+\" and the empty-state source\n\t// buttons. `key` remounts it so a source button re-drills into its own tools\n\t// (the initial drill-in level is read once, on mount).\n\tconst pickerNode = usePicker ? (\n\t\t<MentionPicker\n\t\t\tkey={pickerSource ?? '__root__'}\n\t\t\titems={mentionItems ?? []}\n\t\t\tquery=\"\"\n\t\t\tactiveIndex={0}\n\t\t\tinitialSource={pickerSource ?? undefined}\n\t\t\tonSelect={(item) => {\n\t\t\t\tsetAdding(false);\n\t\t\t\tonAdd(String(item.id));\n\t\t\t}}\n\t\t\tonClose={() => setAdding(false)}\n\t\t\tonCreateSubAgent={\n\t\t\t\tcreateOption\n\t\t\t\t\t? () => {\n\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\tcreateOption.onSelect();\n\t\t\t\t\t }\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\ttoolActions={\n\t\t\t\thasActionSources\n\t\t\t\t\t? actionSources?.map((a) => ({\n\t\t\t\t\t\t\t...a,\n\t\t\t\t\t\t\tonSelect: () => {\n\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\ta.onSelect();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t }))\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\t// Gate native source rows in the picker on their connected state, derived\n\t\t\t// from the source groups (which already carry connected/onConnect). This is\n\t\t\t// what makes the \"+\" dropdown show \"Connect\" for unconnected vendors,\n\t\t\t// consistent with the empty-state buttons.\n\t\t\tintegrationStatus={Object.fromEntries(\n\t\t\t\t(sourceGroups ?? [])\n\t\t\t\t\t.filter((g) => g.connected !== undefined)\n\t\t\t\t\t.map((g) => [g.source, g.connected]),\n\t\t\t)}\n\t\t\tonConnectIntegration={(source) => {\n\t\t\t\tsetAdding(false);\n\t\t\t\tsourceGroups?.find((g) => g.source === source)?.onConnect?.();\n\t\t\t}}\n\t\t\tappLabel={appLabel}\n\t\t/>\n\t) : null;\n\n\treturn (\n\t\t<SideSection>\n\t\t\t<SideSectionHeader>\n\t\t\t\t<TitleSmall color={COLORS.content.primary}>{title}</TitleSmall>\n\t\t\t\t{showAddButton && (\n\t\t\t\t\t<AddButtonWrap ref={headerPickerRef}>\n\t\t\t\t\t\t<AddIconButton\n\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-add`}\n\t\t\t\t\t\t\tonClick={handleAddClick}\n\t\t\t\t\t\t\taria-label={`Add ${title}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<PlusIcon width={16} height={16} color={COLORS.content.primary} />\n\t\t\t\t\t\t</AddIconButton>\n\t\t\t\t\t\t{usePicker && adding && pickerSource === null && (\n\t\t\t\t\t\t\t<PickerPopover\n\t\t\t\t\t\t\t\t$up={pickerOpensUp}\n\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-picker`}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{pickerNode}\n\t\t\t\t\t\t\t</PickerPopover>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</AddButtonWrap>\n\t\t\t\t)}\n\t\t\t</SideSectionHeader>\n\n\t\t\t{helper && (\n\t\t\t\t<BodyCaption color={COLORS.content.secondary}>{helper}</BodyCaption>\n\t\t\t)}\n\n\t\t\t{showSourceButtons ? (\n\t\t\t\t<SourcePickerAnchor ref={usePicker ? sourcePickerRef : undefined}>\n\t\t\t\t\t{/* No tools yet: one button per source (never shown once a tool exists). */}\n\t\t\t\t\t<SourceButtonRow data-test={`${dataTestPrefix}-sources`}>\n\t\t\t\t\t\t{sourceGroups?.map((g) => {\n\t\t\t\t\t\t\t// A connected source with exactly one tool is pointless to drill\n\t\t\t\t\t\t\t// into — surface that single tool right here (its name + the source\n\t\t\t\t\t\t\t// icon) and add it on click, mirroring the `@` picker's single-leaf\n\t\t\t\t\t\t\t// collapse. Connect still wins when the source isn't connected.\n\t\t\t\t\t\t\t// Vendor integrations are exempt (same carve-out the picker makes):\n\t\t\t\t\t\t\t// each stays its own drill-in group so it reads as a discoverable,\n\t\t\t\t\t\t\t// connectable unit even when it serves a single tool.\n\t\t\t\t\t\t\tconst soleTool =\n\t\t\t\t\t\t\t\tg.connected !== false &&\n\t\t\t\t\t\t\t\tg.options.length === 1 &&\n\t\t\t\t\t\t\t\t!isIntegrationSource(g.source)\n\t\t\t\t\t\t\t\t\t? g.options[0]\n\t\t\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<SourceButton\n\t\t\t\t\t\t\t\t\tkey={g.source}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-source-${g.source}`}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t// Not connected → open the connect flow instead of the tools.\n\t\t\t\t\t\t\t\t\t\tif (g.connected === false) {\n\t\t\t\t\t\t\t\t\t\t\tg.onConnect?.();\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (soleTool) {\n\t\t\t\t\t\t\t\t\t\t\t// Single tool → add it directly (no drill-in).\n\t\t\t\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\t\t\t\tonAdd(soleTool.value);\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (usePicker) {\n\t\t\t\t\t\t\t\t\t\t\t// Open the `@` picker drilled straight into this source's tools.\n\t\t\t\t\t\t\t\t\t\t\tsetPickerSource(g.source);\n\t\t\t\t\t\t\t\t\t\t\tsetAdding(true);\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tsetActiveSource(g.source);\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\t\t{renderSourceIcon(sourceIcon(g.source), -4)}\n\t\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t\t{soleTool ? soleTool.label : g.label}\n\t\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t\t{g.connected === false && (\n\t\t\t\t\t\t\t\t\t\t// Not connected → show \"Connect\" upfront (consistent with\n\t\t\t\t\t\t\t\t\t\t// the `@` picker); clicking runs the connect flow.\n\t\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.brand}>\n\t\t\t\t\t\t\t\t\t\t\tConnect\n\t\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</SourceButton>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t\t{actionSources?.map((a) => (\n\t\t\t\t\t\t\t<SourceButton\n\t\t\t\t\t\t\t\tkey={a.source}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-action-${a.source}`}\n\t\t\t\t\t\t\t\t// Not connected → connect flow; otherwise close any open source\n\t\t\t\t\t\t\t\t// picker before opening this drawer, else the previous source's\n\t\t\t\t\t\t\t\t// popup lingers behind it.\n\t\t\t\t\t\t\t\tonClick={\n\t\t\t\t\t\t\t\t\ta.connected === false\n\t\t\t\t\t\t\t\t\t\t? () => a.onConnect?.()\n\t\t\t\t\t\t\t\t\t\t: () => {\n\t\t\t\t\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\t\t\t\t\ta.onSelect();\n\t\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\t\t{renderSourceIcon(a.icon, -4)}\n\t\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t{a.label}\n\t\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t\t{a.connected === false && (\n\t\t\t\t\t\t\t\t\t// Not connected → \"Connect\" upfront (consistent with the\n\t\t\t\t\t\t\t\t\t// source buttons and the `@` picker).\n\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.brand}>\n\t\t\t\t\t\t\t\t\t\tConnect\n\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</SourceButton>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</SourceButtonRow>\n\n\t\t\t\t\t{/* Picker mode: clicking a source opens its tools in the `@` picker. */}\n\t\t\t\t\t{usePicker && adding && pickerSource !== null && (\n\t\t\t\t\t\t<PickerPopover\n\t\t\t\t\t\t\t$align=\"left\"\n\t\t\t\t\t\t\t$up={pickerOpensUp}\n\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-picker`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{pickerNode}\n\t\t\t\t\t\t</PickerPopover>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* Legacy (non-picker) mode: chosen source → its searchable tool list. */}\n\t\t\t\t\t{!usePicker && activeGroup && (\n\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-dropdown`}\n\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\tisSearchable\n\t\t\t\t\t\t\tplaceHolder={`Search ${activeGroup.label} tools`}\n\t\t\t\t\t\t\toptions={activeGroup.options}\n\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\t\t\tsetActiveSource(null);\n\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\t\t\tonAdd(v);\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</SourcePickerAnchor>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t{!usePicker && adding && dropdownOptions.length > 0 && (\n\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-dropdown`}\n\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\tisSearchable\n\t\t\t\t\t\t\tplaceHolder={`Select ${title.toLowerCase()}`}\n\t\t\t\t\t\t\toptions={dropdownOptions}\n\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\tconst v = unwrapDropdownValue(opt);\n\t\t\t\t\t\t\t\tsetAdding(false);\n\t\t\t\t\t\t\t\tif (!v) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (v === CREATE_OPTION_VALUE) {\n\t\t\t\t\t\t\t\t\tcreateOption?.onSelect();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tonAdd(v);\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\n\t\t\t\t\t{items.length === 0 && !adding ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<BodyCaption color={COLORS.content.placeholder}>\n\t\t\t\t\t\t\t\t{emptyText}\n\t\t\t\t\t\t\t</BodyCaption>\n\t\t\t\t\t\t\t{showEmptyCreate && createOption && (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tdata-test={`${dataTestPrefix}-create`}\n\t\t\t\t\t\t\t\t\tbuttonType=\"secondary\"\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\tmatchParentWidth\n\t\t\t\t\t\t\t\t\tLeadingIcon={PlusIcon}\n\t\t\t\t\t\t\t\t\tbuttonText={createOption.label}\n\t\t\t\t\t\t\t\t\tonClick={createOption.onSelect}\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\t\trenderChipRows()\n\t\t\t\t\t)}\n\t\t\t\t</>\n\t\t\t)}\n\t\t\t{confirmDelete && pendingDeleteId && (\n\t\t\t\t<DeleteConfirmationModal\n\t\t\t\t\tdata-test={`${dataTestPrefix}-delete-confirm`}\n\t\t\t\t\theader={`Delete this ${confirmDelete.noun}?`}\n\t\t\t\t\tsubHeader={`Deleting this ${confirmDelete.noun} will also remove it from your instructions, wherever it's referenced.`}\n\t\t\t\t\tconfirmationText=\"Delete\"\n\t\t\t\t\tzIndex={confirmDelete.zIndex}\n\t\t\t\t\tonDeleteConfirmed={() => {\n\t\t\t\t\t\tonRemove(pendingDeleteId);\n\t\t\t\t\t\tsetPendingDeleteId(null);\n\t\t\t\t\t}}\n\t\t\t\t\tonCancelClicked={() => setPendingDeleteId(null)}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</SideSection>\n\t);\n};\n\n// Anchors the `@`-picker popover to the header \"+\" button.\nconst AddButtonWrap = styled.div`\n\tposition: relative;\n\tdisplay: flex;\n`;\n\n// Anchors the `@`-picker popover to the empty-state source buttons.\nconst SourcePickerAnchor = styled.div`\n\tposition: relative;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n`;\n\n// Floating card under the trigger. Aligns to the \"+\" (right) or the source\n// buttons (left) so it stays inside the side panel.\nconst PickerPopover = styled.div<{ $align?: 'left' | 'right'; $up?: boolean }>`\n\tposition: absolute;\n\t${(p) => (p.$up ? 'bottom: calc(100% + 4px);' : 'top: calc(100% + 4px);')}\n\t${(p) => (p.$align === 'left' ? 'left: 0;' : 'right: 0;')}\n\tz-index: 30;\n`;\n"],"names":["CREATE_OPTION_VALUE","SelectableListSection","title","helper","items","addableOptions","onAdd","onRemove","dataTestPrefix","emptyText","createOption","onConfigure","sourceGroups","mentionItems","actionSources","confirmDelete","pickerOpensUp","appLabel","adding","setAdding","useState","pendingDeleteId","setPendingDeleteId","configuringId","setConfiguringId","activeSource","setActiveSource","hasSourceGroups","activeGroup","g","usePicker","headerPickerRef","useRef","sourcePickerRef","pickerSource","setPickerSource","useEffect","onDocMouseDown","e","target","onKeyDown","showAddButton","showEmptyCreate","hasActionSources","showSourceButtons","handleAddClick","v","handleConfigureClick","id","configure","result","renderChipRows","item","jsxs","SelectableRow","renderSourceIcon","RowLabel","jsx","Tooltip","RowText","BodySecondary","COLORS","Shield","RowActions","RowMenuButton","EditIcon","RowActionDivider","DeleteIcon","dropdownOptions","pickerNode","MentionPicker","a","source","SideSection","SideSectionHeader","TitleSmall","AddButtonWrap","AddIconButton","PlusIcon","PickerPopover","BodyCaption","SourcePickerAnchor","SourceButtonRow","soleTool","isIntegrationSource","SourceButton","sourceIcon","Dropdown","opt","unwrapDropdownValue","Fragment","Button","DeleteConfirmationModal","styled","p"],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { AgentChannel, AgentChannelAccount, AgentChannelType } from '../AgentBuilder.model';
|
|
3
|
+
/** How one channel type renders: its label, brand glyph, tint and copy noun. */
|
|
4
|
+
export interface ChannelPresentation {
|
|
5
|
+
/** Row label ("WhatsApp", "Email", …). */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Brand glyph. Undefined for an unknown type — the row renders label-only. */
|
|
8
|
+
Icon?: React.FC<React.SVGProps<SVGSVGElement> & {
|
|
9
|
+
size?: number | string;
|
|
10
|
+
}>;
|
|
11
|
+
/** Tint behind the glyph. */
|
|
12
|
+
tint: string;
|
|
13
|
+
/**
|
|
14
|
+
* What an account IS on this channel, plural — drives the picker's copy
|
|
15
|
+
* ("Select from available WhatsApp numbers"). Kept per-channel because the
|
|
16
|
+
* design's WhatsApp-only wording has to generalise once the same picker opens
|
|
17
|
+
* for Email and Instagram.
|
|
18
|
+
*/
|
|
19
|
+
accountsNoun: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Keyed by the shared `Channels` enum, so a channel key can never drift from the
|
|
23
|
+
* platform's spelling.
|
|
24
|
+
*
|
|
25
|
+
* Typed `Record<AgentChannelType, …>` rather than `Record<string, …>`: that makes
|
|
26
|
+
* the map EXHAUSTIVE, so widening {@link AgentChannelType} without adding the
|
|
27
|
+
* matching presentation here is a compile error rather than a channel that
|
|
28
|
+
* silently renders with no glyph.
|
|
29
|
+
*/
|
|
30
|
+
export declare const CHANNEL_PRESENTATION: Record<AgentChannelType, ChannelPresentation>;
|
|
31
|
+
/** The channel types the builder supports, in display order. */
|
|
32
|
+
export declare const AGENT_CHANNEL_TYPES: AgentChannelType[];
|
|
33
|
+
/**
|
|
34
|
+
* Presentation for a channel.
|
|
35
|
+
*
|
|
36
|
+
* `AgentChannelType` makes the registry hit total at compile time, but the
|
|
37
|
+
* `availableChannels` a consumer passes come off a backend response — so an
|
|
38
|
+
* unrecognised `type` is still handled defensively (the consumer's `label`, then
|
|
39
|
+
* the raw value, with no glyph) rather than rendering `undefined`.
|
|
40
|
+
*/
|
|
41
|
+
export declare const channelPresentation: (type: AgentChannelType, labelOverride?: string) => ChannelPresentation;
|
|
42
|
+
/** True when the store hasn't got a healthy connection to this account. */
|
|
43
|
+
export declare const isAccountDisconnected: (account: AgentChannelAccount) => boolean;
|
|
44
|
+
/**
|
|
45
|
+
* The accounts the agent is actually activated on, in the channel's own order.
|
|
46
|
+
* Selection is stored as backend ids, so an id that no longer exists on the
|
|
47
|
+
* store (channel removed since the agent was saved) simply drops out here.
|
|
48
|
+
*/
|
|
49
|
+
export declare const selectedAccounts: (channel: AgentChannel, selectedIds: string[]) => AgentChannelAccount[];
|
|
50
|
+
/**
|
|
51
|
+
* Selected accounts the store can no longer reach. Drives the row alert and the
|
|
52
|
+
* chips' negative styling. A disconnected account is deliberately NOT dropped
|
|
53
|
+
* from the selection — silently editing a merchant's saved config would hide the
|
|
54
|
+
* very problem they need to go fix.
|
|
55
|
+
*/
|
|
56
|
+
export declare const disconnectedSelectedAccounts: (channel: AgentChannel, selectedIds: string[]) => AgentChannelAccount[];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Channels as c } from "@bikdotai/bik-models/campaigns/models/Channel";
|
|
2
|
+
import { COLORS as s } from "../../../constants/Theme.js";
|
|
3
|
+
import i from "../../../icons/Social/Channels/InstagramV2.js";
|
|
4
|
+
import r from "../../../icons/Social/Channels/EmailV2.js";
|
|
5
|
+
import u from "../../../icons/Social/Channels/WhatsAppV2.js";
|
|
6
|
+
const l = "#FFEAF7", N = s.surface.subdued, e = {
|
|
7
|
+
[c.WHATSAPP]: {
|
|
8
|
+
label: "WhatsApp",
|
|
9
|
+
Icon: u,
|
|
10
|
+
tint: s.background.positive.light,
|
|
11
|
+
accountsNoun: "WhatsApp numbers"
|
|
12
|
+
},
|
|
13
|
+
[c.EMAIL]: {
|
|
14
|
+
label: "Email",
|
|
15
|
+
Icon: r,
|
|
16
|
+
tint: s.background.negative.light,
|
|
17
|
+
accountsNoun: "email addresses"
|
|
18
|
+
},
|
|
19
|
+
[c.INSTAGRAM]: {
|
|
20
|
+
label: "Instagram",
|
|
21
|
+
Icon: i,
|
|
22
|
+
tint: l,
|
|
23
|
+
accountsNoun: "Instagram accounts"
|
|
24
|
+
}
|
|
25
|
+
}, S = Object.keys(
|
|
26
|
+
e
|
|
27
|
+
), T = (n, t) => {
|
|
28
|
+
const o = e[String(n).toLowerCase()];
|
|
29
|
+
if (o)
|
|
30
|
+
return t ? { ...o, label: t } : o;
|
|
31
|
+
const a = t || String(n);
|
|
32
|
+
return { label: a, tint: N, accountsNoun: `${a} channels` };
|
|
33
|
+
}, d = (n) => n.status === "disconnected", E = (n, t) => n.accounts.filter((o) => t.includes(o.channelId));
|
|
34
|
+
export {
|
|
35
|
+
S as AGENT_CHANNEL_TYPES,
|
|
36
|
+
e as CHANNEL_PRESENTATION,
|
|
37
|
+
T as channelPresentation,
|
|
38
|
+
d as isAccountDisconnected,
|
|
39
|
+
E as selectedAccounts
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sources":["../../../../../src/components/agent-builder/constants/channels.ts"],"sourcesContent":["import { Channels } from '@bikdotai/bik-models/campaigns/models/Channel';\nimport { EmailV2, InstagramV2, WhatsAppV2 } from '@src/icons/Social/Channels';\nimport type React from 'react';\nimport { COLORS } from '@src/constants/Theme';\nimport type {\n\tAgentChannel,\n\tAgentChannelAccount,\n\tAgentChannelType,\n} from '../AgentBuilder.model';\n\n/** How one channel type renders: its label, brand glyph, tint and copy noun. */\nexport interface ChannelPresentation {\n\t/** Row label (\"WhatsApp\", \"Email\", …). */\n\tlabel: string;\n\t/** Brand glyph. Undefined for an unknown type — the row renders label-only. */\n\tIcon?: React.FC<React.SVGProps<SVGSVGElement> & { size?: number | string }>;\n\t/** Tint behind the glyph. */\n\ttint: string;\n\t/**\n\t * What an account IS on this channel, plural — drives the picker's copy\n\t * (\"Select from available WhatsApp numbers\"). Kept per-channel because the\n\t * design's WhatsApp-only wording has to generalise once the same picker opens\n\t * for Email and Instagram.\n\t */\n\taccountsNoun: string;\n}\n\n/**\n * Instagram's tint has no theme token (Figma ships it as a one-off pink under\n * \"Intent Colors\"); the other two map onto the standard positive / negative\n * light backgrounds.\n */\nconst INSTAGRAM_TINT = '#FFEAF7';\n\n/** Tint used for an unknown channel type, whose glyph we don't have. */\nconst UNKNOWN_TINT = COLORS.surface.subdued;\n\n/**\n * Keyed by the shared `Channels` enum, so a channel key can never drift from the\n * platform's spelling.\n *\n * Typed `Record<AgentChannelType, …>` rather than `Record<string, …>`: that makes\n * the map EXHAUSTIVE, so widening {@link AgentChannelType} without adding the\n * matching presentation here is a compile error rather than a channel that\n * silently renders with no glyph.\n */\nexport const CHANNEL_PRESENTATION: Record<\n\tAgentChannelType,\n\tChannelPresentation\n> = {\n\t[Channels.WHATSAPP]: {\n\t\tlabel: 'WhatsApp',\n\t\tIcon: WhatsAppV2,\n\t\ttint: COLORS.background.positive.light,\n\t\taccountsNoun: 'WhatsApp numbers',\n\t},\n\t[Channels.EMAIL]: {\n\t\tlabel: 'Email',\n\t\tIcon: EmailV2,\n\t\ttint: COLORS.background.negative.light,\n\t\taccountsNoun: 'email addresses',\n\t},\n\t[Channels.INSTAGRAM]: {\n\t\tlabel: 'Instagram',\n\t\tIcon: InstagramV2,\n\t\ttint: INSTAGRAM_TINT,\n\t\taccountsNoun: 'Instagram accounts',\n\t},\n};\n\n/** The channel types the builder supports, in display order. */\nexport const AGENT_CHANNEL_TYPES = Object.keys(\n\tCHANNEL_PRESENTATION,\n) as AgentChannelType[];\n\n/**\n * Presentation for a channel.\n *\n * `AgentChannelType` makes the registry hit total at compile time, but the\n * `availableChannels` a consumer passes come off a backend response — so an\n * unrecognised `type` is still handled defensively (the consumer's `label`, then\n * the raw value, with no glyph) rather than rendering `undefined`.\n */\nexport const channelPresentation = (\n\ttype: AgentChannelType,\n\tlabelOverride?: string,\n): ChannelPresentation => {\n\tconst known = CHANNEL_PRESENTATION[\n\t\tString(type).toLowerCase() as AgentChannelType\n\t] as ChannelPresentation | undefined;\n\tif (known) {\n\t\treturn labelOverride ? { ...known, label: labelOverride } : known;\n\t}\n\tconst label = labelOverride || String(type);\n\treturn { label, tint: UNKNOWN_TINT, accountsNoun: `${label} channels` };\n};\n\n/** True when the store hasn't got a healthy connection to this account. */\nexport const isAccountDisconnected = (account: AgentChannelAccount): boolean =>\n\taccount.status === 'disconnected';\n\n/**\n * The accounts the agent is actually activated on, in the channel's own order.\n * Selection is stored as backend ids, so an id that no longer exists on the\n * store (channel removed since the agent was saved) simply drops out here.\n */\nexport const selectedAccounts = (\n\tchannel: AgentChannel,\n\tselectedIds: string[],\n): AgentChannelAccount[] =>\n\tchannel.accounts.filter((a) => selectedIds.includes(a.channelId));\n\n/**\n * Selected accounts the store can no longer reach. Drives the row alert and the\n * chips' negative styling. A disconnected account is deliberately NOT dropped\n * from the selection — silently editing a merchant's saved config would hide the\n * very problem they need to go fix.\n */\nexport const disconnectedSelectedAccounts = (\n\tchannel: AgentChannel,\n\tselectedIds: string[],\n): AgentChannelAccount[] =>\n\tselectedAccounts(channel, selectedIds).filter(isAccountDisconnected);\n"],"names":["INSTAGRAM_TINT","UNKNOWN_TINT","COLORS","CHANNEL_PRESENTATION","Channels","WhatsAppV2","EmailV2","InstagramV2","AGENT_CHANNEL_TYPES","channelPresentation","type","labelOverride","known","label","isAccountDisconnected","account","selectedAccounts","channel","selectedIds","a"],"mappings":";;;;;AAgCA,MAAMA,IAAiB,WAGjBC,IAAeC,EAAO,QAAQ,SAWvBC,IAGT;AAAA,EACH,CAACC,EAAS,QAAQ,GAAG;AAAA,IACpB,OAAO;AAAA,IACP,MAAMC;AAAAA,IACN,MAAMH,EAAO,WAAW,SAAS;AAAA,IACjC,cAAc;AAAA,EAAA;AAAA,EAEf,CAACE,EAAS,KAAK,GAAG;AAAA,IACjB,OAAO;AAAA,IACP,MAAME;AAAAA,IACN,MAAMJ,EAAO,WAAW,SAAS;AAAA,IACjC,cAAc;AAAA,EAAA;AAAA,EAEf,CAACE,EAAS,SAAS,GAAG;AAAA,IACrB,OAAO;AAAA,IACP,MAAMG;AAAAA,IACN,MAAMP;AAAA,IACN,cAAc;AAAA,EAAA;AAEhB,GAGaQ,IAAsB,OAAO;AAAA,EACzCL;AACD,GAUaM,IAAsB,CAClCC,GACAC,MACyB;AACzB,QAAMC,IAAQT,EACb,OAAOO,CAAI,EAAE,aACd;AACA,MAAIE;AACH,WAAOD,IAAgB,EAAE,GAAGC,GAAO,OAAOD,MAAkBC;AAE7D,QAAMC,IAAQF,KAAiB,OAAOD,CAAI;AAC1C,SAAO,EAAE,OAAAG,GAAO,MAAMZ,GAAc,cAAc,GAAGY,CAAK,YAAA;AAC3D,GAGaC,IAAwB,CAACC,MACrCA,EAAQ,WAAW,gBAOPC,IAAmB,CAC/BC,GACAC,MAEAD,EAAQ,SAAS,OAAO,CAACE,MAAMD,EAAY,SAASC,EAAE,SAAS,CAAC;"}
|
|
@@ -5,9 +5,39 @@ export interface StepDefinition {
|
|
|
5
5
|
index: number;
|
|
6
6
|
/** Rail label + content section title. */
|
|
7
7
|
title: string;
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Helper text under the section title. May contain {@link APP_TOKEN}, which
|
|
10
|
+
* resolves to the host app's name at render time — see {@link resolveAppToken}.
|
|
11
|
+
*/
|
|
9
12
|
helper: string;
|
|
10
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Placeholder for the host application's name in user-facing copy. The builder
|
|
16
|
+
* ships in both BIK and Manifest, so any sentence naming the product has to be
|
|
17
|
+
* resolved against `applicationType` rather than hardcoded.
|
|
18
|
+
*/
|
|
19
|
+
export declare const APP_TOKEN = "{app}";
|
|
20
|
+
/**
|
|
21
|
+
* The label {@link APP_TOKEN} resolves to when the consumer passes no
|
|
22
|
+
* `applicationType` — i.e. what every existing caller already sees.
|
|
23
|
+
*/
|
|
24
|
+
export declare const DEFAULT_APP_LABEL = "Manifest";
|
|
25
|
+
/** Swap {@link APP_TOKEN} for the host app's label (e.g. "Manifest", "BIK"). */
|
|
26
|
+
export declare const resolveAppToken: (text: string, appLabel: string) => string;
|
|
27
|
+
/**
|
|
28
|
+
* Step copy with {@link APP_TOKEN} left UNRESOLVED. Only the builder itself reads
|
|
29
|
+
* this — it resolves the token against the host app at render time.
|
|
30
|
+
*
|
|
31
|
+
* `STEP_DEFINITIONS` (below) is the public, already-resolved export: it is part
|
|
32
|
+
* of the library's API, so it keeps reading "Manifest" exactly as it always has
|
|
33
|
+
* rather than leaking a raw `{app}` token to anyone consuming the constant.
|
|
34
|
+
*/
|
|
35
|
+
export declare const STEP_DEFINITION_TEMPLATES: StepDefinition[];
|
|
36
|
+
/**
|
|
37
|
+
* Public step definitions, resolved to the default host label. Unchanged output
|
|
38
|
+
* for every existing consumer; the builder uses
|
|
39
|
+
* {@link STEP_DEFINITION_TEMPLATES} instead so it can name the real host app.
|
|
40
|
+
*/
|
|
11
41
|
export declare const STEP_DEFINITIONS: StepDefinition[];
|
|
12
42
|
export declare const STEP_KEYS: StepKey[];
|
|
13
43
|
export declare const getStepIndex: (key: StepKey) => number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const t = [
|
|
1
|
+
const t = "{app}", o = "Manifest", s = (e, n) => e.split(t).join(n), a = [
|
|
2
2
|
{
|
|
3
3
|
key: "about",
|
|
4
4
|
index: 1,
|
|
@@ -9,7 +9,7 @@ const t = [
|
|
|
9
9
|
key: "trigger",
|
|
10
10
|
index: 2,
|
|
11
11
|
title: "When it steps in",
|
|
12
|
-
helper:
|
|
12
|
+
helper: `Choose how ${t} knows when to route a conversation to this agent.`
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
key: "response",
|
|
@@ -23,10 +23,19 @@ const t = [
|
|
|
23
23
|
title: "Handover rules",
|
|
24
24
|
helper: "Define when this agent passes the conversation to a human, and how."
|
|
25
25
|
}
|
|
26
|
-
],
|
|
26
|
+
], i = a.map(
|
|
27
|
+
(e) => ({
|
|
28
|
+
...e,
|
|
29
|
+
helper: s(e.helper, o)
|
|
30
|
+
})
|
|
31
|
+
), h = i.map((e) => e.key), r = (e) => h.indexOf(e);
|
|
27
32
|
export {
|
|
28
|
-
t as
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
t as APP_TOKEN,
|
|
34
|
+
o as DEFAULT_APP_LABEL,
|
|
35
|
+
i as STEP_DEFINITIONS,
|
|
36
|
+
a as STEP_DEFINITION_TEMPLATES,
|
|
37
|
+
h as STEP_KEYS,
|
|
38
|
+
r as getStepIndex,
|
|
39
|
+
s as resolveAppToken
|
|
31
40
|
};
|
|
32
41
|
//# sourceMappingURL=steps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"steps.js","sources":["../../../../../src/components/agent-builder/constants/steps.ts"],"sourcesContent":["import { StepKey } from '../AgentBuilder.model';\n\nexport interface StepDefinition {\n\tkey: StepKey;\n\t/** 1-based number shown in the rail. */\n\tindex: number;\n\t/** Rail label + content section title. */\n\ttitle: string;\n\t
|
|
1
|
+
{"version":3,"file":"steps.js","sources":["../../../../../src/components/agent-builder/constants/steps.ts"],"sourcesContent":["import { StepKey } from '../AgentBuilder.model';\n\nexport interface StepDefinition {\n\tkey: StepKey;\n\t/** 1-based number shown in the rail. */\n\tindex: number;\n\t/** Rail label + content section title. */\n\ttitle: string;\n\t/**\n\t * Helper text under the section title. May contain {@link APP_TOKEN}, which\n\t * resolves to the host app's name at render time — see {@link resolveAppToken}.\n\t */\n\thelper: string;\n}\n\n/**\n * Placeholder for the host application's name in user-facing copy. The builder\n * ships in both BIK and Manifest, so any sentence naming the product has to be\n * resolved against `applicationType` rather than hardcoded.\n */\nexport const APP_TOKEN = '{app}';\n\n/**\n * The label {@link APP_TOKEN} resolves to when the consumer passes no\n * `applicationType` — i.e. what every existing caller already sees.\n */\nexport const DEFAULT_APP_LABEL = 'Manifest';\n\n/** Swap {@link APP_TOKEN} for the host app's label (e.g. \"Manifest\", \"BIK\"). */\nexport const resolveAppToken = (text: string, appLabel: string): string =>\n\ttext.split(APP_TOKEN).join(appLabel);\n\n/**\n * Step copy with {@link APP_TOKEN} left UNRESOLVED. Only the builder itself reads\n * this — it resolves the token against the host app at render time.\n *\n * `STEP_DEFINITIONS` (below) is the public, already-resolved export: it is part\n * of the library's API, so it keeps reading \"Manifest\" exactly as it always has\n * rather than leaking a raw `{app}` token to anyone consuming the constant.\n */\nexport const STEP_DEFINITION_TEMPLATES: StepDefinition[] = [\n\t{\n\t\tkey: 'about',\n\t\tindex: 1,\n\t\ttitle: 'About this agent',\n\t\thelper:\n\t\t\t'Give it a name and one clear job. One agent → one job, that’s what keeps answers sharp.',\n\t},\n\t{\n\t\tkey: 'trigger',\n\t\tindex: 2,\n\t\ttitle: 'When it steps in',\n\t\thelper: `Choose how ${APP_TOKEN} knows when to route a conversation to this agent.`,\n\t},\n\t{\n\t\tkey: 'response',\n\t\tindex: 3,\n\t\ttitle: 'How it responds',\n\t\thelper:\n\t\t\t'Write what this agent should do. Type @ to reference a tool, add a condition, or hand off to a sub-agent.',\n\t},\n\t{\n\t\tkey: 'handover',\n\t\tindex: 4,\n\t\ttitle: 'Handover rules',\n\t\thelper:\n\t\t\t'Define when this agent passes the conversation to a human, and how.',\n\t},\n];\n\n/**\n * Public step definitions, resolved to the default host label. Unchanged output\n * for every existing consumer; the builder uses\n * {@link STEP_DEFINITION_TEMPLATES} instead so it can name the real host app.\n */\nexport const STEP_DEFINITIONS: StepDefinition[] = STEP_DEFINITION_TEMPLATES.map(\n\t(def) => ({\n\t\t...def,\n\t\thelper: resolveAppToken(def.helper, DEFAULT_APP_LABEL),\n\t}),\n);\n\nexport const STEP_KEYS: StepKey[] = STEP_DEFINITIONS.map((s) => s.key);\n\nexport const getStepIndex = (key: StepKey): number => STEP_KEYS.indexOf(key);\n"],"names":["APP_TOKEN","DEFAULT_APP_LABEL","resolveAppToken","text","appLabel","STEP_DEFINITION_TEMPLATES","STEP_DEFINITIONS","def","STEP_KEYS","s","getStepIndex","key"],"mappings":"AAoBO,MAAMA,IAAY,SAMZC,IAAoB,YAGpBC,IAAkB,CAACC,GAAcC,MAC7CD,EAAK,MAAMH,CAAS,EAAE,KAAKI,CAAQ,GAUvBC,IAA8C;AAAA,EAC1D;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QACC;AAAA,EAAA;AAAA,EAEF;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ,cAAcL,CAAS;AAAA,EAAA;AAAA,EAEhC;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QACC;AAAA,EAAA;AAAA,EAEF;AAAA,IACC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QACC;AAAA,EAAA;AAEH,GAOaM,IAAqCD,EAA0B;AAAA,EAC3E,CAACE,OAAS;AAAA,IACT,GAAGA;AAAA,IACH,QAAQL,EAAgBK,EAAI,QAAQN,CAAiB;AAAA,EAAA;AAEvD,GAEaO,IAAuBF,EAAiB,IAAI,CAACG,MAAMA,EAAE,GAAG,GAExDC,IAAe,CAACC,MAAyBH,EAAU,QAAQG,CAAG;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ApplicationType } from '@bikdotai/bik-models/growth';
|
|
2
2
|
import { default as React } from 'react';
|
|
3
3
|
import { VariableListInterfaceV3 } from '../../variable-picker-v3/model';
|
|
4
|
-
import { AgentTool, AgentValue, ConfigToolKey, IntentOption, ModelOption, ParamsBlob, StepKey, StepValidation, SubAgentDraft, SubAgentRef } from '../AgentBuilder.model';
|
|
4
|
+
import { AgentChannel, AgentChannelType, AgentTool, AgentValue, ConfigToolKey, IntentOption, ModelOption, ParamsBlob, StepKey, StepValidation, SubAgentDraft, SubAgentRef } from '../AgentBuilder.model';
|
|
5
5
|
import { AgentCharLimits } from '../constants/charLimits';
|
|
6
6
|
import { ToolSource } from '../constants/tools';
|
|
7
7
|
/** Mention-capable text fields in Step 3 (both store firebase token text). */
|
|
@@ -89,6 +89,15 @@ export interface AgentBuilderContextShape {
|
|
|
89
89
|
variablesData?: VariableListInterfaceV3[];
|
|
90
90
|
/** Host application context (e.g. MANIFEST) — drives tool-chip labelling. */
|
|
91
91
|
applicationType?: ApplicationType;
|
|
92
|
+
/**
|
|
93
|
+
* The store's connected channels + accounts. Absent / empty hides Step 1's
|
|
94
|
+
* "Channels to activate it on" section entirely.
|
|
95
|
+
*/
|
|
96
|
+
availableChannels?: AgentChannel[];
|
|
97
|
+
/** Open the consumer's channel-management screen. Omit to hide the link. */
|
|
98
|
+
onManageChannels?: (type: AgentChannelType) => void;
|
|
99
|
+
/** Open the consumer's smart-agent-handover settings (Step 4, BIK only). */
|
|
100
|
+
onSmartAgentHandover?: () => void;
|
|
92
101
|
/** Resolved per-field character limits (consumer overrides merged over defaults). */
|
|
93
102
|
charLimits: AgentCharLimits;
|
|
94
103
|
/** When true, step-rail items are not clickable (Back / Next only). */
|
|
@@ -135,6 +144,9 @@ interface ProviderProps {
|
|
|
135
144
|
variablesData?: VariableListInterfaceV3[];
|
|
136
145
|
validation?: Partial<StepValidation>;
|
|
137
146
|
applicationType?: ApplicationType;
|
|
147
|
+
availableChannels?: AgentChannel[];
|
|
148
|
+
onManageChannels?: (type: AgentChannelType) => void;
|
|
149
|
+
onSmartAgentHandover?: () => void;
|
|
138
150
|
charLimits?: Partial<AgentCharLimits>;
|
|
139
151
|
disableStepNavigation?: boolean;
|
|
140
152
|
onCreateSubAgent?: (draft: SubAgentDraft) => Promise<SubAgentRef>;
|