From d4a08529554ce73fe852e3593417f43aaf9539a9 Mon Sep 17 00:00:00 2001 From: subratadeypappu Date: Wed, 16 Apr 2025 15:56:50 +0600 Subject: [PATCH] chore: Add code-split for widget refactoring in UI module (#40226) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description EE Counterpart: https://github.com/appsmithorg/appsmith-ee/pull/7143 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="@tag.All" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 5585f90660cc8d16e3a6954db12c999b3e8b6060 > Cypress dashboard. > Tags: `@tag.All` > Spec: >
Fri, 11 Apr 2025 14:44:36 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **New Features** - Introduced context-aware layout management that enhances page design updates and dynamic refactoring. - Added improved handling for layout and widget updates, offering a smoother editing experience. - **Refactor** - Streamlined layout update processes with adaptive behavior based on context. - Optimized service interactions for more robust and modular page and widget processing. --- .../server/domains/ce/LayoutContainer.java | 13 ++ .../com/appsmith/server/dtos/PageDTO.java | 3 +- .../server/layouts/UpdateLayoutServiceCE.java | 3 + .../layouts/UpdateLayoutServiceCEImpl.java | 32 ++-- .../layouts/UpdateLayoutServiceImpl.java | 11 +- .../PageLayoutRefactoringServiceImpl.java | 109 ++++++++++++++ .../internal/OnLoadExecutablesUtilCEImpl.java | 57 ++++--- .../ContextLayoutRefactoringService.java | 107 ++++++++++++++ .../RefactoringServiceCEImpl.java | 53 +++---- .../applications/RefactoringServiceImpl.java | 14 +- .../ContextLayoutRefactorResolver.java | 13 ++ .../ContextLayoutRefactorResolverCE.java | 21 +++ .../WidgetRefactoringServiceCEImpl.java | 139 ++++++++++-------- .../WidgetRefactoringServiceImpl.java | 10 +- .../ce/RefactoringServiceCEImplTest.java | 13 +- 15 files changed, 443 insertions(+), 155 deletions(-) create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/LayoutContainer.java create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/refactors/PageLayoutRefactoringServiceImpl.java create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/ContextLayoutRefactoringService.java create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/resolver/ContextLayoutRefactorResolver.java create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/resolver/ContextLayoutRefactorResolverCE.java diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/LayoutContainer.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/LayoutContainer.java new file mode 100644 index 0000000000..7da4259b21 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/LayoutContainer.java @@ -0,0 +1,13 @@ +package com.appsmith.server.domains.ce; + +import com.appsmith.server.domains.Layout; + +import java.util.List; + +public interface LayoutContainer { + List getLayouts(); + + void setLayouts(List layouts); + + String getId(); +} 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 7bd8d3d0f6..52618c40be 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 @@ -5,6 +5,7 @@ import com.appsmith.external.models.Policy; import com.appsmith.external.views.Git; import com.appsmith.external.views.Views; import com.appsmith.server.domains.Layout; +import com.appsmith.server.domains.ce.LayoutContainer; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonView; import lombok.Getter; @@ -26,7 +27,7 @@ import java.util.Set; @NoArgsConstructor @ToString @FieldNameConstants -public class PageDTO { +public class PageDTO implements LayoutContainer { @Transient @JsonView({Views.Public.class}) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCE.java index 8831d6e523..90eb5b1b15 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCE.java @@ -14,6 +14,9 @@ import java.util.Set; public interface UpdateLayoutServiceCE { Mono updateLayout(String pageId, String applicationId, String layoutId, Layout layout); + Mono updateLayout( + String pageId, String applicationId, String layoutId, Layout layout, CreatorContextType contextType); + Mono updateMultipleLayouts( String defaultApplicationId, UpdateMultiplePageLayoutDTO updateMultiplePageLayoutDTO); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java index 37700b3bfb..e375767314 100755 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java @@ -7,7 +7,6 @@ import com.appsmith.external.exceptions.ErrorDTO; import com.appsmith.external.helpers.MustacheHelper; import com.appsmith.external.models.CreatorContextType; import com.appsmith.external.models.Executable; -import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.ExecutableDependencyEdge; import com.appsmith.server.domains.Layout; @@ -21,6 +20,7 @@ import com.appsmith.server.helpers.ObservationHelperImpl; import com.appsmith.server.helpers.WidgetSpecificUtils; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.onload.internal.OnLoadExecutablesUtil; +import com.appsmith.server.refactors.resolver.ContextLayoutRefactorResolver; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.solutions.PagePermission; @@ -59,6 +59,7 @@ import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_LAYOUT_MET import static com.appsmith.external.constants.spans.PageSpan.GET_PAGE_BY_ID; import static com.appsmith.external.constants.spans.ce.LayoutSpanCE.UPDATE_LAYOUT_BASED_ON_CONTEXT; import static com.appsmith.server.constants.CommonConstants.EVALUATION_VERSION; +import static com.appsmith.server.helpers.ContextTypeUtils.isPageContext; import static java.lang.Boolean.FALSE; @Slf4j @@ -71,10 +72,10 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { private final NewPageService newPageService; private final AnalyticsService analyticsService; private final PagePermission pagePermission; - private final ApplicationService applicationService; private final ObjectMapper objectMapper; private final ObservationRegistry observationRegistry; private final ObservationHelperImpl observationHelper; + private final ContextLayoutRefactorResolver contextLayoutRefactorResolver; private final String layoutOnLoadActionErrorToastMessage = "A cyclic dependency error has been encountered on current page, \nqueries on page load will not run. \n Please check debugger and Appsmith documentation for more information"; @@ -117,7 +118,7 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { }); } - private Mono updateLayoutDsl( + protected Mono updateLayoutDsl( String creatorId, String layoutId, Layout layout, @@ -247,22 +248,29 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE { return layoutDTOMono; } + // TODO: Add contextType and change all its usage to conform to that so that we can get rid of the overloaded + // updateLayout method @Override public Mono updateLayout(String pageId, String applicationId, String layoutId, Layout layout) { - return applicationService - .findById(applicationId) - .switchIfEmpty(Mono.error(new AppsmithException( - AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.APPLICATION_ID, applicationId))) - .flatMap(application -> { - Integer evaluationVersion = application.getEvaluationVersion(); - if (evaluationVersion == null) { - evaluationVersion = EVALUATION_VERSION; - } + return contextLayoutRefactorResolver + .getContextLayoutRefactorHelper(null) + .getEvaluationVersionMono(applicationId) + .flatMap(evaluationVersion -> { return updateLayoutDsl(pageId, layoutId, layout, evaluationVersion, CreatorContextType.PAGE) .name(UPDATE_LAYOUT_DSL_METHOD); }); } + @Override + public Mono updateLayout( + String pageId, String applicationId, String layoutId, Layout layout, CreatorContextType contextType) { + if (isPageContext(contextType)) { + return updateLayout(pageId, applicationId, layoutId, layout); + } else { + return updateLayoutDsl(pageId, layoutId, layout, EVALUATION_VERSION, contextType); + } + } + @Override public Mono updateMultipleLayouts( String baseApplicationId, UpdateMultiplePageLayoutDTO updateMultiplePageLayoutDTO) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java index a50e3e7c66..2c51077002 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceImpl.java @@ -1,9 +1,9 @@ package com.appsmith.server.layouts; -import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.helpers.ObservationHelperImpl; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.onload.internal.OnLoadExecutablesUtil; +import com.appsmith.server.refactors.resolver.ContextLayoutRefactorResolver; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.solutions.PagePermission; @@ -13,26 +13,25 @@ import org.springframework.stereotype.Service; @Service public class UpdateLayoutServiceImpl extends UpdateLayoutServiceCEImpl implements UpdateLayoutService { - public UpdateLayoutServiceImpl( OnLoadExecutablesUtil onLoadExecutablesUtil, SessionUserService sessionUserService, NewPageService newPageService, AnalyticsService analyticsService, PagePermission pagePermission, - ApplicationService applicationService, ObjectMapper objectMapper, ObservationRegistry observationRegistry, - ObservationHelperImpl observationHelper) { + ObservationHelperImpl observationHelper, + ContextLayoutRefactorResolver contextLayoutRefactorResolver) { super( onLoadExecutablesUtil, sessionUserService, newPageService, analyticsService, pagePermission, - applicationService, objectMapper, observationRegistry, - observationHelper); + observationHelper, + contextLayoutRefactorResolver); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/refactors/PageLayoutRefactoringServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/refactors/PageLayoutRefactoringServiceImpl.java new file mode 100644 index 0000000000..00cfe8ca4d --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/refactors/PageLayoutRefactoringServiceImpl.java @@ -0,0 +1,109 @@ +package com.appsmith.server.newpages.refactors; + +import com.appsmith.server.applications.base.ApplicationService; +import com.appsmith.server.constants.FieldName; +import com.appsmith.server.domains.Layout; +import com.appsmith.server.domains.NewPage; +import com.appsmith.server.domains.ce.LayoutContainer; +import com.appsmith.server.dtos.PageDTO; +import com.appsmith.server.dtos.RefactorEntityNameDTO; +import com.appsmith.server.dtos.RefactoringMetaDTO; +import com.appsmith.server.exceptions.AppsmithError; +import com.appsmith.server.exceptions.AppsmithException; +import com.appsmith.server.newpages.base.NewPageService; +import com.appsmith.server.refactors.ContextLayoutRefactoringService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +import java.util.List; + +import static com.appsmith.server.constants.ce.CommonConstantsCE.EVALUATION_VERSION; + +@Component +@RequiredArgsConstructor +@Slf4j +public class PageLayoutRefactoringServiceImpl implements ContextLayoutRefactoringService { + private final NewPageService newPageService; + private final ApplicationService applicationService; + + @Override + public Mono updateContext(String contextId, LayoutContainer dto) { + return newPageService.saveUnpublishedPage((PageDTO) dto); + } + + @Override + public Mono getContextDTOMono(String contextId, boolean viewMode) { + return newPageService.findPageById(contextId, null, viewMode); + } + + @Override + public Mono getContextDTOMono(RefactoringMetaDTO refactoringMetaDTO) { + return refactoringMetaDTO.getPageDTOMono(); + } + + @Override + public Mono getEvaluationVersionMono( + String contextId, RefactorEntityNameDTO refactorEntityNameDTO, RefactoringMetaDTO refactoringMetaDTO) { + Mono pageDTOMono = getContextDTOMono(contextId, false); + refactoringMetaDTO.setPageDTOMono(pageDTOMono); + return pageDTOMono.flatMap( + page -> applicationService.findById(page.getApplicationId()).map(application -> { + Integer evaluationVersion = application.getEvaluationVersion(); + if (evaluationVersion == null) { + evaluationVersion = EVALUATION_VERSION; + } + return evaluationVersion; + })); + } + + @Override + public Mono getEvaluationVersionMono(String artifactId) { + return applicationService + .findById(artifactId) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.APPLICATION_ID, artifactId))) + .map(application -> { + Integer evaluationVersion = application.getEvaluationVersion(); + if (evaluationVersion == null) { + evaluationVersion = EVALUATION_VERSION; + } + return evaluationVersion; + }); + } + + @Override + public List getLayouts(RefactoringMetaDTO refactoringMetaDTO) { + PageDTO updatedPage = refactoringMetaDTO.getUpdatedPage(); + if (updatedPage == null) { + return null; + } + return updatedPage.getLayouts(); + } + + @Override + public Mono updateLayoutByContextId(String contextId, Layout layout) { + // Implementation for updating page layout + return Mono.empty(); + } + + @Override + public String getId(RefactoringMetaDTO refactoringMetaDTO) { + return refactoringMetaDTO.getUpdatedPage() != null + ? refactoringMetaDTO.getUpdatedPage().getId() + : null; + } + + @Override + public String getArtifactId(RefactoringMetaDTO refactoringMetaDTO) { + return refactoringMetaDTO.getUpdatedPage() != null + ? refactoringMetaDTO.getUpdatedPage().getApplicationId() + : null; + } + + @Override + public void setUpdatedContext(RefactoringMetaDTO refactoringMetaDTO, LayoutContainer updatedContext) { + refactoringMetaDTO.setUpdatedPage((PageDTO) updatedContext); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImpl.java index ff04b31306..f311fe9fb1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/onload/internal/OnLoadExecutablesUtilCEImpl.java @@ -167,7 +167,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { widgetDynamicBindingsMap, executableNameToExecutableMapMono, executableBindingsInDslRef, - evaluatedVersion) + evaluatedVersion, + creatorType) .name(ADD_DIRECTLY_REFERENCED_EXECUTABLES_TO_GRAPH) .tap(Micrometer.observation(observationRegistry)); @@ -197,7 +198,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { executablesFoundDuringWalkRef, bindingsFromExecutablesRef, executableNameToExecutableMapMono, - evaluatedVersion)) + evaluatedVersion, + creatorType)) .name(RECURSIVELY_ADD_EXECUTABLES_AND_THEIR_DEPENDENTS_TO_GRAPH_FROM_BINDINGS) .tap(Micrometer.observation(observationRegistry)) // At last, add all the widget relationships to the graph as well. @@ -410,7 +412,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { // Finally update the actions which require an update return Flux.fromIterable(toUpdateExecutables) - .flatMap(executable -> this.updateUnpublishedExecutable(executable.getId(), executable)) + .flatMap(executable -> + this.updateUnpublishedExecutable(executable.getId(), executable, creatorType)) .then(Mono.just(TRUE)); }); } @@ -418,12 +421,13 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { @Override public Mono findAndUpdateLayout( String creatorId, CreatorContextType creatorType, String layoutId, Layout layout) { - return pageExecutableOnLoadService.findAndUpdateLayout(creatorId, layoutId, layout); + return getExecutableOnLoadService(creatorType).findAndUpdateLayout(creatorId, layoutId, layout); } - private Mono updateUnpublishedExecutable(String id, Executable executable) { + private Mono updateUnpublishedExecutable( + String id, Executable executable, CreatorContextType contextType) { if (executable instanceof ActionDTO actionDTO) { - return pageExecutableOnLoadService.updateUnpublishedExecutable(id, actionDTO); + return getExecutableOnLoadService(contextType).updateUnpublishedExecutable(id, actionDTO); } else return Mono.just(executable); } @@ -437,7 +441,7 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { } protected Flux getAllExecutablesByCreatorIdFlux(String creatorId, CreatorContextType creatorType) { - return pageExecutableOnLoadService + return getExecutableOnLoadService(creatorType) .getAllExecutablesByCreatorIdFlux(creatorId) .name(GET_ALL_EXECUTABLES_BY_CREATOR_ID) .tap(Micrometer.observation(observationRegistry)); @@ -701,7 +705,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { Map> widgetDynamicBindingsMap, Mono> executableNameToExecutableMapMono, Set executableBindingsInDslRef, - int evalVersion) { + int evalVersion, + CreatorContextType contextType) { Map> bindingToWidgetNodesMap = new HashMap<>(); List allBindings = new ArrayList<>(); @@ -741,7 +746,7 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { // candidate for on page load executablesUsedInDSLRef.add(possibleEntity.getValidEntityName()); - return updateExecutableSelfReferencingPaths(possibleEntity) + return updateExecutableSelfReferencingPaths(possibleEntity, contextType) .name(UPDATE_EXECUTABLE_SELF_REFERENCING_PATHS) .tap(Micrometer.observation(observationRegistry)) .flatMap(executable -> extractAndSetExecutableBindingsInGraphEdges( @@ -763,16 +768,19 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { .thenReturn(edgesRef); } - protected Mono updateExecutableSelfReferencingPaths(EntityDependencyNode possibleEntity) { - return this.fillSelfReferencingPaths(possibleEntity.getExecutable()).map(executable -> { - possibleEntity.setExecutable(executable); - return executable; - }); + protected Mono updateExecutableSelfReferencingPaths( + EntityDependencyNode possibleEntity, CreatorContextType contextType) { + return this.fillSelfReferencingPaths(possibleEntity.getExecutable(), contextType) + .map(executable -> { + possibleEntity.setExecutable(executable); + return executable; + }); } - protected Mono fillSelfReferencingPaths(T executable) { + protected Mono fillSelfReferencingPaths( + T executable, CreatorContextType contextType) { if (executable instanceof ActionDTO actionDTO) { - return pageExecutableOnLoadService.fillSelfReferencingPaths(actionDTO); + return getExecutableOnLoadService(contextType).fillSelfReferencingPaths(actionDTO); } else return Mono.just(executable); } @@ -1007,7 +1015,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { Map executablesFoundDuringWalk, Set dynamicBindings, Mono> executableNameToExecutableMapMono, - int evalVersion) { + int evalVersion, + CreatorContextType contextType) { if (dynamicBindings == null || dynamicBindings.isEmpty()) { return Mono.just(edges); } @@ -1024,7 +1033,7 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { // Add dependencies of the executables found in the DSL in the graph. .flatMap(possibleEntity -> { if (getExecutableTypes().contains(possibleEntity.getEntityReferenceType())) { - return updateExecutableSelfReferencingPaths(possibleEntity) + return updateExecutableSelfReferencingPaths(possibleEntity, contextType) .name(UPDATE_EXECUTABLE_SELF_REFERENCING_PATHS) .tap(Micrometer.observation(observationRegistry)) .then(extractAndSetExecutableBindingsInGraphEdges( @@ -1052,7 +1061,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { executablesFoundDuringWalk, newBindings, executableNameToExecutableMapMono, - evalVersion) + evalVersion, + contextType) .name(RECURSIVELY_ADD_EXECUTABLES_AND_THEIR_DEPENDENTS_TO_GRAPH_FROM_BINDINGS) .tap(Micrometer.observation(observationRegistry)); }); @@ -1091,7 +1101,7 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { return getUnpublishedOnLoadExecutablesExplicitSetByUserInCreatorContextFlux(creatorId, creatorType) .name(GET_UNPUBLISHED_ON_LOAD_EXECUTABLES_EXPLICIT_SET_BY_USER_IN_CREATOR_CONTEXT) .tap(Micrometer.observation(observationRegistry)) - .flatMap(this::fillSelfReferencingPaths) + .flatMap(executable -> fillSelfReferencingPaths(executable, creatorType)) // Add the vertices and edges to the graph for these executables .flatMap(executable -> { EntityDependencyNode entityDependencyNode = new EntityDependencyNode( @@ -1119,7 +1129,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { protected Flux getUnpublishedOnLoadExecutablesExplicitSetByUserInCreatorContextFlux( String creatorId, CreatorContextType creatorType) { - return pageExecutableOnLoadService.getUnpublishedOnLoadExecutablesExplicitSetByUserInPageFlux(creatorId); + return getExecutableOnLoadService(creatorType) + .getUnpublishedOnLoadExecutablesExplicitSetByUserInPageFlux(creatorId); } /** @@ -1464,4 +1475,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE { return onPageLoadCandidates; } + + protected ExecutableOnLoadService getExecutableOnLoadService(CreatorContextType contextType) { + return pageExecutableOnLoadService; + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/ContextLayoutRefactoringService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/ContextLayoutRefactoringService.java new file mode 100644 index 0000000000..38f3470333 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/ContextLayoutRefactoringService.java @@ -0,0 +1,107 @@ +package com.appsmith.server.refactors; + +import com.appsmith.external.models.BaseDomain; +import com.appsmith.server.domains.Layout; +import com.appsmith.server.domains.ce.LayoutContainer; +import com.appsmith.server.dtos.RefactorEntityNameDTO; +import com.appsmith.server.dtos.RefactoringMetaDTO; +import reactor.core.publisher.Mono; + +import java.util.List; + +/** + * Service interface for handling layout-related refactoring operations within a context + * such as a page or module. It provides methods to retrieve, update, and evaluate layouts + * while preserving consistency during entity renaming or structural changes. + * + * @param The domain type associated with the context (e.g., Page, Module) + * @param The layout container type that holds layouts (e.g., PageDTO, ModuleDTO) + */ +public interface ContextLayoutRefactoringService { + + /** + * Updates the context identified by the given contextId with the provided layout container. + * + * @param contextId The unique identifier of the context to update + * @param dto The layout container containing updated layout information + * @return A Mono emitting the updated layout container + */ + Mono updateContext(String contextId, LayoutContainer dto); + + /** + * Retrieves the layout container (DTO) for the given contextId and view mode. + * + * @param contextId The unique identifier of the context + * @param viewMode true for published version, false for unpublished + * @return A Mono emitting the requested layout container + */ + Mono getContextDTOMono(String contextId, boolean viewMode); + + /** + * Retrieves the layout container using metadata derived from the refactoring context. + * + * @param refactoringMetaDTO Metadata describing the refactoring context + * @return A Mono emitting the corresponding layout container + */ + Mono getContextDTOMono(RefactoringMetaDTO refactoringMetaDTO); + + /** + * Retrieves the evaluation version associated with the context, used to guide DSL parsing or upgrades. + * + * @param contextId The unique identifier of the context + * @param refactorEntityNameDTO DTO containing the old and new entity names + * @param refactoringMetaDTO Metadata describing the refactoring context + * @return A Mono emitting the evaluation version for the context + */ + Mono getEvaluationVersionMono( + String contextId, RefactorEntityNameDTO refactorEntityNameDTO, RefactoringMetaDTO refactoringMetaDTO); + + /** + * Retrieves the evaluation version for the context without refactor-specific inputs. + * + * @param artifactId The unique identifier of the artifact + * @return A Mono emitting the evaluation version + */ + Mono getEvaluationVersionMono(String artifactId); + + /** + * Extracts layouts from the provided refactoring metadata. + * + * @param refactoringMetaDTO Metadata describing the refactoring context + * @return A list of layouts associated with the context + */ + List getLayouts(RefactoringMetaDTO refactoringMetaDTO); + + /** + * Updates a specific layout for the context identified by contextId. + * + * @param contextId The unique identifier of the context + * @param layout The layout to update + * @return A Mono emitting the updated layout container + */ + Mono updateLayoutByContextId(String contextId, Layout layout); + + /** + * Retrieves the context ID from the provided refactoring metadata. + * + * @param refactoringMetaDTO Metadata describing the refactoring context + * @return The unique context identifier + */ + String getId(RefactoringMetaDTO refactoringMetaDTO); + + /** + * Retrieves the artifact ID from the provided refactoring metadata. + * + * @param refactoringMetaDTO Metadata describing the refactoring context + * @return The artifact identifier associated with the context + */ + String getArtifactId(RefactoringMetaDTO refactoringMetaDTO); + + /** + * Updates the in-memory copy of the refactored context in the given metadata object. + * + * @param refactoringMetaDTO Metadata describing the refactoring context + * @param updatedContext The updated layout container to persist in metadata + */ + void setUpdatedContext(RefactoringMetaDTO refactoringMetaDTO, LayoutContainer updatedContext); +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceCEImpl.java index ddaff144ba..c223f42af0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceCEImpl.java @@ -2,24 +2,23 @@ package com.appsmith.server.refactors.applications; import com.appsmith.external.constants.AnalyticsEvents; import com.appsmith.external.models.CreatorContextType; -import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewAction; import com.appsmith.server.dtos.EntityType; import com.appsmith.server.dtos.LayoutDTO; -import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.RefactorEntityNameDTO; import com.appsmith.server.dtos.RefactoringMetaDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newpages.base.NewPageService; +import com.appsmith.server.refactors.ContextLayoutRefactoringService; import com.appsmith.server.refactors.entities.EntityRefactoringService; +import com.appsmith.server.refactors.resolver.ContextLayoutRefactorResolver; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.solutions.PagePermission; import com.appsmith.server.validations.EntityValidationService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -36,7 +35,6 @@ import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; -import static com.appsmith.server.constants.CommonConstants.EVALUATION_VERSION; import static com.appsmith.server.helpers.ContextTypeUtils.getDefaultContextIfNull; @Slf4j @@ -44,8 +42,6 @@ import static com.appsmith.server.helpers.ContextTypeUtils.getDefaultContextIfNu public class RefactoringServiceCEImpl implements RefactoringServiceCE { private final NewPageService newPageService; private final UpdateLayoutService updateLayoutService; - private final ApplicationService applicationService; - private final PagePermission pagePermission; private final AnalyticsService analyticsService; private final SessionUserService sessionUserService; private final EntityValidationService entityValidationService; @@ -54,6 +50,7 @@ public class RefactoringServiceCEImpl implements RefactoringServiceCE { protected final EntityRefactoringService newActionEntityRefactoringService; protected final EntityRefactoringService actionCollectionEntityRefactoringService; protected final EntityRefactoringService widgetEntityRefactoringService; + protected final ContextLayoutRefactorResolver contextLayoutRefactorResolver; /* * To replace fetchUsers in `{{JSON.stringify(fetchUsers)}}` with getUsers, the following regex is required : @@ -73,7 +70,7 @@ public class RefactoringServiceCEImpl implements RefactoringServiceCE { * @return : The DSL after refactor updates */ Mono>> refactorName(RefactorEntityNameDTO refactorEntityNameDTO) { - String pageId = refactorEntityNameDTO.getPageId(); + String contextId = getBranchedContextId(refactorEntityNameDTO); String layoutId = refactorEntityNameDTO.getLayoutId(); String oldName = refactorEntityNameDTO.getOldFullyQualifiedName(); @@ -83,21 +80,30 @@ public class RefactoringServiceCEImpl implements RefactoringServiceCE { refactoringMetaDTO.setOldNamePattern(oldNamePattern); - refactoringMetaDTO.setEvalVersionMono( - getContextBasedEvalVersionMono(pageId, refactorEntityNameDTO, refactoringMetaDTO)); + refactoringMetaDTO.setEvalVersionMono(contextLayoutRefactorResolver + .getContextLayoutRefactorHelper(refactorEntityNameDTO.getContextType()) + .getEvaluationVersionMono(contextId, refactorEntityNameDTO, refactoringMetaDTO)); Mono refactoredReferencesMono = refactorAllReferences(refactorEntityNameDTO, refactoringMetaDTO); return refactoredReferencesMono.then(Mono.defer(() -> { - PageDTO page = refactoringMetaDTO.getUpdatedPage(); Set updatedBindingPaths = refactoringMetaDTO.getUpdatedBindingPaths(); - if (page != null) { - List layouts = page.getLayouts(); + ContextLayoutRefactoringService contextLayoutRefactorHelper = + contextLayoutRefactorResolver.getContextLayoutRefactorHelper( + refactorEntityNameDTO.getContextType()); + List layouts = contextLayoutRefactorHelper.getLayouts(refactoringMetaDTO); + if (layouts != null) { for (Layout layout : layouts) { if (layoutId.equals(layout.getId())) { layout.setDsl(updateLayoutService.unescapeMongoSpecialCharacters(layout)); + String artifactId = contextLayoutRefactorHelper.getArtifactId(refactoringMetaDTO); return updateLayoutService - .updateLayout(page.getId(), page.getApplicationId(), layout.getId(), layout) + .updateLayout( + contextId, + artifactId, + layout.getId(), + layout, + refactorEntityNameDTO.getContextType()) .zipWith(Mono.just(updatedBindingPaths)); } } @@ -107,27 +113,6 @@ public class RefactoringServiceCEImpl implements RefactoringServiceCE { })); } - protected Mono getContextBasedEvalVersionMono( - String contextId, RefactorEntityNameDTO refactorEntityNameDTO, RefactoringMetaDTO refactoringMetaDTO) { - Mono pageMono = newPageService - // fetch the unpublished page - .findPageById(contextId, pagePermission.getEditPermission(), false) - .cache(); - - refactoringMetaDTO.setPageDTOMono(pageMono); - Mono evalVersionMono = pageMono.flatMap(page -> { - return applicationService.findById(page.getApplicationId()).map(application -> { - Integer evaluationVersion = application.getEvaluationVersion(); - if (evaluationVersion == null) { - evaluationVersion = EVALUATION_VERSION; - } - return evaluationVersion; - }); - }) - .cache(); - return evalVersionMono; - } - protected static Pattern getReplacementPattern(String oldName) { String regexPattern = preWord + oldName + postWord; return Pattern.compile(regexPattern); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceImpl.java index 2de04e3c84..d50cf16a47 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/applications/RefactoringServiceImpl.java @@ -1,15 +1,14 @@ package com.appsmith.server.refactors.applications; -import com.appsmith.server.applications.base.ApplicationService; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewAction; import com.appsmith.server.layouts.UpdateLayoutService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.refactors.entities.EntityRefactoringService; +import com.appsmith.server.refactors.resolver.ContextLayoutRefactorResolver; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.solutions.PagePermission; import com.appsmith.server.validations.EntityValidationService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -17,30 +16,27 @@ import org.springframework.stereotype.Service; @Service @Slf4j public class RefactoringServiceImpl extends RefactoringServiceCEImpl implements RefactoringService { - public RefactoringServiceImpl( NewPageService newPageService, UpdateLayoutService updateLayoutService, - ApplicationService applicationService, - PagePermission pagePermission, AnalyticsService analyticsService, SessionUserService sessionUserService, EntityValidationService entityValidationService, EntityRefactoringService jsActionEntityRefactoringService, EntityRefactoringService newActionEntityRefactoringService, EntityRefactoringService actionCollectionEntityRefactoringService, - EntityRefactoringService widgetEntityRefactoringService) { + EntityRefactoringService widgetEntityRefactoringService, + ContextLayoutRefactorResolver contextLayoutRefactorResolver) { super( newPageService, updateLayoutService, - applicationService, - pagePermission, analyticsService, sessionUserService, entityValidationService, jsActionEntityRefactoringService, newActionEntityRefactoringService, actionCollectionEntityRefactoringService, - widgetEntityRefactoringService); + widgetEntityRefactoringService, + contextLayoutRefactorResolver); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/resolver/ContextLayoutRefactorResolver.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/resolver/ContextLayoutRefactorResolver.java new file mode 100644 index 0000000000..bbc3b4668d --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/resolver/ContextLayoutRefactorResolver.java @@ -0,0 +1,13 @@ +package com.appsmith.server.refactors.resolver; + +import com.appsmith.server.domains.NewPage; +import com.appsmith.server.dtos.PageDTO; +import com.appsmith.server.refactors.ContextLayoutRefactoringService; +import org.springframework.stereotype.Service; + +@Service +public class ContextLayoutRefactorResolver extends ContextLayoutRefactorResolverCE { + public ContextLayoutRefactorResolver(ContextLayoutRefactoringService pageLayoutRefactorService) { + super(pageLayoutRefactorService); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/resolver/ContextLayoutRefactorResolverCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/resolver/ContextLayoutRefactorResolverCE.java new file mode 100644 index 0000000000..89f121abbb --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/refactors/resolver/ContextLayoutRefactorResolverCE.java @@ -0,0 +1,21 @@ +package com.appsmith.server.refactors.resolver; + +import com.appsmith.external.models.CreatorContextType; +import com.appsmith.server.domains.NewPage; +import com.appsmith.server.dtos.PageDTO; +import com.appsmith.server.refactors.ContextLayoutRefactoringService; +import org.springframework.stereotype.Service; + +@Service +public class ContextLayoutRefactorResolverCE { + private final ContextLayoutRefactoringService pageLayoutRefactorService; + + public ContextLayoutRefactorResolverCE( + ContextLayoutRefactoringService pageLayoutRefactorService) { + this.pageLayoutRefactorService = pageLayoutRefactorService; + } + + public ContextLayoutRefactoringService getContextLayoutRefactorHelper(CreatorContextType contextType) { + return pageLayoutRefactorService; + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceCEImpl.java index 43535467c6..0aba27d7bc 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceCEImpl.java @@ -1,18 +1,19 @@ package com.appsmith.server.widgets.refactors; import com.appsmith.external.constants.AnalyticsEvents; +import com.appsmith.external.models.BaseDomain; import com.appsmith.external.models.CreatorContextType; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.Layout; +import com.appsmith.server.domains.ce.LayoutContainer; import com.appsmith.server.dtos.EntityType; -import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.dtos.RefactorEntityNameDTO; import com.appsmith.server.dtos.RefactoringMetaDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.newpages.base.NewPageService; +import com.appsmith.server.refactors.ContextLayoutRefactoringService; import com.appsmith.server.refactors.entities.EntityRefactoringServiceCE; -import com.appsmith.server.services.AstService; +import com.appsmith.server.refactors.resolver.ContextLayoutRefactorResolver; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; @@ -26,16 +27,15 @@ import java.util.Set; import java.util.regex.Pattern; import static com.appsmith.external.constants.AnalyticsEvents.REFACTOR_WIDGET; +import static com.appsmith.server.helpers.ContextTypeUtils.isModuleContext; import static com.appsmith.server.helpers.ContextTypeUtils.isPageContext; @Slf4j @RequiredArgsConstructor public class WidgetRefactoringServiceCEImpl implements EntityRefactoringServiceCE { - - private final NewPageService newPageService; - private final AstService astService; - private final ObjectMapper objectMapper; - private final WidgetRefactorUtil widgetRefactorUtil; + protected final ObjectMapper objectMapper; + protected final WidgetRefactorUtil widgetRefactorUtil; + private final ContextLayoutRefactorResolver contextLayoutRefactorResolver; @Override public AnalyticsEvents getRefactorAnalyticsEvent(EntityType entityType) { @@ -45,53 +45,67 @@ public class WidgetRefactoringServiceCEImpl implements EntityRefactoringServiceC @Override public Mono refactorReferencesInExistingEntities( RefactorEntityNameDTO refactorEntityNameDTO, RefactoringMetaDTO refactoringMetaDTO) { - if (!isPageContext(refactorEntityNameDTO.getContextType())) { + if (!isPageContext(refactorEntityNameDTO.getContextType()) + && !isModuleContext(refactorEntityNameDTO.getContextType())) { return Mono.empty().then(); } - Mono pageMono = refactoringMetaDTO.getPageDTOMono(); - Mono evalVersionMono = refactoringMetaDTO.getEvalVersionMono(); - Set updatedBindingPaths = refactoringMetaDTO.getUpdatedBindingPaths(); - Pattern oldNamePattern = refactoringMetaDTO.getOldNamePattern(); + CreatorContextType contextType = refactorEntityNameDTO.getContextType(); String layoutId = refactorEntityNameDTO.getLayoutId(); String oldName = refactorEntityNameDTO.getOldFullyQualifiedName(); String newName = refactorEntityNameDTO.getNewFullyQualifiedName(); - Mono pageDTOMono = Mono.zip(pageMono, evalVersionMono).flatMap(tuple -> { - PageDTO page = tuple.getT1(); - int evalVersion = tuple.getT2(); + Set updatedBindingPaths = refactoringMetaDTO.getUpdatedBindingPaths(); + Pattern oldNamePattern = refactoringMetaDTO.getOldNamePattern(); - List layouts = page.getLayouts(); - for (Layout layout : layouts) { - if (layoutId.equals(layout.getId()) && layout.getDsl() != null) { - // DSL has removed all the old names and replaced it with new name. If the change of name - // was one of the mongoEscaped widgets, then update the names in the set as well - Set mongoEscapedWidgetNames = layout.getMongoEscapedWidgetNames(); - if (mongoEscapedWidgetNames != null && mongoEscapedWidgetNames.contains(oldName)) { - mongoEscapedWidgetNames.remove(oldName); - mongoEscapedWidgetNames.add(newName); - } + // Get the appropriate context refactor service based on context type + ContextLayoutRefactoringService contextLayoutRefactorHelper = + contextLayoutRefactorResolver.getContextLayoutRefactorHelper(contextType); - final JsonNode dslNode = objectMapper.convertValue(layout.getDsl(), JsonNode.class); - Mono refactorNameInDslMono = widgetRefactorUtil - .refactorNameInDsl(dslNode, oldName, newName, evalVersion, oldNamePattern) - .flatMap(dslBindingPaths -> { - updatedBindingPaths.addAll(dslBindingPaths); - layout.setDsl(objectMapper.convertValue(dslNode, JSONObject.class)); - page.setLayouts(layouts); - refactoringMetaDTO.setUpdatedPage(page); - return Mono.just(page); - }); + // Get context DTO mono (either PageDTO or ModuleDTO) + Mono contextDTOMono = + contextLayoutRefactorHelper.getContextDTOMono(refactoringMetaDTO); - // Since the page has most probably changed, save the page and return. - return refactorNameInDslMono.flatMap(newPageService::saveUnpublishedPage); - } - } - // If we have reached here, the layout was not found and the page should be returned as is. - return Mono.just(page); - }); + return contextDTOMono + .flatMap(contextDTO -> { + String contextId = contextDTO.getId(); + Mono evalVersionMono = contextLayoutRefactorHelper.getEvaluationVersionMono( + contextId, refactorEntityNameDTO, refactoringMetaDTO); - return pageDTOMono.then(); + return evalVersionMono.flatMap(evalVersion -> { + List layouts = contextDTO.getLayouts(); + if (layouts == null) { + return Mono.just(contextDTO); + } + for (Layout layout : layouts) { + if (layoutId.equals(layout.getId()) && layout.getDsl() != null) { + // DSL has removed all the old names and replaced it with new name. If the change of + // name + // was one of the mongoEscaped widgets, then update the names in the set as well + Set mongoEscapedWidgetNames = layout.getMongoEscapedWidgetNames(); + if (mongoEscapedWidgetNames != null && mongoEscapedWidgetNames.contains(oldName)) { + mongoEscapedWidgetNames.remove(oldName); + mongoEscapedWidgetNames.add(newName); + } + + final JsonNode dslNode = objectMapper.convertValue(layout.getDsl(), JsonNode.class); + return widgetRefactorUtil + .refactorNameInDsl(dslNode, oldName, newName, evalVersion, oldNamePattern) + .flatMap(dslBindingPaths -> { + updatedBindingPaths.addAll(dslBindingPaths); + layout.setDsl(objectMapper.convertValue(dslNode, JSONObject.class)); + contextDTO.setLayouts(layouts); + contextLayoutRefactorHelper.setUpdatedContext( + refactoringMetaDTO, contextDTO); + + return contextLayoutRefactorHelper.updateContext(contextId, contextDTO); + }); + } + } + return Mono.just(contextDTO); + }); + }) + .then(); } @Override @@ -103,23 +117,26 @@ public class WidgetRefactoringServiceCEImpl implements EntityRefactoringServiceC @Override public Flux getExistingEntityNames( String contextId, CreatorContextType contextType, String layoutId, boolean viewMode) { - return newPageService - // fetch the unpublished page - .findPageById(contextId, null, viewMode) - .flatMapMany(page -> { - List layouts = page.getLayouts(); - for (Layout layout : layouts) { - if (layoutId.equals(layout.getId())) { - if (layout.getWidgetNames() != null - && layout.getWidgetNames().size() > 0) { - return Flux.fromIterable(layout.getWidgetNames()); - } - // In case of no widget names (which implies that there is no DSL), return an empty set. - return Flux.empty(); - } + Mono contextDTOMono = contextLayoutRefactorResolver + .getContextLayoutRefactorHelper(contextType) + .getContextDTOMono(contextId, viewMode); + return contextDTOMono.flatMapMany(contextDTO -> { + LayoutContainer layoutContainer = (LayoutContainer) contextDTO; + List layouts = layoutContainer.getLayouts(); + if (layouts == null) { + return Flux.empty(); + } + for (Layout layout : layouts) { + if (layoutId.equals(layout.getId())) { + if (layout.getWidgetNames() != null + && !layout.getWidgetNames().isEmpty()) { + return Flux.fromIterable(layout.getWidgetNames()); } - return Flux.error( - new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.LAYOUT_ID, layoutId)); - }); + // In case of no widget names (which implies that there is no DSL), return an empty set. + return Flux.empty(); + } + } + return Flux.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.LAYOUT_ID, layoutId)); + }); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceImpl.java index 6ea648816d..7f53225458 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/widgets/refactors/WidgetRefactoringServiceImpl.java @@ -1,9 +1,8 @@ package com.appsmith.server.widgets.refactors; import com.appsmith.server.domains.Layout; -import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.refactors.entities.EntityRefactoringService; -import com.appsmith.server.services.AstService; +import com.appsmith.server.refactors.resolver.ContextLayoutRefactorResolver; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.stereotype.Service; @@ -11,10 +10,9 @@ import org.springframework.stereotype.Service; public class WidgetRefactoringServiceImpl extends WidgetRefactoringServiceCEImpl implements EntityRefactoringService { public WidgetRefactoringServiceImpl( - NewPageService newPageService, - AstService astService, ObjectMapper objectMapper, - WidgetRefactorUtil widgetRefactorUtil) { - super(newPageService, astService, objectMapper, widgetRefactorUtil); + WidgetRefactorUtil widgetRefactorUtil, + ContextLayoutRefactorResolver contextLayoutRefactorResolver) { + super(objectMapper, widgetRefactorUtil, contextLayoutRefactorResolver); } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java index dcbfbd0aad..ac487b0460 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/refactors/ce/RefactoringServiceCEImplTest.java @@ -20,6 +20,7 @@ import com.appsmith.server.newactions.base.NewActionService; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.refactors.applications.RefactoringServiceCEImpl; import com.appsmith.server.refactors.entities.EntityRefactoringService; +import com.appsmith.server.refactors.resolver.ContextLayoutRefactorResolver; import com.appsmith.server.repositories.ActionCollectionRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; @@ -90,6 +91,9 @@ class RefactoringServiceCEImplTest { @SpyBean private EntityRefactoringService widgetEntityRefactoringService; + @SpyBean + private ContextLayoutRefactorResolver contextLayoutRefactorResolver; + @Autowired private EntityValidationService entityValidationService; @@ -101,15 +105,14 @@ class RefactoringServiceCEImplTest { refactoringServiceCE = new RefactoringServiceCEImpl( newPageService, updateLayoutService, - applicationService, - pagePermission, analyticsService, sessionUserService, entityValidationService, jsActionEntityRefactoringService, newActionEntityRefactoringService, actionCollectionEntityRefactoringService, - widgetEntityRefactoringService); + widgetEntityRefactoringService, + contextLayoutRefactorResolver); } @Test @@ -167,7 +170,7 @@ class RefactoringServiceCEImplTest { .thenReturn(Flux.empty()); Mockito.when(updateLayoutService.updateLayout( - Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any())) + Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(layout)); Mockito.doReturn(Flux.just(oldUnpublishedCollection.getName())) @@ -305,7 +308,7 @@ class RefactoringServiceCEImplTest { layout.setLayoutOnLoadActions(new ArrayList<>()); Mockito.when(updateLayoutService.updateLayout( - Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any())) + Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any())) .thenReturn(Mono.just(layout)); Mockito.doReturn(Flux.just(oldUnpublishedCollection.getName()))