mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-27 08:25:07 +00:00
4.8.10 test (#2568)
* perf: i18n perf * fix: detail=fasle response * fix: dataset tag load repeat * feat :doc * perf: rename fun * code comment
This commit is contained in:
@@ -65,15 +65,18 @@ curl --location --request POST 'https://{{host}}/api/admin/initv4810' \
|
|||||||
16. 优化 - 节点选择,避免切换 tab 时候,path 加载报错。
|
16. 优化 - 节点选择,避免切换 tab 时候,path 加载报错。
|
||||||
17. 优化 - 最新 React Markdown 组件,支持 Base64 图片。
|
17. 优化 - 最新 React Markdown 组件,支持 Base64 图片。
|
||||||
18. 优化 - 知识库列表 UI。
|
18. 优化 - 知识库列表 UI。
|
||||||
19. 优化 - 支持无网络配置情况下运行。
|
19. 优化 - 知识库详情页 UI。
|
||||||
20. 优化 - 部分全局变量,增加数据类型约束。
|
20. 优化 - 支持无网络配置情况下运行。
|
||||||
21. 修复 - 全局变量 key 可能重复。
|
21. 优化 - 部分全局变量,增加数据类型约束。
|
||||||
22. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
|
22. 修复 - 全局变量 key 可能重复。
|
||||||
23. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
|
23. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
|
||||||
24. 修复 - 选择 Milvus 部署时,无法导出知识库。
|
24. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
|
||||||
25. 修复 - 创建 APP 副本,无法复制系统配置。
|
25. 修复 - 选择 Milvus 部署时,无法导出知识库。
|
||||||
26. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
|
26. 修复 - 创建 APP 副本,无法复制系统配置。
|
||||||
27. 修复 - 内容提取的数据类型与输出数据类型未一致。
|
27. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
|
||||||
28. 修复 - 工作流运行时间统计错误。
|
28. 修复 - 内容提取的数据类型与输出数据类型未一致。
|
||||||
29. 修复 - stream 模式下,工具调用有可能出现 undefined
|
29. 修复 - 工作流运行时间统计错误。
|
||||||
30. 修复 - 全局变量在 API 中无法持久化。
|
30. 修复 - stream 模式下,工具调用有可能出现 undefined
|
||||||
|
31. 修复 - 全局变量在 API 中无法持久化。
|
||||||
|
32. 修复 - OpenAPI,detail=false模式下,不应该返回 tool 调用结果,仅返回文字。(可解决 cow 不适配问题)
|
||||||
|
33. 修复 - 知识库标签重复加载。
|
||||||
|
@@ -333,7 +333,8 @@ export const removePluginInputVariables = (
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function replaceVariableLabel({
|
// replace {{$xx.xx$}} variables for text
|
||||||
|
export function replaceEditorVariable({
|
||||||
text,
|
text,
|
||||||
nodes,
|
nodes,
|
||||||
variables,
|
variables,
|
||||||
@@ -341,7 +342,7 @@ export function replaceVariableLabel({
|
|||||||
}: {
|
}: {
|
||||||
text: any;
|
text: any;
|
||||||
nodes: RuntimeNodeItemType[];
|
nodes: RuntimeNodeItemType[];
|
||||||
variables: Record<string, string | number>;
|
variables: Record<string, any>; // global variables
|
||||||
runningNode: RuntimeNodeItemType;
|
runningNode: RuntimeNodeItemType;
|
||||||
}) {
|
}) {
|
||||||
if (typeof text !== 'string') return text;
|
if (typeof text !== 'string') return text;
|
||||||
|
@@ -79,7 +79,7 @@ export const readRawContentByFileBuffer = async ({
|
|||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
addLog.info('Use custom read file service');
|
const start = Date.now();
|
||||||
|
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
data.append('file', buffer, {
|
data.append('file', buffer, {
|
||||||
@@ -101,6 +101,8 @@ export const readRawContentByFileBuffer = async ({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addLog.info(`Use custom read file service, time: ${Date.now() - start}ms`);
|
||||||
|
|
||||||
const rawText = response.data.markdown;
|
const rawText = response.data.markdown;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@@ -21,7 +21,7 @@ import {
|
|||||||
} from '@fastgpt/global/core/workflow/node/constant';
|
} from '@fastgpt/global/core/workflow/node/constant';
|
||||||
import { replaceVariable } from '@fastgpt/global/common/string/tools';
|
import { replaceVariable } from '@fastgpt/global/common/string/tools';
|
||||||
import { getSystemTime } from '@fastgpt/global/common/time/timezone';
|
import { getSystemTime } from '@fastgpt/global/common/time/timezone';
|
||||||
import { replaceVariableLabel } from '@fastgpt/global/core/workflow/utils';
|
import { replaceEditorVariable } from '@fastgpt/global/core/workflow/utils';
|
||||||
|
|
||||||
import { dispatchWorkflowStart } from './init/workflowStart';
|
import { dispatchWorkflowStart } from './init/workflowStart';
|
||||||
import { dispatchChatCompletion } from './chat/oneapi';
|
import { dispatchChatCompletion } from './chat/oneapi';
|
||||||
@@ -368,7 +368,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
let value = replaceVariable(input.value, variables);
|
let value = replaceVariable(input.value, variables);
|
||||||
|
|
||||||
// replace {{$xx.xx$}} variables
|
// replace {{$xx.xx$}} variables
|
||||||
value = replaceVariableLabel({
|
value = replaceEditorVariable({
|
||||||
text: value,
|
text: value,
|
||||||
nodes: runtimeNodes,
|
nodes: runtimeNodes,
|
||||||
variables,
|
variables,
|
||||||
|
@@ -73,25 +73,35 @@ export const dispatchReadFiles = async (props: Props): Promise<Response> => {
|
|||||||
// Concat fileUrlList and filesFromHistories; remove not supported files
|
// Concat fileUrlList and filesFromHistories; remove not supported files
|
||||||
const parseUrlList = [...fileUrlList, ...filesFromHistories]
|
const parseUrlList = [...fileUrlList, ...filesFromHistories]
|
||||||
.map((url) => {
|
.map((url) => {
|
||||||
// System file
|
try {
|
||||||
if (url.startsWith('/') || (requestOrigin && url.startsWith(requestOrigin))) {
|
// Avoid "/api/xxx" file error.
|
||||||
// Parse url, get filename query. Keep only documents that can be parsed
|
const origin = requestOrigin ?? 'http://localhost:3000';
|
||||||
const parseUrl = new URL(url);
|
|
||||||
const filenameQuery = parseUrl.searchParams.get('filename');
|
// Check is system upload file
|
||||||
if (filenameQuery) {
|
if (url.startsWith('/') || (requestOrigin && url.startsWith(requestOrigin))) {
|
||||||
const extensionQuery = filenameQuery.split('.').pop()?.toLowerCase() || '';
|
// Parse url, get filename query. Keep only documents that can be parsed
|
||||||
if (!documentFileType.includes(extensionQuery)) {
|
const parseUrl = new URL(url, origin);
|
||||||
return '';
|
const filenameQuery = parseUrl.searchParams.get('filename');
|
||||||
|
|
||||||
|
// Not document
|
||||||
|
if (filenameQuery) {
|
||||||
|
const extensionQuery = filenameQuery.split('.').pop()?.toLowerCase() || '';
|
||||||
|
if (!documentFileType.includes(extensionQuery)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the origin(Make intranet requests directly)
|
||||||
|
if (requestOrigin && url.startsWith(requestOrigin)) {
|
||||||
|
url = url.replace(requestOrigin, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the origin(Make intranet requests directly)
|
return url;
|
||||||
if (requestOrigin && url.startsWith(requestOrigin)) {
|
} catch (error) {
|
||||||
url = url.replace(requestOrigin, '');
|
console.log(error);
|
||||||
}
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.slice(0, maxFiles);
|
.slice(0, maxFiles);
|
||||||
|
@@ -8,7 +8,7 @@ import { getReferenceVariableValue } from '@fastgpt/global/core/workflow/runtime
|
|||||||
import { TUpdateListItem } from '@fastgpt/global/core/workflow/template/system/variableUpdate/type';
|
import { TUpdateListItem } from '@fastgpt/global/core/workflow/template/system/variableUpdate/type';
|
||||||
import { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
|
import { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
|
||||||
import { removeSystemVariable, valueTypeFormat } from '../utils';
|
import { removeSystemVariable, valueTypeFormat } from '../utils';
|
||||||
import { replaceVariableLabel } from '@fastgpt/global/core/workflow/utils';
|
import { replaceEditorVariable } from '@fastgpt/global/core/workflow/utils';
|
||||||
|
|
||||||
type Props = ModuleDispatchProps<{
|
type Props = ModuleDispatchProps<{
|
||||||
[NodeInputKeyEnum.updateList]: TUpdateListItem[];
|
[NodeInputKeyEnum.updateList]: TUpdateListItem[];
|
||||||
@@ -32,7 +32,7 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
|
|||||||
const formatValue = valueTypeFormat(item.value?.[1], item.valueType);
|
const formatValue = valueTypeFormat(item.value?.[1], item.valueType);
|
||||||
|
|
||||||
return typeof formatValue === 'string'
|
return typeof formatValue === 'string'
|
||||||
? replaceVariableLabel({
|
? replaceEditorVariable({
|
||||||
text: formatValue,
|
text: formatValue,
|
||||||
nodes: runtimeNodes,
|
nodes: runtimeNodes,
|
||||||
variables,
|
variables,
|
||||||
|
@@ -20,6 +20,10 @@
|
|||||||
"you_can_convert": "You can redeem",
|
"you_can_convert": "You can redeem",
|
||||||
"yuan": "Yuan"
|
"yuan": "Yuan"
|
||||||
},
|
},
|
||||||
|
"promotion": {
|
||||||
|
"register": "Register",
|
||||||
|
"pay": "Pay"
|
||||||
|
},
|
||||||
"bind_inform_account_error": "Abnormal binding notification account",
|
"bind_inform_account_error": "Abnormal binding notification account",
|
||||||
"bind_inform_account_success": "Binding notification account successful",
|
"bind_inform_account_success": "Binding notification account successful",
|
||||||
"code_error": {
|
"code_error": {
|
||||||
|
@@ -20,6 +20,10 @@
|
|||||||
"current_token_price": "当前积分价格",
|
"current_token_price": "当前积分价格",
|
||||||
"yuan": "元"
|
"yuan": "元"
|
||||||
},
|
},
|
||||||
|
"promotion": {
|
||||||
|
"register": "好友注册",
|
||||||
|
"pay": "好友充值"
|
||||||
|
},
|
||||||
"bind_inform_account_error": "绑定通知账号异常",
|
"bind_inform_account_error": "绑定通知账号异常",
|
||||||
"bind_inform_account_success": "绑定通知账号成功",
|
"bind_inform_account_success": "绑定通知账号成功",
|
||||||
"delete": {
|
"delete": {
|
||||||
|
@@ -19,10 +19,8 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { getPromotionInitData, getPromotionRecords } from '@/web/support/activity/promotion/api';
|
import { getPromotionInitData, getPromotionRecords } from '@/web/support/activity/promotion/api';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
|
|
||||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
|
||||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||||
import type { PromotionRecordType } from '@/global/support/api/userRes.d';
|
import type { PromotionRecordType } from '@/global/support/api/userRes.d';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { usePagination } from '@fastgpt/web/hooks/usePagination';
|
import { usePagination } from '@fastgpt/web/hooks/usePagination';
|
||||||
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
||||||
@@ -116,7 +114,7 @@ const Promotion = () => {
|
|||||||
<Td>
|
<Td>
|
||||||
{item.createTime ? dayjs(item.createTime).format('YYYY/MM/DD HH:mm:ss') : '-'}
|
{item.createTime ? dayjs(item.createTime).format('YYYY/MM/DD HH:mm:ss') : '-'}
|
||||||
</Td>
|
</Td>
|
||||||
<Td>{t(`user.promotion.${item.type}` as any)}</Td>
|
<Td>{t(`user:promotion.${item.type}` as any)}</Td>
|
||||||
<Td>{item.amount}</Td>
|
<Td>{item.amount}</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
))}
|
))}
|
||||||
|
@@ -2,13 +2,11 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
|||||||
import { jsonRes } from '@fastgpt/service/common/response';
|
import { jsonRes } from '@fastgpt/service/common/response';
|
||||||
import { connectToDatabase } from '@/service/mongo';
|
import { connectToDatabase } from '@/service/mongo';
|
||||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||||
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
|
|
||||||
import { DatasetDefaultPermissionVal } from '@fastgpt/global/support/permission/dataset/constant';
|
|
||||||
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
|
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
|
||||||
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
|
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
|
||||||
import { POST } from '@fastgpt/service/common/api/plusRequest';
|
import { POST } from '@fastgpt/service/common/api/plusRequest';
|
||||||
|
|
||||||
/* pg 中的数据搬到 mongo dataset.datas 中,并做映射 */
|
/* 初始化发布的版本 */
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
try {
|
try {
|
||||||
await connectToDatabase();
|
await connectToDatabase();
|
||||||
|
@@ -30,7 +30,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||||||
});
|
});
|
||||||
const { file, bucketName, metadata } = await upload.doUpload(req, res);
|
const { file, bucketName, metadata } = await upload.doUpload(req, res);
|
||||||
filePaths.push(file.path);
|
filePaths.push(file.path);
|
||||||
const { teamId, tmbId, outLinkUid } = await authChatCert({ req, authToken: true });
|
const { teamId, tmbId, outLinkUid } = await authChatCert({
|
||||||
|
req,
|
||||||
|
authToken: true,
|
||||||
|
authApiKey: true
|
||||||
|
});
|
||||||
|
|
||||||
await authUploadLimit(outLinkUid || tmbId);
|
await authUploadLimit(outLinkUid || tmbId);
|
||||||
|
|
||||||
|
@@ -368,6 +368,14 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
if (assistantResponses.length === 0) return '';
|
if (assistantResponses.length === 0) return '';
|
||||||
if (assistantResponses.length === 1 && assistantResponses[0].text?.content)
|
if (assistantResponses.length === 1 && assistantResponses[0].text?.content)
|
||||||
return assistantResponses[0].text?.content;
|
return assistantResponses[0].text?.content;
|
||||||
|
|
||||||
|
if (!detail) {
|
||||||
|
return assistantResponses
|
||||||
|
.map((item) => item?.text?.content)
|
||||||
|
.filter(Boolean)
|
||||||
|
.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
return assistantResponses;
|
return assistantResponses;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@@ -125,7 +125,7 @@ const Header = ({}: {}) => {
|
|||||||
return (
|
return (
|
||||||
<Box display={['block', 'flex']} alignItems={'center'} gap={2}>
|
<Box display={['block', 'flex']} alignItems={'center'} gap={2}>
|
||||||
<HStack flex={1}>
|
<HStack flex={1}>
|
||||||
<Box flex={1} fontWeight={'500'} color={'myGray.900'}>
|
<Box flex={1} fontWeight={'500'} color={'myGray.900'} whiteSpace={'nowrap'}>
|
||||||
<ParentPath
|
<ParentPath
|
||||||
paths={paths.map((path, i) => ({
|
paths={paths.map((path, i) => ({
|
||||||
parentId: path.parentId,
|
parentId: path.parentId,
|
||||||
@@ -173,7 +173,8 @@ const Header = ({}: {}) => {
|
|||||||
{/* search input */}
|
{/* search input */}
|
||||||
{isPc && (
|
{isPc && (
|
||||||
<MyInput
|
<MyInput
|
||||||
w={['100%', '250px']}
|
maxW={'250px'}
|
||||||
|
flex={1}
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
h={'36px'}
|
h={'36px'}
|
||||||
placeholder={t('common:common.Search') || ''}
|
placeholder={t('common:common.Search') || ''}
|
||||||
|
@@ -2,12 +2,10 @@ import { Box, Button, Checkbox, Flex, Input, useDisclosure } from '@chakra-ui/re
|
|||||||
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { postCreateDatasetCollectionTag } from '@/web/core/dataset/api';
|
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
|
||||||
import { CollectionPageContext } from './Context';
|
import { CollectionPageContext } from './Context';
|
||||||
import { debounce, isEqual } from 'lodash';
|
import { debounce, isEqual } from 'lodash';
|
||||||
import TagManageModal from './TagManageModal';
|
import TagManageModal from './TagManageModal';
|
||||||
@@ -15,27 +13,17 @@ import { DatasetTagType } from '@fastgpt/global/core/dataset/type';
|
|||||||
|
|
||||||
const HeaderTagPopOver = () => {
|
const HeaderTagPopOver = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [searchTag, setSearchTag] = useState('');
|
|
||||||
const [checkedTags, setCheckedTags] = useState<string[]>([]);
|
const [checkedTags, setCheckedTags] = useState<string[]>([]);
|
||||||
|
|
||||||
const { datasetDetail, datasetTags, loadDatasetTags, checkedDatasetTag, setCheckedDatasetTag } =
|
const {
|
||||||
useContextSelector(DatasetPageContext, (v) => v);
|
searchDatasetTagsResult,
|
||||||
|
searchTagKey,
|
||||||
const { mutate: onCreateCollectionTag, isLoading: isCreateCollectionTagLoading } = useRequest({
|
setSearchTagKey,
|
||||||
mutationFn: async (tag: string) => {
|
checkedDatasetTag,
|
||||||
const id = await postCreateDatasetCollectionTag({
|
setCheckedDatasetTag,
|
||||||
datasetId: datasetDetail._id,
|
onCreateCollectionTag,
|
||||||
tag
|
isCreateCollectionTagLoading
|
||||||
});
|
} = useContextSelector(DatasetPageContext, (v) => v);
|
||||||
return id;
|
|
||||||
},
|
|
||||||
|
|
||||||
onSuccess() {
|
|
||||||
setSearchTag('');
|
|
||||||
},
|
|
||||||
successToast: t('common:common.Create Success'),
|
|
||||||
errorToast: t('common:common.Create Failed')
|
|
||||||
});
|
|
||||||
|
|
||||||
const { filterTags, setFilterTags, getData } = useContextSelector(
|
const { filterTags, setFilterTags, getData } = useContextSelector(
|
||||||
CollectionPageContext,
|
CollectionPageContext,
|
||||||
@@ -48,10 +36,6 @@ const HeaderTagPopOver = () => {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
loadDatasetTags({ id: datasetDetail._id, searchKey: searchTag });
|
|
||||||
}, [searchTag]);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isTagManageModalOpen,
|
isOpen: isTagManageModalOpen,
|
||||||
onOpen: onOpenTagManageModal,
|
onOpen: onOpenTagManageModal,
|
||||||
@@ -122,35 +106,34 @@ const HeaderTagPopOver = () => {
|
|||||||
pl={2}
|
pl={2}
|
||||||
h={8}
|
h={8}
|
||||||
borderRadius={'xs'}
|
borderRadius={'xs'}
|
||||||
value={searchTag}
|
value={searchTagKey}
|
||||||
placeholder={t('dataset:tag.searchOrAddTag')}
|
placeholder={t('dataset:tag.searchOrAddTag')}
|
||||||
onChange={(e) => setSearchTag(e.target.value)}
|
onChange={(e) => setSearchTagKey(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box my={1} px={1.5} maxH={'240px'} overflow={'auto'}>
|
<Box my={1} px={1.5} maxH={'240px'} overflow={'auto'}>
|
||||||
{searchTag && !datasetTags.map((item) => item.tag).includes(searchTag) && (
|
{searchTagKey &&
|
||||||
<Flex
|
!searchDatasetTagsResult.map((item) => item.tag).includes(searchTagKey) && (
|
||||||
alignItems={'center'}
|
<Flex
|
||||||
fontSize={'sm'}
|
alignItems={'center'}
|
||||||
px={1}
|
fontSize={'sm'}
|
||||||
cursor={'pointer'}
|
px={1}
|
||||||
_hover={{ bg: '#1118240D', color: 'primary.700' }}
|
cursor={'pointer'}
|
||||||
borderRadius={'xs'}
|
_hover={{ bg: '#1118240D', color: 'primary.700' }}
|
||||||
onClick={() => {
|
borderRadius={'xs'}
|
||||||
onCreateCollectionTag(searchTag);
|
onClick={() => onCreateCollectionTag(searchTagKey)}
|
||||||
}}
|
>
|
||||||
>
|
<MyIcon name={'common/addLight'} w={'16px'} />
|
||||||
<MyIcon name={'common/addLight'} w={'16px'} />
|
<Box ml={2} py={2}>
|
||||||
<Box ml={2} py={2}>
|
{t('dataset:tag.add') + ` "${searchTagKey}"`}
|
||||||
{t('dataset:tag.add') + ` "${searchTag}"`}
|
</Box>
|
||||||
</Box>
|
</Flex>
|
||||||
</Flex>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{[
|
{[
|
||||||
...new Map(
|
...new Map(
|
||||||
[...checkedDatasetTag, ...datasetTags].map((item) => [item._id, item])
|
[...checkedDatasetTag, ...searchDatasetTagsResult].map((item) => [item._id, item])
|
||||||
).values()
|
).values()
|
||||||
].map((item) => {
|
].map((item) => {
|
||||||
const checked = checkedTags.includes(item._id);
|
const checked = checkedTags.includes(item._id);
|
||||||
@@ -197,6 +180,7 @@ const HeaderTagPopOver = () => {
|
|||||||
borderBottomLeftRadius={'md'}
|
borderBottomLeftRadius={'md'}
|
||||||
variant={'unstyled'}
|
variant={'unstyled'}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
setSearchTagKey('');
|
||||||
setCheckedTags([]);
|
setCheckedTags([]);
|
||||||
setFilterTags([]);
|
setFilterTags([]);
|
||||||
debounceRefetch();
|
debounceRefetch();
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { Input, Button, Flex, Box, Checkbox, BoxProps } from '@chakra-ui/react';
|
import { Input, Button, Flex, Box, Checkbox } from '@chakra-ui/react';
|
||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
@@ -13,10 +13,9 @@ import {
|
|||||||
getScrollCollectionList,
|
getScrollCollectionList,
|
||||||
getTagUsage,
|
getTagUsage,
|
||||||
postAddTagsToCollections,
|
postAddTagsToCollections,
|
||||||
postCreateDatasetCollectionTag,
|
|
||||||
updateDatasetCollectionTag
|
updateDatasetCollectionTag
|
||||||
} from '@/web/core/dataset/api';
|
} from '@/web/core/dataset/api';
|
||||||
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import MyInput from '@/components/MyInput';
|
import MyInput from '@/components/MyInput';
|
||||||
import { DatasetTagType } from '@fastgpt/global/core/dataset/type';
|
import { DatasetTagType } from '@fastgpt/global/core/dataset/type';
|
||||||
import { ScrollListType, useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
import { ScrollListType, useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
@@ -26,9 +25,13 @@ import { DatasetCollectionsListItemType } from '@/global/core/dataset/type';
|
|||||||
|
|
||||||
const TagManageModal = ({ onClose }: { onClose: () => void }) => {
|
const TagManageModal = ({ onClose }: { onClose: () => void }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
|
const {
|
||||||
const loadDatasetTags = useContextSelector(DatasetPageContext, (v) => v.loadDatasetTags);
|
datasetDetail,
|
||||||
const loadAllDatasetTags = useContextSelector(DatasetPageContext, (v) => v.loadAllDatasetTags);
|
onCreateCollectionTag,
|
||||||
|
isCreateCollectionTagLoading,
|
||||||
|
loadAllDatasetTags,
|
||||||
|
setSearchTagKey
|
||||||
|
} = useContextSelector(DatasetPageContext, (v) => v);
|
||||||
const { getData, pageNum, collections } = useContextSelector(CollectionPageContext, (v) => v);
|
const { getData, pageNum, collections } = useContextSelector(CollectionPageContext, (v) => v);
|
||||||
|
|
||||||
const tagInputRef = useRef<HTMLInputElement>(null);
|
const tagInputRef = useRef<HTMLInputElement>(null);
|
||||||
@@ -56,36 +59,17 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
}
|
}
|
||||||
}, [currentEditTag]);
|
}, [currentEditTag]);
|
||||||
|
|
||||||
const { mutate: onCreateCollectionTag, isLoading: isCreateCollectionTagLoading } = useRequest({
|
|
||||||
mutationFn: async (tag: string) => {
|
|
||||||
const id = await postCreateDatasetCollectionTag({
|
|
||||||
datasetId: datasetDetail._id,
|
|
||||||
tag
|
|
||||||
});
|
|
||||||
return id;
|
|
||||||
},
|
|
||||||
|
|
||||||
onSuccess() {
|
|
||||||
fetchData(1);
|
|
||||||
loadDatasetTags({ id: datasetDetail._id, searchKey: '' });
|
|
||||||
loadAllDatasetTags({ id: datasetDetail._id });
|
|
||||||
},
|
|
||||||
successToast: t('common:common.Create Success'),
|
|
||||||
errorToast: t('common:common.Create Failed')
|
|
||||||
});
|
|
||||||
|
|
||||||
const { runAsync: onDeleteCollectionTag, loading: isDeleteCollectionTagLoading } = useRequest2(
|
const { runAsync: onDeleteCollectionTag, loading: isDeleteCollectionTagLoading } = useRequest2(
|
||||||
(tag: string) => {
|
(tag: string) =>
|
||||||
return delDatasetCollectionTag({
|
delDatasetCollectionTag({
|
||||||
datasetId: datasetDetail._id,
|
datasetId: datasetDetail._id,
|
||||||
id: tag
|
id: tag
|
||||||
});
|
}),
|
||||||
},
|
|
||||||
{
|
{
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
fetchData(1);
|
fetchData(1);
|
||||||
loadDatasetTags({ id: datasetDetail._id, searchKey: '' });
|
setSearchTagKey('');
|
||||||
loadAllDatasetTags({ id: datasetDetail._id });
|
loadAllDatasetTags();
|
||||||
},
|
},
|
||||||
successToast: t('common:common.Delete Success'),
|
successToast: t('common:common.Delete Success'),
|
||||||
errorToast: t('common:common.Delete Failed')
|
errorToast: t('common:common.Delete Failed')
|
||||||
@@ -103,8 +87,8 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
{
|
{
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
fetchData(1);
|
fetchData(1);
|
||||||
loadDatasetTags({ id: datasetDetail._id, searchKey: '' });
|
setSearchTagKey('');
|
||||||
loadAllDatasetTags({ id: datasetDetail._id });
|
loadAllDatasetTags();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -2,12 +2,11 @@ import { Box, Checkbox, Flex, Input } from '@chakra-ui/react';
|
|||||||
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { postCreateDatasetCollectionTag, putDatasetCollectionById } from '@/web/core/dataset/api';
|
import { putDatasetCollectionById } from '@/web/core/dataset/api';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useMemo, useRef, useState } from 'react';
|
||||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
|
||||||
import { useDeepCompareEffect } from 'ahooks';
|
import { useDeepCompareEffect } from 'ahooks';
|
||||||
import { DatasetCollectionItemType, DatasetTagType } from '@fastgpt/global/core/dataset/type';
|
import { DatasetCollectionItemType, DatasetTagType } from '@fastgpt/global/core/dataset/type';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
@@ -19,25 +18,20 @@ const TagsPopOver = ({
|
|||||||
currentCollection: DatasetCollectionItemType | DatasetCollectionsListItemType;
|
currentCollection: DatasetCollectionItemType | DatasetCollectionsListItemType;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
|
const {
|
||||||
const datasetTags = useContextSelector(DatasetPageContext, (v) => v.datasetTags);
|
searchTagKey,
|
||||||
const loadDatasetTags = useContextSelector(DatasetPageContext, (v) => v.loadDatasetTags);
|
setSearchTagKey,
|
||||||
const allDatasetTags = useContextSelector(DatasetPageContext, (v) => v.allDatasetTags);
|
searchDatasetTagsResult,
|
||||||
const loadAllDatasetTags = useContextSelector(DatasetPageContext, (v) => v.loadAllDatasetTags);
|
allDatasetTags,
|
||||||
|
onCreateCollectionTag,
|
||||||
|
isCreateCollectionTagLoading
|
||||||
|
} = useContextSelector(DatasetPageContext, (v) => v);
|
||||||
|
|
||||||
const [collectionTags, setCollectionTags] = useState<string[]>([]);
|
const [collectionTags, setCollectionTags] = useState<string[]>(currentCollection.tags ?? []);
|
||||||
const [searchTag, setSearchTag] = useState('');
|
|
||||||
const [checkedTags, setCheckedTags] = useState<DatasetTagType[]>([]);
|
const [checkedTags, setCheckedTags] = useState<DatasetTagType[]>([]);
|
||||||
|
|
||||||
const [showTagManage, setShowTagManage] = useState(false);
|
const [showTagManage, setShowTagManage] = useState(false);
|
||||||
const [isFocusInput, setIsFocusInput] = useState(false);
|
|
||||||
const [isUpdateLoading, setIsUpdateLoading] = useState(false);
|
const [isUpdateLoading, setIsUpdateLoading] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!currentCollection.tags) return;
|
|
||||||
setCollectionTags(currentCollection.tags);
|
|
||||||
}, [currentCollection]);
|
|
||||||
|
|
||||||
const tagList = useMemo(
|
const tagList = useMemo(
|
||||||
() =>
|
() =>
|
||||||
(collectionTags
|
(collectionTags
|
||||||
@@ -52,12 +46,6 @@ const TagsPopOver = ({
|
|||||||
[collectionTags, allDatasetTags]
|
[collectionTags, allDatasetTags]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isFocusInput) return;
|
|
||||||
loadDatasetTags({ id: datasetDetail._id, searchKey: searchTag });
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [datasetDetail._id, isFocusInput, searchTag]);
|
|
||||||
|
|
||||||
const [visibleTags, setVisibleTags] = useState<DatasetTagType[]>(tagList);
|
const [visibleTags, setVisibleTags] = useState<DatasetTagType[]>(tagList);
|
||||||
const [overflowTags, setOverflowTags] = useState<DatasetTagType[]>([]);
|
const [overflowTags, setOverflowTags] = useState<DatasetTagType[]>([]);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
@@ -96,24 +84,6 @@ const TagsPopOver = ({
|
|||||||
};
|
};
|
||||||
}, [tagList]);
|
}, [tagList]);
|
||||||
|
|
||||||
const { mutate: onCreateCollectionTag, isLoading: isCreateCollectionTagLoading } = useRequest({
|
|
||||||
mutationFn: async (tag: string) => {
|
|
||||||
const id = await postCreateDatasetCollectionTag({
|
|
||||||
datasetId: datasetDetail._id,
|
|
||||||
tag
|
|
||||||
});
|
|
||||||
return id;
|
|
||||||
},
|
|
||||||
|
|
||||||
onSuccess() {
|
|
||||||
setSearchTag('');
|
|
||||||
loadDatasetTags({ id: datasetDetail._id, searchKey: '' });
|
|
||||||
loadAllDatasetTags({ id: datasetDetail._id });
|
|
||||||
},
|
|
||||||
successToast: t('common:common.Create Success'),
|
|
||||||
errorToast: t('common:common.Create Failed')
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyPopover
|
<MyPopover
|
||||||
placement={showTagManage ? 'bottom' : 'bottom-end'}
|
placement={showTagManage ? 'bottom' : 'bottom-end'}
|
||||||
@@ -176,6 +146,8 @@ const TagsPopOver = ({
|
|||||||
</MyBox>
|
</MyBox>
|
||||||
}
|
}
|
||||||
onCloseFunc={async () => {
|
onCloseFunc={async () => {
|
||||||
|
setSearchTagKey('');
|
||||||
|
|
||||||
setShowTagManage(false);
|
setShowTagManage(false);
|
||||||
if (isEqual(checkedTags, tagList) || !showTagManage) return;
|
if (isEqual(checkedTags, tagList) || !showTagManage) return;
|
||||||
setIsUpdateLoading(true);
|
setIsUpdateLoading(true);
|
||||||
@@ -194,36 +166,33 @@ const TagsPopOver = ({
|
|||||||
<MyBox isLoading={isCreateCollectionTagLoading} onClick={(e) => e.stopPropagation()}>
|
<MyBox isLoading={isCreateCollectionTagLoading} onClick={(e) => e.stopPropagation()}>
|
||||||
<Box px={1.5} pt={1.5}>
|
<Box px={1.5} pt={1.5}>
|
||||||
<Input
|
<Input
|
||||||
onFocus={() => setIsFocusInput(true)}
|
|
||||||
onBlur={() => setIsFocusInput(false)}
|
|
||||||
pl={2}
|
pl={2}
|
||||||
h={7}
|
h={7}
|
||||||
borderRadius={'xs'}
|
borderRadius={'xs'}
|
||||||
value={searchTag}
|
value={searchTagKey}
|
||||||
placeholder={t('dataset:tag.searchOrAddTag')}
|
placeholder={t('dataset:tag.searchOrAddTag')}
|
||||||
onChange={(e) => setSearchTag(e.target.value)}
|
onChange={(e) => setSearchTagKey(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box my={1} px={1.5} maxH={'200px'} overflow={'auto'}>
|
<Box my={1} px={1.5} maxH={'200px'} overflow={'auto'}>
|
||||||
{searchTag && !datasetTags.map((item) => item.tag).includes(searchTag) && (
|
{searchTagKey &&
|
||||||
<Flex
|
!searchDatasetTagsResult.map((item) => item.tag).includes(searchTagKey) && (
|
||||||
alignItems={'center'}
|
<Flex
|
||||||
fontSize={'xs'}
|
alignItems={'center'}
|
||||||
px={1}
|
fontSize={'xs'}
|
||||||
cursor={'pointer'}
|
px={1}
|
||||||
_hover={{ bg: '#1118240D', color: '#2B5FD9' }}
|
cursor={'pointer'}
|
||||||
borderRadius={'xs'}
|
_hover={{ bg: '#1118240D', color: '#2B5FD9' }}
|
||||||
onClick={() => {
|
borderRadius={'xs'}
|
||||||
onCreateCollectionTag(searchTag);
|
onClick={() => onCreateCollectionTag(searchTagKey)}
|
||||||
}}
|
>
|
||||||
>
|
<MyIcon name={'common/addLight'} w={'1rem'} />
|
||||||
<MyIcon name={'common/addLight'} w={'16px'} />
|
<Box ml={1} py={1}>
|
||||||
<Box ml={1} py={1}>
|
{t('dataset:tag.add') + ` "${searchTagKey}"`}
|
||||||
{t('dataset:tag.add') + ` "${searchTag}"`}
|
</Box>
|
||||||
</Box>
|
</Flex>
|
||||||
</Flex>
|
)}
|
||||||
)}
|
{searchDatasetTagsResult?.map((item) => {
|
||||||
{datasetTags?.map((item) => {
|
|
||||||
const tagsList = checkedTags.map((tag) => tag.tag);
|
const tagsList = checkedTags.map((tag) => tag.tag);
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
|
@@ -49,12 +49,8 @@ const Detail = ({ datasetId, currentTab }: Props) => {
|
|||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
|
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
|
||||||
const loadDatasetDetail = useContextSelector(DatasetPageContext, (v) => v.loadDatasetDetail);
|
const loadDatasetDetail = useContextSelector(DatasetPageContext, (v) => v.loadDatasetDetail);
|
||||||
const loadAllDatasetTags = useContextSelector(DatasetPageContext, (v) => v.loadAllDatasetTags);
|
|
||||||
|
|
||||||
useRequest2(() => loadDatasetDetail(datasetId), {
|
useRequest2(() => loadDatasetDetail(datasetId), {
|
||||||
onSuccess: () => {
|
|
||||||
loadAllDatasetTags({ id: datasetId });
|
|
||||||
},
|
|
||||||
onError(err: any) {
|
onError(err: any) {
|
||||||
router.replace(`/dataset/list`);
|
router.replace(`/dataset/list`);
|
||||||
toast({
|
toast({
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { ReactNode, SetStateAction, useMemo, useState } from 'react';
|
import { Dispatch, ReactNode, SetStateAction, useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { createContext } from 'use-context-selector';
|
import { createContext } from 'use-context-selector';
|
||||||
import {
|
import {
|
||||||
@@ -8,24 +8,30 @@ import {
|
|||||||
getDatasetCollectionTags,
|
getDatasetCollectionTags,
|
||||||
getDatasetTrainingQueue,
|
getDatasetTrainingQueue,
|
||||||
getTrainingQueueLen,
|
getTrainingQueueLen,
|
||||||
|
postCreateDatasetCollectionTag,
|
||||||
putDatasetById
|
putDatasetById
|
||||||
} from '../api';
|
} from '../api';
|
||||||
import { defaultDatasetDetail } from '../constants';
|
import { defaultDatasetDetail } from '../constants';
|
||||||
import { DatasetUpdateBody } from '@fastgpt/global/core/dataset/api';
|
import { DatasetUpdateBody } from '@fastgpt/global/core/dataset/api';
|
||||||
import { DatasetItemType, DatasetTagType } from '@fastgpt/global/core/dataset/type';
|
import { DatasetItemType, DatasetTagType } from '@fastgpt/global/core/dataset/type';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
|
|
||||||
type DatasetPageContextType = {
|
type DatasetPageContextType = {
|
||||||
datasetId: string;
|
datasetId: string;
|
||||||
datasetDetail: DatasetItemType;
|
datasetDetail: DatasetItemType;
|
||||||
loadDatasetDetail: (id: string) => Promise<DatasetItemType>;
|
loadDatasetDetail: (id: string) => Promise<DatasetItemType>;
|
||||||
updateDataset: (data: DatasetUpdateBody) => Promise<void>;
|
updateDataset: (data: DatasetUpdateBody) => Promise<void>;
|
||||||
datasetTags: DatasetTagType[];
|
|
||||||
loadDatasetTags: (data: { id: string; searchKey: string }) => Promise<void>;
|
searchDatasetTagsResult: DatasetTagType[];
|
||||||
allDatasetTags: DatasetTagType[];
|
allDatasetTags: DatasetTagType[];
|
||||||
loadAllDatasetTags: (data: { id: string }) => Promise<void>;
|
loadAllDatasetTags: () => Promise<DatasetTagType[]>;
|
||||||
checkedDatasetTag: DatasetTagType[];
|
checkedDatasetTag: DatasetTagType[];
|
||||||
setCheckedDatasetTag: React.Dispatch<SetStateAction<DatasetTagType[]>>;
|
setCheckedDatasetTag: React.Dispatch<SetStateAction<DatasetTagType[]>>;
|
||||||
|
onCreateCollectionTag: (tag: string) => Promise<void>;
|
||||||
|
isCreateCollectionTagLoading: boolean;
|
||||||
|
searchTagKey: string;
|
||||||
|
setSearchTagKey: Dispatch<SetStateAction<string>>;
|
||||||
|
|
||||||
vectorTrainingMap: {
|
vectorTrainingMap: {
|
||||||
colorSchema: string;
|
colorSchema: string;
|
||||||
@@ -62,17 +68,22 @@ export const DatasetPageContext = createContext<DatasetPageContextType>({
|
|||||||
updateDataset: function (data: DatasetUpdateBody): Promise<void> {
|
updateDataset: function (data: DatasetUpdateBody): Promise<void> {
|
||||||
throw new Error('Function not implemented.');
|
throw new Error('Function not implemented.');
|
||||||
},
|
},
|
||||||
datasetTags: [],
|
searchDatasetTagsResult: [],
|
||||||
loadDatasetTags: function (data: { id: string; searchKey: string }): Promise<void> {
|
|
||||||
throw new Error('Function not implemented.');
|
|
||||||
},
|
|
||||||
allDatasetTags: [],
|
allDatasetTags: [],
|
||||||
loadAllDatasetTags: function (data: { id: string }): Promise<void> {
|
|
||||||
throw new Error('Function not implemented.');
|
|
||||||
},
|
|
||||||
checkedDatasetTag: [],
|
checkedDatasetTag: [],
|
||||||
setCheckedDatasetTag: function (): void {
|
setCheckedDatasetTag: function (): void {
|
||||||
throw new Error('Function not implemented.');
|
throw new Error('Function not implemented.');
|
||||||
|
},
|
||||||
|
loadAllDatasetTags: function (): Promise<DatasetTagType[]> {
|
||||||
|
throw new Error('Function not implemented.');
|
||||||
|
},
|
||||||
|
onCreateCollectionTag: function (tag: string): Promise<void> {
|
||||||
|
throw new Error('Function not implemented.');
|
||||||
|
},
|
||||||
|
isCreateCollectionTagLoading: false,
|
||||||
|
searchTagKey: '',
|
||||||
|
setSearchTagKey: function (value: SetStateAction<string>): void {
|
||||||
|
throw new Error('Function not implemented.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -108,28 +119,53 @@ export const DatasetPageContextProvider = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// dataset tags
|
// dataset tags
|
||||||
const [datasetTags, setDatasetTags] = useState<DatasetTagType[]>([]);
|
|
||||||
|
|
||||||
const loadDatasetTags = async ({ id, searchKey }: { id: string; searchKey: string }) => {
|
|
||||||
const { list } = await getDatasetCollectionTags({
|
|
||||||
datasetId: id,
|
|
||||||
searchText: searchKey,
|
|
||||||
current: 1,
|
|
||||||
pageSize: 15
|
|
||||||
});
|
|
||||||
setDatasetTags(list);
|
|
||||||
};
|
|
||||||
|
|
||||||
const [checkedDatasetTag, setCheckedDatasetTag] = useState<DatasetTagType[]>([]);
|
const [checkedDatasetTag, setCheckedDatasetTag] = useState<DatasetTagType[]>([]);
|
||||||
|
const [searchTagKey, setSearchTagKey] = useState('');
|
||||||
|
|
||||||
const [allDatasetTags, setAllDatasetTags] = useState<DatasetTagType[]>([]);
|
const { runAsync: loadAllDatasetTags, data: allDatasetTags = [] } = useRequest2(
|
||||||
|
async () => {
|
||||||
|
if (!feConfigs?.isPlus || !datasetDetail._id) return [];
|
||||||
|
|
||||||
const loadAllDatasetTags = async ({ id }: { id: string }) => {
|
const { list } = await getAllTags(datasetDetail._id);
|
||||||
if (!feConfigs?.isPlus) return;
|
return list;
|
||||||
|
},
|
||||||
const { list } = await getAllTags(id);
|
{
|
||||||
setAllDatasetTags(list);
|
manual: false,
|
||||||
};
|
refreshDeps: [datasetDetail._id]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const { data: searchDatasetTagsResult = [] } = useRequest2(
|
||||||
|
async () => {
|
||||||
|
if (!searchTagKey) return allDatasetTags;
|
||||||
|
const { list } = await getDatasetCollectionTags({
|
||||||
|
datasetId: datasetDetail._id,
|
||||||
|
searchText: searchTagKey,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 15
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
manual: false,
|
||||||
|
throttleWait: 300,
|
||||||
|
refreshDeps: [datasetDetail._id, searchTagKey, allDatasetTags]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const { runAsync: onCreateCollectionTag, loading: isCreateCollectionTagLoading } = useRequest2(
|
||||||
|
(tag: string) =>
|
||||||
|
postCreateDatasetCollectionTag({
|
||||||
|
datasetId: datasetDetail._id,
|
||||||
|
tag
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
refreshDeps: [datasetDetail._id],
|
||||||
|
onSuccess() {
|
||||||
|
loadAllDatasetTags();
|
||||||
|
},
|
||||||
|
successToast: t('common:common.Create Success'),
|
||||||
|
errorToast: t('common:common.Create Failed')
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// global queue
|
// global queue
|
||||||
const { data: { vectorTrainingCount = 0, agentTrainingCount = 0 } = {} } = useQuery(
|
const { data: { vectorTrainingCount = 0, agentTrainingCount = 0 } = {} } = useQuery(
|
||||||
@@ -199,12 +235,16 @@ export const DatasetPageContextProvider = ({
|
|||||||
rebuildingCount,
|
rebuildingCount,
|
||||||
trainingCount,
|
trainingCount,
|
||||||
refetchDatasetTraining,
|
refetchDatasetTraining,
|
||||||
datasetTags,
|
|
||||||
loadDatasetTags,
|
searchDatasetTagsResult,
|
||||||
checkedDatasetTag,
|
checkedDatasetTag,
|
||||||
setCheckedDatasetTag,
|
setCheckedDatasetTag,
|
||||||
allDatasetTags,
|
allDatasetTags,
|
||||||
loadAllDatasetTags
|
loadAllDatasetTags,
|
||||||
|
onCreateCollectionTag,
|
||||||
|
isCreateCollectionTagLoading,
|
||||||
|
searchTagKey,
|
||||||
|
setSearchTagKey
|
||||||
};
|
};
|
||||||
|
|
||||||
return <DatasetPageContext.Provider value={contextValue}>{children}</DatasetPageContext.Provider>;
|
return <DatasetPageContext.Provider value={contextValue}>{children}</DatasetPageContext.Provider>;
|
||||||
|
Reference in New Issue
Block a user