mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-15 22:46:49 +00:00
add chat plugin and split query to parse and execute (#25)
* [feature](webapp) add drill down dimensions and metric period compare and modify layout * [feature](webapp) add drill down dimensions and metric period compare and modify layout * [feature](webapp) gitignore add supersonic-webapp * [feature](webapp) gitignore add supersonic-webapp * [feature](webapp) add chat plugin and split query to parse and execute * [feature](webapp) add chat plugin and split query to parse and execute * [feature](webapp) add chat plugin and split query to parse and execute --------- Co-authored-by: williamhliu <williamhliu@tencent.com>
This commit is contained in:
@@ -1,28 +1,54 @@
|
||||
import { updateMessageContainerScroll, isMobile, uuid, getLeafList } from '@/utils/utils';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { Helmet } from 'umi';
|
||||
import { Helmet, useDispatch, useLocation } from 'umi';
|
||||
import MessageContainer from './MessageContainer';
|
||||
import styles from './style.less';
|
||||
import { ConversationDetailType, DomainType, MessageItem, MessageTypeEnum } from './type';
|
||||
import { getDomainList, updateConversationName } from './service';
|
||||
import {
|
||||
ConversationDetailType,
|
||||
DefaultEntityType,
|
||||
DomainType,
|
||||
MessageItem,
|
||||
MessageTypeEnum,
|
||||
} from './type';
|
||||
import { getDomainList } from './service';
|
||||
import { useThrottleFn } from 'ahooks';
|
||||
import RightSection from './RightSection';
|
||||
import Conversation from './Conversation';
|
||||
import ChatFooter from './ChatFooter';
|
||||
import classNames from 'classnames';
|
||||
import { CHAT_TITLE, DEFAULT_CONVERSATION_NAME, WEB_TITLE } from './constants';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { HistoryMsgItemType, MsgDataType, getHistoryMsg } from 'supersonic-chat-sdk';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import 'supersonic-chat-sdk/dist/index.css';
|
||||
import { setToken as setChatSdkToken } from 'supersonic-chat-sdk';
|
||||
import { TOKEN_KEY } from '@/services/request';
|
||||
import Conversation from './Conversation';
|
||||
import { AUTH_TOKEN_KEY } from '@/common/constants';
|
||||
|
||||
type Props = {
|
||||
isCopilotMode?: boolean;
|
||||
copilotFullscreen?: boolean;
|
||||
defaultDomainName?: string;
|
||||
defaultEntityFilter?: DefaultEntityType;
|
||||
copilotSendMsg?: string;
|
||||
triggerNewConversation?: boolean;
|
||||
onNewConversationTriggered?: () => void;
|
||||
onCurrentDomainChange?: (domain?: DomainType) => void;
|
||||
onCancelCopilotFilter?: () => void;
|
||||
onCheckMoreDetail?: () => void;
|
||||
};
|
||||
|
||||
const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
const isMobileMode = (isMobile || isCopilotMode) as boolean;
|
||||
const Chat: React.FC<Props> = ({
|
||||
isCopilotMode,
|
||||
copilotFullscreen,
|
||||
defaultDomainName,
|
||||
defaultEntityFilter,
|
||||
copilotSendMsg,
|
||||
triggerNewConversation,
|
||||
onNewConversationTriggered,
|
||||
onCurrentDomainChange,
|
||||
onCancelCopilotFilter,
|
||||
onCheckMoreDetail,
|
||||
}) => {
|
||||
const isMobileMode = isMobile || isCopilotMode;
|
||||
const localConversationCollapsed = localStorage.getItem('CONVERSATION_COLLAPSED');
|
||||
|
||||
const [messageList, setMessageList] = useState<MessageItem[]>([]);
|
||||
const [inputMsg, setInputMsg] = useState('');
|
||||
@@ -32,68 +58,137 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
const [currentConversation, setCurrentConversation] = useState<
|
||||
ConversationDetailType | undefined
|
||||
>(isMobile ? { chatId: 0, chatName: `${CHAT_TITLE}问答` } : undefined);
|
||||
const [currentEntity, setCurrentEntity] = useState<MsgDataType>();
|
||||
const [miniProgramLoading, setMiniProgramLoading] = useState(false);
|
||||
const [conversationCollapsed, setConversationCollapsed] = useState(
|
||||
!localConversationCollapsed ? true : localConversationCollapsed === 'true',
|
||||
);
|
||||
const [domains, setDomains] = useState<DomainType[]>([]);
|
||||
const [currentDomain, setCurrentDomain] = useState<DomainType>();
|
||||
const [conversationCollapsed, setConversationCollapsed] = useState(false);
|
||||
const [defaultEntity, setDefaultEntity] = useState<DefaultEntityType>();
|
||||
const [applyAuthVisible, setApplyAuthVisible] = useState(false);
|
||||
const [applyAuthDomain, setApplyAuthDomain] = useState('');
|
||||
const [initialDomainName, setInitialDomainName] = useState('');
|
||||
const location = useLocation();
|
||||
const dispatch = useDispatch();
|
||||
const { domainName } = (location as any).query;
|
||||
|
||||
const conversationRef = useRef<any>();
|
||||
const chatFooterRef = useRef<any>();
|
||||
|
||||
useEffect(() => {
|
||||
setChatSdkToken(localStorage.getItem(AUTH_TOKEN_KEY) || '');
|
||||
initDomains();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (domains.length > 0 && initialDomainName && !currentDomain) {
|
||||
changeDomain(domains.find((domain) => domain.name === initialDomainName));
|
||||
}
|
||||
}, [domains]);
|
||||
|
||||
useEffect(() => {
|
||||
if (domainName) {
|
||||
setInitialDomainName(domainName);
|
||||
}
|
||||
}, [domainName]);
|
||||
|
||||
useEffect(() => {
|
||||
if (defaultDomainName !== undefined && domains.length > 0) {
|
||||
changeDomain(domains.find((domain) => domain.name === defaultDomainName));
|
||||
}
|
||||
}, [defaultDomainName]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentConversation) {
|
||||
return;
|
||||
}
|
||||
const { initMsg, domainId, entityId } = currentConversation;
|
||||
if (initMsg) {
|
||||
inputFocus();
|
||||
if (initMsg === 'CUSTOMIZE' && copilotSendMsg) {
|
||||
onSendMsg(copilotSendMsg, [], domainId, entityId);
|
||||
dispatch({
|
||||
type: 'globalState/setCopilotSendMsg',
|
||||
payload: '',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (initMsg === DEFAULT_CONVERSATION_NAME || initMsg.includes('CUSTOMIZE')) {
|
||||
sendHelloRsp();
|
||||
return;
|
||||
}
|
||||
onSendMsg(initMsg, [], domainId, entityId);
|
||||
return;
|
||||
}
|
||||
updateHistoryMsg(1);
|
||||
setPageNo(1);
|
||||
}, [currentConversation]);
|
||||
|
||||
useEffect(() => {
|
||||
setDefaultEntity(defaultEntityFilter);
|
||||
}, [defaultEntityFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (historyInited) {
|
||||
const messageContainerEle = document.getElementById('messageContainer');
|
||||
messageContainerEle?.addEventListener('scroll', handleScroll);
|
||||
}
|
||||
return () => {
|
||||
const messageContainerEle = document.getElementById('messageContainer');
|
||||
messageContainerEle?.removeEventListener('scroll', handleScroll);
|
||||
};
|
||||
}, [historyInited]);
|
||||
|
||||
useEffect(() => {
|
||||
inputFocus();
|
||||
}, [copilotFullscreen]);
|
||||
|
||||
const sendHelloRsp = () => {
|
||||
setMessageList([
|
||||
{
|
||||
id: uuid(),
|
||||
type: MessageTypeEnum.RECOMMEND_QUESTIONS,
|
||||
// msg: '您好,请问有什么我能帮您吗?',
|
||||
type: MessageTypeEnum.TEXT,
|
||||
msg: defaultDomainName
|
||||
? `您好,请输入关于${
|
||||
defaultEntityFilter?.entityName
|
||||
? `${defaultDomainName?.slice(0, defaultDomainName?.length - 1)}【${
|
||||
defaultEntityFilter?.entityName
|
||||
}】`
|
||||
: `【${defaultDomainName}】`
|
||||
}的问题`
|
||||
: '您好,请问有什么我能帮您吗?',
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
const existInstuctionMsg = (list: HistoryMsgItemType[]) => {
|
||||
return list.some((msg) => msg.queryResult?.queryMode === MessageTypeEnum.INSTRUCTION);
|
||||
};
|
||||
|
||||
const updateScroll = (list: HistoryMsgItemType[]) => {
|
||||
if (existInstuctionMsg(list)) {
|
||||
setMiniProgramLoading(true);
|
||||
setTimeout(() => {
|
||||
setMiniProgramLoading(false);
|
||||
updateMessageContainerScroll();
|
||||
}, 3000);
|
||||
} else {
|
||||
updateMessageContainerScroll();
|
||||
}
|
||||
const convertHistoryMsg = (list: HistoryMsgItemType[]) => {
|
||||
return list.map((item: HistoryMsgItemType) => ({
|
||||
id: item.questionId,
|
||||
type:
|
||||
item.queryResult?.queryMode === MessageTypeEnum.PLUGIN ||
|
||||
item.queryResult?.queryMode === MessageTypeEnum.WEB_PAGE
|
||||
? MessageTypeEnum.PLUGIN
|
||||
: MessageTypeEnum.QUESTION,
|
||||
msg: item.queryText,
|
||||
msgData: item.queryResult,
|
||||
score: item.score,
|
||||
isHistory: true,
|
||||
}));
|
||||
};
|
||||
|
||||
const updateHistoryMsg = async (page: number) => {
|
||||
const res = await getHistoryMsg(page, currentConversation!.chatId, 3);
|
||||
const { hasNextPage, list } = res.data?.data || { hasNextPage: false, list: [] };
|
||||
setMessageList([
|
||||
...list.map((item: HistoryMsgItemType) => ({
|
||||
id: item.questionId,
|
||||
type:
|
||||
item.queryResult?.queryMode === MessageTypeEnum.INSTRUCTION
|
||||
? MessageTypeEnum.INSTRUCTION
|
||||
: MessageTypeEnum.QUESTION,
|
||||
msg: item.queryText,
|
||||
msgData: item.queryResult,
|
||||
isHistory: true,
|
||||
})),
|
||||
...(page === 1 ? [] : messageList),
|
||||
]);
|
||||
const msgList = [...convertHistoryMsg(list), ...(page === 1 ? [] : messageList)];
|
||||
setMessageList(msgList);
|
||||
setHasNextPage(hasNextPage);
|
||||
if (page === 1) {
|
||||
if (list.length === 0) {
|
||||
sendHelloRsp();
|
||||
} else {
|
||||
setCurrentEntity(list[list.length - 1].queryResult);
|
||||
}
|
||||
updateScroll(list);
|
||||
updateMessageContainerScroll();
|
||||
setHistoryInited(true);
|
||||
inputFocus();
|
||||
}
|
||||
if (page > 1) {
|
||||
} else {
|
||||
const msgEle = document.getElementById(`${messageList[0]?.id}`);
|
||||
msgEle?.scrollIntoView();
|
||||
}
|
||||
@@ -113,31 +208,21 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
},
|
||||
);
|
||||
|
||||
const initDomains = async () => {
|
||||
try {
|
||||
const res = await getDomainList();
|
||||
const domainList = getLeafList(res.data);
|
||||
setDomains(
|
||||
[{ id: -1, name: '全部', bizName: 'all', parentId: 0 }, ...domainList].slice(0, 11),
|
||||
);
|
||||
} catch (e) {}
|
||||
const changeDomain = (domain?: DomainType) => {
|
||||
setCurrentDomain(domain);
|
||||
if (onCurrentDomainChange) {
|
||||
onCurrentDomainChange(domain);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setChatSdkToken(localStorage.getItem(TOKEN_KEY) || '');
|
||||
initDomains();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (historyInited) {
|
||||
const messageContainerEle = document.getElementById('messageContainer');
|
||||
messageContainerEle?.addEventListener('scroll', handleScroll);
|
||||
const initDomains = async () => {
|
||||
const res = await getDomainList();
|
||||
const domainList = getLeafList(res.data);
|
||||
setDomains([{ id: -1, name: '全部', bizName: 'all', parentId: 0 }, ...domainList].slice(0, 11));
|
||||
if (defaultDomainName !== undefined) {
|
||||
changeDomain(domainList.find((domain) => domain.name === defaultDomainName));
|
||||
}
|
||||
return () => {
|
||||
const messageContainerEle = document.getElementById('messageContainer');
|
||||
messageContainerEle?.removeEventListener('scroll', handleScroll);
|
||||
};
|
||||
}, [historyInited]);
|
||||
};
|
||||
|
||||
const inputFocus = () => {
|
||||
if (!isMobile) {
|
||||
@@ -149,34 +234,12 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
chatFooterRef.current?.inputBlur();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentConversation) {
|
||||
return;
|
||||
}
|
||||
setCurrentEntity(undefined);
|
||||
const { initMsg, domainId } = currentConversation;
|
||||
if (initMsg) {
|
||||
inputFocus();
|
||||
if (initMsg === DEFAULT_CONVERSATION_NAME) {
|
||||
sendHelloRsp();
|
||||
return;
|
||||
}
|
||||
onSendMsg(currentConversation.initMsg, [], domainId);
|
||||
return;
|
||||
}
|
||||
updateHistoryMsg(1);
|
||||
setPageNo(1);
|
||||
}, [currentConversation]);
|
||||
|
||||
const modifyConversationName = async (name: string) => {
|
||||
await updateConversationName(name, currentConversation!.chatId);
|
||||
if (!isMobileMode) {
|
||||
conversationRef?.current?.updateData();
|
||||
window.history.replaceState('', '', `?q=${name}&cid=${currentConversation!.chatId}`);
|
||||
}
|
||||
};
|
||||
|
||||
const onSendMsg = async (msg?: string, list?: MessageItem[], domainId?: number) => {
|
||||
const onSendMsg = async (
|
||||
msg?: string,
|
||||
list?: MessageItem[],
|
||||
domainId?: number,
|
||||
entityId?: string,
|
||||
) => {
|
||||
const currentMsg = msg || inputMsg;
|
||||
if (currentMsg.trim() === '') {
|
||||
setInputMsg('');
|
||||
@@ -184,8 +247,12 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
}
|
||||
const msgDomain = domains.find((item) => currentMsg.includes(item.name));
|
||||
const certainDomain = currentMsg[0] === '@' && msgDomain;
|
||||
let domainChanged = false;
|
||||
|
||||
if (certainDomain) {
|
||||
setCurrentDomain(msgDomain.id === -1 ? undefined : msgDomain);
|
||||
const toDomain = msgDomain.id === -1 ? undefined : msgDomain;
|
||||
changeDomain(toDomain);
|
||||
domainChanged = currentDomain?.id !== toDomain?.id;
|
||||
}
|
||||
const domainIdValue = domainId || msgDomain?.id || currentDomain?.id;
|
||||
const msgs = [
|
||||
@@ -195,6 +262,7 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
msg: currentMsg,
|
||||
msgValue: certainDomain ? currentMsg.replace(`@${msgDomain.name}`, '').trim() : currentMsg,
|
||||
domainId: domainIdValue === -1 ? undefined : domainIdValue,
|
||||
entityId: entityId || (domainChanged ? undefined : defaultEntity?.entityId),
|
||||
identityMsg: certainDomain ? getIdentityMsgText(msgDomain) : undefined,
|
||||
type: MessageTypeEnum.QUESTION,
|
||||
},
|
||||
@@ -202,11 +270,6 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
setMessageList(msgs);
|
||||
updateMessageContainerScroll();
|
||||
setInputMsg('');
|
||||
modifyConversationName(currentMsg);
|
||||
};
|
||||
|
||||
const onToggleCollapseBtn = () => {
|
||||
setConversationCollapsed(!conversationCollapsed);
|
||||
};
|
||||
|
||||
const onInputMsgChange = (value: string) => {
|
||||
@@ -224,29 +287,38 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const onSelectConversation = (conversation: ConversationDetailType, name?: string) => {
|
||||
const onSelectConversation = (
|
||||
conversation: ConversationDetailType,
|
||||
name?: string,
|
||||
domainId?: number,
|
||||
entityId?: string,
|
||||
) => {
|
||||
if (!isMobileMode) {
|
||||
window.history.replaceState('', '', `?q=${conversation.chatName}&cid=${conversation.chatId}`);
|
||||
}
|
||||
setCurrentConversation({
|
||||
...conversation,
|
||||
initMsg: name,
|
||||
domainId,
|
||||
entityId,
|
||||
});
|
||||
saveConversationToLocal(conversation);
|
||||
setCurrentDomain(undefined);
|
||||
};
|
||||
|
||||
const onMsgDataLoaded = (data: MsgDataType, questionId: string | number) => {
|
||||
if (!isMobile) {
|
||||
conversationRef?.current?.updateData();
|
||||
}
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
if (data.queryMode === 'INSTRUCTION') {
|
||||
if (data.queryMode === 'WEB_PAGE') {
|
||||
setMessageList([
|
||||
...messageList.slice(0, messageList.length - 1),
|
||||
...messageList,
|
||||
{
|
||||
id: uuid(),
|
||||
msg: data.response.name || messageList[messageList.length - 1]?.msg,
|
||||
type: MessageTypeEnum.INSTRUCTION,
|
||||
msg: messageList[messageList.length - 1]?.msg,
|
||||
type: MessageTypeEnum.PLUGIN,
|
||||
msgData: data,
|
||||
},
|
||||
]);
|
||||
@@ -259,7 +331,6 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
}
|
||||
updateMessageContainerScroll();
|
||||
}
|
||||
setCurrentEntity(data);
|
||||
};
|
||||
|
||||
const onCheckMore = (data: MsgDataType) => {
|
||||
@@ -268,11 +339,19 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
{
|
||||
id: uuid(),
|
||||
msg: data.response.name,
|
||||
type: MessageTypeEnum.INSTRUCTION,
|
||||
type: MessageTypeEnum.PLUGIN,
|
||||
msgData: data,
|
||||
},
|
||||
]);
|
||||
updateMessageContainerScroll();
|
||||
if (onCheckMoreDetail) {
|
||||
onCheckMoreDetail();
|
||||
}
|
||||
};
|
||||
|
||||
const onToggleCollapseBtn = () => {
|
||||
setConversationCollapsed(!conversationCollapsed);
|
||||
localStorage.setItem('CONVERSATION_COLLAPSED', `${!conversationCollapsed}`);
|
||||
};
|
||||
|
||||
const getIdentityMsgText = (domain?: DomainType) => {
|
||||
@@ -281,26 +360,19 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
: '您好,我将尽力帮您解答所有主题相关问题~';
|
||||
};
|
||||
|
||||
const getIdentityMsg = (domain?: DomainType) => {
|
||||
return {
|
||||
id: uuid(),
|
||||
type: MessageTypeEnum.TEXT,
|
||||
msg: getIdentityMsgText(domain),
|
||||
};
|
||||
const onApplyAuth = (domain: string) => {
|
||||
setApplyAuthDomain(domain);
|
||||
setApplyAuthVisible(true);
|
||||
};
|
||||
|
||||
const onSelectDomain = (domain: DomainType) => {
|
||||
const domainValue = currentDomain?.id === domain.id ? undefined : domain;
|
||||
setCurrentDomain(domainValue);
|
||||
setCurrentEntity(undefined);
|
||||
setMessageList([...messageList, getIdentityMsg(domainValue)]);
|
||||
updateMessageContainerScroll();
|
||||
const onAddConversation = () => {
|
||||
conversationRef.current?.onAddConversation();
|
||||
inputFocus();
|
||||
};
|
||||
|
||||
const chatClass = classNames(styles.chat, {
|
||||
[styles.mobile]: isMobileMode,
|
||||
[styles.copilot]: isCopilotMode,
|
||||
[styles.copilotFullscreen]: copilotFullscreen,
|
||||
[styles.conversationCollapsed]: conversationCollapsed,
|
||||
});
|
||||
|
||||
@@ -312,6 +384,11 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
<Conversation
|
||||
currentConversation={currentConversation}
|
||||
collapsed={conversationCollapsed}
|
||||
isCopilotMode={isCopilotMode}
|
||||
defaultDomainName={defaultDomainName}
|
||||
defaultEntityFilter={defaultEntityFilter}
|
||||
triggerNewConversation={triggerNewConversation}
|
||||
onNewConversationTriggered={onNewConversationTriggered}
|
||||
onSelectConversation={onSelectConversation}
|
||||
ref={conversationRef}
|
||||
/>
|
||||
@@ -325,20 +402,21 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
chatId={currentConversation?.chatId}
|
||||
isMobileMode={isMobileMode}
|
||||
conversationCollapsed={conversationCollapsed}
|
||||
onClickMessageContainer={() => {
|
||||
inputFocus();
|
||||
}}
|
||||
copilotFullscreen={copilotFullscreen}
|
||||
onClickMessageContainer={inputFocus}
|
||||
onMsgDataLoaded={onMsgDataLoaded}
|
||||
onSelectSuggestion={onSendMsg}
|
||||
onCheckMore={onCheckMore}
|
||||
onApplyAuth={onApplyAuth}
|
||||
/>
|
||||
<ChatFooter
|
||||
inputMsg={inputMsg}
|
||||
chatId={currentConversation?.chatId}
|
||||
domains={domains}
|
||||
currentDomain={currentDomain}
|
||||
defaultEntity={defaultEntity}
|
||||
collapsed={conversationCollapsed}
|
||||
isMobileMode={isMobileMode}
|
||||
isCopilotMode={isCopilotMode}
|
||||
copilotFullscreen={copilotFullscreen}
|
||||
onToggleCollapseBtn={onToggleCollapseBtn}
|
||||
onInputMsgChange={onInputMsgChange}
|
||||
onSendMsg={(msg: string, domainId?: number) => {
|
||||
@@ -347,9 +425,12 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
inputBlur();
|
||||
}
|
||||
}}
|
||||
onAddConversation={() => {
|
||||
conversationRef.current?.onAddConversation();
|
||||
inputFocus();
|
||||
onAddConversation={onAddConversation}
|
||||
onCancelDefaultFilter={() => {
|
||||
changeDomain(undefined);
|
||||
if (onCancelCopilotFilter) {
|
||||
onCancelCopilotFilter();
|
||||
}
|
||||
}}
|
||||
ref={chatFooterRef}
|
||||
/>
|
||||
@@ -357,17 +438,6 @@ const Chat: React.FC<Props> = ({ isCopilotMode }) => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* {!isMobileMode && (
|
||||
<RightSection
|
||||
domains={domains}
|
||||
currentEntity={currentEntity}
|
||||
currentDomain={currentDomain}
|
||||
currentConversation={currentConversation}
|
||||
onSelectDomain={onSelectDomain}
|
||||
onSelectConversation={onSelectConversation}
|
||||
conversationRef={conversationRef}
|
||||
/>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user