feat: add more share config (#3120)

* feat: add more share config

* add i18n en
This commit is contained in:
papapatrick
2024-11-12 10:09:02 +08:00
committed by archer
parent f4e0dfc9bd
commit 5892ded567
30 changed files with 389 additions and 173 deletions

View File

@@ -34,7 +34,7 @@ export type ChatProviderProps = OutLinkChatAuthProps & {
// not chat test params
chatId?: string;
chatType?: 'log' | 'chat';
chatType?: 'log' | 'chat' | 'share' | 'team';
};
type useChatStoreType = OutLinkChatAuthProps &

View File

@@ -13,6 +13,9 @@ import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { ChatSiteItemType } from '@fastgpt/global/core/chat/type';
import { addStatisticalDataToHistoryItem } from '@/global/core/chat/utils';
import { useSize } from 'ahooks';
import { ChatContext } from '@/web/core/chat/context/chatContext';
import { useContextSelector } from 'use-context-selector';
import { ChatBoxContext } from '../Provider';
const QuoteModal = dynamic(() => import('./QuoteModal'));
const ContextModal = dynamic(() => import('./ContextModal'));
@@ -37,6 +40,7 @@ const ResponseTags = ({
totalRunningTime: runningTime = 0,
historyPreviewLength = 0
} = useMemo(() => addStatisticalDataToHistoryItem(historyItem), [historyItem]);
const [quoteModalData, setQuoteModalData] = useState<{
rawSearch: SearchDataResponseItemType[];
metadata?: {
@@ -47,6 +51,13 @@ const ResponseTags = ({
}>();
const [quoteFolded, setQuoteFolded] = useState<boolean>(true);
const showCompleteQuote = useContextSelector(ChatContext, (v) => v.showCompleteQuote);
const { chatType } = useContextSelector(ChatBoxContext, (v) => v);
const showAllTag = useMemo(() => {
return chatType !== 'share' && chatType !== 'team';
}, [chatType]);
const {
isOpen: isOpenWholeModal,
onOpen: onOpenWholeModal,
@@ -77,10 +88,10 @@ const ResponseTags = ({
sourceName: item.sourceName,
sourceId: item.sourceId,
icon: getSourceNameIcon({ sourceId: item.sourceId, sourceName: item.sourceName }),
canReadQuote: showDetail || strIsLink(item.sourceId),
canReadQuote: showCompleteQuote || strIsLink(item.sourceId),
collectionId: item.collectionId
}));
}, [quoteList, showDetail]);
}, [quoteList, showCompleteQuote]);
return !showTags ? null : (
<>
@@ -176,49 +187,51 @@ const ResponseTags = ({
</Flex>
</>
)}
{showDetail && (
<Flex alignItems={'center'} mt={3} flexWrap={'wrap'} gap={2}>
{quoteList.length > 0 && (
<MyTooltip label={t('chat:view_citations')}>
<MyTag
colorSchema="blue"
type="borderSolid"
cursor={'pointer'}
onClick={() => setQuoteModalData({ rawSearch: quoteList })}
>
{t('chat:citations', { num: quoteList.length })}
</MyTag>
</MyTooltip>
)}
{llmModuleAccount === 1 && (
<>
{historyPreviewLength > 0 && (
<MyTooltip label={t('chat:click_contextual_preview')}>
<MyTag
colorSchema="green"
cursor={'pointer'}
type="borderSolid"
onClick={onOpenContextModal}
>
{t('chat:contextual', { num: historyPreviewLength })}
</MyTag>
</MyTooltip>
)}
</>
)}
{llmModuleAccount > 1 && (
<MyTag type="borderSolid" colorSchema="blue">
{t('chat:multiple_AI_conversations')}
</MyTag>
)}
{isPc && runningTime > 0 && (
<MyTooltip label={t('chat:module_runtime_and')}>
<MyTag colorSchema="purple" type="borderSolid" cursor={'default'}>
{runningTime}s
</MyTag>
</MyTooltip>
)}
<Flex alignItems={'center'} mt={3} flexWrap={'wrap'} gap={2}>
{quoteList.length > 0 && (
<MyTooltip label={t('chat:view_citations')}>
<MyTag
colorSchema="blue"
type="borderSolid"
cursor={'pointer'}
onClick={() => setQuoteModalData({ rawSearch: quoteList })}
>
{t('chat:citations', { num: quoteList.length })}
</MyTag>
</MyTooltip>
)}
{llmModuleAccount === 1 && showAllTag && (
<>
{historyPreviewLength > 0 && (
<MyTooltip label={t('chat:click_contextual_preview')}>
<MyTag
colorSchema="green"
cursor={'pointer'}
type="borderSolid"
onClick={onOpenContextModal}
>
{t('chat:contextual', { num: historyPreviewLength })}
</MyTag>
</MyTooltip>
)}
</>
)}
{llmModuleAccount > 1 && showAllTag && (
<MyTag type="borderSolid" colorSchema="blue">
{t('chat:multiple_AI_conversations')}
</MyTag>
)}
{isPc && runningTime > 0 && (
<MyTooltip label={t('chat:module_runtime_and')}>
<MyTag colorSchema="purple" type="borderSolid" cursor={'default'}>
{runningTime}s
</MyTag>
</MyTooltip>
)}
{showAllTag && (
<MyTooltip label={t('common:core.chat.response.Read complete response tips')}>
<MyTag
colorSchema="gray"
@@ -229,18 +242,19 @@ const ResponseTags = ({
{t('common:core.chat.response.Read complete response')}
</MyTag>
</MyTooltip>
</Flex>
)}
)}
</Flex>
{!!quoteModalData && (
<QuoteModal
{...quoteModalData}
showDetail={showDetail}
showDetail={showCompleteQuote}
onClose={() => setQuoteModalData(undefined)}
/>
)}
{isOpenContextModal && <ContextModal dataId={dataId} onClose={onCloseContextModal} />}
{isOpenWholeModal && (
<WholeResponseModal dataId={dataId} showDetail={showDetail} onClose={onCloseWholeModal} />
<WholeResponseModal dataId={dataId} showDetail={true} onClose={onCloseWholeModal} />
)}
</>
);

View File

@@ -9,6 +9,8 @@ import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import dynamic from 'next/dynamic';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { SearchScoreTypeEnum, SearchScoreTypeMap } from '@fastgpt/global/core/dataset/constants';
import { useContextSelector } from 'use-context-selector';
import { ChatBoxContext } from '../chat/ChatContainer/ChatBox/Provider';
const InputDataModal = dynamic(() => import('@/pages/dataset/detail/components/InputDataModal'));
@@ -54,6 +56,12 @@ const QuoteItem = ({
const { t } = useTranslation();
const [editInputData, setEditInputData] = useState<{ dataId: string; collectionId: string }>();
const { chatType } = useContextSelector(ChatBoxContext, (v) => v);
const canEdit = useMemo(() => {
return chatType !== 'share' && chatType !== 'team';
}, [chatType]);
const score = useMemo(() => {
if (!Array.isArray(quoteItem.score)) {
return {
@@ -224,7 +232,7 @@ const QuoteItem = ({
canView={canViewSource}
/>
<Box flex={1} />
{quoteItem.id && (
{quoteItem.id && canEdit && (
<MyTooltip label={t('common:core.dataset.data.Edit')}>
<Box
className="hover-data"
@@ -252,7 +260,7 @@ const QuoteItem = ({
</Box>
</MyTooltip>
)}
{linkToDataset && (
{linkToDataset && canEdit && (
<Link
as={NextLink}
className="hover-data"

View File

@@ -6,6 +6,8 @@ import { getCollectionSourceAndOpen } from '@/web/core/dataset/hooks/readCollect
import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useI18n } from '@/web/context/I18n';
import { ChatBoxContext } from '../chat/ChatContainer/ChatBox/Provider';
import { useContextSelector } from 'use-context-selector';
type Props = BoxProps & {
sourceName?: string;
@@ -23,11 +25,19 @@ const RawSourceBox = ({
}: Props) => {
const { t } = useTranslation();
const { fileT } = useI18n();
const { shareId, outLinkUid, chatType } = useContextSelector(ChatBoxContext, (v) => v);
const canPreview = !!sourceId && canView;
const icon = useMemo(() => getSourceNameIcon({ sourceId, sourceName }), [sourceId, sourceName]);
const read = getCollectionSourceAndOpen(collectionId);
const read = getCollectionSourceAndOpen({
collectionId,
authProps: {
shareId,
outLinkUid
},
isShare: chatType === 'share'
});
return (
<MyTooltip

View File

@@ -5,12 +5,15 @@ import { DatasetCollectionTypeEnum } from '@fastgpt/global/core/dataset/constant
import { createFileToken } from '@fastgpt/service/support/permission/controller';
import { BucketNameEnum, ReadFileBaseUrl } from '@fastgpt/global/common/file/constants';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { AuthOutLinkProps } from '@fastgpt/global/support/outLink/api';
import { authOutLink } from '@/service/support/permission/auth/outLink';
export type readCollectionSourceQuery = {
export type readCollectionSourceQuery = {};
export type readCollectionSourceBody = {
collectionId: string;
};
export type readCollectionSourceBody = {};
isShare?: boolean;
} & AuthOutLinkProps;
export type readCollectionSourceResponse = {
type: 'url';
@@ -20,11 +23,17 @@ export type readCollectionSourceResponse = {
async function handler(
req: ApiRequestProps<readCollectionSourceBody, readCollectionSourceQuery>
): Promise<readCollectionSourceResponse> {
const { isShare, outLinkUid, shareId } = req.body;
if (isShare) {
await authOutLink({ shareId, outLinkUid });
}
const { collection, teamId, tmbId } = await authDatasetCollection({
req,
authToken: true,
authApiKey: true,
collectionId: req.query.collectionId,
collectionId: req.body.collectionId,
per: ReadPermissionVal
});

View File

@@ -24,7 +24,7 @@ export type OutLinkUpdateResponse = {};
async function handler(
req: ApiRequestProps<OutLinkUpdateBody, OutLinkUpdateQuery>
): Promise<OutLinkUpdateResponse> {
const { _id, name, responseDetail, limit, app } = req.body;
const { _id, name, responseDetail, limit, app, showCompleteQuote, showNodeStatus } = req.body;
if (!_id) {
return Promise.reject(CommonErrEnum.missingParams);
@@ -35,6 +35,8 @@ async function handler(
await MongoOutLink.findByIdAndUpdate(_id, {
name,
responseDetail,
showCompleteQuote,
showNodeStatus,
limit,
app
});

View File

@@ -83,6 +83,8 @@ type AuthResponseType = {
user: UserModelSchema;
app: AppSchema;
responseDetail?: boolean;
showNodeStatus?: boolean;
showCompleteQuote?: boolean;
authType: `${AuthUserTypeEnum}`;
apikey?: string;
canWrite: boolean;
@@ -160,7 +162,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
sourceName,
apikey,
canWrite,
outLinkUserId = customUid
outLinkUserId = customUid,
showNodeStatus
} = await (async () => {
// share chat
if (shareId && outLinkUid) {
@@ -256,7 +259,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
res,
detail,
streamResponse: stream,
id: chatId
id: chatId,
showNodeStatus
});
/* start flow controller */
@@ -461,7 +465,7 @@ const authShareChat = async ({
shareId: string;
chatId?: string;
}): Promise<AuthResponseType> => {
const { teamId, tmbId, user, appId, authType, responseDetail, uid, sourceName } =
const { teamId, tmbId, user, appId, authType, responseDetail, showNodeStatus, uid, sourceName } =
await authOutLinkChatStart(data);
const app = await MongoApp.findById(appId).lean();
@@ -485,7 +489,8 @@ const authShareChat = async ({
apikey: '',
authType,
canWrite: false,
outLinkUserId: uid
outLinkUserId: uid,
showNodeStatus
};
};
const authTeamSpaceChat = async ({

View File

@@ -1,4 +1,4 @@
import React, { useMemo, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import {
Flex,
Box,
@@ -184,6 +184,8 @@ const Share = ({ appId }: { appId: string; type: PublishChannelEnum }) => {
_id: item._id,
name: item.name,
responseDetail: item.responseDetail,
showCompleteQuote: item.showCompleteQuote,
showNodeStatus: item.showNodeStatus,
limit: item.limit
})
},
@@ -272,11 +274,27 @@ function EditLinkModal({
const {
register,
setValue,
watch,
handleSubmit: submitShareChat
} = useForm({
defaultValues: defaultData
});
const responseDetail = watch('responseDetail');
const showCompleteQuote = watch('showCompleteQuote');
useEffect(() => {
if (!responseDetail) {
setValue('showCompleteQuote', false);
}
}, [responseDetail, setValue]);
useEffect(() => {
if (showCompleteQuote) {
setValue('responseDetail', true);
}
}, [showCompleteQuote, setValue]);
const isEdit = useMemo(() => !!defaultData._id, [defaultData]);
const { mutate: onclickCreate, isLoading: creating } = useRequest({
@@ -302,100 +320,130 @@ function EditLinkModal({
isOpen={true}
iconSrc="/imgs/modal/shareFill.svg"
title={isEdit ? publishT('edit_link') : publishT('create_link')}
w={'53.125rem'}
>
<ModalBody>
<Flex alignItems={'center'}>
<FormLabel flex={'0 0 90px'}>{t('common:Name')}</FormLabel>
<Input
placeholder={publishT('link_name')}
maxLength={20}
{...register('name', {
required: t('common:common.name_is_empty') || 'name_is_empty'
})}
/>
</Flex>
{feConfigs?.isPlus && (
<>
<ModalBody p={6}>
<Flex flexDir={['column', 'row']}>
<Box pr={[0, 6]} borderRight={['0px', '1px']} borderColor={['', 'myGray.150']}>
<Box fontSize={'sm'} fontWeight={'500'} color={'myGray.600'}>
{t('publish:basic_info')}
</Box>
<Flex alignItems={'center'} mt={4}>
<FormLabel flex={'0 0 90px'} alignItems={'center'}>
{t('common:common.Expired Time')}
</FormLabel>
<FormLabel flex={'0 0 90px'}>{t('common:Name')}</FormLabel>
<Input
type="datetime-local"
defaultValue={
defaultData.limit?.expiredTime
? dayjs(defaultData.limit?.expiredTime).format('YYYY-MM-DDTHH:mm')
: ''
}
onChange={(e) => {
setValue('limit.expiredTime', new Date(e.target.value));
}}
/>
</Flex>
<Flex alignItems={'center'} mt={4}>
<Flex flex={'0 0 90px'} alignItems={'center'}>
<FormLabel>QPM</FormLabel>
<QuestionTip ml={1} label={publishT('qpm_tips' || '')}></QuestionTip>
</Flex>
<Input
max={1000}
{...register('limit.QPM', {
min: 0,
max: 1000,
valueAsNumber: true,
required: publishT('qpm_is_empty') || ''
placeholder={publishT('link_name')}
maxLength={20}
{...register('name', {
required: t('common:common.name_is_empty') || 'name_is_empty'
})}
/>
</Flex>
<Flex alignItems={'center'} mt={4}>
<Flex flex={'0 0 90px'} alignItems={'center'}>
<FormLabel>{t('common:support.outlink.Max usage points')}</FormLabel>
{feConfigs?.isPlus && (
<>
<Flex alignItems={'center'} mt={4}>
<FormLabel flex={'0 0 90px'} alignItems={'center'}>
{t('common:common.Expired Time')}
</FormLabel>
<Input
type="datetime-local"
defaultValue={
defaultData.limit?.expiredTime
? dayjs(defaultData.limit?.expiredTime).format('YYYY-MM-DDTHH:mm')
: ''
}
onChange={(e) => {
setValue('limit.expiredTime', new Date(e.target.value));
}}
/>
</Flex>
<Flex alignItems={'center'} mt={4}>
<Flex flex={'0 0 90px'} alignItems={'center'}>
<FormLabel>QPM</FormLabel>
<QuestionTip ml={1} label={publishT('qpm_tips' || '')}></QuestionTip>
</Flex>
<Input
max={1000}
{...register('limit.QPM', {
min: 0,
max: 1000,
valueAsNumber: true,
required: publishT('qpm_is_empty') || ''
})}
/>
</Flex>
<Flex alignItems={'center'} mt={4}>
<Flex flex={'0 0 90px'} alignItems={'center'}>
<FormLabel>{t('common:support.outlink.Max usage points')}</FormLabel>
<QuestionTip
ml={1}
label={t('common:support.outlink.Max usage points tip')}
></QuestionTip>
</Flex>
<Input
{...register('limit.maxUsagePoints', {
min: -1,
max: 10000000,
valueAsNumber: true,
required: true
})}
/>
</Flex>
<Flex alignItems={'center'} mt={4}>
<Flex flex={'0 0 90px'} alignItems={'center'}>
<FormLabel>{publishT('token_auth')}</FormLabel>
<QuestionTip ml={1} label={publishT('token_auth_tips') || ''}></QuestionTip>
</Flex>
<Input
placeholder={publishT('token_auth_tips') || ''}
fontSize={'sm'}
{...register('limit.hookUrl')}
/>
</Flex>
<Link
href={getDocPath('/docs/development/openapi/share')}
target={'_blank'}
fontSize={'xs'}
color={'myGray.500'}
>
{publishT('token_auth_use_cases')}
</Link>
</>
)}
</Box>
<Box pl={[0, 6]} flexGrow={1} pt={[6, 0]}>
<Box fontSize={'sm'} fontWeight={'500'} color={'myGray.600'}>
{t('publish:config')}
</Box>
<Flex alignItems={'center'} mt={4} justify={'space-between'}>
<Flex alignItems={'center'}>
<FormLabel>{t('publish:show_node')}</FormLabel>
</Flex>
<Switch {...register('showNodeStatus')} />
</Flex>
<Flex alignItems={'center'} mt={4} justify={'space-between'}>
<Flex alignItems={'center'}>
<FormLabel>{t('common:support.outlink.share.Response Quote')}</FormLabel>
<QuestionTip
ml={1}
label={t('common:support.outlink.Max usage points tip')}
label={t('common:support.outlink.share.Response Quote tips' || '')}
></QuestionTip>
</Flex>
<Input
{...register('limit.maxUsagePoints', {
min: -1,
max: 10000000,
valueAsNumber: true,
required: true
})}
/>
<Switch {...register('responseDetail')} isChecked={responseDetail} />
</Flex>
<Flex alignItems={'center'} mt={4}>
<Flex flex={'0 0 90px'} alignItems={'center'}>
<FormLabel>{publishT('token_auth')}</FormLabel>
<QuestionTip ml={1} label={publishT('token_auth_tips') || ''}></QuestionTip>
<Flex alignItems={'center'} mt={4} justify={'space-between'}>
<Flex alignItems={'center'}>
<FormLabel>{t('common:support.outlink.share.show_complete_quote')}</FormLabel>
<QuestionTip
ml={1}
label={t('common:support.outlink.share.show_complete_quote_tips' || '')}
></QuestionTip>
</Flex>
<Input
placeholder={publishT('token_auth_tips') || ''}
fontSize={'sm'}
{...register('limit.hookUrl')}
/>
<Switch {...register('showCompleteQuote')} isChecked={showCompleteQuote} />
</Flex>
<Link
href={getDocPath('/docs/development/openapi/share')}
target={'_blank'}
fontSize={'xs'}
color={'myGray.500'}
>
{publishT('token_auth_use_cases')}
</Link>
</>
)}
<Flex alignItems={'center'} mt={4}>
<Flex flex={'0 0 90px'} alignItems={'center'}>
<FormLabel>{t('common:support.outlink.share.Response Quote')}</FormLabel>
<QuestionTip
ml={1}
label={t('support.outlink.share.Response Quote tips' || '')}
></QuestionTip>
</Flex>
<Switch {...register('responseDetail')} />
</Box>
</Flex>
</ModalBody>

View File

@@ -42,6 +42,7 @@ type Props = {
shareId: string;
authToken: string;
customUid: string;
showCompleteQuote: boolean;
};
const OutLink = (
@@ -364,6 +365,7 @@ const OutLink = (
chatId={chatId}
shareId={shareId}
outLinkUid={outLinkUid}
chatType="share"
/>
)}
</Box>
@@ -375,13 +377,13 @@ const OutLink = (
};
const Render = (props: Props) => {
const { shareId, authToken, customUid } = props;
const { shareId, authToken, customUid, showCompleteQuote } = props;
const { localUId, loaded } = useShareChatStore();
const [isLoaded, setIsLoaded] = useState(false);
const contextParams = useMemo(() => {
return { shareId, outLinkUid: authToken || customUid || localUId };
}, [authToken, customUid, localUId, shareId]);
return { shareId, outLinkUid: authToken || localUId || customUid, showCompleteQuote };
}, [authToken, customUid, localUId, shareId, showCompleteQuote]);
useMount(() => {
setIsLoaded(true);
@@ -415,7 +417,7 @@ export async function getServerSideProps(context: any) {
{
shareId
},
'appId'
'appId showCompleteQuote'
)
.populate('appId', 'name avatar intro')
.lean()) as OutLinkWithAppType;
@@ -431,6 +433,7 @@ export async function getServerSideProps(context: any) {
appName: app?.appId?.name ?? 'AI',
appAvatar: app?.appId?.avatar ?? '',
appIntro: app?.appId?.intro ?? 'AI',
showCompleteQuote: app?.showCompleteQuote ?? false,
shareId: shareId ?? '',
authToken: authToken ?? '',
customUid,

View File

@@ -296,6 +296,7 @@ const Chat = ({ myApps }: { myApps: AppListItemType[] }) => {
chatId={chatId}
teamId={teamId}
teamToken={teamToken}
chatType="team"
/>
)}
</Box>

View File

@@ -10,6 +10,8 @@ import { formatTime2YMDHM } from '@fastgpt/global/common/string/time';
import { DatasetCollectionTypeMap, TrainingTypeMap } from '@fastgpt/global/core/dataset/constants';
import { getCollectionSourceAndOpen } from '@/web/core/dataset/hooks/readCollectionSource';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useContextSelector } from 'use-context-selector';
import { ChatBoxContext } from '@/components/core/chat/ChatContainer/ChatBox/Provider';
const MetaDataCard = ({ datasetId }: { datasetId: string }) => {
const { t } = useTranslation();
@@ -18,7 +20,17 @@ const MetaDataCard = ({ datasetId }: { datasetId: string }) => {
collectionId: string;
datasetId: string;
};
const readSource = getCollectionSourceAndOpen(collectionId);
const { shareId, outLinkUid, chatType } = useContextSelector(ChatBoxContext, (v) => v);
const readSource = getCollectionSourceAndOpen({
collectionId,
authProps: {
shareId,
outLinkUid
},
isShare: chatType === 'share'
});
const { data: collection, loading: isLoading } = useRequest2(
() => getDatasetCollectionById(collectionId),
{

View File

@@ -3,7 +3,8 @@ import type {
AuthOutLinkChatProps,
AuthOutLinkLimitProps,
AuthOutLinkInitProps,
AuthOutLinkResponse
AuthOutLinkResponse,
AuthOutLinkProps
} from '@fastgpt/global/support/outLink/api.d';
import { authOutLinkValid } from '@fastgpt/service/support/permission/publish/authLink';
import { getUserChatInfoAndAuthTeamPoints } from '@/service/support/permission/auth/team';
@@ -23,10 +24,7 @@ export function authOutLinkChatLimit(data: AuthOutLinkLimitProps): Promise<AuthO
export const authOutLink = async ({
shareId,
outLinkUid
}: {
shareId?: string;
outLinkUid?: string;
}): Promise<{
}: AuthOutLinkProps): Promise<{
uid: string;
appId: string;
shareChat: OutLinkSchema;
@@ -70,6 +68,7 @@ export async function authOutLinkChatStart({
tmbId: shareChat.tmbId,
authType: AuthUserTypeEnum.token,
responseDetail: shareChat.responseDetail,
showNodeStatus: shareChat.showNodeStatus,
user,
appId,
uid

View File

@@ -23,6 +23,8 @@ export const defaultApp: AppDetailType = {
export const defaultOutLinkForm: OutLinkEditType = {
name: '',
responseDetail: false,
showNodeStatus: false,
showCompleteQuote: false,
limit: {
QPM: 100,
maxUsagePoints: -1

View File

@@ -16,7 +16,7 @@ import { getNanoid } from '@fastgpt/global/common/string/tools';
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
type ChatContextValueType = {
params: Record<string, string | number>;
params: Record<string, string | number | boolean>;
};
type ChatContextType = {
chatId: string;
@@ -44,6 +44,7 @@ type ChatContextType = {
isLoading: boolean;
histories: ChatHistoryItemType[];
onUpdateHistoryTitle: ({ chatId, newTitle }: { chatId: string; newTitle: string }) => void;
showCompleteQuote: boolean;
};
export const ChatContext = createContext<ChatContextType>({
@@ -85,7 +86,8 @@ export const ChatContext = createContext<ChatContextType>({
onChangeAppId: function (appId: string): void {
throw new Error('Function not implemented.');
},
isLoading: false
isLoading: false,
showCompleteQuote: true
});
const ChatContextProvider = ({
@@ -94,6 +96,7 @@ const ChatContextProvider = ({
}: ChatContextValueType & { children: ReactNode }) => {
const router = useRouter();
const { chatId = '' } = router.query as { chatId: string };
const { showCompleteQuote }: { showCompleteQuote?: boolean } = params;
const forbidLoadChat = useRef(false);
@@ -225,7 +228,8 @@ const ChatContextProvider = ({
ScrollData,
loadHistories,
histories,
onUpdateHistoryTitle
onUpdateHistoryTitle,
showCompleteQuote: showCompleteQuote ?? true
};
return <ChatContext.Provider value={contextValue}>{children}</ChatContext.Provider>;
};

View File

@@ -56,6 +56,7 @@ import type { UpdateDatasetDataProps } from '@fastgpt/global/core/dataset/contro
import type { DatasetFolderCreateBody } from '@/pages/api/core/dataset/folder/create';
import type { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
import type { GetScrollCollectionsProps } from '@/pages/api/core/dataset/collection/scrollList';
import { AuthOutLinkProps } from '@fastgpt/global/support/outLink/api';
/* ======================== dataset ======================= */
export const getDatasets = (data: GetDatasetListBody) =>
@@ -197,5 +198,6 @@ export const getPreviewChunks = (data: PostPreviewFilesChunksProps) =>
POST<PreviewChunksResponse>('/core/dataset/file/getPreviewChunks', data);
/* ================== read source ======================== */
export const getCollectionSource = (collectionId: string) =>
GET<readCollectionSourceResponse>('/core/dataset/collection/read', { collectionId });
export const getCollectionSource = (
data: { collectionId: string; isShare?: boolean } & AuthOutLinkProps
) => POST<readCollectionSourceResponse>('/core/dataset/collection/read', data);

View File

@@ -1,10 +1,20 @@
import { authOutLink } from '@/service/support/permission/auth/outLink';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { getCollectionSource } from '@/web/core/dataset/api';
import { getErrText } from '@fastgpt/global/common/error/utils';
import { AuthOutLinkProps } from '@fastgpt/global/support/outLink/api';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useTranslation } from 'next-i18next';
export function getCollectionSourceAndOpen(collectionId: string) {
export function getCollectionSourceAndOpen({
collectionId,
authProps,
isShare
}: {
collectionId: string;
authProps: AuthOutLinkProps;
isShare?: boolean;
}) {
const { toast } = useToast();
const { t } = useTranslation();
const { setLoading } = useSystemStore();
@@ -12,7 +22,8 @@ export function getCollectionSourceAndOpen(collectionId: string) {
return async () => {
try {
setLoading(true);
const { value: url } = await getCollectionSource(collectionId);
const { value: url } = await getCollectionSource({ collectionId, isShare, ...authProps });
if (!url) {
throw new Error('No file found');