diff --git a/app/client/src/layoutSystems/anvil/canvas/AnvilCanvas.tsx b/app/client/src/layoutSystems/anvil/canvas/AnvilCanvas.tsx
index 7ececea6fb..2957b12a33 100644
--- a/app/client/src/layoutSystems/anvil/canvas/AnvilCanvas.tsx
+++ b/app/client/src/layoutSystems/anvil/canvas/AnvilCanvas.tsx
@@ -6,7 +6,6 @@ import type { WidgetProps } from "widgets/BaseWidget";
import { renderLayouts } from "../utils/layouts/renderUtils";
import { getAnvilCanvasId } from "./utils";
import { RenderModes } from "constants/WidgetConstants";
-import { getCanvasClassName } from "utils/generators";
export const AnvilCanvas = (props: BaseWidgetProps) => {
const map: LayoutComponentProps["childrenMap"] = {};
@@ -14,9 +13,7 @@ export const AnvilCanvas = (props: BaseWidgetProps) => {
map[child.widgetId] = child;
});
- const className: string = `anvil-canvas ${getCanvasClassName()} ${props.classList?.join(
- " ",
- )}`;
+ const className: string = `anvil-canvas ${props.classList?.join(" ")}`;
return (
diff --git a/app/client/src/layoutSystems/anvil/canvasArenas/hooks/useAnvilDnDStates.ts b/app/client/src/layoutSystems/anvil/canvasArenas/hooks/useAnvilDnDStates.ts
index d767701af5..8d4c551664 100644
--- a/app/client/src/layoutSystems/anvil/canvasArenas/hooks/useAnvilDnDStates.ts
+++ b/app/client/src/layoutSystems/anvil/canvasArenas/hooks/useAnvilDnDStates.ts
@@ -24,7 +24,7 @@ export interface AnvilDnDStates {
draggedBlocks: DraggedWidget[];
dragDetails: DragDetails;
selectedWidgets: string[];
- isChildOfCanvas: boolean;
+ isChildOfLayout: boolean;
isCurrentDraggedCanvas: boolean;
isDragging: boolean;
isNewWidget: boolean;
@@ -94,7 +94,6 @@ const checkIfWidgetTypeDraggedIsAllowedToDrop = (
export const useAnvilDnDStates = ({
allowedWidgetTypes,
- canvasId,
layoutId,
}: AnvilDnDStatesProps): AnvilDnDStates => {
const mainCanvasLayoutId: string = useSelector((state) =>
@@ -122,9 +121,9 @@ export const useAnvilDnDStates = ({
*/
const isNewWidget = !!newWidget && !dragParent;
/**
- * boolean to indicate if the widget being dragged is this particular canvas's child.
+ * boolean to indicate if the widget being dragged is this particular layout's child.
*/
- const isChildOfCanvas = dragParent === canvasId;
+ const isChildOfLayout = dragParent === layoutId;
/**
* boolean to indicate if the widget is being dragged on this particular canvas.
*/
@@ -172,7 +171,7 @@ export const useAnvilDnDStates = ({
draggedBlocks,
dragDetails,
selectedWidgets,
- isChildOfCanvas,
+ isChildOfLayout,
isCurrentDraggedCanvas,
isDragging,
isNewWidget,
diff --git a/app/client/src/layoutSystems/anvil/canvasArenas/hooks/useCanvasActivation.ts b/app/client/src/layoutSystems/anvil/canvasArenas/hooks/useCanvasActivation.ts
index f650b5b99f..f005b35f02 100644
--- a/app/client/src/layoutSystems/anvil/canvasArenas/hooks/useCanvasActivation.ts
+++ b/app/client/src/layoutSystems/anvil/canvasArenas/hooks/useCanvasActivation.ts
@@ -1,6 +1,7 @@
import { CANVAS_ART_BOARD } from "constants/componentClassNameConstants";
import { Indices } from "constants/Layers";
import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants";
+import type { LayoutElementPosition } from "layoutSystems/common/types";
import { positionObserver } from "layoutSystems/common/utils/LayoutElementPositionsObserver";
import { getAnvilLayoutDOMId } from "layoutSystems/common/utils/LayoutElementPositionsObserver/utils";
import { useEffect, useRef } from "react";
@@ -11,6 +12,22 @@ export const AnvilCanvasZIndex = {
activated: Indices.Layer10.toString(),
deactivated: "",
};
+
+const checkIfMousePositionIsInsideBlock = (
+ e: MouseEvent,
+ mainCanvasRect: DOMRect,
+ layoutElementPosition: LayoutElementPosition,
+) => {
+ return (
+ layoutElementPosition.left <= e.clientX - mainCanvasRect.left &&
+ e.clientX - mainCanvasRect.left <=
+ layoutElementPosition.left + layoutElementPosition.width &&
+ layoutElementPosition.top <= e.clientY - mainCanvasRect.top &&
+ e.clientY - mainCanvasRect.top <=
+ layoutElementPosition.top + layoutElementPosition.height
+ );
+};
+
export const useCanvasActivation = (
anvilDragStates: AnvilDnDStates,
layoutId: string,
@@ -26,6 +43,9 @@ export const useCanvasActivation = (
const mainContainerDOMNode = document.getElementById(CANVAS_ART_BOARD);
const { setDraggingCanvas, setDraggingNewWidget, setDraggingState } =
useWidgetDragResize();
+ const draggedWidgetPositions = anvilDragStates.selectedWidgets.map((each) => {
+ return layoutElementPositions[each];
+ });
/**
* boolean ref that indicates if the mouse position is outside of main canvas while dragging
* this is being tracked in order to activate/deactivate canvas.
@@ -72,6 +92,7 @@ export const useCanvasActivation = (
return currentPositions && !!layoutInfo.isDropTarget;
})
.map((each) => allLayouts[each].layoutId);
+
/**
* layoutIds sorted by area of each layout in ascending order.
* This is done because a point can be inside multiple canvas areas, but only the smallest of them is the immediate parent.
@@ -101,21 +122,23 @@ export const useCanvasActivation = (
smallToLargeSortedDroppableLayoutIds.length > 0
) {
const mainCanvasRect = mainContainerDOMNode.getBoundingClientRect();
- const hoveredCanvas = smallToLargeSortedDroppableLayoutIds.find(
- (each) => {
- const currentCanvasPositions = layoutElementPositions[each];
- if (currentCanvasPositions) {
- return (
- currentCanvasPositions.left <= e.clientX - mainCanvasRect.left &&
- e.clientX - mainCanvasRect.left <=
- currentCanvasPositions.left + currentCanvasPositions.width &&
- currentCanvasPositions.top <= e.clientY - mainCanvasRect.top &&
- e.clientY - mainCanvasRect.top <=
- currentCanvasPositions.top + currentCanvasPositions.height
- );
- }
- },
- );
+ const isMousePositionOutsideOfDraggingWidgets =
+ !isNewWidget &&
+ draggedWidgetPositions.find((each) => {
+ return checkIfMousePositionIsInsideBlock(e, mainCanvasRect, each);
+ });
+ const hoveredCanvas = isMousePositionOutsideOfDraggingWidgets
+ ? dragDetails.dragGroupActualParent
+ : smallToLargeSortedDroppableLayoutIds.find((each) => {
+ const currentCanvasPositions = layoutElementPositions[each];
+ if (currentCanvasPositions) {
+ return checkIfMousePositionIsInsideBlock(
+ e,
+ mainCanvasRect,
+ currentCanvasPositions,
+ );
+ }
+ });
if (dragDetails.draggedOn !== hoveredCanvas) {
if (hoveredCanvas) {
isMouseOutOfMainCanvas.current = false;
diff --git a/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx b/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx
index bff06ccbd1..c93d042206 100644
--- a/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx
+++ b/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx
@@ -26,15 +26,14 @@ import { getWidgetSizeConfiguration } from "../utils/widgetUtils";
* @returns Enhanced Widget
*/
export const AnvilEditorWidgetOnion = (props: BaseWidgetProps) => {
- const { layoutId, parentId } = props;
+ const { layoutId } = props;
// if layoutId is not present on widget props then we need a selector to fetch layout id of a widget.
// const layoutId = useSelector(getLayoutIdByWidgetId(props.widgetId));
const generateDragState = useCallback(() => {
return generateDragStateForAnvilLayout({
- canvasId: parentId || "",
- layoutId: layoutId,
+ layoutId,
});
- }, [layoutId, parentId]);
+ }, [layoutId]);
const widgetSize: SizeConfig = useMemo(
() => getWidgetSizeConfiguration(props.type, props),
[props.type],
diff --git a/app/client/src/layoutSystems/anvil/integrations/sagas/draggingSagas.ts b/app/client/src/layoutSystems/anvil/integrations/sagas/draggingSagas.ts
index 1e3e504670..fd62abae66 100644
--- a/app/client/src/layoutSystems/anvil/integrations/sagas/draggingSagas.ts
+++ b/app/client/src/layoutSystems/anvil/integrations/sagas/draggingSagas.ts
@@ -15,6 +15,8 @@ import { addWidgetsToPreset } from "../../utils/layouts/update/additionUtils";
import { moveWidgets } from "../../utils/layouts/update/moveUtils";
import { AnvilReduxActionTypes } from "../actions/actionTypes";
import { generateDefaultLayoutPreset } from "layoutSystems/anvil/layoutComponents/presets/DefaultLayoutPreset";
+import { selectWidgetInitAction } from "actions/widgetSelectionActions";
+import { SelectionRequestType } from "sagas/WidgetSelectUtils";
function* addWidgetsSaga(
actionPayload: ReduxAction<{
@@ -82,6 +84,9 @@ function* addWidgetsSaga(
},
};
yield put(updateAndSaveLayout(updatedWidgets));
+ yield put(
+ selectWidgetInitAction(SelectionRequestType.One, [newWidget.newWidgetId]),
+ );
log.debug("Anvil : add new widget took", performance.now() - start, "ms");
} catch (error) {
yield put({
diff --git a/app/client/src/layoutSystems/anvil/integrations/utils.test.ts b/app/client/src/layoutSystems/anvil/integrations/utils.test.ts
deleted file mode 100644
index dbdb1d030b..0000000000
--- a/app/client/src/layoutSystems/anvil/integrations/utils.test.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
-import type { WidgetProps } from "widgets/BaseWidget";
-import { getAffectedWidgetsFromLayers, getAllChildWidgets } from "./utils";
-
-const widgets = {
- "0": {
- children: ["1", "3", "4"],
- detachFromLayout: true,
- flexLayers: [
- { children: [{ id: "1" }, { id: "3" }] },
- { children: [{ id: "4" }] },
- ],
- },
- "1": {
- children: ["2"],
- },
- "2": {
- children: ["5", "6", "7", "8"],
- detachFromLayout: true,
- flexLayers: [
- { children: [{ id: "5" }] },
- { children: [{ id: "6" }, { id: "7" }] },
- { children: [{ id: "8" }] },
- ],
- },
- "3": { children: [] },
- "4": { children: [] },
- "5": { children: [] },
- "6": { children: [] },
- "7": { children: [] },
- "8": { children: [] },
-} as unknown as CanvasWidgetsReduxState;
-
-describe("should test getAffectedWidgetsFromLayers", () => {
- const layerQueue1 = {
- "0": 0,
- };
-
- const layerQueue2 = {
- "0": 1,
- "2": 1,
- };
-
- const layerQueue3 = {
- "2": 0,
- };
-
- const layerQueue4 = {
- "0": 1,
- "2": 2,
- };
-
- const affectedWidgets1 = {
- "1": true,
- "3": true,
- "4": true,
- "5": true,
- "6": true,
- "7": true,
- "8": true,
- };
-
- const affectedWidgets2 = {
- "4": true,
- "6": true,
- "7": true,
- "8": true,
- };
-
- const affectedWidgets3 = {
- "5": true,
- "6": true,
- "7": true,
- "8": true,
- };
-
- const affectedWidgets4 = {
- "4": true,
- "8": true,
- };
-
- it("should return all the affected widgets derived from layer queue", () => {
- expect(getAffectedWidgetsFromLayers(layerQueue1, widgets)).toEqual(
- affectedWidgets1,
- );
- expect(getAffectedWidgetsFromLayers(layerQueue2, widgets)).toEqual(
- affectedWidgets2,
- );
- expect(getAffectedWidgetsFromLayers(layerQueue3, widgets)).toEqual(
- affectedWidgets3,
- );
- expect(getAffectedWidgetsFromLayers(layerQueue4, widgets)).toEqual(
- affectedWidgets4,
- );
- });
-});
-
-describe("should test getAllChildWidgets", () => {
- const widget1 = {
- widgetId: "0",
- children: ["1", "3", "4"],
- } as unknown as WidgetProps;
-
- const widget2 = {
- widgetId: "1",
- children: ["2"],
- } as unknown as WidgetProps;
-
- const widget3 = {
- widgetId: "2",
- children: ["5", "6", "7", "8"],
- } as unknown as WidgetProps;
-
- const widget4 = {
- widgetId: "3",
- children: [],
- } as unknown as WidgetProps;
-
- const childWidgets1 = {
- "1": true,
- "3": true,
- "4": true,
- "5": true,
- "6": true,
- "7": true,
- "8": true,
- };
-
- const childWidgets2 = {
- "5": true,
- "6": true,
- "7": true,
- "8": true,
- };
-
- const childWidgets3 = {
- "5": true,
- "6": true,
- "7": true,
- "8": true,
- };
-
- const childWidgets4 = {};
-
- it("should return all the child widgets except canvas widgets", () => {
- expect(getAllChildWidgets(widget1, widgets)).toEqual(childWidgets1);
- expect(getAllChildWidgets(widget2, widgets)).toEqual(childWidgets2);
- expect(getAllChildWidgets(widget3, widgets)).toEqual(childWidgets3);
- expect(getAllChildWidgets(widget4, widgets)).toEqual(childWidgets4);
- });
-});
diff --git a/app/client/src/layoutSystems/anvil/integrations/utils.ts b/app/client/src/layoutSystems/anvil/integrations/utils.ts
deleted file mode 100644
index e7c71f1572..0000000000
--- a/app/client/src/layoutSystems/anvil/integrations/utils.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
-import type { WidgetProps } from "widgets/BaseWidget";
-
-/**
- * This method is used to determine all the affected widgets from all the layers that have changed
- * @param layersProcessQueue Changed layer Ids, will have one layer id per canvas
- * @param widgets all widget dsl Properties
- * @returns list of all affected widgets
- */
-export function getAffectedWidgetsFromLayers(
- layersProcessQueue: {
- [canvasId: string]: number;
- },
- widgets: CanvasWidgetsReduxState,
-) {
- let affectedWidgets: { [widgetDOMId: string]: boolean } = {};
-
- //Even though it has many nested iterations it will go through all teh affected widgets only once
- //Iterate through all the canvases and it's first layer that got affected
- for (const [canvasId, layerIndex] of Object.entries(layersProcessQueue)) {
- const flexLayers = widgets[canvasId]?.flexLayers || [];
-
- //iterate through all the layers below the changed layer id inculuding the layer
- for (let i = layerIndex; i < flexLayers.length; i++) {
- const children = flexLayers[i]?.children || [];
- //iterate through all the child widgets inside the layer
- for (const child of children) {
- const childWidget = widgets[child.id];
-
- if (!childWidget) continue;
-
- affectedWidgets[child.id] = true;
-
- //if the widget has children get all the nested children
- if (childWidget.children && childWidget.children.length > 0) {
- affectedWidgets = {
- ...affectedWidgets,
- ...getAllChildWidgets(childWidget, widgets, layersProcessQueue),
- };
- }
- }
- }
- }
-
- return affectedWidgets;
-}
-
-/**
- * This Method gets all the nested child widgets,
- * within the given widgets ignoring the canvas type widgets
- * @param widget Widget whose nested children have to be found
- * @param widgets all widget dsl Properties
- * @returns list of all the nested child widgets of widget
- */
-export function getAllChildWidgets(
- widget: WidgetProps,
- widgets: CanvasWidgetsReduxState,
- layersProcessQueue?: {
- [canvasId: string]: number;
- },
-) {
- let childWidgets: { [widgetDOMId: string]: boolean } = {};
-
- const children = widget.children;
-
- //iterate through children if widget
- for (const childId of children) {
- const childWidget = widgets[childId];
-
- if (!childWidget) continue;
-
- //if the child widget is not a canvas add it to the list
- if (!childWidget.detachFromLayout) {
- childWidgets[childId] = true;
- } else if (layersProcessQueue) {
- //If it is a canvas widget remove the widget from the layer queue to avoid processing it again
- delete layersProcessQueue[childId];
- }
-
- //if the widget further has nested children call the getAllChildWidgets recursively.
- if (childWidget.children && childWidget.children.length > 0) {
- childWidgets = {
- ...childWidgets,
- ...getAllChildWidgets(childWidget, widgets, layersProcessQueue),
- };
- }
- }
-
- return childWidgets;
-}
diff --git a/app/client/src/layoutSystems/anvil/utils/widgetUtils.ts b/app/client/src/layoutSystems/anvil/utils/widgetUtils.ts
index ae9c496d24..d3f3b1957e 100644
--- a/app/client/src/layoutSystems/anvil/utils/widgetUtils.ts
+++ b/app/client/src/layoutSystems/anvil/utils/widgetUtils.ts
@@ -36,15 +36,13 @@ export const validateResponsiveProp = (
) => data && Object.keys(data)?.length;
export const generateDragStateForAnvilLayout = ({
- canvasId,
layoutId,
}: {
- canvasId: string;
layoutId: string;
}): SetDraggingStateActionPayload => {
return {
isDragging: true,
- dragGroupActualParent: canvasId || "",
+ dragGroupActualParent: layoutId || "",
draggedOn: layoutId,
};
};
diff --git a/app/client/src/sagas/WidgetAdditionSagas.ts b/app/client/src/sagas/WidgetAdditionSagas.ts
index 093127e9b7..187e0af60e 100644
--- a/app/client/src/sagas/WidgetAdditionSagas.ts
+++ b/app/client/src/sagas/WidgetAdditionSagas.ts
@@ -49,6 +49,9 @@ import {
} from "selectors/editorSelectors";
import { getWidgetMinMaxDimensionsInPixel } from "layoutSystems/autolayout/utils/flexWidgetUtils";
import { isFunction } from "lodash";
+import type { LayoutComponentProps } from "layoutSystems/anvil/utils/anvilTypes";
+import { getLayoutSystemType } from "selectors/layoutSystemSelectors";
+import { LayoutSystemTypes } from "layoutSystems/types";
const WidgetTypes = WidgetFactory.widgetTypes;
@@ -73,6 +76,7 @@ function* getChildWidgetProps(
widgets: { [widgetId: string]: FlattenedWidgetProps },
) {
const { leftColumn, newWidgetId, topRow, type } = params;
+ const layoutSystemType: LayoutSystemTypes = yield select(getLayoutSystemType);
let { columns, parentColumnSpace, parentRowSpace, props, rows, widgetName } =
params;
let minHeight = undefined;
@@ -108,6 +112,21 @@ function* getChildWidgetProps(
draft.children = [];
}
});
+ if (
+ layoutSystemType === LayoutSystemTypes.ANVIL &&
+ props.layout &&
+ props.layout.length
+ ) {
+ props = {
+ ...props,
+ layout: props.layout.map((each: LayoutComponentProps) => {
+ return {
+ ...each,
+ layoutId: generateReactKey(),
+ };
+ }),
+ };
+ }
}
}