feat: Clear handles from advanced fields on code update (#8754)
* ✨ (frontend): add new function clearHandlesFromAdvancedFields to handle clearing handles from advanced fields when code is updated 📝 (frontend): update documentation and add tests for deleting handles from advanced fields when code is updated 🔧 (frontend): remove unused style for Outlook in styleUtils to clean up code 🔧 (frontend): add test for deleting handles from advanced fields when code is updated in general-bugs-delete-handle-advanced-input.spec * ✨ (frontend): add support for managing edges and nodes in the flowStore to improve data handling and flow visualization ♻️ (frontend): refactor cleanEdges function to accept an object with nodes, edges, componentId, and data parameters for better modularity and reusability * ✨ (codeAreaModal/index.tsx): Refactor import statements and function names for better clarity and organization ♻️ (flowStore.ts): Refactor cleanEdges function to accept nodes and edges as separate arguments instead of an object ♻️ (flowStore.ts): Update all calls to cleanEdges function to pass nodes and edges separately ♻️ (reactflowUtils.ts): Refactor clearHandlesFromAdvancedFields function to accept only necessary arguments and remove unnecessary logic
This commit is contained in:
parent
04f8f90649
commit
65b71bec5b
4 changed files with 132 additions and 3 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { usePostValidateCode } from "@/controllers/API/queries/nodes/use-post-validate-code";
|
||||
import { usePostValidateComponentCode } from "@/controllers/API/queries/nodes/use-post-validate-component-code";
|
||||
import useFlowStore from "@/stores/flowStore";
|
||||
import { clearHandlesFromAdvancedFields } from "@/utils/reactflowUtils";
|
||||
import "ace-builds/src-noconflict/ace";
|
||||
import "ace-builds/src-noconflict/ext-language_tools";
|
||||
import "ace-builds/src-noconflict/ext-searchbox";
|
||||
|
|
@ -83,7 +83,6 @@ export default function CodeAreaModal({
|
|||
});
|
||||
setOpen(false);
|
||||
setValue(code);
|
||||
// setValue(code);
|
||||
} else {
|
||||
if (funcErrors.length !== 0) {
|
||||
setErrorData({
|
||||
|
|
@ -121,6 +120,8 @@ export default function CodeAreaModal({
|
|||
onSuccess: ({ data, type }) => {
|
||||
if (data && type) {
|
||||
setValue(code);
|
||||
clearHandlesFromAdvancedFields(componentId!, data);
|
||||
|
||||
setNodeClass(data, type);
|
||||
setError({ detail: { error: undefined, traceback: undefined } });
|
||||
setOpen(false);
|
||||
|
|
@ -255,6 +256,7 @@ export default function CodeAreaModal({
|
|||
type="submit"
|
||||
id="checkAndSaveBtn"
|
||||
disabled={readonly}
|
||||
data-testid="checkAndSaveBtn"
|
||||
>
|
||||
Check & Save
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -176,6 +176,45 @@ export function cleanEdges(nodes: AllNodeType[], edges: EdgeType[]) {
|
|||
return newEdges;
|
||||
}
|
||||
|
||||
export function clearHandlesFromAdvancedFields(
|
||||
componentId: string,
|
||||
data: APIClassType,
|
||||
): void {
|
||||
if (!componentId || !data?.template) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const flowStore = useFlowStore.getState();
|
||||
const { edges, deleteEdge } = flowStore;
|
||||
|
||||
const connectedEdges = edges.filter((edge) => edge.target === componentId);
|
||||
|
||||
if (connectedEdges.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const edgeIdsToDelete: string[] = [];
|
||||
|
||||
for (const edge of connectedEdges) {
|
||||
const fieldName = edge.data?.targetHandle?.fieldName;
|
||||
|
||||
if (fieldName && isAdvancedField(data, fieldName)) {
|
||||
edgeIdsToDelete.push(edge.id);
|
||||
}
|
||||
}
|
||||
|
||||
edgeIdsToDelete.forEach(deleteEdge);
|
||||
} catch (error) {
|
||||
console.error("Error clearing handles from advanced fields:", error);
|
||||
}
|
||||
}
|
||||
|
||||
const isAdvancedField = (data: APIClassType, fieldName: string): boolean => {
|
||||
const field = data.template[fieldName];
|
||||
return field && "advanced" in field && field.advanced === true;
|
||||
};
|
||||
|
||||
export function filterHiddenFieldsEdges(
|
||||
edge: EdgeType,
|
||||
newEdges: EdgeType[],
|
||||
|
|
|
|||
|
|
@ -229,7 +229,6 @@ export const SIDEBAR_CATEGORIES = [
|
|||
];
|
||||
|
||||
export const SIDEBAR_BUNDLES = [
|
||||
{ display_name: "Outlook", name: "outlook", icon: "Outlook" },
|
||||
{
|
||||
display_name: "Language Models",
|
||||
name: "languagemodels",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
import { expect, test } from "@playwright/test";
|
||||
import { awaitBootstrapTest } from "../../utils/await-bootstrap-test";
|
||||
import { extractAndCleanCode } from "../../utils/extract-and-clean-code";
|
||||
import { zoomOut } from "../../utils/zoom-out";
|
||||
|
||||
test(
|
||||
"the system must delete the handles from advanced fields when the code is updated",
|
||||
{ tag: ["@release"] },
|
||||
async ({ page }) => {
|
||||
await awaitBootstrapTest(page);
|
||||
|
||||
await page.getByTestId("blank-flow").click();
|
||||
|
||||
await page.waitForSelector('[data-testid="fit_view"]', {
|
||||
timeout: 100000,
|
||||
});
|
||||
await page.getByTestId("sidebar-search-input").click();
|
||||
await page.getByTestId("sidebar-search-input").fill("if else");
|
||||
|
||||
await page
|
||||
.getByTestId("logicIf-Else")
|
||||
.hover()
|
||||
.then(async () => {
|
||||
await page.getByTestId("add-component-button-if-else").click();
|
||||
});
|
||||
|
||||
await page.getByTestId("fit_view").click();
|
||||
await zoomOut(page, 3);
|
||||
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.getByTestId("showmessage").click();
|
||||
|
||||
await page.getByText("Close").last().click();
|
||||
|
||||
await page.getByTestId("sidebar-search-input").click();
|
||||
await page.getByTestId("sidebar-search-input").fill("text input");
|
||||
await page.waitForSelector('[data-testid="input_outputText Input"]', {
|
||||
timeout: 2000,
|
||||
});
|
||||
await page
|
||||
.getByTestId("input_outputText Input")
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'), {
|
||||
targetPosition: { x: 200, y: 100 },
|
||||
});
|
||||
|
||||
await page
|
||||
.getByTestId("handle-textinput-shownode-output text-right")
|
||||
.click();
|
||||
|
||||
await page
|
||||
.getByTestId("handle-conditionalrouter-shownode-alternative output-left")
|
||||
.click();
|
||||
|
||||
await page.getByTestId("title-If-Else").click();
|
||||
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
const numberOfDisabledInputs = await page
|
||||
.getByPlaceholder("Receiving input")
|
||||
.count();
|
||||
|
||||
expect(numberOfDisabledInputs).toBe(2);
|
||||
|
||||
const numberOfLockIcons = await page.getByTestId("icon-lock").count();
|
||||
|
||||
expect(numberOfLockIcons).toBe(2);
|
||||
|
||||
await page.getByText("Close").last().click();
|
||||
|
||||
await page.getByTestId("title-If-Else").click();
|
||||
|
||||
await page.getByTestId("code-button-modal").click();
|
||||
|
||||
await page.getByTestId("checkAndSaveBtn").last().click();
|
||||
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
const numberOfDisabledInputsAfter = await page
|
||||
.getByPlaceholder("Receiving input")
|
||||
.count();
|
||||
|
||||
expect(numberOfDisabledInputsAfter).toBe(0);
|
||||
|
||||
const numberOfLockIconsAfter = await page.getByTestId("icon-lock").count();
|
||||
|
||||
expect(numberOfLockIconsAfter).toBe(0);
|
||||
},
|
||||
);
|
||||
Loading…
Add table
Add a link
Reference in a new issue