chore(ui): login page & workflow page (#3046)
* login page & number input & multirow select & llm select * workflow * adjust nodes
This commit is contained in:
@@ -68,7 +68,9 @@ const SettingLLMModel = ({
|
||||
<Button
|
||||
w={'100%'}
|
||||
justifyContent={'flex-start'}
|
||||
variant={'whiteBase'}
|
||||
variant={'whitePrimaryOutline'}
|
||||
size={'lg'}
|
||||
fontSize={'sm'}
|
||||
bg={bg}
|
||||
_active={{
|
||||
transform: 'none'
|
||||
@@ -81,8 +83,9 @@ const SettingLLMModel = ({
|
||||
w={'18px'}
|
||||
/>
|
||||
}
|
||||
rightIcon={<MyIcon name={'common/select'} w={'1rem'} />}
|
||||
pl={4}
|
||||
rightIcon={<MyIcon name={'common/select'} w={'1.2rem'} color={'myGray.500'} />}
|
||||
px={3}
|
||||
pr={2}
|
||||
onClick={onOpenAIChatSetting}
|
||||
>
|
||||
<Box flex={1} textAlign={'left'}>
|
||||
|
||||
@@ -59,7 +59,9 @@ const FileSelect = ({
|
||||
return (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/simpleMode/file'} mr={2} w={'20px'} />
|
||||
<FormLabel {...labelStyle}>{t('app:file_upload')}</FormLabel>
|
||||
<FormLabel color={'myGray.600'} {...labelStyle}>
|
||||
{t('app:file_upload')}
|
||||
</FormLabel>
|
||||
<ChatFunctionTip type={'file'} />
|
||||
<Box flex={1} />
|
||||
<MyTooltip label={t('app:config_file_upload')}>
|
||||
@@ -68,6 +70,7 @@ const FileSelect = ({
|
||||
iconSpacing={1}
|
||||
size={'sm'}
|
||||
mr={'-5px'}
|
||||
color={'myGray.600'}
|
||||
onClick={onOpen}
|
||||
>
|
||||
{formLabel}
|
||||
|
||||
@@ -87,7 +87,7 @@ const InputGuideConfig = ({
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/inputGuides'} mr={2} w={'20px'} />
|
||||
<Flex alignItems={'center'}>
|
||||
<FormLabel>{chatT('input_guide')}</FormLabel>
|
||||
<FormLabel color={'myGray.600'}>{chatT('input_guide')}</FormLabel>
|
||||
<ChatFunctionTip type={'inputGuide'} />
|
||||
</Flex>
|
||||
<Box flex={1} />
|
||||
@@ -97,6 +97,7 @@ const InputGuideConfig = ({
|
||||
iconSpacing={1}
|
||||
size={'sm'}
|
||||
mr={'-5px'}
|
||||
color={'myGray.600'}
|
||||
onClick={onOpen}
|
||||
>
|
||||
{formLabel}
|
||||
|
||||
@@ -11,7 +11,7 @@ const QGSwitch = (props: SwitchProps) => {
|
||||
return (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/chat/QGFill'} mr={2} w={'20px'} />
|
||||
<FormLabel>{t('common:core.app.Question Guide')}</FormLabel>
|
||||
<FormLabel color={'myGray.600'}>{t('common:core.app.Question Guide')}</FormLabel>
|
||||
<ChatFunctionTip type={'nextQuestion'} />
|
||||
<Box flex={1} />
|
||||
<Switch {...props} />
|
||||
|
||||
@@ -270,7 +270,7 @@ const ScheduledTriggerConfig = ({
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/schedulePlan'} w={'20px'} />
|
||||
<HStack ml={2} flex={1} spacing={1}>
|
||||
<FormLabel>{t('common:core.app.Interval timer run')}</FormLabel>
|
||||
<FormLabel color={'myGray.600'}>{t('common:core.app.Interval timer run')}</FormLabel>
|
||||
<QuestionTip label={t('common:core.app.Interval timer tip')} />
|
||||
</HStack>
|
||||
<MyTooltip label={t('common:core.app.Config schedule plan')}>
|
||||
@@ -279,6 +279,7 @@ const ScheduledTriggerConfig = ({
|
||||
iconSpacing={1}
|
||||
size={'sm'}
|
||||
mr={'-5px'}
|
||||
color={'myGray.600'}
|
||||
onClick={onOpen}
|
||||
>
|
||||
{formatLabel}
|
||||
|
||||
@@ -82,7 +82,7 @@ const TTSSelect = ({
|
||||
return (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/simpleMode/tts'} mr={2} w={'20px'} />
|
||||
<FormLabel>{t('common:core.app.TTS')}</FormLabel>
|
||||
<FormLabel color={'myGray.600'}>{t('common:core.app.TTS')}</FormLabel>
|
||||
<ChatFunctionTip type={'tts'} />
|
||||
<Box flex={1} />
|
||||
<MyTooltip label={t('common:core.app.Select TTS')}>
|
||||
@@ -92,6 +92,7 @@ const TTSSelect = ({
|
||||
size={'sm'}
|
||||
mr={'-5px'}
|
||||
onClick={onOpen}
|
||||
color={'myGray.600'}
|
||||
>
|
||||
{formLabel}
|
||||
</Button>
|
||||
|
||||
@@ -173,7 +173,9 @@ const VariableEdit = ({
|
||||
{/* Row box */}
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/simpleMode/variable'} w={'20px'} />
|
||||
<FormLabel ml={2}>{t('common:core.module.Variable')}</FormLabel>
|
||||
<FormLabel ml={2} color={'myGray.600'}>
|
||||
{t('common:core.module.Variable')}
|
||||
</FormLabel>
|
||||
<ChatFunctionTip type={'variable'} />
|
||||
<Box flex={1} />
|
||||
<Button
|
||||
@@ -181,6 +183,7 @@ const VariableEdit = ({
|
||||
leftIcon={<SmallAddIcon />}
|
||||
iconSpacing={1}
|
||||
size={'sm'}
|
||||
color={'myGray.600'}
|
||||
mr={'-5px'}
|
||||
onClick={() => {
|
||||
reset(addVariable());
|
||||
@@ -193,60 +196,96 @@ const VariableEdit = ({
|
||||
{formatVariables.length > 0 && (
|
||||
<Box mt={2} borderRadius={'md'} overflow={'hidden'} borderWidth={'1px'} borderBottom="none">
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<Thead>
|
||||
<Table bg={'white'}>
|
||||
<Thead h={8}>
|
||||
<Tr>
|
||||
<Th
|
||||
fontSize={'mini'}
|
||||
borderRadius={'none !important'}
|
||||
w={'18px !important'}
|
||||
bg={'myGray.50'}
|
||||
p={0}
|
||||
/>
|
||||
<Th fontSize={'mini'}>{t('workflow:Variable_name')}</Th>
|
||||
<Th fontSize={'mini'}>{t('app:global_variables_desc')}</Th>
|
||||
<Th fontSize={'mini'}>{t('common:common.Require Input')}</Th>
|
||||
<Th fontSize={'mini'} borderRadius={'none !important'}></Th>
|
||||
px={4}
|
||||
fontWeight={'medium'}
|
||||
>
|
||||
{t('common:core.module.variable.key')}
|
||||
</Th>
|
||||
<Th fontSize={'mini'} bg={'myGray.50'} p={0} px={4} fontWeight={'medium'}>
|
||||
{t('workflow:Variable_name')}
|
||||
</Th>
|
||||
<Th fontSize={'mini'} bg={'myGray.50'} p={0} px={4} fontWeight={'medium'}>
|
||||
{t('common:common.Require Input')}
|
||||
</Th>
|
||||
<Th
|
||||
fontSize={'mini'}
|
||||
borderRadius={'none !important'}
|
||||
bg={'myGray.50'}
|
||||
p={0}
|
||||
px={4}
|
||||
fontWeight={'medium'}
|
||||
>
|
||||
{t('common:common.Operation')}
|
||||
</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{formatVariables.map((item) => (
|
||||
<Tr key={item.id}>
|
||||
<Td p={0} pl={3}>
|
||||
<MyIcon name={item.icon as any} w={'16px'} color={'myGray.500'} />
|
||||
</Td>
|
||||
<Td>{item.key}</Td>
|
||||
<Td
|
||||
maxW={'200px'}
|
||||
fontSize={'sm'}
|
||||
whiteSpace={'pre-wrap'}
|
||||
wordBreak={'break-all'}
|
||||
px={0}
|
||||
p={0}
|
||||
px={4}
|
||||
h={8}
|
||||
color={'myGray.900'}
|
||||
fontSize={'mini'}
|
||||
fontWeight={'medium'}
|
||||
>
|
||||
{item.description || '-'}
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={item.icon as any} w={'16px'} color={'myGray.400'} mr={2} />
|
||||
{item.label}
|
||||
</Flex>
|
||||
</Td>
|
||||
<Td>{item.required ? '✔' : '-'}</Td>
|
||||
<Td>
|
||||
<MyIcon
|
||||
mr={3}
|
||||
name={'common/settingLight'}
|
||||
w={'16px'}
|
||||
cursor={'pointer'}
|
||||
onClick={() => {
|
||||
const formattedItem = {
|
||||
...item,
|
||||
list: item.enums || []
|
||||
};
|
||||
reset(formattedItem);
|
||||
}}
|
||||
/>
|
||||
<MyIcon
|
||||
name={'delete'}
|
||||
w={'16px'}
|
||||
cursor={'pointer'}
|
||||
onClick={() =>
|
||||
onChange(variables.filter((variable) => variable.id !== item.id))
|
||||
}
|
||||
/>
|
||||
<Td
|
||||
p={0}
|
||||
px={4}
|
||||
h={8}
|
||||
color={'myGray.900'}
|
||||
fontSize={'mini'}
|
||||
fontWeight={'medium'}
|
||||
>
|
||||
<Flex alignItems={'center'}>{item.key}</Flex>
|
||||
</Td>
|
||||
<Td p={0} px={4} h={8} color={'myGray.900'} fontSize={'mini'}>
|
||||
<Flex alignItems={'center'}>
|
||||
{item.required ? (
|
||||
<MyIcon name={'check'} w={'16px'} color={'myGray.900'} mr={2} />
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</Flex>
|
||||
</Td>
|
||||
<Td p={0} px={4} h={8} color={'myGray.600'} fontSize={'mini'}>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon
|
||||
mr={3}
|
||||
name={'common/settingLight'}
|
||||
w={'16px'}
|
||||
cursor={'pointer'}
|
||||
onClick={() => {
|
||||
const formattedItem = {
|
||||
...item,
|
||||
list: item.enums || []
|
||||
};
|
||||
reset(formattedItem);
|
||||
}}
|
||||
/>
|
||||
<MyIcon
|
||||
name={'delete'}
|
||||
w={'16px'}
|
||||
cursor={'pointer'}
|
||||
onClick={() =>
|
||||
onChange(variables.filter((variable) => variable.id !== item.id))
|
||||
}
|
||||
/>
|
||||
</Flex>
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
|
||||
@@ -13,17 +13,20 @@ const WelcomeTextConfig = (props: TextareaProps) => {
|
||||
<>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/simpleMode/chat'} w={'20px'} />
|
||||
<FormLabel ml={2}>{t('common:core.app.Welcome Text')}</FormLabel>
|
||||
<FormLabel ml={2} color={'myGray.600'}>
|
||||
{t('common:core.app.Welcome Text')}
|
||||
</FormLabel>
|
||||
<ChatFunctionTip type={'welcome'} />
|
||||
</Flex>
|
||||
<MyTextarea
|
||||
className="nowheel"
|
||||
iconSrc={'core/app/simpleMode/chat'}
|
||||
title={t('common:core.app.Welcome Text')}
|
||||
mt={2}
|
||||
mt={1.5}
|
||||
rows={6}
|
||||
fontSize={'sm'}
|
||||
bg={'myGray.50'}
|
||||
bg={'white'}
|
||||
minW={'384px'}
|
||||
placeholder={t('common:core.app.tip.welcomeTextTip')}
|
||||
autoHeight
|
||||
minH={100}
|
||||
|
||||
@@ -34,7 +34,7 @@ const WhisperConfig = ({
|
||||
return (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/simpleMode/whisper'} mr={2} w={'20px'} />
|
||||
<FormLabel>{t('common:core.app.Whisper')}</FormLabel>
|
||||
<FormLabel color={'myGray.600'}>{t('common:core.app.Whisper')}</FormLabel>
|
||||
<Box flex={1} />
|
||||
<MyTooltip label={t('common:core.app.Config whisper')}>
|
||||
<Button
|
||||
@@ -42,6 +42,7 @@ const WhisperConfig = ({
|
||||
iconSpacing={1}
|
||||
size={'sm'}
|
||||
mr={'-5px'}
|
||||
color={'myGray.600'}
|
||||
onClick={onOpen}
|
||||
>
|
||||
{formLabel}
|
||||
|
||||
@@ -39,6 +39,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
import MyTextarea from '@/components/common/Textarea/MyTextarea';
|
||||
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';
|
||||
|
||||
type props = {
|
||||
value: UserChatItemValueItemType | AIChatItemValueItemType;
|
||||
@@ -244,25 +245,15 @@ const RenderUserFormInteractive = React.memo(function RenderFormInput({
|
||||
/>
|
||||
)}
|
||||
{input.type === FlowNodeInputTypeEnum.numberInput && (
|
||||
<NumberInput
|
||||
step={1}
|
||||
<MyNumberInput
|
||||
min={input.min}
|
||||
max={input.max}
|
||||
isDisabled={interactive.params.submitted}
|
||||
bg={'white'}
|
||||
rounded={'md'}
|
||||
>
|
||||
<NumberInputField
|
||||
bg={'white'}
|
||||
{...register(input.label, {
|
||||
required: input.required
|
||||
})}
|
||||
/>
|
||||
<NumberInputStepper>
|
||||
<NumberIncrementStepper />
|
||||
<NumberDecrementStepper />
|
||||
</NumberInputStepper>
|
||||
</NumberInput>
|
||||
register={register}
|
||||
name={input.label}
|
||||
isRequired={input.required}
|
||||
/>
|
||||
)}
|
||||
{input.type === FlowNodeInputTypeEnum.select && (
|
||||
<Controller
|
||||
|
||||
@@ -61,6 +61,7 @@ const DefaultPermissionList = ({
|
||||
}
|
||||
}}
|
||||
fontSize={styles?.fontSize}
|
||||
fontWeight={styles?.fontWeight}
|
||||
/>
|
||||
</Box>
|
||||
<ConfirmModal />
|
||||
|
||||
@@ -145,7 +145,6 @@ const Header = () => {
|
||||
)}
|
||||
<Flex
|
||||
mt={[2, 0]}
|
||||
py={3}
|
||||
pl={[2, 4]}
|
||||
pr={[2, 6]}
|
||||
borderBottom={'base'}
|
||||
@@ -163,12 +162,20 @@ const Header = () => {
|
||||
})}
|
||||
>
|
||||
{/* back */}
|
||||
<MyIcon
|
||||
name={'common/leftArrowLight'}
|
||||
w={'1.75rem'}
|
||||
cursor={'pointer'}
|
||||
onClick={isPublished ? onBack : onOpenBackConfirm}
|
||||
/>
|
||||
<Box
|
||||
_hover={{
|
||||
bg: 'myGray.200'
|
||||
}}
|
||||
p={0.5}
|
||||
borderRadius={'sm'}
|
||||
>
|
||||
<MyIcon
|
||||
name={'common/leftArrowLight'}
|
||||
w={6}
|
||||
cursor={'pointer'}
|
||||
onClick={isPublished ? onBack : onOpenBackConfirm}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* app info */}
|
||||
<Box ml={1}>
|
||||
|
||||
@@ -51,6 +51,7 @@ const RouteTab = () => {
|
||||
px={2}
|
||||
py={0.5}
|
||||
fontWeight={'medium'}
|
||||
borderRadius={'sm'}
|
||||
{...(currentTab === tab.id
|
||||
? {
|
||||
color: 'primary.700'
|
||||
@@ -59,8 +60,7 @@ const RouteTab = () => {
|
||||
color: 'myGray.600',
|
||||
cursor: 'pointer',
|
||||
_hover: {
|
||||
bg: 'myGray.200',
|
||||
borderRadius: 'md'
|
||||
bg: 'myGray.200'
|
||||
},
|
||||
onClick: () => setCurrentTab(tab.id)
|
||||
})}
|
||||
|
||||
@@ -84,7 +84,7 @@ const AppCard = () => {
|
||||
>
|
||||
{appDetail.intro || t('common:core.app.tip.Add a intro to app')}
|
||||
</Box>
|
||||
<HStack alignItems={'flex-end'}>
|
||||
<HStack alignItems={'center'}>
|
||||
<Button
|
||||
size={['sm', 'md']}
|
||||
variant={'whitePrimary'}
|
||||
@@ -107,7 +107,7 @@ const AppCard = () => {
|
||||
<MyMenu
|
||||
Button={
|
||||
<IconButton
|
||||
variant={'whiteBase'}
|
||||
variant={'whitePrimary'}
|
||||
size={['smSquare', 'mdSquare']}
|
||||
icon={<MyIcon name={'more'} w={'1rem'} />}
|
||||
aria-label={''}
|
||||
|
||||
@@ -151,7 +151,6 @@ const Header = () => {
|
||||
)}
|
||||
<Flex
|
||||
mt={[2, 0]}
|
||||
py={3}
|
||||
pl={[2, 4]}
|
||||
pr={[2, 6]}
|
||||
borderBottom={'base'}
|
||||
@@ -169,12 +168,20 @@ const Header = () => {
|
||||
})}
|
||||
>
|
||||
{/* back */}
|
||||
<MyIcon
|
||||
name={'common/leftArrowLight'}
|
||||
w={'1.75rem'}
|
||||
cursor={'pointer'}
|
||||
onClick={isPublished ? onBack : onOpenBackConfirm}
|
||||
/>
|
||||
<Box
|
||||
_hover={{
|
||||
bg: 'myGray.200'
|
||||
}}
|
||||
p={0.5}
|
||||
borderRadius={'sm'}
|
||||
>
|
||||
<MyIcon
|
||||
name={'common/leftArrowLight'}
|
||||
w={6}
|
||||
cursor={'pointer'}
|
||||
onClick={isPublished ? onBack : onOpenBackConfirm}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* app info */}
|
||||
<Box ml={1}>
|
||||
|
||||
@@ -16,6 +16,7 @@ import { publishStatusStyle } from '../constants';
|
||||
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
||||
import { fileDownload } from '@/web/common/file/utils';
|
||||
import { AppChatConfigType } from '@fastgpt/global/core/app/type';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
|
||||
const ImportSettings = dynamic(() => import('./Flow/ImportSettings'));
|
||||
|
||||
@@ -27,97 +28,120 @@ const AppCard = ({
|
||||
isPublished: boolean;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { feConfigs } = useSystemStore();
|
||||
|
||||
const { appDetail, onOpenInfoEdit, onOpenTeamTagModal, onDelApp, currentTab } =
|
||||
useContextSelector(AppContext, (v) => v);
|
||||
const { showHistoryModal } = useContextSelector(WorkflowContext, (v) => v);
|
||||
const { appDetail, onOpenInfoEdit, onOpenTeamTagModal, onDelApp } = useContextSelector(
|
||||
AppContext,
|
||||
(v) => v
|
||||
);
|
||||
|
||||
const { isOpen: isOpenImport, onOpen: onOpenImport, onClose: onCloseImport } = useDisclosure();
|
||||
|
||||
const InfoMenu = useCallback(
|
||||
({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<MyMenu
|
||||
width={150}
|
||||
Button={children}
|
||||
menuList={[
|
||||
{
|
||||
children: [
|
||||
{
|
||||
icon: 'edit',
|
||||
label: t('app:edit_info'),
|
||||
onClick: onOpenInfoEdit
|
||||
},
|
||||
{
|
||||
icon: 'support/team/key',
|
||||
label: t('common:common.Role'),
|
||||
onClick: onOpenInfoEdit
|
||||
}
|
||||
]
|
||||
},
|
||||
...(!showHistoryModal && currentTab === TabEnum.appEdit
|
||||
? [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
label: t('app:import_configs'),
|
||||
icon: 'common/importLight',
|
||||
onClick: onOpenImport
|
||||
},
|
||||
{
|
||||
label: ExportPopover({
|
||||
chatConfig: appDetail.chatConfig,
|
||||
appName: appDetail.name
|
||||
}),
|
||||
menuItemStyles: {
|
||||
p: 0,
|
||||
cursor: 'default'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
: []),
|
||||
...(appDetail.permission.hasWritePer && feConfigs?.show_team_chat
|
||||
? [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
icon: 'support/team/memberLight',
|
||||
label: t('common:common.Team Tags Set'),
|
||||
onClick: onOpenTeamTagModal
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
: []),
|
||||
...(appDetail.permission.isOwner
|
||||
? [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
type: 'danger' as 'danger',
|
||||
icon: 'delete',
|
||||
label: t('common:common.Delete'),
|
||||
onClick: onDelApp
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
: [])
|
||||
]}
|
||||
/>
|
||||
<MyPopover
|
||||
placement={'bottom-end'}
|
||||
hasArrow={false}
|
||||
offset={[2, 4]}
|
||||
w={'116px'}
|
||||
trigger={'hover'}
|
||||
Trigger={children}
|
||||
>
|
||||
{({ onClose }) => (
|
||||
<Box p={1.5}>
|
||||
<MyBox
|
||||
display={'flex'}
|
||||
size={'md'}
|
||||
px={1}
|
||||
py={1.5}
|
||||
rounded={'4px'}
|
||||
_hover={{ color: 'primary.600', bg: 'rgba(17, 24, 36, 0.05)' }}
|
||||
cursor={'pointer'}
|
||||
onClick={onOpenInfoEdit}
|
||||
>
|
||||
<MyIcon name={'edit'} w={'16px'} mr={2} />
|
||||
<Box fontSize={'sm'}>{t('app:edit_info')}</Box>
|
||||
</MyBox>
|
||||
<MyBox
|
||||
display={'flex'}
|
||||
size={'md'}
|
||||
px={1}
|
||||
py={1.5}
|
||||
rounded={'4px'}
|
||||
_hover={{ color: 'primary.600', bg: 'rgba(17, 24, 36, 0.05)' }}
|
||||
cursor={'pointer'}
|
||||
onClick={onOpenInfoEdit}
|
||||
>
|
||||
<MyIcon name={'support/team/key'} w={'16px'} mr={2} />
|
||||
<Box fontSize={'sm'}>{t('app:Role_setting')}</Box>
|
||||
</MyBox>
|
||||
<Box w={'full'} h={'1px'} bg={'myGray.200'} my={1} />
|
||||
<MyBox
|
||||
display={'flex'}
|
||||
size={'md'}
|
||||
px={1}
|
||||
py={1.5}
|
||||
rounded={'4px'}
|
||||
_hover={{ color: 'primary.600', bg: 'rgba(17, 24, 36, 0.05)' }}
|
||||
cursor={'pointer'}
|
||||
onClick={onOpenImport}
|
||||
>
|
||||
<MyIcon name={'common/importLight'} w={'16px'} mr={2} />
|
||||
<Box fontSize={'sm'}>{t('app:import_configs')}</Box>
|
||||
</MyBox>
|
||||
<MyBox
|
||||
display={'flex'}
|
||||
size={'md'}
|
||||
px={1}
|
||||
py={1.5}
|
||||
rounded={'4px'}
|
||||
_hover={{ color: 'primary.600', bg: 'rgba(17, 24, 36, 0.05)' }}
|
||||
cursor={'pointer'}
|
||||
>
|
||||
{ExportPopover({
|
||||
chatConfig: appDetail.chatConfig,
|
||||
appName: appDetail.name
|
||||
})}
|
||||
</MyBox>
|
||||
<Box w={'full'} h={'1px'} bg={'myGray.200'} my={1} />
|
||||
|
||||
<MyBox
|
||||
display={'flex'}
|
||||
size={'md'}
|
||||
px={1}
|
||||
py={1.5}
|
||||
rounded={'4px'}
|
||||
_hover={{ color: 'primary.600', bg: 'rgba(17, 24, 36, 0.05)' }}
|
||||
cursor={'pointer'}
|
||||
onClick={onOpenTeamTagModal}
|
||||
>
|
||||
<MyIcon name={'core/dataset/tag'} w={'16px'} mr={2} />
|
||||
<Box fontSize={'sm'}>{t('app:Team_Tags')}</Box>
|
||||
</MyBox>
|
||||
<Box w={'full'} h={'1px'} bg={'myGray.200'} my={1} />
|
||||
|
||||
<MyBox
|
||||
display={'flex'}
|
||||
size={'md'}
|
||||
px={1}
|
||||
py={1.5}
|
||||
rounded={'4px'}
|
||||
color={'red.600'}
|
||||
_hover={{ bg: 'rgba(17, 24, 36, 0.05)' }}
|
||||
cursor={'pointer'}
|
||||
onClick={onDelApp}
|
||||
>
|
||||
<MyIcon name={'delete'} w={'16px'} mr={2} />
|
||||
<Box fontSize={'sm'}>{t('common:common.Delete')}</Box>
|
||||
</MyBox>
|
||||
</Box>
|
||||
)}
|
||||
</MyPopover>
|
||||
);
|
||||
},
|
||||
[
|
||||
appDetail.chatConfig,
|
||||
appDetail.name,
|
||||
appDetail.permission.hasWritePer,
|
||||
appDetail.permission.isOwner,
|
||||
currentTab,
|
||||
feConfigs?.show_team_chat,
|
||||
showHistoryModal,
|
||||
onDelApp,
|
||||
onOpenImport,
|
||||
onOpenInfoEdit,
|
||||
@@ -129,21 +153,26 @@ const AppCard = ({
|
||||
const Render = useMemo(() => {
|
||||
return (
|
||||
<HStack>
|
||||
<InfoMenu>
|
||||
<Avatar src={appDetail.avatar} w={'1.75rem'} borderRadius={'md'} />
|
||||
</InfoMenu>
|
||||
<Avatar src={appDetail.avatar} w={'1.75rem'} borderRadius={'md'} />
|
||||
<Box>
|
||||
<InfoMenu>
|
||||
<HStack spacing={1} cursor={'pointer'}>
|
||||
<HStack
|
||||
spacing={1}
|
||||
cursor={'pointer'}
|
||||
pl={1}
|
||||
ml={-1}
|
||||
borderRadius={'xs'}
|
||||
_hover={{ bg: 'myGray.150' }}
|
||||
>
|
||||
<Box color={'myGray.900'}>{appDetail.name}</Box>
|
||||
<MyIcon name={'common/select'} w={'1rem'} />
|
||||
<MyIcon name={'common/select'} w={'1rem'} color={'myGray.500'} />
|
||||
</HStack>
|
||||
</InfoMenu>
|
||||
{showSaveStatus && (
|
||||
<Flex alignItems={'center'} h={'20px'} fontSize={'mini'} lineHeight={1}>
|
||||
<Flex alignItems={'center'} fontSize={'mini'} lineHeight={1}>
|
||||
<MyTag
|
||||
py={0}
|
||||
px={0}
|
||||
px={1}
|
||||
showDot
|
||||
bg={'transparent'}
|
||||
colorSchema={
|
||||
@@ -211,15 +240,19 @@ function ExportPopover({
|
||||
return (
|
||||
<MyPopover
|
||||
placement={'right-start'}
|
||||
offset={[0, 0]}
|
||||
offset={[0, 20]}
|
||||
hasArrow
|
||||
trigger={'hover'}
|
||||
w={'8.6rem'}
|
||||
Trigger={
|
||||
<Flex align={'center'} w={'100%'} py={2} px={3}>
|
||||
<Avatar src={'export'} borderRadius={'sm'} w={'1rem'} mr={3} />
|
||||
{t('app:export_configs')}
|
||||
</Flex>
|
||||
// <Flex align={'center'} w={'100%'} py={2} px={3}>
|
||||
// <Avatar src={'export'} borderRadius={'sm'} w={'1rem'} mr={3} />
|
||||
// {t('app:export_configs')}
|
||||
// </Flex>
|
||||
<MyBox display={'flex'} size={'md'} rounded={'4px'} cursor={'pointer'}>
|
||||
<MyIcon name={'export'} w={'16px'} mr={2} />
|
||||
<Box fontSize={'sm'}>{t('app:export_configs')}</Box>
|
||||
</MyBox>
|
||||
}
|
||||
>
|
||||
{({ onClose }) => (
|
||||
|
||||
@@ -116,13 +116,13 @@ const ButtonEdge = (props: EdgeProps) => {
|
||||
(edge) => edge.sourceHandle === sourceHandleId && edge.targetHandle === targetHandleId
|
||||
);
|
||||
if (!targetEdge) {
|
||||
if (highlightEdge) return '#3370ff';
|
||||
if (highlightEdge) return '#487FFF';
|
||||
return '#94B5FF';
|
||||
}
|
||||
|
||||
// debug mode
|
||||
const colorMap = {
|
||||
[RuntimeEdgeStatusEnum.active]: '#39CC83',
|
||||
[RuntimeEdgeStatusEnum.active]: '#487FFF',
|
||||
[RuntimeEdgeStatusEnum.waiting]: '#5E8FFF',
|
||||
[RuntimeEdgeStatusEnum.skipped]: '#8A95A7'
|
||||
};
|
||||
|
||||
@@ -6,10 +6,8 @@ const Container = ({ children, ...props }: BoxProps) => {
|
||||
return (
|
||||
<Flex
|
||||
flexDirection={'column'}
|
||||
px={4}
|
||||
mx={2}
|
||||
mb={2}
|
||||
py={'10px'}
|
||||
mx={4}
|
||||
p={4}
|
||||
position={'relative'}
|
||||
bg={'myGray.50'}
|
||||
border={'1px solid #F0F1F6'}
|
||||
|
||||
@@ -4,7 +4,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
|
||||
const IOTitle = ({ text, ...props }: { text?: 'Input' | 'Output' | string } & StackProps) => {
|
||||
return (
|
||||
<HStack fontSize={'md'} alignItems={'center'} fontWeight={'medium'} mb={3} {...props}>
|
||||
<HStack fontSize={'md'} alignItems={'center'} fontWeight={'medium'} mb={4} {...props}>
|
||||
<Box w={'3px'} h={'14px'} borderRadius={'13px'} bg={'primary.600'} />
|
||||
<Box color={'myGray.900'}>{text}</Box>
|
||||
</HStack>
|
||||
|
||||
@@ -290,7 +290,7 @@ export const useWorkflow = () => {
|
||||
// Loop node size and position
|
||||
const resetParentNodeSizeAndPosition = useMemoizedFn((rect: Rect, parentId: string) => {
|
||||
const width = rect.width + 110 > 900 ? rect.width + 110 : 900;
|
||||
const height = rect.height + 380 > 900 ? rect.height + 380 : 900;
|
||||
const height = rect.height + 420 > 900 ? rect.height + 420 : 900;
|
||||
|
||||
// Update parentNode size and position
|
||||
onChangeNode({
|
||||
|
||||
@@ -80,7 +80,7 @@ const NodeLoopEnd = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
debug: true
|
||||
}}
|
||||
>
|
||||
<Box px={4} pb={4}>
|
||||
<Box px={4} pb={4} pt={2}>
|
||||
{inputItem && <Reference item={inputItem} nodeId={nodeId} />}
|
||||
</Box>
|
||||
</NodeCard>
|
||||
|
||||
@@ -100,7 +100,7 @@ const NodeLoopStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
debug: true
|
||||
}}
|
||||
>
|
||||
<Box px={4} w={'420px'} h={'116px'}>
|
||||
<Box px={4} pt={2} w={'420px'} h={'116px'}>
|
||||
{!loopItemInputType ? (
|
||||
<EmptyTip text={t('workflow:loop_start_tip')} py={0} mt={4} iconSize={'32px'} />
|
||||
) : (
|
||||
|
||||
@@ -99,7 +99,7 @@ const NodeCQNode = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
nodeId={nodeId}
|
||||
handleId={getHandleId(nodeId, 'source', item.key)}
|
||||
position={Position.Right}
|
||||
translate={[26, 0]}
|
||||
translate={[36, 0]}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@@ -60,7 +60,8 @@ const NodeExtract = ({ data }: NodeProps<FlowNodeItemType>) => {
|
||||
</Box>
|
||||
<Button
|
||||
size={'sm'}
|
||||
variant={'whitePrimary'}
|
||||
variant={'ghost'}
|
||||
color={'myGray.600'}
|
||||
leftIcon={<AddIcon fontSize={'10px'} />}
|
||||
onClick={() => setEditExtractField(defaultField)}
|
||||
>
|
||||
@@ -78,12 +79,10 @@ const NodeExtract = ({ data }: NodeProps<FlowNodeItemType>) => {
|
||||
<Table bg={'white'}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th bg={'myGray.50'} borderRadius={'none !important'}>
|
||||
{t('common:item_name')}
|
||||
</Th>
|
||||
<Th bg={'myGray.50'}>{t('common:item_description')}</Th>
|
||||
<Th bg={'myGray.50'}>{t('common:required')}</Th>
|
||||
<Th bg={'myGray.50'} borderRadius={'none !important'}></Th>
|
||||
<Th borderRadius={'none !important'}>{t('common:item_name')}</Th>
|
||||
<Th>{t('common:item_description')}</Th>
|
||||
<Th>{t('common:required')}</Th>
|
||||
<Th borderRadius={'none !important'}></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
FlowValueTypeMap
|
||||
} from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io';
|
||||
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
import MultipleSelect from '@fastgpt/web/components/common/MySelect/MultipleSelect';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
@@ -35,6 +34,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import DndDrag, { Draggable } from '@fastgpt/web/components/common/DndDrag';
|
||||
import MyTextarea from '@/components/common/Textarea/MyTextarea';
|
||||
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';
|
||||
|
||||
type ListValueType = { id: string; value: string; label: string }[];
|
||||
|
||||
@@ -249,8 +249,6 @@ const InputTypeConfig = ({
|
||||
{t('common:core.module.Max Length')}
|
||||
</FormLabel>
|
||||
<MyNumberInput
|
||||
flex={'1 0 0'}
|
||||
bg={'myGray.50'}
|
||||
placeholder={t('common:core.module.Max Length placeholder')}
|
||||
value={maxLength}
|
||||
max={50000}
|
||||
@@ -269,8 +267,6 @@ const InputTypeConfig = ({
|
||||
{t('common:core.module.Max Value')}
|
||||
</FormLabel>
|
||||
<MyNumberInput
|
||||
flex={'1 0 0'}
|
||||
bg={'myGray.50'}
|
||||
value={max}
|
||||
onChange={(e) => {
|
||||
// @ts-ignore
|
||||
@@ -283,8 +279,6 @@ const InputTypeConfig = ({
|
||||
{t('common:core.module.Min Value')}
|
||||
</FormLabel>
|
||||
<MyNumberInput
|
||||
flex={'1 0 0'}
|
||||
bg={'myGray.50'}
|
||||
value={min}
|
||||
onChange={(e) => {
|
||||
// @ts-ignore
|
||||
|
||||
@@ -35,6 +35,7 @@ const FieldEditModal = dynamic(() => import('./InputEditModal'));
|
||||
const NodePluginInput = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
const { t } = useTranslation();
|
||||
const { nodeId, inputs = [], outputs } = data;
|
||||
console.log(outputs);
|
||||
|
||||
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
||||
|
||||
@@ -141,7 +142,7 @@ const NodePluginInput = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
}}
|
||||
/>
|
||||
</Container>
|
||||
{!!outputs.length && (
|
||||
{!!outputs.filter((output) => output.type !== FlowNodeOutputTypeEnum.hidden).length && (
|
||||
<Container>
|
||||
<IOTitle text={t('common:common.Output')} />
|
||||
<RenderOutput nodeId={nodeId} flowOutputList={outputs} />
|
||||
|
||||
@@ -15,7 +15,7 @@ import { WorkflowContext } from '../../context';
|
||||
const NodeSimple = ({
|
||||
data,
|
||||
selected,
|
||||
minW = '350px',
|
||||
minW = '524px',
|
||||
maxW
|
||||
}: NodeProps<FlowNodeItemType> & { minW?: string | number; maxW?: string | number }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -21,6 +21,7 @@ import WelcomeTextConfig from '@/components/core/app/WelcomeTextConfig';
|
||||
import FileSelect from '@/components/core/app/FileSelect';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { userFilesInput } from '@fastgpt/global/core/workflow/template/system/workflowStart';
|
||||
import Container from '../components/Container';
|
||||
|
||||
type ComponentProps = {
|
||||
chatConfig: AppChatConfigType;
|
||||
@@ -49,7 +50,7 @@ const NodeUserGuide = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
return (
|
||||
<>
|
||||
<NodeCard
|
||||
minW={'300px'}
|
||||
minW={'420px'}
|
||||
selected={selected}
|
||||
menuForbid={{
|
||||
debug: true,
|
||||
@@ -58,30 +59,30 @@ const NodeUserGuide = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
}}
|
||||
{...data}
|
||||
>
|
||||
<Box px={4} py={'10px'} position={'relative'} borderRadius={'md'} className="nodrag">
|
||||
<Container>
|
||||
<WelcomeText {...componentsProps} />
|
||||
<Box pt={4}>
|
||||
<Box mt={2} pt={2}>
|
||||
<ChatStartVariable {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'}>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<FileSelectConfig {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'}>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<TTSGuide {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'}>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<WhisperGuide {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'}>
|
||||
<Box mt={3} pt={4} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<QuestionGuide {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'}>
|
||||
<Box mt={4} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<ScheduledTrigger {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'}>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<QuestionInputGuide {...componentsProps} />
|
||||
</Box>
|
||||
</Box>
|
||||
</Container>
|
||||
</NodeCard>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -26,7 +26,7 @@ const NodeTools = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
<RenderOutput nodeId={nodeId} flowOutputList={outputs} />
|
||||
</Container>
|
||||
<Box position={'relative'}>
|
||||
<Box borderBottomLeftRadius={'md'} borderBottomRadius={'md'} overflow={'hidden'}>
|
||||
<Box mb={-4} borderBottomLeftRadius={'md'} borderBottomRadius={'md'} overflow={'hidden'}>
|
||||
<Divider
|
||||
showBorderBottom={false}
|
||||
icon={<MyIcon name="phoneTabbar/tool" w={'16px'} h={'16px'} />}
|
||||
|
||||
@@ -65,7 +65,7 @@ const NodeStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
|
||||
return (
|
||||
<NodeCard
|
||||
minW={'240px'}
|
||||
minW={'420px'}
|
||||
selected={selected}
|
||||
menuForbid={{
|
||||
copy: true,
|
||||
|
||||
@@ -5,6 +5,7 @@ import { handleHighLightStyle, sourceCommonStyle, handleConnectedStyle, handleSi
|
||||
import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowContext } from '../../../../context';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
|
||||
type Props = {
|
||||
nodeId: string;
|
||||
@@ -108,9 +109,7 @@ const MySourceHandle = React.memo(function MySourceHandle({
|
||||
position={position}
|
||||
isConnectableEnd={false}
|
||||
>
|
||||
{showAddIcon && (
|
||||
<SmallAddIcon pointerEvents={'none'} color={'primary.600'} fontWeight={'bold'} />
|
||||
)}
|
||||
{showAddIcon && <MyIcon name={'edgeAdd'} />}
|
||||
</Handle>
|
||||
);
|
||||
}, [handleId, position, showAddIcon, styles, transform]);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const primaryColor = '#3370FF';
|
||||
export const primaryColor = '#487FFF';
|
||||
export const lowPrimaryColor = '#94B5FF';
|
||||
export const handleSize = {
|
||||
width: '18px',
|
||||
|
||||
@@ -25,7 +25,6 @@ import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
import { useWorkflowUtils } from '../../hooks/useUtils';
|
||||
import { WholeResponseContent } from '@/components/core/chat/components/WholeResponseModal';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { getDocPath } from '@/web/common/system/doc';
|
||||
|
||||
type Props = FlowNodeItemType & {
|
||||
@@ -149,15 +148,17 @@ const NodeCard = (props: Props) => {
|
||||
<Box position={'relative'}>
|
||||
{/* debug */}
|
||||
{showHeader && (
|
||||
<Box px={4} py={3}>
|
||||
<Box px={4} pt={4}>
|
||||
{/* tool target handle */}
|
||||
<ToolTargetHandle show={showToolHandle} nodeId={nodeId} />
|
||||
|
||||
{/* avatar and name */}
|
||||
<Flex alignItems={'center'}>
|
||||
{node?.flowNodeType !== FlowNodeTypeEnum.stopTool && (
|
||||
<Box
|
||||
mr={2}
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
mr={1}
|
||||
p={1}
|
||||
cursor={'pointer'}
|
||||
rounded={'sm'}
|
||||
_hover={{ bg: 'myGray.200' }}
|
||||
@@ -172,20 +173,20 @@ const NodeCard = (props: Props) => {
|
||||
>
|
||||
<MyIcon
|
||||
name={!isFolded ? 'core/chat/chevronDown' : 'core/chat/chevronRight'}
|
||||
w={'24px'}
|
||||
h={'24px'}
|
||||
w={'16px'}
|
||||
h={'16px'}
|
||||
color={'myGray.500'}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
)}
|
||||
<Avatar
|
||||
src={avatar}
|
||||
borderRadius={'sm'}
|
||||
objectFit={'contain'}
|
||||
w={'30px'}
|
||||
h={'30px'}
|
||||
w={'24px'}
|
||||
h={'24px'}
|
||||
/>
|
||||
<Box ml={3} fontSize={'md'} fontWeight={'medium'}>
|
||||
<Box ml={2} fontSize={'18px'} fontWeight={'medium'} color={'myGray.900'}>
|
||||
{t(name as any)}
|
||||
</Box>
|
||||
<MyIcon
|
||||
@@ -330,13 +331,16 @@ const NodeCard = (props: Props) => {
|
||||
maxW={maxW}
|
||||
minH={minH}
|
||||
bg={'white'}
|
||||
borderWidth={'1px'}
|
||||
borderRadius={'md'}
|
||||
boxShadow={'1'}
|
||||
outline={selected ? '2px solid' : '1px solid'}
|
||||
borderRadius={'lg'}
|
||||
boxShadow={
|
||||
'0px 4px 10px 0px rgba(19, 51, 107, 0.10), 0px 0px 1px 0px rgba(19, 51, 107, 0.10)'
|
||||
}
|
||||
w={w}
|
||||
h={h}
|
||||
_hover={{
|
||||
boxShadow: '4',
|
||||
boxShadow:
|
||||
'0px 12px 16px -4px rgba(19, 51, 107, 0.20), 0px 0px 1px 0px rgba(19, 51, 107, 0.20)',
|
||||
'& .controller-menu': {
|
||||
display: 'flex'
|
||||
},
|
||||
@@ -351,17 +355,19 @@ const NodeCard = (props: Props) => {
|
||||
onMouseLeave={() => setHoverNodeId(undefined)}
|
||||
{...(isError
|
||||
? {
|
||||
borderColor: 'red.500',
|
||||
outlineColor: 'red.500',
|
||||
onMouseDownCapture: () => onUpdateNodeError(nodeId, false)
|
||||
}
|
||||
: {
|
||||
borderColor: selected ? 'primary.600' : 'borderColor.base'
|
||||
outlineColor: selected ? 'primary.600' : 'myGray.250'
|
||||
})}
|
||||
{...customStyle}
|
||||
>
|
||||
<NodeDebugResponse nodeId={nodeId} debugResult={debugResult} />
|
||||
{Header}
|
||||
{!isFolded && children}
|
||||
<Flex flexDirection={'column'} flex={1} my={4} gap={2}>
|
||||
{!isFolded ? children : <Box h={4} />}
|
||||
</Flex>
|
||||
{RenderHandle}
|
||||
{RenderToolHandle}
|
||||
|
||||
@@ -568,31 +574,35 @@ const NodeIntro = React.memo(function NodeIntro({
|
||||
const Render = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
<Flex alignItems={'flex-end'} py={1}>
|
||||
<Box fontSize={'xs'} color={'myGray.600'} flex={'1 0 0'}>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box fontSize={'sm'} color={'myGray.500'} flex={'1 0 0'}>
|
||||
{t(intro as any)}
|
||||
</Box>
|
||||
{NodeIsTool && (
|
||||
<Button
|
||||
size={'xs'}
|
||||
variant={'whiteBase'}
|
||||
onClick={() => {
|
||||
onOpenIntroModal({
|
||||
defaultVal: intro,
|
||||
onSuccess(e) {
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'attr',
|
||||
key: 'intro',
|
||||
value: e
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t('common:core.module.Edit intro')}
|
||||
</Button>
|
||||
)}
|
||||
<Flex
|
||||
p={'7px'}
|
||||
rounded={'sm'}
|
||||
alignItems={'center'}
|
||||
_hover={{
|
||||
bg: NodeIsTool ? 'myGray.100' : 'transparent'
|
||||
}}
|
||||
cursor={NodeIsTool ? 'pointer' : 'default'}
|
||||
onClick={() => {
|
||||
if (!NodeIsTool) return;
|
||||
onOpenIntroModal({
|
||||
defaultVal: intro,
|
||||
onSuccess(e) {
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
type: 'attr',
|
||||
key: 'intro',
|
||||
value: e
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<MyIcon name={'edit'} w={'18px'} opacity={NodeIsTool ? 1 : 0} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
<EditIntroModal maxLength={500} />
|
||||
</>
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
} from '@chakra-ui/react';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowContext } from '@/pages/app/detail/components/WorkflowComponents/context';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
|
||||
const NumberInputRender = ({ item, nodeId }: RenderInputProps) => {
|
||||
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
||||
@@ -19,6 +20,8 @@ const NumberInputRender = ({ item, nodeId }: RenderInputProps) => {
|
||||
defaultValue={item.value}
|
||||
min={item.min}
|
||||
max={item.max}
|
||||
bg={'white'}
|
||||
rounded={'md'}
|
||||
onChange={(e) => {
|
||||
onChangeNode({
|
||||
nodeId,
|
||||
@@ -31,10 +34,31 @@ const NumberInputRender = ({ item, nodeId }: RenderInputProps) => {
|
||||
});
|
||||
}}
|
||||
>
|
||||
<NumberInputField bg={'white'} px={3} borderRadius={'sm'} />
|
||||
<NumberInputStepper>
|
||||
<NumberIncrementStepper />
|
||||
<NumberDecrementStepper />
|
||||
<NumberInputField
|
||||
bg={'white'}
|
||||
px={3}
|
||||
rounded={'md'}
|
||||
_hover={{
|
||||
borderColor: 'primary.500'
|
||||
}}
|
||||
/>
|
||||
<NumberInputStepper roundedTopRight={'none'}>
|
||||
<NumberIncrementStepper
|
||||
borderTopRightRadius={'sm !important'}
|
||||
_hover={{
|
||||
bg: 'myGray.100'
|
||||
}}
|
||||
>
|
||||
<MyIcon name={'core/chat/chevronUp'} width={'12px'} />
|
||||
</NumberIncrementStepper>
|
||||
<NumberDecrementStepper
|
||||
borderBottomRightRadius={'sm !important'}
|
||||
_hover={{
|
||||
bg: 'myGray.100'
|
||||
}}
|
||||
>
|
||||
<MyIcon name={'core/chat/chevronDown'} width={'12px'} />
|
||||
</NumberDecrementStepper>
|
||||
</NumberInputStepper>
|
||||
</NumberInput>
|
||||
);
|
||||
|
||||
@@ -130,7 +130,7 @@ export const useReference = ({
|
||||
label: (
|
||||
<Flex alignItems={'center'}>
|
||||
<Avatar src={node.avatar} w={'1.25rem'} borderRadius={'xs'} />
|
||||
<Box ml={1}>{t(node.name as any)}</Box>
|
||||
<Box ml={2}>{t(node.name as any)}</Box>
|
||||
</Flex>
|
||||
),
|
||||
value: node.nodeId,
|
||||
@@ -205,7 +205,7 @@ export const ReferSelector = ({
|
||||
selectItemLabel ? (
|
||||
<Flex alignItems={'center'}>
|
||||
{selectItemLabel[0].label}
|
||||
<MyIcon name={'common/rightArrowLight'} mx={1} w={'14px'}></MyIcon>
|
||||
<MyIcon name={'core/chat/chevronRight'} mx={1} w={4} />
|
||||
{selectItemLabel[1].label}
|
||||
</Flex>
|
||||
) : (
|
||||
|
||||
@@ -302,9 +302,9 @@ const SettingQuotePrompt = (props: RenderInputProps) => {
|
||||
return (
|
||||
<>
|
||||
<Flex className="nodrag" cursor={'default'} alignItems={'center'} position={'relative'}>
|
||||
<Box position={'relative'} color={'myGray.600'} fontWeight={'medium'}>
|
||||
<FormLabel position={'relative'} color={'myGray.600'} fontWeight={'medium'}>
|
||||
{t('common:core.module.Dataset quote.label')}
|
||||
</Box>
|
||||
</FormLabel>
|
||||
<ValueTypeLabel
|
||||
valueType={WorkflowIOValueTypeEnum.datasetQuote}
|
||||
valueDesc={datasetQuoteValueDesc}
|
||||
@@ -320,7 +320,7 @@ const SettingQuotePrompt = (props: RenderInputProps) => {
|
||||
/>
|
||||
</MyTooltip>
|
||||
</Flex>
|
||||
<Box mt={1}>
|
||||
<Box mt={3}>
|
||||
<Reference {...props} />
|
||||
</Box>
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ const RenderOutput = ({
|
||||
<FormLabel
|
||||
key={output.key}
|
||||
required={output.required}
|
||||
mb={i === renderOutputs.length - 1 ? 0 : 5}
|
||||
mb={i === renderOutputs.length - 1 ? 0 : 4}
|
||||
position={'relative'}
|
||||
>
|
||||
<OutputLabel nodeId={nodeId} output={output} />
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import React, { useCallback, useMemo, useRef } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
NumberInput,
|
||||
NumberInputField,
|
||||
NumberInputStepper,
|
||||
NumberIncrementStepper,
|
||||
NumberDecrementStepper,
|
||||
Input,
|
||||
Button,
|
||||
ModalBody,
|
||||
@@ -29,6 +24,8 @@ import { useContextSelector } from 'use-context-selector';
|
||||
import { DatasetImportContext } from '../Context';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
|
||||
function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean }) {
|
||||
const { t } = useTranslation();
|
||||
@@ -127,14 +124,7 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
|
||||
<Box>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box>{t('dataset:ideal_chunk_length')}</Box>
|
||||
<MyTooltip label={t('dataset:ideal_chunk_length_tips')}>
|
||||
<MyIcon
|
||||
name={'common/questionLight'}
|
||||
ml={1}
|
||||
w={'14px'}
|
||||
color={'myGray.500'}
|
||||
/>
|
||||
</MyTooltip>
|
||||
<QuestionTip label={t('dataset:ideal_chunk_length_tips')} />
|
||||
</Flex>
|
||||
<Box
|
||||
mt={1}
|
||||
@@ -150,30 +140,18 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
|
||||
max: maxChunkSize
|
||||
})}
|
||||
>
|
||||
<NumberInput
|
||||
size={'sm'}
|
||||
step={100}
|
||||
<MyNumberInput
|
||||
name={chunkSizeField}
|
||||
min={minChunkSize}
|
||||
max={maxChunkSize}
|
||||
size={'sm'}
|
||||
step={100}
|
||||
value={chunkSize}
|
||||
onChange={(e) => {
|
||||
if (e === undefined) return;
|
||||
setValue(chunkSizeField, +e);
|
||||
}}
|
||||
>
|
||||
<NumberInputField
|
||||
min={minChunkSize}
|
||||
max={maxChunkSize}
|
||||
{...register(chunkSizeField, {
|
||||
min: minChunkSize,
|
||||
max: maxChunkSize,
|
||||
valueAsNumber: true
|
||||
})}
|
||||
/>
|
||||
<NumberInputStepper>
|
||||
<NumberIncrementStepper />
|
||||
<NumberDecrementStepper />
|
||||
</NumberInputStepper>
|
||||
</NumberInput>
|
||||
/>
|
||||
</MyTooltip>
|
||||
</Box>
|
||||
</Box>
|
||||
@@ -182,14 +160,9 @@ function DataProcess({ showPreviewChunks = true }: { showPreviewChunks: boolean
|
||||
<Box mt={3}>
|
||||
<Box>
|
||||
{t('common:core.dataset.import.Custom split char')}
|
||||
<MyTooltip label={t('common:core.dataset.import.Custom split char Tips')}>
|
||||
<MyIcon
|
||||
name={'common/questionLight'}
|
||||
ml={1}
|
||||
w={'14px'}
|
||||
color={'myGray.500'}
|
||||
/>
|
||||
</MyTooltip>
|
||||
<QuestionTip
|
||||
label={t('common:core.dataset.import.Custom split char Tips')}
|
||||
/>
|
||||
</Box>
|
||||
<Box mt={1}>
|
||||
<Input
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, Dispatch, useCallback } from 'react';
|
||||
import { FormControl, Box, Input, Button, useDisclosure } from '@chakra-ui/react';
|
||||
import React, { Dispatch } from 'react';
|
||||
import { FormControl, Box, Input, Button } from '@chakra-ui/react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { LoginPageTypeEnum } from '@/web/support/user/login/constants';
|
||||
import { postFindPassword } from '@/web/support/user/api';
|
||||
@@ -73,11 +73,11 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box fontWeight={'bold'} fontSize={'2xl'} textAlign={'center'}>
|
||||
<Box fontWeight={'medium'} fontSize={'lg'} textAlign={'center'} color={'myGray.900'}>
|
||||
{t('user:password.retrieved_account', { account: feConfigs?.systemTitle })}
|
||||
</Box>
|
||||
<Box
|
||||
mt={'42px'}
|
||||
mt={9}
|
||||
onKeyDown={(e) => {
|
||||
if (e.keyCode === 13 && !e.shiftKey && !requesting) {
|
||||
handleSubmit(onclickFindPassword)();
|
||||
@@ -87,6 +87,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<FormControl isInvalid={!!errors.username}>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
size={'lg'}
|
||||
placeholder={placeholder}
|
||||
{...register('username', {
|
||||
required: t('user:password.email_phone_void'),
|
||||
@@ -107,6 +108,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
size={'lg'}
|
||||
flex={1}
|
||||
maxLength={8}
|
||||
placeholder={t('user:password.verification_code')}
|
||||
@@ -120,6 +122,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
type={'password'}
|
||||
size={'lg'}
|
||||
placeholder={t('user:password.new_password')}
|
||||
{...register('password', {
|
||||
required: t('user:password.password_required'),
|
||||
@@ -138,6 +141,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
type={'password'}
|
||||
size={'lg'}
|
||||
placeholder={t('user:password.confirm')}
|
||||
{...register('password2', {
|
||||
validate: (val) =>
|
||||
@@ -148,9 +152,12 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
mt={10}
|
||||
mt={12}
|
||||
w={'100%'}
|
||||
size={['md', 'md']}
|
||||
rounded={['md', 'md']}
|
||||
h={[10, 10]}
|
||||
fontWeight={['medium', 'medium']}
|
||||
colorScheme="blue"
|
||||
isLoading={requesting}
|
||||
onClick={handleSubmit(onclickFindPassword)}
|
||||
@@ -159,9 +166,10 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
</Button>
|
||||
<Box
|
||||
float={'right'}
|
||||
fontSize="sm"
|
||||
mt={2}
|
||||
fontSize="mini"
|
||||
mt={3}
|
||||
mb={'50px'}
|
||||
fontWeight={'medium'}
|
||||
color={'primary.700'}
|
||||
cursor={'pointer'}
|
||||
_hover={{ textDecoration: 'underline' }}
|
||||
|
||||
@@ -80,7 +80,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
return (
|
||||
<FormLayout setPageType={setPageType} pageType={LoginPageTypeEnum.passwordLogin}>
|
||||
<Box
|
||||
mt={'42px'}
|
||||
mt={9}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey && !requesting) {
|
||||
handleSubmit(onclickLogin)();
|
||||
@@ -90,15 +90,17 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<FormControl isInvalid={!!errors.username}>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
size={'lg'}
|
||||
placeholder={placeholder}
|
||||
{...register('username', {
|
||||
required: true
|
||||
})}
|
||||
></Input>
|
||||
</FormControl>
|
||||
<FormControl mt={6} isInvalid={!!errors.password}>
|
||||
<FormControl mt={7} isInvalid={!!errors.password}>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
size={'lg'}
|
||||
type={'password'}
|
||||
placeholder={
|
||||
isCommunityVersion
|
||||
@@ -115,13 +117,19 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
></Input>
|
||||
</FormControl>
|
||||
{feConfigs?.docUrl && (
|
||||
<Flex alignItems={'center'} mt={7} fontSize={'mini'}>
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
mt={7}
|
||||
fontSize={'mini'}
|
||||
color={'myGray.700'}
|
||||
fontWeight={'medium'}
|
||||
>
|
||||
{t('login:policy_tip')}
|
||||
<Link
|
||||
ml={1}
|
||||
href={getDocPath('/docs/agreement/terms/')}
|
||||
target={'_blank'}
|
||||
color={'primary.500'}
|
||||
color={'primary.700'}
|
||||
>
|
||||
{t('login:terms')}
|
||||
</Link>
|
||||
@@ -129,7 +137,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<Link
|
||||
href={getDocPath('/docs/agreement/privacy/')}
|
||||
target={'_blank'}
|
||||
color={'primary.500'}
|
||||
color={'primary.700'}
|
||||
>
|
||||
{t('login:privacy')}
|
||||
</Link>
|
||||
@@ -138,9 +146,11 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
my={6}
|
||||
my={5}
|
||||
w={'100%'}
|
||||
size={['md', 'md']}
|
||||
h={[10, 10]}
|
||||
fontWeight={['medium', 'medium']}
|
||||
colorScheme="blue"
|
||||
isLoading={requesting}
|
||||
onClick={handleSubmit(onclickLogin)}
|
||||
@@ -148,29 +158,34 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
{t('login:Login')}
|
||||
</Button>
|
||||
|
||||
<Flex align={'center'} justifyContent={'flex-end'} color={'primary.700'}>
|
||||
<Flex
|
||||
align={'center'}
|
||||
justifyContent={'flex-end'}
|
||||
color={'primary.700'}
|
||||
fontWeight={'medium'}
|
||||
>
|
||||
{feConfigs?.find_password_method && feConfigs.find_password_method.length > 0 && (
|
||||
<Box
|
||||
cursor={'pointer'}
|
||||
_hover={{ textDecoration: 'underline' }}
|
||||
onClick={() => setPageType('forgetPassword')}
|
||||
fontSize="sm"
|
||||
fontSize="mini"
|
||||
>
|
||||
{t('login:forget_password')}
|
||||
</Box>
|
||||
)}
|
||||
{feConfigs?.register_method && feConfigs.register_method.length > 0 && (
|
||||
<>
|
||||
<Box mx={3} h={'16px'} w={'1.5px'} bg={'myGray.250'}></Box>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box mx={3} h={'12px'} w={'1px'} bg={'myGray.250'}></Box>
|
||||
<Box
|
||||
cursor={'pointer'}
|
||||
_hover={{ textDecoration: 'underline' }}
|
||||
onClick={() => setPageType('register')}
|
||||
fontSize="sm"
|
||||
fontSize="mini"
|
||||
>
|
||||
{t('login:register')}
|
||||
</Box>
|
||||
</>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
@@ -5,7 +5,6 @@ import { Box, Center, Image } from '@chakra-ui/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getWXLoginQR, getWXLoginResult } from '@/web/support/user/api';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import FormLayout from './components/FormLayout';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@@ -40,7 +39,7 @@ const WechatForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
return (
|
||||
<FormLayout setPageType={setPageType} pageType={LoginPageTypeEnum.wechat}>
|
||||
<Box>
|
||||
<Box w={'full'} textAlign={'center'} pt={5}>
|
||||
<Box w={'full'} textAlign={'center'} pt={6} fontWeight={'medium'}>
|
||||
{t('common:support.user.login.wx_qr_login')}
|
||||
</Box>
|
||||
<Box p={5} display={'flex'} w={'full'} justifyContent={'center'}>
|
||||
|
||||
@@ -8,7 +8,6 @@ import { customAlphabet } from 'nanoid';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Dispatch, useRef } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Divider from '@/pages/app/detail/components/WorkflowComponents/Flow/components/Divider';
|
||||
import I18nLngSelector from '@/components/Select/I18nLngSelector';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 8);
|
||||
@@ -64,7 +63,7 @@ const FormLayout = ({ children, setPageType, pageType }: Props) => {
|
||||
{
|
||||
label: t('common:support.user.login.Password login'),
|
||||
provider: LoginPageTypeEnum.passwordLogin,
|
||||
icon: 'support/account/passwordLogin',
|
||||
icon: 'support/permission/privateLight',
|
||||
pageType: LoginPageTypeEnum.passwordLogin
|
||||
}
|
||||
]
|
||||
@@ -77,20 +76,20 @@ const FormLayout = ({ children, setPageType, pageType }: Props) => {
|
||||
return (
|
||||
<Flex flexDirection={'column'} h={'100%'}>
|
||||
<Flex alignItems={'center'} justify={'space-between'}>
|
||||
<Flex>
|
||||
<Flex alignItems={'center'}>
|
||||
<Flex
|
||||
w={['48px', '56px']}
|
||||
h={['48px', '56px']}
|
||||
w={['42px', '56px']}
|
||||
h={['42px', '56px']}
|
||||
bg={'myGray.25'}
|
||||
borderRadius={'xl'}
|
||||
borderWidth={'1.5px'}
|
||||
borderColor={'borderColor.base'}
|
||||
borderRadius={['semilg', 'lg']}
|
||||
borderWidth={['1px', '1.5px']}
|
||||
borderColor={'myGray.200'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
>
|
||||
<Image src={LOGO_ICON} w={['24px', '28px']} alt={'icon'} />
|
||||
<Image src={LOGO_ICON} w={['22.5px', '36px']} alt={'icon'} />
|
||||
</Flex>
|
||||
<Box ml={3} fontSize={['2xl', '3xl']} fontWeight={'bold'}>
|
||||
<Box ml={[3, 5]} fontSize={['lg', 'xl']} fontWeight={'bold'} color={'myGray.900'}>
|
||||
{feConfigs?.systemTitle}
|
||||
</Box>
|
||||
</Flex>
|
||||
@@ -101,26 +100,21 @@ const FormLayout = ({ children, setPageType, pageType }: Props) => {
|
||||
<>
|
||||
<Box flex={1} />
|
||||
<Box position={'relative'}>
|
||||
<Divider />
|
||||
<AbsoluteCenter bg="white" px="4" color={'myGray.500'}>
|
||||
<Box h={'1px'} bg={'myGray.250'} />
|
||||
<AbsoluteCenter bg={'white'} px={3} color={'myGray.500'} fontSize={'mini'}>
|
||||
or
|
||||
</AbsoluteCenter>
|
||||
</Box>
|
||||
<Box mt={8}>
|
||||
<Box mt={4}>
|
||||
{oAuthList.map((item) => (
|
||||
<Box key={item.provider} _notFirst={{ mt: 4 }}>
|
||||
<Button
|
||||
variant={'whitePrimary'}
|
||||
w={'100%'}
|
||||
h={'42px'}
|
||||
leftIcon={
|
||||
<MyIcon
|
||||
name={item.icon as any}
|
||||
w={'20px'}
|
||||
cursor={'pointer'}
|
||||
color={'myGray.800'}
|
||||
/>
|
||||
}
|
||||
h={'40px'}
|
||||
borderRadius={'sm'}
|
||||
fontWeight={'medium'}
|
||||
leftIcon={<MyIcon name={item.icon as any} w={'20px'} />}
|
||||
onClick={() => {
|
||||
item.redirectUrl &&
|
||||
setLoginStore({
|
||||
@@ -142,7 +136,8 @@ const FormLayout = ({ children, setPageType, pageType }: Props) => {
|
||||
<Button
|
||||
variant={'whitePrimary'}
|
||||
w={'100%'}
|
||||
h={'42px'}
|
||||
h={'40px'}
|
||||
borderRadius={'sm'}
|
||||
leftIcon={<Image alt="" src={feConfigs.sso.icon as any} w="20px" />}
|
||||
onClick={() => {
|
||||
feConfigs.sso?.url && router.replace(feConfigs.sso?.url, '_self');
|
||||
|
||||
@@ -102,11 +102,11 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box fontWeight={'bold'} fontSize={'2xl'} textAlign={'center'}>
|
||||
<Box fontWeight={'medium'} fontSize={'lg'} textAlign={'center'} color={'myGray.900'}>
|
||||
{t('user:register.register_account', { account: feConfigs?.systemTitle })}
|
||||
</Box>
|
||||
<Box
|
||||
mt={'42px'}
|
||||
mt={9}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey && !requesting) {
|
||||
handleSubmit(onclickRegister)();
|
||||
@@ -116,6 +116,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<FormControl isInvalid={!!errors.username}>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
size={'lg'}
|
||||
placeholder={placeholder}
|
||||
{...register('username', {
|
||||
required: t('user:password.email_phone_void'),
|
||||
@@ -135,6 +136,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
position={'relative'}
|
||||
>
|
||||
<Input
|
||||
size={'lg'}
|
||||
bg={'myGray.50'}
|
||||
flex={1}
|
||||
maxLength={8}
|
||||
@@ -148,6 +150,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<FormControl mt={6} isInvalid={!!errors.password}>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
size={'lg'}
|
||||
type={'password'}
|
||||
placeholder={t('user:password.new_password')}
|
||||
{...register('password', {
|
||||
@@ -166,6 +169,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
<FormControl mt={6} isInvalid={!!errors.password2}>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
size={'lg'}
|
||||
type={'password'}
|
||||
placeholder={t('user:password.confirm')}
|
||||
{...register('password2', {
|
||||
@@ -176,9 +180,12 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
</FormControl>
|
||||
<Button
|
||||
type="submit"
|
||||
mt={6}
|
||||
mt={12}
|
||||
w={'100%'}
|
||||
size={['md', 'md']}
|
||||
rounded={['md', 'md']}
|
||||
h={[10, 10]}
|
||||
fontWeight={['medium', 'medium']}
|
||||
colorScheme="blue"
|
||||
isLoading={requesting}
|
||||
onClick={handleSubmit(onclickRegister)}
|
||||
@@ -187,9 +194,10 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
</Button>
|
||||
<Box
|
||||
float={'right'}
|
||||
fontSize="sm"
|
||||
mt={2}
|
||||
fontSize="mini"
|
||||
mt={3}
|
||||
mb={'50px'}
|
||||
fontWeight={'medium'}
|
||||
color={'primary.700'}
|
||||
cursor={'pointer'}
|
||||
_hover={{ textDecoration: 'underline' }}
|
||||
|
||||
@@ -145,7 +145,6 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => {
|
||||
backgroundSize={'cover'}
|
||||
userSelect={'none'}
|
||||
h={'100%'}
|
||||
px={[0, '10vw']}
|
||||
>
|
||||
{isPc && (
|
||||
<Box position={'absolute'} top={'24px'} right={'50px'}>
|
||||
@@ -154,16 +153,15 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => {
|
||||
)}
|
||||
<Flex
|
||||
flexDirection={'column'}
|
||||
w={['100%', 'auto']}
|
||||
h={['100%', '700px']}
|
||||
maxH={['100%', '90vh']}
|
||||
w={['100%', '556px']}
|
||||
h={['100%', '677px']}
|
||||
bg={'white'}
|
||||
px={['5vw', '88px']}
|
||||
py={'5vh'}
|
||||
borderRadius={[0, '24px']}
|
||||
py={['5vh', '64px']}
|
||||
borderRadius={[0, '16px']}
|
||||
boxShadow={[
|
||||
'',
|
||||
'0px 0px 1px 0px rgba(19, 51, 107, 0.20), 0px 32px 64px -12px rgba(19, 51, 107, 0.20)'
|
||||
'0px 32px 64px -12px rgba(19, 51, 107, 0.20), 0px 0px 1px 0px rgba(19, 51, 107, 0.20)'
|
||||
]}
|
||||
>
|
||||
<Box w={['100%', '380px']} flex={'1 0 0'}>
|
||||
@@ -179,6 +177,8 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => {
|
||||
<Box
|
||||
mt={8}
|
||||
color={'primary.700'}
|
||||
fontSize={'mini'}
|
||||
fontWeight={'medium'}
|
||||
cursor={'pointer'}
|
||||
textAlign={'center'}
|
||||
onClick={onOpen}
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
Grid,
|
||||
NumberDecrementStepper,
|
||||
NumberInput,
|
||||
NumberIncrementStepper,
|
||||
NumberInputField,
|
||||
NumberInputStepper,
|
||||
Button
|
||||
} from '@chakra-ui/react';
|
||||
import { Box, Flex, Grid, Button } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
@@ -19,6 +9,7 @@ import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { getWxPayQRCode } from '@/web/support/wallet/bill/api';
|
||||
import { BillTypeEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
import QRCodePayModal, { type QRPayProps } from '@/components/support/wallet/QRCodePayModal';
|
||||
import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput';
|
||||
|
||||
const ExtraPlan = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -170,22 +161,14 @@ const ExtraPlan = () => {
|
||||
{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'}
|
||||
{...registerDatasetSize('month', {
|
||||
required: true,
|
||||
min: 1,
|
||||
max: 12,
|
||||
valueAsNumber: true
|
||||
})}
|
||||
/>
|
||||
<NumberInputStepper>
|
||||
<NumberIncrementStepper />
|
||||
<NumberDecrementStepper />
|
||||
</NumberInputStepper>
|
||||
</NumberInput>
|
||||
<Box position={'absolute'} right={'20px'} color={'myGray.600'} fontSize={'xs'}>
|
||||
<MyNumberInput
|
||||
name="month"
|
||||
register={registerDatasetSize}
|
||||
min={1}
|
||||
max={12}
|
||||
size={'sm'}
|
||||
/>
|
||||
<Box position={'absolute'} right={'30px'} color={'myGray.600'} fontSize={'xs'}>
|
||||
{t('common:common.month')}
|
||||
</Box>
|
||||
</Flex>
|
||||
@@ -195,30 +178,14 @@ const ExtraPlan = () => {
|
||||
{t('common:support.wallet.subscription.Update extra dataset size')}
|
||||
</Box>
|
||||
<Flex alignItems={'center'} mt={1} w={'180px'} position={'relative'}>
|
||||
<NumberInput
|
||||
size={'sm'}
|
||||
flex={1}
|
||||
<MyNumberInput
|
||||
name="datasetSize"
|
||||
register={registerDatasetSize}
|
||||
min={0}
|
||||
max={10000}
|
||||
step={1}
|
||||
position={'relative'}
|
||||
>
|
||||
<NumberInputField
|
||||
pr={'30px'}
|
||||
{...registerDatasetSize('datasetSize', {
|
||||
required: true,
|
||||
min: 0,
|
||||
max: 10000,
|
||||
valueAsNumber: true
|
||||
})}
|
||||
step={1}
|
||||
/>
|
||||
<NumberInputStepper>
|
||||
<NumberIncrementStepper />
|
||||
<NumberDecrementStepper />
|
||||
</NumberInputStepper>
|
||||
</NumberInput>
|
||||
<Box position={'absolute'} right={'20px'} color={'myGray.600'} fontSize={'xs'}>
|
||||
size={'sm'}
|
||||
/>
|
||||
<Box position={'absolute'} right={'30px'} color={'myGray.600'} fontSize={'xs'}>
|
||||
000{t('common:core.dataset.data.unit')}
|
||||
</Box>
|
||||
</Flex>
|
||||
@@ -291,30 +258,14 @@ const ExtraPlan = () => {
|
||||
position={'relative'}
|
||||
color={'myGray.500'}
|
||||
>
|
||||
<NumberInput
|
||||
size={'sm'}
|
||||
flex={1}
|
||||
<MyNumberInput
|
||||
name="points"
|
||||
register={registerDatasetSize}
|
||||
min={0}
|
||||
max={10000}
|
||||
step={1}
|
||||
position={'relative'}
|
||||
>
|
||||
<NumberInputField
|
||||
pr={'30px'}
|
||||
step={1}
|
||||
{...registerExtraPoints('points', {
|
||||
required: true,
|
||||
min: 0,
|
||||
max: 10000,
|
||||
valueAsNumber: true
|
||||
})}
|
||||
/>
|
||||
<NumberInputStepper>
|
||||
<NumberIncrementStepper />
|
||||
<NumberDecrementStepper />
|
||||
</NumberInputStepper>
|
||||
</NumberInput>
|
||||
<Box position={'absolute'} right={'20px'} color={'myGray.500'} fontSize={'xs'}>
|
||||
size={'sm'}
|
||||
/>
|
||||
<Box position={'absolute'} right={'30px'} color={'myGray.500'} fontSize={'xs'}>
|
||||
{'000' + t('common:support.wallet.subscription.point')}
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
@@ -64,7 +64,8 @@ export const useSendCode = ({ type }: { type: `${UserAuthTypeEnum}` }) => {
|
||||
position={'absolute'}
|
||||
right={3}
|
||||
zIndex={1}
|
||||
fontSize={'sm'}
|
||||
fontSize={'mini'}
|
||||
fontWeight={'medium'}
|
||||
{...styles}
|
||||
{...(codeCountDown > 0
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user