mirror of
https://github.com/labring/FastGPT.git
synced 2025-08-01 20:27:45 +00:00
External dataset (#1485)
* fix: revert version * feat: external collection * import context * external ui * doc * fix: ts * clear invalid data * feat: rename sub name * fix: node if else edge remove * fix: init * api size * fix: if else node refresh
This commit is contained in:
14
projects/app/src/components/common/NextHead/index.tsx
Normal file
14
projects/app/src/components/common/NextHead/index.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import Head from 'next/head';
|
||||
import React from 'react';
|
||||
|
||||
const NextHead = ({ title, icon, desc }: { title?: string; icon?: string; desc?: string }) => {
|
||||
return (
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
{desc && <meta name="description" content={desc} />}
|
||||
{icon && <link rel="icon" href={icon} />}
|
||||
</Head>
|
||||
);
|
||||
};
|
||||
|
||||
export default NextHead;
|
@@ -1,12 +1,12 @@
|
||||
import { Box, Flex, FlexProps } from '@chakra-ui/react';
|
||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React from 'react';
|
||||
import { DatasetTypeMap } from '@fastgpt/global/core/dataset/constants';
|
||||
import { useI18n } from '@/web/context/I18n';
|
||||
|
||||
const DatasetTypeTag = ({ type, ...props }: { type: `${DatasetTypeEnum}` } & FlexProps) => {
|
||||
const { t } = useTranslation();
|
||||
const DatasetTypeTag = ({ type, ...props }: { type: DatasetTypeEnum } & FlexProps) => {
|
||||
const { datasetT } = useI18n();
|
||||
|
||||
const item = DatasetTypeMap[type] || DatasetTypeMap['dataset'];
|
||||
|
||||
@@ -22,7 +22,8 @@ const DatasetTypeTag = ({ type, ...props }: { type: `${DatasetTypeEnum}` } & Fle
|
||||
{...props}
|
||||
>
|
||||
<MyIcon name={item.icon as any} w={'16px'} mr={2} color={'myGray.400'} />
|
||||
<Box>{t(item.label)}</Box>
|
||||
{/* @ts-ignore */}
|
||||
<Box>{datasetT(item.label)}</Box>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@@ -50,16 +50,11 @@ const ListItem = ({
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { getZoom } = useReactFlow();
|
||||
const onDelEdge = useContextSelector(WorkflowContext, (v) => v.onDelEdge);
|
||||
const handleId = getHandleId(nodeId, 'source', getElseIFLabel(conditionIndex));
|
||||
|
||||
return (
|
||||
<Box
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
style={{
|
||||
...provided.draggableProps.style,
|
||||
opacity: snapshot.isDragging ? 0.8 : 1
|
||||
}}
|
||||
>
|
||||
const Render = useMemo(() => {
|
||||
return (
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
position={'relative'}
|
||||
@@ -68,7 +63,10 @@ const ListItem = ({
|
||||
>
|
||||
<Container w={snapshot.isDragging ? '' : 'full'} className="nodrag">
|
||||
<Flex mb={4} alignItems={'center'}>
|
||||
{ifElseList.length > 1 && <DragIcon provided={provided} />}
|
||||
<DragIcon
|
||||
visibility={ifElseList.length > 1 ? 'visible' : 'hidden'}
|
||||
provided={provided}
|
||||
/>
|
||||
<Box color={'black'} fontSize={'lg'} ml={2}>
|
||||
{getElseIFLabel(conditionIndex)}
|
||||
</Box>
|
||||
@@ -109,6 +107,10 @@ const ListItem = ({
|
||||
color={'myGray.400'}
|
||||
onClick={() => {
|
||||
onUpdateIfElseList(ifElseList.filter((_, index) => index !== conditionIndex));
|
||||
onDelEdge({
|
||||
nodeId,
|
||||
sourceHandle: handleId
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@@ -185,21 +187,21 @@ const ListItem = ({
|
||||
onChange={(e) => {
|
||||
onUpdateIfElseList(
|
||||
ifElseList.map((ifElse, index) => {
|
||||
if (index === conditionIndex) {
|
||||
return {
|
||||
...ifElse,
|
||||
list: ifElse.list.map((item, index) => {
|
||||
if (index === i) {
|
||||
return {
|
||||
...item,
|
||||
value: e
|
||||
};
|
||||
}
|
||||
return item;
|
||||
})
|
||||
};
|
||||
}
|
||||
return ifElse;
|
||||
return {
|
||||
...ifElse,
|
||||
list:
|
||||
index === conditionIndex
|
||||
? ifElse.list.map((item, index) => {
|
||||
if (index === i) {
|
||||
return {
|
||||
...item,
|
||||
value: e
|
||||
};
|
||||
}
|
||||
return item;
|
||||
})
|
||||
: ifElse.list
|
||||
};
|
||||
})
|
||||
);
|
||||
}}
|
||||
@@ -263,12 +265,38 @@ const ListItem = ({
|
||||
{!snapshot.isDragging && (
|
||||
<SourceHandle
|
||||
nodeId={nodeId}
|
||||
handleId={getHandleId(nodeId, 'source', getElseIFLabel(conditionIndex))}
|
||||
handleId={handleId}
|
||||
position={Position.Right}
|
||||
translate={[18, 0]}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
}, [
|
||||
conditionIndex,
|
||||
conditionItem.condition,
|
||||
conditionItem.list,
|
||||
getZoom,
|
||||
handleId,
|
||||
ifElseList,
|
||||
nodeId,
|
||||
onDelEdge,
|
||||
onUpdateIfElseList,
|
||||
provided,
|
||||
snapshot.isDragging,
|
||||
t
|
||||
]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
style={{
|
||||
...provided.draggableProps.style,
|
||||
opacity: snapshot.isDragging ? 0.8 : 1
|
||||
}}
|
||||
>
|
||||
{Render}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -387,35 +415,39 @@ const ConditionValueInput = ({
|
||||
return output.valueType;
|
||||
}, [nodeList, variable]);
|
||||
|
||||
if (valueType === WorkflowIOValueTypeEnum.boolean) {
|
||||
return (
|
||||
<MySelect
|
||||
list={[
|
||||
{ label: 'True', value: 'true' },
|
||||
{ label: 'False', value: 'false' }
|
||||
]}
|
||||
onchange={onChange}
|
||||
value={value}
|
||||
placeholder={'选择值'}
|
||||
isDisabled={
|
||||
condition === VariableConditionEnum.isEmpty ||
|
||||
condition === VariableConditionEnum.isNotEmpty
|
||||
}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<MyInput
|
||||
value={value}
|
||||
placeholder={'输入值'}
|
||||
w={'100%'}
|
||||
bg={'white'}
|
||||
isDisabled={
|
||||
condition === VariableConditionEnum.isEmpty ||
|
||||
condition === VariableConditionEnum.isNotEmpty
|
||||
}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
const Render = useMemo(() => {
|
||||
if (valueType === WorkflowIOValueTypeEnum.boolean) {
|
||||
return (
|
||||
<MySelect
|
||||
list={[
|
||||
{ label: 'True', value: 'true' },
|
||||
{ label: 'False', value: 'false' }
|
||||
]}
|
||||
onchange={onChange}
|
||||
value={value}
|
||||
placeholder={'选择值'}
|
||||
isDisabled={
|
||||
condition === VariableConditionEnum.isEmpty ||
|
||||
condition === VariableConditionEnum.isNotEmpty
|
||||
}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<MyInput
|
||||
value={value}
|
||||
placeholder={'输入值'}
|
||||
w={'100%'}
|
||||
bg={'white'}
|
||||
isDisabled={
|
||||
condition === VariableConditionEnum.isEmpty ||
|
||||
condition === VariableConditionEnum.isNotEmpty
|
||||
}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}, [condition, onChange, value, valueType]);
|
||||
|
||||
return Render;
|
||||
};
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import NodeCard from '../render/NodeCard';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Box, Button, Flex } from '@chakra-ui/react';
|
||||
@@ -9,7 +9,7 @@ import { IfElseListItemType } from '@fastgpt/global/core/workflow/template/syste
|
||||
import { useContextSelector } from 'use-context-selector';
|
||||
import { WorkflowContext } from '../../../context';
|
||||
import Container from '../../components/Container';
|
||||
import DndDrag, { Draggable, DropResult } from '@fastgpt/web/components/common/DndDrag/index';
|
||||
import DndDrag, { Draggable } from '@fastgpt/web/components/common/DndDrag/index';
|
||||
import { SourceHandle } from '../render/Handle';
|
||||
import { getHandleId } from '@fastgpt/global/core/workflow/utils';
|
||||
import ListItem from './ListItem';
|
||||
@@ -19,6 +19,7 @@ const NodeIfElse = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
const { t } = useTranslation();
|
||||
const { nodeId, inputs = [] } = data;
|
||||
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
||||
const elseHandleId = getHandleId(nodeId, 'source', IfElseResultEnum.ELSE);
|
||||
|
||||
const ifElseList = useMemo(
|
||||
() =>
|
||||
@@ -49,7 +50,7 @@ const NodeIfElse = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
<NodeCard selected={selected} maxW={'1000px'} {...data}>
|
||||
<Box px={4} cursor={'default'}>
|
||||
<DndDrag<IfElseListItemType>
|
||||
onDragEndCb={(list) => onUpdateIfElseList(list)}
|
||||
onDragEndCb={(list: IfElseListItemType[]) => onUpdateIfElseList(list)}
|
||||
dataList={ifElseList}
|
||||
renderClone={(provided, snapshot, rubric) => (
|
||||
<ListItem
|
||||
@@ -95,7 +96,7 @@ const NodeIfElse = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
</Box>
|
||||
<SourceHandle
|
||||
nodeId={nodeId}
|
||||
handleId={getHandleId(nodeId, 'source', IfElseResultEnum.ELSE)}
|
||||
handleId={elseHandleId}
|
||||
position={Position.Right}
|
||||
translate={[26, 0]}
|
||||
/>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { getPublishList, postRevertVersion } from '@/web/core/app/versionApi';
|
||||
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||
import CustomRightDrawer from '@fastgpt/web/components/common/MyDrawer/CustomRightDrawer';
|
||||
@@ -14,6 +14,8 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type';
|
||||
import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
|
||||
|
||||
const PublishHistoriesSlider = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -45,29 +47,29 @@ const PublishHistoriesSlider = () => {
|
||||
setIsShowVersionHistories(false);
|
||||
});
|
||||
|
||||
const onPreview = useMemoizedFn((data: AppVersionSchemaType) => {
|
||||
const onPreview = useCallback((data: AppVersionSchemaType) => {
|
||||
setSelectedHistoryId(data._id);
|
||||
|
||||
initData({
|
||||
nodes: data.nodes,
|
||||
edges: data.edges
|
||||
});
|
||||
});
|
||||
const onCloseSlider = useMemoizedFn(() => {
|
||||
setSelectedHistoryId(undefined);
|
||||
initData({
|
||||
nodes: appDetail.modules,
|
||||
edges: appDetail.edges
|
||||
});
|
||||
onClose();
|
||||
});
|
||||
}, []);
|
||||
const onCloseSlider = useCallback(
|
||||
(data: { nodes: StoreNodeItemType[]; edges: StoreEdgeItemType[] }) => {
|
||||
setSelectedHistoryId(undefined);
|
||||
initData(data);
|
||||
onClose();
|
||||
},
|
||||
[appDetail]
|
||||
);
|
||||
|
||||
const { mutate: onRevert, isLoading: isReverting } = useRequest({
|
||||
mutationFn: async (data: AppVersionSchemaType) => {
|
||||
if (!appId) return;
|
||||
await postRevertVersion(appId, {
|
||||
versionId: data._id,
|
||||
editNodes: appDetail.modules,
|
||||
editNodes: appDetail.modules, // old workflow
|
||||
editEdges: appDetail.edges
|
||||
});
|
||||
|
||||
@@ -77,7 +79,7 @@ const PublishHistoriesSlider = () => {
|
||||
edges: data.edges
|
||||
});
|
||||
|
||||
onCloseSlider();
|
||||
onCloseSlider(data);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -86,7 +88,12 @@ const PublishHistoriesSlider = () => {
|
||||
return (
|
||||
<>
|
||||
<CustomRightDrawer
|
||||
onClose={onCloseSlider}
|
||||
onClose={() =>
|
||||
onCloseSlider({
|
||||
nodes: appDetail.modules,
|
||||
edges: appDetail.edges
|
||||
})
|
||||
}
|
||||
iconSrc="core/workflow/versionHistories"
|
||||
title={t('core.workflow.publish.histories')}
|
||||
maxW={'300px'}
|
||||
|
@@ -430,8 +430,8 @@ const WorkflowContextProvider = ({
|
||||
|
||||
const initData = useMemoizedFn(
|
||||
async (e: { nodes: StoreNodeItemType[]; edges: StoreEdgeItemType[] }) => {
|
||||
setNodes(e.nodes?.map((item) => storeNode2FlowNode({ item })));
|
||||
setEdges(e.edges?.map((item) => storeEdgesRenderEdge({ edge: item })));
|
||||
setNodes(e.nodes?.map((item) => storeNode2FlowNode({ item })) || []);
|
||||
setEdges(e.edges?.map((item) => storeEdgesRenderEdge({ edge: item })) || []);
|
||||
}
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user