diff --git a/eslint-suppressions.json b/eslint-suppressions.json index c2cf1d9b4a1..27a40b17491 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -523,20 +523,6 @@ "count": 1 } }, - "web/app/components/app/configuration/config/agent/agent-setting/index.tsx": { - "jsx-a11y/click-events-have-key-events": { - "count": 1 - }, - "jsx-a11y/no-static-element-interactions": { - "count": 1 - }, - "react/set-state-in-effect": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 1 - } - }, "web/app/components/app/configuration/config/agent/agent-tools/index.tsx": { "jsx-a11y/mouse-events-have-key-events": { "count": 2 diff --git a/web/app/components/app/configuration/config/__tests__/agent-setting-button.spec.tsx b/web/app/components/app/configuration/config/__tests__/agent-setting-button.spec.tsx index 601efdf9557..a6f650b6671 100644 --- a/web/app/components/app/configuration/config/__tests__/agent-setting-button.spec.tsx +++ b/web/app/components/app/configuration/config/__tests__/agent-setting-button.spec.tsx @@ -8,7 +8,7 @@ import AgentSettingButton from '../agent-setting-button' let latestAgentSettingProps: any vi.mock('../agent/agent-setting', () => ({ - default: (props: any) => { + AgentSetting: (props: any) => { latestAgentSettingProps = props return (
diff --git a/web/app/components/app/configuration/config/agent-setting-button.tsx b/web/app/components/app/configuration/config/agent-setting-button.tsx index f7204da0216..21234c593c4 100644 --- a/web/app/components/app/configuration/config/agent-setting-button.tsx +++ b/web/app/components/app/configuration/config/agent-setting-button.tsx @@ -5,7 +5,7 @@ import { Button } from '@langgenius/dify-ui/button' import * as React from 'react' import { useState } from 'react' import { useTranslation } from 'react-i18next' -import AgentSetting from './agent/agent-setting' +import { AgentSetting } from './agent/agent-setting' type Props = Readonly<{ isFunctionCall: boolean diff --git a/web/app/components/app/configuration/config/agent/agent-setting/__tests__/index.spec.tsx b/web/app/components/app/configuration/config/agent/agent-setting/__tests__/index.spec.tsx index 08a6e0f62bc..c9ce45a0e1f 100644 --- a/web/app/components/app/configuration/config/agent/agent-setting/__tests__/index.spec.tsx +++ b/web/app/components/app/configuration/config/agent/agent-setting/__tests__/index.spec.tsx @@ -1,16 +1,7 @@ import type { AgentConfig } from '@/models/debug' import { act, fireEvent, render, screen } from '@testing-library/react' -import * as React from 'react' import { MAX_ITERATIONS_NUM } from '@/config' -import AgentSetting from '../index' - -vi.mock('ahooks', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - useClickAway: vi.fn(), - } -}) +import { AgentSetting } from '../index' vi.mock('@langgenius/dify-ui/slider', () => ({ Slider: (props: { className?: string, min?: number, max?: number, value: number, onValueChange: (value: number) => void }) => ( @@ -65,8 +56,8 @@ describe('AgentSetting', () => { }) it('should update iteration via slider and number input', () => { - const { container } = renderModal() - const slider = container.querySelector('.slider') as HTMLInputElement + renderModal() + const slider = screen.getByRole('slider') const numberInput = screen.getByRole('spinbutton') fireEvent.change(slider, { target: { value: '7' } }) @@ -94,6 +85,34 @@ describe('AgentSetting', () => { expect(onCancel).toHaveBeenCalled() }) + it('should call onCancel when Escape is pressed', () => { + const { onCancel } = renderModal() + + fireEvent.keyDown(document, { key: 'Escape' }) + + expect(onCancel).toHaveBeenCalledTimes(1) + }) + + it('should call onCancel when the backdrop is clicked', () => { + const { onCancel } = renderModal() + const dialog = screen.getByRole('dialog') + + fireEvent.pointerDown(document.body, { target: document.body }) + fireEvent.mouseDown(document.body, { target: document.body }) + fireEvent.click(document.body, { target: document.body }) + + expect(dialog).toBeInTheDocument() + expect(onCancel).toHaveBeenCalledTimes(1) + }) + + it('should call onCancel when close button clicked', () => { + const { onCancel } = renderModal() + + fireEvent.click(screen.getByRole('button', { name: 'common.operation.close' })) + + expect(onCancel).toHaveBeenCalledTimes(1) + }) + it('should call onSave with updated payload', async () => { const { onSave } = renderModal() const numberInput = screen.getByRole('spinbutton') diff --git a/web/app/components/app/configuration/config/agent/agent-setting/index.tsx b/web/app/components/app/configuration/config/agent/agent-setting/index.tsx index 0894da5e6f0..37213fa30db 100644 --- a/web/app/components/app/configuration/config/agent/agent-setting/index.tsx +++ b/web/app/components/app/configuration/config/agent/agent-setting/index.tsx @@ -1,13 +1,10 @@ 'use client' -import type { FC } from 'react' import type { AgentConfig } from '@/models/debug' import { Button } from '@langgenius/dify-ui/button' +import { Dialog, DialogCloseButton, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' import { Fieldset, FieldsetLegend } from '@langgenius/dify-ui/fieldset' import { Slider } from '@langgenius/dify-ui/slider' -import { RiCloseLine } from '@remixicon/react' -import { useClickAway } from 'ahooks' -import * as React from 'react' -import { useEffect, useRef, useState } from 'react' +import { useState } from 'react' import { useTranslation } from 'react-i18next' import { CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication' import { Unblur } from '@/app/components/base/icons/src/vender/solid/education' @@ -19,60 +16,43 @@ type Props = Readonly<{ payload: AgentConfig isFunctionCall: boolean onCancel: () => void - onSave: (payload: any) => void + onSave: (payload: AgentConfig) => void }> const maxIterationsMin = 1 -const AgentSetting: FC = ({ +export function AgentSetting({ isChatModel, payload, isFunctionCall, onCancel, onSave, -}) => { +}: Props) { const { t } = useTranslation() const [tempPayload, setTempPayload] = useState(payload) - const ref = useRef(null) - const [mounted, setMounted] = useState(false) const maximumIterationsLabel = t($ => $['agent.setting.maximumIterations.name'], { ns: 'appDebug' }) - useClickAway(() => { - if (mounted) - onCancel() - }, ref) - - useEffect(() => { - setMounted(true) - }, []) - const handleSave = () => { onSave(tempPayload) } return ( -
{ + if (!open) + onCancel() }} > -
+
-
-
{t($ => $['agent.setting.name'], { ns: 'appDebug' })}
-
-
-
- -
-
+ + {t($ => $['agent.setting.name'], { ns: 'appDebug' })} + + $['operation.close'], { ns: 'common' })} + />
{/* Body */}
= ({ className="sticky bottom-0 z-5 flex w-full justify-end border-t border-divider-regular bg-background-section-burn px-6 py-4" >
-
-
+ + ) } -export default React.memo(AgentSetting) diff --git a/web/app/components/base/mermaid/index.tsx b/web/app/components/base/mermaid/index.tsx index 4eae3c443aa..2a9224d4f13 100644 --- a/web/app/components/base/mermaid/index.tsx +++ b/web/app/components/base/mermaid/index.tsx @@ -540,7 +540,7 @@ const Flowchart = (props: FlowchartProps) => { {svgString && (
-
+
-
- -
ESC
-
{activeItem?.description}
)}
+
+ +
ESC
+
{activeMenu === ACCOUNT_SETTING_TAB.PROVIDER && ( diff --git a/web/app/components/header/account-setting/menu-dialog.tsx b/web/app/components/header/account-setting/menu-dialog.tsx index e0aef1ef484..e801b60e0b9 100644 --- a/web/app/components/header/account-setting/menu-dialog.tsx +++ b/web/app/components/header/account-setting/menu-dialog.tsx @@ -29,9 +29,9 @@ const MenuDialog = ({ }} > diff --git a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/configuration-button.tsx b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/configuration-button.tsx index e08b62b04c7..d16ace1ad72 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/configuration-button.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/configuration-button.tsx @@ -13,7 +13,6 @@ const ConfigurationButton = ({ modelProvider, handleOpenModal }: ConfigurationBu return (
)} {linkText && linkHref && ( -
+
{ diff --git a/web/app/components/rag-pipeline/components/update-dsl-modal.tsx b/web/app/components/rag-pipeline/components/update-dsl-modal.tsx index 6a16b6e9b27..17e2b858004 100644 --- a/web/app/components/rag-pipeline/components/update-dsl-modal.tsx +++ b/web/app/components/rag-pipeline/components/update-dsl-modal.tsx @@ -60,7 +60,7 @@ const UpdateDSLModal = ({
-
+
@@ -70,7 +70,7 @@ const UpdateDSLModal = ({
-
diff --git a/web/app/components/workflow/__tests__/custom-edge.spec.tsx b/web/app/components/workflow/__tests__/custom-edge.spec.tsx index 5c98402d9e9..0263cdae272 100644 --- a/web/app/components/workflow/__tests__/custom-edge.spec.tsx +++ b/web/app/components/workflow/__tests__/custom-edge.spec.tsx @@ -141,6 +141,7 @@ describe('CustomEdge', () => { expect(screen.getByTestId('block-selector').parentElement).toHaveStyle({ transform: 'translate(-50%, -50%) translate(24px, 48px)', opacity: '0.7', + zIndex: '1001', }) fireEvent.click(screen.getByTestId('block-selector')) diff --git a/web/app/components/workflow/__tests__/syncing-data-modal.spec.tsx b/web/app/components/workflow/__tests__/syncing-data-modal.spec.tsx index 54ad58ffcec..e88f836a557 100644 --- a/web/app/components/workflow/__tests__/syncing-data-modal.spec.tsx +++ b/web/app/components/workflow/__tests__/syncing-data-modal.spec.tsx @@ -15,8 +15,6 @@ describe('SyncingDataModal', () => { }, }) - const overlay = container.firstElementChild - expect(overlay).toHaveClass('absolute', 'inset-0') - expect(overlay).toHaveClass('z-9999') + expect(container.firstElementChild).toBeInTheDocument() }) }) diff --git a/web/app/components/workflow/block-selector/snippets/__tests__/use-insert-snippet.spec.tsx b/web/app/components/workflow/block-selector/snippets/__tests__/use-insert-snippet.spec.tsx index aabf65d826b..fcdeff1d1e6 100644 --- a/web/app/components/workflow/block-selector/snippets/__tests__/use-insert-snippet.spec.tsx +++ b/web/app/components/workflow/block-selector/snippets/__tests__/use-insert-snippet.spec.tsx @@ -1,4 +1,5 @@ import { act, renderHook } from '@testing-library/react' +import { NESTED_ELEMENT_Z_INDEX } from '../../../constants' import { useInsertSnippet } from '../use-insert-snippet' type TestNode = { @@ -6,7 +7,9 @@ type TestNode = { position: { x: number, y: number } selected?: boolean parentId?: string + zIndex?: number data: { + type?: string selected?: boolean _children?: { nodeId: string, nodeType: string }[] _connectedSourceHandleIds?: string[] @@ -20,6 +23,13 @@ type TestEdge = { sourceHandle?: string target: string targetHandle?: string + zIndex?: number + data?: { + isInIteration?: boolean + iteration_id?: string + isInLoop?: boolean + loop_id?: string + } } const mockFetchQuery = vi.fn() @@ -93,14 +103,16 @@ describe('useInsertSnippet', () => { nodes: [ { id: 'snippet-node-1', + zIndex: 1, position: { x: 10, y: 20 }, - data: { selected: false, _children: [{ nodeId: 'snippet-node-2', nodeType: 'code' }] }, + data: { type: 'iteration', selected: false, _children: [{ nodeId: 'snippet-node-2', nodeType: 'code' }] }, }, { id: 'snippet-node-2', parentId: 'snippet-node-1', + zIndex: 1002, position: { x: 30, y: 40 }, - data: { selected: false }, + data: { type: 'code', selected: false }, }, ], edges: [ @@ -110,6 +122,7 @@ describe('useInsertSnippet', () => { sourceHandle: 'source', target: 'snippet-node-2', targetHandle: 'target', + zIndex: 1002, data: {}, }, ], @@ -132,12 +145,15 @@ describe('useInsertSnippet', () => { expect(nextNodes).toHaveLength(3) expect(nextNodes[1]!.id).not.toBe('snippet-node-1') expect(nextNodes[2]!.parentId).toBe(nextNodes[1]!.id) + expect(nextNodes[1]!.zIndex).toBe(0) + expect(nextNodes[2]!.zIndex).toBe(NESTED_ELEMENT_Z_INDEX) expect(nextNodes[1]!.data._children![0]!.nodeId).toBe(nextNodes[2]!.id) const nextEdges = mockSetEdges.mock.calls[0]![0] as TestEdge[] expect(nextEdges).toHaveLength(2) expect(nextEdges[1]!.source).toBe(nextNodes[1]!.id) expect(nextEdges[1]!.target).toBe(nextNodes[2]!.id) + expect(nextEdges[1]!.zIndex).toBe(NESTED_ELEMENT_Z_INDEX) expect(mockSaveStateToHistory).toHaveBeenCalledWith('NodePaste', { nodeId: nextNodes[1]!.id, @@ -148,18 +164,32 @@ describe('useInsertSnippet', () => { }) }) - it('should connect inserted snippet nodes to the requested edge position', async () => { + it.each(['iteration', 'loop'] as const)('should connect inserted snippet nodes inside the %s container', async (containerType) => { mockGetNodes.mockReturnValue([ + { + id: 'container-node', + position: { x: 0, y: 0 }, + data: { + type: containerType, + selected: false, + _children: [ + { nodeId: 'prev-node', nodeType: 'code' }, + { nodeId: 'next-node', nodeType: 'code' }, + ], + }, + }, { id: 'prev-node', + parentId: 'container-node', position: { x: 0, y: 0 }, width: 240, - data: { type: 'start', selected: true, _connectedSourceHandleIds: ['source'] }, + data: { type: 'code', selected: true, _connectedSourceHandleIds: ['source'] }, }, { id: 'next-node', + parentId: 'container-node', position: { x: 300, y: 0 }, - data: { type: 'answer', selected: false, _connectedTargetHandleIds: ['target'] }, + data: { type: 'code', selected: false, _connectedTargetHandleIds: ['target'] }, }, ]) mockEdges = [ @@ -170,8 +200,8 @@ describe('useInsertSnippet', () => { target: 'next-node', targetHandle: 'target', data: { - sourceType: 'start', - targetType: 'answer', + sourceType: 'code', + targetType: 'code', }, }, ] @@ -221,6 +251,8 @@ describe('useInsertSnippet', () => { const insertedExit = nextNodes.find(node => node.id !== 'prev-node' && node.id !== 'next-node' && node.id.includes('snippet-exit'))! const shiftedNextNode = nextNodes.find(node => node.id === 'next-node')! expect(insertedEntry.position).toEqual({ x: 300, y: 0 }) + expect(insertedEntry.parentId).toBe('container-node') + expect(insertedExit.parentId).toBe('container-node') expect(shiftedNextNode.position.x).toBe(600) expect(nextNodes.find(node => node.id === 'prev-node')!.data._connectedSourceHandleIds).toEqual(['source']) expect(insertedEntry.data._connectedTargetHandleIds).toEqual(['target']) @@ -248,6 +280,18 @@ describe('useInsertSnippet', () => { targetHandle: 'target', }), ])) + const incomingEdge = nextEdges.find(edge => edge.source === 'prev-node' && edge.target === insertedEntry.id) + const insertedInternalEdge = nextEdges.find(edge => edge.source === insertedEntry.id && edge.target === insertedExit.id) + const outgoingEdge = nextEdges.find(edge => edge.source === insertedExit.id && edge.target === 'next-node') + expect(incomingEdge?.zIndex).toBe(NESTED_ELEMENT_Z_INDEX) + expect(insertedInternalEdge?.zIndex).toBe(NESTED_ELEMENT_Z_INDEX) + expect(outgoingEdge?.zIndex).toBe(NESTED_ELEMENT_Z_INDEX) + expect(insertedInternalEdge?.data).toEqual(expect.objectContaining({ + isInIteration: containerType === 'iteration', + iteration_id: containerType === 'iteration' ? 'container-node' : undefined, + isInLoop: containerType === 'loop', + loop_id: containerType === 'loop' ? 'container-node' : undefined, + })) expect(mockIncrementSnippetUseCount).toHaveBeenCalledWith({ params: { snippetId: 'snippet-1' }, }) diff --git a/web/app/components/workflow/block-selector/snippets/use-insert-snippet.ts b/web/app/components/workflow/block-selector/snippets/use-insert-snippet.ts index 6d69451fa38..8c19a519805 100644 --- a/web/app/components/workflow/block-selector/snippets/use-insert-snippet.ts +++ b/web/app/components/workflow/block-selector/snippets/use-insert-snippet.ts @@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next' import { useStoreApi } from 'reactflow' import { consoleQuery } from '@/service/client' import { useIncrementSnippetUseCountMutation } from '@/service/use-snippets' -import { CUSTOM_EDGE, ITERATION_CHILDREN_Z_INDEX, LOOP_CHILDREN_Z_INDEX, NODE_WIDTH_X_OFFSET, X_OFFSET } from '../../constants' +import { CUSTOM_EDGE, NESTED_ELEMENT_Z_INDEX, NODE_WIDTH_X_OFFSET, X_OFFSET } from '../../constants' import { useNodesSyncDraft, useWorkflowHistory, WorkflowHistoryEvent } from '../../hooks' import { BlockEnum } from '../../types' import { getNodesConnectedSourceOrTargetHandleIdsMap } from '../../utils' @@ -212,9 +212,7 @@ const createBoundaryEdges = ({ const parentNode = getParentNode(currentNodes, insertPayload) const isInIteration = parentNode?.data.type === BlockEnum.Iteration const isInLoop = parentNode?.data.type === BlockEnum.Loop - const zIndex = parentNode - ? isInIteration ? ITERATION_CHILDREN_Z_INDEX : LOOP_CHILDREN_Z_INDEX - : 0 + const zIndex = parentNode ? NESTED_ELEMENT_Z_INDEX : 0 const incomingEdges: Edge[] = [] const outgoingEdges: Edge[] = [] @@ -315,6 +313,7 @@ export const useInsertSnippet = () => { changes, [...currentNodes, ...remappedGraph.nodes], ) + const remappedNodesById = new Map(remappedGraph.nodes.map(node => [node.id, node])) const firstEntryNode = entryNodes.find(canConnectToTarget) ?? entryNodes[0] const clearedNodes = currentNodes.map(node => ({ ...node, @@ -354,14 +353,15 @@ export const useInsertSnippet = () => { const shouldMoveIntoParent = !!parentNode && rootNodeIds.has(node.id) const isInIteration = parentNode?.data.type === BlockEnum.Iteration const isInLoop = parentNode?.data.type === BlockEnum.Loop + const snippetParentNode = node.parentId ? remappedNodesById.get(node.parentId) : undefined + const isNestedInSnippet = snippetParentNode?.data.type === BlockEnum.Iteration + || snippetParentNode?.data.type === BlockEnum.Loop return { ...node, parentId: shouldMoveIntoParent ? parentNode.id : node.parentId, extent: shouldMoveIntoParent ? parentNode.extent : node.extent, - zIndex: shouldMoveIntoParent - ? isInIteration ? ITERATION_CHILDREN_Z_INDEX : LOOP_CHILDREN_Z_INDEX - : node.zIndex, + zIndex: shouldMoveIntoParent || isNestedInSnippet ? NESTED_ELEMENT_Z_INDEX : 0, data: { ...node.data, ...(nodesConnectedSourceOrTargetHandleIdsMap[node.id] ?? {}), @@ -372,8 +372,31 @@ export const useInsertSnippet = () => { }, } }) + const nextNodes = [...clearedNodes, ...insertedNodes] + const finalNodesById = new Map(nextNodes.map(node => [node.id, node])) + const insertedEdges = remappedGraph.edges.map((edge) => { + const sourceNode = finalNodesById.get(edge.source) + const targetNode = finalNodesById.get(edge.target) + const sourceParentNode = sourceNode?.parentId ? finalNodesById.get(sourceNode.parentId) : undefined + const targetParentNode = targetNode?.parentId ? finalNodesById.get(targetNode.parentId) : undefined + const nestedParentNode = [sourceParentNode, targetParentNode].find(node => node?.data.type === BlockEnum.Iteration || node?.data.type === BlockEnum.Loop) + const isInIteration = nestedParentNode?.data.type === BlockEnum.Iteration + const isInLoop = nestedParentNode?.data.type === BlockEnum.Loop - setNodes([...clearedNodes, ...insertedNodes]) + return { + ...edge, + data: { + ...edge.data, + isInIteration, + iteration_id: isInIteration ? nestedParentNode.id : undefined, + isInLoop, + loop_id: isInLoop ? nestedParentNode.id : undefined, + }, + zIndex: nestedParentNode ? NESTED_ELEMENT_Z_INDEX : 0, + } + }) + + setNodes(nextNodes) setEdges([ ...edges .filter(edge => edge.id !== currentEdge?.id) @@ -384,7 +407,7 @@ export const useInsertSnippet = () => { _connectedNodeIsSelected: false, }, })), - ...remappedGraph.edges, + ...insertedEdges, ...boundaryEdges, ]) saveStateToHistory(WorkflowHistoryEvent.NodePaste, { diff --git a/web/app/components/workflow/comment/comment-input.tsx b/web/app/components/workflow/comment/comment-input.tsx index d5fd8bec18f..7157f152ba6 100644 --- a/web/app/components/workflow/comment/comment-input.tsx +++ b/web/app/components/workflow/comment/comment-input.tsx @@ -135,7 +135,7 @@ export const CommentInput: FC = memo(({ return (
{ return (
(({ {showMentionDropdown && filteredMentionUsers.length > 0 && typeof document !== 'undefined' && createPortal(
= memo(({ return (
setIsTriggerHovered(true)} onMouseLeave={() => setIsTriggerHovered(false)} diff --git a/web/app/components/workflow/hooks/__tests__/use-nodes-interactions.spec.ts b/web/app/components/workflow/hooks/__tests__/use-nodes-interactions.spec.ts index 95591c7a844..dba8107f7d4 100644 --- a/web/app/components/workflow/hooks/__tests__/use-nodes-interactions.spec.ts +++ b/web/app/components/workflow/hooks/__tests__/use-nodes-interactions.spec.ts @@ -1112,6 +1112,7 @@ describe('useNodesInteractions', () => { createNode({ id: nodeId, position: { x: 120, y: 120 }, + zIndex: 1002, data: { type: containerType, title: containerType === BlockEnum.Iteration ? 'Iteration' : 'Loop', @@ -1136,6 +1137,7 @@ describe('useNodesInteractions', () => { expect(newContainer).toBeDefined() expect(newContainer?.parentId).toBeUndefined() + expect(newContainer?.zIndex).toBe(0) expect(newContainer?.data.isInIteration).toBeFalsy() expect(newContainer?.data.isInLoop).toBeFalsy() }) diff --git a/web/app/components/workflow/hooks/use-nodes-interactions.ts b/web/app/components/workflow/hooks/use-nodes-interactions.ts index 7d57c09cb9d..ec874092a75 100644 --- a/web/app/components/workflow/hooks/use-nodes-interactions.ts +++ b/web/app/components/workflow/hooks/use-nodes-interactions.ts @@ -27,10 +27,9 @@ import { consoleQuery } from '@/service/client' import { collaborationManager } from '../collaboration/core/collaboration-manager' import { CUSTOM_EDGE, - ITERATION_CHILDREN_Z_INDEX, ITERATION_PADDING, - LOOP_CHILDREN_Z_INDEX, LOOP_PADDING, + NESTED_ELEMENT_Z_INDEX, NODE_WIDTH_X_OFFSET, X_OFFSET, Y_OFFSET, @@ -597,11 +596,7 @@ export const useNodesInteractions = () => { isInLoop, loop_id: isInLoop ? targetNode?.parentId : undefined, }, - zIndex: targetNode?.parentId - ? isInIteration - ? ITERATION_CHILDREN_Z_INDEX - : LOOP_CHILDREN_Z_INDEX - : 0, + zIndex: targetNode?.parentId ? NESTED_ELEMENT_Z_INDEX : 0, } const nodesConnectedSourceOrTargetHandleIdsMap = getNodesConnectedSourceOrTargetHandleIdsMap( @@ -998,11 +993,11 @@ export const useNodesInteractions = () => { newNode.data.isInLoop = isInLoop if (isInIteration) { newNode.data.iteration_id = parentNode.id - newNode.zIndex = ITERATION_CHILDREN_Z_INDEX + newNode.zIndex = NESTED_ELEMENT_Z_INDEX } if (isInLoop) { newNode.data.loop_id = parentNode.id - newNode.zIndex = LOOP_CHILDREN_Z_INDEX + newNode.zIndex = NESTED_ELEMENT_Z_INDEX } if ( isInIteration @@ -1042,11 +1037,7 @@ export const useNodesInteractions = () => { loop_id: isInLoop ? prevNode!.parentId : undefined, _connectedNodeIsSelected: true, }, - zIndex: prevNode!.parentId - ? isInIteration - ? ITERATION_CHILDREN_Z_INDEX - : LOOP_CHILDREN_Z_INDEX - : 0, + zIndex: prevNode!.parentId ? NESTED_ELEMENT_Z_INDEX : 0, } } @@ -1156,11 +1147,11 @@ export const useNodesInteractions = () => { newNode.data.isInLoop = isInLoop if (isInIteration) { newNode.data.iteration_id = parentNode.id - newNode.zIndex = ITERATION_CHILDREN_Z_INDEX + newNode.zIndex = NESTED_ELEMENT_Z_INDEX } if (isInLoop) { newNode.data.loop_id = parentNode.id - newNode.zIndex = LOOP_CHILDREN_Z_INDEX + newNode.zIndex = NESTED_ELEMENT_Z_INDEX } } @@ -1188,11 +1179,7 @@ export const useNodesInteractions = () => { loop_id: isInLoop ? nextNode.parentId : undefined, _connectedNodeIsSelected: true, }, - zIndex: nextNode.parentId - ? isInIteration - ? ITERATION_CHILDREN_Z_INDEX - : LOOP_CHILDREN_Z_INDEX - : 0, + zIndex: nextNode.parentId ? NESTED_ELEMENT_Z_INDEX : 0, } } @@ -1309,11 +1296,11 @@ export const useNodesInteractions = () => { newNode.data.isInLoop = isInLoop if (isInIteration) { newNode.data.iteration_id = parentNode.id - newNode.zIndex = ITERATION_CHILDREN_Z_INDEX + newNode.zIndex = NESTED_ELEMENT_Z_INDEX } if (isInLoop) { newNode.data.loop_id = parentNode.id - newNode.zIndex = LOOP_CHILDREN_Z_INDEX + newNode.zIndex = NESTED_ELEMENT_Z_INDEX } } @@ -1339,11 +1326,7 @@ export const useNodesInteractions = () => { loop_id: isInLoop ? prevNode.parentId : undefined, _connectedNodeIsSelected: true, }, - zIndex: prevNode.parentId - ? isInIteration - ? ITERATION_CHILDREN_Z_INDEX - : LOOP_CHILDREN_Z_INDEX - : 0, + zIndex: prevNode.parentId ? NESTED_ELEMENT_Z_INDEX : 0, } } @@ -1382,11 +1365,7 @@ export const useNodesInteractions = () => { loop_id: isNextNodeInLoop ? nextNode.parentId : undefined, _connectedNodeIsSelected: true, }, - zIndex: nextNode.parentId - ? isNextNodeInIteration - ? ITERATION_CHILDREN_Z_INDEX - : LOOP_CHILDREN_Z_INDEX - : 0, + zIndex: nextNode.parentId ? NESTED_ELEMENT_Z_INDEX : 0, } } const nodesConnectedSourceOrTargetHandleIdsMap @@ -1627,11 +1606,7 @@ export const useNodesInteractions = () => { loop_id: isInLoop ? targetNodeForEdge.parentId : undefined, _connectedNodeIsSelected: false, }, - zIndex: targetNodeForEdge.parentId - ? isInIteration - ? ITERATION_CHILDREN_Z_INDEX - : LOOP_CHILDREN_Z_INDEX - : 0, + zIndex: targetNodeForEdge.parentId ? NESTED_ELEMENT_Z_INDEX : 0, }) } @@ -1667,11 +1642,7 @@ export const useNodesInteractions = () => { loop_id: newNodeIsInLoop ? newCurrentNode.parentId : undefined, _connectedNodeIsSelected: false, }, - zIndex: newCurrentNode.parentId - ? newNodeIsInIteration - ? ITERATION_CHILDREN_Z_INDEX - : LOOP_CHILDREN_Z_INDEX - : 0, + zIndex: newCurrentNode.parentId ? NESTED_ELEMENT_Z_INDEX : 0, }) } @@ -2075,7 +2046,7 @@ export const useNodesInteractions = () => { y: nodeToPaste.position.y + offsetY, }, extent: nodeToPaste.extent, - zIndex: nodeToPaste.zIndex, + zIndex: 0, }) newNode.id = newNode.id + index @@ -2145,7 +2116,7 @@ export const useNodesInteractions = () => { positionAbsolute: child.positionAbsolute, parentId: newNode.id, extent: child.extent, - zIndex: ITERATION_CHILDREN_Z_INDEX, + zIndex: NESTED_ELEMENT_Z_INDEX, }) newChild.id = `${newNode.id}${newChild.id + childIndex}` idMapping[child.id] = newChild.id @@ -2245,7 +2216,7 @@ export const useNodesInteractions = () => { positionAbsolute: child.positionAbsolute, parentId: newNode.id, extent: child.extent, - zIndex: LOOP_CHILDREN_Z_INDEX, + zIndex: NESTED_ELEMENT_Z_INDEX, }) newChild.id = `${newNode.id}${newChild.id + childIndex}` idMapping[child.id] = newChild.id @@ -2290,7 +2261,7 @@ export const useNodesInteractions = () => { newNode.data.loop_id = !isIteration ? selectedContainerNode.id : undefined newNode.parentId = selectedContainerNode.id - newNode.zIndex = isIteration ? ITERATION_CHILDREN_Z_INDEX : LOOP_CHILDREN_Z_INDEX + newNode.zIndex = NESTED_ELEMENT_Z_INDEX newNode.positionAbsolute = { x: newNode.position.x, y: newNode.position.y, @@ -2348,13 +2319,7 @@ export const useNodesInteractions = () => { loop_id: isInLoop ? parentNode?.id : undefined, _connectedNodeIsSelected: false, }, - zIndex: parentNode - ? isInIteration - ? ITERATION_CHILDREN_Z_INDEX - : isInLoop - ? LOOP_CHILDREN_Z_INDEX - : 0 - : 0, + zIndex: parentNode && (isInIteration || isInLoop) ? NESTED_ELEMENT_Z_INDEX : 0, } edgesToPaste.push(newEdge) } diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx index 3562511b0b1..629c2a2c1b7 100644 --- a/web/app/components/workflow/index.tsx +++ b/web/app/components/workflow/index.tsx @@ -73,7 +73,6 @@ import { CommentThread } from './comment/thread' import { CUSTOM_EDGE, CUSTOM_NODE, - ITERATION_CHILDREN_Z_INDEX, WORKFLOW_DATA_UPDATE, } from './constants' import CustomConnectionLine from './custom-connection-line' @@ -618,13 +617,12 @@ export const Workflow: FC = memo(({
-
= memo(({ onPaneContextMenu={handlePaneContextMenu} onSelectionContextMenu={handleSelectionContextMenu} connectionLineComponent={CustomConnectionLine} - // NOTE: For LOOP node, how to distinguish between ITERATION and LOOP here? Maybe both are the same? - connectionLineContainerStyle={{ zIndex: ITERATION_CHILDREN_Z_INDEX }} defaultViewport={viewport} multiSelectionKeyCode={null} deleteKeyCode={null} @@ -785,6 +781,7 @@ export const Workflow: FC = memo(({ )} +
) }) diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars.tsx b/web/app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars.tsx index 5688f8b1e3d..ed2c59248db 100644 --- a/web/app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars.tsx +++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars.tsx @@ -151,12 +151,10 @@ const CodeEditor: FC = ({ {isShowVarPicker && createPortal(
{ position: { x: 12, y: 24 }, positionAbsolute: { x: 12, y: 24 }, extent: 'parent', - zIndex: 7, + zIndex: 1002, data: { type: BlockEnum.Code, title: 'Original', desc: 'child', selected: true }, }) @@ -99,7 +99,7 @@ describe('iteration interaction helpers', () => { expect(result).toEqual(expect.objectContaining({ parentId: 'iteration-2', - zIndex: 7, + zIndex: 1001, data: expect.objectContaining({ title: 'blocks.code 3', iteration_id: 'iteration-2', diff --git a/web/app/components/workflow/nodes/iteration/use-interactions.helpers.ts b/web/app/components/workflow/nodes/iteration/use-interactions.helpers.ts index 1af83c4fc2b..a6675080a8a 100644 --- a/web/app/components/workflow/nodes/iteration/use-interactions.helpers.ts +++ b/web/app/components/workflow/nodes/iteration/use-interactions.helpers.ts @@ -5,6 +5,7 @@ import type { } from '../../types' import { ITERATION_PADDING, + NESTED_ELEMENT_Z_INDEX, } from '../../constants' import { CUSTOM_ITERATION_START_NODE } from '../iteration-start/constants' @@ -108,6 +109,6 @@ export const buildIterationChildCopy = ({ positionAbsolute: child.positionAbsolute, parentId: newNodeId, extent: child.extent, - zIndex: child.zIndex, + zIndex: NESTED_ELEMENT_Z_INDEX, } } diff --git a/web/app/components/workflow/nodes/loop/__tests__/use-interactions.helpers.spec.ts b/web/app/components/workflow/nodes/loop/__tests__/use-interactions.helpers.spec.ts index 283b7a2f48a..7e559e5a5d0 100644 --- a/web/app/components/workflow/nodes/loop/__tests__/use-interactions.helpers.spec.ts +++ b/web/app/components/workflow/nodes/loop/__tests__/use-interactions.helpers.spec.ts @@ -87,7 +87,7 @@ describe('loop interaction helpers', () => { expect(result.newId).toBe('loop-23') expect(result.params).toEqual(expect.objectContaining({ parentId: 'loop-2', - zIndex: 1002, + zIndex: 1001, data: expect.objectContaining({ title: 'Code 3', isInLoop: true, diff --git a/web/app/components/workflow/nodes/loop/use-interactions.helpers.ts b/web/app/components/workflow/nodes/loop/use-interactions.helpers.ts index 41fa7de8f2d..380b9754638 100644 --- a/web/app/components/workflow/nodes/loop/use-interactions.helpers.ts +++ b/web/app/components/workflow/nodes/loop/use-interactions.helpers.ts @@ -3,8 +3,8 @@ import type { Node, } from '../../types' import { - LOOP_CHILDREN_Z_INDEX, LOOP_PADDING, + NESTED_ELEMENT_Z_INDEX, } from '../../constants' import { CUSTOM_LOOP_START_NODE } from '../loop-start/constants' @@ -99,7 +99,7 @@ export const buildLoopChildCopy = ({ positionAbsolute: child.positionAbsolute, parentId: newNodeId, extent: child.extent, - zIndex: LOOP_CHILDREN_Z_INDEX, + zIndex: NESTED_ELEMENT_Z_INDEX, } return { diff --git a/web/app/components/workflow/style.css b/web/app/components/workflow/style.css index e0ad7649867..c89738c30f0 100644 --- a/web/app/components/workflow/style.css +++ b/web/app/components/workflow/style.css @@ -24,7 +24,7 @@ } #workflow-container .react-flow__node-custom-note { - z-index: -1000 !important; + z-index: -1 !important; } #workflow-container .react-flow__attribution { diff --git a/web/app/components/workflow/syncing-data-modal.tsx b/web/app/components/workflow/syncing-data-modal.tsx index 6d5e40a48ea..735096c4103 100644 --- a/web/app/components/workflow/syncing-data-modal.tsx +++ b/web/app/components/workflow/syncing-data-modal.tsx @@ -7,7 +7,7 @@ const SyncingDataModal = () => { return null return ( -
+
) } diff --git a/web/app/components/workflow/update-dsl-modal.tsx b/web/app/components/workflow/update-dsl-modal.tsx index dfbb3993405..ada3c9bbd52 100644 --- a/web/app/components/workflow/update-dsl-modal.tsx +++ b/web/app/components/workflow/update-dsl-modal.tsx @@ -220,7 +220,7 @@ const UpdateDSLModal = ({
-
+
@@ -230,7 +230,7 @@ const UpdateDSLModal = ({