style: dataset detail page style refactor (#2501)

* style: dataset detail page style refactor

* remove px

* remove py px px

* change shadow

* style: 2期联调结束

* 优化部分代码
This commit is contained in:
papapatrick
2024-08-28 10:17:49 +08:00
committed by GitHub
parent c9bb39d802
commit bebf565c06
33 changed files with 860 additions and 632 deletions

View File

@@ -12,17 +12,17 @@ export const DatasetTypeMap = {
collectionLabel: 'common.Folder'
},
[DatasetTypeEnum.dataset]: {
icon: 'core/dataset/commonDataset',
icon: 'core/dataset/commonDatasetOutline',
label: 'common_dataset',
collectionLabel: 'common.File'
},
[DatasetTypeEnum.websiteDataset]: {
icon: 'core/dataset/websiteDataset',
icon: 'core/dataset/websiteDatasetOutline',
label: 'website_dataset',
collectionLabel: 'common.Website'
},
[DatasetTypeEnum.externalFile]: {
icon: 'core/dataset/externalDataset',
icon: 'core/dataset/externalDatasetOutline',
label: 'external_file',
collectionLabel: 'common.File'
}

View File

@@ -8,6 +8,10 @@ export const iconPaths = {
collectionLight: () => import('./icons/collectionLight.svg'),
collectionSolid: () => import('./icons/collectionSolid.svg'),
'common/add2': () => import('./icons/common/add2.svg'),
'common/setting': () => import('./icons/common/setting.svg'),
'common/addUser': () => import('./icons/common/addUser.svg'),
'common/monitor': () => import('./icons/common/monitor.svg'),
'common/list': () => import('./icons/common/list.svg'),
'common/addCircleLight': () => import('./icons/common/addCircleLight.svg'),
'common/addLight': () => import('./icons/common/addLight.svg'),
'common/backFill': () => import('./icons/common/backFill.svg'),
@@ -37,8 +41,10 @@ export const iconPaths = {
'common/language/en': () => import('./icons/common/language/en.svg'),
'common/language/zh': () => import('./icons/common/language/zh.svg'),
'common/leftArrowLight': () => import('./icons/common/leftArrowLight.svg'),
'common/arrowLeft': () => import('./icons/common/arrowLeft.svg'),
'common/lineChange': () => import('./icons/common/lineChange.svg'),
'common/linkBlue': () => import('./icons/common/linkBlue.svg'),
'common/folderImport': () => import('./icons/common/folderImport.svg'),
'common/loading': () => import('./icons/common/loading.svg'),
'common/logLight': () => import('./icons/common/logLight.svg'),
'common/navbar/pluginFill': () => import('./icons/common/navbar/pluginFill.svg'),

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" >
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.2293 4.81275C11.2293 6.59622 9.78352 8.04201 8.00005 8.04201C6.21658 8.04201 4.77079 6.59622 4.77079 4.81275C4.77079 3.02928 6.21658 1.5835 8.00005 1.5835C9.78352 1.5835 11.2293 3.02928 11.2293 4.81275ZM9.89598 4.81275C9.89598 5.85984 9.04714 6.70868 8.00005 6.70868C6.95296 6.70868 6.10413 5.85984 6.10413 4.81275C6.10413 3.76566 6.95296 2.91683 8.00005 2.91683C9.04714 2.91683 9.89598 3.76566 9.89598 4.81275Z" />
<path d="M2.40479 13.2218C2.40479 11.0126 4.19565 9.22177 6.40478 9.22177H8.84078C9.20897 9.22177 9.50745 9.52025 9.50745 9.88844C9.50745 10.2566 9.20897 10.5551 8.84078 10.5551H6.40478C5.01243 10.5551 3.8693 11.6222 3.74864 12.9832H8.84078C9.20897 12.9832 9.50745 13.2817 9.50745 13.6499C9.50745 14.0181 9.20897 14.3165 8.84078 14.3165H3.13812C2.73312 14.3165 2.40479 13.9882 2.40479 13.5832V13.2218Z" />
<path d="M13.1385 9.91359C13.1385 9.5454 12.8401 9.24693 12.4719 9.24693C12.1037 9.24693 11.8052 9.54541 11.8052 9.91359V11.165H10.5538C10.1856 11.165 9.88708 11.4635 9.88708 11.8317C9.88708 12.1999 10.1856 12.4984 10.5538 12.4984H11.8052V13.7498C11.8052 14.118 12.1037 14.4165 12.4719 14.4165C12.8401 14.4165 13.1385 14.118 13.1385 13.7498V12.4984H14.39C14.7582 12.4984 15.0567 12.1999 15.0567 11.8317C15.0567 11.4635 14.7582 11.165 14.39 11.165H13.1385V9.91359Z" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,3 @@
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.13807 3.52864C7.39842 3.78899 7.39842 4.2111 7.13807 4.47145L4.27614 7.33337H13.3333C13.7015 7.33337 14 7.63185 14 8.00004C14 8.36823 13.7015 8.66671 13.3333 8.66671H4.27614L7.13807 11.5286C7.39842 11.789 7.39842 12.2111 7.13807 12.4714C6.87772 12.7318 6.45561 12.7318 6.19526 12.4714L2.19526 8.47145C1.93491 8.2111 1.93491 7.78899 2.19526 7.52864L6.19526 3.52864C6.45561 3.26829 6.87772 3.26829 7.13807 3.52864Z" />
</svg>

After

Width:  |  Height:  |  Size: 553 B

View File

@@ -0,0 +1,3 @@
<svg viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.8927 3.49903C7.81856 3.47346 7.71954 3.46368 7.16372 3.46368H4.49393C4.09037 3.46368 3.8328 3.46426 3.63748 3.48022C3.45092 3.49546 3.3881 3.52091 3.36204 3.53419C3.2403 3.59622 3.14133 3.69519 3.07931 3.81692C3.06603 3.84298 3.04058 3.9058 3.02533 4.09237C3.01205 4.25491 3.00942 4.46056 3.00891 4.7576H8.72855L8.49207 4.28464C8.24351 3.78751 8.19047 3.70331 8.13444 3.64844C8.06593 3.58133 7.98336 3.5303 7.8927 3.49903ZM10.4056 4.7576L9.83371 3.61382C9.82029 3.58697 9.80699 3.56028 9.79379 3.53377C9.6103 3.16543 9.44385 2.83129 9.18401 2.57681C8.95666 2.35413 8.68265 2.18478 8.38181 2.08102C8.03799 1.96243 7.6647 1.96298 7.25318 1.96359C7.22356 1.96363 7.19374 1.96368 7.16372 1.96368L4.46545 1.96367C4.0986 1.96366 3.7791 1.96365 3.51533 1.9852C3.23601 2.00802 2.95382 2.0587 2.68105 2.19768C2.27707 2.40352 1.94863 2.73196 1.7428 3.13594C1.60382 3.4087 1.55314 3.69089 1.53031 3.97022C1.50876 4.23398 1.50878 4.55348 1.50879 4.92033L1.50879 11.9643C1.50878 12.525 1.50877 12.9908 1.53983 13.371C1.57217 13.7668 1.64188 14.1352 1.81893 14.4827C2.09173 15.0181 2.52702 15.4534 3.06243 15.7262C3.4099 15.9032 3.77834 15.9729 4.17414 16.0053C4.55428 16.0363 5.02013 16.0363 5.58082 16.0363H12.9064C13.4671 16.0363 13.9329 16.0363 14.313 16.0053C14.7088 15.9729 15.0773 15.9032 15.4248 15.7262C15.9602 15.4534 16.3955 15.0181 16.6683 14.4827C16.8453 14.1352 16.915 13.7668 16.9474 13.371C16.9784 12.9908 16.9784 12.525 16.9784 11.9643V8.82963C16.9784 8.26893 16.9784 7.80308 16.9474 7.42295C16.915 7.02715 16.8453 6.6587 16.6683 6.31123C16.3955 5.77583 15.9602 5.34053 15.4248 5.06773C15.0773 4.89069 14.7088 4.82097 14.313 4.78864C13.9329 4.75758 13.4671 4.75759 12.9063 4.7576L10.4056 4.7576ZM9.92698 6.2576C9.93741 6.25782 9.94786 6.25782 9.95833 6.2576H12.8757C13.4748 6.2576 13.8791 6.25818 14.1909 6.28365C14.4939 6.30841 14.643 6.3529 14.7438 6.40424C14.9969 6.53323 15.2028 6.73906 15.3318 6.99222C15.3831 7.09299 15.4276 7.24206 15.4523 7.54509C15.4778 7.85689 15.4784 8.26115 15.4784 8.8603V11.9336C15.4784 12.5328 15.4778 12.937 15.4523 13.2488C15.4276 13.5519 15.3831 13.7009 15.3318 13.8017C15.2028 14.0549 14.9969 14.2607 14.7438 14.3897C14.643 14.441 14.4939 14.4855 14.1909 14.5103C13.8791 14.5357 13.4748 14.5363 12.8757 14.5363H5.6115C5.01234 14.5363 4.60808 14.5357 4.29629 14.5103C3.99325 14.4855 3.84418 14.441 3.74341 14.3897C3.49025 14.2607 3.28443 14.0549 3.15543 13.8017C3.10409 13.7009 3.05961 13.5519 3.03485 13.2488C3.00937 12.937 3.00879 12.5328 3.00879 11.9336V6.2576H9.92698ZM9.24359 7.55152C9.65781 7.55152 9.99359 7.8873 9.99359 8.30152V10.6817L10.8087 9.86663C11.1016 9.57373 11.5765 9.57373 11.8694 9.86663C12.1623 10.1595 12.1623 10.6344 11.8694 10.9273L9.77392 13.0227C9.48103 13.3156 9.00616 13.3156 8.71326 13.0227L6.61782 10.9273C6.32493 10.6344 6.32493 10.1595 6.61782 9.86663C6.91072 9.57373 7.38559 9.57373 7.67848 9.86663L8.49359 10.6817V8.30152C8.49359 7.8873 8.82938 7.55152 9.24359 7.55152Z" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,9 @@
<svg viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.27575 7.0869C2.80962 7.0869 3.24242 6.65411 3.24242 6.12023C3.24242 5.58636 2.80962 5.15356 2.27575 5.15356C1.74187 5.15356 1.30908 5.58636 1.30908 6.12023C1.30908 6.65411 1.74187 7.0869 2.27575 7.0869Z" />
<path d="M6.02288 5.2869C5.56264 5.2869 5.18954 5.65999 5.18954 6.12023C5.18954 6.58047 5.56264 6.95356 6.02288 6.95356H17.923C18.3832 6.95356 18.7563 6.58047 18.7563 6.12023C18.7563 5.65999 18.3832 5.2869 17.923 5.2869H6.02288Z" />
<path d="M5.18954 10C5.18954 9.53977 5.56264 9.16668 6.02288 9.16668H17.923C18.3832 9.16668 18.7563 9.53977 18.7563 10C18.7563 10.4602 18.3832 10.8333 17.923 10.8333H6.02288C5.56264 10.8333 5.18954 10.4602 5.18954 10Z" />
<path d="M2.27575 10.9667C2.80962 10.9667 3.24242 10.5339 3.24242 10C3.24242 9.46613 2.80962 9.03334 2.27575 9.03334C1.74187 9.03334 1.30908 9.46613 1.30908 10C1.30908 10.5339 1.74187 10.9667 2.27575 10.9667Z" />
<path d="M5.18954 13.88C5.18954 13.4198 5.56264 13.0467 6.02288 13.0467H17.923C18.3832 13.0467 18.7563 13.4198 18.7563 13.88C18.7563 14.3402 18.3832 14.7133 17.923 14.7133H6.02288C5.56264 14.7133 5.18954 14.3402 5.18954 13.88Z" />
<path d="M2.27575 14.8467C2.80962 14.8467 3.24242 14.4139 3.24242 13.88C3.24242 13.3461 2.80962 12.9133 2.27575 12.9133C1.74187 12.9133 1.30908 13.3461 1.30908 13.88C1.30908 14.4139 1.74187 14.8467 2.27575 14.8467Z" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" fill="none">
<path d="M2.3252 6.75C2.1127 6.75 1.93445 6.678 1.79045 6.534C1.64645 6.39 1.5747 6.212 1.5752 6V4.5C1.5752 4.0875 1.7222 3.73425 2.0162 3.44025C2.3102 3.14625 2.6632 2.9995 3.0752 3H15.0752C15.4877 3 15.8409 3.147 16.1349 3.441C16.4289 3.735 16.5757 4.088 16.5752 4.5V6C16.5752 6.2125 16.5032 6.39075 16.3592 6.53475C16.2152 6.67875 16.0372 6.7505 15.8252 6.75C15.6127 6.75 15.4344 6.678 15.2904 6.534C15.1464 6.39 15.0747 6.212 15.0752 6V4.5H3.0752V6C3.0752 6.2125 3.0032 6.39075 2.8592 6.53475C2.7152 6.67875 2.5372 6.7505 2.3252 6.75ZM3.0752 15C2.6627 15 2.30945 14.853 2.01545 14.559C1.72145 14.265 1.5747 13.912 1.5752 13.5V12C1.5752 11.7875 1.6472 11.6093 1.7912 11.4653C1.9352 11.3213 2.1132 11.2495 2.3252 11.25C2.5377 11.25 2.71595 11.322 2.85995 11.466C3.00395 11.61 3.0757 11.788 3.0752 12V13.5H15.0752V12C15.0752 11.7875 15.1472 11.6093 15.2912 11.4653C15.4352 11.3213 15.6132 11.2495 15.8252 11.25C16.0377 11.25 16.2159 11.322 16.3599 11.466C16.5039 11.61 16.5757 11.788 16.5752 12V13.5C16.5752 13.9125 16.4282 14.2658 16.1342 14.5598C15.8402 14.8538 15.4872 15.0005 15.0752 15H3.0752ZM7.5752 12.75C7.7127 12.75 7.84395 12.7155 7.96895 12.6465C8.09395 12.5775 8.1877 12.4745 8.2502 12.3375L10.5752 7.6875L11.4002 9.3375C11.4627 9.475 11.5564 9.57825 11.6814 9.64725C11.8064 9.71625 11.9377 9.7505 12.0752 9.75H15.8252C16.0377 9.75 16.2159 9.678 16.3599 9.534C16.5039 9.39 16.5757 9.212 16.5752 9C16.5752 8.7875 16.5032 8.60925 16.3592 8.46525C16.2152 8.32125 16.0372 8.2495 15.8252 8.25H12.5439L11.2502 5.6625C11.1127 5.4125 10.8877 5.2875 10.5752 5.2875C10.2627 5.2875 10.0377 5.4125 9.9002 5.6625L7.5752 10.3125L6.7502 8.6625C6.6877 8.525 6.59395 8.42175 6.46895 8.35275C6.34395 8.28375 6.2127 8.2495 6.0752 8.25H2.3252C2.1127 8.25 1.93445 8.322 1.79045 8.466C1.64645 8.61 1.5747 8.788 1.5752 9C1.5752 9.2125 1.6472 9.39075 1.7912 9.53475C1.9352 9.67875 2.1132 9.7505 2.3252 9.75H5.60645L6.9002 12.3375C6.9627 12.475 7.05645 12.5783 7.18145 12.6473C7.30645 12.7163 7.4377 12.7505 7.5752 12.75Z" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -9,6 +9,7 @@ type Props<ValueType = string> = Omit<GridProps, 'onChange'> & {
value: ValueType;
size?: 'sm' | 'md' | 'lg';
inlineStyles?: FlexProps;
activatedColor?: string;
onChange: (value: ValueType) => void;
};
@@ -16,6 +17,7 @@ const LightRowTabs = <ValueType = string,>({
list,
size = 'md',
value,
activatedColor = 'primary.600',
onChange,
inlineStyles,
...props
@@ -64,13 +66,12 @@ const LightRowTabs = <ValueType = string,>({
borderBottom={'2px solid transparent'}
px={3}
whiteSpace={'nowrap'}
{...inlineStyles}
{...(value === item.value
? {
color: 'primary.600',
color: activatedColor,
cursor: 'default',
fontWeight: 'bold',
borderBottomColor: 'primary.600'
borderBottomColor: activatedColor
}
: {
cursor: 'pointer'
@@ -79,13 +80,14 @@ const LightRowTabs = <ValueType = string,>({
if (value === item.value) return;
onChange(item.value);
}}
{...inlineStyles}
>
{item.icon && (
<>
<Avatar src={item.icon} alt={''} w={'1.25rem'} borderRadius={'sm'} />
<Avatar src={item.icon} alt={''} w={'1.25rem'} borderRadius={'sm'} mr={1} />
</>
)}
<Box ml={1}>{typeof item.label === 'string' ? t(item.label as any) : item.label}</Box>
<Box>{typeof item.label === 'string' ? t(item.label as any) : item.label}</Box>
</Flex>
))}
</Grid>

View File

@@ -221,6 +221,7 @@
"Select Avatar": "Click to select avatar",
"Select Failed": "Select avatar failed"
},
"base_config": "Basic configuration",
"choosable": "Choosable",
"confirm": {
"Common Tip": "Operation confirmation"
@@ -782,7 +783,8 @@
"QA mode": "Question and answer split",
"Vector queue": "Index queue",
"Waiting": "Estimated 5 minutes",
"Website Sync": "Web site sync"
"Website Sync": "Web site sync",
"tag": "queue situation"
},
"website": {
"Base Url": "Base URL",

View File

@@ -119,6 +119,7 @@
"Cancel": "取消",
"Choose": "选择",
"Close": "关闭",
"base_config": "基础配置",
"Config": "配置",
"Confirm": "确认",
"Confirm Create": "确认创建",
@@ -638,8 +639,7 @@
"success": "开始同步"
}
},
"training": {
}
"training": {}
},
"data": {
"Auxiliary Data": "辅助数据",
@@ -775,6 +775,7 @@
"test result tip": "根据知识库内容与测试文本的相似度进行排序,你可以根据测试结果调整对应的文本。\n注意测试记录中的数据可能已经被修改过点击某条测试数据后将展示最新的数据。"
},
"training": {
"tag": "排队情况",
"Agent queue": "QA 训练排队",
"Auto mode": "增强处理(实验)",
"Auto mode Tip": "通过子索引以及调用模型生成相关问题与摘要,来增加数据块的语义丰富度,更利于检索。需要消耗更多的存储空间和增加 AI 调用次数。",

View File

@@ -85,7 +85,7 @@ const EditResourceModal = ({
w={'2rem'}
h={'2rem'}
cursor={'pointer'}
borderRadius={'md'}
borderRadius={'sm'}
onClick={onOpenSelectFile}
/>
</MyTooltip>

View File

@@ -15,9 +15,10 @@ const DatasetTypeTag = ({ type, ...props }: { type: `${DatasetTypeEnum}` } & Fle
bg={'myGray.100'}
borderWidth={'1px'}
borderColor={'myGray.200'}
px={4}
py={'6px'}
borderRadius={'md'}
px={3}
py={1.5}
h={'1.75rem'}
borderRadius={'sm'}
fontSize={'xs'}
alignItems={'center'}
{...props}

View File

@@ -1,4 +1,4 @@
import { Box, BoxProps } from '@chakra-ui/react';
import { Box, BoxProps, ButtonProps } from '@chakra-ui/react';
import MySelect from '@fastgpt/web/components/common/MySelect';
import React from 'react';
import type { PermissionValueType } from '@fastgpt/global/support/permission/type';
@@ -20,6 +20,7 @@ type Props = Omit<BoxProps, 'onChange'> & {
writePer?: PermissionValueType;
onChange: (v: PermissionValueType) => Promise<any> | any;
isInheritPermission?: boolean;
isDisabled?: boolean;
hasParent?: boolean;
};
@@ -31,6 +32,7 @@ const DefaultPermissionList = ({
onChange,
isInheritPermission = false,
hasParent,
isDisabled = false,
...styles
}: Props) => {
const { ConfirmModal, openConfirm } = useConfirm({});
@@ -63,6 +65,8 @@ const DefaultPermissionList = ({
return onRequestChange(per);
}
}}
isDisabled={isDisabled}
fontSize={styles?.fontSize}
/>
</Box>
<ConfirmModal />

View File

@@ -1,4 +1,4 @@
import { Box, Button, Flex } from '@chakra-ui/react';
import { Box, Button, Flex, FormLabel } from '@chakra-ui/react';
import React from 'react';
import CollaboratorContextProvider, {
MemberManagerInputPropsType
@@ -9,29 +9,38 @@ import { useTranslation } from 'next-i18next';
function MemberManager({ managePer }: { managePer: MemberManagerInputPropsType }) {
const { t } = useTranslation();
return (
<Box mt={4}>
<Box>
<CollaboratorContextProvider {...managePer}>
{({ MemberListCard, onOpenManageModal, onOpenAddMember }) => {
return (
<>
<Flex alignItems="center" flexDirection="row" justifyContent="space-between" w="full">
<Flex flexDirection="row" gap="2">
<Button
size="sm"
variant="whitePrimary"
leftIcon={<MyIcon w="4" name="common/settingLight" />}
onClick={onOpenManageModal}
>
{t('common:permission.Manage')}
</Button>
<Button
size="sm"
variant="whitePrimary"
leftIcon={<MyIcon w="4" name="support/permission/collaborator" />}
onClick={onOpenAddMember}
>
{t('common:common.Add')}
</Button>
<Box>
<FormLabel fontSize={'mini'}>{t('common:permission.Collaborator')}</FormLabel>
</Box>
<Flex gap={0.5}>
<Box p={1}>
<MyIcon
onClick={onOpenManageModal}
name="common/setting"
w={'1rem'}
h={'1rem'}
color={'myGray.600'}
cursor={'pointer'}
_hover={{ color: 'primary.500' }}
/>
</Box>
<Box p={1}>
<MyIcon
cursor={'pointer'}
onClick={onOpenAddMember}
name="common/addUser"
_hover={{ color: 'primary.500' }}
w={'1rem'}
h={'1rem'}
color={'myGray.600'}
/>
</Box>
</Flex>
</Flex>
<MemberListCard mt={2} p={1.5} bg="myGray.100" borderRadius="md" />

View File

@@ -39,6 +39,7 @@ const FileSourceSelector = dynamic(() => import('../Import/components/FileSource
const Header = ({}: {}) => {
const { t } = useTranslation();
const theme = useTheme();
const { setLoading, feConfigs } = useSystemStore();
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
@@ -110,35 +111,43 @@ const Header = ({}: {}) => {
successToast: t('common:common.Create Success'),
errorToast: t('common:common.Create Failed')
});
const isWebSite = datasetDetail?.type === DatasetTypeEnum.websiteDataset;
return (
<Flex px={[2, 6]} alignItems={'flex-start'} h={'35px'}>
<Box flex={1}>
<Box flex={1} fontWeight={'500'} color={'myGray.900'} h={'100%'}>
<ParentPath
paths={paths.map((path, i) => ({
parentId: path.parentId,
parentName: i === paths.length - 1 ? `${path.parentName}` : path.parentName
}))}
FirstPathDom={
<>
<Box fontWeight={'bold'} fontSize={['sm', 'md']}>
<Flex
flexDir={'column'}
justify={'center'}
h={'100%'}
fontSize={isWebSite ? 'sm' : 'md'}
fontWeight={'500'}
color={'myGray.600'}
>
<Flex align={'center'}>
{!isWebSite && <MyIcon name="common/list" mr={2} w={'20px'} color={'black'} />}
{t(DatasetTypeMap[datasetDetail?.type]?.collectionLabel as any)}({total})
</Box>
</Flex>
{datasetDetail?.websiteConfig?.url && (
<Flex fontSize={'sm'}>
<Flex fontSize={'mini'}>
{t('common:core.dataset.website.Base Url')}:
<Link
href={datasetDetail.websiteConfig.url}
target="_blank"
mr={2}
textDecoration={'underline'}
color={'primary.600'}
color={'blue.700'}
>
{datasetDetail.websiteConfig.url}
</Link>
</Flex>
)}
</>
</Flex>
}
onClick={(e) => {
router.replace({
@@ -202,18 +211,26 @@ const Header = ({}: {}) => {
fontSize={['sm', 'md']}
>
<Flex
alignItems={'center'}
px={5}
px={3.5}
py={2}
borderRadius={'md'}
borderRadius={'sm'}
cursor={'pointer'}
bg={'primary.500'}
overflow={'hidden'}
color={'white'}
h={['28px', '35px']}
>
<MyIcon name={'common/importLight'} mr={2} w={'14px'} />
<Box>{t('common:dataset.collections.Create And Import')}</Box>
<Flex h={'20px'} alignItems={'center'}>
<MyIcon
name={'common/folderImport'}
mr={2}
w={'18px'}
h={'18px'}
color={'white'}
/>
</Flex>
<Box h={'20px'} fontSize={'sm'} fontWeight={'500'}>
{t('common:dataset.collections.Create And Import')}
</Box>
</Flex>
</MenuButton>
}
@@ -323,18 +340,26 @@ const Header = ({}: {}) => {
fontSize={['sm', 'md']}
>
<Flex
alignItems={'center'}
px={5}
px={3.5}
py={2}
borderRadius={'md'}
borderRadius={'sm'}
cursor={'pointer'}
bg={'primary.500'}
overflow={'hidden'}
color={'white'}
h={['28px', '35px']}
>
<MyIcon name={'common/importLight'} mr={2} w={'14px'} />
<Box>{t('common:dataset.collections.Create And Import')}</Box>
<Flex h={'20px'} alignItems={'center'}>
<MyIcon
name={'common/folderImport'}
mr={2}
w={'18px'}
h={'18px'}
color={'white'}
/>
</Flex>
<Box h={'20px'} fontSize={'sm'} fontWeight={'500'}>
{t('common:dataset.collections.Create And Import')}
</Box>
</Flex>
</MenuButton>
}

View File

@@ -121,7 +121,7 @@ const HeaderTagPopOver = () => {
<Input
pl={2}
h={8}
borderRadius={'4px'}
borderRadius={'xs'}
value={searchTag}
placeholder={t('dataset:tag.searchOrAddTag')}
onChange={(e) => setSearchTag(e.target.value)}

View File

@@ -246,7 +246,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
flex={'1'}
_hover={{ bg: 'myGray.100' }}
alignItems={'center'}
borderRadius={'4px'}
borderRadius={'xs'}
>
<Flex
flex={'1 0 0'}
@@ -263,7 +263,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
bg={'#DBF3FF'}
color={'#0884DD'}
fontSize={'xs'}
borderRadius={'6px'}
borderRadius={'sm'}
>
{item.tag}
</Box>
@@ -299,7 +299,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
_hover={{ bg: '#1118240D' }}
mr={2}
p={1}
borderRadius={'6px'}
borderRadius={'sm'}
onClick={() => {
setCurrentAddTag({ ...item, collections });
}}
@@ -313,7 +313,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
_hover={{ bg: '#1118240D' }}
mr={2}
p={1}
borderRadius={'6px'}
borderRadius={'sm'}
cursor={'pointer'}
onClick={(e) => {
setCurrentEditTag(item);
@@ -332,7 +332,7 @@ const TagManageModal = ({ onClose }: { onClose: () => void }) => {
display="none"
_hover={{ bg: '#1118240D' }}
p={1}
borderRadius={'6px'}
borderRadius={'sm'}
cursor={'pointer'}
>
<MyIcon name="delete" w={4} />
@@ -441,7 +441,7 @@ const AddTagToCollections = ({
bg={'#DBF3FF'}
color={'#0884DD'}
fontSize={'sm'}
borderRadius={'6px'}
borderRadius={'sm'}
>
{currentAddTag.tag}
</Box>
@@ -496,7 +496,7 @@ const AddTagToCollections = ({
: {})
}}
alignItems={'center'}
borderRadius={'4px'}
borderRadius={'xs'}
key={collection.id}
cursor={'pointer'}
onClick={() => {
@@ -525,7 +525,7 @@ const AddTagToCollections = ({
isChecked={selectedCollections.includes(collection.id)}
/>
<MyIcon name={collection.icon as any} w={'20px'} mr={2} />
<Box fontSize={'14px'} borderRadius={'6px'} color={'myGray.900'}>
<Box fontSize={'sm'} borderRadius={'sm'} color={'myGray.900'}>
{collection.name}
</Box>
</Flex>

View File

@@ -161,7 +161,7 @@ const TagsPopOver = ({
fontWeight={'500'}
bg={'#F0FBFF'}
color={'#0884DD'}
borderRadius={'4px'}
borderRadius={'xs'}
>
{item.tag}
</Box>
@@ -197,7 +197,7 @@ const TagsPopOver = ({
onBlur={() => setIsFocusInput(false)}
pl={2}
h={7}
borderRadius={'4px'}
borderRadius={'xs'}
value={searchTag}
placeholder={t('dataset:tag.searchOrAddTag')}
onChange={(e) => setSearchTag(e.target.value)}
@@ -217,7 +217,7 @@ const TagsPopOver = ({
// setCheckedTags([...checkedTags, item]);
}}
>
<MyIcon name={'common/addLight'} w={'14px'} />
<MyIcon name={'common/addLight'} w={'sm'} />
<Box ml={1} py={1}>
{t('dataset:tag.add') + ` "${searchTag}"`}
</Box>
@@ -277,7 +277,7 @@ const TagsPopOver = ({
fontSize={'11px'}
bg={'#F0FBFF'}
color={'#0884DD'}
borderRadius={'4px'}
borderRadius={'xs'}
>
{tag.tag}
</Box>

View File

@@ -186,12 +186,12 @@ const CollectionCard = () => {
return (
<MyBox isLoading={isLoading} h={'100%'} py={[2, 4]}>
<Flex ref={BoxRef} flexDirection={'column'} py={[1, 3]} h={'100%'}>
<Flex ref={BoxRef} flexDirection={'column'} py={[1, 0]} h={'100%'}>
{/* header */}
<Header />
{/* collection table */}
<TableContainer px={[2, 6]} mt={[0, 3]} flex={'1 0 0'} overflowY={'auto'} fontSize={'sm'}>
<TableContainer px={[2, 6]} mt={[0, 3]} overflowY={'auto'} fontSize={'sm'}>
<Table variant={'simple'} draggable={false}>
<Thead draggable={false}>
<Tr>

View File

@@ -7,12 +7,6 @@ import {
Grid,
Button,
useTheme,
Drawer,
DrawerBody,
DrawerFooter,
DrawerHeader,
DrawerOverlay,
DrawerContent,
useDisclosure,
HStack
} from '@chakra-ui/react';
@@ -52,6 +46,8 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
import TagsPopOver from './CollectionCard/TagsPopOver';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import MyDivider from '@fastgpt/web/components/common/MyDivider';
import index from '../../../index';
const DataCard = () => {
const BoxRef = useRef<HTMLDivElement>(null);
@@ -67,7 +63,6 @@ const DataCard = () => {
const { feConfigs } = useSystemStore();
const { t } = useTranslation();
const { datasetT } = useI18n();
const [searchText, setSearchText] = useState('');
const { toast } = useToast();
const { openConfirm, ConfirmModal } = useConfirm({
@@ -132,66 +127,6 @@ const DataCard = () => {
const canWrite = useMemo(() => datasetDetail.permission.hasWritePer, [datasetDetail]);
const metadataList = useMemo(() => {
if (!collection) return [];
const webSelector =
collection?.datasetId?.websiteConfig?.selector || collection?.metadata?.webPageSelector;
return [
{
label: t('common:core.dataset.collection.metadata.source'),
value: t(DatasetCollectionTypeMap[collection.type]?.name as any)
},
{
label: t('common:core.dataset.collection.metadata.source name'),
value: collection.file?.filename || collection?.rawLink || collection?.name
},
{
label: t('common:core.dataset.collection.metadata.source size'),
value: collection.file ? formatFileSize(collection.file.length) : '-'
},
{
label: t('common:core.dataset.collection.metadata.Createtime'),
value: formatTime2YMDHM(collection.createTime)
},
{
label: t('common:core.dataset.collection.metadata.Updatetime'),
value: formatTime2YMDHM(collection.updateTime)
},
{
label: t('common:core.dataset.collection.metadata.Raw text length'),
value: collection.rawTextLength ?? '-'
},
{
label: t('common:core.dataset.collection.metadata.Training Type'),
value: t(TrainingTypeMap[collection.trainingType]?.label as any)
},
{
label: t('common:core.dataset.collection.metadata.Chunk Size'),
value: collection.chunkSize || '-'
},
...(webSelector
? [
{
label: t('common:core.dataset.collection.metadata.Web page selector'),
value: webSelector
}
]
: []),
{
...(collection.tags
? [
{
label: datasetT('collection_tags'),
value: collection.tags?.join(', ') || '-'
}
]
: [])
}
];
}, [collection, datasetT, t]);
const { run: onUpdate, loading } = useRequest2(putDatasetDataById, {
onSuccess() {
getData(pageNum);
@@ -205,23 +140,6 @@ const DataCard = () => {
<Flex ref={BoxRef} flexDirection={'column'} h={'100%'}>
{/* Header */}
<Flex alignItems={'center'} px={5}>
<IconButton
mr={3}
icon={<MyIcon name={'common/backFill'} w={['14px', '18px']} color={'primary.500'} />}
variant={'whitePrimary'}
size={'smSquare'}
borderRadius={'50%'}
aria-label={''}
onClick={() =>
router.replace({
query: {
datasetId: router.query.datasetId,
parentId: router.query.parentId,
currentTab: TabEnum.collectionCard
}
})
}
/>
<Flex className="textEllipsis" flex={'1 0 0'} mr={[3, 5]} alignItems={'center'}>
<Box>
<Box alignItems={'center'} gap={2} display={isPc ? 'flex' : ''}>
@@ -234,12 +152,6 @@ const DataCard = () => {
textDecoration={'none'}
/>
)}
<Box fontSize={'sm'} color={'myGray.500'}>
{t('common:core.dataset.collection.id')}:{' '}
<Box as={'span'} userSelect={'all'}>
{collection?._id}
</Box>
</Box>
</Box>
{feConfigs?.isPlus && !!collection?.tags?.length && (
<TagsPopOver currentCollection={collection} />
@@ -250,7 +162,6 @@ const DataCard = () => {
<Box>
<Button
ml={2}
mr={isPc ? 2 : 0}
variant={'whitePrimary'}
size={['sm', 'md']}
onClick={() => {
@@ -262,24 +173,17 @@ const DataCard = () => {
</Button>
</Box>
)}
{isPc && (
<MyTooltip label={t('common:core.dataset.collection.metadata.Read Metadata')}>
<IconButton
variant={'whiteBase'}
size={['sm', 'md']}
icon={<MyIcon name={'menu'} w={'18px'} />}
aria-label={''}
onClick={onOpen}
/>
</MyTooltip>
)}
</Flex>
<Flex my={3} alignItems={'center'} px={5}>
<Box>
<Box as={'span'} fontSize={['sm', 'md']}>
<Box justifyContent={'center'} px={5} pos={'relative'} w={'100%'}>
<MyDivider my={'17px'} w={'100%'} />
</Box>
<Flex alignItems={'center'} px={5} pb={4}>
<Flex align={'center'} color={'myGray.500'}>
<MyIcon name="common/list" mr={2} w={'18px'} />
<Box as={'span'} fontSize={['sm', '14px']} fontWeight={'500'}>
{t('core.dataset.data.Total Amount', { total })}
</Box>
</Box>
</Flex>
<Box flex={1} mr={1} />
<MyInput
leftIcon={
@@ -287,9 +191,12 @@ const DataCard = () => {
name="common/searchLight"
position={'absolute'}
w={'14px'}
color={'myGray.500'}
color={'myGray.600'}
/>
}
bg={'myGray.25'}
borderColor={'myGray.200'}
color={'myGray.500'}
w={['200px', '300px']}
placeholder={t('common:core.dataset.data.Search data placeholder')}
value={searchText}
@@ -300,45 +207,59 @@ const DataCard = () => {
</Flex>
{/* data */}
<Box flex={'1 0 0'} overflow={'auto'} px={5}>
<Grid
gridTemplateColumns={['1fr', 'repeat(2,1fr)', 'repeat(3,1fr)', 'repeat(4,1fr)']}
gridGap={4}
>
{datasetDataList.map((item) => (
<Flex flexDir={'column'} gap={2}>
{datasetDataList.map((item, index) => (
<Card
key={item._id}
cursor={'pointer'}
p={3}
userSelect={'none'}
boxShadow={'none'}
bg={'myWhite.500'}
bg={index % 2 === 1 ? 'myGray.50' : 'blue.50'}
border={theme.borders.sm}
position={'relative'}
overflow={'hidden'}
_hover={{
borderColor: 'myGray.200',
borderColor: 'blue.600',
boxShadow: 'lg',
bg: 'white',
'& .footer': { h: 'auto', p: 3 },
'& .forbid-switch': { display: 'flex' }
'& .header': { visibility: 'visible' },
'& .footer': { visibility: 'visible' },
'& .forbid-switch': { display: 'flex' },
bg: index % 2 === 1 ? 'myGray.200' : 'blue.100'
}}
onClick={() => {
if (!collection) return;
setEditDataId(item._id);
}}
>
<Flex zIndex={1} alignItems={'center'}>
<MyTag type="borderFill"># {item.chunkIndex ?? '-'}</MyTag>
<Box
className={'textEllipsis'}
flex={'1 0 0'}
w="0"
fontSize={'mini'}
textAlign={'right'}
<Flex
position={'absolute'}
zIndex={1}
alignItems={'center'}
visibility={'hidden'}
className="header"
>
<MyTag
px={2}
type="borderFill"
borderRadius={'sm'}
border={'1px'}
color={'myGray.200'}
bg={'white'}
fontWeight={'500'}
>
ID:{item._id}
</Box>
<Box color={'blue.600'}>#{item.chunkIndex ?? '-'} </Box>
<Box
ml={1.5}
className={'textEllipsis'}
fontSize={'mini'}
textAlign={'right'}
color={'myGray.500'}
>
ID:{item._id}
</Box>
</MyTag>
{/* {item.forbid ? (
<MyTag colorSchema="gray" bg={'transparent'} px={1} showDot>
{datasetT('Disabled')}
@@ -390,54 +311,69 @@ const DataCard = () => {
<Flex
className="footer"
position={'absolute'}
top={0}
bottom={0}
left={0}
right={0}
h={'0'}
bottom={2}
right={2}
overflow={'hidden'}
bg={'linear-gradient(to top, white,white 20%, rgba(255,255,255,0) 60%)'}
alignItems={'flex-end'}
visibility={'hidden'}
fontSize={'mini'}
>
<HStack p={0} flex={1}>
<Flex alignItems={'center'}>
<MyIcon name="common/text/t" w={'0.8rem'} mr={1} color={'myGray.500'} />
<Box>{item.q.length + (item.a?.length || 0)}</Box>
</Flex>
<Box flex={1}></Box>
{/* <Box className={'textEllipsis'} flex={'1 0 0'} w="0">
ID:{item._id}
</Box> */}
{canWrite && (
<IconButton
display={'flex'}
icon={<DeleteIcon />}
variant={'whiteDanger'}
size={'xsSquare'}
aria-label={'delete'}
onClick={(e) => {
e.stopPropagation();
openConfirm(async () => {
try {
await delOneDatasetDataById(item._id);
getData(pageNum);
} catch (error) {
toast({
title: getErrText(error),
status: 'error'
});
}
})();
}}
/>
)}
</HStack>
<Flex
alignItems={'center'}
bg={'white'}
color={'myGray.600'}
borderRadius={'sm'}
border={'1px'}
borderColor={'myGray.200'}
h={'24px'}
px={2}
fontSize={'mini'}
boxShadow={'1'}
py={1}
mr={2}
>
<MyIcon
bg={'white'}
color={'myGray.600'}
borderRadius={'sm'}
border={'1px'}
borderColor={'myGray.200'}
name="common/text/t"
w={'14px'}
mr={1}
/>
{item.q.length + (item.a?.length || 0)}
</Flex>
{canWrite && (
<IconButton
display={'flex'}
p={1}
boxShadow={'1'}
icon={<MyIcon name={'common/trash'} w={'14px'} color={'myGray.600'} />}
variant={'whiteDanger'}
size={'xsSquare'}
aria-label={'delete'}
onClick={(e) => {
e.stopPropagation();
openConfirm(async () => {
try {
await delOneDatasetDataById(item._id);
getData(pageNum);
} catch (error) {
toast({
title: getErrText(error),
status: 'error'
});
}
})();
}}
/>
)}
</Flex>
</Box>
</Card>
))}
</Grid>
</Flex>
{total > pageSize && (
<Flex mt={2} justifyContent={'center'}>
<Pagination />
@@ -447,38 +383,6 @@ const DataCard = () => {
</Box>
</Flex>
{/* metadata drawer */}
<Drawer isOpen={isOpen} placement="right" size={'md'} onClose={onClose}>
<DrawerOverlay />
<DrawerContent>
<DrawerHeader fontSize={'lg'}>
{t('common:core.dataset.collection.metadata.metadata')}
</DrawerHeader>
<DrawerBody>
{metadataList.map((item, i) => (
<Flex key={i} alignItems={'center'} mb={5} wordBreak={'break-all'} fontSize={'sm'}>
<Box color={'myGray.500'} flex={'0 0 100px'}>
{item.label}
</Box>
<Box>{item.value}</Box>
</Flex>
))}
{collection?.sourceId && (
<Button variant={'whitePrimary'} onClick={readSource}>
{t('common:core.dataset.collection.metadata.read source')}
</Button>
)}
</DrawerBody>
<DrawerFooter>
<Button variant={'whitePrimary'} onClick={onClose}>
{t('common:common.Close')}
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
{editDataId !== undefined && collection && (
<InputDataModal
collectionId={collection._id}

View File

@@ -6,7 +6,7 @@ import { ImportDataSourceEnum, TrainingModeEnum } from '@fastgpt/global/core/dat
import { useMyStep } from '@fastgpt/web/hooks/useStep';
import { Box, Button, Flex, IconButton } from '@chakra-ui/react';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { TabEnum } from '../Slider';
import { TabEnum } from '../NavBar';
import { ImportProcessWayEnum } from '@/web/core/dataset/constants';
import { UseFormReturn, useForm } from 'react-hook-form';
import { ImportSourceItemType } from '@/web/core/dataset/type';

View File

@@ -272,7 +272,7 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
<Box mt={5} pl={[0, '100px']} gap={3}>
{feConfigs?.show_pay && (
<MyTooltip label={priceTip}>
<MyTag colorSchema={'gray'} py={'6px'} borderRadius={'md'} px={3} whiteSpace={'wrap'}>
<MyTag colorSchema={'gray'} py={1.5} borderRadius={'md'} px={3} whiteSpace={'wrap'}>
{priceTip}
</MyTag>
</MyTooltip>

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { useRouter } from 'next/router';
import { Box, Flex, Button, IconButton, Input, Textarea, HStack } from '@chakra-ui/react';
import { DeleteIcon } from '@chakra-ui/icons';
@@ -16,15 +16,15 @@ import { useRequest } from '@fastgpt/web/hooks/useRequest';
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
import AIModelSelector from '@/components/Select/AIModelSelector';
import { postRebuildEmbedding } from '@/web/core/dataset/api';
import { useI18n } from '@/web/context/I18n';
import type { VectorModelItemType } from '@fastgpt/global/core/ai/model.d';
import { useContextSelector } from 'use-context-selector';
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
import MyDivider from '@fastgpt/web/components/common/MyDivider/index';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { DatasetTypeEnum, DatasetTypeMap } from '@fastgpt/global/core/dataset/constants';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
import DefaultPermissionList from '@/components/support/permission/DefaultPerList';
import MyIcon from '@fastgpt/web/components/common/Icon';
import {
DatasetDefaultPermissionVal,
DatasetPermissionList
@@ -35,18 +35,23 @@ import {
postUpdateDatasetCollaborators,
deleteDatasetCollaborators
} from '@/web/core/dataset/api/collaborator';
import DatasetTypeTag from '@/components/core/dataset/DatasetTypeTag';
import dynamic from 'next/dynamic';
import { EditResourceInfoFormType } from '@/components/common/Modal/EditResourceModal';
const EditResourceModal = dynamic(() => import('@/components/common/Modal/EditResourceModal'));
const Info = ({ datasetId }: { datasetId: string }) => {
const router = useRouter();
const [openBaseConfig, setOpenBaseConfig] = useState(true);
const [openPermissionConfig, setOpenPermissionConfig] = useState(true);
const { t } = useTranslation();
const { datasetT, commonT } = useI18n();
const { datasetDetail, loadDatasetDetail, updateDataset, rebuildingCount, trainingCount } =
useContextSelector(DatasetPageContext, (v) => v);
const [editedDataset, setEditedDataset] = useState<EditResourceInfoFormType>();
const refetchDatasetTraining = useContextSelector(
DatasetPageContext,
(v) => v.refetchDatasetTraining
);
const { setValue, register, handleSubmit, watch } = useForm<DatasetItemType>({
defaultValues: datasetDetail
});
@@ -57,16 +62,13 @@ const Info = ({ datasetId }: { datasetId: string }) => {
const defaultPermission = watch('defaultPermission');
const { datasetModelList, vectorModelList } = useSystemStore();
const router = useRouter();
const { openConfirm: onOpenConfirmDel, ConfirmModal: ConfirmDelModal } = useConfirm({
content: t('common:core.dataset.Delete Confirm'),
type: 'delete'
});
const { openConfirm: onOpenConfirmRebuild, ConfirmModal: ConfirmRebuildModal } = useConfirm({
title: t('common:common.confirm.Common Tip'),
content: datasetT('confirm_to_rebuild_embedding_tip'),
content: t('dataset:confirm_to_rebuild_embedding_tip'),
type: 'delete'
});
@@ -87,13 +89,10 @@ const Info = ({ datasetId }: { datasetId: string }) => {
errorToast: t('common:common.Delete Failed')
});
const { mutate: onclickSave, isLoading: isSaving } = useRequest({
const { mutate: onSave, isLoading: isSaving } = useRequest({
mutationFn: (data: DatasetItemType) => {
return updateDataset({
id: datasetId,
name: data.name,
avatar: data.avatar,
intro: data.intro,
agentModel: data.agentModel,
externalReadUrl: data.externalReadUrl,
defaultPermission: data.defaultPermission
@@ -133,156 +132,191 @@ const Info = ({ datasetId }: { datasetId: string }) => {
refetchDatasetTraining();
loadDatasetDetail(datasetId);
},
successToast: datasetT('rebuild_embedding_start_tip'),
successToast: t('dataset:rebuild_embedding_start_tip'),
errorToast: t('common:common.Update Failed')
});
const btnLoading = isSelecting || isDeleting || isSaving || isRebuilding;
const totalLoading = isSelecting || isDeleting || isSaving || isRebuilding;
return (
<Box py={5} px={[5, 10]}>
<Flex mt={5} w={'100%'} alignItems={'center'}>
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
{t('common:core.dataset.Dataset ID')}
</FormLabel>
<Box flex={1}>{datasetDetail._id}</Box>
</Flex>
<Flex mt={8} w={'100%'} alignItems={'center'} flexWrap={'wrap'}>
<HStack flex={['0 0 90px', '0 0 160px']} w={0} spacing={1}>
<FormLabel>{t('common:core.ai.model.Vector Model')}</FormLabel>
<QuestionTip label={t('common:core.dataset.embedding model tip')} />
</HStack>
<Box flex={[1, '0 0 320px']}>
<AIModelSelector
w={'100%'}
value={vectorModel.model}
disableTip={
rebuildingCount > 0 || trainingCount > 0
? datasetT('the_knowledge_base_has_indexes_that_are_being_trained_or_being_rebuilt')
: undefined
<Box w={'100%'} h={'100%'} p={6}>
<Box>
<Flex mb={2} alignItems={'center'}>
<Avatar src={datasetDetail.avatar} w={'20px'} h={'20px'} borderRadius={'xs'} />
<Box ml={1.5}>
<Box fontWeight={'bold'} color={'myGray.900'}>
{datasetDetail.name}
</Box>
</Box>
<MyIcon
pl={1.5}
name={'edit'}
_hover={{ color: 'primary.600' }}
w={'0.875rem'}
cursor={'pointer'}
onClick={() =>
setEditedDataset({
id: datasetDetail._id,
name: datasetDetail.name,
avatar: datasetDetail.avatar,
intro: datasetDetail.intro
})
}
list={vectorModelList.map((item) => ({
label: item.name,
value: item.model
}))}
onchange={(e) => {
const vectorModel = vectorModelList.find((item) => item.model === e);
if (!vectorModel) return;
onOpenConfirmRebuild(() => {
setValue('vectorModel', vectorModel);
onRebuilding(vectorModel);
})();
}}
/>
</Box>
</Flex>
<Flex mt={8} w={'100%'} alignItems={'center'}>
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
{t('common:core.Max Token')}
</FormLabel>
<Box flex={[1, '0 0 320px']}>{vectorModel.maxToken}</Box>
</Flex>
<Flex mt={6} alignItems={'center'} flexWrap={'wrap'}>
<HStack flex={['0 0 90px', '0 0 160px']} w={0} spacing={1}>
<FormLabel>{t('common:core.ai.model.Dataset Agent Model')}</FormLabel>
<QuestionTip label={t('dataset:file_model_function_tip')} />
</HStack>
<Box flex={[1, '0 0 320px']}>
<AIModelSelector
w={'100%'}
value={agentModel.model}
list={datasetModelList.map((item) => ({
label: item.name,
value: item.model
}))}
onchange={(e) => {
const agentModel = datasetModelList.find((item) => item.model === e);
if (!agentModel) return;
setValue('agentModel', agentModel);
}}
/>
</Box>
</Flex>
<MyDivider my={6} h={'2px'} maxW={'500px'} />
{datasetDetail.type === DatasetTypeEnum.externalFile && (
<>
<Flex w={'100%'} alignItems={'center'}>
<FormLabel
display={'flex'}
flex={['0 0 90px', '0 0 160px']}
w={0}
gap={1}
alignItems={'center'}
>
<Box>{datasetT('external_read_url')}</Box>
<QuestionTip label={datasetT('external_read_url_tip')} />
</FormLabel>
<Input
flex={[1, '0 0 320px']}
placeholder="https://test.com/read?fileId={{fileId}}"
{...register('externalReadUrl')}
/>
</Flex>
{DatasetTypeMap[datasetDetail.type] && (
<Flex alignItems={'center'} justifyContent={'space-between'}>
<DatasetTypeTag type={datasetDetail.type} />
</Flex>
<MyDivider my={6} h={'2px'} maxW={'500px'} />
</>
)}
<Flex mt={5} w={'100%'} alignItems={'center'}>
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
{t('common:core.dataset.Avatar')}
</FormLabel>
<Box flex={[1, '0 0 320px']}>
<MyTooltip label={t('common:common.avatar.Select Avatar')}>
<Avatar
m={'auto'}
src={avatar}
w={['32px', '40px']}
h={['32px', '40px']}
cursor={'pointer'}
borderRadius={'md'}
onClick={onOpenSelectFile}
/>
</MyTooltip>
)}
<Box
flex={1}
className={'textEllipsis3'}
pt={3}
wordBreak={'break-all'}
fontSize={'xs'}
color={'myGray.500'}
>
{datasetDetail.intro || t('common:core.dataset.Intro Placeholder')}
</Box>
</Flex>
<Flex mt={8} w={'100%'} alignItems={'center'}>
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
{t('common:core.dataset.Name')}
</FormLabel>
<Input flex={[1, '0 0 320px']} maxLength={30} {...register('name')} />
</Flex>
<Flex mt={8} alignItems={'center'} w={'100%'}>
<FormLabel flex={['0 0 90px', '0 0 160px']}>{t('common:common.Intro')}</FormLabel>
<Textarea
flex={[1, '0 0 320px']}
{...register('intro')}
placeholder={t('common:common.Intro')}
/>
</Flex>
</Box>
<MyDivider my={4} h={'2px'} maxW={'500px'} />
<Box overflow={'hidden'} h={openBaseConfig ? 'auto' : '24px'}>
<Flex justify={'space-between'} alignItems={'center'} fontSize={'mini'} h={'24px'}>
<Box fontWeight={'500'} color={'myGray.900'}>
{t('common:common.base_config')}
</Box>
<MyIcon
w={'16px'}
_hover={{ color: 'primary.500', cursor: 'pointer' }}
color={'myGray.500'}
name={openBaseConfig ? 'core/chat/chevronUp' : 'core/chat/chevronDown'}
onClick={() => setOpenBaseConfig(!openBaseConfig)}
/>
</Flex>
<Flex mt={3} w={'100%'} flexDir={'column'}>
<FormLabel fontSize={'mini'}>{t('common:core.dataset.Dataset ID')}</FormLabel>
<Box fontSize={'mini'}>{datasetDetail._id}</Box>
</Flex>
<Box mt={5} w={'100%'}>
<FormLabel fontSize={'mini'}>{t('common:core.ai.model.Vector Model')}</FormLabel>
<Box pt={2} flex={[1, '0 0 320px']}>
<AIModelSelector
w={'100%'}
value={vectorModel.model}
fontSize={'mini'}
disableTip={
rebuildingCount > 0 || trainingCount > 0
? t(
'dataset:the_knowledge_base_has_indexes_that_are_being_trained_or_being_rebuilt'
)
: undefined
}
list={vectorModelList.map((item) => ({
label: item.name,
value: item.model
}))}
onchange={(e) => {
const vectorModel = vectorModelList.find((item) => item.model === e);
if (!vectorModel) return;
onOpenConfirmRebuild(() => {
setValue('vectorModel', vectorModel);
onRebuilding(vectorModel);
})();
}}
/>
</Box>
</Box>
<Flex mt={2} w={'100%'} alignItems={'center'}>
<FormLabel flex={['0 0 90px', '0 0 160px']} fontSize={'mini'} w={0}>
{t('common:core.Max Token')}
</FormLabel>
<Box flex={[1, '0 0 320px']} fontSize={'mini'}>
{vectorModel.maxToken}
</Box>
</Flex>
<Box pt={5}>
<FormLabel fontSize={'mini'}>{t('common:core.ai.model.Dataset Agent Model')}</FormLabel>
<Box pt={2}>
<AIModelSelector
w={'100%'}
value={agentModel.model}
list={datasetModelList.map((item) => ({
label: item.name,
value: item.model
}))}
fontSize={'mini'}
onchange={(e) => {
const agentModel = datasetModelList.find((item) => item.model === e);
if (!agentModel) return;
setValue('agentModel', agentModel);
handleSubmit((data) => onSave({ ...data, agentModel: agentModel }))();
}}
isDisabled={totalLoading}
/>
</Box>
</Box>
{/* <MyDivider my={4} h={'2px'} maxW={'500px'} /> */}
{datasetDetail.type === DatasetTypeEnum.externalFile && (
<>
<Box w={'100%'} alignItems={'center'} pt={4}>
<FormLabel display={'flex'} pb={2} fontSize={'mini'}>
<Box>{t('dataset:external_read_url')}</Box>
<QuestionTip label={t('dataset:external_read_url_tip')} />
</FormLabel>
<Input
fontSize={'mini'}
flex={[1, '0 0 320px']}
placeholder="https://test.com/read?fileId={{fileId}}"
{...register('externalReadUrl')}
onBlur={handleSubmit((data) => onSave(data))}
/>
</Box>
</>
)}
</Box>
{datasetDetail.permission.hasManagePer && (
<>
<MyDivider my={6} h={'2px'} maxW={'500px'} />
<MyDivider my={4} h={'2px'} maxW={'500px'} />
<Box overflow={'hidden'} h={openPermissionConfig ? 'auto' : '24px'}>
<Flex justify={'space-between'} alignItems={'center'} fontSize={'mini'} h={'24px'}>
<Box fontWeight={'500'} color={'myGray.900'}>
{t('common:permission.Permission config')}
</Box>
<MyIcon
w={'16px'}
_hover={{ color: 'primary.500', cursor: 'pointer' }}
color={'myGray.500'}
name={openPermissionConfig ? 'core/chat/chevronUp' : 'core/chat/chevronDown'}
onClick={() => setOpenPermissionConfig(!openPermissionConfig)}
/>
</Flex>
<Flex mt={5} alignItems={'center'} w={'100%'} flexWrap={'wrap'} maxW="500px">
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
{commonT('permission.Default permission')}
</FormLabel>
<DefaultPermissionList
w="320px"
per={defaultPermission}
defaultPer={DatasetDefaultPermissionVal}
onChange={(v) => setValue('defaultPermission', v)}
/>
</Flex>
<Box mt={3}>
<FormLabel fontSize={'mini'} pb={3}>
{t('common:permission.Default permission')}
</FormLabel>
<DefaultPermissionList
fontSize={'mini'}
per={defaultPermission}
defaultPer={DatasetDefaultPermissionVal}
isDisabled={totalLoading}
onChange={(v) => {
setValue('defaultPermission', v);
handleSubmit((data) => onSave({ ...data, defaultPermission: v }))();
}}
/>
</Box>
<Flex mt={5} alignItems={'center'} w={'100%'} flexWrap={'wrap'} maxW="500px">
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
{commonT('permission.Collaborator')}
</FormLabel>
<Box flex={1}>
<Box mt={4}>
<MemberManager
managePer={{
permission: datasetDetail.permission,
@@ -301,35 +335,31 @@ const Info = ({ datasetId }: { datasetId: string }) => {
}}
/>
</Box>
</Flex>
</Box>
</>
)}
<Flex mt={5} w={'100%'} alignItems={'flex-end'}>
<Box flex={['0 0 90px', '0 0 160px']} w={0}></Box>
<Button
isLoading={btnLoading}
mr={4}
w={'100px'}
onClick={handleSubmit((data) => onclickSave(data))}
>
{t('common:common.Save')}
</Button>
{datasetDetail.permission.isOwner && (
<IconButton
isLoading={btnLoading}
icon={<DeleteIcon />}
aria-label={''}
variant={'whiteDanger'}
size={'smSquare'}
onClick={onOpenConfirmDel(onclickDelete)}
/>
)}
</Flex>
<File onSelect={onSelectFile} />
<ConfirmDelModal />
<ConfirmRebuildModal countDown={10} />
{editedDataset && (
<EditResourceModal
{...editedDataset}
title={t('common:dataset.Edit Info')}
onClose={() => {
setEditedDataset(undefined);
}}
onEdit={async (data) => {
await updateDataset({
id: editedDataset.id,
name: data.name,
intro: data.intro,
avatar: data.avatar
});
setEditedDataset(undefined);
}}
/>
)}
</Box>
);
};

View File

@@ -0,0 +1,123 @@
import React, { useMemo, useState } from 'react';
import { Box, Flex, Button, IconButton, Input, Textarea, HStack } from '@chakra-ui/react';
import { DeleteIcon } from '@chakra-ui/icons';
import { useTranslation } from 'next-i18next';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { getDatasetCollectionById } from '@/web/core/dataset/api';
import { useRouter } from 'next/router';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { formatFileSize } from '@fastgpt/global/common/file/tools';
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';
const MetaDataCard = ({ datasetId }: { datasetId: string }) => {
const { t } = useTranslation();
const router = useRouter();
const { collectionId = '' } = router.query as {
collectionId: string;
datasetId: string;
};
const readSource = getCollectionSourceAndOpen(collectionId);
const { data: collection, loading: isLoading } = useRequest2(
() => getDatasetCollectionById(collectionId),
{
onError: () => {
router.replace({
query: {
datasetId
}
});
},
manual: false
}
);
const metadataList = useMemo(() => {
if (!collection) return [];
const webSelector =
collection?.datasetId?.websiteConfig?.selector || collection?.metadata?.webPageSelector;
return [
{
label: t('common:core.dataset.collection.metadata.source'),
value: t(DatasetCollectionTypeMap[collection.type]?.name as any)
},
{
label: t('common:core.dataset.collection.metadata.source name'),
value: collection.file?.filename || collection?.rawLink || collection?.name
},
{
label: t('common:core.dataset.collection.metadata.source size'),
value: collection.file ? formatFileSize(collection.file.length) : '-'
},
{
label: t('common:core.dataset.collection.metadata.Createtime'),
value: formatTime2YMDHM(collection.createTime)
},
{
label: t('common:core.dataset.collection.metadata.Updatetime'),
value: formatTime2YMDHM(collection.updateTime)
},
{
label: t('common:core.dataset.collection.metadata.Raw text length'),
value: collection.rawTextLength ?? '-'
},
{
label: t('common:core.dataset.collection.metadata.Training Type'),
value: t(TrainingTypeMap[collection.trainingType]?.label as any)
},
{
label: t('common:core.dataset.collection.metadata.Chunk Size'),
value: collection.chunkSize || '-'
},
...(webSelector
? [
{
label: t('common:core.dataset.collection.metadata.Web page selector'),
value: webSelector
}
]
: []),
{
...(collection.tags
? [
{
label: t('dataset:collection_tags'),
value: collection.tags?.join(', ') || '-'
}
]
: [])
}
];
}, [collection, t]);
return (
<MyBox isLoading={isLoading} w={'100%'} h={'100%'} p={6}>
<Box fontSize={'lg'} pb={4}>
{t('common:core.dataset.collection.metadata.metadata')}
</Box>
<Box fontSize={'sm'} color={'myGray.500'} mb={5}>
{t('common:core.dataset.collection.id')}:{' '}
<Box as={'span'} userSelect={'all'}>
{collection?._id}
</Box>
</Box>
{metadataList.map((item, i) => (
<Flex key={i} alignItems={'center'} mb={5} wordBreak={'break-all'} fontSize={'sm'}>
<Box color={'myGray.500'} flex={'0 0 100px'}>
{item.label}
</Box>
<Box>{item.value}</Box>
</Flex>
))}
{collection?.sourceId && (
<Button variant={'whitePrimary'} onClick={readSource}>
{t('common:core.dataset.collection.metadata.read source')}
</Button>
)}
</MyBox>
);
};
export default React.memo(MetaDataCard);

View File

@@ -0,0 +1,212 @@
import React, { useCallback } from 'react';
import { useTranslation } from 'next-i18next';
import { Box, Flex, IconButton, useTheme, Progress } from '@chakra-ui/react';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useRouter } from 'next/router';
import { useContextSelector } from 'use-context-selector';
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
import { useI18n } from '@/web/context/I18n';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
import MyPopover from '@fastgpt/web/components/common/MyPopover';
export enum TabEnum {
dataCard = 'dataCard',
collectionCard = 'collectionCard',
test = 'test',
info = 'info',
import = 'import'
}
const NavBar = ({ currentTab }: { currentTab: TabEnum }) => {
const theme = useTheme();
const { t } = useTranslation();
const { datasetT } = useI18n();
const router = useRouter();
const query = router.query;
const { isPc } = useSystem();
const { datasetDetail, vectorTrainingMap, agentTrainingMap, rebuildingCount } =
useContextSelector(DatasetPageContext, (v) => v);
const tabList = [
{
label: t('common:core.dataset.Collection'),
value: TabEnum.collectionCard
},
{ label: t('common:core.dataset.test.Search Test'), value: TabEnum.test },
...(datasetDetail.permission.hasManagePer && !isPc
? [{ label: t('common:common.Config'), value: TabEnum.info }]
: [])
];
const setCurrentTab = useCallback(
(tab: TabEnum) => {
router.replace({
query: {
datasetId: query.datasetId,
currentTab: tab
}
});
},
[query, router]
);
return (
<>
{isPc ? (
<Flex
py={2}
px={4}
justify={'space-between'}
borderBottom={theme.borders.base}
borderColor={'myGray.200'}
position={'relative'}
>
<Flex
alignItems={'center'}
cursor={'pointer'}
py={'0.38rem'}
px={2}
h={10}
borderRadius={'md'}
_hover={{ bg: 'myGray.05' }}
fontSize={'sm'}
fontWeight={500}
onClick={() => {
if (currentTab !== TabEnum.dataCard) router.replace('/dataset/list');
else
router.replace({
query: {
datasetId: router.query.datasetId,
parentId: router.query.parentId,
currentTab: TabEnum.collectionCard
}
});
}}
>
<IconButton
p={2}
mr={2}
w={'1.5rem'}
h={'24px'}
border={'1px solid'}
borderColor={'myGray.200'}
boxShadow={'1'}
icon={<MyIcon name={'common/arrowLeft'} w={'16px'} color={'myGray.500'} />}
bg={'white'}
size={'smSquare'}
borderRadius={'50%'}
aria-label={''}
_hover={'none'}
/>
<Box fontWeight={500} color={'myGray.600'} fontSize={'sm'}>
{currentTab !== TabEnum.dataCard
? t('common:core.dataset.All Dataset')
: datasetDetail.name}
</Box>
</Flex>
<Box position={'absolute'} left={'50%'} transform={'translateX(-50%)'}>
<LightRowTabs<TabEnum>
px={4}
py={1}
visibility={currentTab === TabEnum.dataCard ? 'hidden' : 'visible'}
flex={1}
mx={'auto'}
w={'100%'}
list={tabList}
value={currentTab}
activatedColor="blue.700"
onChange={setCurrentTab}
inlineStyles={{
fontSize: '1rem',
lineHeight: '1.5rem',
fontWeight: 500,
border: 'none',
_hover: {
bg: 'myGray.05',
color: 'blue.700'
},
borderRadius: '6px'
}}
/>
</Box>
{/* 训练情况hover弹窗 */}
<MyPopover
placement="bottom-end"
visibility={currentTab === TabEnum.collectionCard ? 'visible' : 'hidden'}
trigger="hover"
Trigger={
<Flex
visibility={currentTab === TabEnum.collectionCard ? 'visible' : 'hidden'}
alignItems={'center'}
justifyContent={'center'}
p={2}
borderRadius={'md'}
_hover={{
bg: 'myGray.05'
}}
>
<MyIcon name={'common/monitor'} w={'18px'} h={'18px'} color={'myGray.500'} />
<Box color={'myGray.600'} ml={1.5} fontWeight={500}>
{t('common:core.dataset.training.tag')}
</Box>
</Flex>
}
>
{({ onClose }) => (
<Box p={6}>
{rebuildingCount > 0 && (
<Box mb={3}>
<Box fontSize={'sm'}>
{datasetT('rebuilding_index_count', { count: rebuildingCount })}
</Box>
</Box>
)}
<Box mb={3}>
<Box fontSize={'sm'} pb={1}>
{t('common:core.dataset.training.Agent queue')}({agentTrainingMap.tip})
</Box>
<Progress
value={100}
size={'xs'}
colorScheme={agentTrainingMap.colorSchema}
borderRadius={'md'}
isAnimated
hasStripe
/>
</Box>
<Box>
<Box fontSize={'sm'} pb={1}>
{t('common:core.dataset.training.Vector queue')}({vectorTrainingMap.tip})
</Box>
<Progress
value={100}
size={'xs'}
colorScheme={vectorTrainingMap.colorSchema}
borderRadius={'md'}
isAnimated
hasStripe
/>
</Box>
</Box>
)}
</MyPopover>
</Flex>
) : (
<Box mb={3}>
<LightRowTabs<TabEnum>
m={'auto'}
w={'full'}
size={'sm'}
list={tabList}
value={currentTab}
onChange={setCurrentTab}
/>
</Box>
)}
</>
);
};
export default NavBar;

View File

@@ -1,165 +0,0 @@
import React, { useCallback } from 'react';
import { useTranslation } from 'next-i18next';
import { Box, Flex, IconButton, useTheme, Progress } from '@chakra-ui/react';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import Avatar from '@fastgpt/web/components/common/Avatar';
import { DatasetTypeMap } from '@fastgpt/global/core/dataset/constants';
import DatasetTypeTag from '@/components/core/dataset/DatasetTypeTag';
import MyIcon from '@fastgpt/web/components/common/Icon';
import SideTabs from '@/components/SideTabs';
import { useRouter } from 'next/router';
import { useContextSelector } from 'use-context-selector';
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
import { useI18n } from '@/web/context/I18n';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
export enum TabEnum {
dataCard = 'dataCard',
collectionCard = 'collectionCard',
test = 'test',
info = 'info',
import = 'import'
}
const Slider = ({ currentTab }: { currentTab: TabEnum }) => {
const theme = useTheme();
const { t } = useTranslation();
const { datasetT } = useI18n();
const router = useRouter();
const query = router.query;
const { isPc } = useSystem();
const { datasetDetail, vectorTrainingMap, agentTrainingMap, rebuildingCount } =
useContextSelector(DatasetPageContext, (v) => v);
const tabList = [
{
label: t('common:core.dataset.Collection'),
value: TabEnum.collectionCard,
icon: 'common/overviewLight'
},
{ label: t('common:core.dataset.test.Search Test'), value: TabEnum.test, icon: 'kbTest' },
...(datasetDetail.permission.hasManagePer
? [{ label: t('common:common.Config'), value: TabEnum.info, icon: 'common/settingLight' }]
: [])
];
const setCurrentTab = useCallback(
(tab: TabEnum) => {
router.replace({
query: {
datasetId: query.datasetId,
currentTab: tab
}
});
},
[query, router]
);
return (
<>
{isPc ? (
<Flex
flexDirection={'column'}
py={4}
h={'100%'}
flex={'0 0 200px'}
borderRight={theme.borders.base}
>
<Box px={4} borderBottom={'1px'} borderColor={'myGray.200'} pb={4} mb={4}>
<Flex mb={4} alignItems={'center'}>
<Avatar src={datasetDetail.avatar} w={'34px'} borderRadius={'md'} />
<Box ml={2}>
<Box fontWeight={'bold'}>{datasetDetail.name}</Box>
</Box>
</Flex>
{DatasetTypeMap[datasetDetail.type] && (
<Flex alignItems={'center'} pl={2} justifyContent={'space-between'}>
<DatasetTypeTag type={datasetDetail.type} />
</Flex>
)}
</Box>
<SideTabs<TabEnum>
px={4}
flex={1}
mx={'auto'}
w={'100%'}
list={tabList}
value={currentTab}
onChange={setCurrentTab}
/>
<Box px={4}>
{rebuildingCount > 0 && (
<Box mb={3}>
<Box fontSize={'sm'}>
{datasetT('rebuilding_index_count', { count: rebuildingCount })}
</Box>
</Box>
)}
<Box mb={3}>
<Box fontSize={'sm'}>
{t('common:core.dataset.training.Agent queue')}({agentTrainingMap.tip})
</Box>
<Progress
value={100}
size={'xs'}
colorScheme={agentTrainingMap.colorSchema}
borderRadius={'10px'}
isAnimated
hasStripe
/>
</Box>
<Box mb={3}>
<Box fontSize={'sm'}>
{t('common:core.dataset.training.Vector queue')}({vectorTrainingMap.tip})
</Box>
<Progress
value={100}
size={'xs'}
colorScheme={vectorTrainingMap.colorSchema}
borderRadius={'10px'}
isAnimated
hasStripe
/>
</Box>
</Box>
<Flex
alignItems={'center'}
cursor={'pointer'}
py={2}
px={3}
borderRadius={'md'}
_hover={{ bg: 'myGray.100' }}
fontSize={'sm'}
onClick={() => router.replace('/dataset/list')}
>
<IconButton
mr={3}
icon={<MyIcon name={'common/backFill'} w={'1rem'} color={'primary.500'} />}
bg={'white'}
boxShadow={'1px 1px 9px rgba(0,0,0,0.15)'}
size={'smSquare'}
borderRadius={'50%'}
aria-label={''}
/>
{t('common:core.dataset.All Dataset')}
</Flex>
</Flex>
) : (
<Box mb={3}>
<LightRowTabs<TabEnum>
m={'auto'}
w={'full'}
size={isPc ? 'md' : 'sm'}
list={tabList}
value={currentTab}
onChange={setCurrentTab}
/>
</Box>
)}
</>
);
};
export default Slider;

View File

@@ -141,7 +141,6 @@ const Test = ({ datasetId }: { datasetId: string }) => {
flex={1}
maxW={'500px'}
py={4}
borderRight={['none', theme.borders.base]}
>
<Box
border={'2px solid'}
@@ -280,7 +279,7 @@ const Test = ({ datasetId }: { datasetId: string }) => {
</Button>
</Flex>
</Box>
<Box mt={5} flex={'1 0 0'} px={4} overflow={'overlay'} display={['none', 'block']}>
<Box mt={5} px={4} overflow={'overlay'} display={['none', 'block']}>
<TestHistories
datasetId={datasetId}
datasetTestItem={datasetTestItem}

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { useRouter } from 'next/router';
import { Box } from '@chakra-ui/react';
import { Box, Flex } from '@chakra-ui/react';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useQuery } from '@tanstack/react-query';
import { getErrText } from '@fastgpt/global/common/error/utils';
@@ -8,8 +8,8 @@ import dynamic from 'next/dynamic';
import PageContainer from '@/components/PageContainer';
import { serviceSideProps } from '@/web/common/utils/i18n';
import { useTranslation } from 'next-i18next';
import Slider from './components/Slider';
import MetaDataCard from './components/MetaDataCard';
import NavBar from './components/NavBar';
import MyBox from '@fastgpt/web/components/common/MyBox';
import {
DatasetPageContext,
@@ -19,6 +19,7 @@ import CollectionPageContextProvider from './components/CollectionCard/Context';
import { useContextSelector } from 'use-context-selector';
import NextHead from '@/components/common/NextHead';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
const CollectionCard = dynamic(() => import('./components/CollectionCard/index'));
const DataCard = dynamic(() => import('./components/DataCard'));
@@ -39,6 +40,7 @@ const Detail = ({ datasetId, currentTab }: Props) => {
const { t } = useTranslation();
const { toast } = useToast();
const router = useRouter();
const { isPc } = useSystem();
const datasetDetail = useContextSelector(DatasetPageContext, (v) => v.datasetDetail);
const loadDatasetDetail = useContextSelector(DatasetPageContext, (v) => v.loadDatasetDetail);
const loadAllDatasetTags = useContextSelector(DatasetPageContext, (v) => v.loadAllDatasetTags);
@@ -60,25 +62,71 @@ const Detail = ({ datasetId, currentTab }: Props) => {
return (
<>
<NextHead title={datasetDetail?.name} icon={datasetDetail?.avatar} />
<PageContainer insertProps={{ bg: 'white' }}>
<MyBox display={'flex'} flexDirection={['column', 'row']} h={'100%'} pt={[4, 0]}>
<Slider currentTab={currentTab} />
{!!datasetDetail._id && (
<Box flex={'1 0 0'} pb={0} overflow={'auto'}>
{isPc ? (
<Flex h={'100%'} w={'100%'}>
<Flex
flexGrow={1}
flex={81}
bg={'white'}
w={'100%'}
flexDir={'column'}
my={3}
mr={2}
boxShadow={'2'}
borderRadius={'md'}
>
{currentTab !== TabEnum.import && <NavBar currentTab={currentTab} />}
<Box flex={'1 0 0'} w={'100%'} overflow={'auto'}>
{currentTab === TabEnum.collectionCard && (
<CollectionPageContextProvider>
<CollectionCard />
</CollectionPageContextProvider>
)}
{currentTab === TabEnum.dataCard && <DataCard />}
{currentTab === TabEnum.test && <Test datasetId={datasetId} />}
{currentTab === TabEnum.info && <Info datasetId={datasetId} />}
{currentTab === TabEnum.dataCard && <DataCard />}
{currentTab === TabEnum.import && <Import />}
</Box>
</Flex>
{currentTab !== TabEnum.import && (
<Flex
bg={'white'}
borderRadius={'md'}
overflowY={'scroll'}
boxShadow={'2'}
my={3}
mr={3}
flex={19}
>
{currentTab === TabEnum.dataCard ? (
<MetaDataCard datasetId={datasetId} />
) : (
<Info datasetId={datasetId} />
)}
</Flex>
)}
</MyBox>
</PageContainer>
</Flex>
) : (
<PageContainer insertProps={{ bg: 'white' }}>
<MyBox display={'flex'} flexDirection={['column', 'row']} h={'100%'} pt={[4, 0]}>
<NavBar currentTab={currentTab} />
{!!datasetDetail._id && (
<Box flex={'1 0 0'} pb={0} overflow={'auto'}>
{currentTab === TabEnum.collectionCard && (
<CollectionPageContextProvider>
<CollectionCard />
</CollectionPageContextProvider>
)}
{currentTab === TabEnum.dataCard && <DataCard />}
{currentTab === TabEnum.test && <Test datasetId={datasetId} />}
{currentTab === TabEnum.info && <Info datasetId={datasetId} />}
{currentTab === TabEnum.import && <Import />}
</Box>
)}
</MyBox>
</PageContainer>
)}
</>
);
};

View File

@@ -118,7 +118,7 @@ const CreateModal = ({
<MyModal
title={
<Flex alignItems={'center'} ml={-3}>
<Avatar w={'20px'} h={'20px'} borderRadius={'4px'} src={iconMap[type]} pr={'10px'} />
<Avatar w={'20px'} h={'20px'} borderRadius={'xs'} src={iconMap[type]} pr={'10px'} />
{t('common:core.dataset.Create dataset', { name: databaseNameMap[type] })}
</Flex>
}
@@ -127,9 +127,9 @@ const CreateModal = ({
isCentered={!isPc}
w={'490px'}
>
<ModalBody py={'24px'} px={'36px'}>
<ModalBody py={6} px={9}>
<Box>
<Box color={'myGray.900'} fontWeight={500} fontSize={'14px'}>
<Box color={'myGray.900'} fontWeight={500} fontSize={'sm'}>
{t('common:common.Set Name')}
</Box>
<Flex mt={'12px'} alignItems={'center'}>
@@ -226,7 +226,7 @@ const CreateModal = ({
)}
</ModalBody>
<ModalFooter px={'36px'}>
<ModalFooter px={9}>
<Button variant={'whiteBase'} mr={3} onClick={onClose}>
{t('common:common.Close')}
</Button>

View File

@@ -229,7 +229,7 @@ function List() {
>
<HStack>
<Avatar src={dataset.avatar} borderRadius={6} w={'28px'} />
<Box flex={'1 0 0'} className="textEllipsis3">
<Box flex={'1 0 0'} className="textEllipsis3" color={'myGray.900'}>
{dataset.name}
</Box>
@@ -264,7 +264,7 @@ function List() {
h={'24px'}
alignItems={'center'}
justifyContent={'space-between'}
fontSize={'12px'}
fontSize={'sm'}
fontWeight={500}
color={'myGray.500'}
>

View File

@@ -28,7 +28,7 @@ const SideTag = ({ type, ...props }: { type: `${DatasetTypeEnum}` } & FlexProps)
return (
<Flex
bg={'myGray.100'}
py={'3px'}
py={0.75}
pl={'8px'}
pr={'12px'}
borderRadius={'md'}

View File

@@ -155,7 +155,7 @@ const Dataset = () => {
placement="bottom-end"
Button={
<Button variant={'primary'} px="0">
<Flex alignItems={'center'} px={'20px'}>
<Flex alignItems={'center'} px={5}>
<AddIcon mr={2} />
<Box>{t('common:common.Create New')}</Box>
</Flex>