diff --git a/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas.ts b/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas.ts index 579c607891..20f4b55df2 100644 --- a/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas.ts +++ b/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas.ts @@ -11,7 +11,6 @@ import type { } from "../../utils/anvilTypes"; import { getWidget, getWidgets } from "sagas/selectors"; import { addWidgetsToPreset } from "../../utils/layouts/update/additionUtils"; -import { moveWidgets } from "../../utils/layouts/update/moveUtils"; import type { AnvilMoveWidgetsPayload, AnvilNewWidgetsPayload, @@ -41,6 +40,7 @@ import { getCreateWidgetPayload, } from "layoutSystems/anvil/utils/widgetAdditionUtils"; import { updateAndSaveAnvilLayout } from "../../utils/anvilChecksUtils"; +import { moveWidgetsToZone } from "layoutSystems/anvil/utils/layouts/update/zoneUtils"; // Function to retrieve highlighting information for the last row in the main canvas layout export function* getMainCanvasLastRowHighlight() { @@ -363,8 +363,14 @@ export function* handleWidgetMovement( highlight, ); } else { - updatedWidgets = moveWidgets(allWidgets, movedWidgetIds, highlight); + updatedWidgets = yield call( + moveWidgetsToZone, + allWidgets, + movedWidgetIds, + highlight, + ); } + return updatedWidgets; } diff --git a/app/client/src/layoutSystems/anvil/utils/layouts/update/sectionUtils.ts b/app/client/src/layoutSystems/anvil/utils/layouts/update/sectionUtils.ts index 3000a4a254..427a57c275 100644 --- a/app/client/src/layoutSystems/anvil/utils/layouts/update/sectionUtils.ts +++ b/app/client/src/layoutSystems/anvil/utils/layouts/update/sectionUtils.ts @@ -158,6 +158,7 @@ export function* addWidgetsToSection( * Can this be prevent during DnD itself? i.e. Don't show highlights for sections that can't handle so many zones. */ const [zones, nonZones] = splitWidgets(draggedWidgets); + let itemsAdded = 0; /** * Step 2: Add zones to the section layout. */ @@ -175,13 +176,14 @@ export function* addWidgetsToSection( sectionProps, sectionLayout, sectionComp, - highlight, + { ...highlight, rowIndex: highlight.rowIndex + itemsAdded }, zone, ); sectionProps = res.canvasWidgets[sectionProps.widgetId]; sectionLayout = res.section; canvasWidgets = res.canvasWidgets; + itemsAdded += 1; } /** @@ -198,7 +200,7 @@ export function* addWidgetsToSection( createZoneAndAddWidgets, canvasWidgets, nonZones, - highlight, + { ...highlight, rowIndex: highlight.rowIndex + itemsAdded }, sectionProps.widgetId, ); sectionProps.children = [ diff --git a/app/client/src/layoutSystems/anvil/utils/layouts/update/zoneUtils.ts b/app/client/src/layoutSystems/anvil/utils/layouts/update/zoneUtils.ts index 3823d6855b..b8677fbce3 100644 --- a/app/client/src/layoutSystems/anvil/utils/layouts/update/zoneUtils.ts +++ b/app/client/src/layoutSystems/anvil/utils/layouts/update/zoneUtils.ts @@ -16,6 +16,8 @@ import { } from "../../widgetAdditionUtils"; import { isLargeWidget } from "../../widgetUtils"; import { anvilWidgets } from "widgets/anvil/constants"; +import { severTiesFromParents, transformMovedWidgets } from "./moveUtils"; +import type { WidgetProps } from "widgets/BaseWidget"; export function* createZoneAndAddWidgets( allWidgets: CanvasWidgetsReduxState, @@ -27,7 +29,7 @@ export function* createZoneAndAddWidgets( * Create Zone widget. */ const widgetId: string = generateReactKey(); - let updatedWidgets: CanvasWidgetsReduxState = yield call( + const updatedWidgets: CanvasWidgetsReduxState = yield call( addNewWidgetToDsl, allWidgets, getCreateWidgetPayload(widgetId, anvilWidgets.ZONE_WIDGET, parentId), @@ -37,9 +39,33 @@ export function* createZoneAndAddWidgets( * Extract zone layout. */ const zoneProps: FlattenedWidgetProps = updatedWidgets[widgetId]; - const { widgetId: zoneWidgetId } = zoneProps; + + /** + * Add widgets to zone. and update relationships. + */ + const res: { canvasWidgets: CanvasWidgetsReduxState; zone: WidgetProps } = + yield call( + addWidgetsToZone, + updatedWidgets, + draggedWidgets, + highlight, + zoneProps, + ); + + return res; +} + +export function* addWidgetsToZone( + allWidgets: CanvasWidgetsReduxState, + draggedWidgets: WidgetLayoutProps[], + highlight: AnvilHighlightInfo, + zone: WidgetProps, +) { + let updatedWidgets: CanvasWidgetsReduxState = { ...allWidgets }; + const zoneProps = { ...zone }; const preset: LayoutProps[] = zoneProps.layout; let zoneLayout: LayoutProps = preset[0]; + const { widgetId: zoneWidgetId } = zoneProps; /** * If dragged widget is a new widget, @@ -67,6 +93,7 @@ export function* createZoneAndAddWidgets( zoneLayout.layoutType, ); + let rowsAdded = 0; if (smallWidgets.length) { zoneLayout = addWidgetsToChildTemplate( zoneLayout, @@ -74,34 +101,28 @@ export function* createZoneAndAddWidgets( smallWidgets, highlight, ); + rowsAdded += 1; } /** * Add large widgets to the zone layout. */ - largeWidgets.forEach((widget: WidgetLayoutProps) => { - zoneLayout = addWidgetsToChildTemplate( - zoneLayout, - zoneComp, - [widget], - highlight, - ); + largeWidgets.forEach((widget: WidgetLayoutProps, index: number) => { + zoneLayout = addWidgetsToChildTemplate(zoneLayout, zoneComp, [widget], { + ...highlight, + rowIndex: highlight.rowIndex + rowsAdded + index, + }); }); - /** - * Update zone preset with the updated zone layout. - */ - preset[0] = zoneLayout; - /** * Update zone widget with the updated preset. */ - zoneProps.layout = preset; + zoneProps.layout = [zoneLayout]; return { canvasWidgets: { ...updatedWidgets, - [zoneWidgetId]: zoneProps, + [zoneProps.widgetId]: zoneProps, }, zone: zoneProps, }; @@ -154,3 +175,36 @@ function* updateDraggedWidgets( } return updatedWidgets; } + +export function* moveWidgetsToZone( + allWidgets: CanvasWidgetsReduxState, + movedWidgets: string[], + highlight: AnvilHighlightInfo, +) { + let widgets: CanvasWidgetsReduxState = { ...allWidgets }; + + /** + * Remove moved widgets from previous parents. + */ + widgets = severTiesFromParents(widgets, movedWidgets); + + /** + * Get the new Zone parent and its Canvas. + */ + const { canvasId } = highlight; + + const zone: FlattenedWidgetProps = widgets[canvasId]; + + /** + * Add moved widgets to the section. + */ + const { canvasWidgets } = yield call( + addWidgetsToZone, + widgets, + transformMovedWidgets(widgets, movedWidgets, highlight), + highlight, + zone, + ); + + return canvasWidgets; +} diff --git a/app/client/src/layoutSystems/anvil/utils/paste/destinationUtils.ts b/app/client/src/layoutSystems/anvil/utils/paste/destinationUtils.ts index ce787a5d56..32b53136a1 100644 --- a/app/client/src/layoutSystems/anvil/utils/paste/destinationUtils.ts +++ b/app/client/src/layoutSystems/anvil/utils/paste/destinationUtils.ts @@ -70,6 +70,10 @@ function getPastingInfo( }; } const layout: LayoutProps = parent.layout[0]; + /** + * If parentOrder.length === 1 => add the copied widgets at the end of the layout. + * Else find index of the child (usually selected widget) in the layout, and add the copied widgets after it. + */ const info: Omit = parentOrder.length === 1 ? getLastIndexInLayout(parent) @@ -105,6 +109,10 @@ function getChildIndexInLayout( const Comp: typeof BaseLayoutComponent = LayoutFactory.get(layout.layoutType); if (Comp.rendersWidgets) { + /** + * if layout renders widgets, then find the index of the child in the layout. + * => If child is not found, then return -1. + */ const index = (layout.layout as WidgetLayoutProps[]).findIndex( (w: WidgetLayoutProps) => w.widgetId === childId, ); @@ -120,6 +128,9 @@ function getChildIndexInLayout( rowIndex: [...rowIndex, index + 1], }; } else { + /** + * If layout renders other layouts, then find the index of the child in the nested layouts. + */ let res: Omit = { alignment: FlexLayerAlignment.Start, layoutOrder, @@ -134,6 +145,9 @@ function getChildIndexInLayout( [...layoutOrder, each], [...rowIndex, index + 1], ); + /** + * Acknowledge the result only if the child is found in the layout. + */ if (temp.rowIndex[temp.rowIndex.length - 1] !== -1) res = temp; }, );