From c2f94e9e8a9bf24a880d52ac89579031680cabd6 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 19 Sep 2025 11:32:30 +0800 Subject: [PATCH] feat: api call the try app and support disable feedback --- .../base/chat/chat/answer/operation.tsx | 5 ++-- web/app/components/base/chat/chat/context.tsx | 3 ++ web/app/components/base/chat/chat/index.tsx | 3 ++ .../chat/embedded-chatbot/chat-wrapper.tsx | 2 ++ .../base/chat/embedded-chatbot/context.tsx | 1 + .../base/chat/embedded-chatbot/hooks.tsx | 30 +++++++++++-------- web/app/components/try/app/chat.tsx | 4 ++- web/service/share.ts | 11 +++++-- 8 files changed, 40 insertions(+), 19 deletions(-) diff --git a/web/app/components/base/chat/chat/answer/operation.tsx b/web/app/components/base/chat/chat/answer/operation.tsx index 7ffb21c6d8..f86801f86b 100644 --- a/web/app/components/base/chat/chat/answer/operation.tsx +++ b/web/app/components/base/chat/chat/answer/operation.tsx @@ -51,6 +51,7 @@ const Operation: FC = ({ onAnnotationAdded, onAnnotationEdited, onAnnotationRemoved, + disableFeedback, onFeedback, onRegenerate, } = useChatContext() @@ -166,7 +167,7 @@ const Operation: FC = ({ )} )} - {!isOpeningStatement && config?.supportFeedback && !localFeedback?.rating && onFeedback && ( + {!disableFeedback && !isOpeningStatement && config?.supportFeedback && !localFeedback?.rating && onFeedback && (
{!localFeedback?.rating && ( <> @@ -180,7 +181,7 @@ const Operation: FC = ({ )}
)} - {!isOpeningStatement && config?.supportFeedback && localFeedback?.rating && onFeedback && ( + {!disableFeedback && !isOpeningStatement && config?.supportFeedback && localFeedback?.rating && onFeedback && (
{localFeedback?.rating === 'like' && ( handleFeedback(null)}> diff --git a/web/app/components/base/chat/chat/context.tsx b/web/app/components/base/chat/chat/context.tsx index 8c69884c91..983814f134 100644 --- a/web/app/components/base/chat/chat/context.tsx +++ b/web/app/components/base/chat/chat/context.tsx @@ -15,6 +15,7 @@ export type ChatContextValue = Pick @@ -39,6 +40,7 @@ export const ChatContextProvider = ({ onAnnotationEdited, onAnnotationAdded, onAnnotationRemoved, + disableFeedback, onFeedback, }: ChatContextProviderProps) => { return ( @@ -54,6 +56,7 @@ export const ChatContextProvider = ({ onAnnotationEdited, onAnnotationAdded, onAnnotationRemoved, + disableFeedback, onFeedback, }}> {children} diff --git a/web/app/components/base/chat/chat/index.tsx b/web/app/components/base/chat/chat/index.tsx index bee37cf2cd..7f831c7a6a 100644 --- a/web/app/components/base/chat/chat/index.tsx +++ b/web/app/components/base/chat/chat/index.tsx @@ -60,6 +60,7 @@ export type ChatProps = { onAnnotationAdded?: (annotationId: string, authorName: string, question: string, answer: string, index: number) => void onAnnotationRemoved?: (index: number) => void chatNode?: ReactNode + disableFeedback?: boolean onFeedback?: (messageId: string, feedback: Feedback) => void chatAnswerContainerInner?: string hideProcessDetail?: boolean @@ -99,6 +100,7 @@ const Chat: FC = ({ onAnnotationEdited, onAnnotationRemoved, chatNode, + disableFeedback, onFeedback, chatAnswerContainerInner, hideProcessDetail, @@ -225,6 +227,7 @@ const Chat: FC = ({ onAnnotationAdded={onAnnotationAdded} onAnnotationEdited={onAnnotationEdited} onAnnotationRemoved={onAnnotationRemoved} + disableFeedback={disableFeedback} onFeedback={onFeedback} >
diff --git a/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx b/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx index fe8601d2c7..dc1e969b53 100644 --- a/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx +++ b/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx @@ -44,6 +44,7 @@ const ChatWrapper = () => { isInstalledApp, appId, appMeta, + disableFeedback, handleFeedback, currentChatInstanceRef, themeBuilder, @@ -258,6 +259,7 @@ const ChatWrapper = () => { } allToolIcons={appMeta?.tool_icons || {}} + disableFeedback={disableFeedback} onFeedback={handleFeedback} suggestedQuestions={suggestedQuestions} answerIcon={answerIcon} diff --git a/web/app/components/base/chat/embedded-chatbot/context.tsx b/web/app/components/base/chat/embedded-chatbot/context.tsx index 544da253af..b8e385d33f 100644 --- a/web/app/components/base/chat/embedded-chatbot/context.tsx +++ b/web/app/components/base/chat/embedded-chatbot/context.tsx @@ -42,6 +42,7 @@ export type EmbeddedChatbotContextValue = { isInstalledApp: boolean allowResetChat: boolean appId?: string + disableFeedback?: boolean handleFeedback: (messageId: string, feedback: Feedback) => void currentChatInstanceRef: RefObject<{ handleStop: () => void }> themeBuilder?: ThemeBuilder diff --git a/web/app/components/base/chat/embedded-chatbot/hooks.tsx b/web/app/components/base/chat/embedded-chatbot/hooks.tsx index a8a6d640ff..773d3d3a19 100644 --- a/web/app/components/base/chat/embedded-chatbot/hooks.tsx +++ b/web/app/components/base/chat/embedded-chatbot/hooks.tsx @@ -24,6 +24,7 @@ import { fetchAppParams, fetchChatList, fetchConversations, + fetchTryAppInfo, generationConversationName, updateFeedback, } from '@/service/share' @@ -66,25 +67,27 @@ function getFormattedChatList(messages: any[]) { return newChatList } -export const useEmbeddedChatbot = () => { - const isInstalledApp = false - const appSourceType = AppSourceType.webApp +export const useEmbeddedChatbot = (appSourceType = AppSourceType.webApp, tryAppId?: string) => { + // const isWebApp = appSourceType === AppSourceType.webApp + const isInstalledApp = false // webapp and try app + const isTryApp = appSourceType === AppSourceType.tryApp const systemFeatures = useGlobalPublicStore(s => s.systemFeatures) - const { data: appInfo, isLoading: appInfoLoading, error: appInfoError } = useSWR('appInfo', fetchAppInfo) + const { data: appInfo, isLoading: appInfoLoading, error: appInfoError } = useSWR('appInfo', isTryApp ? fetchTryAppInfo : fetchAppInfo) const { isPending: isCheckingPermission, data: userCanAccessResult } = useGetUserCanAccessApp({ appId: appInfo?.app_id, isInstalledApp, - enabled: systemFeatures.webapp_auth.enabled, + enabled: systemFeatures.webapp_auth.enabled && !isTryApp, }) const appData = useMemo(() => { return appInfo }, [appInfo]) - const appId = useMemo(() => appData?.app_id, [appData]) + const appId = useMemo(() => isTryApp ? tryAppId : appData?.app_id, [appData, appSourceType, tryAppId]) const [userId, setUserId] = useState() const [conversationId, setConversationId] = useState() useEffect(() => { + if(isTryApp) return getProcessedSystemVariablesFromUrlParams().then(({ user_id, conversation_id }) => { setUserId(user_id) setConversationId(conversation_id) @@ -92,6 +95,7 @@ export const useEmbeddedChatbot = () => { }, []) useEffect(() => { + if(isTryApp) return const setLanguageFromParams = async () => { // Check URL parameters for language override const urlParams = new URLSearchParams(window.location.search) @@ -147,11 +151,11 @@ export const useEmbeddedChatbot = () => { return currentConversationId }, [currentConversationId, newConversationId]) - const { data: appParams } = useSWR(['appParams', isInstalledApp, appId], () => fetchAppParams(appSourceType, appId)) - const { data: appMeta } = useSWR(['appMeta', isInstalledApp, appId], () => fetchAppMeta(appSourceType, appId)) - const { data: appPinnedConversationData } = useSWR(['appConversationData', isInstalledApp, appId, true], () => fetchConversations(appSourceType, appId, undefined, true, 100)) - const { data: appConversationData, isLoading: appConversationDataLoading, mutate: mutateAppConversationData } = useSWR(['appConversationData', isInstalledApp, appId, false], () => fetchConversations(appSourceType, appId, undefined, false, 100)) - const { data: appChatListData, isLoading: appChatListDataLoading } = useSWR(chatShouldReloadKey ? ['appChatList', chatShouldReloadKey, isInstalledApp, appId] : null, () => fetchChatList(chatShouldReloadKey, appSourceType, appId)) + const { data: appParams } = useSWR(['appParams', appSourceType, appId], () => fetchAppParams(appSourceType, appId)) + const { data: appMeta } = useSWR(['appMeta', appSourceType, appId], () => fetchAppMeta(appSourceType, appId)) + const { data: appPinnedConversationData } = useSWR(['appConversationData', appSourceType, appId, true], () => fetchConversations(appSourceType, appId, undefined, true, 100)) + const { data: appConversationData, isLoading: appConversationDataLoading, mutate: mutateAppConversationData } = useSWR(isTryApp ? null : ['appConversationData', appSourceType, appId, false], () => fetchConversations(appSourceType, appId, undefined, false, 100)) + const { data: appChatListData, isLoading: appChatListDataLoading } = useSWR(chatShouldReloadKey ? ['appChatList', chatShouldReloadKey, appSourceType, appId] : null, () => fetchChatList(chatShouldReloadKey, appSourceType, appId)) const [clearChatList, setClearChatList] = useState(false) const [isResponding, setIsResponding] = useState(false) @@ -268,7 +272,7 @@ export const useEmbeddedChatbot = () => { handleNewConversationInputsChange(conversationInputs) }, [handleNewConversationInputsChange, inputsForms]) - const { data: newConversation } = useSWR(newConversationId ? [isInstalledApp, appId, newConversationId] : null, () => generationConversationName(appSourceType, appId, newConversationId), { revalidateOnFocus: false }) + const { data: newConversation } = useSWR((!isTryApp && newConversationId) ? [isInstalledApp, appId, newConversationId] : null, () => generationConversationName(appSourceType, appId, newConversationId), { revalidateOnFocus: false }) const [originConversationList, setOriginConversationList] = useState([]) useEffect(() => { if (appConversationData?.data && !appConversationDataLoading) @@ -399,7 +403,7 @@ export const useEmbeddedChatbot = () => { return { appInfoError, appInfoLoading: appInfoLoading || (systemFeatures.webapp_auth.enabled && isCheckingPermission), - userCanAccess: systemFeatures.webapp_auth.enabled ? (userCanAccessResult as { result: boolean })?.result : true, + userCanAccess: isTryApp || (systemFeatures.webapp_auth.enabled ? (userCanAccessResult as { result: boolean })?.result : true), isInstalledApp, allowResetChat, appId, diff --git a/web/app/components/try/app/chat.tsx b/web/app/components/try/app/chat.tsx index b9f1d39fdd..364f0d2860 100644 --- a/web/app/components/try/app/chat.tsx +++ b/web/app/components/try/app/chat.tsx @@ -11,6 +11,7 @@ import { useEmbeddedChatbot, } from '@/app/components/base/chat/embedded-chatbot/hooks' import cn from '@/utils/classnames' +import { AppSourceType } from '@/service/share' type Props = { appId: string @@ -24,10 +25,11 @@ const TryApp: FC = ({ const media = useBreakpoints() const isMobile = media === MediaType.mobile const themeBuilder = useThemeContext() - const chatData = useEmbeddedChatbot() + const chatData = useEmbeddedChatbot(AppSourceType.tryApp, appId) return ( diff --git a/web/service/share.ts b/web/service/share.ts index 3b28338a8c..9b6eef8b97 100644 --- a/web/service/share.ts +++ b/web/service/share.ts @@ -39,7 +39,7 @@ export enum AppSourceType { const apiPrefix = { [AppSourceType.webApp]: '', [AppSourceType.installedApp]: 'installed-apps', - [AppSourceType.tryApp]: 'try-apps', + [AppSourceType.tryApp]: 'installed-apps', // 'trial-apps', use 'installed-apps' for test } function getIsPublicAPI(appSourceType: AppSourceType) { @@ -141,6 +141,11 @@ export const fetchAppInfo = async () => { return get('/site') as Promise } +// would use trial-apps after api is ok +export const fetchTryAppInfo = async () => { + return get('/site') as Promise +} + export const fetchConversations = async (appSourceType: AppSourceType, installedAppId = '', last_id?: string, pinned?: boolean, limit?: number) => { return getAction('get', appSourceType)(getUrl('conversations', appSourceType, installedAppId), { params: { limit: limit || 20, ...(last_id ? { last_id } : {}), ...(pinned !== undefined ? { pinned } : {}) } }) as Promise } @@ -175,8 +180,8 @@ export const fetchChatList = async (conversationId: string, appSourceType: AppSo // } // init value. wait for server update -export const fetchAppParams = async (appSourceType: AppSourceType, installedAppId = '') => { - return (getAction('get', appSourceType))(getUrl('parameters', appSourceType, installedAppId)) as Promise +export const fetchAppParams = async (appSourceType: AppSourceType, appId = '') => { + return (getAction('get', appSourceType))(getUrl('parameters', appSourceType, appId)) as Promise } export const fetchWebSAMLSSOUrl = async (appCode: string, redirectUrl: string) => {