mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-24 22:03:54 +00:00
4.8.12 test (#3006)
* perf: oneapi error tip * fix: qps limit condition error * perf: Plan tip * fix: permission modal ui * perf: dataset slider ui * perf: api key auth tmbId problem * perf: dataset upload i18n * fix: http json path check
This commit is contained in:
@@ -126,29 +126,11 @@ const FolderSlideCard = ({
|
||||
<MyDivider my={6} />
|
||||
|
||||
<Box>
|
||||
<FormLabel>{t('common:support.permission.Permission')}</FormLabel>
|
||||
|
||||
{!isInheritPermission && (
|
||||
<Box mt={2}>
|
||||
<ResumeInherit onResume={() => resumeInheritPermission?.().then(refetchResource)} />
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{managePer.permission.hasManagePer && !!defaultPer && (
|
||||
<Box mt={5}>
|
||||
<Box fontSize={'sm'} color={'myGray.500'}>
|
||||
{t('common:permission.Default permission')}
|
||||
</Box>
|
||||
<DefaultPermissionList
|
||||
mt="1"
|
||||
per={defaultPer.value}
|
||||
defaultPer={defaultPer.defaultValue}
|
||||
isInheritPermission={isInheritPermission}
|
||||
onChange={(v) => defaultPer.onChange(v)}
|
||||
hasParent={hasParent}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
<Box mt={6}>
|
||||
<CollaboratorContextProvider
|
||||
{...managePer}
|
||||
@@ -190,8 +172,8 @@ const FolderSlideCard = ({
|
||||
<MemberListCard
|
||||
mt={2}
|
||||
tagStyle={{
|
||||
type: 'borderSolid',
|
||||
colorSchema: 'gray'
|
||||
type: 'fill',
|
||||
colorSchema: 'white'
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
@@ -114,6 +114,35 @@ const ChatInput = ({
|
||||
renderAudioGraph,
|
||||
stream
|
||||
} = useSpeech({ appId, ...outLinkAuthData });
|
||||
const onWhisperRecord = useCallback(() => {
|
||||
const finishWhisperTranscription = (text: string) => {
|
||||
if (!text) return;
|
||||
if (whisperConfig?.autoSend) {
|
||||
onSendMessage({
|
||||
text,
|
||||
files: fileList,
|
||||
autoTTSResponse
|
||||
});
|
||||
replaceFiles([]);
|
||||
} else {
|
||||
resetInputVal({ text });
|
||||
}
|
||||
};
|
||||
if (isSpeaking) {
|
||||
return stopSpeak();
|
||||
}
|
||||
startSpeak(finishWhisperTranscription);
|
||||
}, [
|
||||
autoTTSResponse,
|
||||
fileList,
|
||||
isSpeaking,
|
||||
onSendMessage,
|
||||
replaceFiles,
|
||||
resetInputVal,
|
||||
startSpeak,
|
||||
stopSpeak,
|
||||
whisperConfig?.autoSend
|
||||
]);
|
||||
useEffect(() => {
|
||||
if (!stream) {
|
||||
return;
|
||||
@@ -131,28 +160,6 @@ const ChatInput = ({
|
||||
};
|
||||
renderCurve();
|
||||
}, [renderAudioGraph, stream]);
|
||||
const finishWhisperTranscription = useCallback(
|
||||
(text: string) => {
|
||||
if (!text) return;
|
||||
if (whisperConfig?.autoSend) {
|
||||
onSendMessage({
|
||||
text,
|
||||
files: fileList,
|
||||
autoTTSResponse
|
||||
});
|
||||
replaceFiles([]);
|
||||
} else {
|
||||
resetInputVal({ text });
|
||||
}
|
||||
},
|
||||
[autoTTSResponse, fileList, onSendMessage, replaceFiles, resetInputVal, whisperConfig?.autoSend]
|
||||
);
|
||||
const onWhisperRecord = useCallback(() => {
|
||||
if (isSpeaking) {
|
||||
return stopSpeak();
|
||||
}
|
||||
startSpeak(finishWhisperTranscription);
|
||||
}, [finishWhisperTranscription, isSpeaking, startSpeak, stopSpeak]);
|
||||
|
||||
const RenderTranslateLoading = useMemo(
|
||||
() => (
|
||||
|
@@ -95,23 +95,19 @@ function AddMemberModal({ onClose, mode = 'member' }: AddModalPropsType) {
|
||||
iconSrc="modal/AddClb"
|
||||
title={t('user:team.add_collaborator')}
|
||||
minW="800px"
|
||||
h={'100%'}
|
||||
isCentered
|
||||
isLoading={loadingMembersAndGroups}
|
||||
>
|
||||
<ModalBody>
|
||||
<ModalBody flex={'1'}>
|
||||
<Grid
|
||||
border="1px solid"
|
||||
borderColor="myGray.200"
|
||||
borderRadius="0.5rem"
|
||||
gridTemplateColumns="1fr 1fr"
|
||||
h={'100%'}
|
||||
>
|
||||
<Flex
|
||||
flexDirection="column"
|
||||
borderRight="1px solid"
|
||||
borderColor="myGray.200"
|
||||
p="4"
|
||||
minH="200px"
|
||||
>
|
||||
<Flex flexDirection="column" borderRight="1px solid" borderColor="myGray.200" p="4">
|
||||
<SearchInput
|
||||
placeholder={t('user:search_user')}
|
||||
bgColor="myGray.50"
|
||||
|
@@ -325,6 +325,7 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => {
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const PlanUsage = () => {
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
|
@@ -527,15 +527,14 @@ const authHeaderRequest = async ({
|
||||
teamId,
|
||||
tmbId,
|
||||
authType,
|
||||
apikey,
|
||||
canWrite: apiKeyCanWrite
|
||||
apikey
|
||||
} = await authCert({
|
||||
req,
|
||||
authToken: true,
|
||||
authApiKey: true
|
||||
});
|
||||
|
||||
const { app, canWrite } = await (async () => {
|
||||
const { app } = await (async () => {
|
||||
if (authType === AuthUserTypeEnum.apikey) {
|
||||
if (!apiKeyAppId) {
|
||||
return Promise.reject(
|
||||
@@ -551,16 +550,14 @@ const authHeaderRequest = async ({
|
||||
appId = String(app._id);
|
||||
|
||||
return {
|
||||
app,
|
||||
canWrite: apiKeyCanWrite
|
||||
app
|
||||
};
|
||||
} else {
|
||||
// token_auth
|
||||
|
||||
if (!appId) {
|
||||
return Promise.reject('appId is empty');
|
||||
}
|
||||
const { app, permission } = await authApp({
|
||||
const { app } = await authApp({
|
||||
req,
|
||||
authToken: true,
|
||||
appId,
|
||||
@@ -568,8 +565,7 @@ const authHeaderRequest = async ({
|
||||
});
|
||||
|
||||
return {
|
||||
app,
|
||||
canWrite: permission.hasReadPer
|
||||
app
|
||||
};
|
||||
}
|
||||
})();
|
||||
@@ -579,7 +575,12 @@ const authHeaderRequest = async ({
|
||||
MongoChat.findOne({ appId, chatId }).lean()
|
||||
]);
|
||||
|
||||
if (chat && (String(chat.teamId) !== teamId || String(chat.tmbId) !== tmbId)) {
|
||||
if (
|
||||
chat &&
|
||||
(String(chat.teamId) !== teamId ||
|
||||
// There's no need to distinguish who created it if it's apiKey auth
|
||||
(authType === AuthUserTypeEnum.token && String(chat.tmbId) !== tmbId))
|
||||
) {
|
||||
return Promise.reject(ChatErrEnum.unAuthChat);
|
||||
}
|
||||
|
||||
@@ -591,7 +592,7 @@ const authHeaderRequest = async ({
|
||||
responseDetail: true,
|
||||
apikey,
|
||||
authType,
|
||||
canWrite
|
||||
canWrite: true
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -386,7 +386,7 @@ const Render = (props: Props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<NextHead title={props.appName} desc={props.appIntro} icon={props.appAvatar} />
|
||||
<NextHead title={props.appName || 'AI'} desc={props.appIntro} icon={props.appAvatar} />
|
||||
{systemLoaded && (
|
||||
<ChatContextProvider params={contextParams}>
|
||||
<OutLink {...props} outLinkUid={contextParams.outLinkUid} />;
|
||||
|
@@ -15,11 +15,11 @@ function MemberManager({ managePer }: { managePer: MemberManagerInputPropsType }
|
||||
return (
|
||||
<>
|
||||
<Flex alignItems="center" flexDirection="row" justifyContent="space-between" w="full">
|
||||
<Box>
|
||||
<FormLabel fontSize={'mini'}>{t('common:permission.Collaborator')}</FormLabel>
|
||||
<Box color={'myGray.900'} fontSize={'mini'} fontWeight={'bold'}>
|
||||
{t('common:permission.Collaborator')}
|
||||
</Box>
|
||||
<Flex gap={0.5}>
|
||||
<Box p={1}>
|
||||
<Flex gap={2}>
|
||||
<Box>
|
||||
<MyIcon
|
||||
onClick={onOpenManageModal}
|
||||
name="common/setting"
|
||||
@@ -30,7 +30,7 @@ function MemberManager({ managePer }: { managePer: MemberManagerInputPropsType }
|
||||
_hover={{ color: 'primary.500' }}
|
||||
/>
|
||||
</Box>
|
||||
<Box p={1}>
|
||||
<Box>
|
||||
<MyIcon
|
||||
cursor={'pointer'}
|
||||
onClick={onOpenAddMember}
|
||||
|
@@ -182,7 +182,7 @@ const DatasetImportContextProvider = ({ children }: { children: React.ReactNode
|
||||
showChunkInput: false,
|
||||
showPromptInput: false,
|
||||
charsPointsPrice: agentModel.charsPointsPrice,
|
||||
priceTip: t('common:core.dataset.import.Auto mode Estimated Price Tips', {
|
||||
priceTip: t('dataset:import.Auto mode Estimated Price Tips', {
|
||||
price: agentModel.charsPointsPrice
|
||||
}),
|
||||
uploadRate: 100
|
||||
@@ -197,7 +197,7 @@ const DatasetImportContextProvider = ({ children }: { children: React.ReactNode
|
||||
showChunkInput: true,
|
||||
showPromptInput: false,
|
||||
charsPointsPrice: vectorModel.charsPointsPrice,
|
||||
priceTip: t('common:core.dataset.import.Embedding Estimated Price Tips', {
|
||||
priceTip: t('dataset:import.Embedding Estimated Price Tips', {
|
||||
price: vectorModel.charsPointsPrice
|
||||
}),
|
||||
uploadRate: 150
|
||||
@@ -212,8 +212,8 @@ const DatasetImportContextProvider = ({ children }: { children: React.ReactNode
|
||||
showChunkInput: true,
|
||||
showPromptInput: true,
|
||||
charsPointsPrice: agentModel.charsPointsPrice,
|
||||
priceTip: t('common:core.dataset.import.QA Estimated Price Tips', {
|
||||
price: agentModel?.charsPointsPrice
|
||||
priceTip: t('dataset:import.Auto mode Estimated Price Tips', {
|
||||
price: agentModel.charsPointsPrice
|
||||
}),
|
||||
uploadRate: 30
|
||||
}
|
||||
|
@@ -78,7 +78,7 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
|
||||
<Box h={'100%'} display={['block', 'flex']} fontSize={'sm'}>
|
||||
<Box
|
||||
flex={'1 0 0'}
|
||||
minW={['auto', '540px']}
|
||||
minW={['auto', '500px']}
|
||||
maxW={'600px'}
|
||||
h={['auto', '100%']}
|
||||
overflow={'auto'}
|
||||
@@ -86,11 +86,11 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
|
||||
>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'common/settingLight'} w={'20px'} />
|
||||
<Box fontSize={'md'}>{t('common:core.dataset.import.Data process params')}</Box>
|
||||
<Box fontSize={'md'}>{t('dataset:data_process_setting')}</Box>
|
||||
</Flex>
|
||||
|
||||
<Box display={['block', 'flex']} mt={4} alignItems={'center'}>
|
||||
<FormLabel flex={'0 0 100px'}>{t('common:core.dataset.import.Training mode')}</FormLabel>
|
||||
<FormLabel flex={'0 0 100px'}>{t('dataset:training_mode')}</FormLabel>
|
||||
<LeftRadio
|
||||
list={trainingModeList.map(([key, value]) => ({
|
||||
title: t(value.label as any),
|
||||
@@ -107,8 +107,9 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
|
||||
flexWrap={'wrap'}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box display={['block', 'flex']} mt={5}>
|
||||
<FormLabel flex={'0 0 100px'}>{t('common:core.dataset.import.Process way')}</FormLabel>
|
||||
<FormLabel flex={'0 0 100px'}>{t('dataset:data_process_params')}</FormLabel>
|
||||
<LeftRadio
|
||||
list={[
|
||||
{
|
||||
@@ -117,18 +118,16 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
|
||||
value: ImportProcessWayEnum.auto
|
||||
},
|
||||
{
|
||||
title: t('common:core.dataset.import.Custom process'),
|
||||
desc: t('common:core.dataset.import.Custom process desc'),
|
||||
title: t('dataset:custom_data_process_params'),
|
||||
desc: t('dataset:custom_data_process_params_desc'),
|
||||
value: ImportProcessWayEnum.custom,
|
||||
children: way === ImportProcessWayEnum.custom && (
|
||||
<Box mt={5}>
|
||||
{showChunkInput && chunkSizeField && (
|
||||
<Box>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box>{t('common:core.dataset.import.Ideal chunk length')}</Box>
|
||||
<MyTooltip
|
||||
label={t('common:core.dataset.import.Ideal chunk length Tips')}
|
||||
>
|
||||
<Box>{t('dataset:ideal_chunk_length')}</Box>
|
||||
<MyTooltip label={t('dataset:ideal_chunk_length_tips')}>
|
||||
<MyIcon
|
||||
name={'common/questionLight'}
|
||||
ml={1}
|
||||
@@ -269,15 +268,15 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
|
||||
}}
|
||||
></LeftRadio>
|
||||
</Box>
|
||||
<Box mt={5} pl={[0, '100px']} gap={3}>
|
||||
{feConfigs?.show_pay && (
|
||||
<MyTooltip label={priceTip}>
|
||||
<MyTag colorSchema={'gray'} py={1.5} borderRadius={'md'} px={3} whiteSpace={'wrap'}>
|
||||
{priceTip}
|
||||
</MyTag>
|
||||
</MyTooltip>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{feConfigs?.show_pay && (
|
||||
<Box mt={5} pl={[0, '100px']} gap={3}>
|
||||
<MyTag colorSchema={'gray'} py={1.5} borderRadius={'md'} px={3} whiteSpace={'wrap'}>
|
||||
{priceTip}
|
||||
</MyTag>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Flex mt={5} gap={3} justifyContent={'flex-end'}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Box, Flex, IconButton } from '@chakra-ui/react';
|
||||
import { Box, Flex, Grid, IconButton } from '@chakra-ui/react';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
@@ -19,68 +19,69 @@ const Preview = ({ showPreviewChunks }: { showPreviewChunks: boolean }) => {
|
||||
const [previewChunkSource, setPreviewChunkSource] = useState<ImportSourceItemType>();
|
||||
|
||||
return (
|
||||
<Box h={'100%'} display={['block', 'flex']} flexDirection={'column'}>
|
||||
<Box h={'100%'} w={'100%'} display={['block', 'flex']} flexDirection={'column'}>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/dataset/fileCollection'} w={'20px'} />
|
||||
<Box fontSize={'md'}>{t('common:core.dataset.import.Sources list')}</Box>
|
||||
</Flex>
|
||||
<Box mt={3} flex={'1 0 0'} width={'100%'} overflow={'auto'}>
|
||||
{sources.map((source) => (
|
||||
<Flex
|
||||
key={source.id}
|
||||
bg={'white'}
|
||||
p={4}
|
||||
borderRadius={'md'}
|
||||
borderWidth={'1px'}
|
||||
borderColor={'borderColor.low'}
|
||||
boxShadow={'2'}
|
||||
mb={3}
|
||||
alignItems={'center'}
|
||||
>
|
||||
<MyIcon name={source.icon as any} w={'16px'} />
|
||||
<Box mx={1} flex={'1 0 0'} w={0} className="textEllipsis">
|
||||
{source.sourceName}
|
||||
</Box>
|
||||
{showPreviewChunks && (
|
||||
<Box fontSize={'xs'} color={'myGray.600'}>
|
||||
<MyMenu
|
||||
Button={
|
||||
<IconButton
|
||||
icon={<MyIcon name={'common/viewLight'} w={'14px'} p={2} />}
|
||||
aria-label={''}
|
||||
size={'sm'}
|
||||
variant={'whitePrimary'}
|
||||
/>
|
||||
}
|
||||
menuList={[
|
||||
{
|
||||
children: [
|
||||
{
|
||||
label: (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/dataset/fileCollection'} w={'14px'} mr={2} />
|
||||
{t('common:core.dataset.import.Preview raw text')}
|
||||
</Flex>
|
||||
),
|
||||
onClick: () => setPreviewRawTextSource(source)
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/dataset/splitLight'} w={'14px'} mr={2} />
|
||||
{t('common:core.dataset.import.Preview chunks')}
|
||||
</Flex>
|
||||
),
|
||||
onClick: () => setPreviewChunkSource(source)
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
<Box mt={3} flex={'1 0 0'} width={'100%'} overflowY={'auto'}>
|
||||
<Grid w={'100%'} gap={3} gridTemplateColumns={['1fr', '1fr', '1fr', '1fr', '1fr 1fr']}>
|
||||
{sources.map((source) => (
|
||||
<Flex
|
||||
key={source.id}
|
||||
bg={'white'}
|
||||
p={4}
|
||||
borderRadius={'md'}
|
||||
borderWidth={'1px'}
|
||||
borderColor={'borderColor.low'}
|
||||
boxShadow={'2'}
|
||||
alignItems={'center'}
|
||||
>
|
||||
<MyIcon name={source.icon as any} w={['1rem', '1.25rem']} />
|
||||
<Box mx={1} flex={'1 0 0'} wordBreak={'break-all'} fontSize={'sm'}>
|
||||
{source.sourceName}
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
))}
|
||||
{showPreviewChunks && (
|
||||
<Box fontSize={'xs'} color={'myGray.600'}>
|
||||
<MyMenu
|
||||
Button={
|
||||
<IconButton
|
||||
icon={<MyIcon name={'common/viewLight'} w={'14px'} p={2} />}
|
||||
aria-label={''}
|
||||
size={'sm'}
|
||||
variant={'whitePrimary'}
|
||||
/>
|
||||
}
|
||||
menuList={[
|
||||
{
|
||||
children: [
|
||||
{
|
||||
label: (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/dataset/fileCollection'} w={'14px'} mr={2} />
|
||||
{t('common:core.dataset.import.Preview raw text')}
|
||||
</Flex>
|
||||
),
|
||||
onClick: () => setPreviewRawTextSource(source)
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/dataset/splitLight'} w={'14px'} mr={2} />
|
||||
{t('common:core.dataset.import.Preview chunks')}
|
||||
</Flex>
|
||||
),
|
||||
onClick: () => setPreviewChunkSource(source)
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
))}
|
||||
</Grid>
|
||||
</Box>
|
||||
{!!previewRawTextSource && (
|
||||
<PreviewRawText
|
||||
|
@@ -33,8 +33,6 @@ import { EditResourceInfoFormType } from '@/components/common/Modal/EditResource
|
||||
const EditResourceModal = dynamic(() => import('@/components/common/Modal/EditResourceModal'));
|
||||
|
||||
const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
const [openBaseConfig, setOpenBaseConfig] = useState(true);
|
||||
const [openPermissionConfig, setOpenPermissionConfig] = useState(true);
|
||||
const { t } = useTranslation();
|
||||
const { datasetDetail, loadDatasetDetail, updateDataset, rebuildingCount, trainingCount } =
|
||||
useContextSelector(DatasetPageContext, (v) => v);
|
||||
@@ -175,23 +173,13 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
|
||||
<MyDivider my={4} h={'2px'} maxW={'500px'} />
|
||||
|
||||
<Box overflow={'hidden'} h={openBaseConfig ? 'auto' : '24px'}>
|
||||
<Box overflow={'hidden'}>
|
||||
<Flex justify={'space-between'} alignItems={'center'} fontSize={'mini'} h={'24px'}>
|
||||
<Box fontWeight={'500'} color={'myGray.900'} userSelect={'none'}>
|
||||
{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={(e) => {
|
||||
e.preventDefault();
|
||||
setOpenBaseConfig(!openBaseConfig);
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex mt={3} w={'100%'} flexDir={'column'} userSelect={'none'}>
|
||||
<Flex mt={3} w={'100%'} flexDir={'column'}>
|
||||
<FormLabel fontSize={'mini'} fontWeight={'500'}>
|
||||
{t('common:core.dataset.Dataset ID')}
|
||||
</FormLabel>
|
||||
@@ -202,7 +190,7 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
<FormLabel fontSize={'mini'} fontWeight={'500'}>
|
||||
{t('common:core.ai.model.Vector Model')}
|
||||
</FormLabel>
|
||||
<Box pt={2} flex={[1, '0 0 320px']}>
|
||||
<Box pt={2}>
|
||||
<AIModelSelector
|
||||
w={'100%'}
|
||||
value={vectorModel.model}
|
||||
@@ -231,12 +219,10 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
</Box>
|
||||
|
||||
<Flex mt={2} w={'100%'} alignItems={'center'}>
|
||||
<FormLabel flex={['0 0 90px', '0 0 160px']} fontSize={'mini'} w={0} fontWeight={'500'}>
|
||||
<FormLabel flex={1} fontSize={'mini'} w={0} fontWeight={'500'}>
|
||||
{t('common:core.Max Token')}
|
||||
</FormLabel>
|
||||
<Box flex={[1, '0 0 320px']} fontSize={'mini'}>
|
||||
{vectorModel.maxToken}
|
||||
</Box>
|
||||
<Box fontSize={'mini'}>{vectorModel.maxToken}</Box>
|
||||
</Flex>
|
||||
|
||||
<Box pt={5}>
|
||||
@@ -286,54 +272,33 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
||||
{datasetDetail.permission.hasManagePer && (
|
||||
<>
|
||||
<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'} userSelect={'none'}>
|
||||
{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>
|
||||
|
||||
<Box mt={3}>
|
||||
<FormLabel fontWeight={'500'} fontSize={'mini'} pb={3} userSelect={'none'}>
|
||||
{t('common:permission.Default permission')}
|
||||
</FormLabel>
|
||||
</Box>
|
||||
|
||||
<Box py={4}>
|
||||
<MemberManager
|
||||
managePer={{
|
||||
mode: 'all',
|
||||
permission: datasetDetail.permission,
|
||||
onGetCollaboratorList: () => getCollaboratorList(datasetId),
|
||||
permissionList: DatasetPermissionList,
|
||||
onUpdateCollaborators: (body) =>
|
||||
postUpdateDatasetCollaborators({
|
||||
...body,
|
||||
datasetId
|
||||
}),
|
||||
onDelOneCollaborator: async ({ groupId, tmbId }) => {
|
||||
if (tmbId) {
|
||||
return deleteDatasetCollaborators({
|
||||
datasetId,
|
||||
tmbId
|
||||
});
|
||||
} else if (groupId) {
|
||||
return deleteDatasetCollaborators({
|
||||
datasetId,
|
||||
groupId
|
||||
});
|
||||
}
|
||||
<Box>
|
||||
<MemberManager
|
||||
managePer={{
|
||||
mode: 'all',
|
||||
permission: datasetDetail.permission,
|
||||
onGetCollaboratorList: () => getCollaboratorList(datasetId),
|
||||
permissionList: DatasetPermissionList,
|
||||
onUpdateCollaborators: (body) =>
|
||||
postUpdateDatasetCollaborators({
|
||||
...body,
|
||||
datasetId
|
||||
}),
|
||||
onDelOneCollaborator: async ({ groupId, tmbId }) => {
|
||||
if (tmbId) {
|
||||
return deleteDatasetCollaborators({
|
||||
datasetId,
|
||||
tmbId
|
||||
});
|
||||
} else if (groupId) {
|
||||
return deleteDatasetCollaborators({
|
||||
datasetId,
|
||||
groupId
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
|
@@ -13,7 +13,6 @@ import { useTranslation } from 'next-i18next';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
@@ -272,31 +271,15 @@ const ExtraPlan = () => {
|
||||
<MyIcon mr={2} name={'support/bill/shoppingCart'} w={'16px'} color={'primary.600'} />
|
||||
{t('common:support.wallet.buy_resource')}
|
||||
</Flex>
|
||||
{/* <Flex mt={4} alignItems={'center'}>
|
||||
<Box flex={['0 0 100px', '1 0 0']}>
|
||||
<Flex mt={4} alignItems={'center'}>
|
||||
<Box flex={['0 0 100px', '1 0 0']} color={'myGray.600'}>
|
||||
{t('common:support.wallet.subscription.Month amount')}
|
||||
</Box>
|
||||
<Flex alignItems={'center'} mt={1} w={'180px'} position={'relative'}>
|
||||
<NumberInput size={'sm'} flex={1} step={1} min={1} max={12} position={'relative'}>
|
||||
<NumberInputField
|
||||
pr={'30px'}
|
||||
{...registerExtraPoints('month', {
|
||||
required: true,
|
||||
min: 1,
|
||||
max: 12,
|
||||
valueAsNumber: true
|
||||
})}
|
||||
/>
|
||||
<NumberInputStepper>
|
||||
<NumberIncrementStepper />
|
||||
<NumberDecrementStepper />
|
||||
</NumberInputStepper>
|
||||
</NumberInput>
|
||||
<Box position={'absolute'} right={'20px'} color={'myGray.500'} fontSize={'xs'}>
|
||||
{t('common:common.month')}
|
||||
</Box>
|
||||
<Box>1</Box>
|
||||
<Box color={'myGray.600'}>{t('common:common.month')}</Box>
|
||||
</Flex>
|
||||
</Flex> */}
|
||||
</Flex>
|
||||
<Flex mt={4} alignItems={'center'}>
|
||||
<Box flex={['0 0 100px', '1 0 0']} color={'myGray.600'}>
|
||||
{t('common:support.wallet.subscription.Update extra ai points')}
|
||||
|
@@ -84,21 +84,35 @@ export const useSpeech = (props?: OutLinkChatAuthProps & { appId?: string }) =>
|
||||
mediaRecorder.current.onstop = async () => {
|
||||
if (!cancelWhisperSignal.current) {
|
||||
const formData = new FormData();
|
||||
let options = {};
|
||||
const { options, filename } = (() => {
|
||||
if (MediaRecorder.isTypeSupported('video/webm; codecs=vp9')) {
|
||||
return {
|
||||
options: { mimeType: 'video/webm; codecs=vp9' },
|
||||
filename: 'recording.mp3'
|
||||
};
|
||||
}
|
||||
if (MediaRecorder.isTypeSupported('video/webm')) {
|
||||
return {
|
||||
options: { type: 'video/webm' },
|
||||
filename: 'recording.mp3'
|
||||
};
|
||||
}
|
||||
if (MediaRecorder.isTypeSupported('video/mp4')) {
|
||||
return {
|
||||
options: { mimeType: 'video/mp4', videoBitsPerSecond: 100000 },
|
||||
filename: 'recording.mp4'
|
||||
};
|
||||
}
|
||||
return {
|
||||
options: { type: 'video/webm' },
|
||||
filename: 'recording.mp3'
|
||||
};
|
||||
})();
|
||||
|
||||
if (MediaRecorder.isTypeSupported('video/webm; codecs=vp9')) {
|
||||
options = { mimeType: 'video/webm; codecs=vp9' };
|
||||
} else if (MediaRecorder.isTypeSupported('video/webm')) {
|
||||
options = { type: 'video/webm' };
|
||||
} else if (MediaRecorder.isTypeSupported('video/mp4')) {
|
||||
options = { mimeType: 'video/mp4', videoBitsPerSecond: 100000 };
|
||||
} else {
|
||||
console.error('no suitable mimetype found for this device');
|
||||
}
|
||||
const blob = new Blob(chunks, options);
|
||||
const duration = Math.round((Date.now() - startTimestamp.current) / 1000);
|
||||
|
||||
formData.append('file', blob, 'recording.mp3');
|
||||
console.log(options, filename, '=-=-');
|
||||
formData.append('file', blob, filename);
|
||||
formData.append(
|
||||
'data',
|
||||
JSON.stringify({
|
||||
|
Reference in New Issue
Block a user