mirror of
https://github.com/labring/FastGPT.git
synced 2025-11-28 01:04:42 +08:00
fix: start node check (#5794)
* fix: start node check * remove log * fix: variables refresh * fix: workflow start check * fix: variables refresh * perf: auto save * perf: add log
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
||||
Textarea,
|
||||
HStack
|
||||
} from '@chakra-ui/react';
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
@@ -61,105 +61,91 @@ const ScheduledTriggerConfig = ({
|
||||
}
|
||||
}, []);
|
||||
|
||||
const Render = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/schedulePlan'} w={'20px'} />
|
||||
<HStack ml={2} flex={1} spacing={1}>
|
||||
<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')}>
|
||||
<Button
|
||||
variant={'transparentBase'}
|
||||
iconSpacing={1}
|
||||
size={'sm'}
|
||||
mr={'-5px'}
|
||||
color={'myGray.600'}
|
||||
onClick={onOpen}
|
||||
>
|
||||
{cronString2Label(value?.cronString ?? '', t)}
|
||||
</Button>
|
||||
</MyTooltip>
|
||||
</Flex>
|
||||
return (
|
||||
<>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'core/app/schedulePlan'} w={'20px'} />
|
||||
<HStack ml={2} flex={1} spacing={1}>
|
||||
<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')}>
|
||||
<Button
|
||||
variant={'transparentBase'}
|
||||
iconSpacing={1}
|
||||
size={'sm'}
|
||||
mr={'-5px'}
|
||||
color={'myGray.600'}
|
||||
onClick={onOpen}
|
||||
>
|
||||
{cronString2Label(value?.cronString ?? '', t)}
|
||||
</Button>
|
||||
</MyTooltip>
|
||||
</Flex>
|
||||
|
||||
<MyModal
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
iconSrc={'core/app/schedulePlan'}
|
||||
title={t('common:core.app.Interval timer config')}
|
||||
overflow={'unset'}
|
||||
>
|
||||
<ModalBody>
|
||||
<Flex justifyContent={'space-between'} alignItems={'center'}>
|
||||
<FormLabel flex={'0 0 80px'}>{t('common:core.app.schedule.Open schedule')}</FormLabel>
|
||||
<Switch
|
||||
isChecked={isOpenSchedule}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
onUpdate({ cronString: defaultCronString });
|
||||
} else {
|
||||
onUpdate({ cronString: '' });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
{isOpenSchedule && (
|
||||
<>
|
||||
<Flex alignItems={'center'} mt={5}>
|
||||
<FormLabel flex={'0 0 80px'}>{t('app:execute_time')}</FormLabel>
|
||||
<Box flex={'1 0 0'}>
|
||||
<ScheduleTimeSelect
|
||||
cronString={value?.cronString}
|
||||
onChange={(e) => {
|
||||
onUpdate({ cronString: e });
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} mt={5}>
|
||||
<FormLabel flex={'0 0 80px'}>{t('app:time_zone')}</FormLabel>
|
||||
<Box flex={'1 0 0'}>
|
||||
<TimezoneSelect
|
||||
value={timezone}
|
||||
onChange={(e) => {
|
||||
onUpdate({ timezone: e });
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box mt={5}>
|
||||
<FormLabel mb={1}>{t('common:core.app.schedule.Default prompt')}</FormLabel>
|
||||
<Textarea
|
||||
value={defaultPrompt}
|
||||
rows={8}
|
||||
bg={'myGray.50'}
|
||||
placeholder={t('common:core.app.schedule.Default prompt placeholder')}
|
||||
<MyModal
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
iconSrc={'core/app/schedulePlan'}
|
||||
title={t('common:core.app.Interval timer config')}
|
||||
overflow={'unset'}
|
||||
>
|
||||
<ModalBody>
|
||||
<Flex justifyContent={'space-between'} alignItems={'center'}>
|
||||
<FormLabel flex={'0 0 80px'}>{t('common:core.app.schedule.Open schedule')}</FormLabel>
|
||||
<Switch
|
||||
isChecked={isOpenSchedule}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
onUpdate({ cronString: defaultCronString });
|
||||
} else {
|
||||
onUpdate({ cronString: '' });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
{isOpenSchedule && (
|
||||
<>
|
||||
<Flex alignItems={'center'} mt={5}>
|
||||
<FormLabel flex={'0 0 80px'}>{t('app:execute_time')}</FormLabel>
|
||||
<Box flex={'1 0 0'}>
|
||||
<ScheduleTimeSelect
|
||||
cronString={value?.cronString}
|
||||
onChange={(e) => {
|
||||
onUpdate({ defaultPrompt: e.target.value });
|
||||
onUpdate({ cronString: e });
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</ModalBody>
|
||||
</MyModal>
|
||||
</>
|
||||
);
|
||||
}, [
|
||||
defaultPrompt,
|
||||
isOpen,
|
||||
isOpenSchedule,
|
||||
onClose,
|
||||
onOpen,
|
||||
onUpdate,
|
||||
t,
|
||||
timezone,
|
||||
value?.cronString
|
||||
]);
|
||||
|
||||
return Render;
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} mt={5}>
|
||||
<FormLabel flex={'0 0 80px'}>{t('app:time_zone')}</FormLabel>
|
||||
<Box flex={'1 0 0'}>
|
||||
<TimezoneSelect
|
||||
value={timezone}
|
||||
onChange={(e) => {
|
||||
onUpdate({ timezone: e });
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box mt={5}>
|
||||
<FormLabel mb={1}>{t('common:core.app.schedule.Default prompt')}</FormLabel>
|
||||
<Textarea
|
||||
value={defaultPrompt}
|
||||
rows={8}
|
||||
bg={'myGray.50'}
|
||||
placeholder={t('common:core.app.schedule.Default prompt placeholder')}
|
||||
onChange={(e) => {
|
||||
onUpdate({ defaultPrompt: e.target.value });
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</ModalBody>
|
||||
</MyModal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(ScheduledTriggerConfig);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { type Dispatch, useMemo } from 'react';
|
||||
import React, { type Dispatch, useCallback, useMemo } from 'react';
|
||||
import { type NodeProps, useViewport } from 'reactflow';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { type FlowNodeItemType } from '@fastgpt/global/core/workflow/type/node.d';
|
||||
@@ -18,12 +18,10 @@ import {
|
||||
type AppDetailType,
|
||||
type VariableItemType
|
||||
} from '@fastgpt/global/core/app/type';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import VariableEdit from '@/components/core/app/VariableEdit';
|
||||
import { AppContext } from '@/pageComponents/app/detail/context';
|
||||
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';
|
||||
import AutoExecConfig from '@/components/core/app/AutoExecConfig';
|
||||
@@ -44,7 +42,7 @@ const NodeUserGuide = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
systemConfigNode: data,
|
||||
isPublicFetch: true
|
||||
});
|
||||
}, [data, appDetail]);
|
||||
}, [data, appDetail.chatConfig]);
|
||||
|
||||
const componentsProps = useMemo(
|
||||
() => ({
|
||||
@@ -54,51 +52,47 @@ const NodeUserGuide = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
[chatConfig, setAppDetail]
|
||||
);
|
||||
|
||||
const Render = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
<NodeCard
|
||||
selected={selected}
|
||||
menuForbid={{
|
||||
debug: true,
|
||||
copy: true,
|
||||
delete: true
|
||||
}}
|
||||
{...data}
|
||||
>
|
||||
<Container>
|
||||
<WelcomeText {...componentsProps} />
|
||||
<Box mt={2} pt={2}>
|
||||
<ChatStartVariable {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<FileSelectConfig {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<TTSGuide {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<WhisperGuide {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={4} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<QuestionGuide {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={4} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<ScheduledTrigger {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<AutoExecute {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<QuestionInputGuide {...componentsProps} />
|
||||
</Box>
|
||||
</Container>
|
||||
</NodeCard>
|
||||
</>
|
||||
);
|
||||
}, [componentsProps, data, selected]);
|
||||
|
||||
return Render;
|
||||
return (
|
||||
<>
|
||||
<NodeCard
|
||||
selected={selected}
|
||||
menuForbid={{
|
||||
debug: true,
|
||||
copy: true,
|
||||
delete: true
|
||||
}}
|
||||
{...data}
|
||||
>
|
||||
<Container>
|
||||
<WelcomeText {...componentsProps} />
|
||||
<Box mt={2} pt={2}>
|
||||
<ChatStartVariable {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<FileSelectConfig {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<TTSGuide {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<WhisperGuide {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={4} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<QuestionGuide {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={4} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<ScheduledTrigger {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<AutoExecute {...componentsProps} />
|
||||
</Box>
|
||||
<Box mt={3} pt={3} borderTop={'base'} borderColor={'myGray.200'}>
|
||||
<QuestionInputGuide {...componentsProps} />
|
||||
</Box>
|
||||
</Container>
|
||||
</NodeCard>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(NodeUserGuide);
|
||||
@@ -124,15 +118,18 @@ function WelcomeText({ chatConfig: { welcomeText }, setAppDetail }: ComponentPro
|
||||
}
|
||||
|
||||
function ChatStartVariable({ chatConfig: { variables = [] }, setAppDetail }: ComponentProps) {
|
||||
const updateVariables = useMemoizedFn((value: VariableItemType[]) => {
|
||||
setAppDetail((state) => ({
|
||||
...state,
|
||||
chatConfig: {
|
||||
...state.chatConfig,
|
||||
variables: value
|
||||
}
|
||||
}));
|
||||
});
|
||||
const updateVariables = useCallback(
|
||||
(value: VariableItemType[]) => {
|
||||
setAppDetail((state) => ({
|
||||
...state,
|
||||
chatConfig: {
|
||||
...state.chatConfig,
|
||||
variables: value
|
||||
}
|
||||
}));
|
||||
},
|
||||
[setAppDetail]
|
||||
);
|
||||
const { zoom } = useViewport();
|
||||
|
||||
return <VariableEdit variables={variables} onChange={(e) => updateVariables(e)} zoom={zoom} />;
|
||||
|
||||
@@ -8,7 +8,6 @@ import IOTitle from '../components/IOTitle';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowBufferDataContext } from '../../context/workflowInitContext';
|
||||
import { useCreation } from 'ahooks';
|
||||
import { type FlowNodeOutputItemType } from '@fastgpt/global/core/workflow/type/io';
|
||||
import { FlowNodeOutputTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
@@ -16,8 +15,7 @@ import { AppContext } from '@/pageComponents/app/detail/context';
|
||||
import { workflowSystemVariables } from '@/web/core/app/utils';
|
||||
import {
|
||||
formatEditorVariablePickerIcon,
|
||||
getAppChatConfig,
|
||||
getGuideModule
|
||||
getAppChatConfig
|
||||
} from '@fastgpt/global/core/workflow/utils';
|
||||
import MyDivider from '@fastgpt/web/components/common/MyDivider';
|
||||
import { useMemoEnhance } from '@fastgpt/web/hooks/useMemoEnhance';
|
||||
@@ -48,9 +46,9 @@ const NodeStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
valueDesc: item.valueDesc
|
||||
};
|
||||
});
|
||||
}, [systemConfigNode, appDetail.chatConfig, t]);
|
||||
}, [appDetail.chatConfig, systemConfigNode, t]);
|
||||
|
||||
const systemVariables = useMemo(
|
||||
const systemVariables = useMemoEnhance(
|
||||
() =>
|
||||
workflowSystemVariables.map((item) => ({
|
||||
id: item.key,
|
||||
|
||||
@@ -14,7 +14,7 @@ import React, {
|
||||
useState
|
||||
} from 'react';
|
||||
import { createContext, useContextSelector } from 'use-context-selector';
|
||||
import { useDebounceEffect } from 'ahooks';
|
||||
import { useDebounceEffect, useMemoizedFn, useUnmount } from 'ahooks';
|
||||
import { WorkflowBufferDataContext, WorkflowInitContext } from './workflowInitContext';
|
||||
import { compareSnapshot } from '@/web/core/workflow/utils';
|
||||
import { AppContext } from '@/pageComponents/app/detail/context';
|
||||
@@ -105,13 +105,10 @@ export const WorkflowPersistenceProvider: React.FC<PropsWithChildren> = ({ child
|
||||
}, [appDetail.chatConfig, flowData2StoreData, isSaved, onSaveApp]);
|
||||
|
||||
// 页面关闭前自动保存
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (isProduction) {
|
||||
autoSaveFn();
|
||||
}
|
||||
};
|
||||
}, [autoSaveFn]);
|
||||
useUnmount(() => {
|
||||
autoSaveFn();
|
||||
});
|
||||
|
||||
useBeforeunload({
|
||||
tip: t('common:core.tip.leave page'),
|
||||
callback: autoSaveFn
|
||||
|
||||
@@ -188,12 +188,7 @@ const SelectAppModal = ({
|
||||
onClick={handleItemClick}
|
||||
>
|
||||
<Flex alignItems={'center'} w={'1.25rem'} onClick={(e) => e.stopPropagation()}>
|
||||
{!isFolder && (
|
||||
<Checkbox
|
||||
isChecked={selected}
|
||||
onChange={handleItemClick}
|
||||
/>
|
||||
)}
|
||||
{!isFolder && <Checkbox isChecked={selected} onChange={handleItemClick} />}
|
||||
</Flex>
|
||||
<Avatar src={item.avatar} w="1.5rem" borderRadius={'sm'} />
|
||||
<Box>{item.name}</Box>
|
||||
|
||||
Reference in New Issue
Block a user