feat: add more share config (#3120)
* feat: add more share config * add i18n en
This commit is contained in:
parent
f4e0dfc9bd
commit
5892ded567
@ -82,7 +82,7 @@ export const filterPublicNodeResponseData = ({
|
||||
}: {
|
||||
flowResponses?: ChatHistoryItemResType[];
|
||||
}) => {
|
||||
const filedList = ['quoteList', 'moduleType', 'pluginOutput'];
|
||||
const filedList = ['quoteList', 'moduleType', 'pluginOutput', 'runningTime'];
|
||||
const filterModuleTypeList: any[] = [
|
||||
FlowNodeTypeEnum.pluginModule,
|
||||
FlowNodeTypeEnum.datasetSearchNode,
|
||||
|
||||
4
packages/global/support/outLink/api.d.ts
vendored
4
packages/global/support/outLink/api.d.ts
vendored
@ -10,3 +10,7 @@ export type AuthOutLinkLimitProps = AuthOutLinkChatProps & { outLink: OutLinkSch
|
||||
export type AuthOutLinkResponse = {
|
||||
uid: string;
|
||||
};
|
||||
export type AuthOutLinkProps = {
|
||||
shareId?: string;
|
||||
outLinkUid?: string;
|
||||
};
|
||||
|
||||
6
packages/global/support/outLink/type.d.ts
vendored
6
packages/global/support/outLink/type.d.ts
vendored
@ -51,6 +51,10 @@ export type OutLinkSchema<T extends OutlinkAppType = undefined> = {
|
||||
|
||||
// whether the response content is detailed
|
||||
responseDetail: boolean;
|
||||
// whether to hide the node status
|
||||
showNodeStatus: boolean;
|
||||
// whether to show the complete quote
|
||||
showCompleteQuote: boolean;
|
||||
|
||||
// response when request
|
||||
immediateResponse?: string;
|
||||
@ -79,6 +83,8 @@ export type OutLinkEditType<T = undefined> = {
|
||||
_id?: string;
|
||||
name: string;
|
||||
responseDetail?: OutLinkSchema<T>['responseDetail'];
|
||||
showNodeStatus?: OutLinkSchema<T>['showNodeStatus'];
|
||||
showCompleteQuote?: OutLinkSchema<T>['showCompleteQuote'];
|
||||
// response when request
|
||||
immediateResponse?: string;
|
||||
// response when error or other situation
|
||||
|
||||
@ -18,12 +18,14 @@ export const getWorkflowResponseWrite = ({
|
||||
res,
|
||||
detail,
|
||||
streamResponse,
|
||||
id = getNanoid(24)
|
||||
id = getNanoid(24),
|
||||
showNodeStatus = true
|
||||
}: {
|
||||
res?: NextApiResponse;
|
||||
detail: boolean;
|
||||
streamResponse: boolean;
|
||||
id?: string;
|
||||
showNodeStatus?: boolean;
|
||||
}) => {
|
||||
return ({
|
||||
write,
|
||||
@ -50,8 +52,18 @@ export const getWorkflowResponseWrite = ({
|
||||
SseResponseEventEnum.toolResponse,
|
||||
SseResponseEventEnum.updateVariables
|
||||
];
|
||||
|
||||
if (!detail && detailEvent.includes(event)) return;
|
||||
|
||||
if (
|
||||
!showNodeStatus &&
|
||||
(event === SseResponseEventEnum.flowNodeStatus ||
|
||||
event === SseResponseEventEnum.toolCall ||
|
||||
event === SseResponseEventEnum.toolParams ||
|
||||
event === SseResponseEventEnum.toolResponse)
|
||||
)
|
||||
return;
|
||||
|
||||
responseWrite({
|
||||
res,
|
||||
write,
|
||||
|
||||
@ -46,6 +46,14 @@ const OutLinkSchema = new Schema({
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showNodeStatus: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showCompleteQuote: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
limit: {
|
||||
maxUsagePoints: {
|
||||
type: Number,
|
||||
|
||||
@ -74,6 +74,7 @@
|
||||
"module.type": "\"{{type}}\" type\n{{description}}",
|
||||
"modules.Title is required": "Module name cannot be empty",
|
||||
"month.unit": "Day",
|
||||
"move.hint": "After moving, the selected application/folder will inherit the permission settings of the new folder, and the original permission settings will become invalid.",
|
||||
"move_app": "Move Application",
|
||||
"not_json_file": "Please select a JSON file",
|
||||
"open_vision_function_tip": "Models with icon switches have image recognition capabilities. \nAfter being turned on, the model will parse the pictures in the file link and automatically parse the pictures in the user's question (user question ≤ 500 words).",
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
"not_select_file": "No file selected",
|
||||
"plugins_output": "Plugin Output",
|
||||
"question_tip": "From top to bottom, the response order of each module",
|
||||
"response.child total points": "Sub-workflow point consumption",
|
||||
"response.dataset_concat_length": "Combined total",
|
||||
"response.node_inputs": "Node Inputs",
|
||||
"select": "Select",
|
||||
|
||||
@ -53,6 +53,7 @@
|
||||
"code_error.error_code.502": "Gateway Error",
|
||||
"code_error.error_code.503": "Server Overloaded or Under Maintenance",
|
||||
"code_error.error_code.504": "Gateway Timeout",
|
||||
"code_error.error_code[429]": "Requests are too frequent",
|
||||
"code_error.error_message.403": "Credential Error",
|
||||
"code_error.error_message.510": "Insufficient Account Balance",
|
||||
"code_error.error_message.511": "Unauthorized to Operate This Model",
|
||||
@ -79,6 +80,7 @@
|
||||
"code_error.team_error.plugin_amount_not_enough": "Plugin Limit Reached",
|
||||
"code_error.team_error.re_rank_not_enough": "Unauthorized to Use Re-Rank",
|
||||
"code_error.team_error.un_auth": "Unauthorized to Operate This Team",
|
||||
"code_error.team_error.user_not_active": "The user did not accept or has left the team",
|
||||
"code_error.team_error.website_sync_not_enough": "Unauthorized to Use Website Sync",
|
||||
"code_error.token_error_code.403": "Invalid Login Status, Please Re-login",
|
||||
"code_error.user_error.balance_not_enough": "Insufficient Account Balance",
|
||||
@ -120,6 +122,7 @@
|
||||
"common.Documents": "Documents",
|
||||
"common.Done": "Done",
|
||||
"common.Edit": "Edit",
|
||||
"common.Error": "Error",
|
||||
"common.Exit": "Exit",
|
||||
"common.Exit Directly": "Exit Directly",
|
||||
"common.Expired Time": "Expiration Time",
|
||||
@ -151,6 +154,7 @@
|
||||
"common.Params": "Parameters",
|
||||
"common.Password inconsistency": "Passwords Do Not Match",
|
||||
"common.Permission": "Permission",
|
||||
"common.Permission_tip": "Individual permissions are greater than group permissions",
|
||||
"common.Please Input Name": "Please Enter a Name",
|
||||
"common.Read document": "Read Document",
|
||||
"common.Read intro": "Read Introduction",
|
||||
@ -188,7 +192,6 @@
|
||||
"common.Update Successful": "Updated Successfully",
|
||||
"common.Username": "Username",
|
||||
"common.Waiting": "Waiting",
|
||||
"common.Error": "Error",
|
||||
"common.Warning": "Warning",
|
||||
"common.Website": "Website",
|
||||
"common.all_result": "Full Results",
|
||||
@ -546,6 +549,7 @@
|
||||
"core.dataset.import.Chunk Range": "Range: {{min}}~{{max}}",
|
||||
"core.dataset.import.Chunk Split": "Direct Segmentation",
|
||||
"core.dataset.import.Chunk Split Tip": "Segment the text according to certain rules and convert it into a format that can be semantically searched. Suitable for most scenarios. No additional model processing is required, and the cost is low.",
|
||||
"core.dataset.import.Continue upload": "Continue upload",
|
||||
"core.dataset.import.Custom process": "Custom Rules",
|
||||
"core.dataset.import.Custom process desc": "Customize segmentation and preprocessing rules",
|
||||
"core.dataset.import.Custom prompt": "Custom Prompt",
|
||||
@ -574,11 +578,10 @@
|
||||
"core.dataset.import.Select source": "Select Source",
|
||||
"core.dataset.import.Source name": "Source Name",
|
||||
"core.dataset.import.Sources list": "Source List",
|
||||
"core.dataset.import.Continue upload": "Continue upload",
|
||||
"core.dataset.import.Upload complete": "Upload complete",
|
||||
"core.dataset.import.Start upload": "Start Upload",
|
||||
"core.dataset.import.Total files": "Total {{total}} Files",
|
||||
"core.dataset.import.Training mode": "Training Mode",
|
||||
"core.dataset.import.Upload complete": "Upload complete",
|
||||
"core.dataset.import.Upload data": "Confirm Upload",
|
||||
"core.dataset.import.Upload file progress": "File Upload Progress",
|
||||
"core.dataset.import.Upload status": "Status",
|
||||
@ -889,7 +892,9 @@
|
||||
"is_using": "In Use",
|
||||
"item_description": "Field Description",
|
||||
"item_name": "Field Name",
|
||||
"just_now": "just",
|
||||
"key_repetition": "Key Repetition",
|
||||
"move.confirm": "Confirm move",
|
||||
"navbar.Account": "Account",
|
||||
"navbar.Chat": "Chat",
|
||||
"navbar.Datasets": "Datasets",
|
||||
@ -970,6 +975,9 @@
|
||||
"support.outlink.Usage points": "Points Consumption",
|
||||
"support.outlink.share.Response Quote": "Return Quote",
|
||||
"support.outlink.share.Response Quote tips": "Return quoted content in the share link, but do not allow users to download the original document",
|
||||
"support.outlink.share.running_node": "Running node",
|
||||
"support.outlink.share.show_complete_quote": "View original source",
|
||||
"support.outlink.share.show_complete_quote_tips": "View and download the complete citation document, or jump to the citation website",
|
||||
"support.permission.Permission": "Permission",
|
||||
"support.standard.AI Bonus Points": "AI Points",
|
||||
"support.standard.due_date": "Due Date",
|
||||
@ -1200,6 +1208,8 @@
|
||||
"user.team.member.waiting": "Pending Acceptance",
|
||||
"user.team.role.Admin": "Admin",
|
||||
"user.team.role.Owner": "Owner",
|
||||
"user.team.role.Visitor": "visitor",
|
||||
"user.team.role.writer": "writable member",
|
||||
"user.type": "Type",
|
||||
"verification": "Verification",
|
||||
"xx_search_result": "{{key}} Search Results",
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
"confirm_to_rebuild_embedding_tip": "Are you sure you want to switch the index for the Dataset?\nSwitching the index is a significant operation that requires re-indexing all data in your Dataset, which may take a long time. Please ensure your account has sufficient remaining points.\n\nAdditionally, you need to update the applications that use this Dataset to avoid conflicts with other indexed model Datasets.",
|
||||
"custom_data_process_params": "Custom",
|
||||
"custom_data_process_params_desc": "Customize data processing rules",
|
||||
"data.ideal_chunk_length": "ideal block length",
|
||||
"data_process_params": "Processing parameters",
|
||||
"data_process_setting": "Data processing configuration",
|
||||
"dataset.no_collections": "No datasets available",
|
||||
@ -25,6 +26,7 @@
|
||||
"ideal_chunk_length_tips": "Segment according to the end symbol and combine multiple segments into one block. This value determines the estimated size of the block, if there is any fluctuation.",
|
||||
"import.Auto mode Estimated Price Tips": "The text understanding model needs to be called, which requires more points: {{price}} points/1K tokens",
|
||||
"import.Embedding Estimated Price Tips": "Only use the index model and consume a small amount of AI points: {{price}} points/1K tokens",
|
||||
"move.hint": "After moving, the selected knowledge base/folder will inherit the permission settings of the new folder, and the original permission settings will become invalid.",
|
||||
"permission.des.manage": "Can manage the entire knowledge base data and information",
|
||||
"permission.des.read": "View knowledge base content",
|
||||
"permission.des.write": "Ability to add and change knowledge base content",
|
||||
@ -44,4 +46,4 @@
|
||||
"training_mode": "Chunk mode",
|
||||
"website_dataset": "Website Sync",
|
||||
"website_dataset_desc": "Website sync allows you to build a Dataset directly using a web link."
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"app_key_tips": "These keys are already linked to the current application. Check the documentation for detailed usage.",
|
||||
"basic_info": "Basic Info",
|
||||
"config": "Visibility configuration",
|
||||
"copy_link_hint": "Copy the link below to the specified location",
|
||||
"create_api_key": "Create New Key",
|
||||
"create_link": "Create Link",
|
||||
@ -22,7 +23,10 @@
|
||||
"publish_name": "Name",
|
||||
"qpm_is_empty": "QPM cannot be empty",
|
||||
"qpm_tips": "Maximum number of queries per minute per IP",
|
||||
"quote_content": "Quote content",
|
||||
"request_address": "Request URL",
|
||||
"show_node": "real-time running status",
|
||||
"show_origin_content": "View original source",
|
||||
"show_share_link_modal_title": "Get Started",
|
||||
"token_auth": "Token Authentication",
|
||||
"token_auth_tips": "Token authentication server URL. If provided, a request will be sent to the specified server for authentication before each conversation.",
|
||||
@ -33,4 +37,4 @@
|
||||
"wecom.create_modal_title": "Create WeCom Bot",
|
||||
"wecom.edit_modal_title": "Edit WeCom Bot",
|
||||
"wecom.title": "Publish to WeCom Bot"
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
"bind_inform_account_success": "Notification Account Bound Successfully",
|
||||
"delete.admin_failed": "Failed to Delete Admin",
|
||||
"delete.admin_success": "Admin Deleted Successfully",
|
||||
"delete.failed": "Delete failed",
|
||||
"delete.success": "Delete successfully",
|
||||
"has_chosen": "Selected",
|
||||
"individuation": "Individuation",
|
||||
"login.error": "Login Error",
|
||||
@ -32,6 +34,7 @@
|
||||
"notification.Bind Notification Pipe Hint": "Please bind a notification receiving account to ensure you receive notifications such as plan expiration reminders, ensuring your service runs smoothly.",
|
||||
"notification.remind_owner_bind": "Please remind the creator to bind a notification account",
|
||||
"operations": "Actions",
|
||||
"owner": "owner",
|
||||
"password.code_required": "Verification Code Required",
|
||||
"password.code_send_error": "Failed to Send Verification Code",
|
||||
"password.code_sended": "Verification Code Sent",
|
||||
@ -76,6 +79,32 @@
|
||||
"synchronization.title": "Enter the sync tag link and click the sync button to synchronize",
|
||||
"team.Add manager": "Add Admin",
|
||||
"team.add_collaborator": "Add Collaborator",
|
||||
"team.add_writer": "Add writable members",
|
||||
"team.avatar_and_name": "avatar",
|
||||
"team.belong_to_group": "Member group",
|
||||
"team.group.avatar": "Group avatar",
|
||||
"team.group.create": "Create group",
|
||||
"team.group.create_failed": "Failed to create group",
|
||||
"team.group.default_group": "Default group",
|
||||
"team.group.delete_confirm": "Confirm to delete group?",
|
||||
"team.group.edit": "Edit group",
|
||||
"team.group.edit_info": "Edit information",
|
||||
"team.group.group": "group",
|
||||
"team.group.keep_admin": "Keep administrator rights",
|
||||
"team.group.manage_member": "Managing members",
|
||||
"team.group.manage_tip": "You can invite members, delete members, create groups, manage all groups, and assign permissions to groups and members",
|
||||
"team.group.members": "member",
|
||||
"team.group.name": "Group name",
|
||||
"team.group.permission.manage": "administrator",
|
||||
"team.group.permission.write": "Workbench/knowledge base creation",
|
||||
"team.group.permission_tip": "Members with individually configured permissions will follow the individual permission configuration and will no longer be affected by group permissions.\n\nIf a member is in multiple permission groups, the member's permissions are combined.",
|
||||
"team.group.role.admin": "administrator",
|
||||
"team.group.role.member": "member",
|
||||
"team.group.role.owner": "owner",
|
||||
"team.group.search_placeholder": "Search member/group name",
|
||||
"team.group.set_as_admin": "Set as administrator",
|
||||
"team.group.toast.can_not_delete_owner": "Owner cannot be deleted, please transfer first",
|
||||
"team.group.transfer_owner": "transfer owner",
|
||||
"team.manage_collaborators": "Manage Collaborators",
|
||||
"team.no_collaborators": "No Collaborators",
|
||||
"team.write_role_member": "",
|
||||
@ -84,4 +113,4 @@
|
||||
"usage.share": "Share Link",
|
||||
"usage.wecom": "WeCom",
|
||||
"usage_record": "Usages"
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
"contains": "Contains",
|
||||
"content_to_retrieve": "Content to Retrieve",
|
||||
"content_to_search": "Content to Search",
|
||||
"contextMenu.addComment": "Add comment",
|
||||
"context_menu.add_comment": "Add comment",
|
||||
"create_link_error": "Error creating link",
|
||||
"custom_feedback": "Custom Feedback",
|
||||
@ -177,6 +178,7 @@
|
||||
"tool_params.params_description_placeholder": "Name/Age/SQL statement..",
|
||||
"tool_params.params_name": "Name",
|
||||
"tool_params.params_name_placeholder": "name/age/sql",
|
||||
"tool_params.tool_params_result": "Parameter configuration results",
|
||||
"trigger_after_application_completion": "Will be triggered after the application is fully completed",
|
||||
"update_link_error": "Error updating link",
|
||||
"update_specified_node_output_or_global_variable": "Can update the output value of a specified node or update global variables",
|
||||
|
||||
@ -974,8 +974,11 @@
|
||||
"support.outlink.Max usage points": "积分上限",
|
||||
"support.outlink.Max usage points tip": "该链接最多允许使用多少积分,超出后将无法使用。-1 代表无限制。",
|
||||
"support.outlink.Usage points": "积分消耗",
|
||||
"support.outlink.share.Response Quote": "返回引用",
|
||||
"support.outlink.share.Response Quote tips": "在分享链接中返回引用内容,但不会允许用户下载原文档",
|
||||
"support.outlink.share.Response Quote": "引用内容",
|
||||
"support.outlink.share.Response Quote tips": "查看知识库搜索的引用内容,不可查看完整引用文档或跳转引用网站",
|
||||
"support.outlink.share.running_node": "运行节点",
|
||||
"support.outlink.share.show_complete_quote": "查看来源原文",
|
||||
"support.outlink.share.show_complete_quote_tips": "查看及下载完整引用文档,或跳转引用网站",
|
||||
"support.permission.Permission": "权限",
|
||||
"support.standard.AI Bonus Points": "AI 积分",
|
||||
"support.standard.due_date": "到期时间",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"app_key_tips": "这些 key 已有当前应用标识,具体使用可参考文档",
|
||||
"basic_info": "基本信息",
|
||||
"config": "可见度配置",
|
||||
"copy_link_hint": "将下面链接复制到指定位置",
|
||||
"create_api_key": "创建新 key",
|
||||
"create_link": "创建链接",
|
||||
@ -25,12 +26,15 @@
|
||||
"request_address": "请求地址",
|
||||
"show_share_link_modal_title": "开始使用",
|
||||
"token_auth": "身份验证",
|
||||
"token_auth_tips": "身份校验服务器地址,如填写该值,每次对话前都会向指定服务器发送一个请求,进行身份校验",
|
||||
"token_auth_tips": "身份校验服务器地址",
|
||||
"token_auth_use_cases": "查看身份验证使用说明",
|
||||
"wecom.api": "企微 API",
|
||||
"wecom.bot": "企业微信机器人",
|
||||
"wecom.bot_desc": "通过 API 直接接入企业微信机器人",
|
||||
"wecom.create_modal_title": "创建企微机器人",
|
||||
"wecom.edit_modal_title": "编辑企微机器人",
|
||||
"wecom.title": "发布到企业微信机器人"
|
||||
}
|
||||
"wecom.title": "发布到企业微信机器人",
|
||||
"show_node": "实时运行状态",
|
||||
"quote_content": "引用内容",
|
||||
"show_origin_content": "查看来源原文"
|
||||
}
|
||||
|
||||
@ -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 &
|
||||
|
||||
@ -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} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
});
|
||||
|
||||
|
||||
@ -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
|
||||
});
|
||||
|
||||
@ -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 ({
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -296,6 +296,7 @@ const Chat = ({ myApps }: { myApps: AppListItemType[] }) => {
|
||||
chatId={chatId}
|
||||
teamId={teamId}
|
||||
teamToken={teamToken}
|
||||
chatType="team"
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@ -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),
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -23,6 +23,8 @@ export const defaultApp: AppDetailType = {
|
||||
export const defaultOutLinkForm: OutLinkEditType = {
|
||||
name: '',
|
||||
responseDetail: false,
|
||||
showNodeStatus: false,
|
||||
showCompleteQuote: false,
|
||||
limit: {
|
||||
QPM: 100,
|
||||
maxUsagePoints: -1
|
||||
|
||||
@ -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>;
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user