diff --git a/app/client/cypress/fixtures/CanvasResizeDsl.json b/app/client/cypress/fixtures/CanvasResizeDsl.json new file mode 100644 index 0000000000..0ade4a1ac2 --- /dev/null +++ b/app/client/cypress/fixtures/CanvasResizeDsl.json @@ -0,0 +1,57 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1224, + "snapColumns": 16, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 2960, + "containerStyle": "none", + "snapRows": 33, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 7, + "minHeight": 1292, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "widgetName": "Text2", + "rightColumn": 8, + "textAlign": "LEFT", + "widgetId": "i4eeob8e7t", + "topRow": 71, + "bottomRow": 72, + "parentRowSpace": 40, + "isVisible": true, + "type": "TEXT_WIDGET", + "parentId": "0", + "isLoading": false, + "parentColumnSpace": 74, + "leftColumn": 4, + "text": "Label", + "textStyle": "LABEL" + }, + { + "widgetName": "Checkbox1", + "rightColumn": 4, + "widgetId": "vyl7d3u54d", + "topRow": 5, + "bottomRow": 6, + "parentRowSpace": 40, + "isVisible": true, + "label": "Label", + "type": "CHECKBOX_WIDGET", + "parentId": "0", + "isLoading": false, + "parentColumnSpace": 74, + "leftColumn": 1, + "defaultCheckedState": true + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/integration/Smoke_TestSuite/Canvas/Resize_spec.js b/app/client/cypress/integration/Smoke_TestSuite/Canvas/Resize_spec.js new file mode 100644 index 0000000000..d31feed86d --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/Canvas/Resize_spec.js @@ -0,0 +1,16 @@ +const commonlocators = require("../../../locators/commonlocators.json"); +const dsl = require("../../../fixtures/CanvasResizeDsl.json"); + +describe("Canvas Resize", function() { + before(() => { + cy.addDsl(dsl); + }); + it("Deleting bottom widget should resize canvas", function() { + const InitHeight = "2960px"; + const FinalHeight = "1292px"; + cy.get(commonlocators.dropTarget).should("have.css", "height", InitHeight); + cy.openPropertyPane("textwidget"); + cy.get(commonlocators.deleteWidget).click(); + cy.get(commonlocators.dropTarget).should("have.css", "height", FinalHeight); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_DragAndDropWidget_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_DragAndDropWidget_spec.js index b9fc71360c..8af5138486 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_DragAndDropWidget_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ExplorerTests/Entity_Explorer_DragAndDropWidget_spec.js @@ -15,7 +15,7 @@ describe("Entity explorer Drag and Drop widgets testcases", function() { cy.get(commonlocators.entityExplorersearch) .clear() .type("form"); - cy.dragAndDropToCanvas("formwidget"); + cy.dragAndDropToCanvas("formwidget", { x: 300, y: -300 }); /** * @param{Text} Random Text * @param{FormWidget}Mouseover diff --git a/app/client/cypress/integration/Smoke_TestSuite/LayoutWidgets/Tab_spec.js b/app/client/cypress/integration/Smoke_TestSuite/LayoutWidgets/Tab_spec.js index 38e9147674..e358cada5e 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/LayoutWidgets/Tab_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/LayoutWidgets/Tab_spec.js @@ -32,6 +32,7 @@ describe("Tab widget test", function() { .click({ force: true }) .should("be.visible"); cy.get(Layoutpage.tabButton).click({ force: true }); + cy.wait(200); cy.tabVerify(2, "Day"); cy.get(Layoutpage.tabDelete) .eq(2) diff --git a/app/client/cypress/locators/commonlocators.json b/app/client/cypress/locators/commonlocators.json index b6e49bef45..e8fdd2183a 100644 --- a/app/client/cypress/locators/commonlocators.json +++ b/app/client/cypress/locators/commonlocators.json @@ -70,6 +70,7 @@ "toastmsg": ".Toastify__toast-body span", "copyWidget": ".t--copy-widget", "deleteWidget": ".t--delete-widget", + "dropTarget":".t--drop-target", "toastAction": ".t--toast-action", "toastBody": ".Toastify__toast-body", "videoInner": ".t--draggable-videowidget span.t--widget-name", diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 93823443c7..d5e3516184 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -1526,11 +1526,11 @@ Cypress.Commands.add("runAndDeleteQuery", () => { ); }); -Cypress.Commands.add("dragAndDropToCanvas", widgetType => { +Cypress.Commands.add("dragAndDropToCanvas", (widgetType, { x, y }) => { const selector = `.t--widget-card-draggable-${widgetType}`; cy.get(selector) .trigger("mousedown", { button: 0 }, { force: true }) - .trigger("mousemove", 300, -300, { force: true }); + .trigger("mousemove", x, y, { force: true }); cy.get(explorer.dropHere) .click() .trigger("mouseup", { force: true }); diff --git a/app/client/src/components/editorComponents/DropTargetComponent.tsx b/app/client/src/components/editorComponents/DropTargetComponent.tsx index 1042715989..8fb3d91473 100644 --- a/app/client/src/components/editorComponents/DropTargetComponent.tsx +++ b/app/client/src/components/editorComponents/DropTargetComponent.tsx @@ -276,6 +276,7 @@ export const DropTargetComponent = memo((props: DropTargetComponentProps) => { height, border, }} + className={"t--drop-target"} > {props.children} {!(childWidgets && childWidgets.length) && diff --git a/app/client/src/sagas/WidgetOperationSagas.tsx b/app/client/src/sagas/WidgetOperationSagas.tsx index 31a8614b3f..c8f42b751c 100644 --- a/app/client/src/sagas/WidgetOperationSagas.tsx +++ b/app/client/src/sagas/WidgetOperationSagas.tsx @@ -329,6 +329,36 @@ const getAllWidgetsInTree = ( return widgetList; }; +/** + * Note: Mutates finalWidgets[parentId].bottomRow for CANVAS_WIDGET + * @param finalWidgets + * @param parentId + */ +const resizeCanvasToLowestWidget = ( + finalWidgets: CanvasWidgetsReduxState, + parentId: string, +) => { + if ( + !finalWidgets[parentId] || + finalWidgets[parentId].type !== WidgetTypes.CANVAS_WIDGET + ) { + return; + } + + let lowestBottomRow = 0; + const childIds = finalWidgets[parentId].children || []; + // find lowest row + childIds.forEach(cId => { + const child = finalWidgets[cId]; + if (child.bottomRow > lowestBottomRow) { + lowestBottomRow = child.bottomRow; + } + }); + finalWidgets[parentId].bottomRow = + (lowestBottomRow + GridDefaults.CANVAS_EXTENSION_OFFSET) * + GridDefaults.DEFAULT_GRID_ROW_HEIGHT; +}; + export function* deleteSaga(deleteAction: ReduxAction) { try { let { widgetId, parentId } = deleteAction.payload; @@ -402,11 +432,14 @@ export function* deleteSaga(deleteAction: ReduxAction) { yield call(clearEvalPropertyCacheOfWidget, widgetName); - const finalWidgets = _.omit( + const finalWidgets: CanvasWidgetsReduxState = _.omit( widgets, otherWidgetsToDelete.map(widgets => widgets.widgetId), ); + // Note: mutates finalWidgets + resizeCanvasToLowestWidget(finalWidgets, parentId); + yield put(updateAndSaveLayout(finalWidgets)); } } catch (error) {