Fix: App crash on list widget after copy/paste (#5605)
* fix list widget in list widget bug when pasting
* remove console.log
* add test
Co-authored-by: root <root@DESKTOP-9GENCK0.localdomain>
(cherry picked from commit fa4e42f4c6)
This commit is contained in:
parent
be05a1bc26
commit
df4cfb99ab
|
|
@ -1301,7 +1301,11 @@ const unsetPropertyPath = (obj: Record<string, unknown>, path: string) => {
|
||||||
|
|
||||||
function* resetChildrenMetaSaga(action: ReduxAction<{ widgetId: string }>) {
|
function* resetChildrenMetaSaga(action: ReduxAction<{ widgetId: string }>) {
|
||||||
const parentWidgetId = action.payload.widgetId;
|
const parentWidgetId = action.payload.widgetId;
|
||||||
const childrenIds: string[] = yield call(getWidgetChildren, parentWidgetId);
|
const canvasWidgets: CanvasWidgetsReduxState = yield select(getWidgets);
|
||||||
|
const childrenIds: string[] = getWidgetChildren(
|
||||||
|
canvasWidgets,
|
||||||
|
parentWidgetId,
|
||||||
|
);
|
||||||
for (const childIndex in childrenIds) {
|
for (const childIndex in childrenIds) {
|
||||||
const childId = childrenIds[childIndex];
|
const childId = childrenIds[childIndex];
|
||||||
yield put(resetWidgetMetaProperty(childId));
|
yield put(resetWidgetMetaProperty(childId));
|
||||||
|
|
@ -1483,6 +1487,7 @@ function* pasteWidgetSaga() {
|
||||||
parentId: string;
|
parentId: string;
|
||||||
list: WidgetProps[];
|
list: WidgetProps[];
|
||||||
}[] = yield getCopiedWidgets();
|
}[] = yield getCopiedWidgets();
|
||||||
|
|
||||||
if (!Array.isArray(copiedWidgetGroups)) {
|
if (!Array.isArray(copiedWidgetGroups)) {
|
||||||
return;
|
return;
|
||||||
// to avoid invoking old copied widgets
|
// to avoid invoking old copied widgets
|
||||||
|
|
@ -1492,12 +1497,17 @@ function* pasteWidgetSaga() {
|
||||||
getSelectedWidget,
|
getSelectedWidget,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
selectedWidget = yield checkIfPastingIntoListWidget(
|
||||||
|
stateWidgets,
|
||||||
|
selectedWidget,
|
||||||
|
copiedWidgetGroups,
|
||||||
|
);
|
||||||
|
|
||||||
const pastingIntoWidgetId: string = yield getParentWidgetIdForPasting(
|
const pastingIntoWidgetId: string = yield getParentWidgetIdForPasting(
|
||||||
{ ...stateWidgets },
|
{ ...stateWidgets },
|
||||||
selectedWidget,
|
selectedWidget,
|
||||||
);
|
);
|
||||||
|
|
||||||
selectedWidget = yield checkIfPastingIntoListWidget(selectedWidget);
|
|
||||||
let widgets = { ...stateWidgets };
|
let widgets = { ...stateWidgets };
|
||||||
const newlyCreatedWidgetIds: string[] = [];
|
const newlyCreatedWidgetIds: string[] = [];
|
||||||
const sortedWidgetList = copiedWidgetGroups.sort(
|
const sortedWidgetList = copiedWidgetGroups.sort(
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import {
|
||||||
handleIfParentIsListWidgetWhilePasting,
|
handleIfParentIsListWidgetWhilePasting,
|
||||||
handleSpecificCasesWhilePasting,
|
handleSpecificCasesWhilePasting,
|
||||||
doesTriggerPathsContainPropertyPath,
|
doesTriggerPathsContainPropertyPath,
|
||||||
|
checkIfPastingIntoListWidget,
|
||||||
} from "./WidgetOperationUtils";
|
} from "./WidgetOperationUtils";
|
||||||
|
|
||||||
describe("WidgetOperationSaga", () => {
|
describe("WidgetOperationSaga", () => {
|
||||||
|
|
@ -384,4 +385,75 @@ describe("WidgetOperationSaga", () => {
|
||||||
"{{closeModal('Modal1Copy')}}",
|
"{{closeModal('Modal1Copy')}}",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should returns widgets after executing checkIfPastingIntoListWidget", async () => {
|
||||||
|
const result = checkIfPastingIntoListWidget(
|
||||||
|
{
|
||||||
|
list2: {
|
||||||
|
widgetId: "list2",
|
||||||
|
type: "LIST_WIDGET",
|
||||||
|
widgetName: "List2",
|
||||||
|
parentId: "0",
|
||||||
|
renderMode: "CANVAS",
|
||||||
|
parentColumnSpace: 2,
|
||||||
|
parentRowSpace: 3,
|
||||||
|
leftColumn: 2,
|
||||||
|
rightColumn: 3,
|
||||||
|
topRow: 1,
|
||||||
|
bottomRow: 3,
|
||||||
|
isLoading: false,
|
||||||
|
listData: [],
|
||||||
|
version: 16,
|
||||||
|
disablePropertyPane: false,
|
||||||
|
template: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
widgetId: "list2",
|
||||||
|
type: "LIST_WIDGET",
|
||||||
|
widgetName: "List2",
|
||||||
|
parentId: "0",
|
||||||
|
renderMode: "CANVAS",
|
||||||
|
parentColumnSpace: 2,
|
||||||
|
parentRowSpace: 3,
|
||||||
|
leftColumn: 2,
|
||||||
|
rightColumn: 3,
|
||||||
|
topRow: 1,
|
||||||
|
bottomRow: 3,
|
||||||
|
isLoading: false,
|
||||||
|
listData: [],
|
||||||
|
version: 16,
|
||||||
|
disablePropertyPane: false,
|
||||||
|
template: {},
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
widgetId: "list2",
|
||||||
|
parentId: "0",
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
widgetId: "list2",
|
||||||
|
type: "LIST_WIDGET",
|
||||||
|
widgetName: "List2",
|
||||||
|
parentId: "0",
|
||||||
|
renderMode: "CANVAS",
|
||||||
|
parentColumnSpace: 2,
|
||||||
|
parentRowSpace: 3,
|
||||||
|
leftColumn: 2,
|
||||||
|
rightColumn: 3,
|
||||||
|
topRow: 1,
|
||||||
|
bottomRow: 3,
|
||||||
|
isLoading: false,
|
||||||
|
listData: [],
|
||||||
|
version: 16,
|
||||||
|
disablePropertyPane: false,
|
||||||
|
template: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result?.type).toStrictEqual("LIST_WIDGET");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@ import {
|
||||||
CanvasWidgetsReduxState,
|
CanvasWidgetsReduxState,
|
||||||
FlattenedWidgetProps,
|
FlattenedWidgetProps,
|
||||||
} from "reducers/entityReducers/canvasWidgetsReducer";
|
} from "reducers/entityReducers/canvasWidgetsReducer";
|
||||||
import { call, select } from "redux-saga/effects";
|
import { select } from "redux-saga/effects";
|
||||||
import { getDynamicBindings } from "utils/DynamicBindingUtils";
|
import { getDynamicBindings } from "utils/DynamicBindingUtils";
|
||||||
import { getWidget, getWidgetMetaProps } from "./selectors";
|
import { WidgetProps } from "widgets/BaseWidget";
|
||||||
|
import { getWidgetMetaProps } from "./selectors";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks if triggerpaths contains property path passed
|
* checks if triggerpaths contains property path passed
|
||||||
|
|
@ -203,9 +204,12 @@ export const handleSpecificCasesWhilePasting = (
|
||||||
return widgets;
|
return widgets;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function* getWidgetChildren(widgetId: string): any {
|
export function getWidgetChildren(
|
||||||
|
canvasWidgets: CanvasWidgetsReduxState,
|
||||||
|
widgetId: string,
|
||||||
|
): any {
|
||||||
const childrenIds: string[] = [];
|
const childrenIds: string[] = [];
|
||||||
const widget = yield select(getWidget, widgetId);
|
const widget = get(canvasWidgets, widgetId);
|
||||||
// When a form widget tries to resetChildrenMetaProperties
|
// When a form widget tries to resetChildrenMetaProperties
|
||||||
// But one or more of its container like children
|
// But one or more of its container like children
|
||||||
// have just been deleted, widget can be undefined
|
// have just been deleted, widget can be undefined
|
||||||
|
|
@ -218,7 +222,7 @@ export function* getWidgetChildren(widgetId: string): any {
|
||||||
if (children.hasOwnProperty(childIndex)) {
|
if (children.hasOwnProperty(childIndex)) {
|
||||||
const child = children[childIndex];
|
const child = children[childIndex];
|
||||||
childrenIds.push(child);
|
childrenIds.push(child);
|
||||||
const grandChildren = yield call(getWidgetChildren, child);
|
const grandChildren = getWidgetChildren(canvasWidgets, child);
|
||||||
if (grandChildren.length) {
|
if (grandChildren.length) {
|
||||||
childrenIds.push(...grandChildren);
|
childrenIds.push(...grandChildren);
|
||||||
}
|
}
|
||||||
|
|
@ -251,8 +255,11 @@ export const getParentWidgetIdForPasting = function*(
|
||||||
newWidgetParentId = selectedWidget.parentId;
|
newWidgetParentId = selectedWidget.parentId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Select the selected widget if the widget is container like
|
// Select the selected widget if the widget is container like ( excluding list widget )
|
||||||
if (selectedWidget.children) {
|
if (
|
||||||
|
selectedWidget.children &&
|
||||||
|
selectedWidget.type !== WidgetTypes.LIST_WIDGET
|
||||||
|
) {
|
||||||
parentWidget = widgets[selectedWidget.widgetId];
|
parentWidget = widgets[selectedWidget.widgetId];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -289,8 +296,14 @@ export const getParentWidgetIdForPasting = function*(
|
||||||
return newWidgetParentId;
|
return newWidgetParentId;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const checkIfPastingIntoListWidget = function*(
|
export const checkIfPastingIntoListWidget = function(
|
||||||
|
canvasWidgets: CanvasWidgetsReduxState,
|
||||||
selectedWidget: FlattenedWidgetProps | undefined,
|
selectedWidget: FlattenedWidgetProps | undefined,
|
||||||
|
copiedWidgets: {
|
||||||
|
widgetId: string;
|
||||||
|
parentId: string;
|
||||||
|
list: WidgetProps[];
|
||||||
|
}[],
|
||||||
) {
|
) {
|
||||||
// when list widget is selected, if the user is pasting, we want it to be pasted in the template
|
// when list widget is selected, if the user is pasting, we want it to be pasted in the template
|
||||||
// which is first children of list widget
|
// which is first children of list widget
|
||||||
|
|
@ -299,13 +312,23 @@ export const checkIfPastingIntoListWidget = function*(
|
||||||
selectedWidget.children &&
|
selectedWidget.children &&
|
||||||
selectedWidget?.type === WidgetTypes.LIST_WIDGET
|
selectedWidget?.type === WidgetTypes.LIST_WIDGET
|
||||||
) {
|
) {
|
||||||
const childrenIds: string[] = yield call(
|
const childrenIds: string[] = getWidgetChildren(
|
||||||
getWidgetChildren,
|
canvasWidgets,
|
||||||
selectedWidget.children[0],
|
selectedWidget.children[0],
|
||||||
);
|
);
|
||||||
const firstChildId = childrenIds[0];
|
const firstChildId = childrenIds[0];
|
||||||
|
|
||||||
selectedWidget = yield select(getWidget, firstChildId);
|
// if any copiedWidget is a list widget, we will paste into the parent of list widget
|
||||||
|
for (let i = 0; i < copiedWidgets.length; i++) {
|
||||||
|
const copiedWidgetId = copiedWidgets[i].widgetId;
|
||||||
|
const copiedWidget = canvasWidgets[copiedWidgetId];
|
||||||
|
|
||||||
|
if (copiedWidget.type === WidgetTypes.LIST_WIDGET) {
|
||||||
|
return selectedWidget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return get(canvasWidgets, firstChildId);
|
||||||
}
|
}
|
||||||
return selectedWidget;
|
return selectedWidget;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user