-
Notifications
You must be signed in to change notification settings - Fork 8.2k
feat: Add alias functionality in the UI and in tweaks processing #9801
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
base: main
Are you sure you want to change the base?
Changes from all commits
e1cab5c
2de3451
08694dc
a7c0e27
bcc40ac
ded8e08
0918d53
c5feac7
ed582ef
d8bde89
f6f88c5
0ff5cee
98b63f7
0f00c71
87f5261
d952ca5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,7 @@ import ShadTooltip from "@/components/common/shadTooltipComponent"; | |||||||||||||||||||||
| import { EditNodeComponent } from "@/modals/editNodeModal/components/editNodeComponent"; | ||||||||||||||||||||||
| import type { APIClassType } from "@/types/api"; | ||||||||||||||||||||||
| import type { AllNodeType } from "@/types/flow"; | ||||||||||||||||||||||
| import { getEffectiveAliasFromAnyNode } from "@/types/flow"; | ||||||||||||||||||||||
| import { customStringify } from "@/utils/reactflowUtils"; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export function TweakComponent({ | ||||||||||||||||||||||
|
|
@@ -25,11 +26,24 @@ export function TweakComponent({ | |||||||||||||||||||||
| return; | ||||||||||||||||||||||
| setNodeClass(node.data?.node); | ||||||||||||||||||||||
| }, [node.data?.node]); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Get alias info for badge display | ||||||||||||||||||||||
| const effectiveAlias = getEffectiveAliasFromAnyNode(node); | ||||||||||||||||||||||
| const aliasNumber = effectiveAlias?.match(/#(\d+)$/)?.[1]; | ||||||||||||||||||||||
| const displayName = node.data.node?.display_name || ""; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
Comment on lines
+30
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Derive badge number from the actual alias field to avoid false positives. - const effectiveAlias = getEffectiveAliasFromAnyNode(node);
- const aliasNumber = effectiveAlias?.match(/#(\d+)$/)?.[1];
- const displayName = node.data.node?.display_name || "";
+ const effectiveAlias = getEffectiveAliasFromAnyNode(node);
+ const rawAlias =
+ node.type === "genericNode" ? node.data.node?.alias ?? "" : "";
+ const aliasNumber = rawAlias.match(/#(\d+)$/)?.[1];
+ const displayName = node.data.node?.display_name || "";📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| return node && node.data && nodeClass ? ( | ||||||||||||||||||||||
| <AccordionComponent | ||||||||||||||||||||||
| trigger={ | ||||||||||||||||||||||
| <ShadTooltip side="top" styleClasses="z-50" content={node.data.id}> | ||||||||||||||||||||||
| <div className="text-primary">{node.data.node?.display_name}</div> | ||||||||||||||||||||||
| <div className="flex items-center gap-2 text-primary"> | ||||||||||||||||||||||
| <span>{displayName}</span> | ||||||||||||||||||||||
| {aliasNumber && ( | ||||||||||||||||||||||
| <div className="flex h-5 w-auto min-w-[18px] items-center justify-center rounded border border-border bg-background px-1.5 text-xs font-semibold text-foreground"> | ||||||||||||||||||||||
| #{aliasNumber} | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| )} | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| </ShadTooltip> | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| keyValue={node.data.id} | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,12 +5,15 @@ import { track } from "@/customization/utils/analytics"; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import useFlowStore from "@/stores/flowStore"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { APIClassType } from "@/types/api"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { AllNodeType } from "@/types/flow"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { assignAliasToNewComponent } from "@/utils/aliasUtils"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getNodeId } from "@/utils/reactflowUtils"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getNodeRenderType } from "@/utils/utils"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function useAddComponent() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const store = useStoreApi(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const paste = useFlowStore((state) => state.paste); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const nodes = useFlowStore((state) => state.nodes); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const setNodes = useFlowStore((state) => state.setNodes); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const addComponent = useCallback( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -55,16 +58,39 @@ export function useAddComponent() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: getNodeRenderType("genericnode"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| position: { x: 0, y: 0 }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node: component, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| node: { ...component }, // Clone component to avoid mutation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| showNode: !component.minimized, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: type, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: newId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Generate alias for the new component and update existing ones if needed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assignAliasToNewComponent(newNode, nodes); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Check if we need to update existing nodes (when adding second component of same type) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const displayName = newNode.data.node.display_name; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const sameTypeNodes = nodes.filter( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (n) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| n.type === "genericNode" && n.data.node.display_name === displayName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (sameTypeNodes.length === 1 && !sameTypeNodes[0].data.node.alias) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // This is the second component - need to assign aliases to both | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const firstNode = sameTypeNodes[0]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (firstNode.type === "genericNode") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| firstNode.data.node.alias = `${displayName}#1`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Update the first node in the store | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setNodes((currentNodes) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| currentNodes.map((n) => (n.id === firstNode.id ? firstNode : n)), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+68
to
+90
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix: store mutation via utility is not persisted; reorder logic to ensure setNodes runs assignAliasToNewComponent mutates the existing nodes array by reference. Because the zustand store isn’t updated unless setNodes is called, your subsequent condition can be skipped (alias already set in-memory), leading to no store update and missing re-render. Compute the “second-of-its-type” condition before calling the utility, then always persist the first node’s alias immutably when needed. Apply: - // Generate alias for the new component and update existing ones if needed
- assignAliasToNewComponent(newNode, nodes);
-
- // Check if we need to update existing nodes (when adding second component of same type)
- const displayName = newNode.data.node.display_name;
- const sameTypeNodes = nodes.filter(
- (n) =>
- n.type === "genericNode" && n.data.node.display_name === displayName,
- );
-
- if (sameTypeNodes.length === 1 && !sameTypeNodes[0].data.node.alias) {
- // This is the second component - need to assign aliases to both
- const firstNode = sameTypeNodes[0];
- if (firstNode.type === "genericNode") {
- firstNode.data.node.alias = `${displayName}#1`;
- }
-
- // Update the first node in the store
- setNodes((currentNodes) =>
- currentNodes.map((n) => (n.id === firstNode.id ? firstNode : n)),
- );
- }
+ // Precompute if we are adding the second component of this display_name with no existing alias
+ const displayName = newNode.data.node.display_name;
+ const sameTypeNodesBefore = nodes.filter(
+ (n) => n.type === "genericNode" && n.data.node.display_name === displayName,
+ );
+ const needsPromoteFirst =
+ sameTypeNodesBefore.length === 1 &&
+ !sameTypeNodesBefore[0].data.node.alias;
+
+ // Assign alias to the new node (the utility will also compute target aliases)
+ assignAliasToNewComponent(newNode, nodes);
+
+ // Persist alias on the first existing node immutably so subscribers re-render
+ if (needsPromoteFirst) {
+ const firstId = sameTypeNodesBefore[0].id;
+ setNodes((currentNodes) =>
+ currentNodes.map((n) =>
+ n.id === firstId && n.type === "genericNode"
+ ? {
+ ...n,
+ data: {
+ ...n.data,
+ node: {
+ ...n.data.node,
+ alias: `${displayName}#1`,
+ },
+ },
+ }
+ : n,
+ ),
+ );
+ }📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| paste({ nodes: [newNode], edges: [] }, pos); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [store, paste], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [store, paste, nodes, setNodes], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return addComponent; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| import { ENABLE_DATASTAX_LANGFLOW } from "@/customization/feature-flags"; | ||
| import { customGetHostProtocol } from "@/customization/utils/custom-get-host-protocol"; | ||
| import { GetCodeType } from "@/types/tweaks"; | ||
| import { convertTweaksToAliases } from "@/utils/aliasUtils"; | ||
| import { | ||
| getAllChatInputNodeIds, | ||
| getAllFileNodeIds, | ||
|
|
@@ -56,12 +57,14 @@ export function getNewCurlCode({ | |
| processedPayload, | ||
| platform, | ||
| shouldDisplayApiKey, | ||
| nodes, | ||
| }: { | ||
| flowId: string; | ||
| endpointName: string; | ||
| processedPayload: any; | ||
| platform?: "unix" | "powershell"; | ||
| shouldDisplayApiKey: boolean; | ||
| nodes?: any[]; | ||
| }): { steps: { title: string; code: string }[] } | string { | ||
| const { protocol, host } = customGetHostProtocol(); | ||
| const baseUrl = `${protocol}//${host}`; | ||
|
|
@@ -75,14 +78,21 @@ export function getNewCurlCode({ | |
| : "unix"); | ||
|
|
||
| // Check if there are file uploads | ||
| const tweaks = processedPayload.tweaks || {}; | ||
| const hasFiles = hasFileTweaks(tweaks); | ||
| const originalTweaks = processedPayload.tweaks || {}; | ||
| const tweaks = convertTweaksToAliases(originalTweaks, nodes); | ||
| const hasFiles = hasFileTweaks(originalTweaks); // Use original tweaks for file detection | ||
|
|
||
| // Create payload with aliased tweaks | ||
| const payloadWithAliases = { | ||
| ...processedPayload, | ||
| tweaks: tweaks, | ||
| }; | ||
|
|
||
| // If no file uploads, use existing logic | ||
| if (!hasFiles) { | ||
| if (detectedPlatform === "powershell") { | ||
| const payloadWithSession = { | ||
| ...processedPayload, | ||
| ...payloadWithAliases, | ||
| session_id: "YOUR_SESSION_ID_HERE", | ||
| }; | ||
| const singleLinePayload = JSON.stringify(payloadWithSession); | ||
|
|
@@ -103,7 +113,7 @@ curl.exe --request POST \` | |
| --data $jsonData`; | ||
| } else { | ||
| const payloadWithSession = { | ||
| ...processedPayload, | ||
| ...payloadWithAliases, | ||
| session_id: "YOUR_SESSION_ID_HERE", | ||
| }; | ||
| // Unix-like systems (Linux, Mac, WSL2) | ||
|
|
@@ -126,9 +136,9 @@ curl.exe --request POST \` | |
| } | ||
|
|
||
| // File upload logic - handle multiple file types additively | ||
| const chatInputNodeIds = getAllChatInputNodeIds(tweaks); | ||
| const fileNodeIds = getAllFileNodeIds(tweaks); | ||
| const nonFileTweaks = getNonFileTypeTweaks(tweaks); | ||
| const chatInputNodeIds = getAllChatInputNodeIds(originalTweaks); // Use original tweaks for detection | ||
| const fileNodeIds = getAllFileNodeIds(originalTweaks); // Use original tweaks for detection | ||
| const nonFileTweaks = getNonFileTypeTweaks(tweaks); // Use aliased tweaks for display | ||
|
|
||
| // Build upload commands and tweak entries | ||
| const uploadCommands: string[] = []; | ||
|
|
@@ -152,16 +162,17 @@ curl.exe --request POST \` | |
| --form "file=@your_image_${uploadCounter}.jpg"`, | ||
| ); | ||
| } | ||
| const originalTweak = tweaks[nodeId]; | ||
|
|
||
| // Get alias for this node | ||
| const node = nodes?.find((n) => n.id === nodeId); | ||
| const alias = node ? getEffectiveAliasFromAnyNode(node) : nodeId; | ||
|
|
||
|
Comment on lines
+166
to
+169
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing import for Function is used but not imported. Apply: import { GetCodeType } from "@/types/tweaks";
+import { getEffectiveAliasFromAnyNode } from "@/types/flow";Also applies to: 199-202 🤖 Prompt for AI Agents |
||
| const originalTweak = originalTweaks[nodeId]; | ||
| const modifiedTweak = { ...originalTweak }; | ||
| modifiedTweak.files = [ | ||
| `REPLACE_WITH_FILE_PATH_FROM_UPLOAD_${uploadCounter}`, | ||
| ]; | ||
| const tweakEntry = ` "${nodeId}": ${JSON.stringify( | ||
| modifiedTweak, | ||
| null, | ||
| 6, | ||
| ) | ||
| const tweakEntry = ` "${alias}": ${JSON.stringify(modifiedTweak, null, 6) | ||
| .split("\n") | ||
| .join("\n ")}`; | ||
| tweakEntries.push(tweakEntry); | ||
|
|
@@ -185,7 +196,11 @@ curl.exe --request POST \` | |
| --form "file=@your_file_${uploadCounter}.pdf"`, | ||
| ); | ||
| } | ||
| const originalTweak = tweaks[nodeId]; | ||
| // Get alias for this node | ||
| const node = nodes?.find((n) => n.id === nodeId); | ||
| const alias = node ? getEffectiveAliasFromAnyNode(node) : nodeId; | ||
|
|
||
| const originalTweak = originalTweaks[nodeId]; | ||
| const modifiedTweak = { ...originalTweak }; | ||
| if ("path" in originalTweak) { | ||
| modifiedTweak.path = [ | ||
|
|
@@ -194,21 +209,17 @@ curl.exe --request POST \` | |
| } else if ("file_path" in originalTweak) { | ||
| modifiedTweak.file_path = `REPLACE_WITH_FILE_PATH_FROM_UPLOAD_${uploadCounter}`; | ||
| } | ||
| const tweakEntry = ` "${nodeId}": ${JSON.stringify( | ||
| modifiedTweak, | ||
| null, | ||
| 6, | ||
| ) | ||
| const tweakEntry = ` "${alias}": ${JSON.stringify(modifiedTweak, null, 6) | ||
| .split("\n") | ||
| .join("\n ")}`; | ||
| tweakEntries.push(tweakEntry); | ||
| uploadCounter++; | ||
| }); | ||
|
|
||
| // Add non-file tweaks | ||
| Object.entries(nonFileTweaks).forEach(([nodeId, tweak]) => { | ||
| // Add non-file tweaks (already aliased) | ||
| Object.entries(nonFileTweaks).forEach(([aliasOrNodeId, tweak]) => { | ||
| tweakEntries.push( | ||
| ` "${nodeId}": ${JSON.stringify(tweak, null, 6) | ||
| ` "${aliasOrNodeId}": ${JSON.stringify(tweak, null, 6) | ||
| .split("\n") | ||
| .join("\n ")}`, | ||
| ); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify alias update produces a new nodes array
If updateAliasesForDisplayNameChange mutates and returns the same array reference, some subscribers may not re-render. Ensure it returns a new array instance.
Run:
Expected: It returns a new array (e.g., return [...allNodes]). If it returns allNodes directly, consider cloning before setNodes.
🏁 Script executed:
Length of output: 262
Ensure
updateAliasesForDisplayNameChangealways returns a new array instanceIn
src/frontend/src/utils/aliasUtils.tsthe function currently does:return allNodes;return allNodes;Both return the original array reference, which can prevent subscribers from re-rendering. Change these to return a clone (e.g.
return [...allNodes]) or otherwise produce a new array before callingsetNodes.🤖 Prompt for AI Agents