-
-
-
setShowFeaturesPanel(false)}
- >
-
-
+
+
+ Features
+
+
+
+
setShowFeaturesPanel(false)}
+ >
+
-
- {},
- }}
- annotationProps={{
- onEmbeddingChange: () => {},
- onScoreChange: () => {},
- }}
- />
-
-
+
+ {},
+ }}
+ annotationProps={{
+ onEmbeddingChange: () => {},
+ onScoreChange: () => {},
+ }}
+ />
+
+
)
}
diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx
index 074e7458c1..81d22a7616 100644
--- a/web/app/components/workflow/index.tsx
+++ b/web/app/components/workflow/index.tsx
@@ -1,7 +1,6 @@
import type { FC } from 'react'
import {
memo,
- // useEffect,
} from 'react'
import { useParams } from 'next/navigation'
import useSWR from 'swr'
@@ -10,11 +9,9 @@ import ReactFlow, {
Background,
ReactFlowProvider,
useEdgesState,
- // useNodesInitialized,
useNodesState,
} from 'reactflow'
import 'reactflow/dist/style.css'
-// import './style.css'
import type {
Edge,
Node,
@@ -22,7 +19,7 @@ import type {
import { useWorkflow } from './hooks'
import Header from './header'
import CustomNode from './nodes'
-import ZoomInOut from './zoom-in-out'
+import Operator from './operator'
import CustomEdge from './custom-edge'
import CustomConnectionLine from './custom-connection-line'
import Panel from './panel'
@@ -34,6 +31,7 @@ import {
syncWorkflowDraft,
} from '@/service/workflow'
import Loading from '@/app/components/base/loading'
+import { FeaturesProvider } from '@/app/components/base/features'
const nodeTypes = {
custom: CustomNode,
@@ -53,11 +51,8 @@ const Workflow: FC
= memo(({
const showFeaturesPanel = useStore(state => state.showFeaturesPanel)
const [nodes] = useNodesState(initialNodes)
const [edges, _, onEdgesChange] = useEdgesState(initialEdges)
- // const nodesInitialized = useNodesInitialized()
const {
- // handleLayout,
-
handleNodeDragStart,
handleNodeDrag,
handleNodeDragStop,
@@ -71,18 +66,13 @@ const Workflow: FC = memo(({
handleEdgeDelete,
} = useWorkflow()
- // useEffect(() => {
- // if (nodesInitialized)
- // handleLayout()
- // }, [nodesInitialized, handleLayout])
-
useKeyPress('Backspace', handleEdgeDelete)
return (
-
+
{
showFeaturesPanel &&
}
@@ -121,8 +111,7 @@ const WorkflowWrap: FC
= ({
edges,
}) => {
const appId = useParams().appId
- const { data, isLoading, error } = useSWR(`/apps/${appId}/workflows/draft`, fetchWorkflowDraft)
- // const { data: configsData } = useSWR(`/apps/${appId}/workflows/default-workflow-block-configs`, fetchNodesDefaultConfigs)
+ const { isLoading, error } = useSWR(`/apps/${appId}/workflows/draft`, fetchWorkflowDraft)
if (error) {
syncWorkflowDraft({
@@ -152,10 +141,12 @@ const WorkflowWrap: FC = ({
return (
-
+
+
+
)
}
diff --git a/web/app/components/workflow/operator/index.tsx b/web/app/components/workflow/operator/index.tsx
new file mode 100644
index 0000000000..4feb08adc0
--- /dev/null
+++ b/web/app/components/workflow/operator/index.tsx
@@ -0,0 +1,22 @@
+import { memo } from 'react'
+import ZoomInOut from './zoom-in-out'
+import { OrganizeGrid } from '@/app/components/base/icons/src/vender/line/layout'
+import TooltipPlus from '@/app/components/base/tooltip-plus'
+
+const Operator = () => {
+ return (
+
+ )
+}
+
+export default memo(Operator)
diff --git a/web/app/components/workflow/operator/zoom-in-out.tsx b/web/app/components/workflow/operator/zoom-in-out.tsx
new file mode 100644
index 0000000000..4373320bd1
--- /dev/null
+++ b/web/app/components/workflow/operator/zoom-in-out.tsx
@@ -0,0 +1,109 @@
+import type { FC } from 'react'
+import {
+ Fragment,
+ memo,
+ useState,
+} from 'react'
+import { useReactFlow } from 'reactflow'
+import {
+ PortalToFollowElem,
+ PortalToFollowElemContent,
+ PortalToFollowElemTrigger,
+} from '@/app/components/base/portal-to-follow-elem'
+import { SearchLg } from '@/app/components/base/icons/src/vender/line/general'
+import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
+
+const ZOOM_IN_OUT_OPTIONS = [
+ [
+ {
+ key: 'in',
+ text: 'Zoom In',
+ },
+ {
+ key: 'out',
+ text: 'Zoom Out',
+ },
+ ],
+ [
+ {
+ key: 'to50',
+ text: 'Zoom to 50%',
+ },
+ {
+ key: 'to100',
+ text: 'Zoom to 100%',
+ },
+ ],
+ [
+ {
+ key: 'fit',
+ text: 'Zoom to Fit',
+ },
+ ],
+]
+
+const ZoomInOut: FC = () => {
+ const reactFlow = useReactFlow()
+ const [open, setOpen] = useState(false)
+
+ const handleZoom = (type: string) => {
+ if (type === 'in')
+ reactFlow.zoomIn()
+
+ if (type === 'out')
+ reactFlow.zoomOut()
+
+ if (type === 'fit')
+ reactFlow.fitView()
+ }
+
+ return (
+
+ setOpen(v => !v)}>
+
+
+ 100%
+
+
+
+
+
+ {
+ ZOOM_IN_OUT_OPTIONS.map((options, i) => (
+
+ {
+ i !== 0 && (
+
+ )
+ }
+
+ {
+ options.map(option => (
+
handleZoom(option.key)}
+ >
+ {option.text}
+
+ ))
+ }
+
+
+ ))
+ }
+
+
+
+ )
+}
+
+export default memo(ZoomInOut)