chore(ui): login page & workflow page (#3046)
* login page & number input & multirow select & llm select * workflow * adjust nodes
This commit is contained in:
@@ -1,12 +1,37 @@
|
||||
<svg width="1041" height="1348" viewBox="0 0 1041 1348" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M340.837 0.33933L681.068 0.338989V0.455643C684.032 0.378397 686.999 0.339702 689.967 0.339702C735.961 0.3397 781.504 9.62899 823.997 27.6772C866.49 45.7254 905.099 72.1791 937.622 105.528C970.144 138.877 995.942 178.467 1013.54 222.04C1031.14 265.612 1040.2 312.312 1040.2 359.474L340.836 359.474L340.836 1347.84C296.157 1347.84 251.914 1338.55 210.636 1320.49C169.357 1302.43 131.85 1275.95 100.257 1242.58C68.6636 1209.21 43.6023 1169.59 26.5041 1125.99C11.3834 1087.43 2.75216 1046.42 0.957956 1004.81H0.605869L0.605897 368.098H0.70363C0.105752 341.831 2.23741 315.443 7.14306 289.411C20.2709 219.745 52.6748 155.754 100.257 105.528C147.839 55.3017 208.462 21.0975 274.461 7.24017C296.426 2.62833 318.657 0.339101 340.837 0.33933Z" fill="url(#paint0_linear_1172_228)"/>
|
||||
<path d="M633.639 904.645H513.029V576.37H635.422V576.377C678.161 576.607 720.454 585.093 759.951 601.37C799.997 617.874 836.384 642.064 867.033 672.559C897.683 703.054 921.996 739.257 938.583 779.101C955.171 818.944 963.709 861.648 963.709 904.775H633.639V904.645Z" fill="url(#paint1_linear_1172_228)"/>
|
||||
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21.5938 10.9C21.5938 9.45229 21.1475 8.03706 20.3113 6.8333C19.4751 5.62954 18.2866 4.69132 16.8961 4.13729C15.5056 3.58326 13.9755 3.4383 12.4993 3.72075C11.0231 4.00319 9.66715 4.70034 8.60288 5.72406C7.53861 6.74777 6.81384 8.05206 6.52021 9.47199C6.22658 10.8919 6.37728 12.3637 6.95326 13.7013C7.52923 15.0388 8.50462 16.182 9.75606 16.9864C11.0075 17.7907 12.4788 18.22 13.9839 18.22V10.9H21.5938Z" fill="url(#paint0_linear_0_5622)"/>
|
||||
<path d="M29.6263 10.9C29.6263 9.93877 29.4498 8.98691 29.1069 8.09882C28.764 7.21072 28.2613 6.40377 27.6277 5.72405C26.9941 5.04433 26.2418 4.50515 25.414 4.13729C24.5861 3.76943 23.6987 3.58009 22.8027 3.58009C21.9066 3.58009 21.0192 3.76943 20.1913 4.13729C19.3635 4.50515 18.6112 5.04434 17.9776 5.72406C17.344 6.40378 16.8413 7.21072 16.4984 8.09882C16.1555 8.98692 15.979 9.93877 15.979 10.9L29.6263 10.9Z" fill="url(#paint1_linear_0_5622)"/>
|
||||
<path d="M28.3745 22.634C28.3745 21.8174 28.2342 21.0087 27.9617 20.2543C27.6892 19.4998 27.2898 18.8143 26.7863 18.2368C26.2828 17.6594 25.685 17.2013 25.0272 16.8888C24.3693 16.5763 23.6642 16.4155 22.9521 16.4155V22.634H28.3745Z" fill="url(#paint2_linear_0_5622)"/>
|
||||
<path d="M13.9836 20.3912C12.9843 20.3912 11.9947 20.5635 11.0715 20.8985C10.1482 21.2334 9.30926 21.7242 8.60262 22.3431C7.89597 22.9619 7.33543 23.6966 6.95299 24.5051C6.57056 25.3137 6.37372 26.1803 6.37372 27.0554C6.37372 27.9306 6.57056 28.7972 6.95299 29.6057C7.33543 30.4143 7.89597 31.1489 8.60262 31.7678C9.30926 32.3866 10.1482 32.8775 11.0715 33.2124C11.9947 33.5473 12.9843 33.7197 13.9836 33.7197L13.9836 20.3912Z" fill="url(#paint3_linear_0_5622)"/>
|
||||
<path d="M13.9837 10.6101L13.9837 26.9823L6.3736 26.9823L6.3736 10.6101H13.9837Z" fill="url(#paint4_linear_0_5622)"/>
|
||||
<path d="M23.0327 10.8988L13.8973 10.8988L13.8973 3.58008L23.0327 3.58008V10.8988Z" fill="url(#paint5_linear_0_5622)"/>
|
||||
<path d="M23.0327 22.6316H17.9771V16.4155L23.0327 16.4155V22.6316Z" fill="url(#paint6_linear_0_5622)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_1172_228" x1="520.404" y1="0.338989" x2="520.404" y2="1347.84" gradientUnits="userSpaceOnUse">
|
||||
<linearGradient id="paint0_linear_0_5622" x1="18" y1="3.58008" x2="18" y2="33.7197" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#326DFF"/>
|
||||
<stop offset="1" stop-color="#8EAEFF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1172_228" x1="738.369" y1="576.37" x2="738.369" y2="904.775" gradientUnits="userSpaceOnUse">
|
||||
<linearGradient id="paint1_linear_0_5622" x1="18" y1="3.58008" x2="18" y2="33.7197" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#326DFF"/>
|
||||
<stop offset="1" stop-color="#8EAEFF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_0_5622" x1="18" y1="3.58008" x2="18" y2="33.7197" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#326DFF"/>
|
||||
<stop offset="1" stop-color="#8EAEFF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_0_5622" x1="18" y1="3.58008" x2="18" y2="33.7197" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#326DFF"/>
|
||||
<stop offset="1" stop-color="#8EAEFF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_0_5622" x1="18" y1="3.58008" x2="18" y2="33.7197" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#326DFF"/>
|
||||
<stop offset="1" stop-color="#8EAEFF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_0_5622" x1="18" y1="3.58008" x2="18" y2="33.7197" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#326DFF"/>
|
||||
<stop offset="1" stop-color="#8EAEFF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_0_5622" x1="18" y1="3.58008" x2="18" y2="33.7197" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#326DFF"/>
|
||||
<stop offset="1" stop-color="#8EAEFF"/>
|
||||
</linearGradient>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 3.4 KiB |
4
projects/app/public/icon/resizer.svg
Normal file
4
projects/app/public/icon/resizer.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="12" height="11" viewBox="0 0 12 11" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.45093 7.94055L8.82385 0.567627" stroke="#8A95A7" stroke-linecap="round"/>
|
||||
<path d="M4.8418 7.953L8.82373 3.97107" stroke="#8A95A7" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 271 B |
@@ -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