Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 3.8k
improvement(executor): support nested loops/parallels#3398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
b7e377eda46a38fdca73615ace5e67aa4bb34d92fa115f04e0d86ea0af5923467f8a684fd0989198e2c27ecbe5dacfd6d6c140523968ed5886736d0b87563ba94e6341f3110f740aee69f677f3a90eb31665e7cc39c9c806e17cc4c00c5f1c3c364966472419265b9ca1cb4c0d9cc375a2a7d1a828475ceac3c5b80adb61ce29e6043a86dd1a516648d2ae129fa8d3c0eb3f73d16784e367ccf67ff85a445ec8b255d8099ecfb48fbfbad9cea51d8c35634a4310687afd2e15b7b89b20a54324e2e6171115f3d9c2b977919205786f972409837e7c803860556af3d53ab07a723bac0dd8093739f8de34bea4fcdc27ed713d7141492a6b631File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1167,93 +1167,122 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({ | ||
| {} as Record<string, { type: string; id: string }> | ||
| ) | ||
| let loopBlockGroup: BlockTagGroup | null = null | ||
| const loopBlockGroups: BlockTagGroup[] = [] | ||
| const ancestorLoopIds = new Set<string>() | ||
| const visitedContainerIds = new Set<string>() | ||
| const findAncestorContainers = (targetId: string) => { | ||
| if (visitedContainerIds.has(targetId)) return | ||
| visitedContainerIds.add(targetId) | ||
| // Check if targetId is directly inside any loop | ||
| for (const [loopId, loop] of Object.entries(loops)) { | ||
| if (loop.nodes.includes(targetId) && !ancestorLoopIds.has(loopId)) { | ||
| ancestorLoopIds.add(loopId) | ||
| const loopBlock = blocks[loopId] | ||
| if (loopBlock) { | ||
| const loopType = loop.loopType || 'for' | ||
| const loopBlockName = loopBlock.name || loopBlock.type | ||
| const normalizedLoopName = normalizeName(loopBlockName) | ||
| const contextualTags: string[] = [`${normalizedLoopName}.index`] | ||
| if (loopType === 'forEach') { | ||
| contextualTags.push(`${normalizedLoopName}.currentItem`) | ||
| contextualTags.push(`${normalizedLoopName}.items`) | ||
| } | ||
| loopBlockGroups.push({ | ||
| blockName: loopBlockName, | ||
| blockId: loopId, | ||
| blockType: 'loop', | ||
| tags: contextualTags, | ||
| distance: 0, | ||
| isContextual: true, | ||
| }) | ||
| } | ||
| findAncestorContainers(loopId) | ||
| } | ||
| } | ||
| // Also walk through containing parallels so we find loops that contain | ||
| // the parallel (e.g. block inside parallel inside loop) | ||
| for (const [parallelId, parallel] of Object.entries(parallels || {})) { | ||
| if (parallel.nodes.includes(targetId)) { | ||
| findAncestorContainers(parallelId) | ||
| } | ||
| } | ||
waleedlatif1 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. waleedlatif1 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| const isLoopBlock = blocks[blockId]?.type === 'loop' | ||
| const currentLoop = isLoopBlock ? loops[blockId] : null | ||
| const containingLoop = Object.entries(loops).find(([_, loop]) => loop.nodes.includes(blockId)) | ||
| let containingLoopBlockId: string | null = null | ||
| if (currentLoop && isLoopBlock) { | ||
| containingLoopBlockId = blockId | ||
| const loopType = currentLoop.loopType || 'for' | ||
| if (isLoopBlock && loops[blockId]) { | ||
| const loop = loops[blockId] | ||
| ancestorLoopIds.add(blockId) | ||
| const loopBlock = blocks[blockId] | ||
| if (loopBlock) { | ||
| const loopType = loop.loopType || 'for' | ||
| const loopBlockName = loopBlock.name || loopBlock.type | ||
| const normalizedLoopName = normalizeName(loopBlockName) | ||
| const contextualTags: string[] = [`${normalizedLoopName}.index`] | ||
| if (loopType === 'forEach') { | ||
| contextualTags.push(`${normalizedLoopName}.currentItem`) | ||
| contextualTags.push(`${normalizedLoopName}.items`) | ||
| } | ||
| loopBlockGroup = { | ||
| loopBlockGroups.push({ | ||
| blockName: loopBlockName, | ||
| blockId: blockId, | ||
| blockType: 'loop', | ||
| tags: contextualTags, | ||
| distance: 0, | ||
| isContextual: true, | ||
| } | ||
| }) | ||
| } | ||
| } else if (containingLoop) { | ||
| const [loopId, loop] = containingLoop | ||
| containingLoopBlockId = loopId | ||
| const loopType = loop.loopType || 'for' | ||
| const containingLoopBlock = blocks[loopId] | ||
| if (containingLoopBlock) { | ||
| const loopBlockName = containingLoopBlock.name || containingLoopBlock.type | ||
| const normalizedLoopName = normalizeName(loopBlockName) | ||
| const contextualTags: string[] = [`${normalizedLoopName}.index`] | ||
| if (loopType === 'forEach') { | ||
| contextualTags.push(`${normalizedLoopName}.currentItem`) | ||
| contextualTags.push(`${normalizedLoopName}.items`) | ||
| } | ||
| findAncestorContainers(blockId) | ||
| } else { | ||
| findAncestorContainers(blockId) | ||
| } | ||
| loopBlockGroup = { | ||
| blockName: loopBlockName, | ||
| blockId: loopId, | ||
| blockType: 'loop', | ||
| tags: contextualTags, | ||
| distance: 0, | ||
| isContextual: true, | ||
| const parallelBlockGroups: BlockTagGroup[] = [] | ||
| const ancestorParallelIds = new Set<string>() | ||
| const visitedParallelTargets = new Set<string>() | ||
| const findAncestorParallels = (targetId: string) => { | ||
| if (visitedParallelTargets.has(targetId)) return | ||
| visitedParallelTargets.add(targetId) | ||
| for (const [parallelId, parallel] of Object.entries(parallels || {})) { | ||
| if (parallel.nodes.includes(targetId) && !ancestorParallelIds.has(parallelId)) { | ||
| ancestorParallelIds.add(parallelId) | ||
| const parallelBlock = blocks[parallelId] | ||
| if (parallelBlock) { | ||
| const parallelType = parallel.parallelType || 'count' | ||
| const parallelBlockName = parallelBlock.name || parallelBlock.type | ||
| const normalizedParallelName = normalizeName(parallelBlockName) | ||
| const contextualTags: string[] = [`${normalizedParallelName}.index`] | ||
| if (parallelType === 'collection') { | ||
| contextualTags.push(`${normalizedParallelName}.currentItem`) | ||
| contextualTags.push(`${normalizedParallelName}.items`) | ||
| } | ||
| parallelBlockGroups.push({ | ||
| blockName: parallelBlockName, | ||
| blockId: parallelId, | ||
| blockType: 'parallel', | ||
| tags: contextualTags, | ||
| distance: 0, | ||
| isContextual: true, | ||
| }) | ||
| } | ||
| // Walk up through containing loops and parallels | ||
| for (const [loopId, loop] of Object.entries(loops)) { | ||
| if (loop.nodes.includes(parallelId)) { | ||
| findAncestorParallels(loopId) | ||
| } | ||
| } | ||
| findAncestorParallels(parallelId) | ||
waleedlatif1 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| } | ||
| } | ||
| let parallelBlockGroup: BlockTagGroup | null = null | ||
| const containingParallel = Object.entries(parallels || {}).find(([_, parallel]) => | ||
| parallel.nodes.includes(blockId) | ||
| ) | ||
| let containingParallelBlockId: string | null = null | ||
| if (containingParallel) { | ||
| const [parallelId, parallel] = containingParallel | ||
| containingParallelBlockId = parallelId | ||
| const parallelType = parallel.parallelType || 'count' | ||
| const containingParallelBlock = blocks[parallelId] | ||
| if (containingParallelBlock) { | ||
| const parallelBlockName = containingParallelBlock.name || containingParallelBlock.type | ||
| const normalizedParallelName = normalizeName(parallelBlockName) | ||
| const contextualTags: string[] = [`${normalizedParallelName}.index`] | ||
| if (parallelType === 'collection') { | ||
| contextualTags.push(`${normalizedParallelName}.currentItem`) | ||
| contextualTags.push(`${normalizedParallelName}.items`) | ||
| } | ||
| parallelBlockGroup = { | ||
| blockName: parallelBlockName, | ||
| blockId: parallelId, | ||
| blockType: 'parallel', | ||
| tags: contextualTags, | ||
| distance: 0, | ||
| isContextual: true, | ||
| } | ||
| } | ||
| findAncestorParallels(blockId) | ||
| // Also check through ancestor loops (a block in a loop that's in a parallel) | ||
| for (const loopId of ancestorLoopIds) { | ||
| findAncestorParallels(loopId) | ||
| } | ||
| const blockTagGroups: BlockTagGroup[] = [] | ||
| @@ -1275,8 +1304,8 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({ | ||
| if (!blockConfig) { | ||
| if (accessibleBlock.type === 'loop' || accessibleBlock.type === 'parallel') { | ||
| if ( | ||
| accessibleBlockId === containingLoopBlockId || | ||
| accessibleBlockId === containingParallelBlockId | ||
| ancestorLoopIds.has(accessibleBlockId) || | ||
| ancestorParallelIds.has(accessibleBlockId) | ||
| ) { | ||
| continue | ||
| } | ||
| @@ -1366,12 +1395,8 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({ | ||
| } | ||
| const finalBlockTagGroups: BlockTagGroup[] = [] | ||
| if (loopBlockGroup) { | ||
| finalBlockTagGroups.push(loopBlockGroup) | ||
| } | ||
| if (parallelBlockGroup) { | ||
| finalBlockTagGroups.push(parallelBlockGroup) | ||
| } | ||
| finalBlockTagGroups.push(...loopBlockGroups) | ||
| finalBlockTagGroups.push(...parallelBlockGroups) | ||
| blockTagGroups.sort((a, b) => a.distance - b.distance) | ||
| finalBlockTagGroups.push(...blockTagGroups) | ||
| @@ -1570,21 +1595,6 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({ | ||
| if (variableObj) { | ||
| processedTag = tag | ||
| } | ||
| } else if ( | ||
waleedlatif1 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| blockGroup?.isContextual && | ||
| (blockGroup.blockType === 'loop' || blockGroup.blockType === 'parallel') | ||
| ) { | ||
| const tagParts = tag.split('.') | ||
| if (tagParts.length === 1) { | ||
| processedTag = blockGroup.blockType | ||
| } else { | ||
| const lastPart = tagParts[tagParts.length - 1] | ||
| if (['index', 'currentItem', 'items'].includes(lastPart)) { | ||
| processedTag = `${blockGroup.blockType}.${lastPart}` | ||
| } else { | ||
| processedTag = tag | ||
| } | ||
| } | ||
| } | ||
| let newValue: string | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.