From fadf9112956d68b64e74244bb9e5a926b37cb513 Mon Sep 17 00:00:00 2001 From: Manish Kumar <107841575+sondermanish@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:10:23 +0530 Subject: [PATCH 1/4] chore: removed git annotation from dependency map variable (#34406) --- .../src/main/java/com/appsmith/server/dtos/PageDTO.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageDTO.java index fccb245d80ea..3b61de875c91 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/PageDTO.java @@ -78,8 +78,7 @@ public class PageDTO { @JsonView(Views.Public.class) DefaultResources defaultResources; - // TODO: get this clarified for GIT annotation - @JsonView({Views.Public.class, Git.class}) + @JsonView(Views.Public.class) Map> dependencyMap; public void sanitiseToExportDBObject() { From 0a2ca2c38cc96bce6daf4ef9310a84fec214895d Mon Sep 17 00:00:00 2001 From: Ashok Kumar M <35134347+marks0351@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:47:26 +0530 Subject: [PATCH 2/4] feat: Anvil dnd sagas unit tests (#34407) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![workerB](https://img.shields.io/endpoint?url=https%3A%2F%2Fworkerb.linearb.io%2Fv2%2Fbadge%2Fprivate%2FU2FsdGVkX1IH0H4UjkYrlztX0lkyWZ1n2uZYh8Epg%2Fcollaboration.svg%3FcacheSeconds%3D60)](https://workerb.linearb.io/v2/badge/collaboration-page?magicLinkId=Pmk6xa9) ## Description > [!TIP] > _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team)._ > > _Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR._ Fixes #33981 _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.Anvil" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 311f59c5d6cff265ea985c13f9891193866304d6 > Cypress dashboard. > Tags: `@tag.Anvil` ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **Tests** - Introduced test cases for adding and moving widgets within a canvas layout. - **New Features** - Added functionality to generate mock data for a layout with two sections, each containing a zone widget. --- .../anvilDraggingSagas.test.ts | 232 ++++++++++++++++++ .../index.ts} | 16 +- .../anvilDraggingSagas/mockData.helper.ts | 113 +++++++++ 3 files changed, 355 insertions(+), 6 deletions(-) create mode 100644 app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/anvilDraggingSagas.test.ts rename app/client/src/layoutSystems/anvil/integrations/sagas/{anvilDraggingSagas.ts => anvilDraggingSagas/index.ts} (96%) create mode 100644 app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/mockData.helper.ts diff --git a/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/anvilDraggingSagas.test.ts b/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/anvilDraggingSagas.test.ts new file mode 100644 index 000000000000..fb1ffd3ab6b4 --- /dev/null +++ b/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/anvilDraggingSagas.test.ts @@ -0,0 +1,232 @@ +import { select } from "redux-saga/effects"; +import { addWidgetsSaga, moveWidgetsSaga } from "."; +import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; +import { generateReactKey } from "@shared/dsl/src/migrate/utils"; +import { LayoutComponentTypes } from "layoutSystems/anvil/utils/anvilTypes"; +import { expectSaga } from "redux-saga-test-plan"; +import { getWidgets } from "sagas/selectors"; +import { registerWidgets } from "WidgetProvider/factory/registrationHelper"; +import { SectionWidget } from "widgets/anvil/SectionWidget"; +import { ZoneWidget } from "widgets/anvil/ZoneWidget"; +import { WDSButtonWidget } from "widgets/wds/WDSButtonWidget"; +import { + getCanvasWidth, + getIsAutoLayoutMobileBreakPoint, +} from "selectors/editorSelectors"; +import { getCurrentlyOpenAnvilDetachedWidgets } from "../../modalSelectors"; +import { getDataTree } from "selectors/dataTreeSelectors"; +import { getLayoutSystemType } from "selectors/layoutSystemSelectors"; +import { registerLayoutComponents } from "layoutSystems/anvil/utils/layouts/layoutUtils"; +import { getIsAnvilLayout } from "../../selectors"; +import { selectWidgetInitAction } from "actions/widgetSelectionActions"; +import { SelectionRequestType } from "sagas/WidgetSelectUtils"; +import { WDSModalWidget } from "widgets/wds/WDSModalWidget"; +import { generateMockDataWithTwoSections } from "./mockData.helper"; +import type { AnvilMoveWidgetsPayload } from "../../actions/actionTypes"; +import { + AnvilReduxActionTypes, + type AnvilNewWidgetsPayload, +} from "../../actions/actionTypes"; +import { AnvilDraggedWidgetTypesEnum } from "layoutSystems/anvil/editor/canvasArenas/types"; +import { + FlexLayerAlignment, + ResponsiveBehavior, +} from "layoutSystems/common/utils/constants"; +import { mockAnvilHighlightInfo } from "mocks/mockHighlightInfo"; + +describe("", () => { + beforeAll(() => { + registerLayoutComponents(); + registerWidgets([ + SectionWidget, + ZoneWidget, + WDSButtonWidget, + WDSModalWidget, + ]); + }); + // Successfully adds a new widget to the main canvas + it("should successfully add a new widget to the main canvas", async () => { + const mainCanvasLayoutId = generateReactKey(); + const newWidgetId = generateReactKey(); + const allWidgets: any = { + [MAIN_CONTAINER_WIDGET_ID]: { + widgetName: "Main Container", + widgetId: MAIN_CONTAINER_WIDGET_ID, + children: [], + layout: [ + { + layoutId: mainCanvasLayoutId, + layoutType: LayoutComponentTypes.ALIGNED_LAYOUT_COLUMN, + layout: [], + }, + ], + }, + }; + const payload: AnvilNewWidgetsPayload = { + dragMeta: { + draggedOn: "MAIN_CANVAS", + draggedWidgetTypes: AnvilDraggedWidgetTypesEnum.WIDGETS, + }, + highlight: mockAnvilHighlightInfo({ + alignment: FlexLayerAlignment.Start, + canvasId: MAIN_CONTAINER_WIDGET_ID, + layoutId: mainCanvasLayoutId, + layoutOrder: [mainCanvasLayoutId], + }), + newWidget: { + width: 100, + height: 50, + newWidgetId, + type: "WDS_BUTTON_WIDGET", + detachFromLayout: false, + }, + }; + const actionPayload = { + type: AnvilReduxActionTypes.ANVIL_ADD_NEW_WIDGET, + payload, + }; + const { effects } = await expectSaga(addWidgetsSaga, actionPayload) + .provide([ + [select(getWidgets), allWidgets], + [select(getCanvasWidth), 100], + [select(getIsAutoLayoutMobileBreakPoint), false], + [select(getCurrentlyOpenAnvilDetachedWidgets), []], + [select(getDataTree), {}], + [select(getLayoutSystemType), "ANVIL"], + [select(getIsAnvilLayout), true], + ]) + .run(); + const widgetSelectPutEffect = effects.put[effects.put.length - 1]; + expect(widgetSelectPutEffect.payload.action).toEqual( + selectWidgetInitAction(SelectionRequestType.Create, [newWidgetId]), + ); + const updateWidgetsPutEffect = effects.put[effects.put.length - 2]; + expect(updateWidgetsPutEffect.payload.action.type).toBe("UPDATE_LAYOUT"); + // check if new widget was added to main canvas by wrapping it in a section and zone + const updatedWidgets = + updateWidgetsPutEffect.payload.action.payload.widgets; + const mainCanvasWidget = updatedWidgets[MAIN_CONTAINER_WIDGET_ID]; + const sectionWidgetId = mainCanvasWidget.children[0]; + const sectionWidget = updatedWidgets[sectionWidgetId]; + const zoneWidgetId = sectionWidget.children[0]; + const zoneWidget = updatedWidgets[zoneWidgetId]; + expect(zoneWidget.children).toContain(newWidgetId); + }); + it("should successfully add a new modal widget to the main canvas", async () => { + const mainCanvasLayoutId = generateReactKey(); + const newModalId = generateReactKey(); + const allWidgets: any = { + [MAIN_CONTAINER_WIDGET_ID]: { + widgetName: "Main Container", + widgetId: MAIN_CONTAINER_WIDGET_ID, + children: [], + layout: [ + { + layoutId: mainCanvasLayoutId, + layoutType: LayoutComponentTypes.ALIGNED_LAYOUT_COLUMN, + layout: [], + }, + ], + }, + }; + const payload: AnvilNewWidgetsPayload = { + dragMeta: { + draggedOn: "MAIN_CANVAS", + draggedWidgetTypes: AnvilDraggedWidgetTypesEnum.WIDGETS, + }, + highlight: mockAnvilHighlightInfo({ + alignment: FlexLayerAlignment.Start, + canvasId: MAIN_CONTAINER_WIDGET_ID, + layoutId: mainCanvasLayoutId, + layoutOrder: [mainCanvasLayoutId], + }), + newWidget: { + width: 100, + height: 50, + newWidgetId: newModalId, + type: "WDS_MODAL_WIDGET", + detachFromLayout: true, + }, + }; + const actionPayload = { + type: AnvilReduxActionTypes.ANVIL_ADD_NEW_WIDGET, + payload, + }; + + const { effects } = await expectSaga(addWidgetsSaga, actionPayload) + .provide([ + [select(getWidgets), allWidgets], + [select(getCanvasWidth), 100], + [select(getIsAutoLayoutMobileBreakPoint), false], + [select(getCurrentlyOpenAnvilDetachedWidgets), []], + [select(getDataTree), {}], + [select(getLayoutSystemType), "ANVIL"], + [select(getIsAnvilLayout), true], + ]) + .run(); + const widgetSelectPutEffect = effects.put[effects.put.length - 1]; + expect(widgetSelectPutEffect.payload.action).toEqual( + selectWidgetInitAction(SelectionRequestType.Create, [newModalId]), + ); + const updateWidgetsPutEffect = effects.put[effects.put.length - 2]; + expect(updateWidgetsPutEffect.payload.action.type).toBe("UPDATE_LAYOUT"); + // check if new widget was added to main canvas by wrapping it in a section and zone + const updatedWidgets = + updateWidgetsPutEffect.payload.action.payload.widgets; + const mainCanvasWidget = updatedWidgets[MAIN_CONTAINER_WIDGET_ID]; + const modalWidgetId = mainCanvasWidget.children[0]; + expect(modalWidgetId).toContain(newModalId); + }); + + it("should successfully move widget to the main canvas", async () => { + const { allWidgets, mainCanvasLayoutId, section1Id, section2Id } = + generateMockDataWithTwoSections(); + const payload: AnvilMoveWidgetsPayload = { + dragMeta: { + draggedOn: "MAIN_CANVAS", + draggedWidgetTypes: AnvilDraggedWidgetTypesEnum.SECTION, + }, + movedWidgets: [ + { + widgetId: section2Id, + type: "SECTION_WIDGET", + parentId: MAIN_CONTAINER_WIDGET_ID, + responsiveBehavior: ResponsiveBehavior.Fill, + }, + ], + highlight: mockAnvilHighlightInfo({ + alignment: FlexLayerAlignment.Start, + rowIndex: 0, + canvasId: MAIN_CONTAINER_WIDGET_ID, + layoutId: mainCanvasLayoutId, + layoutOrder: [mainCanvasLayoutId], + }), + }; + const actionPayload = { + type: AnvilReduxActionTypes.ANVIL_MOVE_WIDGET, + payload, + }; + const { effects } = await expectSaga(moveWidgetsSaga, actionPayload) + .provide([ + [select(getWidgets), allWidgets], + [select(getCanvasWidth), 100], + [select(getIsAutoLayoutMobileBreakPoint), false], + [select(getCurrentlyOpenAnvilDetachedWidgets), []], + [select(getDataTree), {}], + [select(getLayoutSystemType), "ANVIL"], + [select(getIsAnvilLayout), true], + ]) + .run(); + const updateWidgetsPutEffect = effects.put[effects.put.length - 1]; + expect(updateWidgetsPutEffect.payload.action.type).toBe("UPDATE_LAYOUT"); + // expect section2 to be moved to the first position in layout + const updatedWidgets = + updateWidgetsPutEffect.payload.action.payload.widgets; + const mainCanvasWidget = updatedWidgets[MAIN_CONTAINER_WIDGET_ID]; + const mainCanvasLayout = mainCanvasWidget.layout[0]; + const firstWidgetRow = mainCanvasLayout.layout[0]; + const secondWidgetRow = mainCanvasLayout.layout[1]; + expect(firstWidgetRow.layout[0].widgetId).toBe(section2Id); + expect(secondWidgetRow.layout[0].widgetId).toBe(section1Id); + }); +}); diff --git a/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas.ts b/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/index.ts similarity index 96% rename from app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas.ts rename to app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/index.ts index fbaea2af140b..b8a8581ca605 100644 --- a/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas.ts +++ b/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/index.ts @@ -10,12 +10,12 @@ import type { WidgetLayoutProps, } from "layoutSystems/anvil/utils/anvilTypes"; import { getWidget, getWidgets } from "sagas/selectors"; -import { addWidgetsToPreset } from "../../utils/layouts/update/additionUtils"; +import { addWidgetsToPreset } from "../../../utils/layouts/update/additionUtils"; import type { AnvilMoveWidgetsPayload, AnvilNewWidgetsPayload, -} from "../actions/actionTypes"; -import { AnvilReduxActionTypes } from "../actions/actionTypes"; +} from "../../actions/actionTypes"; +import { AnvilReduxActionTypes } from "../../actions/actionTypes"; import { generateDefaultLayoutPreset } from "layoutSystems/anvil/layoutComponents/presets/DefaultLayoutPreset"; import { selectWidgetInitAction } from "actions/widgetSelectionActions"; import { SelectionRequestType } from "sagas/WidgetSelectUtils"; @@ -39,7 +39,7 @@ import { addNewWidgetToDsl, getCreateWidgetPayload, } from "layoutSystems/anvil/utils/widgetAdditionUtils"; -import { updateAndSaveAnvilLayout } from "../../utils/anvilChecksUtils"; +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 @@ -201,7 +201,9 @@ export function* addNewChildToDSL( } // function to handle the addition of new widgets to the Anvil layout -function* addWidgetsSaga(actionPayload: ReduxAction) { +export function* addWidgetsSaga( + actionPayload: ReduxAction, +) { try { const start = performance.now(); @@ -297,7 +299,9 @@ function* addWidgetToGenericLayout( * Remove widgets from current parents and layouts. * Add to new parent and layout. */ -function* moveWidgetsSaga(actionPayload: ReduxAction) { +export function* moveWidgetsSaga( + actionPayload: ReduxAction, +) { try { const start = performance.now(); const { diff --git a/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/mockData.helper.ts b/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/mockData.helper.ts new file mode 100644 index 000000000000..559884b8a082 --- /dev/null +++ b/app/client/src/layoutSystems/anvil/integrations/sagas/anvilDraggingSagas/mockData.helper.ts @@ -0,0 +1,113 @@ +import { generateReactKey } from "@shared/dsl/src/migrate/utils"; +import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; +import { LayoutComponentTypes } from "layoutSystems/anvil/utils/anvilTypes"; +import { FlexLayerAlignment } from "layoutSystems/common/utils/constants"; + +export const generateMockDataWithTwoSections = () => { + const mainCanvasLayoutId = generateReactKey(); + const section1Id = generateReactKey(); + const section2Id = generateReactKey(); + const zone1Id = generateReactKey(); + const zone2Id = generateReactKey(); + const section1Layout = { + layoutType: LayoutComponentTypes.SECTION, + layout: [ + { + widgetId: zone1Id, + alignment: FlexLayerAlignment.Start, + widgetType: "ZONE_WIDGET", + }, + ], + }; + const section2Layout = { + layoutType: LayoutComponentTypes.SECTION, + layout: [ + { + widgetId: zone2Id, + alignment: FlexLayerAlignment.Start, + widgetType: "ZONE_WIDGET", + }, + ], + }; + const allWidgets: any = { + [MAIN_CONTAINER_WIDGET_ID]: { + widgetName: "Main Container", + widgetId: MAIN_CONTAINER_WIDGET_ID, + children: [section1Id, section2Id], + layout: [ + { + layoutId: mainCanvasLayoutId, + layoutType: LayoutComponentTypes.ALIGNED_LAYOUT_COLUMN, + childTemplate: { + insertChild: true, + layoutId: "", + layoutType: LayoutComponentTypes.WIDGET_ROW, + layout: [], + }, + layout: [ + { + layoutType: LayoutComponentTypes.WIDGET_ROW, + layout: [ + { + widgetId: section1Id, + alignment: FlexLayerAlignment.Start, + widgetType: "SECTION_WIDGET", + }, + ], + }, + { + layoutType: LayoutComponentTypes.WIDGET_ROW, + layout: [ + { + widgetId: section2Id, + alignment: FlexLayerAlignment.Start, + widgetType: "SECTION_WIDGET", + }, + ], + }, + ], + }, + ], + }, + [section1Id]: { + widgetName: "Section 1", + type: "SECTION_WIDGET", + widgetId: section1Id, + children: [zone1Id], + layout: [section1Layout], + zoneCount: 1, + parentId: MAIN_CONTAINER_WIDGET_ID, + }, + [section2Id]: { + widgetName: "Section 2", + type: "SECTION_WIDGET", + widgetId: section2Id, + children: [zone2Id], + layout: [section2Layout], + zoneCount: 1, + parentId: MAIN_CONTAINER_WIDGET_ID, + }, + [zone1Id]: { + widgetName: "Zone 1", + type: "ZONE_WIDGET", + widgetId: zone1Id, + children: [], + parentId: section1Id, + }, + [zone2Id]: { + widgetName: "Zone 2", + type: "ZONE_WIDGET", + widgetId: zone2Id, + children: [], + parentId: section2Id, + }, + }; + return { + allWidgets, + mainCanvasLayoutId, + section1Id, + section2Id, + zone1Id, + zone2Id, + }; +}; From b849d348297f430ca9a27e7c01abab404e463e33 Mon Sep 17 00:00:00 2001 From: Sagar Khalasi Date: Mon, 24 Jun 2024 12:00:23 +0530 Subject: [PATCH 3/4] ci: Fix non used matrix parameter in build-client-server.yml (#34417) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Fix non used matrix parameter in build-client-server.yml. It was removed from originated function parameter. Fixes #`34418` ## Automation /ok-to-test tags="@tag.Sanity" ### :mag: Cypress test results > [!IMPORTANT] > 🟣 🟣 🟣 Your tests are running. > Tests running at: > Commit: acc2e4d8af13ae3c29a429c0e4db069976d69826 > Workflow: `PR Automation test suite` > Tags: `@tag.Sanity` ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No --- .github/workflows/build-client-server.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-client-server.yml b/.github/workflows/build-client-server.yml index 52253d4d03b4..c4029239ed82 100644 --- a/.github/workflows/build-client-server.yml +++ b/.github/workflows/build-client-server.yml @@ -131,7 +131,6 @@ jobs: secrets: inherit with: pr: ${{fromJson(needs.file-check.outputs.pr)}} - matrix: ${{needs.file-check.outputs.matrix_count}} ci-test-limited-existing-docker-image: needs: [file-check] From cb89dda2ed4b7da8f1e245eae33374f5c1dd4060 Mon Sep 17 00:00:00 2001 From: yatinappsmith <84702014+yatinappsmith@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:13:20 +0530 Subject: [PATCH 4/4] ci: removed matrix for ci-test-limit (#34420) ## Description removed matrix for ci-test-limit Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="" ### :mag: Cypress test results > [!CAUTION] > If you modify the content in this section, you are likely to disrupt the CI result for your PR. ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **Chores** - Updated CI workflows to streamline the `ci-test-limited` job by removing the `matrix` configuration. --- .github/workflows/build-client-server.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-client-server.yml b/.github/workflows/build-client-server.yml index c4029239ed82..550758e0fcbd 100644 --- a/.github/workflows/build-client-server.yml +++ b/.github/workflows/build-client-server.yml @@ -142,7 +142,6 @@ jobs: with: pr: ${{fromJson(needs.file-check.outputs.pr)}} previous-workflow-run-id: ${{ fromJson(needs.file-check.outputs.runId) }} - matrix: ${{ needs.file-check.outputs.matrix_count }} ci-test-limited-result: needs: [file-check, ci-test-limited]