From ccc8ad32d68800b986640b827c746ceb19b4951a Mon Sep 17 00:00:00 2001 From: Ashok Kumar M <35134347+marks0351@users.noreply.github.com> Date: Mon, 23 Oct 2023 16:41:40 +0530 Subject: [PATCH] fix: Check for parent widget existence to render drop target (#28275) In the legacy architecture, List Widget meta first item was rendering in edit mode allowing DnD, resize, etc while the rest of the items were rendering in view mode restricting any editing experience. The first item was being used as a template to decide what the template was going to be for rest of the items. However after the overhaul of BaseWidget and CanvasWidget render mode is always EDIT or VIEW for all widgets so DropTarget had to render a meta canvas widget which it was not written to handle. so have added checks to make sure DropTarget does not render and wrap widgets that do not have a parent. Ideally this should have been caught in the CI, there are tests already but the checks were happening to check if List widget was allowed inside another List widget but the other items that were rendering in view mode were not being asserted. I have added tests to check if all nested widgets are properly rendered and there is no "Oops, something went wrong" error. This should make sure this issue does not get past CI in the future. (cherry picked from commit 6355e7a697da9b0eaebe583c47dc752c5449b718) --- .../Widgets/ListV2/ListV2_NestedList_spec.ts | 9 +++++++++ app/client/cypress/fixtures/listV2NestedDsl.json | 2 +- .../common/dropTarget/DropTargetComponentWrapper.tsx | 10 +++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_NestedList_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_NestedList_spec.ts index 0bd956001d..5b0d9269cf 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_NestedList_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/ListV2_NestedList_spec.ts @@ -1,3 +1,4 @@ +import { WIDGET } from "../../../../../locators/WidgetLocators"; import { agHelper, entityExplorer, @@ -13,6 +14,14 @@ describe("Nested List widget V2 ", () => { }); it("1. Verify only 3 levels of nesting is allowed", () => { + agHelper.AssertContains( + "Oops, Something went wrong.", + "not.exist", + locators._widgetInCanvas(WIDGET.LIST_V2), + ); + agHelper + .GetElement(locators._widgetInCanvas(WIDGET.LIST_V2)) + .should("have.length", 5); entityExplorer.SelectEntityByName("List1", "Widgets"); entityExplorer.SelectEntityByName("Container1", "List1"); entityExplorer.SelectEntityByName("List2", "Container1"); diff --git a/app/client/cypress/fixtures/listV2NestedDsl.json b/app/client/cypress/fixtures/listV2NestedDsl.json index 8d8948cea5..d2f772e7c9 100644 --- a/app/client/cypress/fixtures/listV2NestedDsl.json +++ b/app/client/cypress/fixtures/listV2NestedDsl.json @@ -1238,7 +1238,7 @@ } ], "displayName": "List", - "bottomRow": 48, + "bottomRow": 88, "parentRowSpace": 10, "hideCard": false, "templateBottomRow": 16, diff --git a/app/client/src/layoutSystems/common/dropTarget/DropTargetComponentWrapper.tsx b/app/client/src/layoutSystems/common/dropTarget/DropTargetComponentWrapper.tsx index 45ec5947a6..ecc048b180 100644 --- a/app/client/src/layoutSystems/common/dropTarget/DropTargetComponentWrapper.tsx +++ b/app/client/src/layoutSystems/common/dropTarget/DropTargetComponentWrapper.tsx @@ -3,6 +3,10 @@ import type { DropTargetComponentProps } from "layoutSystems/common/dropTarget/D import type { ReactNode } from "react"; import { memo } from "react"; import React from "react"; +import { useSelector } from "react-redux"; +import { getWidget } from "sagas/selectors"; +import type { AppState } from "@appsmith/reducers"; +import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; interface DropTargetComponentWrapperProps { dropTargetProps: DropTargetComponentProps; @@ -22,7 +26,11 @@ export const DropTargetComponentWrapper = memo( dropDisabled, dropTargetProps, }: DropTargetComponentWrapperProps) => { - if (dropDisabled) { + // This code block is added exclusively to handle List Widget Meta Canvas Widget which is generated via template. + const widget = useSelector((state: AppState) => + getWidget(state, dropTargetProps.parentId || MAIN_CONTAINER_WIDGET_ID), + ); + if ((dropTargetProps.parentId && !widget) || dropDisabled) { //eslint-disable-next-line return <>{children}; }