## Description **Problem** When deleting a List widget in the EE environment, the widget is successfully removed, but errors are displayed in the in-app debugger. These errors disappear upon refreshing the page, leaving users confused as to why the errors appeared in the first place, despite the widget being deleted correctly. **Root Cause** - The issue arises from the sequence in which widgets and their associated meta widgets are deleted. - When deleting a widget with meta widgets (e.g., a List widget): - The main widget is removed first via the deleteWidget saga. - Meta widgets are then deleted later during the componentWillUnmount lifecycle method. - The lint evaluation runs between these two processes, detecting meta widgets still present in the state without a parent widget. - This mismatch triggers errors in the in-app debugger, which disappear once the page is refreshed, as the meta widgets have already been deleted by then. **Solution** - We have modified the deletion process to ensure that both the main widget and its associated meta widgets are removed within the same action. - Instead of handling meta widget deletion in the general deleteSaga: - We now check for widgets with the hasMetaWidgets flag within the deleteWidget saga. - If such widgets are found, their meta widgets are deleted before the main widget is removed from the layout. - This adjustment ensures that the lint evaluation occurs after both the main widget and its meta widgets have been removed, preventing errors in the debugger. Fixes #35628 ## Automation /ok-to-test tags="@tag.Widget, @tag.List, @tag.IDE, @tag.Sanity" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/10629216245> > Commit: 56a4c85076d574cc2ebfef12d3b9f998ee1a4ece > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10629216245&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Widget, @tag.List, @tag.IDE, @tag.Sanity` > Spec: > <hr>Fri, 30 Aug 2024 09:25:02 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Enhanced testing for the list widget to include verification of the drag, drop, and delete functionalities. - Improved widget deletion process by ensuring related meta widgets are also addressed during deletion. - Updated test descriptions for better clarity and scope, specifically focusing on deletion functionality. - Introduced a factory for creating instances of version 2 list widgets, streamlining widget generation. - **Bug Fixes** - Expanded test coverage for potential issues in widget behavior, particularly concerning deletion. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
53 lines
1.4 KiB
TypeScript
53 lines
1.4 KiB
TypeScript
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
|
|
import { keyBy } from "lodash";
|
|
import { runSaga } from "redux-saga";
|
|
import store, { testStore } from "store";
|
|
import { ListV2Factory } from "test/factories/Widgets/ListV2Factory";
|
|
import { deleteSaga } from "./WidgetDeletionSagas";
|
|
|
|
test("deleteSaga should dispatch DELETE_META_WIDGETS when widget has meta widgets", async () => {
|
|
const listWidget = ListV2Factory.build();
|
|
const defaultState = store.getState();
|
|
const mockStore = testStore({
|
|
...defaultState,
|
|
entities: {
|
|
...defaultState.entities,
|
|
canvasWidgets: keyBy([listWidget], "widgetId"),
|
|
},
|
|
ui: {
|
|
...defaultState.ui,
|
|
widgetDragResize: {
|
|
...defaultState.ui.widgetDragResize,
|
|
lastSelectedWidget: listWidget.widgetId,
|
|
},
|
|
},
|
|
});
|
|
const dispatched: unknown[] = [];
|
|
|
|
const deleteAction = {
|
|
type: "DELETE_WIDGET",
|
|
payload: {
|
|
widgetId: undefined,
|
|
parentId: undefined,
|
|
disallowUndo: false,
|
|
isShortcut: false,
|
|
},
|
|
};
|
|
|
|
await runSaga(
|
|
{
|
|
dispatch: (action) => dispatched.push(action),
|
|
getState: () => mockStore.getState(),
|
|
},
|
|
deleteSaga,
|
|
deleteAction,
|
|
).toPromise();
|
|
|
|
expect(dispatched).toContainEqual({
|
|
type: ReduxActionTypes.DELETE_META_WIDGETS,
|
|
payload: {
|
|
creatorIds: [listWidget.widgetId],
|
|
},
|
|
});
|
|
});
|