diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ActionController.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ActionController.java index 7f34fb6d82..11062409f0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ActionController.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ActionController.java @@ -2,11 +2,11 @@ package com.appsmith.server.controllers; import com.appsmith.external.models.ActionExecutionResult; import com.appsmith.server.constants.Url; -import com.appsmith.server.domains.Layout; import com.appsmith.server.dtos.ActionDTO; import com.appsmith.server.dtos.ActionMoveDTO; import com.appsmith.server.dtos.ActionViewDTO; import com.appsmith.server.dtos.ExecuteActionDTO; +import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.RefactorNameDTO; import com.appsmith.server.dtos.ResponseDTO; import com.appsmith.server.services.ActionCollectionService; @@ -82,7 +82,7 @@ public class ActionController { } @PutMapping("/refactor") - public Mono> refactorActionName(@RequestBody RefactorNameDTO refactorNameDTO) { + public Mono> refactorActionName(@RequestBody RefactorNameDTO refactorNameDTO) { return layoutActionService.refactorActionName(refactorNameDTO) .map(created -> new ResponseDTO<>(HttpStatus.OK.value(), created, null)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/LayoutController.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/LayoutController.java index 18996edb58..5cb2d43be2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/LayoutController.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/LayoutController.java @@ -2,6 +2,7 @@ package com.appsmith.server.controllers; import com.appsmith.server.constants.Url; import com.appsmith.server.domains.Layout; +import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.RefactorNameDTO; import com.appsmith.server.dtos.ResponseDTO; import com.appsmith.server.services.LayoutActionService; @@ -46,7 +47,7 @@ public class LayoutController { } @PutMapping("/{layoutId}/pages/{pageId}") - public Mono> updateLayout(@PathVariable String pageId, @PathVariable String layoutId, @RequestBody Layout layout) { + public Mono> updateLayout(@PathVariable String pageId, @PathVariable String layoutId, @RequestBody Layout layout) { return layoutActionService.updateLayout(pageId, layoutId, layout) .map(created -> new ResponseDTO<>(HttpStatus.OK.value(), created, null)); } @@ -58,7 +59,7 @@ public class LayoutController { } @PutMapping("/refactor") - public Mono> refactorWidgetName(@RequestBody RefactorNameDTO refactorNameDTO) { + public Mono> refactorWidgetName(@RequestBody RefactorNameDTO refactorNameDTO) { return layoutActionService.refactorWidgetName(refactorNameDTO) .map(created -> new ResponseDTO<>(HttpStatus.OK.value(), created, null)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutActionUpdateDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutActionUpdateDTO.java new file mode 100644 index 0000000000..0a3775fcca --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutActionUpdateDTO.java @@ -0,0 +1,16 @@ +package com.appsmith.server.dtos; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +/** + * This class would be used to send any action updates that have happened as part of update layout. The client should + * consume this structure to update the actions in its local storage (instead of fetching all the page actions afresh). + */ +public class LayoutActionUpdateDTO { + String id; + String name; + Boolean executeOnLoad; +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutDTO.java new file mode 100644 index 0000000000..97ddeed54a --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/LayoutDTO.java @@ -0,0 +1,31 @@ +package com.appsmith.server.dtos; + +import com.appsmith.server.domains.ScreenType; +import lombok.Getter; +import lombok.Setter; +import net.minidev.json.JSONObject; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Getter +@Setter +public class LayoutDTO { + + private String id; + + ScreenType screen; + + JSONObject dsl; + + List> layoutOnLoadActions; + + // All the actions which have been updated as part of updateLayout function call + List actionUpdates; + + // All the toast messages that the developer user should be displayed to inform about the consequences of update layout. + List messages; + + public Set userPermissions = new HashSet<>(); +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionService.java index 3929aadeba..cb43f494ac 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionService.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionService.java @@ -4,16 +4,17 @@ import com.appsmith.server.domains.Layout; import com.appsmith.server.dtos.ActionDTO; import com.appsmith.server.dtos.ActionMoveDTO; import com.appsmith.server.dtos.RefactorNameDTO; +import com.appsmith.server.dtos.LayoutDTO; import reactor.core.publisher.Mono; public interface LayoutActionService { - Mono updateLayout(String pageId, String layoutId, Layout layout); + Mono updateLayout(String pageId, String layoutId, Layout layout); Mono moveAction(ActionMoveDTO actionMoveDTO); - Mono refactorWidgetName(RefactorNameDTO refactorNameDTO); + Mono refactorWidgetName(RefactorNameDTO refactorNameDTO); - Mono refactorActionName(RefactorNameDTO refactorNameDTO); + Mono refactorActionName(RefactorNameDTO refactorNameDTO); Mono updateAction(String id, ActionDTO action); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java index c4f4ac3462..d9ad17dda7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java @@ -7,8 +7,10 @@ import com.appsmith.server.domains.Layout; import com.appsmith.server.dtos.ActionDTO; import com.appsmith.server.dtos.ActionMoveDTO; import com.appsmith.server.dtos.DslActionDTO; +import com.appsmith.server.dtos.LayoutActionUpdateDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.RefactorNameDTO; +import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.MustacheHelper; @@ -121,7 +123,7 @@ public class LayoutActionServiceImpl implements LayoutActionService { } @Override - public Mono refactorWidgetName(RefactorNameDTO refactorNameDTO) { + public Mono refactorWidgetName(RefactorNameDTO refactorNameDTO) { String pageId = refactorNameDTO.getPageId(); String layoutId = refactorNameDTO.getLayoutId(); String oldName = refactorNameDTO.getOldName(); @@ -136,7 +138,7 @@ public class LayoutActionServiceImpl implements LayoutActionService { } @Override - public Mono refactorActionName(RefactorNameDTO refactorNameDTO) { + public Mono refactorActionName(RefactorNameDTO refactorNameDTO) { String pageId = refactorNameDTO.getPageId(); String layoutId = refactorNameDTO.getLayoutId(); String oldName = refactorNameDTO.getOldName(); @@ -167,7 +169,7 @@ public class LayoutActionServiceImpl implements LayoutActionService { * @param newName * @return */ - private Mono refactorName(String pageId, String layoutId, String oldName, String newName) { + private Mono refactorName(String pageId, String layoutId, String oldName, String newName) { String regexPattern = preWord + oldName + postWord; Pattern oldNamePattern = Pattern.compile(regexPattern); @@ -466,11 +468,11 @@ public class LayoutActionServiceImpl implements LayoutActionService { } @Override - public Mono updateLayout(String pageId, String layoutId, Layout layout) { + public Mono updateLayout(String pageId, String layoutId, Layout layout) { JSONObject dsl = layout.getDsl(); if (dsl == null) { // There is no DSL here. No need to process anything. Return as is. - return Mono.just(layout); + return Mono.just(generateResponseDTO(layout)); } Set widgetNames = new HashSet<>(); @@ -496,6 +498,8 @@ public class LayoutActionServiceImpl implements LayoutActionService { Set edges = new HashSet<>(); Set actionsUsedInDSL = new HashSet<>(); List flatmapPageLoadActions = new ArrayList<>(); + List actionUpdates = new ArrayList<>(); + List messages = new ArrayList<>(); Mono>> allOnLoadActionsMono = pageLoadActionsUtil .findAllOnLoadActions(dynamicBindingNames, actionNames, pageId, edges, actionsUsedInDSL, flatmapPageLoadActions); @@ -504,7 +508,9 @@ public class LayoutActionServiceImpl implements LayoutActionService { return allOnLoadActionsMono .flatMap(allOnLoadActions -> { // Update these actions to be executed on load, unless the user has touched the executeOnLoad setting for this - return newActionService.setOnLoad((flatmapPageLoadActions)).thenReturn(allOnLoadActions); + return newActionService + .updateActionsExecuteOnLoad(flatmapPageLoadActions, pageId, actionUpdates, messages) + .thenReturn(allOnLoadActions); }) .zipWith(newPageService.findByIdAndLayoutsId(pageId, layoutId, MANAGE_PAGES, false) .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.ACL_NO_RESOURCE_FOUND, @@ -542,7 +548,26 @@ public class LayoutActionServiceImpl implements LayoutActionService { } } return Mono.empty(); + }) + .map(savedLayout -> { + LayoutDTO layoutDTO = generateResponseDTO(savedLayout); + layoutDTO.setActionUpdates(actionUpdates); + layoutDTO.setMessages(messages); + return layoutDTO; }); } + private LayoutDTO generateResponseDTO(Layout layout) { + + LayoutDTO layoutDTO = new LayoutDTO(); + + layoutDTO.setId(layout.getId()); + layoutDTO.setDsl(layout.getDsl()); + layoutDTO.setScreen(layout.getScreen()); + layoutDTO.setLayoutOnLoadActions(layout.getLayoutOnLoadActions()); + layoutDTO.setUserPermissions(layout.getUserPermissions()); + + return layoutDTO; + } + } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionService.java index 64a6204d1d..d34efe9756 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionService.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionService.java @@ -6,6 +6,7 @@ import com.appsmith.server.domains.NewAction; import com.appsmith.server.dtos.ActionDTO; import com.appsmith.server.dtos.ActionViewDTO; import com.appsmith.server.dtos.ExecuteActionDTO; +import com.appsmith.server.dtos.LayoutActionUpdateDTO; import org.springframework.data.domain.Sort; import org.springframework.util.MultiValueMap; import reactor.core.publisher.Flux; @@ -57,5 +58,5 @@ public interface NewActionService extends CrudService { Flux findByPageId(String pageId); - Mono setOnLoad(List actions); + Mono updateActionsExecuteOnLoad(List actions, String pageId, List actionUpdates, List messages); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java index 4c91518940..afd677a35a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/NewActionServiceImpl.java @@ -30,6 +30,7 @@ import com.appsmith.server.domains.User; import com.appsmith.server.dtos.ActionDTO; import com.appsmith.server.dtos.ActionViewDTO; import com.appsmith.server.dtos.ExecuteActionDTO; +import com.appsmith.server.dtos.LayoutActionUpdateDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.MustacheHelper; @@ -42,6 +43,7 @@ import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import org.springframework.util.LinkedCaseInsensitiveMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import reactor.core.publisher.Flux; @@ -57,6 +59,7 @@ import java.time.Instant; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeoutException; @@ -916,25 +919,147 @@ public class NewActionServiceImpl extends BaseService setOnLoad(List actions) { - if (actions == null) { - return Mono.just(FALSE); - } + public Mono updateActionsExecuteOnLoad(List onLoadActions, + String pageId, + List actionUpdates, + List messages) { List toUpdateActions = new ArrayList<>(); - for (ActionDTO action : actions) { - // If a user has ever set execute on load, this field can not be changed automatically. It has to be - // explicitly changed by the user again. Add the action to update only if this condition is false. - if (FALSE.equals(action.getUserSetOnLoad())) { - action.setExecuteOnLoad(TRUE); - toUpdateActions.add(action); - } - } - return Flux.fromIterable(toUpdateActions) - .flatMap(actionDTO -> updateUnpublishedAction(actionDTO.getId(), actionDTO)) - .then(Mono.just(TRUE)); + MultiValueMap params = CollectionUtils.toMultiValueMap(new LinkedCaseInsensitiveMap<>(8, Locale.ENGLISH)); + params.add(FieldName.PAGE_ID, pageId); + + // Fetch all the actions which exist in this page. + Flux pageActionsFlux = this.getUnpublishedActions(params).cache(); + + // Before we update the actions, fetch all the actions which are currently set to execute on load. + Mono> existingOnPageLoadActionsMono = pageActionsFlux + .flatMap(action -> { + if (TRUE.equals(action.getExecuteOnLoad())) { + return Mono.just(action); + } + return Mono.empty(); + }) + .collectList(); + + return existingOnPageLoadActionsMono + .zipWith(pageActionsFlux.collectList()) + .flatMap( tuple -> { + List existingOnPageLoadActions = tuple.getT1(); + List pageActions = tuple.getT2(); + + // There are no actions in this page. No need to proceed further since no actions would get updated + if (pageActions.isEmpty()) { + return Mono.just(FALSE); + } + + // No actions require an update if no actions have been found as page load actions as well as + // existing on load page actions are empty + if (existingOnPageLoadActions.isEmpty() && (onLoadActions == null || onLoadActions.isEmpty())) { + return Mono.just(FALSE); + } + + // Extract names of existing pageload actions and new page load actions for quick lookup. + Set existingOnPageLoadActionNames = existingOnPageLoadActions + .stream() + .map(action -> action.getName()) + .collect(Collectors.toSet()); + + Set newOnLoadActionNames = onLoadActions + .stream() + .map(action -> action.getName()) + .collect(Collectors.toSet()); + + + // Calculate the actions which would need to be updated from execute on load TRUE to FALSE. + Set turnedOffActionNames = new HashSet<>(); + turnedOffActionNames.addAll(existingOnPageLoadActionNames); + turnedOffActionNames.removeAll(newOnLoadActionNames); + + // Calculate the actions which would need to be updated from execute on load FALSE to TRUE + Set turnedOnActionNames = new HashSet<>(); + turnedOnActionNames.addAll(newOnLoadActionNames); + turnedOnActionNames.removeAll(existingOnPageLoadActionNames); + + for (ActionDTO action : pageActions) { + + String actionName = action.getName(); + // If a user has ever set execute on load, this field can not be changed automatically. It has to be + // explicitly changed by the user again. Add the action to update only if this condition is false. + if (FALSE.equals(action.getUserSetOnLoad())) { + + // If this action is no longer an onload action, turn the execute on load to false + if (turnedOffActionNames.contains(actionName)) { + action.setExecuteOnLoad(FALSE); + toUpdateActions.add(action); + } + + // If this action is newly found to be on load, turn execute on load to true + if (turnedOnActionNames.contains(actionName)) { + action.setExecuteOnLoad(TRUE); + toUpdateActions.add(action); + } + } else { + // Remove the action name from either of the lists (if present) because this action should + // not be updated + turnedOnActionNames.remove(actionName); + turnedOffActionNames.remove(actionName); + } + } + + // Add newly turned on page actions to report back to the caller + actionUpdates.addAll( + addActionUpdatesForActionNames(pageActions, turnedOnActionNames) + ); + + // Add newly turned off page actions to report back to the caller + actionUpdates.addAll( + addActionUpdatesForActionNames(pageActions, turnedOffActionNames) + ); + + // Now add messages that would eventually be displayed to the developer user informing them + // about the action setting change. + if (!turnedOffActionNames.isEmpty()) { + messages.add(turnedOffActionNames.toString() + " will no longer be executed on page load"); + } + + if (!turnedOnActionNames.isEmpty()) { + messages.add(turnedOnActionNames.toString() + " will be executed automatically on page load"); + } + + // Finally update the actions which require an update + return Flux.fromIterable(toUpdateActions) + .flatMap(actionDTO -> updateUnpublishedAction(actionDTO.getId(), actionDTO)) + .then(Mono.just(TRUE)); + }); + } + + private List addActionUpdatesForActionNames(List pageActions, + Set actionNames) { + + return pageActions + .stream() + .filter(pageAction -> actionNames.contains(pageAction.getName())) + .map(pageAction -> { + LayoutActionUpdateDTO layoutActionUpdateDTO = new LayoutActionUpdateDTO(); + layoutActionUpdateDTO.setId(pageAction.getId()); + layoutActionUpdateDTO.setName(pageAction.getName()); + layoutActionUpdateDTO.setExecuteOnLoad(pageAction.getExecuteOnLoad()); + return layoutActionUpdateDTO; + }) + .collect(Collectors.toList()); } @Override diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java index f850509da5..1702990a76 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutActionServiceTest.java @@ -11,6 +11,8 @@ import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.User; import com.appsmith.server.dtos.ActionDTO; import com.appsmith.server.dtos.DslActionDTO; +import com.appsmith.server.dtos.LayoutActionUpdateDTO; +import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.RefactorNameDTO; import com.appsmith.server.helpers.MockPluginExecutor; @@ -37,6 +39,7 @@ import reactor.test.StepVerifier; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -216,7 +219,7 @@ public class LayoutActionServiceTest { ActionDTO createdAction = newActionService.createAction(action).block(); - Layout firstLayout = layoutActionService.updateLayout(testPage.getId(), layout.getId(), layout).block(); + LayoutDTO firstLayout = layoutActionService.updateLayout(testPage.getId(), layout.getId(), layout).block(); RefactorNameDTO refactorNameDTO = new RefactorNameDTO(); @@ -225,7 +228,7 @@ public class LayoutActionServiceTest { refactorNameDTO.setOldName("beforeNameChange"); refactorNameDTO.setNewName("PostNameChange"); - Layout postNameChangeLayout = layoutActionService.refactorActionName(refactorNameDTO).block(); + LayoutDTO postNameChangeLayout = layoutActionService.refactorActionName(refactorNameDTO).block(); Mono postNameChangeActionMono = newActionService.findById(createdAction.getId(), READ_ACTIONS); @@ -238,11 +241,105 @@ public class LayoutActionServiceTest { DslActionDTO actionDTO = postNameChangeLayout.getLayoutOnLoadActions().get(0).iterator().next(); assertThat(actionDTO.getName()).isEqualTo("PostNameChange"); -// JSONObject newDsl = new JSONObject(Map.of("widgetName", "firstWidget", "mustacheProp", "{{ PostNameChange.data }}")); dsl.put("testField", "{{ PostNameChange.data }}"); assertThat(postNameChangeLayout.getDsl()).isEqualTo(dsl); }) .verifyComplete(); } + @Test + @WithUserDetails(value = "api_user") + public void actionExecuteOnLoadChangeOnUpdateLayout() { + Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())).thenReturn(Mono.just(new MockPluginExecutor())); + + ActionDTO action1 = new ActionDTO(); + action1.setName("firstAction"); + action1.setPageId(testPage.getId()); + ActionConfiguration actionConfiguration1 = new ActionConfiguration(); + actionConfiguration1.setHttpMethod(HttpMethod.GET); + action1.setActionConfiguration(actionConfiguration1); + action1.setDatasource(datasource); + + ActionDTO action2 = new ActionDTO(); + action2.setName("secondAction"); + action2.setPageId(testPage.getId()); + ActionConfiguration actionConfiguration2 = new ActionConfiguration(); + actionConfiguration2.setHttpMethod(HttpMethod.GET); + action2.setActionConfiguration(actionConfiguration2); + action2.setDatasource(datasource); + + JSONObject dsl = new JSONObject(); + dsl.put("widgetName", "firstWidget"); + JSONArray temp = new JSONArray(); + temp.addAll(List.of(new JSONObject(Map.of("key", "testField")))); + dsl.put("dynamicBindingPathList", temp); + dsl.put("testField", "{{ firstAction.data }}"); + + Layout layout = testPage.getLayouts().get(0); + layout.setDsl(dsl); + + ActionDTO createdAction1 = newActionService.createAction(action1).block(); + ActionDTO createdAction2 = newActionService.createAction(action2).block(); + + Mono updateLayoutMono = layoutActionService.updateLayout(testPage.getId(), layout.getId(), layout); + + StepVerifier.create(updateLayoutMono) + .assertNext(updatedLayout -> { + log.debug("{}", updatedLayout.getMessages()); + DslActionDTO actionDTO = updatedLayout.getLayoutOnLoadActions().get(0).iterator().next(); + assertThat(actionDTO.getName()).isEqualTo("firstAction"); + + List actionUpdates = updatedLayout.getActionUpdates(); + assertThat(actionUpdates.size()).isEqualTo(1); + assertThat(actionUpdates.get(0).getName()).isEqualTo("firstAction"); + assertThat(actionUpdates.get(0).getExecuteOnLoad()).isTrue(); + }) + .verifyComplete(); + + StepVerifier.create(newActionService.findById(createdAction1.getId())) + .assertNext(newAction -> assertThat(newAction.getUnpublishedAction().getExecuteOnLoad()).isTrue()); + + StepVerifier.create(newActionService.findById(createdAction2.getId())) + .assertNext(newAction -> assertThat(newAction.getUnpublishedAction().getExecuteOnLoad()).isFalse()); + + dsl = new JSONObject(); + dsl.put("widgetName", "firstWidget"); + temp = new JSONArray(); + temp.addAll(List.of(new JSONObject(Map.of("key", "testField")))); + dsl.put("dynamicBindingPathList", temp); + dsl.put("testField", "{{ secondAction.data }}"); + + layout.setDsl(dsl); + + updateLayoutMono = layoutActionService.updateLayout(testPage.getId(), layout.getId(), layout); + + StepVerifier.create(updateLayoutMono) + .assertNext(updatedLayout -> { + log.debug("{}", updatedLayout.getMessages()); + DslActionDTO actionDTO = updatedLayout.getLayoutOnLoadActions().get(0).iterator().next(); + assertThat(actionDTO.getName()).isEqualTo("secondAction"); + + List actionUpdates = updatedLayout.getActionUpdates(); + assertThat(actionUpdates.size()).isEqualTo(2); + + Optional firstActionUpdateOptional = actionUpdates.stream().filter(actionUpdate -> actionUpdate.getName().equals("firstAction")).findFirst(); + LayoutActionUpdateDTO firstActionUpdate = firstActionUpdateOptional.get(); + assertThat(firstActionUpdate).isNotNull(); + assertThat(firstActionUpdate.getExecuteOnLoad()).isFalse(); + + Optional secondActionUpdateOptional = actionUpdates.stream().filter(actionUpdate -> actionUpdate.getName().equals("secondAction")).findFirst(); + LayoutActionUpdateDTO secondActionUpdate = secondActionUpdateOptional.get(); + assertThat(secondActionUpdate).isNotNull(); + assertThat(secondActionUpdate.getExecuteOnLoad()).isTrue(); + }) + .verifyComplete(); + + StepVerifier.create(newActionService.findById(createdAction1.getId())) + .assertNext(newAction -> assertThat(newAction.getUnpublishedAction().getExecuteOnLoad()).isFalse()); + + StepVerifier.create(newActionService.findById(createdAction2.getId())) + .assertNext(newAction -> assertThat(newAction.getUnpublishedAction().getExecuteOnLoad()).isTrue()); + + } + } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutServiceTest.java index 401edcf19f..078f6d498e 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutServiceTest.java @@ -7,13 +7,12 @@ import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.Application; import com.appsmith.server.domains.Datasource; import com.appsmith.server.domains.Layout; -import com.appsmith.server.domains.NewAction; -import com.appsmith.server.domains.NewPage; import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.PluginType; import com.appsmith.server.domains.User; import com.appsmith.server.dtos.ActionDTO; import com.appsmith.server.dtos.DslActionDTO; +import com.appsmith.server.dtos.LayoutDTO; import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; @@ -205,7 +204,7 @@ public class LayoutServiceTest { Layout startLayout = layoutService.createLayout(page.getId(), testLayout).block(); - Mono updatedLayoutMono = layoutActionService.updateLayout("random-impossible-id-page", startLayout.getId(), updateLayout); + Mono updatedLayoutMono = layoutActionService.updateLayout("random-impossible-id-page", startLayout.getId(), updateLayout); StepVerifier .create(updatedLayoutMono) @@ -238,7 +237,7 @@ public class LayoutServiceTest { Mono startLayoutMono = pageMono.flatMap(page -> layoutService.createLayout(page.getId(), testLayout)); - Mono updatedLayoutMono = Mono.zip(pageMono, startLayoutMono) + Mono updatedLayoutMono = Mono.zip(pageMono, startLayoutMono) .flatMap(tuple -> { PageDTO page = tuple.getT1(); Layout startLayout = tuple.getT2(); @@ -276,7 +275,7 @@ public class LayoutServiceTest { Mono pageMono = createPage(app, testPage).cache(); - Mono testMono = pageMono + Mono testMono = pageMono .flatMap(page1 -> { List> monos = new ArrayList<>(); @@ -464,7 +463,7 @@ public class LayoutServiceTest { Mono pageMono = createPage(app, testPage).cache(); - Mono testMono = pageMono + Mono testMono = pageMono .flatMap(page1 -> { List> monos = new ArrayList<>();