@brainfish-ai/components 0.13.7 → 0.13.9
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/components/chat-search/ChatSearchContext.d.ts +2 -0
- package/dist/components/chat-search/hooks/useScrollManager.d.ts +2 -1
- package/dist/components/chat-search/types.d.ts +1 -0
- package/dist/components/markdown/FormattedMessage.d.ts +1 -1
- package/dist/esm/chunks/{ChatSearch.CxwRDkGx.js → ChatSearch.CNtUt5oJ.js} +256 -240
- package/dist/esm/chunks/ChatSearch.CNtUt5oJ.js.map +1 -0
- package/dist/esm/chunks/{FormattedMessage.CpTetIzd.js → FormattedMessage.Ci8jirX2.js} +9 -7
- package/dist/esm/chunks/{FormattedMessage.CpTetIzd.js.map → FormattedMessage.Ci8jirX2.js.map} +1 -1
- package/dist/esm/components/chat-search.js +1 -1
- package/dist/esm/components/markdown.js +1 -1
- package/dist/esm/index.css +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/lib/getContentType.d.ts +1 -1
- package/dist/stats.html +1 -1
- package/package.json +1 -1
- package/dist/esm/chunks/ChatSearch.CxwRDkGx.js.map +0 -1
|
@@ -25,10 +25,12 @@ interface ChatSearchContextProps {
|
|
|
25
25
|
setLoadError: React.Dispatch<React.SetStateAction<string>>;
|
|
26
26
|
showMobileCloseWidgetButton: boolean;
|
|
27
27
|
setShowMobileCloseWidgetButton: React.Dispatch<React.SetStateAction<boolean>>;
|
|
28
|
+
contentTypeEndpoint?: string;
|
|
28
29
|
}
|
|
29
30
|
export declare const ChatSearchProvider: React.FC<{
|
|
30
31
|
children: ReactNode;
|
|
31
32
|
searchPath?: string;
|
|
33
|
+
contentTypeEndpoint?: string;
|
|
32
34
|
}>;
|
|
33
35
|
export declare const useChatSearch: () => ChatSearchContextProps;
|
|
34
36
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RefObject } from 'react';
|
|
2
|
-
export declare const useScrollManager: (answerRefs: RefObject<(HTMLDivElement | null)[]>, containerRef: RefObject<HTMLDivElement | null>) => {
|
|
2
|
+
export declare const useScrollManager: (answerRefs: RefObject<(HTMLDivElement | null)[]>, containerRef: RefObject<HTMLDivElement | null>, bottomRef?: RefObject<HTMLDivElement | null>) => {
|
|
3
3
|
scrollToLastAnswer: () => void;
|
|
4
4
|
scrollToAnswer: (index: number) => void;
|
|
5
|
+
scrollToBottom: () => void;
|
|
5
6
|
};
|
|
@@ -160,6 +160,7 @@ export interface ChatSearchProps {
|
|
|
160
160
|
loadConversationEndpoint?: string;
|
|
161
161
|
followUpQuestionsEndpoint?: string;
|
|
162
162
|
autocompleteEndpoint?: string;
|
|
163
|
+
contentTypeEndpoint?: string;
|
|
163
164
|
disableFollowUpQuestions?: boolean;
|
|
164
165
|
disableImageAttachment?: boolean;
|
|
165
166
|
disableFeedback?: boolean;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React__default, {
|
|
1
|
+
import React__default, { useState, useCallback, useMemo, createContext, useContext, Fragment, useRef, useEffect, forwardRef, useImperativeHandle } from 'react';
|
|
2
2
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
3
3
|
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '../components/ui/tooltip.js';
|
|
4
4
|
import { Button } from '../components/ui/button.js';
|
|
5
5
|
import { XCircle, Check, Copy, CaretDown, ArrowSquareOut, CaretRight, ArrowsVertical, ArrowDown, MagnifyingGlass, X, CheckCircle, Circle, Image, ArrowRight, ArrowLeft, ArrowsInSimple, ArrowsOutSimple } from '@phosphor-icons/react';
|
|
6
|
-
import { g as getDefaultExportFromCjs, F as FormattedMessage, c as addPopupWidgetUtm } from './FormattedMessage.
|
|
6
|
+
import { g as getDefaultExportFromCjs, F as FormattedMessage, c as addPopupWidgetUtm } from './FormattedMessage.Ci8jirX2.js';
|
|
7
7
|
import { appendErrors, useForm, Controller } from 'react-hook-form';
|
|
8
8
|
import { validateFieldsNatively, toNestErrors } from '@hookform/resolvers';
|
|
9
9
|
import require$$0 from 'ajv';
|
|
@@ -14,13 +14,13 @@ import { S as SimpleSelect } from './simpleSelect.BfAgKOea.js';
|
|
|
14
14
|
import { c as cn, i as isAnswerUncertain } from './utils.DaMF_LVC.js';
|
|
15
15
|
import { D as DatePicker } from './date-picker.DqcdwXZS.js';
|
|
16
16
|
import { createId } from '@paralleldrive/cuid2';
|
|
17
|
+
import { useImmerReducer } from 'use-immer';
|
|
18
|
+
import { useSearchParam, useEffectOnce } from 'react-use';
|
|
17
19
|
import { MemoizedIcon } from '../components/ui/icon.js';
|
|
18
20
|
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '../components/ui/collapsible.js';
|
|
19
21
|
import { F as Feedback } from './feedback.NWn6_mYe.js';
|
|
20
22
|
import { G as GeneratingStar } from './generating-star.B0RUXRff.js';
|
|
21
23
|
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '../components/ui/dropdown-menu.js';
|
|
22
|
-
import { useImmerReducer } from 'use-immer';
|
|
23
|
-
import { useSearchParam, useEffectOnce } from 'react-use';
|
|
24
24
|
import { ScrollArea } from '../components/ui/scroll-area.js';
|
|
25
25
|
|
|
26
26
|
import '../ChatSearch.css';function Suggestions({ suggestions, onQuestionClick, title = "Suggested questions" }) {
|
|
@@ -3450,36 +3450,6 @@ function ActionButtonsBlock({ block: _block }) {
|
|
|
3450
3450
|
return null;
|
|
3451
3451
|
}
|
|
3452
3452
|
|
|
3453
|
-
function MarkdownTextBlock({ block, redirectRules, state }) {
|
|
3454
|
-
if (!block.text || block.text.trim() === "") {
|
|
3455
|
-
return /* @__PURE__ */ React__default.createElement("div", { className: "w-full py-4" }, /* @__PURE__ */ React__default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React__default.createElement("div", { className: "h-4 rounded w-3/4 shimmer" }), /* @__PURE__ */ React__default.createElement("div", { className: "h-4 rounded w-full shimmer" }), /* @__PURE__ */ React__default.createElement("div", { className: "h-4 rounded w-5/6 shimmer" }))));
|
|
3456
|
-
}
|
|
3457
|
-
const { text } = block;
|
|
3458
|
-
return /* @__PURE__ */ React__default.createElement("div", { className: "w-full" }, /* @__PURE__ */ React__default.createElement("div", { className: "prose prose-sm max-w-none text-foreground" }, /* @__PURE__ */ React__default.createElement(
|
|
3459
|
-
FormattedMessage,
|
|
3460
|
-
{
|
|
3461
|
-
message: {
|
|
3462
|
-
content: text
|
|
3463
|
-
},
|
|
3464
|
-
redirectRules,
|
|
3465
|
-
isStreaming: state === "streaming"
|
|
3466
|
-
}
|
|
3467
|
-
)));
|
|
3468
|
-
}
|
|
3469
|
-
|
|
3470
|
-
function AnswerBlock({ block, redirectRules, state }) {
|
|
3471
|
-
switch (block.type) {
|
|
3472
|
-
case "markdown-text":
|
|
3473
|
-
return /* @__PURE__ */ React__default.createElement(MarkdownTextBlock, { block, redirectRules, state });
|
|
3474
|
-
case "action-buttons":
|
|
3475
|
-
return /* @__PURE__ */ React__default.createElement(ActionButtonsBlock, { block });
|
|
3476
|
-
case "action-input-form":
|
|
3477
|
-
return /* @__PURE__ */ React__default.createElement(ActionInputFormBlock, { block });
|
|
3478
|
-
default:
|
|
3479
|
-
return null;
|
|
3480
|
-
}
|
|
3481
|
-
}
|
|
3482
|
-
|
|
3483
3453
|
const markdownTextBlock = ({ text = "" } = {}) => ({
|
|
3484
3454
|
id: createId(),
|
|
3485
3455
|
type: "markdown-text",
|
|
@@ -3512,196 +3482,6 @@ const isActionInputFormBlock = (block) => {
|
|
|
3512
3482
|
return block.type === "action-input-form";
|
|
3513
3483
|
};
|
|
3514
3484
|
|
|
3515
|
-
const MotionButton$1 = motion(Button);
|
|
3516
|
-
const NextBestActions = ({ nextBestActions, onActionClick }) => {
|
|
3517
|
-
if (!nextBestActions.length) return null;
|
|
3518
|
-
return /* @__PURE__ */ React__default.createElement(
|
|
3519
|
-
motion.div,
|
|
3520
|
-
{
|
|
3521
|
-
initial: { opacity: 0, y: 20 },
|
|
3522
|
-
animate: { opacity: 1, y: 0 },
|
|
3523
|
-
exit: { opacity: 0, y: -20 },
|
|
3524
|
-
className: "w-full"
|
|
3525
|
-
},
|
|
3526
|
-
/* @__PURE__ */ React__default.createElement("div", { className: "rounded-lg overflow-hidden bg-card border divide-y divide-dark-300" }, nextBestActions.map((action, index) => {
|
|
3527
|
-
const handleClick = () => {
|
|
3528
|
-
onActionClick(action);
|
|
3529
|
-
};
|
|
3530
|
-
const className = "w-full h-12 py-2 px-4 inline-flex items-center justify-center gap-2 whitespace-nowrap text-base font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-6 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground";
|
|
3531
|
-
const key = `${action.label}-${index}`.replace(/\s+/g, "-");
|
|
3532
|
-
switch (action.type) {
|
|
3533
|
-
case "email":
|
|
3534
|
-
return /* @__PURE__ */ React__default.createElement(
|
|
3535
|
-
motion.a,
|
|
3536
|
-
{
|
|
3537
|
-
key,
|
|
3538
|
-
initial: { opacity: 0, x: -20 },
|
|
3539
|
-
animate: { opacity: 1, x: 0 },
|
|
3540
|
-
transition: { delay: index * 0.1 },
|
|
3541
|
-
href: `mailto:${action.value}`,
|
|
3542
|
-
target: "_blank",
|
|
3543
|
-
rel: "noopener noreferrer",
|
|
3544
|
-
className,
|
|
3545
|
-
onClick: () => handleClick()
|
|
3546
|
-
},
|
|
3547
|
-
action.icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: action.icon }),
|
|
3548
|
-
/* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
|
|
3549
|
-
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
|
|
3550
|
-
);
|
|
3551
|
-
case "link":
|
|
3552
|
-
return /* @__PURE__ */ React__default.createElement(
|
|
3553
|
-
motion.a,
|
|
3554
|
-
{
|
|
3555
|
-
key,
|
|
3556
|
-
initial: { opacity: 0, x: -20 },
|
|
3557
|
-
animate: { opacity: 1, x: 0 },
|
|
3558
|
-
transition: { delay: index * 0.1 },
|
|
3559
|
-
href: addPopupWidgetUtm(action.value),
|
|
3560
|
-
target: "_blank",
|
|
3561
|
-
rel: "noopener noreferrer",
|
|
3562
|
-
className,
|
|
3563
|
-
onClick: () => handleClick()
|
|
3564
|
-
},
|
|
3565
|
-
action.icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: action.icon }),
|
|
3566
|
-
/* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
|
|
3567
|
-
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
|
|
3568
|
-
);
|
|
3569
|
-
case "phone":
|
|
3570
|
-
return /* @__PURE__ */ React__default.createElement(
|
|
3571
|
-
motion.a,
|
|
3572
|
-
{
|
|
3573
|
-
key,
|
|
3574
|
-
initial: { opacity: 0, x: -20 },
|
|
3575
|
-
animate: { opacity: 1, x: 0 },
|
|
3576
|
-
transition: { delay: index * 0.1 },
|
|
3577
|
-
href: `tel:${action.value}`,
|
|
3578
|
-
target: "_blank",
|
|
3579
|
-
rel: "noopener noreferrer",
|
|
3580
|
-
className,
|
|
3581
|
-
onClick: () => handleClick()
|
|
3582
|
-
},
|
|
3583
|
-
action.icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: action.icon }),
|
|
3584
|
-
/* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
|
|
3585
|
-
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
|
|
3586
|
-
);
|
|
3587
|
-
default:
|
|
3588
|
-
return /* @__PURE__ */ React__default.createElement(Fragment, { key }, /* @__PURE__ */ React__default.createElement(
|
|
3589
|
-
MotionButton$1,
|
|
3590
|
-
{
|
|
3591
|
-
initial: { opacity: 0, x: -20 },
|
|
3592
|
-
animate: { opacity: 1, x: 0 },
|
|
3593
|
-
transition: { delay: index * 0.1 },
|
|
3594
|
-
className: "w-full text-left h-12 rounded-none [&_svg]:pointer-events-none [&_svg]:size-6 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground text-base font-medium",
|
|
3595
|
-
variant: "ghost",
|
|
3596
|
-
onClick: () => handleClick()
|
|
3597
|
-
},
|
|
3598
|
-
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowCircleRight" }),
|
|
3599
|
-
/* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
|
|
3600
|
-
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
|
|
3601
|
-
));
|
|
3602
|
-
}
|
|
3603
|
-
}))
|
|
3604
|
-
);
|
|
3605
|
-
};
|
|
3606
|
-
|
|
3607
|
-
var ActionType = /* @__PURE__ */ ((ActionType2) => {
|
|
3608
|
-
ActionType2["CallPhone"] = "call_phone";
|
|
3609
|
-
ActionType2["OpenUrl"] = "open_url";
|
|
3610
|
-
ActionType2["SendEmail"] = "send_email";
|
|
3611
|
-
ActionType2["RunCallback"] = "run_callback";
|
|
3612
|
-
return ActionType2;
|
|
3613
|
-
})(ActionType || {});
|
|
3614
|
-
var NextBestActionType = /* @__PURE__ */ ((NextBestActionType2) => {
|
|
3615
|
-
NextBestActionType2["Link"] = "link";
|
|
3616
|
-
NextBestActionType2["Email"] = "email";
|
|
3617
|
-
NextBestActionType2["Phone"] = "phone";
|
|
3618
|
-
NextBestActionType2["Callback"] = "callback";
|
|
3619
|
-
NextBestActionType2["Function"] = "function";
|
|
3620
|
-
return NextBestActionType2;
|
|
3621
|
-
})(NextBestActionType || {});
|
|
3622
|
-
|
|
3623
|
-
const getActionMapping = (action) => {
|
|
3624
|
-
const actionMapping = {
|
|
3625
|
-
[ActionType.CallPhone]: {
|
|
3626
|
-
type: NextBestActionType.Phone,
|
|
3627
|
-
icon: "Phone",
|
|
3628
|
-
getValue: (a) => a.action?.options?.phoneNumber || a.id,
|
|
3629
|
-
getLabel: (a) => a.action?.options?.title || a.type
|
|
3630
|
-
},
|
|
3631
|
-
[ActionType.SendEmail]: {
|
|
3632
|
-
type: NextBestActionType.Email,
|
|
3633
|
-
icon: "EnvelopeSimple",
|
|
3634
|
-
getValue: (a) => a.action?.options?.to || a.id,
|
|
3635
|
-
getLabel: (a) => a.action?.options?.title || a.type
|
|
3636
|
-
},
|
|
3637
|
-
[ActionType.OpenUrl]: {
|
|
3638
|
-
type: NextBestActionType.Link,
|
|
3639
|
-
icon: "Link",
|
|
3640
|
-
getValue: (a) => a.action?.options?.url || a.id,
|
|
3641
|
-
getLabel: (a) => a.action?.options?.title || a.type
|
|
3642
|
-
}
|
|
3643
|
-
};
|
|
3644
|
-
const mapping = actionMapping[action.type] || {
|
|
3645
|
-
type: NextBestActionType.Link,
|
|
3646
|
-
icon: "Link",
|
|
3647
|
-
getValue: (a) => a.action?.options?.url || a.id,
|
|
3648
|
-
getLabel: (a) => a.action?.options?.title || a.type
|
|
3649
|
-
};
|
|
3650
|
-
return mapping;
|
|
3651
|
-
};
|
|
3652
|
-
|
|
3653
|
-
const AnswerActions = ({
|
|
3654
|
-
actions,
|
|
3655
|
-
nextBestActions,
|
|
3656
|
-
isLastAnswer,
|
|
3657
|
-
handleActionClick,
|
|
3658
|
-
searchQueryId,
|
|
3659
|
-
question,
|
|
3660
|
-
answer
|
|
3661
|
-
}) => {
|
|
3662
|
-
const hasActions = actions && actions.length > 0;
|
|
3663
|
-
const hasNextBestActions = nextBestActions && isLastAnswer && nextBestActions.length > 0;
|
|
3664
|
-
const [showAnswerActions] = useState(hasActions || hasNextBestActions);
|
|
3665
|
-
if (!showAnswerActions) {
|
|
3666
|
-
return null;
|
|
3667
|
-
}
|
|
3668
|
-
let mappedActions = [];
|
|
3669
|
-
if (hasActions) {
|
|
3670
|
-
mappedActions = actions.map((action) => {
|
|
3671
|
-
const mapping = getActionMapping(action);
|
|
3672
|
-
return {
|
|
3673
|
-
id: action.id,
|
|
3674
|
-
label: mapping.getLabel(action),
|
|
3675
|
-
type: mapping.type,
|
|
3676
|
-
icon: mapping.icon,
|
|
3677
|
-
value: mapping.getValue(action)
|
|
3678
|
-
};
|
|
3679
|
-
});
|
|
3680
|
-
}
|
|
3681
|
-
if (hasNextBestActions) {
|
|
3682
|
-
const filteredNextBestActions = nextBestActions.filter(
|
|
3683
|
-
(action) => !mappedActions.some((mappedAction) => mappedAction.type === action.type)
|
|
3684
|
-
);
|
|
3685
|
-
mappedActions = mappedActions.concat(filteredNextBestActions);
|
|
3686
|
-
}
|
|
3687
|
-
return /* @__PURE__ */ React__default.createElement("div", { className: "p-4" }, /* @__PURE__ */ React__default.createElement(
|
|
3688
|
-
NextBestActions,
|
|
3689
|
-
{
|
|
3690
|
-
nextBestActions: mappedActions,
|
|
3691
|
-
onActionClick: (action) => {
|
|
3692
|
-
if (action) {
|
|
3693
|
-
handleActionClick?.({
|
|
3694
|
-
action,
|
|
3695
|
-
searchQueryId: searchQueryId || "",
|
|
3696
|
-
query: question,
|
|
3697
|
-
answer
|
|
3698
|
-
});
|
|
3699
|
-
}
|
|
3700
|
-
}
|
|
3701
|
-
}
|
|
3702
|
-
));
|
|
3703
|
-
};
|
|
3704
|
-
|
|
3705
3485
|
const AnswersActions = {
|
|
3706
3486
|
SET_ANSWERS: "answers/set_answers",
|
|
3707
3487
|
CLEAR_ALL: "answers/clear_all",
|
|
@@ -4030,10 +3810,7 @@ const useConversationId = (searchPath) => {
|
|
|
4030
3810
|
};
|
|
4031
3811
|
|
|
4032
3812
|
const ChatSearchContext = createContext(void 0);
|
|
4033
|
-
const ChatSearchProvider = ({
|
|
4034
|
-
children,
|
|
4035
|
-
searchPath
|
|
4036
|
-
}) => {
|
|
3813
|
+
const ChatSearchProvider = ({ children, searchPath, contentTypeEndpoint }) => {
|
|
4037
3814
|
const [query, setQuery] = useState("");
|
|
4038
3815
|
const [queryId, setQueryId] = useState("");
|
|
4039
3816
|
const [followUpQuery, setFollowUpQuery] = useState("");
|
|
@@ -4069,7 +3846,8 @@ const ChatSearchProvider = ({
|
|
|
4069
3846
|
loadError,
|
|
4070
3847
|
setLoadError,
|
|
4071
3848
|
showMobileCloseWidgetButton,
|
|
4072
|
-
setShowMobileCloseWidgetButton
|
|
3849
|
+
setShowMobileCloseWidgetButton,
|
|
3850
|
+
contentTypeEndpoint
|
|
4073
3851
|
}),
|
|
4074
3852
|
[
|
|
4075
3853
|
query,
|
|
@@ -4085,7 +3863,8 @@ const ChatSearchProvider = ({
|
|
|
4085
3863
|
clearConversationId,
|
|
4086
3864
|
isLoadingConversation,
|
|
4087
3865
|
loadError,
|
|
4088
|
-
showMobileCloseWidgetButton
|
|
3866
|
+
showMobileCloseWidgetButton,
|
|
3867
|
+
contentTypeEndpoint
|
|
4089
3868
|
]
|
|
4090
3869
|
);
|
|
4091
3870
|
return /* @__PURE__ */ React__default.createElement(ChatSearchContext.Provider, { value: contextValue }, children);
|
|
@@ -4098,13 +3877,235 @@ const useChatSearch = () => {
|
|
|
4098
3877
|
return context;
|
|
4099
3878
|
};
|
|
4100
3879
|
|
|
3880
|
+
function MarkdownTextBlock({ block, redirectRules, state }) {
|
|
3881
|
+
const { contentTypeEndpoint } = useChatSearch();
|
|
3882
|
+
if (!block.text || block.text.trim() === "") {
|
|
3883
|
+
return /* @__PURE__ */ React__default.createElement("div", { className: "w-full py-4" }, /* @__PURE__ */ React__default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React__default.createElement("div", { className: "space-y-3" }, /* @__PURE__ */ React__default.createElement("div", { className: "h-4 rounded w-3/4 shimmer" }), /* @__PURE__ */ React__default.createElement("div", { className: "h-4 rounded w-full shimmer" }), /* @__PURE__ */ React__default.createElement("div", { className: "h-4 rounded w-5/6 shimmer" }))));
|
|
3884
|
+
}
|
|
3885
|
+
const { text } = block;
|
|
3886
|
+
return /* @__PURE__ */ React__default.createElement("div", { className: "w-full" }, /* @__PURE__ */ React__default.createElement("div", { className: "prose prose-sm max-w-none text-foreground" }, /* @__PURE__ */ React__default.createElement(
|
|
3887
|
+
FormattedMessage,
|
|
3888
|
+
{
|
|
3889
|
+
message: {
|
|
3890
|
+
content: text
|
|
3891
|
+
},
|
|
3892
|
+
redirectRules,
|
|
3893
|
+
isStreaming: state === "streaming",
|
|
3894
|
+
contentTypeEndpoint
|
|
3895
|
+
}
|
|
3896
|
+
)));
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
function AnswerBlock({ block, redirectRules, state }) {
|
|
3900
|
+
switch (block.type) {
|
|
3901
|
+
case "markdown-text":
|
|
3902
|
+
return /* @__PURE__ */ React__default.createElement(MarkdownTextBlock, { block, redirectRules, state });
|
|
3903
|
+
case "action-buttons":
|
|
3904
|
+
return /* @__PURE__ */ React__default.createElement(ActionButtonsBlock, { block });
|
|
3905
|
+
case "action-input-form":
|
|
3906
|
+
return /* @__PURE__ */ React__default.createElement(ActionInputFormBlock, { block });
|
|
3907
|
+
default:
|
|
3908
|
+
return null;
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3912
|
+
const MotionButton$1 = motion(Button);
|
|
3913
|
+
const NextBestActions = ({ nextBestActions, onActionClick }) => {
|
|
3914
|
+
if (!nextBestActions.length) return null;
|
|
3915
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
3916
|
+
motion.div,
|
|
3917
|
+
{
|
|
3918
|
+
initial: { opacity: 0, y: 20 },
|
|
3919
|
+
animate: { opacity: 1, y: 0 },
|
|
3920
|
+
exit: { opacity: 0, y: -20 },
|
|
3921
|
+
className: "w-full"
|
|
3922
|
+
},
|
|
3923
|
+
/* @__PURE__ */ React__default.createElement("div", { className: "rounded-lg overflow-hidden bg-card border divide-y divide-dark-300" }, nextBestActions.map((action, index) => {
|
|
3924
|
+
const handleClick = () => {
|
|
3925
|
+
onActionClick(action);
|
|
3926
|
+
};
|
|
3927
|
+
const className = "w-full h-12 py-2 px-4 inline-flex items-center justify-center gap-2 whitespace-nowrap text-base font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-6 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground";
|
|
3928
|
+
const key = `${action.label}-${index}`.replace(/\s+/g, "-");
|
|
3929
|
+
switch (action.type) {
|
|
3930
|
+
case "email":
|
|
3931
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
3932
|
+
motion.a,
|
|
3933
|
+
{
|
|
3934
|
+
key,
|
|
3935
|
+
initial: { opacity: 0, x: -20 },
|
|
3936
|
+
animate: { opacity: 1, x: 0 },
|
|
3937
|
+
transition: { delay: index * 0.1 },
|
|
3938
|
+
href: `mailto:${action.value}`,
|
|
3939
|
+
target: "_blank",
|
|
3940
|
+
rel: "noopener noreferrer",
|
|
3941
|
+
className,
|
|
3942
|
+
onClick: () => handleClick()
|
|
3943
|
+
},
|
|
3944
|
+
action.icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: action.icon }),
|
|
3945
|
+
/* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
|
|
3946
|
+
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
|
|
3947
|
+
);
|
|
3948
|
+
case "link":
|
|
3949
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
3950
|
+
motion.a,
|
|
3951
|
+
{
|
|
3952
|
+
key,
|
|
3953
|
+
initial: { opacity: 0, x: -20 },
|
|
3954
|
+
animate: { opacity: 1, x: 0 },
|
|
3955
|
+
transition: { delay: index * 0.1 },
|
|
3956
|
+
href: addPopupWidgetUtm(action.value),
|
|
3957
|
+
target: "_blank",
|
|
3958
|
+
rel: "noopener noreferrer",
|
|
3959
|
+
className,
|
|
3960
|
+
onClick: () => handleClick()
|
|
3961
|
+
},
|
|
3962
|
+
action.icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: action.icon }),
|
|
3963
|
+
/* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
|
|
3964
|
+
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
|
|
3965
|
+
);
|
|
3966
|
+
case "phone":
|
|
3967
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
3968
|
+
motion.a,
|
|
3969
|
+
{
|
|
3970
|
+
key,
|
|
3971
|
+
initial: { opacity: 0, x: -20 },
|
|
3972
|
+
animate: { opacity: 1, x: 0 },
|
|
3973
|
+
transition: { delay: index * 0.1 },
|
|
3974
|
+
href: `tel:${action.value}`,
|
|
3975
|
+
target: "_blank",
|
|
3976
|
+
rel: "noopener noreferrer",
|
|
3977
|
+
className,
|
|
3978
|
+
onClick: () => handleClick()
|
|
3979
|
+
},
|
|
3980
|
+
action.icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: action.icon }),
|
|
3981
|
+
/* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
|
|
3982
|
+
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
|
|
3983
|
+
);
|
|
3984
|
+
default:
|
|
3985
|
+
return /* @__PURE__ */ React__default.createElement(Fragment, { key }, /* @__PURE__ */ React__default.createElement(
|
|
3986
|
+
MotionButton$1,
|
|
3987
|
+
{
|
|
3988
|
+
initial: { opacity: 0, x: -20 },
|
|
3989
|
+
animate: { opacity: 1, x: 0 },
|
|
3990
|
+
transition: { delay: index * 0.1 },
|
|
3991
|
+
className: "w-full text-left h-12 rounded-none [&_svg]:pointer-events-none [&_svg]:size-6 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground text-base font-medium",
|
|
3992
|
+
variant: "ghost",
|
|
3993
|
+
onClick: () => handleClick()
|
|
3994
|
+
},
|
|
3995
|
+
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowCircleRight" }),
|
|
3996
|
+
/* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
|
|
3997
|
+
/* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
|
|
3998
|
+
));
|
|
3999
|
+
}
|
|
4000
|
+
}))
|
|
4001
|
+
);
|
|
4002
|
+
};
|
|
4003
|
+
|
|
4004
|
+
var ActionType = /* @__PURE__ */ ((ActionType2) => {
|
|
4005
|
+
ActionType2["CallPhone"] = "call_phone";
|
|
4006
|
+
ActionType2["OpenUrl"] = "open_url";
|
|
4007
|
+
ActionType2["SendEmail"] = "send_email";
|
|
4008
|
+
ActionType2["RunCallback"] = "run_callback";
|
|
4009
|
+
return ActionType2;
|
|
4010
|
+
})(ActionType || {});
|
|
4011
|
+
var NextBestActionType = /* @__PURE__ */ ((NextBestActionType2) => {
|
|
4012
|
+
NextBestActionType2["Link"] = "link";
|
|
4013
|
+
NextBestActionType2["Email"] = "email";
|
|
4014
|
+
NextBestActionType2["Phone"] = "phone";
|
|
4015
|
+
NextBestActionType2["Callback"] = "callback";
|
|
4016
|
+
NextBestActionType2["Function"] = "function";
|
|
4017
|
+
return NextBestActionType2;
|
|
4018
|
+
})(NextBestActionType || {});
|
|
4019
|
+
|
|
4020
|
+
const getActionMapping = (action) => {
|
|
4021
|
+
const actionMapping = {
|
|
4022
|
+
[ActionType.CallPhone]: {
|
|
4023
|
+
type: NextBestActionType.Phone,
|
|
4024
|
+
icon: "Phone",
|
|
4025
|
+
getValue: (a) => a.action?.options?.phoneNumber || a.id,
|
|
4026
|
+
getLabel: (a) => a.action?.options?.title || a.type
|
|
4027
|
+
},
|
|
4028
|
+
[ActionType.SendEmail]: {
|
|
4029
|
+
type: NextBestActionType.Email,
|
|
4030
|
+
icon: "EnvelopeSimple",
|
|
4031
|
+
getValue: (a) => a.action?.options?.to || a.id,
|
|
4032
|
+
getLabel: (a) => a.action?.options?.title || a.type
|
|
4033
|
+
},
|
|
4034
|
+
[ActionType.OpenUrl]: {
|
|
4035
|
+
type: NextBestActionType.Link,
|
|
4036
|
+
icon: "Link",
|
|
4037
|
+
getValue: (a) => a.action?.options?.url || a.id,
|
|
4038
|
+
getLabel: (a) => a.action?.options?.title || a.type
|
|
4039
|
+
}
|
|
4040
|
+
};
|
|
4041
|
+
const mapping = actionMapping[action.type] || {
|
|
4042
|
+
type: NextBestActionType.Link,
|
|
4043
|
+
icon: "Link",
|
|
4044
|
+
getValue: (a) => a.action?.options?.url || a.id,
|
|
4045
|
+
getLabel: (a) => a.action?.options?.title || a.type
|
|
4046
|
+
};
|
|
4047
|
+
return mapping;
|
|
4048
|
+
};
|
|
4049
|
+
|
|
4050
|
+
const AnswerActions = ({
|
|
4051
|
+
actions,
|
|
4052
|
+
nextBestActions,
|
|
4053
|
+
isLastAnswer,
|
|
4054
|
+
handleActionClick,
|
|
4055
|
+
searchQueryId,
|
|
4056
|
+
question,
|
|
4057
|
+
answer
|
|
4058
|
+
}) => {
|
|
4059
|
+
const hasActions = actions && actions.length > 0;
|
|
4060
|
+
const hasNextBestActions = nextBestActions && isLastAnswer && nextBestActions.length > 0;
|
|
4061
|
+
const [showAnswerActions] = useState(hasActions || hasNextBestActions);
|
|
4062
|
+
if (!showAnswerActions) {
|
|
4063
|
+
return null;
|
|
4064
|
+
}
|
|
4065
|
+
let mappedActions = [];
|
|
4066
|
+
if (hasActions) {
|
|
4067
|
+
mappedActions = actions.map((action) => {
|
|
4068
|
+
const mapping = getActionMapping(action);
|
|
4069
|
+
return {
|
|
4070
|
+
id: action.id,
|
|
4071
|
+
label: mapping.getLabel(action),
|
|
4072
|
+
type: mapping.type,
|
|
4073
|
+
icon: mapping.icon,
|
|
4074
|
+
value: mapping.getValue(action)
|
|
4075
|
+
};
|
|
4076
|
+
});
|
|
4077
|
+
}
|
|
4078
|
+
if (hasNextBestActions) {
|
|
4079
|
+
const filteredNextBestActions = nextBestActions.filter(
|
|
4080
|
+
(action) => !mappedActions.some((mappedAction) => mappedAction.type === action.type)
|
|
4081
|
+
);
|
|
4082
|
+
mappedActions = mappedActions.concat(filteredNextBestActions);
|
|
4083
|
+
}
|
|
4084
|
+
return /* @__PURE__ */ React__default.createElement("div", { className: "p-4" }, /* @__PURE__ */ React__default.createElement(
|
|
4085
|
+
NextBestActions,
|
|
4086
|
+
{
|
|
4087
|
+
nextBestActions: mappedActions,
|
|
4088
|
+
onActionClick: (action) => {
|
|
4089
|
+
if (action) {
|
|
4090
|
+
handleActionClick?.({
|
|
4091
|
+
action,
|
|
4092
|
+
searchQueryId: searchQueryId || "",
|
|
4093
|
+
query: question,
|
|
4094
|
+
answer
|
|
4095
|
+
});
|
|
4096
|
+
}
|
|
4097
|
+
}
|
|
4098
|
+
}
|
|
4099
|
+
));
|
|
4100
|
+
};
|
|
4101
|
+
|
|
4101
4102
|
const useIsChatSearchDirty = () => {
|
|
4102
4103
|
const { showResults, answers } = useChatSearch();
|
|
4103
4104
|
const isDirty = Boolean(showResults || answers.length > 0);
|
|
4104
4105
|
return isDirty;
|
|
4105
4106
|
};
|
|
4106
4107
|
|
|
4107
|
-
const useScrollManager = (answerRefs, containerRef) => {
|
|
4108
|
+
const useScrollManager = (answerRefs, containerRef, bottomRef) => {
|
|
4108
4109
|
const scrollToLastAnswer = () => {
|
|
4109
4110
|
requestAnimationFrame(() => {
|
|
4110
4111
|
const lastAnswer = answerRefs.current?.[answerRefs.current.length - 1];
|
|
@@ -4129,7 +4130,14 @@ const useScrollManager = (answerRefs, containerRef) => {
|
|
|
4129
4130
|
}
|
|
4130
4131
|
});
|
|
4131
4132
|
};
|
|
4132
|
-
|
|
4133
|
+
const scrollToBottom = () => {
|
|
4134
|
+
setTimeout(() => {
|
|
4135
|
+
if (bottomRef?.current && containerRef.current) {
|
|
4136
|
+
bottomRef.current.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
4137
|
+
}
|
|
4138
|
+
}, 200);
|
|
4139
|
+
};
|
|
4140
|
+
return { scrollToLastAnswer, scrollToAnswer, scrollToBottom };
|
|
4133
4141
|
};
|
|
4134
4142
|
|
|
4135
4143
|
const defaultRetryOptions = {
|
|
@@ -4524,7 +4532,7 @@ function Answer({
|
|
|
4524
4532
|
return /* @__PURE__ */ React__default.createElement(
|
|
4525
4533
|
"div",
|
|
4526
4534
|
{
|
|
4527
|
-
className: "rounded-lg relative mx-auto overflow-hidden bg-card border border-primary
|
|
4535
|
+
className: "rounded-lg relative mx-auto overflow-hidden bg-card border border-primary",
|
|
4528
4536
|
"data-name": "SearchResults",
|
|
4529
4537
|
"data-index": index
|
|
4530
4538
|
},
|
|
@@ -5352,6 +5360,7 @@ const ChatSearchComponent = forwardRef(
|
|
|
5352
5360
|
const fileInputRef = useRef(null);
|
|
5353
5361
|
const primarySearchRef = useRef(null);
|
|
5354
5362
|
const followUpSearchRef = useRef(null);
|
|
5363
|
+
const bottomRef = useRef(null);
|
|
5355
5364
|
const { suggestions: autocompleteSuggestions } = useAutocomplete({
|
|
5356
5365
|
query,
|
|
5357
5366
|
endpoint: autocompleteEndpoint || "",
|
|
@@ -5366,7 +5375,11 @@ const ChatSearchComponent = forwardRef(
|
|
|
5366
5375
|
headers,
|
|
5367
5376
|
mergedTextConfig
|
|
5368
5377
|
});
|
|
5369
|
-
const { scrollToLastAnswer, scrollToAnswer } = useScrollManager(
|
|
5378
|
+
const { scrollToLastAnswer, scrollToAnswer, scrollToBottom } = useScrollManager(
|
|
5379
|
+
answerRefs,
|
|
5380
|
+
containerRef,
|
|
5381
|
+
bottomRef
|
|
5382
|
+
);
|
|
5370
5383
|
const { subscribeToStateChanges } = useSubscriptionManager();
|
|
5371
5384
|
const loadFollowUpQuestions = async (searchQueryId, conversationId) => {
|
|
5372
5385
|
if (!followUpQuestionsEndpoint || disableFollowUpQuestions) {
|
|
@@ -5403,6 +5416,7 @@ const ChatSearchComponent = forwardRef(
|
|
|
5403
5416
|
for (const line of lines) {
|
|
5404
5417
|
try {
|
|
5405
5418
|
if (line === "[DONE]") {
|
|
5419
|
+
scrollToBottom();
|
|
5406
5420
|
continue;
|
|
5407
5421
|
}
|
|
5408
5422
|
const event = JSON.parse(line);
|
|
@@ -5413,6 +5427,7 @@ const ChatSearchComponent = forwardRef(
|
|
|
5413
5427
|
text: event.content
|
|
5414
5428
|
})
|
|
5415
5429
|
);
|
|
5430
|
+
scrollToBottom();
|
|
5416
5431
|
const uncertaintyCheck = isAnswerUncertain(accumulatedAnswer);
|
|
5417
5432
|
isUncertain = uncertaintyCheck.uncertain;
|
|
5418
5433
|
if (isUncertain) {
|
|
@@ -5944,7 +5959,8 @@ const ChatSearchComponent = forwardRef(
|
|
|
5944
5959
|
ref: (el) => answerRefs.current[i] = el,
|
|
5945
5960
|
initial: { opacity: 0, y: 20 },
|
|
5946
5961
|
animate: { opacity: 1, y: 0 },
|
|
5947
|
-
transition: { duration: 0.5, delay: i * 0.1 }
|
|
5962
|
+
transition: { duration: 0.5, delay: i * 0.1 },
|
|
5963
|
+
className: "space-y-4 last:!mb-8"
|
|
5948
5964
|
},
|
|
5949
5965
|
/* @__PURE__ */ React__default.createElement(
|
|
5950
5966
|
Answer,
|
|
@@ -5967,13 +5983,13 @@ const ChatSearchComponent = forwardRef(
|
|
|
5967
5983
|
onFeedbackReasonSubmit: (reason) => void handleFeedbackReasonSubmit(reason, answer.searchQueryId)
|
|
5968
5984
|
}
|
|
5969
5985
|
),
|
|
5970
|
-
i === answers.length - 1 && !disableFollowUpQuestions && answer.followUpQuestions && answer.state === "completed" && /* @__PURE__ */ React__default.createElement(
|
|
5986
|
+
i === answers.length - 1 && !disableFollowUpQuestions && answer.followUpQuestions && answer.state === "completed" && /* @__PURE__ */ React__default.createElement(
|
|
5971
5987
|
FollowUpQuestions,
|
|
5972
5988
|
{
|
|
5973
5989
|
questions: answer.followUpQuestions,
|
|
5974
5990
|
onQuestionClick: handleFollowUpQuestionClick
|
|
5975
5991
|
}
|
|
5976
|
-
)
|
|
5992
|
+
)
|
|
5977
5993
|
))
|
|
5978
5994
|
))), showResults && answers.length > 1 && /* @__PURE__ */ React__default.createElement("div", { className: "hidden lg:block" }, /* @__PURE__ */ React__default.createElement(
|
|
5979
5995
|
TimelineNavigation,
|
|
@@ -5986,7 +6002,7 @@ const ChatSearchComponent = forwardRef(
|
|
|
5986
6002
|
},
|
|
5987
6003
|
offset
|
|
5988
6004
|
}
|
|
5989
|
-
)), disclaimer && isWidgetMode && !(showResults && showFollowUp) && /* @__PURE__ */ React__default.createElement("div", { className: "mt-2 px-3 @3xl:px-0 text-xs text-dark-500 flex items-center gap-1 absolute bottom-12 justify-center text-center w-full" }, /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "Info", className: "size-4" }), disclaimer)),
|
|
6005
|
+
)), disclaimer && isWidgetMode && !(showResults && showFollowUp) && /* @__PURE__ */ React__default.createElement("div", { className: "mt-2 px-3 @3xl:px-0 text-xs text-dark-500 flex items-center gap-1 absolute bottom-12 justify-center text-center w-full" }, /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "Info", className: "size-4" }), disclaimer), /* @__PURE__ */ React__default.createElement("div", { ref: bottomRef })),
|
|
5990
6006
|
showResults && showFollowUp && /* @__PURE__ */ React__default.createElement(
|
|
5991
6007
|
FollowUpSearchBar,
|
|
5992
6008
|
{
|
|
@@ -6003,8 +6019,8 @@ const ChatSearchComponent = forwardRef(
|
|
|
6003
6019
|
}
|
|
6004
6020
|
);
|
|
6005
6021
|
ChatSearchComponent.displayName = "ChatSearch";
|
|
6006
|
-
const ChatSearch = forwardRef(({ featureFlags, ...props }, ref) => /* @__PURE__ */ React__default.createElement(FeatureFlagProvider, { flags: featureFlags }, /* @__PURE__ */ React__default.createElement(ChatSearchProvider, { searchPath: props.searchPath }, /* @__PURE__ */ React__default.createElement(ChatSearchComponent, { ...props, ref }))));
|
|
6022
|
+
const ChatSearch = forwardRef(({ featureFlags, ...props }, ref) => /* @__PURE__ */ React__default.createElement(FeatureFlagProvider, { flags: featureFlags }, /* @__PURE__ */ React__default.createElement(ChatSearchProvider, { searchPath: props.searchPath, contentTypeEndpoint: props.contentTypeEndpoint }, /* @__PURE__ */ React__default.createElement(ChatSearchComponent, { ...props, ref }))));
|
|
6007
6023
|
ChatSearch.displayName = "ChatSearch";
|
|
6008
6024
|
|
|
6009
6025
|
export { ChatSearch as C, ChatSearchProvider as a, useIsChatSearchDirty as b, useChatSearch as u };
|
|
6010
|
-
//# sourceMappingURL=ChatSearch.
|
|
6026
|
+
//# sourceMappingURL=ChatSearch.CNtUt5oJ.js.map
|