From ab64bf29af025480a09e6a22fa220222f4e9c035 Mon Sep 17 00:00:00 2001 From: Anagh Hegde Date: Wed, 24 Jan 2024 13:36:19 +0530 Subject: [PATCH] fix: duplicate name issue in partial import for queries and jsobjects (#30457) ## Description When the queries and js objects are imported in the same page, the names were not updated properly which ended up with duplicate names for queries and jsobjects. This PR adds a fix which will append the number in the increasing order to avoid the duplicate entries for the above scenario. Example - jsObject will be jsObject1 #### PR fixes following issue(s) Fixes #30291 #### Type of change - Bug fix (non-breaking change which fixes an issue) ## Testing #### How Has This Been Tested? - [ ] Manual - [ ] JUnit #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed ## Summary by CodeRabbit - **New Features** - Enhanced import functionality to support partial imports, allowing users to selectively import components into their applications. - **Refactoring** - Codebase refactored to improve the clarity and efficiency of the import services. - **Tests** - Expanded test coverage to include new cases for partial imports and ensure the integrity of import operations. --- ...tionCollectionImportableServiceCEImpl.java | 34 +- .../base/ApplicationImportServiceCEImpl.java | 21 +- .../DatasourceImportableServiceCEImpl.java | 7 +- .../server/dtos/ImportingMetaDTO.java | 2 + .../ce/MappedImportableResourcesCE_DTO.java | 5 + .../importable/ImportableServiceCE.java | 7 +- .../ImportApplicationServiceCEImpl.java | 17 +- .../imports/internal/ImportServiceCEImpl.java | 5 +- .../internal/PartialImportServiceCEImpl.java | 32 +- .../internal/PartialImportServiceImpl.java | 7 +- .../CustomJSLibImportableServiceCEImpl.java | 3 +- .../NewActionImportableServiceCEImpl.java | 38 +- .../NewPageImportableServiceCEImpl.java | 6 +- .../PluginImportableServiceCEImpl.java | 7 +- .../imports/ThemeImportableServiceCEImpl.java | 7 +- .../PartialExportServiceTest.java | 10 +- .../solutions/PartialImportServiceTest.java | 446 +++++ ...portApplicationTransactionServiceTest.java | 5 +- .../partial-export-resource.json | 1650 +++++++++++------ .../partial-export-valid-without-widget.json | 189 ++ 20 files changed, 1871 insertions(+), 627 deletions(-) rename app/server/appsmith-server/src/test/java/com/appsmith/server/{services => solutions}/PartialExportServiceTest.java (97%) create mode 100644 app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialImportServiceTest.java create mode 100644 app/server/appsmith-server/src/test/resources/test_assets/ImportExportServiceTest/partial-export-valid-without-widget.json diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/imports/ActionCollectionImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/imports/ActionCollectionImportableServiceCEImpl.java index f0c541c5e1..287266f3fc 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/imports/ActionCollectionImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/actioncollections/imports/ActionCollectionImportableServiceCEImpl.java @@ -53,8 +53,7 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic MappedImportableResourcesDTO mappedImportableResourcesDTO, Mono workspaceMono, Mono applicationMono, - ApplicationJson applicationJson, - boolean isPartialImport) { + ApplicationJson applicationJson) { List importedActionCollectionList = CollectionUtils.isEmpty(applicationJson.getActionCollectionList()) ? new ArrayList<>() @@ -156,6 +155,15 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic actionCollectionsInBranchesMono = Mono.just(Collections.emptyMap()); } + // update the action name in the json to avoid duplicate names for the partial import + // It is page level action and hence the action name should be unique + if (Boolean.TRUE.equals(importingMetaDTO.getIsPartialImport()) + && mappedImportableResourcesDTO.getRefactoringNameReference() != null) { + updateActionCollectionNameBeforeMerge( + importedActionCollectionList, + mappedImportableResourcesDTO.getRefactoringNameReference()); + } + return Mono.zip(actionCollectionsInCurrentAppMono, actionCollectionsInBranchesMono) .flatMap(objects -> { Map actionsCollectionsInCurrentApp = objects.getT1(); @@ -323,6 +331,28 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic }); } + private void updateActionCollectionNameBeforeMerge( + List importedNewActionCollectionList, Set refactoringNameSet) { + + for (ActionCollection actionCollection : importedNewActionCollectionList) { + String + oldNameActionCollection = + actionCollection.getUnpublishedCollection().getName(), + newNameActionCollection = + actionCollection.getUnpublishedCollection().getName(); + int i = 1; + while (refactoringNameSet.contains(newNameActionCollection)) { + newNameActionCollection = oldNameActionCollection + i++; + } + String oldId = actionCollection.getId().split("_")[1]; + actionCollection.setId(newNameActionCollection + "_" + oldId); + actionCollection.getUnpublishedCollection().setName(newNameActionCollection); + if (actionCollection.getPublishedCollection() != null) { + actionCollection.getPublishedCollection().setName(newNameActionCollection); + } + } + } + protected Flux getCollectionsInCurrentAppFlux(Application importedApplication) { return repository.findByApplicationId(importedApplication.getId()); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationImportServiceCEImpl.java index 0cec2011f0..b0be3f4b19 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/applications/base/ApplicationImportServiceCEImpl.java @@ -250,8 +250,7 @@ public class ApplicationImportServiceCEImpl implements ApplicationImportServiceC mappedImportableResourcesDTO, workspaceMono, importedApplicationMono, - applicationJson, - false); + applicationJson); // Requires pageNameMap, pageNameToOldNameMap, pluginMap and actionResultDTO to be present in importable // resources. @@ -262,8 +261,7 @@ public class ApplicationImportServiceCEImpl implements ApplicationImportServiceC mappedImportableResourcesDTO, workspaceMono, importedApplicationMono, - applicationJson, - false); + applicationJson); Mono combinedActionImportablesMono = importedNewActionsMono.then(importedActionCollectionsMono); return List.of(combinedActionImportablesMono); @@ -443,12 +441,7 @@ public class ApplicationImportServiceCEImpl implements ApplicationImportServiceC // Persists relevant information and updates mapped resources return customJSLibImportableService.importEntities( - importingMetaDTO, - mappedImportableResourcesDTO, - null, - null, - (ApplicationJson) artifactExchangeJson, - false); + importingMetaDTO, mappedImportableResourcesDTO, null, null, (ApplicationJson) artifactExchangeJson); } @Override @@ -595,9 +588,9 @@ public class ApplicationImportServiceCEImpl implements ApplicationImportServiceC ImportingMetaDTO importingMetaDTO) { return Mono.just((Application) importableContext).flatMap(application -> { return newActionImportableService - .updateImportedEntities(application, importingMetaDTO, mappedImportableResourcesDTO, false) + .updateImportedEntities(application, importingMetaDTO, mappedImportableResourcesDTO) .then(newPageImportableService.updateImportedEntities( - application, importingMetaDTO, mappedImportableResourcesDTO, false)) + application, importingMetaDTO, mappedImportableResourcesDTO)) .thenReturn(application); }); } @@ -649,8 +642,7 @@ public class ApplicationImportServiceCEImpl implements ApplicationImportServiceC mappedImportableResourcesDTO, workspaceMono, Mono.just(application), - applicationJson, - false); + applicationJson); // Directly updates required theme information in DB Mono importedThemesMono = themeImportableService.importEntities( @@ -659,7 +651,6 @@ public class ApplicationImportServiceCEImpl implements ApplicationImportServiceC workspaceMono, Mono.just(application), applicationJson, - false, true); return Flux.merge(List.of(importedPagesMono, importedThemesMono)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/imports/DatasourceImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/imports/DatasourceImportableServiceCEImpl.java index faa879a7d2..17a4ed97e5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/imports/DatasourceImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/imports/DatasourceImportableServiceCEImpl.java @@ -63,7 +63,6 @@ public class DatasourceImportableServiceCEImpl implements ImportableServiceCE workspaceMono, Mono importContextMono, ArtifactExchangeJson importableContextJson, - boolean isPartialImport, boolean isContextAgnostic) { return importContextMono.flatMap(importableContext -> { Application application = (Application) importableContext; @@ -73,8 +72,7 @@ public class DatasourceImportableServiceCEImpl implements ImportableServiceCE workspaceMono, Mono applicationMono, - ApplicationJson applicationJson, - boolean isPartialImport) { + ApplicationJson applicationJson) { return workspaceMono.flatMap(workspace -> { final Flux existingDatasourceFlux = datasourceService .getAllByWorkspaceIdWithStorages(workspace.getId(), Optional.empty()) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportingMetaDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportingMetaDTO.java index 1cd11b253d..9d08a3de45 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportingMetaDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ImportingMetaDTO.java @@ -27,6 +27,8 @@ public class ImportingMetaDTO { */ Boolean appendToArtifact; + Boolean isPartialImport; + ImportArtifactPermissionProvider permissionProvider; Set currentUserPermissionGroups; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/MappedImportableResourcesCE_DTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/MappedImportableResourcesCE_DTO.java index d0d8d015cf..53b24a1263 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/MappedImportableResourcesCE_DTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/MappedImportableResourcesCE_DTO.java @@ -11,6 +11,7 @@ import lombok.NoArgsConstructor; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; @NoArgsConstructor @Data @@ -24,6 +25,10 @@ public class MappedImportableResourcesCE_DTO { // This attribute is re-usable across artifacts according to the needs Map pageOrModuleNewNameToOldName; + // Artifact independent, used in PartialImport + // This attribute contain set of names used/existing in page such as widgetName, action and actionCollection names + Set refactoringNameReference; + /** * Attribute used to carry objects specific to the context of the Artifacts. * In case of application it carries the NewPage entity diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/importable/ImportableServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/importable/ImportableServiceCE.java index 4397f5f922..096b0a0bfa 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/importable/ImportableServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/importable/ImportableServiceCE.java @@ -17,14 +17,12 @@ public interface ImportableServiceCE { MappedImportableResourcesDTO mappedImportableResourcesDTO, Mono workspaceMono, Mono applicationMono, - ApplicationJson applicationJson, - boolean isPartialImport); + ApplicationJson applicationJson); default Mono updateImportedEntities( Application application, ImportingMetaDTO importingMetaDTO, - MappedImportableResourcesDTO mappedImportableResourcesDTO, - boolean isPartialImport) { + MappedImportableResourcesDTO mappedImportableResourcesDTO) { return null; } @@ -34,7 +32,6 @@ public interface ImportableServiceCE { Mono workspaceMono, Mono importContextMono, ArtifactExchangeJson importableContextJson, - boolean isPartialImport, boolean isContextAgnostic) { return null; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportApplicationServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportApplicationServiceCEImpl.java index c833e135a5..e684be14f0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportApplicationServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportApplicationServiceCEImpl.java @@ -529,7 +529,7 @@ public class ImportApplicationServiceCEImpl implements ImportApplicationServiceC } ImportingMetaDTO importingMetaDTO = new ImportingMetaDTO( - workspaceId, applicationId, branchName, appendToApp, permissionProvider, permissionGroups); + workspaceId, applicationId, branchName, appendToApp, false, permissionProvider, permissionGroups); MappedImportableResourcesDTO mappedImportableResourcesDTO = new MappedImportableResourcesDTO(); @@ -578,9 +578,9 @@ public class ImportApplicationServiceCEImpl implements ImportApplicationServiceC .then(importedApplicationMono) .flatMap(application -> { return newActionImportableService - .updateImportedEntities(application, importingMetaDTO, mappedImportableResourcesDTO, false) + .updateImportedEntities(application, importingMetaDTO, mappedImportableResourcesDTO) .then(newPageImportableService.updateImportedEntities( - application, importingMetaDTO, mappedImportableResourcesDTO, false)) + application, importingMetaDTO, mappedImportableResourcesDTO)) .thenReturn(application); }) .flatMap(application -> { @@ -713,8 +713,7 @@ public class ImportApplicationServiceCEImpl implements ImportApplicationServiceC mappedImportableResourcesDTO, workspaceMono, importedApplicationMono, - applicationJson, - false); + applicationJson); // Requires pluginMap to be present in importable resources. // Updates datasourceNameToIdMap in importable resources. @@ -746,8 +745,7 @@ public class ImportApplicationServiceCEImpl implements ImportApplicationServiceC mappedImportableResourcesDTO, workspaceMono, importedApplicationMono, - applicationJson, - false); + applicationJson); // Requires pageNameMap, pageNameToOldNameMap, pluginMap and actionResultDTO to be present in importable // resources. @@ -758,8 +756,7 @@ public class ImportApplicationServiceCEImpl implements ImportApplicationServiceC mappedImportableResourcesDTO, workspaceMono, importedApplicationMono, - applicationJson, - false); + applicationJson); Mono combinedActionImportablesMono = importedNewActionsMono.then(importedActionCollectionsMono); return List.of(combinedActionImportablesMono); @@ -771,7 +768,7 @@ public class ImportApplicationServiceCEImpl implements ImportApplicationServiceC MappedImportableResourcesDTO mappedImportableResourcesDTO) { // Persists relevant information and updates mapped resources Mono installedJsLibsMono = customJSLibImportableService.importEntities( - importingMetaDTO, mappedImportableResourcesDTO, null, null, applicationJson, false); + importingMetaDTO, mappedImportableResourcesDTO, null, null, applicationJson); return installedJsLibsMono; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java index 7665e2055e..f08677cf46 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/ImportServiceCEImpl.java @@ -446,7 +446,7 @@ public class ImportServiceCEImpl implements ImportServiceCE { } ImportingMetaDTO importingMetaDTO = new ImportingMetaDTO( - workspaceId, artifactId, branchName, appendToArtifact, permissionProvider, permissionGroups); + workspaceId, artifactId, branchName, appendToArtifact, false, permissionProvider, permissionGroups); MappedImportableResourcesDTO mappedImportableResourcesDTO = new MappedImportableResourcesDTO(); contextBasedImportService.syncClientAndSchemaVersion(importedDoc); @@ -655,7 +655,6 @@ public class ImportServiceCEImpl implements ImportServiceCE { workspaceMono, importedArtifactMono, artifactExchangeJson, - false, true); // Requires pluginMap to be present in importable resources. @@ -667,7 +666,6 @@ public class ImportServiceCEImpl implements ImportServiceCE { workspaceMono, importedArtifactMono, artifactExchangeJson, - false, true)); // Directly updates required theme information in DB @@ -677,7 +675,6 @@ public class ImportServiceCEImpl implements ImportServiceCE { workspaceMono, importedArtifactMono, artifactExchangeJson, - false, true); return Flux.merge(List.of(importedDatasourcesMono, importedThemesMono)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/PartialImportServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/PartialImportServiceCEImpl.java index 2b1ffb1e10..fe2b99b129 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/PartialImportServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/PartialImportServiceCEImpl.java @@ -1,6 +1,7 @@ package com.appsmith.server.imports.internal; import com.appsmith.external.constants.AnalyticsEvents; +import com.appsmith.external.models.CreatorContextType; import com.appsmith.external.models.Datasource; import com.appsmith.server.acl.AclPermission; import com.appsmith.server.applications.base.ApplicationService; @@ -8,6 +9,7 @@ import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.ActionCollection; import com.appsmith.server.domains.Application; import com.appsmith.server.domains.CustomJSLib; +import com.appsmith.server.domains.Layout; import com.appsmith.server.domains.NewAction; import com.appsmith.server.domains.NewPage; import com.appsmith.server.domains.Plugin; @@ -21,6 +23,7 @@ import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.ce.ImportArtifactPermissionProvider; import com.appsmith.server.imports.importable.ImportableService; import com.appsmith.server.newpages.base.NewPageService; +import com.appsmith.server.refactors.applications.RefactoringService; import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; @@ -64,6 +67,7 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { private final ImportableService newActionImportableService; private final ImportableService actionCollectionImportableService; private final NewPageService newPageService; + private final RefactoringService refactoringService; @Override public Mono importResourceInPage( @@ -101,7 +105,7 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { .cache(); ImportingMetaDTO importingMetaDTO = new ImportingMetaDTO( - workspaceId, applicationId, branchName, false, permissionProvider, null); + workspaceId, applicationId, branchName, false, true, permissionProvider, null); // Get the Application from DB Mono importedApplicationMono = applicationService @@ -111,7 +115,19 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { permissionProvider.getRequiredPermissionOnTargetApplication()) .cache(); - return importedApplicationMono + return newPageService + .findByBranchNameAndDefaultPageId(branchName, pageId, AclPermission.MANAGE_PAGES) + .flatMap(page -> { + Layout layout = + page.getUnpublishedPage().getLayouts().get(0); + return refactoringService.getAllExistingEntitiesMono( + page.getId(), CreatorContextType.PAGE, layout.getId(), false); + }) + .flatMap(nameSet -> { + // Fetch name of the existing resources in the page to avoid name clashing + mappedImportableResourcesDTO.setRefactoringNameReference(nameSet); + return importedApplicationMono; + }) .flatMap(application -> { applicationJson.setExportedApplication(application); return Mono.just(applicationJson); @@ -147,9 +163,9 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { } return newActionImportableService .updateImportedEntities( - application, importingMetaDTO, mappedImportableResourcesDTO, true) + application, importingMetaDTO, mappedImportableResourcesDTO) .then(newPageImportableService.updateImportedEntities( - application, importingMetaDTO, mappedImportableResourcesDTO, true)) + application, importingMetaDTO, mappedImportableResourcesDTO)) .thenReturn(application); }); }) @@ -221,7 +237,7 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { true); Mono customJsLibMono = customJSLibImportableService.importEntities( - importingMetaDTO, mappedImportableResourcesDTO, null, null, applicationJson, true); + importingMetaDTO, mappedImportableResourcesDTO, null, null, applicationJson); return pluginMono.then(datasourceMono).then(customJsLibMono).then(); } @@ -237,16 +253,14 @@ public class PartialImportServiceCEImpl implements PartialImportServiceCE { mappedImportableResourcesDTO, workspaceMono, importedApplicationMono, - applicationJson, - true); + applicationJson); Mono actionCollectionMono = actionCollectionImportableService.importEntities( importingMetaDTO, mappedImportableResourcesDTO, workspaceMono, importedApplicationMono, - applicationJson, - true); + applicationJson); return actionMono.then(actionCollectionMono).then(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/PartialImportServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/PartialImportServiceImpl.java index 38342ed94a..de52286a29 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/PartialImportServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/imports/internal/PartialImportServiceImpl.java @@ -9,6 +9,7 @@ import com.appsmith.server.domains.NewPage; import com.appsmith.server.domains.Plugin; import com.appsmith.server.imports.importable.ImportableService; import com.appsmith.server.newpages.base.NewPageService; +import com.appsmith.server.refactors.applications.RefactoringService; import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; @@ -47,7 +48,8 @@ public class PartialImportServiceImpl extends PartialImportServiceCEImpl impleme ImportableService datasourceImportableService, ImportableService newActionImportableService, ImportableService actionCollectionImportableService, - NewPageService newPageService) { + NewPageService newPageService, + RefactoringService refactoringService) { super( importApplicationService, workspaceService, @@ -67,6 +69,7 @@ public class PartialImportServiceImpl extends PartialImportServiceCEImpl impleme datasourceImportableService, newActionImportableService, actionCollectionImportableService, - newPageService); + newPageService, + refactoringService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/imports/CustomJSLibImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/imports/CustomJSLibImportableServiceCEImpl.java index a6f6d67d29..a05597421e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/imports/CustomJSLibImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/imports/CustomJSLibImportableServiceCEImpl.java @@ -30,8 +30,7 @@ public class CustomJSLibImportableServiceCEImpl implements ImportableServiceCE workspaceMono, Mono applicationMono, - ApplicationJson applicationJson, - boolean isPartialImport) { + ApplicationJson applicationJson) { List customJSLibs = applicationJson.getCustomJSLibList(); if (customJSLibs == null) { customJSLibs = new ArrayList<>(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/imports/NewActionImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/imports/NewActionImportableServiceCEImpl.java index 1239044154..a737b58565 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/imports/NewActionImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newactions/imports/NewActionImportableServiceCEImpl.java @@ -63,8 +63,7 @@ public class NewActionImportableServiceCEImpl implements ImportableServiceCE workspaceMono, Mono applicationMono, - ApplicationJson applicationJson, - boolean isPartialImport) { + ApplicationJson applicationJson) { List importedNewActionList = applicationJson.getActionList(); @@ -104,7 +103,7 @@ public class NewActionImportableServiceCEImpl implements ImportableServiceCE invalidActionIds = new HashSet<>(); - if (Boolean.FALSE.equals(isPartialImport)) { + if (Boolean.FALSE.equals(importingMetaDTO.getIsPartialImport())) { for (NewAction action : importActionResultDTO.getExistingActions()) { if (!importActionResultDTO .getImportedActionIds() @@ -139,8 +138,7 @@ public class NewActionImportableServiceCEImpl implements ImportableServiceCE updateImportedEntities( Application application, ImportingMetaDTO importingMetaDTO, - MappedImportableResourcesDTO mappedImportableResourcesDTO, - boolean isPartialImport) { + MappedImportableResourcesDTO mappedImportableResourcesDTO) { ImportActionResultDTO importActionResultDTO = mappedImportableResourcesDTO.getActionResultDTO(); ImportActionCollectionResultDTO importActionCollectionResultDTO = @@ -162,7 +160,7 @@ public class NewActionImportableServiceCEImpl implements ImportableServiceCE invalidCollectionIds = new HashSet<>(); for (ActionCollection collection : @@ -240,6 +238,14 @@ public class NewActionImportableServiceCEImpl implements ImportableServiceCE { Map actionsInCurrentApp = objects.getT1(); @@ -422,6 +428,26 @@ public class NewActionImportableServiceCEImpl implements ImportableServiceCE importedNewActionList, Set refactoringNames) { + + for (NewAction newAction : importedNewActionList) { + String oldNameAction = newAction.getUnpublishedAction().getName(), + newNameAction = newAction.getUnpublishedAction().getName(); + int i = 1; + while (refactoringNames.contains(newNameAction)) { + newNameAction = oldNameAction + i++; + } + String oldId = newAction.getId().split("_")[1]; + newAction.setId(newNameAction + "_" + oldId); + newAction.getUnpublishedAction().setName(newNameAction); + newAction.getUnpublishedAction().setFullyQualifiedName(newNameAction); + if (newAction.getPublishedAction() != null) { + newAction.getPublishedAction().setName(newNameAction); + newAction.getPublishedAction().setFullyQualifiedName(newNameAction); + } + } + } + private void populateNewAction( ImportingMetaDTO importingMetaDTO, MappedImportableResourcesDTO mappedImportableResourcesDTO, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/imports/NewPageImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/imports/NewPageImportableServiceCEImpl.java index bf4da75d88..595beec80a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/imports/NewPageImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/newpages/imports/NewPageImportableServiceCEImpl.java @@ -68,8 +68,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE workspaceMono, Mono applicationMono, - ApplicationJson applicationJson, - boolean isPartialImport) { + ApplicationJson applicationJson) { List importedNewPageList = applicationJson.getPageList(); @@ -114,8 +113,7 @@ public class NewPageImportableServiceCEImpl implements ImportableServiceCE updateImportedEntities( Application application, ImportingMetaDTO importingMetaDTO, - MappedImportableResourcesDTO mappedImportableResourcesDTO, - boolean isPartialImport) { + MappedImportableResourcesDTO mappedImportableResourcesDTO) { ImportedActionAndCollectionMapsDTO actionAndCollectionMapsDTO = mappedImportableResourcesDTO.getActionAndCollectionMapsDTO(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/imports/PluginImportableServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/imports/PluginImportableServiceCEImpl.java index c7697f4bfd..32088df699 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/imports/PluginImportableServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/imports/PluginImportableServiceCEImpl.java @@ -35,8 +35,7 @@ public class PluginImportableServiceCEImpl implements ImportableServiceCE workspaceMono, Mono applicationMono, - ApplicationJson applicationJson, - boolean isPartialImport) { + ApplicationJson applicationJson) { return workspaceMono .map(workspace -> workspace.getPlugins().stream() .map(WorkspacePlugin::getPluginId) @@ -65,7 +64,6 @@ public class PluginImportableServiceCEImpl implements ImportableServiceCE workspaceMono, Mono importContextMono, ArtifactExchangeJson importableContextJson, - boolean isPartialImport, boolean isContextAgnostic) { return importContextMono.flatMap(importableContext -> { Application application = (Application) importableContext; @@ -75,8 +73,7 @@ public class PluginImportableServiceCEImpl implements ImportableServiceCE MappedImportableResourcesDTO mappedImportableResourcesDTO, Mono workspaceMono, Mono applicationMono, - ApplicationJson applicationJson, - boolean isPartialImport) { + ApplicationJson applicationJson) { if (Boolean.TRUE.equals(importingMetaDTO.getAppendToArtifact())) { // appending to existing app, theme should not change return Mono.empty().then(); @@ -123,7 +122,6 @@ public class ThemeImportableServiceCEImpl implements ImportableServiceCE Mono workspaceMono, Mono importContextMono, ArtifactExchangeJson importableContextJson, - boolean isPartialImport, boolean isContextAgnostic) { return importContextMono.flatMap(importableContext -> { Application application = (Application) importableContext; @@ -133,8 +131,7 @@ public class ThemeImportableServiceCEImpl implements ImportableServiceCE mappedImportableResourcesDTO, workspaceMono, Mono.just(application), - applicationJson, - isPartialImport); + applicationJson); }); } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PartialExportServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialExportServiceTest.java similarity index 97% rename from app/server/appsmith-server/src/test/java/com/appsmith/server/services/PartialExportServiceTest.java rename to app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialExportServiceTest.java index ed40c09bc0..0e275562bc 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/PartialExportServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialExportServiceTest.java @@ -1,4 +1,4 @@ -package com.appsmith.server.services; +package com.appsmith.server.solutions; import com.appsmith.external.models.ActionConfiguration; import com.appsmith.external.models.ActionDTO; @@ -30,8 +30,12 @@ import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.repositories.ThemeRepository; -import com.appsmith.server.solutions.EnvironmentPermission; -import com.appsmith.server.solutions.PagePermission; +import com.appsmith.server.services.ApplicationPageService; +import com.appsmith.server.services.LayoutActionService; +import com.appsmith.server.services.LayoutCollectionService; +import com.appsmith.server.services.PermissionGroupService; +import com.appsmith.server.services.SessionUserService; +import com.appsmith.server.services.WorkspaceService; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialImportServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialImportServiceTest.java new file mode 100644 index 0000000000..645308b074 --- /dev/null +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/PartialImportServiceTest.java @@ -0,0 +1,446 @@ +package com.appsmith.server.solutions; + +import com.appsmith.external.models.DBAuth; +import com.appsmith.external.models.Datasource; +import com.appsmith.external.models.DatasourceConfiguration; +import com.appsmith.external.models.DatasourceStorageDTO; +import com.appsmith.external.models.DefaultResources; +import com.appsmith.external.models.Property; +import com.appsmith.server.actioncollections.base.ActionCollectionService; +import com.appsmith.server.applications.base.ApplicationService; +import com.appsmith.server.datasources.base.DatasourceService; +import com.appsmith.server.domains.ActionCollection; +import com.appsmith.server.domains.Application; +import com.appsmith.server.domains.GitApplicationMetadata; +import com.appsmith.server.domains.NewAction; +import com.appsmith.server.domains.Plugin; +import com.appsmith.server.domains.User; +import com.appsmith.server.domains.Workspace; +import com.appsmith.server.dtos.PageDTO; +import com.appsmith.server.helpers.MockPluginExecutor; +import com.appsmith.server.helpers.PluginExecutorHelper; +import com.appsmith.server.imports.internal.PartialImportService; +import com.appsmith.server.newactions.base.NewActionService; +import com.appsmith.server.newpages.base.NewPageService; +import com.appsmith.server.plugins.base.PluginService; +import com.appsmith.server.repositories.ApplicationRepository; +import com.appsmith.server.repositories.CacheableRepositoryHelper; +import com.appsmith.server.repositories.PermissionGroupRepository; +import com.appsmith.server.repositories.PluginRepository; +import com.appsmith.server.repositories.ThemeRepository; +import com.appsmith.server.services.ApplicationPageService; +import com.appsmith.server.services.PermissionGroupService; +import com.appsmith.server.services.SessionUserService; +import com.appsmith.server.services.WorkspaceService; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.core.io.buffer.DefaultDataBufferFactory; +import org.springframework.http.MediaType; +import org.springframework.http.codec.multipart.FilePart; +import org.springframework.http.codec.multipart.Part; +import org.springframework.security.test.context.support.WithUserDetails; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; +import reactor.util.function.Tuple3; + +import java.time.Instant; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +@Slf4j +@ExtendWith(SpringExtension.class) +@SpringBootTest +public class PartialImportServiceTest { + + private static final Map datasourceMap = new HashMap<>(); + private static Plugin installedPlugin; + private static String workspaceId; + private static String defaultEnvironmentId; + private static String testAppId; + private static Datasource jsDatasource; + private static Plugin installedJsPlugin; + private static Boolean isSetupDone = false; + + @Autowired + private ApplicationService applicationService; + + @Autowired + private NewPageService newPageService; + + @Autowired + private SessionUserService sessionUserService; + + @Autowired + ApplicationPageService applicationPageService; + + @Autowired + PluginRepository pluginRepository; + + @Autowired + ApplicationRepository applicationRepository; + + @Autowired + DatasourceService datasourceService; + + @Autowired + WorkspaceService workspaceService; + + @MockBean + PluginExecutorHelper pluginExecutorHelper; + + @Autowired + ThemeRepository themeRepository; + + @Autowired + PermissionGroupRepository permissionGroupRepository; + + @Autowired + PermissionGroupService permissionGroupService; + + @Autowired + EnvironmentPermission environmentPermission; + + @Autowired + PagePermission pagePermission; + + @SpyBean + PluginService pluginService; + + @Autowired + CacheableRepositoryHelper cacheableRepositoryHelper; + + @Autowired + Gson gson; + + @Autowired + PartialImportService partialImportService; + + @Autowired + NewActionService newActionService; + + @Autowired + ActionCollectionService actionCollectionService; + + @BeforeEach + public void setup() { + Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())) + .thenReturn(Mono.just(new MockPluginExecutor())); + + if (Boolean.TRUE.equals(isSetupDone)) { + return; + } + User currentUser = sessionUserService.getCurrentUser().block(); + Set beforeCreatingWorkspace = + cacheableRepositoryHelper.getPermissionGroupsOfUser(currentUser).block(); + log.info("Permission Groups for User before creating workspace: {}", beforeCreatingWorkspace); + installedPlugin = pluginRepository.findByPackageName("installed-plugin").block(); + Workspace workspace = new Workspace(); + workspace.setName("Import-Export-Test-Workspace"); + Workspace savedWorkspace = workspaceService.create(workspace).block(); + workspaceId = savedWorkspace.getId(); + defaultEnvironmentId = workspaceService + .getDefaultEnvironmentId(workspaceId, environmentPermission.getExecutePermission()) + .block(); + Set afterCreatingWorkspace = + cacheableRepositoryHelper.getPermissionGroupsOfUser(currentUser).block(); + log.info("Permission Groups for User after creating workspace: {}", afterCreatingWorkspace); + + log.info("Workspace ID: {}", workspaceId); + log.info("Workspace Role Ids: {}", workspace.getDefaultPermissionGroups()); + log.info("Policy for created Workspace: {}", workspace.getPolicies()); + log.info("Current User ID: {}", currentUser.getId()); + + Application testApplication = new Application(); + testApplication.setName("Export-Application-Test-Application"); + testApplication.setWorkspaceId(workspaceId); + testApplication.setUpdatedAt(Instant.now()); + testApplication.setLastDeployedAt(Instant.now()); + testApplication.setModifiedBy("some-user"); + testApplication.setGitApplicationMetadata(new GitApplicationMetadata()); + + Application savedApplication = applicationPageService + .createApplication(testApplication, workspaceId) + .block(); + testAppId = savedApplication.getId(); + + Datasource ds1 = new Datasource(); + ds1.setName("DS1"); + ds1.setWorkspaceId(workspaceId); + ds1.setPluginId(installedPlugin.getId()); + final DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration(); + datasourceConfiguration.setUrl("http://example.org/get"); + datasourceConfiguration.setHeaders(List.of(new Property("X-Answer", "42"))); + + HashMap storages1 = new HashMap<>(); + storages1.put( + defaultEnvironmentId, new DatasourceStorageDTO(null, defaultEnvironmentId, datasourceConfiguration)); + ds1.setDatasourceStorages(storages1); + + Datasource ds2 = new Datasource(); + ds2.setName("DS2"); + ds2.setPluginId(installedPlugin.getId()); + ds2.setWorkspaceId(workspaceId); + DatasourceConfiguration datasourceConfiguration2 = new DatasourceConfiguration(); + DBAuth auth = new DBAuth(); + auth.setPassword("awesome-password"); + datasourceConfiguration2.setAuthentication(auth); + HashMap storages2 = new HashMap<>(); + storages2.put( + defaultEnvironmentId, new DatasourceStorageDTO(null, defaultEnvironmentId, datasourceConfiguration2)); + ds2.setDatasourceStorages(storages2); + + jsDatasource = new Datasource(); + jsDatasource.setName("Default JS datasource"); + jsDatasource.setWorkspaceId(workspaceId); + installedJsPlugin = + pluginRepository.findByPackageName("installed-js-plugin").block(); + assert installedJsPlugin != null; + jsDatasource.setPluginId(installedJsPlugin.getId()); + + ds1 = datasourceService.create(ds1).block(); + ds2 = datasourceService.create(ds2).block(); + datasourceMap.put("DS1", ds1); + datasourceMap.put("DS2", ds2); + isSetupDone = true; + } + + private Application createGitConnectedApp(String applicationName) { + // Create application connected to git + Application testApplication = new Application(); + testApplication.setName(applicationName); + testApplication.setWorkspaceId(workspaceId); + testApplication.setUpdatedAt(Instant.now()); + testApplication.setLastDeployedAt(Instant.now()); + testApplication.setModifiedBy("some-user"); + testApplication.setGitApplicationMetadata(new GitApplicationMetadata()); + GitApplicationMetadata gitData = new GitApplicationMetadata(); + gitData.setBranchName("master"); + gitData.setDefaultBranchName("master"); + testApplication.setGitApplicationMetadata(gitData); + + return applicationPageService + .createApplication(testApplication, workspaceId) + .flatMap(application1 -> { + application1.getGitApplicationMetadata().setDefaultApplicationId(application1.getId()); + return applicationService.save(application1); + }) + .block(); + } + + private FilePart createFilePart(String filePath) { + FilePart filepart = Mockito.mock(FilePart.class, Mockito.RETURNS_DEEP_STUBS); + Flux dataBufferFlux = DataBufferUtils.read( + new ClassPathResource(filePath), new DefaultDataBufferFactory(), 4096) + .cache(); + + Mockito.when(filepart.content()).thenReturn(dataBufferFlux); + Mockito.when(filepart.headers().getContentType()).thenReturn(MediaType.APPLICATION_JSON); + + return filepart; + } + + @Test + @WithUserDetails(value = "api_user") + public void testPartialImport_nonGitConnectedApp_success() { + + // Create an application with all resources + Application testApplication = new Application(); + testApplication.setName("testPartialImport_nonGitConnectedApp_success"); + testApplication.setWorkspaceId(workspaceId); + + testApplication = applicationPageService + .createApplication(testApplication, workspaceId) + .block(); + + String pageId = newPageService + .findById(testApplication.getPages().get(0).getId(), Optional.empty()) + .block() + .getId(); + + Part filePart = createFilePart("test_assets/ImportExportServiceTest/partial-export-resource.json"); + + Mono, List>> result = partialImportService + .importResourceInPage(workspaceId, testApplication.getId(), pageId, null, filePart) + .flatMap(application -> { + Mono> actionList = newActionService + .findByPageId(pageId, Optional.empty()) + .collectList(); + Mono> actionCollectionList = + actionCollectionService.findByPageId(pageId).collectList(); + + return Mono.zip(Mono.just(application), actionList, actionCollectionList); + }); + + StepVerifier.create(result) + .assertNext(object -> { + Application application = object.getT1(); + List actionList = object.getT2(); + List actionCollectionList = object.getT3(); + + // Verify that the application has the imported resource + assertThat(application.getPages().size()).isEqualTo(1); + + assertThat(actionCollectionList.size()).isEqualTo(1); + assertThat(actionCollectionList + .get(0) + .getUnpublishedCollection() + .getName()) + .isEqualTo("utils"); + assertThat(actionList.size()).isEqualTo(4); + Set actionNames = Set.of("DeleteQuery", "UpdateQuery", "SelectQuery", "InsertQuery"); + actionList.forEach(action -> { + assertThat(actionNames.contains( + action.getUnpublishedAction().getName())) + .isTrue(); + }); + }) + .verifyComplete(); + } + + @Test + @WithUserDetails(value = "api_user") + public void testPartialImport_gitConnectedAppDefaultBranch_success() { + Application application = createGitConnectedApp("testPartialImport_gitConnectedAppDefaultBranch_success"); + + // update git branch name for page + PageDTO savedPage = new PageDTO(); + savedPage.setName("Page 2"); + savedPage.setApplicationId(application.getId()); + DefaultResources defaultResources = new DefaultResources(); + defaultResources.setApplicationId(application.getId()); + defaultResources.setBranchName("master"); + savedPage.setDefaultResources(defaultResources); + savedPage = applicationPageService + .createPageWithBranchName(savedPage, "master") + .block(); + + Part filePart = createFilePart("test_assets/ImportExportServiceTest/partial-export-valid-without-widget.json"); + + PageDTO finalSavedPage = savedPage; + Mono, List>> result = partialImportService + .importResourceInPage(workspaceId, application.getId(), savedPage.getId(), "master", filePart) + .flatMap(application1 -> { + Mono> actionList = newActionService + .findByPageId(finalSavedPage.getId(), Optional.empty()) + .collectList(); + Mono> actionCollectionList = actionCollectionService + .findByPageId(finalSavedPage.getId()) + .collectList(); + return Mono.zip(Mono.just(application1), actionList, actionCollectionList); + }); + + StepVerifier.create(result) + .assertNext(object -> { + Application application1 = object.getT1(); + List actionList = object.getT2(); + List actionCollectionList = object.getT3(); + + // Verify that the application has the imported resource + assertThat(application1.getPages().size()).isEqualTo(2); + + assertThat(application1.getUnpublishedCustomJSLibs().size()).isEqualTo(1); + + assertThat(actionCollectionList.size()).isEqualTo(1); + assertThat(actionCollectionList + .get(0) + .getUnpublishedCollection() + .getName()) + .isEqualTo("Github_Transformer"); + assertThat(actionList.size()).isEqualTo(1); + Set actionNames = Set.of("get_force_roster"); + actionList.forEach(action -> { + assertThat(actionNames.contains( + action.getUnpublishedAction().getName())) + .isTrue(); + }); + }) + .verifyComplete(); + } + + @Test + @WithUserDetails(value = "api_user") + public void testPartialImport_nameClashInAction_successWithNoNameDuplicates() { + + // Create an application with all resources + Application testApplication = new Application(); + testApplication.setName("testPartialImport_nameClashInAction_successWithNoNameDuplicates"); + testApplication.setWorkspaceId(workspaceId); + + testApplication = applicationPageService + .createApplication(testApplication, workspaceId) + .block(); + + String pageId = newPageService + .findById(testApplication.getPages().get(0).getId(), Optional.empty()) + .block() + .getId(); + + Part filePart = createFilePart("test_assets/ImportExportServiceTest/partial-export-resource.json"); + + Mono, List>> result = partialImportService + .importResourceInPage(workspaceId, testApplication.getId(), pageId, null, filePart) + .then(partialImportService.importResourceInPage( + workspaceId, testApplication.getId(), pageId, null, filePart)) + .flatMap(application -> { + Mono> actionList = newActionService + .findByPageId(pageId, Optional.empty()) + .collectList(); + Mono> actionCollectionList = + actionCollectionService.findByPageId(pageId).collectList(); + + return Mono.zip(Mono.just(application), actionList, actionCollectionList); + }); + + StepVerifier.create(result) + .assertNext(object -> { + Application application = object.getT1(); + List actionList = object.getT2(); + List actionCollectionList = object.getT3(); + + // Verify that the application has the imported resource + assertThat(application.getPages().size()).isEqualTo(1); + + assertThat(actionCollectionList.size()).isEqualTo(2); + Set nameList = Set.of("utils", "utils1"); + actionCollectionList.forEach(collection -> { + assertThat(nameList.contains( + collection.getUnpublishedCollection().getName())) + .isTrue(); + }); + assertThat(actionList.size()).isEqualTo(8); + Set actionNames = Set.of( + "DeleteQuery", + "UpdateQuery", + "SelectQuery", + "InsertQuery", + "DeleteQuery1", + "UpdateQuery1", + "SelectQuery1", + "InsertQuery1"); + actionList.forEach(action -> { + assertThat(actionNames.contains( + action.getUnpublishedAction().getName())) + .isTrue(); + }); + }) + .verifyComplete(); + } +} diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/transactions/ImportApplicationTransactionServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/transactions/ImportApplicationTransactionServiceTest.java index 9bbf793b12..83aea2a41d 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/transactions/ImportApplicationTransactionServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/transactions/ImportApplicationTransactionServiceTest.java @@ -45,7 +45,6 @@ import reactor.test.StepVerifier; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; // All the test case are for failure or exception. Test cases for valid json file is already present in // ImportExportApplicationServiceTest class @@ -138,7 +137,7 @@ public class ImportApplicationTransactionServiceTest { Workspace newWorkspace = new Workspace(); newWorkspace.setName("Template Workspace"); - Mockito.when(newActionImportableService.importEntities(any(), any(), any(), any(), any(), anyBoolean())) + Mockito.when(newActionImportableService.importEntities(any(), any(), any(), any(), any())) .thenReturn(Mono.error(new AppsmithException(AppsmithError.GENERIC_BAD_REQUEST))); Workspace createdWorkspace = workspaceService.create(newWorkspace).block(); @@ -169,7 +168,7 @@ public class ImportApplicationTransactionServiceTest { Workspace newWorkspace = new Workspace(); newWorkspace.setName("Template Workspace"); - Mockito.when(newActionImportableService.importEntities(any(), any(), any(), any(), any(), anyBoolean())) + Mockito.when(newActionImportableService.importEntities(any(), any(), any(), any(), any())) .thenReturn(Mono.error(new MongoTransactionException( "Command failed with error 251 (NoSuchTransaction): 'Transaction 1 has been aborted.'"))); diff --git a/app/server/appsmith-server/src/test/resources/test_assets/ImportExportServiceTest/partial-export-resource.json b/app/server/appsmith-server/src/test/resources/test_assets/ImportExportServiceTest/partial-export-resource.json index dd48c4aad0..5b04a12691 100644 --- a/app/server/appsmith-server/src/test/resources/test_assets/ImportExportServiceTest/partial-export-resource.json +++ b/app/server/appsmith-server/src/test/resources/test_assets/ImportExportServiceTest/partial-export-resource.json @@ -1,596 +1,789 @@ { "clientSchemaVersion": 1, "serverSchemaVersion": 7, + "datasourceList": [ + { + "datasourceConfiguration": {}, + "name": "Sheets", + "pluginId": "google-sheets-plugin", + "messages": [], + "isAutoGenerated": false, + "isTemplate": true, + "isValid": true, + "embedded": false, + "new": true + } + ], "actionList": [ { - "id": "Send Messages_SendEmail", - "pluginType": "DB", - "pluginId": "smtp-plugin", + "id": "Investors_DeleteQuery", + "pluginType": "SAAS", + "pluginId": "google-sheets-plugin", "unpublishedAction": { - "name": "SendEmail", + "name": "DeleteQuery", "datasource": { + "id": "Sheets", "userPermissions": [], - "pluginId": "smtp-plugin", + "name": "Sheets", + "pluginId": "google-sheets-plugin", "messages": [], "isValid": true, - "new": true + "new": false }, - "pageId": "Send Messages", + "pageId": "Investors", "actionConfiguration": { "timeoutInMillisecond": 10000, "paginationType": "NONE", "encodeParamsToggle": true, - "body": "{{EmailText.text}}", "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [ + { + "key": "method", + "value": "DELETE_ROW" + }, + { + "key": "sheetUrl", + "value": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit#gid=0" + }, + { + "key": "range", + "value": "" + }, + { + "key": "spreadsheetName", + "value": "" + }, + { + "key": "tableHeaderIndex", + "value": "1" + }, + { + "key": "queryFormat", + "value": "ROWS" + }, + { + "key": "rowLimit", + "value": "{{data_table.pageSize}}" + }, + { + "key": "sheetName", + "value": "Investor Details" + }, + { + "key": "rowOffset", + "value": "{{(data_table.pageNo - 1) * data_table.pageSize}}" + }, + { + "key": "rowObject" + }, + { + "key": "rowObjects" + }, + { + "key": "rowIndex", + "value": "{{data_table.triggeredRow.rowIndex}}" + }, + { + "key": "deleteFormat", + "value": "SHEET" + }, + { + "key": "smartSubstitution", + "value": false + } + ], "formData": { - "command": "SEND", - "send": { - "from": "appsmithtemp@gmail.com", - "to": "kocharrahul8@gmail.com,{{Utils.get()}}", - "subject": "Communication Sent Via Appsmith" + "tableHeaderIndex": { + "data": "1", + "viewType": "component", + "componentData": "1" + }, + "pagination": { + "data": { + "offset": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "limit": "{{data_table.pageSize}}" + }, + "viewType": "component", + "componentData": { + "offset": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "limit": "{{data_table.pageSize}}" + } + }, + "sheetName": { + "data": "Investor Details", + "viewType": "component", + "componentData": "Investor Details" + }, + "entityType": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "rowIndex": { + "data": "{{data_table.triggeredRow.rowIndex}}", + "viewType": "component", + "componentData": "{{data_table.triggeredRow.rowIndex}}" + }, + "sheetUrl": { + "data": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit", + "viewType": "component", + "componentData": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit" + }, + "command": { + "data": "DELETE_ONE", + "viewType": "component", + "componentData": "DELETE_ONE" + }, + "smartSubstitution": { + "data": false, + "viewType": "component", + "componentData": false + }, + "queryFormat": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "projection": { + "data": [] + }, + "range": { + "data": "" } } }, "executeOnLoad": false, - "dynamicBindingPathList": [ - { - "key": "body" - }, - { - "key": "formData.send.to" - } - ], + "dynamicBindingPathList": [], "isValid": true, "invalids": [], "messages": [], "jsonPathKeys": [ - "EmailText.text", - "Utils.get()" + "data_table.pageSize", + "data_table.triggeredRow.rowIndex", + "(data_table.pageNo - 1) * data_table.pageSize" ], "confirmBeforeExecute": false, "userPermissions": [], - "validName": "SendEmail", - "configurationPath": "SendEmail.actionConfiguration", - "executableConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "body": "{{EmailText.text}}", - "selfReferencingDataPaths": [], - "formData": { - "command": "SEND", - "send": { - "from": "appsmithtemp@gmail.com", - "to": "kocharrahul8@gmail.com,{{Utils.get()}}", - "subject": "Communication Sent Via Appsmith" - } - } - }, - "selfReferencingDataPaths": [], - "dslExecutable": { - "name": "SendEmail", - "confirmBeforeExecute": false, - "jsonPathKeys": [ - "EmailText.text", - "Utils.get()" - ], - "timeoutInMillisecond": 10000 - } + "validName": "DeleteQuery", + "selfReferencingDataPaths": [] }, "publishedAction": { - "name": "SendEmail", + "name": "DeleteQuery", "datasource": { + "id": "Sheets", "userPermissions": [], - "pluginId": "smtp-plugin", + "name": "Sheets", + "pluginId": "google-sheets-plugin", "messages": [], "isValid": true, - "new": true + "new": false }, - "pageId": "Send Messages", + "pageId": "Investors", "actionConfiguration": { "timeoutInMillisecond": 10000, "paginationType": "NONE", "encodeParamsToggle": true, - "body": "{{EmailText.text}}", "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [ + { + "key": "method", + "value": "DELETE_ROW" + }, + { + "key": "sheetUrl", + "value": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit#gid=0" + }, + { + "key": "range", + "value": "" + }, + { + "key": "spreadsheetName", + "value": "" + }, + { + "key": "tableHeaderIndex", + "value": "1" + }, + { + "key": "queryFormat", + "value": "ROWS" + }, + { + "key": "rowLimit", + "value": "{{data_table.pageSize}}" + }, + { + "key": "sheetName", + "value": "Investor Details" + }, + { + "key": "rowOffset", + "value": "{{(data_table.pageNo - 1) * data_table.pageSize}}" + }, + { + "key": "rowObject" + }, + { + "key": "rowObjects" + }, + { + "key": "rowIndex", + "value": "{{data_table.triggeredRow.rowIndex}}" + }, + { + "key": "deleteFormat", + "value": "SHEET" + }, + { + "key": "smartSubstitution", + "value": false + } + ], "formData": { - "command": "SEND", - "send": { - "from": "appsmithtemp@gmail.com", - "to": "kocharrahul8@gmail.com,{{Utils.get()}}", - "subject": "Communication Sent Via Appsmith" + "tableHeaderIndex": { + "data": "1", + "viewType": "component", + "componentData": "1" + }, + "pagination": { + "data": { + "offset": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "limit": "{{data_table.pageSize}}" + }, + "viewType": "component", + "componentData": { + "offset": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "limit": "{{data_table.pageSize}}" + } + }, + "sheetName": { + "data": "Investor Details", + "viewType": "component", + "componentData": "Investor Details" + }, + "entityType": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "rowIndex": { + "data": "{{data_table.triggeredRow.rowIndex}}", + "viewType": "component", + "componentData": "{{data_table.triggeredRow.rowIndex}}" + }, + "sheetUrl": { + "data": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit", + "viewType": "component", + "componentData": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit" + }, + "command": { + "data": "DELETE_ONE", + "viewType": "component", + "componentData": "DELETE_ONE" + }, + "smartSubstitution": { + "data": false, + "viewType": "component", + "componentData": false + }, + "queryFormat": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "projection": { + "data": [] + }, + "range": { + "data": "" } } }, "executeOnLoad": false, - "dynamicBindingPathList": [ - { - "key": "body" - }, - { - "key": "formData.send.to" - } - ], + "dynamicBindingPathList": [], "isValid": true, "invalids": [], "messages": [], "jsonPathKeys": [ - "EmailText.text", - "Utils.get()" + "data_table.pageSize", + "data_table.triggeredRow.rowIndex", + "(data_table.pageNo - 1) * data_table.pageSize" ], "confirmBeforeExecute": false, "userPermissions": [], - "validName": "SendEmail", - "configurationPath": "SendEmail.actionConfiguration", - "executableConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "body": "{{EmailText.text}}", - "selfReferencingDataPaths": [], - "formData": { - "command": "SEND", - "send": { - "from": "appsmithtemp@gmail.com", - "to": "kocharrahul8@gmail.com,{{Utils.get()}}", - "subject": "Communication Sent Via Appsmith" - } - } - }, - "selfReferencingDataPaths": [], - "dslExecutable": { - "name": "SendEmail", - "confirmBeforeExecute": false, - "jsonPathKeys": [ - "EmailText.text", - "Utils.get()" - ], - "timeoutInMillisecond": 10000 - } + "validName": "DeleteQuery", + "selfReferencingDataPaths": [] }, "new": false }, { - "id": "Send Messages_DiscordAPI", - "pluginType": "API", - "pluginId": "restapi-plugin", + "id": "Investors_UpdateQuery", + "pluginType": "SAAS", + "pluginId": "google-sheets-plugin", "unpublishedAction": { - "name": "DiscordAPI", + "name": "UpdateQuery", "datasource": { + "id": "Sheets", "userPermissions": [], - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { - "url": "{{List1.selectedItem.Discord_Webhook}}" - }, - "invalids": [], + "name": "Sheets", + "pluginId": "google-sheets-plugin", "messages": [], "isValid": true, - "new": true + "new": false }, - "pageId": "Send Messages", + "pageId": "Investors", "actionConfiguration": { "timeoutInMillisecond": 10000, "paginationType": "NONE", - "path": "", - "headers": [ - { - "key": "content-type", - "value": "application/json" - } - ], "encodeParamsToggle": true, - "queryParameters": [], - "body": "{\n\"content\" : {{DiscordText.text}}\n}", - "httpMethod": "POST", "selfReferencingDataPaths": [], "pluginSpecifiedTemplates": [ { - "value": true + "key": "method", + "value": "UPDATE" + }, + { + "key": "sheetUrl", + "value": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit#gid=0" + }, + { + "key": "range", + "value": "" + }, + { + "key": "spreadsheetName", + "value": "" + }, + { + "key": "tableHeaderIndex", + "value": "1" + }, + { + "key": "queryFormat", + "value": "ROWS" + }, + { + "key": "rowLimit", + "value": "" + }, + { + "key": "sheetName", + "value": "Investor Details" + }, + { + "key": "rowOffset", + "value": "" + }, + { + "key": "rowObject", + "value": "{\n\t \"rowIndex\": {{data_table.selectedItem.rowIndex}}, \n\t\t\"interestLevel\": \"{{Rating1Copy.value}}\", \n\t\t\"website\": \"{{colInput2Copy.text}}\", \n\t\t\"address\": \"{{colInput3Copy.text}}\", \n\t\t\"topInvestments\": \"{{colInput4Copy.text}}\"\n}" + }, + { + "key": "rowObjects" + }, + { + "key": "rowIndex", + "value": "" + }, + { + "key": "deleteFormat", + "value": "SHEET" + }, + { + "key": "smartSubstitution", + "value": false + }, + { + "key": "where", + "value": [ + {} + ] } - ] + ], + "formData": { + "rowObjects": { + "data": "{\n\t \"rowIndex\": {{data_table.selectedItem.rowIndex}}, \n\t\t\"interestLevel\": \"{{Rating1Copy.value}}\", \n\t\t\"website\": \"{{colInput2Copy.text}}\", \n\t\t\"address\": \"{{colInput3Copy.text}}\", \n\t\t\"topInvestments\": \"{{colInput4Copy.text}}\"\n}", + "viewType": "component", + "componentData": "{\n\t \"rowIndex\": {{data_table.selectedItem.rowIndex}}, \n\t\t\"interestLevel\": \"{{Rating1Copy.value}}\", \n\t\t\"website\": \"{{colInput2Copy.text}}\", \n\t\t\"address\": \"{{colInput3Copy.text}}\", \n\t\t\"topInvestments\": \"{{colInput4Copy.text}}\"\n}" + }, + "tableHeaderIndex": { + "data": "1", + "viewType": "component", + "componentData": "1" + }, + "sheetName": { + "data": "Investor Details", + "viewType": "component", + "componentData": "Investor Details" + }, + "entityType": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "where": { + "data": { + "condition": "AND" + }, + "viewType": "component", + "componentData": { + "condition": "AND" + } + }, + "sheetUrl": { + "data": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit", + "viewType": "component", + "componentData": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit" + }, + "command": { + "data": "UPDATE_ONE", + "viewType": "component", + "componentData": "UPDATE_ONE" + }, + "smartSubstitution": { + "data": false, + "viewType": "component", + "componentData": false + }, + "queryFormat": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "projection": { + "data": [] + } + } }, "executeOnLoad": false, - "dynamicBindingPathList": [ - { - "key": "body" - }, - { - "key": "datasourceUrl" - } - ], + "dynamicBindingPathList": [], "isValid": true, "invalids": [], "messages": [], "jsonPathKeys": [ - "DiscordText.text", - "List1.selectedItem.Discord_Webhook" + "colInput3Copy.text", + "data_table.selectedItem.rowIndex", + "Rating1Copy.value", + "colInput2Copy.text", + "colInput4Copy.text" ], "confirmBeforeExecute": false, "userPermissions": [], - "validName": "DiscordAPI", - "configurationPath": "DiscordAPI.actionConfiguration", - "executableConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "path": "", - "headers": [ - { - "key": "content-type", - "value": "application/json" - } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{\n\"content\" : {{DiscordText.text}}\n}", - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [ - { - "value": true - } - ] - }, - "selfReferencingDataPaths": [], - "dslExecutable": { - "name": "DiscordAPI", - "confirmBeforeExecute": false, - "jsonPathKeys": [ - "DiscordText.text", - "List1.selectedItem.Discord_Webhook" - ], - "timeoutInMillisecond": 10000 - } + "validName": "UpdateQuery", + "selfReferencingDataPaths": [] }, "publishedAction": { - "name": "DiscordAPI", + "name": "UpdateQuery", "datasource": { + "id": "Sheets", "userPermissions": [], - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { - "url": "{{List1.selectedItem.Discord_Webhook}}" - }, - "invalids": [], + "name": "Sheets", + "pluginId": "google-sheets-plugin", "messages": [], "isValid": true, - "new": true + "new": false }, - "pageId": "Send Messages", + "pageId": "Investors", "actionConfiguration": { "timeoutInMillisecond": 10000, "paginationType": "NONE", - "path": "", - "headers": [ - { - "key": "content-type", - "value": "application/json" - } - ], "encodeParamsToggle": true, - "queryParameters": [], - "body": "{\n\"content\" : {{DiscordText.text}}\n}", - "httpMethod": "POST", "selfReferencingDataPaths": [], "pluginSpecifiedTemplates": [ { - "value": true + "key": "method", + "value": "UPDATE" + }, + { + "key": "sheetUrl", + "value": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit#gid=0" + }, + { + "key": "range", + "value": "" + }, + { + "key": "spreadsheetName", + "value": "" + }, + { + "key": "tableHeaderIndex", + "value": "1" + }, + { + "key": "queryFormat", + "value": "ROWS" + }, + { + "key": "rowLimit", + "value": "" + }, + { + "key": "sheetName", + "value": "Investor Details" + }, + { + "key": "rowOffset", + "value": "" + }, + { + "key": "rowObject", + "value": "{\n\t \"rowIndex\": {{data_table.selectedItem.rowIndex}}, \n\t\t\"interestLevel\": \"{{Rating1Copy.value}}\", \n\t\t\"website\": \"{{colInput2Copy.text}}\", \n\t\t\"address\": \"{{colInput3Copy.text}}\", \n\t\t\"topInvestments\": \"{{colInput4Copy.text}}\"\n}" + }, + { + "key": "rowObjects" + }, + { + "key": "rowIndex", + "value": "" + }, + { + "key": "deleteFormat", + "value": "SHEET" + }, + { + "key": "smartSubstitution", + "value": false + }, + { + "key": "where", + "value": [ + {} + ] } - ] + ], + "formData": { + "rowObjects": { + "data": "{\n\t \"rowIndex\": {{data_table.selectedItem.rowIndex}}, \n\t\t\"interestLevel\": \"{{Rating1Copy.value}}\", \n\t\t\"website\": \"{{colInput2Copy.text}}\", \n\t\t\"address\": \"{{colInput3Copy.text}}\", \n\t\t\"topInvestments\": \"{{colInput4Copy.text}}\"\n}", + "viewType": "component", + "componentData": "{\n\t \"rowIndex\": {{data_table.selectedItem.rowIndex}}, \n\t\t\"interestLevel\": \"{{Rating1Copy.value}}\", \n\t\t\"website\": \"{{colInput2Copy.text}}\", \n\t\t\"address\": \"{{colInput3Copy.text}}\", \n\t\t\"topInvestments\": \"{{colInput4Copy.text}}\"\n}" + }, + "tableHeaderIndex": { + "data": "1", + "viewType": "component", + "componentData": "1" + }, + "sheetName": { + "data": "Investor Details", + "viewType": "component", + "componentData": "Investor Details" + }, + "entityType": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "where": { + "data": { + "condition": "AND" + }, + "viewType": "component", + "componentData": { + "condition": "AND" + } + }, + "sheetUrl": { + "data": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit", + "viewType": "component", + "componentData": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit" + }, + "command": { + "data": "UPDATE_ONE", + "viewType": "component", + "componentData": "UPDATE_ONE" + }, + "smartSubstitution": { + "data": false, + "viewType": "component", + "componentData": false + }, + "queryFormat": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "projection": { + "data": [] + } + } }, "executeOnLoad": false, - "dynamicBindingPathList": [ - { - "key": "body" - }, - { - "key": "datasourceUrl" - } - ], + "dynamicBindingPathList": [], "isValid": true, "invalids": [], "messages": [], "jsonPathKeys": [ - "DiscordText.text", - "List1.selectedItem.Discord_Webhook" + "colInput3Copy.text", + "data_table.selectedItem.rowIndex", + "Rating1Copy.value", + "colInput2Copy.text", + "colInput4Copy.text" ], "confirmBeforeExecute": false, "userPermissions": [], - "validName": "DiscordAPI", - "configurationPath": "DiscordAPI.actionConfiguration", - "executableConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "path": "", - "headers": [ - { - "key": "content-type", - "value": "application/json" - } - ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "{\n\"content\" : {{DiscordText.text}}\n}", - "httpMethod": "POST", - "selfReferencingDataPaths": [], - "pluginSpecifiedTemplates": [ - { - "value": true - } - ] - }, - "selfReferencingDataPaths": [], - "dslExecutable": { - "name": "DiscordAPI", - "confirmBeforeExecute": false, - "jsonPathKeys": [ - "DiscordText.text", - "List1.selectedItem.Discord_Webhook" - ], - "timeoutInMillisecond": 10000 - } + "validName": "UpdateQuery", + "selfReferencingDataPaths": [] }, "new": false }, { - "id": "Send Messages_AddNewList", - "pluginType": "DB", - "pluginId": "mongo-plugin", + "id": "Investors_SelectQuery", + "pluginType": "SAAS", + "pluginId": "google-sheets-plugin", "unpublishedAction": { - "name": "AddNewList", + "name": "SelectQuery", "datasource": { + "id": "Sheets", "userPermissions": [], - "pluginId": "mongo-plugin", + "name": "Sheets", + "pluginId": "google-sheets-plugin", "messages": [], "isValid": true, - "new": true + "new": false }, - "pageId": "Send Messages", + "pageId": "Investors", "actionConfiguration": { "timeoutInMillisecond": 10000, "paginationType": "NONE", "encodeParamsToggle": true, "selfReferencingDataPaths": [], - "formData": { - "insert": { - "documents": { - "data": "\n{\"Discord_Webhook\":{{Webhook.text}}\n\"Mailinglist\":{{List_Name.text}}\n\"MailinglistID\":{{List_ID.text}}\n\"Icon\":{{Icon.text}}\n\"Users\":{{Table2.selectedRows.map(a => a.CustomerID)}}\n\"CreationDate\": ISODate({{moment().format('YYYY-MM-DDT00:00:00.000Z')}})\n}", - "viewType": "component", - "componentData": "\n{\"Discord_Webhook\":{{Webhook.text}}\n\"Mailinglist\":{{List_Name.text}}\n\"MailinglistID\":{{List_ID.text}}\n\"Icon\":{{Icon.text}}\n\"Users\":{{Table2.selectedRows.map(a => a.CustomerID)}}\n\"CreationDate\": ISODate({{moment().format('YYYY-MM-DDT00:00:00.000Z')}})\n}" - } + "pluginSpecifiedTemplates": [ + { + "key": "method", + "value": "GET" }, - "collection": { - "data": "MailingList", - "viewType": "component", - "componentData": "MailingList" + { + "key": "sheetUrl", + "value": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit#gid=0" }, - "command": { - "data": "INSERT", - "viewType": "component", - "componentData": "INSERT" + { + "key": "range", + "value": "" }, - "smartSubstitution": { - "data": true, - "viewType": "component", - "componentData": true + { + "key": "spreadsheetName", + "value": "" + }, + { + "key": "tableHeaderIndex", + "value": "1" + }, + { + "key": "queryFormat", + "value": "ROWS" + }, + { + "key": "rowLimit", + "value": "5" + }, + { + "key": "sheetName", + "value": "Investor Details" + }, + { + "key": "rowOffset", + "value": "{{(data_table.pageNo - 1) * data_table.pageSize}}" + }, + { + "key": "rowObject" + }, + { + "key": "rowObjects" + }, + { + "key": "rowIndex", + "value": "" + }, + { + "key": "deleteFormat", + "value": "SHEET" + }, + { + "key": "smartSubstitution", + "value": false + }, + { + "key": "where", + "value": [ + {} + ] } - } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { - "key": "formData.insert.documents.data" - } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "List_Name.text", - "List_ID.text", - "Webhook.text", - "Table2.selectedRows.map(a => a.CustomerID)", - "Icon.text", - "moment().format('YYYY-MM-DDT00:00:00.000Z')" - ], - "confirmBeforeExecute": false, - "userPermissions": [], - "validName": "AddNewList", - "configurationPath": "AddNewList.actionConfiguration", - "executableConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "selfReferencingDataPaths": [], - "formData": { - "insert": { - "documents": { - "data": "\n{\"Discord_Webhook\":{{Webhook.text}}\n\"Mailinglist\":{{List_Name.text}}\n\"MailinglistID\":{{List_ID.text}}\n\"Icon\":{{Icon.text}}\n\"Users\":{{Table2.selectedRows.map(a => a.CustomerID)}}\n\"CreationDate\": ISODate({{moment().format('YYYY-MM-DDT00:00:00.000Z')}})\n}", - "viewType": "component", - "componentData": "\n{\"Discord_Webhook\":{{Webhook.text}}\n\"Mailinglist\":{{List_Name.text}}\n\"MailinglistID\":{{List_ID.text}}\n\"Icon\":{{Icon.text}}\n\"Users\":{{Table2.selectedRows.map(a => a.CustomerID)}}\n\"CreationDate\": ISODate({{moment().format('YYYY-MM-DDT00:00:00.000Z')}})\n}" - } - }, - "collection": { - "data": "MailingList", - "viewType": "component", - "componentData": "MailingList" - }, - "command": { - "data": "INSERT", - "viewType": "component", - "componentData": "INSERT" - }, - "smartSubstitution": { - "data": true, - "viewType": "component", - "componentData": true - } - } - }, - "selfReferencingDataPaths": [], - "dslExecutable": { - "name": "AddNewList", - "confirmBeforeExecute": false, - "jsonPathKeys": [ - "List_Name.text", - "List_ID.text", - "Webhook.text", - "Table2.selectedRows.map(a => a.CustomerID)", - "Icon.text", - "moment().format('YYYY-MM-DDT00:00:00.000Z')" ], - "timeoutInMillisecond": 10000 - } - }, - "publishedAction": { - "name": "AddNewList", - "datasource": { - "userPermissions": [], - "pluginId": "mongo-plugin", - "messages": [], - "isValid": true, - "new": true - }, - "pageId": "Send Messages", - "actionConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "selfReferencingDataPaths": [], "formData": { - "insert": { - "documents": { - "data": "\n{\"Discord_Webhook\":{{Webhook.text}}\n\"Mailinglist\":{{List_Name.text}}\n\"MailinglistID\":{{List_ID.text}}\n\"Icon\":{{Icon.text}}\n\"Users\":{{Table2.selectedRows.map(a => a.CustomerID)}}\n\"CreationDate\": ISODate({{moment().format('YYYY-MM-DDT00:00:00.000Z')}})\n}", - "viewType": "component", - "componentData": "\n{\"Discord_Webhook\":{{Webhook.text}}\n\"Mailinglist\":{{List_Name.text}}\n\"MailinglistID\":{{List_ID.text}}\n\"Icon\":{{Icon.text}}\n\"Users\":{{Table2.selectedRows.map(a => a.CustomerID)}}\n\"CreationDate\": ISODate({{moment().format('YYYY-MM-DDT00:00:00.000Z')}})\n}" + "tableHeaderIndex": { + "data": "1", + "viewType": "component", + "componentData": "1" + }, + "pagination": { + "data": { + "offset": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "limit": "5" + }, + "viewType": "component", + "componentData": { + "offset": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "limit": "5" } }, - "collection": { - "data": "MailingList", + "sheetName": { + "data": "Investor Details", "viewType": "component", - "componentData": "MailingList" + "componentData": "Investor Details" + }, + "entityType": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "where": { + "data": { + "condition": "AND", + "children": [ + { + "condition": "LT" + } + ] + }, + "viewType": "component", + "componentData": { + "condition": "AND" + } + }, + "sheetUrl": { + "data": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit", + "viewType": "json", + "componentData": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit" }, "command": { - "data": "INSERT", + "data": "FETCH_MANY", "viewType": "component", - "componentData": "INSERT" + "componentData": "FETCH_MANY" }, "smartSubstitution": { - "data": true, + "data": false, "viewType": "component", - "componentData": true - } - } - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { - "key": "formData.insert.documents.data" - } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "List_Name.text", - "List_ID.text", - "Webhook.text", - "Table2.selectedRows.map(a => a.CustomerID)", - "Icon.text", - "moment().format('YYYY-MM-DDT00:00:00.000Z')" - ], - "confirmBeforeExecute": false, - "userPermissions": [], - "validName": "AddNewList", - "configurationPath": "AddNewList.actionConfiguration", - "executableConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "selfReferencingDataPaths": [], - "formData": { - "insert": { - "documents": { - "data": "\n{\"Discord_Webhook\":{{Webhook.text}}\n\"Mailinglist\":{{List_Name.text}}\n\"MailinglistID\":{{List_ID.text}}\n\"Icon\":{{Icon.text}}\n\"Users\":{{Table2.selectedRows.map(a => a.CustomerID)}}\n\"CreationDate\": ISODate({{moment().format('YYYY-MM-DDT00:00:00.000Z')}})\n}", - "viewType": "component", - "componentData": "\n{\"Discord_Webhook\":{{Webhook.text}}\n\"Mailinglist\":{{List_Name.text}}\n\"MailinglistID\":{{List_ID.text}}\n\"Icon\":{{Icon.text}}\n\"Users\":{{Table2.selectedRows.map(a => a.CustomerID)}}\n\"CreationDate\": ISODate({{moment().format('YYYY-MM-DDT00:00:00.000Z')}})\n}" - } + "componentData": false }, - "collection": { - "data": "MailingList", + "queryFormat": { + "data": "ROWS", "viewType": "component", - "componentData": "MailingList" + "componentData": "ROWS" }, - "command": { - "data": "INSERT", - "viewType": "component", - "componentData": "INSERT" + "sortBy": { + "data": [ + { + "column": "", + "order": "Ascending" + } + ] }, - "smartSubstitution": { - "data": true, - "viewType": "component", - "componentData": true - } - } - }, - "selfReferencingDataPaths": [], - "dslExecutable": { - "name": "AddNewList", - "confirmBeforeExecute": false, - "jsonPathKeys": [ - "List_Name.text", - "List_ID.text", - "Webhook.text", - "Table2.selectedRows.map(a => a.CustomerID)", - "Icon.text", - "moment().format('YYYY-MM-DDT00:00:00.000Z')" - ], - "timeoutInMillisecond": 10000 - } - }, - "new": false - }, - { - "id": "Send Messages_doNotDisturbCount", - "pluginType": "DB", - "pluginId": "mongo-plugin", - "unpublishedAction": { - "name": "doNotDisturbCount", - "datasource": { - "userPermissions": [], - "pluginId": "mongo-plugin", - "messages": [], - "isValid": true, - "new": true - }, - "pageId": "Send Messages", - "actionConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "selfReferencingDataPaths": [], - "formData": { - "count": { - "query": { - "data": "{\"UsersDoNotDisturb\": 1}", - "viewType": "component", - "componentData": "{\"UsersDoNotDisturb\": 1}" - } + "projection": { + "data": [] }, - "collection": { - "data": "Customers", - "viewType": "component", - "componentData": "Customers" - }, - "body": { - "data": "{\n \"count\": \"customers\",\n \"filter\": {\n \"UsersDoNotDisturb\": 1\n\t}\n}\n", - "viewType": "component", - "componentData": "{\n \"count\": \"customers\",\n \"filter\": {\n \"UsersDoNotDisturb\": 1\n\t}\n}\n" - }, - "command": { - "data": "COUNT", - "viewType": "component", - "componentData": "COUNT" + "range": { + "data": "" } } }, @@ -599,86 +792,167 @@ "isValid": true, "invalids": [], "messages": [], - "jsonPathKeys": [], + "jsonPathKeys": [ + "(data_table.pageNo - 1) * data_table.pageSize" + ], "confirmBeforeExecute": false, "userPermissions": [], - "validName": "doNotDisturbCount", - "configurationPath": "doNotDisturbCount.actionConfiguration", - "executableConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "selfReferencingDataPaths": [], - "formData": { - "count": { - "query": { - "data": "{\"UsersDoNotDisturb\": 1}", - "viewType": "component", - "componentData": "{\"UsersDoNotDisturb\": 1}" - } - }, - "collection": { - "data": "Customers", - "viewType": "component", - "componentData": "Customers" - }, - "body": { - "data": "{\n \"count\": \"customers\",\n \"filter\": {\n \"UsersDoNotDisturb\": 1\n\t}\n}\n", - "viewType": "component", - "componentData": "{\n \"count\": \"customers\",\n \"filter\": {\n \"UsersDoNotDisturb\": 1\n\t}\n}\n" - }, - "command": { - "data": "COUNT", - "viewType": "component", - "componentData": "COUNT" - } - } - }, - "selfReferencingDataPaths": [], - "dslExecutable": { - "name": "doNotDisturbCount", - "confirmBeforeExecute": false, - "jsonPathKeys": [], - "timeoutInMillisecond": 10000 - } + "validName": "SelectQuery", + "selfReferencingDataPaths": [] }, "publishedAction": { - "name": "doNotDisturbCount", + "name": "SelectQuery", "datasource": { + "id": "Sheets", "userPermissions": [], - "pluginId": "mongo-plugin", + "name": "Sheets", + "pluginId": "google-sheets-plugin", "messages": [], "isValid": true, - "new": true + "new": false }, - "pageId": "Send Messages", + "pageId": "Investors", "actionConfiguration": { "timeoutInMillisecond": 10000, "paginationType": "NONE", "encodeParamsToggle": true, "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [ + { + "key": "method", + "value": "GET" + }, + { + "key": "sheetUrl", + "value": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit#gid=0" + }, + { + "key": "range", + "value": "" + }, + { + "key": "spreadsheetName", + "value": "" + }, + { + "key": "tableHeaderIndex", + "value": "1" + }, + { + "key": "queryFormat", + "value": "ROWS" + }, + { + "key": "rowLimit", + "value": "5" + }, + { + "key": "sheetName", + "value": "Investor Details" + }, + { + "key": "rowOffset", + "value": "{{(data_table.pageNo - 1) * data_table.pageSize}}" + }, + { + "key": "rowObject" + }, + { + "key": "rowObjects" + }, + { + "key": "rowIndex", + "value": "" + }, + { + "key": "deleteFormat", + "value": "SHEET" + }, + { + "key": "smartSubstitution", + "value": false + }, + { + "key": "where", + "value": [ + {} + ] + } + ], "formData": { - "count": { - "query": { - "data": "{\"UsersDoNotDisturb\": 1}", - "viewType": "component", - "componentData": "{\"UsersDoNotDisturb\": 1}" + "tableHeaderIndex": { + "data": "1", + "viewType": "component", + "componentData": "1" + }, + "pagination": { + "data": { + "offset": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "limit": "5" + }, + "viewType": "component", + "componentData": { + "offset": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "limit": "5" } }, - "collection": { - "data": "Customers", + "sheetName": { + "data": "Investor Details", "viewType": "component", - "componentData": "Customers" + "componentData": "Investor Details" }, - "body": { - "data": "{\n \"count\": \"customers\",\n \"filter\": {\n \"UsersDoNotDisturb\": 1\n\t}\n}\n", + "entityType": { + "data": "ROWS", "viewType": "component", - "componentData": "{\n \"count\": \"customers\",\n \"filter\": {\n \"UsersDoNotDisturb\": 1\n\t}\n}\n" + "componentData": "ROWS" + }, + "where": { + "data": { + "condition": "AND", + "children": [ + { + "condition": "LT" + } + ] + }, + "viewType": "component", + "componentData": { + "condition": "AND" + } + }, + "sheetUrl": { + "data": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit", + "viewType": "json", + "componentData": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit" }, "command": { - "data": "COUNT", + "data": "FETCH_MANY", "viewType": "component", - "componentData": "COUNT" + "componentData": "FETCH_MANY" + }, + "smartSubstitution": { + "data": false, + "viewType": "component", + "componentData": false + }, + "queryFormat": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "sortBy": { + "data": [ + { + "column": "", + "order": "Ascending" + } + ] + }, + "projection": { + "data": [] + }, + "range": { + "data": "" } } }, @@ -687,80 +961,362 @@ "isValid": true, "invalids": [], "messages": [], - "jsonPathKeys": [], + "jsonPathKeys": [ + "(data_table.pageNo - 1) * data_table.pageSize" + ], "confirmBeforeExecute": false, "userPermissions": [], - "validName": "doNotDisturbCount", - "configurationPath": "doNotDisturbCount.actionConfiguration", - "executableConfiguration": { + "validName": "SelectQuery", + "selfReferencingDataPaths": [] + }, + "new": false + }, + { + "id": "Investors_InsertQuery", + "pluginType": "SAAS", + "pluginId": "google-sheets-plugin", + "unpublishedAction": { + "name": "InsertQuery", + "datasource": { + "id": "Sheets", + "userPermissions": [], + "pluginId": "google-sheets-plugin", + "messages": [], + "isValid": true, + "new": false + }, + "pageId": "Investors", + "actionConfiguration": { "timeoutInMillisecond": 10000, "paginationType": "NONE", "encodeParamsToggle": true, "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [ + { + "key": "method", + "value": "APPEND" + }, + { + "key": "sheetUrl", + "value": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit#gid=0" + }, + { + "key": "range", + "value": "" + }, + { + "key": "spreadsheetName", + "value": "" + }, + { + "key": "tableHeaderIndex", + "value": "1" + }, + { + "key": "queryFormat", + "value": "ROWS" + }, + { + "key": "rowLimit", + "value": "" + }, + { + "key": "sheetName", + "value": "Investor Details" + }, + { + "key": "rowOffset", + "value": "" + }, + { + "key": "rowObject", + "value": "{ \n\t\t\"interestLevel\": \"{{InterestLevel.value}}\", \n\t\t\"website\": \"{{Website.text}}\", \n\t\t\"address\": \"{{Address.text}}\", \n\t\t\"topInvestments\": \"{{topInvestments.text}}\",\n\t\t\"location\": \"{{Location.text}}\",\n\t\t\"fundSize\": \"{{fundSize.text}}\",\n\t\t\"investorName\": \"{{investorName.text}}\",\n\t\t\"investmentFund\": \"{{Investment_Fund.text}}\",\n\t\t\"InvestorID\": \"{{Math.floor(Math.random()*1000+100)}}\"\n}\n" + }, + { + "key": "rowObjects" + }, + { + "key": "rowIndex", + "value": "" + }, + { + "key": "deleteFormat", + "value": "SHEET" + }, + { + "key": "smartSubstitution", + "value": false + }, + { + "key": "where", + "value": [ + {} + ] + } + ], "formData": { - "count": { - "query": { - "data": "{\"UsersDoNotDisturb\": 1}", - "viewType": "component", - "componentData": "{\"UsersDoNotDisturb\": 1}" + "rowObjects": { + "data": "{ \n\t\t\"interestLevel\": \"{{InterestLevel.value}}\", \n\t\t\"website\": \"{{Website.text}}\", \n\t\t\"address\": \"{{Address.text}}\", \n\t\t\"topInvestments\": \"{{topInvestments.text}}\",\n\t\t\"location\": \"{{Location.text}}\",\n\t\t\"fundSize\": \"{{fundSize.text}}\",\n\t\t\"investorName\": \"{{investorName.text}}\",\n\t\t\"investmentFund\": \"{{Investment_Fund.text}}\",\n\t\t\"InvestorID\": \"{{Math.floor(Math.random()*1000+100)}}\"\n}\n", + "viewType": "component", + "componentData": "{ \n\t\t\"interestLevel\": \"{{InterestLevel.value}}\", \n\t\t\"website\": \"{{Website.text}}\", \n\t\t\"address\": \"{{Address.text}}\", \n\t\t\"topInvestments\": \"{{topInvestments.text}}\",\n\t\t\"location\": \"{{Location.text}}\",\n\t\t\"fundSize\": \"{{fundSize.text}}\",\n\t\t\"investorName\": \"{{investorName.text}}\",\n\t\t\"investmentFund\": \"{{Investment_Fund.text}}\",\n\t\t\"InvestorID\": \"{{Math.floor(Math.random()*1000+100)}}\"\n}\n" + }, + "tableHeaderIndex": { + "data": "1", + "viewType": "component", + "componentData": "1" + }, + "sheetName": { + "data": "Investor Details", + "viewType": "component", + "componentData": "Investor Details" + }, + "entityType": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "where": { + "data": { + "condition": "AND" + }, + "viewType": "component", + "componentData": { + "condition": "AND" } }, - "collection": { - "data": "Customers", + "sheetUrl": { + "data": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit", "viewType": "component", - "componentData": "Customers" - }, - "body": { - "data": "{\n \"count\": \"customers\",\n \"filter\": {\n \"UsersDoNotDisturb\": 1\n\t}\n}\n", - "viewType": "component", - "componentData": "{\n \"count\": \"customers\",\n \"filter\": {\n \"UsersDoNotDisturb\": 1\n\t}\n}\n" + "componentData": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit" }, "command": { - "data": "COUNT", + "data": "INSERT_ONE", "viewType": "component", - "componentData": "COUNT" + "componentData": "INSERT_ONE" + }, + "smartSubstitution": { + "data": false, + "viewType": "component", + "componentData": false + }, + "queryFormat": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" } } }, - "selfReferencingDataPaths": [], - "dslExecutable": { - "name": "doNotDisturbCount", - "confirmBeforeExecute": false, - "jsonPathKeys": [], - "timeoutInMillisecond": 10000 - } + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "formData.rowObjects.data" + } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "Location.text", + "fundSize.text", + "Investment_Fund.text", + "topInvestments.text", + "investorName.text", + "InterestLevel.value", + "Website.text", + "Math.floor(Math.random()*1000+100)", + "Address.text" + ], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "InsertQuery", + "selfReferencingDataPaths": [] + }, + "publishedAction": { + "name": "InsertQuery", + "datasource": { + "id": "Sheets", + "userPermissions": [], + "pluginId": "google-sheets-plugin", + "messages": [], + "isValid": true, + "new": false + }, + "pageId": "Investors", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [ + { + "key": "method", + "value": "APPEND" + }, + { + "key": "sheetUrl", + "value": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit#gid=0" + }, + { + "key": "range", + "value": "" + }, + { + "key": "spreadsheetName", + "value": "" + }, + { + "key": "tableHeaderIndex", + "value": "1" + }, + { + "key": "queryFormat", + "value": "ROWS" + }, + { + "key": "rowLimit", + "value": "" + }, + { + "key": "sheetName", + "value": "Investor Details" + }, + { + "key": "rowOffset", + "value": "" + }, + { + "key": "rowObject", + "value": "{ \n\t\t\"interestLevel\": \"{{InterestLevel.value}}\", \n\t\t\"website\": \"{{Website.text}}\", \n\t\t\"address\": \"{{Address.text}}\", \n\t\t\"topInvestments\": \"{{topInvestments.text}}\",\n\t\t\"location\": \"{{Location.text}}\",\n\t\t\"fundSize\": \"{{fundSize.text}}\",\n\t\t\"investorName\": \"{{investorName.text}}\",\n\t\t\"investmentFund\": \"{{Investment_Fund.text}}\",\n\t\t\"InvestorID\": \"{{Math.floor(Math.random()*1000+100)}}\"\n}\n" + }, + { + "key": "rowObjects" + }, + { + "key": "rowIndex", + "value": "" + }, + { + "key": "deleteFormat", + "value": "SHEET" + }, + { + "key": "smartSubstitution", + "value": false + }, + { + "key": "where", + "value": [ + {} + ] + } + ], + "formData": { + "rowObjects": { + "data": "{ \n\t\t\"interestLevel\": \"{{InterestLevel.value}}\", \n\t\t\"website\": \"{{Website.text}}\", \n\t\t\"address\": \"{{Address.text}}\", \n\t\t\"topInvestments\": \"{{topInvestments.text}}\",\n\t\t\"location\": \"{{Location.text}}\",\n\t\t\"fundSize\": \"{{fundSize.text}}\",\n\t\t\"investorName\": \"{{investorName.text}}\",\n\t\t\"investmentFund\": \"{{Investment_Fund.text}}\",\n\t\t\"InvestorID\": \"{{Math.floor(Math.random()*1000+100)}}\"\n}\n", + "viewType": "component", + "componentData": "{ \n\t\t\"interestLevel\": \"{{InterestLevel.value}}\", \n\t\t\"website\": \"{{Website.text}}\", \n\t\t\"address\": \"{{Address.text}}\", \n\t\t\"topInvestments\": \"{{topInvestments.text}}\",\n\t\t\"location\": \"{{Location.text}}\",\n\t\t\"fundSize\": \"{{fundSize.text}}\",\n\t\t\"investorName\": \"{{investorName.text}}\",\n\t\t\"investmentFund\": \"{{Investment_Fund.text}}\",\n\t\t\"InvestorID\": \"{{Math.floor(Math.random()*1000+100)}}\"\n}\n" + }, + "tableHeaderIndex": { + "data": "1", + "viewType": "component", + "componentData": "1" + }, + "sheetName": { + "data": "Investor Details", + "viewType": "component", + "componentData": "Investor Details" + }, + "entityType": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + }, + "where": { + "data": { + "condition": "AND" + }, + "viewType": "component", + "componentData": { + "condition": "AND" + } + }, + "sheetUrl": { + "data": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit", + "viewType": "component", + "componentData": "https://docs.google.com/spreadsheets/d/1jKfAZllzDxAr8Y7L1k7ZQY3reYYuuKMdGFAf31jFxE8/edit" + }, + "command": { + "data": "INSERT_ONE", + "viewType": "component", + "componentData": "INSERT_ONE" + }, + "smartSubstitution": { + "data": false, + "viewType": "component", + "componentData": false + }, + "queryFormat": { + "data": "ROWS", + "viewType": "component", + "componentData": "ROWS" + } + } + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "formData.rowObjects.data" + } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "Location.text", + "fundSize.text", + "Investment_Fund.text", + "topInvestments.text", + "investorName.text", + "InterestLevel.value", + "Website.text", + "Math.floor(Math.random()*1000+100)", + "Address.text" + ], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "InsertQuery", + "selfReferencingDataPaths": [] }, "new": false } ], "actionCollectionList": [ { - "id": "Send Messages_Utils", + "id": "Investors_utils", "unpublishedCollection": { - "name": "Utils", - "pageId": "Send Messages", + "name": "utils", + "pageId": "Investors", "pluginId": "js-plugin", "pluginType": "JS", "actions": [], "archivedActions": [], - "body": "export default {\n\tsendMessages: () => {\n\t\tif(DiscordSwitch.isSwitchedOn){\n\t\t\tDiscordAPI.run();\n\t\t\tconst successMessage1 =\"Discord Message sent to \".concat(List1.selectedItem.Mailinglist).concat(\" server\") \n\t\t\tshowAlert(successMessage1,'success');\n\t\t\t}\n\t\tif(EmailSwitch.isSwitchedOn){\n\t\t\tSendEmail.run();\n\t\t\tconst successMessage2 =\"Email sent to users on \".concat(List1.selectedItem.Mailinglist).concat(\" list\") \n\t\t\tshowAlert(successMessage2,'success');\n\t\t}\n\t\tresetWidget(\"MessageModal\");\n\t\tcloseModal(\"MessageModal\");\n\t},\n\tgetEmails: () => {\n\t\tvar nameArray = Table1.selectedRows.map(function (el) { return el.CustomerEmailID; });\n\t\treturn nameArray.toString();\n\t},\n\taddList: () => {\n\t\tconst a =\"We have created a new list\".concat(List_Name.text);\n\t\tAddNewList.run();\n\t\tshowAlert(a,'success');\n\t\tresetWidget(\"mailingListModal\");\n\t\tGetMarketingList.run();\n\t\tcloseModal(\"mailingListModal\");\n\t}\n}", + "body": "export default {\n\tgetDummyData: () => {\n\t\tconst data = [\n\t\t\t{\n\t\t\t\t\"InvestorID\": 100,\n\t\t\t\t\"investmentFund\": \"Gislason, Weimann and Donnelly\",\n\t\t\t\t\"location\": \"Jakarta,Indonesia\",\n\t\t\t\t\"investorName\": \"Millisent Pottiphar\",\n\t\t\t\t\"topInvestments\": \"\",\n\t\t\t\t\"fundSize\": 31,\n\t\t\t\t\"website\": \"www.google.com\",\n\t\t\t\t\"interestLevel\": 4,\n\t\t\t\t\"address\": \"\",\n\t\t\t\t\"rowIndex\": 1\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"InvestorID\": 103,\n\t\t\t\t\"investmentFund\": \"Funk, Cassin and Kovacek\",\n\t\t\t\t\"location\": \"Manila,Philippines\",\n\t\t\t\t\"investorName\": \"Lora Godleman\",\n\t\t\t\t\"topInvestments\": \"O\",\n\t\t\t\t\"fundSize\": 36,\n\t\t\t\t\"website\": \"https://yellowbr1cks.fr\",\n\t\t\t\t\"interestLevel\": 4,\n\t\t\t\t\"address\": \"25 rue Lenepveu\",\n\t\t\t\t\"rowIndex\": 3\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"InvestorID\": 104,\n\t\t\t\t\"investmentFund\": \"O'Reilly, Dicki and Wisozk\",\n\t\t\t\t\"location\": \"Seoul,South Korea\",\n\t\t\t\t\"investorName\": \"Vivyanne Ridsdole\",\n\t\t\t\t\"topInvestments\": \"Towne, Weissnat and Toy\",\n\t\t\t\t\"fundSize\": 38,\n\t\t\t\t\"website\": \"srbgamer.w3spaces.com\",\n\t\t\t\t\"interestLevel\": 5,\n\t\t\t\t\"address\": \"2 Sauthoff Point\",\n\t\t\t\t\"rowIndex\": 4\n\t\t\t}\n\t\t]\n\n\t\treturn data;\n\t},\n\n\tgetInvestors: async () => {\n\t\ttry{\n\t\t\tconst data = await SelectQuery.run();\n\t\t\tif (data && data.length > 0) {\n\t\t\t\treturn data;\n\t\t\t}\n\t\t}catch(error){\n\t\t\treturn utils.getDummyData();\n\t\t}\n\n\t},\n\n\tupdateInvestorDetails: async () => {\n\t\ttry{\n\t\t\tconst data = await SelectQuery.run();\n\t\t\tif (data && data.length > 0) {\n\t\t\t\tawait UpdateQuery.run();\n\t\t\t\tshowAlert('Investor details updated!', 'success');\n\t\t\t}\n\t\t}catch(error){\n\t\t\tshowAlert('Demo Investor details updated!', 'success');\n\t\t}\n\t},\n\n\tcreateInvestor: async () => {\n\t\ttry{\n\t\t\tconst data = await SelectQuery.run();\n\t\t\tif (data && data.length > 0) {\n\t\t\t\tawait InsertQuery.run();\n\t\t\t\tcloseModal('Modal1')\n\t\t\t\tshowAlert('Investor details created!', 'success');\n\t\t\t\tawait SelectQuery.run();\n\t\t\t} \n\t\t}catch(error){\n\t\t\tshowAlert('Demo Investor details created!', 'success');\n\t\t}\n\t},\n}", "variables": [], "userPermissions": [] }, "publishedCollection": { - "name": "Utils", - "pageId": "Send Messages", + "name": "utils", + "pageId": "Investors", "pluginId": "js-plugin", "pluginType": "JS", "actions": [], "archivedActions": [], - "body": "export default {\n\tsendMessages: () => {\n\t\tif(DiscordSwitch.isSwitchedOn){\n\t\t\tDiscordAPI.run();\n\t\t\tconst successMessage1 =\"Discord Message sent to \".concat(List1.selectedItem.Mailinglist).concat(\" server\") \n\t\t\tshowAlert(successMessage1,'success');\n\t\t\t}\n\t\tif(EmailSwitch.isSwitchedOn){\n\t\t\tSendEmail.run();\n\t\t\tconst successMessage2 =\"Email sent to users on \".concat(List1.selectedItem.Mailinglist).concat(\" list\") \n\t\t\tshowAlert(successMessage2,'success');\n\t\t}\n\t\tresetWidget(\"MessageModal\");\n\t\tcloseModal(\"MessageModal\");\n\t},\n\tgetEmails: () => {\n\t\tvar nameArray = Table1.selectedRows.map(function (el) { return el.CustomerEmailID; });\n\t\treturn nameArray.toString();\n\t},\n\taddList: () => {\n\t\tconst a =\"We have created a new list\".concat(List_Name.text);\n\t\tAddNewList.run();\n\t\tshowAlert(a,'success');\n\t\tresetWidget(\"mailingListModal\");\n\t\tGetMarketingList.run();\n\t\tcloseModal(\"mailingListModal\");\n\t}\n}", + "body": "export default {\n\tgetDummyData: () => {\n\t\tconst data = [\n\t\t\t{\n\t\t\t\t\"InvestorID\": 100,\n\t\t\t\t\"investmentFund\": \"Gislason, Weimann and Donnelly\",\n\t\t\t\t\"location\": \"Jakarta,Indonesia\",\n\t\t\t\t\"investorName\": \"Millisent Pottiphar\",\n\t\t\t\t\"topInvestments\": \"\",\n\t\t\t\t\"fundSize\": 31,\n\t\t\t\t\"website\": \"www.google.com\",\n\t\t\t\t\"interestLevel\": 4,\n\t\t\t\t\"address\": \"\",\n\t\t\t\t\"rowIndex\": 1\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"InvestorID\": 103,\n\t\t\t\t\"investmentFund\": \"Funk, Cassin and Kovacek\",\n\t\t\t\t\"location\": \"Manila,Philippines\",\n\t\t\t\t\"investorName\": \"Lora Godleman\",\n\t\t\t\t\"topInvestments\": \"O\",\n\t\t\t\t\"fundSize\": 36,\n\t\t\t\t\"website\": \"https://yellowbr1cks.fr\",\n\t\t\t\t\"interestLevel\": 4,\n\t\t\t\t\"address\": \"25 rue Lenepveu\",\n\t\t\t\t\"rowIndex\": 3\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"InvestorID\": 104,\n\t\t\t\t\"investmentFund\": \"O'Reilly, Dicki and Wisozk\",\n\t\t\t\t\"location\": \"Seoul,South Korea\",\n\t\t\t\t\"investorName\": \"Vivyanne Ridsdole\",\n\t\t\t\t\"topInvestments\": \"Towne, Weissnat and Toy\",\n\t\t\t\t\"fundSize\": 38,\n\t\t\t\t\"website\": \"srbgamer.w3spaces.com\",\n\t\t\t\t\"interestLevel\": 5,\n\t\t\t\t\"address\": \"2 Sauthoff Point\",\n\t\t\t\t\"rowIndex\": 4\n\t\t\t}\n\t\t]\n\n\t\treturn data;\n\t},\n\n\tgetInvestors: async () => {\n\t\ttry{\n\t\t\tconst data = await SelectQuery.run();\n\t\t\tif (data && data.length > 0) {\n\t\t\t\treturn data;\n\t\t\t}\n\t\t}catch(error){\n\t\t\treturn utils.getDummyData();\n\t\t}\n\n\t},\n\n\tupdateInvestorDetails: async () => {\n\t\ttry{\n\t\t\tconst data = await SelectQuery.run();\n\t\t\tif (data && data.length > 0) {\n\t\t\t\tawait UpdateQuery.run();\n\t\t\t\tshowAlert('Investor details updated!', 'success');\n\t\t\t}\n\t\t}catch(error){\n\t\t\tshowAlert('Demo Investor details updated!', 'success');\n\t\t}\n\t},\n\n\tcreateInvestor: async () => {\n\t\ttry{\n\t\t\tconst data = await SelectQuery.run();\n\t\t\tif (data && data.length > 0) {\n\t\t\t\tawait InsertQuery.run();\n\t\t\t\tcloseModal('Modal1')\n\t\t\t\tshowAlert('Investor details created!', 'success');\n\t\t\t\tawait SelectQuery.run();\n\t\t\t} \n\t\t}catch(error){\n\t\t\tshowAlert('Demo Investor details created!', 'success');\n\t\t}\n\t},\n}", "variables": [], "userPermissions": [] }, "new": false } ], - "widgets": "{\"widgets\":[{\"widgetId\":\"n4j5niuf3l\",\"list\":[{\"boxShadow\":\"none\",\"widgetName\":\"Container6CopyCopyCopy\",\"borderColor\":\"transparent\",\"isCanvas\":true,\"displayName\":\"Container\",\"iconSVG\":\"/static/media/icon.1977dca3.svg\",\"topRow\":15,\"bottomRow\":27,\"parentRowSpace\":10,\"type\":\"CONTAINER_WIDGET\",\"hideCard\":false,\"animateLoading\":true,\"parentColumnSpace\":18.0625,\"dynamicTriggerPathList\":[],\"leftColumn\":23,\"dynamicBindingPathList\":[],\"children\":[\"fd8c2u1eha\"],\"borderWidth\":\"0\",\"key\":\"p5ueindstb\",\"backgroundColor\":\"#FFFFFF\",\"rightColumn\":36,\"widgetId\":\"n4j5niuf3l\",\"containerStyle\":\"card\",\"isVisible\":true,\"version\":1,\"parentId\":\"0\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"borderRadius\":\"15px\",\"dynamicPropertyPathList\":[{\"key\":\"borderRadius\"}],\"labelTextSize\":\"0.875rem\",\"minDynamicHeight\":4,\"maxDynamicHeight\":9000,\"dynamicHeight\":\"FIXED\"},{\"widgetName\":\"Canvas9CopyCopyCopy\",\"rightColumn\":433.5,\"detachFromLayout\":true,\"displayName\":\"Canvas\",\"widgetId\":\"fd8c2u1eha\",\"containerStyle\":\"none\",\"topRow\":0,\"bottomRow\":120,\"parentRowSpace\":1,\"isVisible\":true,\"type\":\"CANVAS_WIDGET\",\"canExtend\":false,\"version\":1,\"hideCard\":true,\"parentId\":\"n4j5niuf3l\",\"minHeight\":400,\"renderMode\":\"CANVAS\",\"isLoading\":false,\"parentColumnSpace\":1,\"leftColumn\":0,\"children\":[\"r03q89gxpz\"],\"key\":\"he8asa5zlk\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"labelTextSize\":\"0.875rem\"},{\"widgetName\":\"Statbox1CopyCopyCopy\",\"backgroundColor\":\"#FFFFFF\",\"rightColumn\":64,\"isCanvas\":true,\"displayName\":\"Stats Box\",\"iconSVG\":\"/static/media/icon.382a7c7b.svg\",\"widgetId\":\"r03q89gxpz\",\"topRow\":0,\"bottomRow\":10,\"parentRowSpace\":10,\"isVisible\":true,\"type\":\"STATBOX_WIDGET\",\"hideCard\":false,\"parentId\":\"fd8c2u1eha\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"animateLoading\":true,\"parentColumnSpace\":18.0625,\"dynamicTriggerPathList\":[],\"leftColumn\":0,\"dynamicBindingPathList\":[],\"children\":[\"0tbog0qb4e\"],\"key\":\"e50ggjmboq\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"labelTextSize\":\"0.875rem\",\"minDynamicHeight\":4,\"maxDynamicHeight\":9000,\"dynamicHeight\":\"FIXED\"},{\"widgetName\":\"Canvas8CopyCopyCopy\",\"rightColumn\":289,\"detachFromLayout\":true,\"displayName\":\"Canvas\",\"widgetId\":\"0tbog0qb4e\",\"containerStyle\":\"none\",\"topRow\":0,\"bottomRow\":100,\"parentRowSpace\":1,\"isVisible\":true,\"type\":\"CANVAS_WIDGET\",\"canExtend\":false,\"version\":1,\"hideCard\":true,\"parentId\":\"r03q89gxpz\",\"minHeight\":140,\"renderMode\":\"CANVAS\",\"isLoading\":false,\"parentColumnSpace\":1,\"leftColumn\":0,\"children\":[\"p4ieqw603v\",\"yt0hi52if6\",\"8ouo8d7pqy\"],\"key\":\"he8asa5zlk\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"labelTextSize\":\"0.875rem\"},{\"widgetName\":\"Text6Copy4CopyCopy\",\"displayName\":\"Text\",\"iconSVG\":\"/static/media/icon.97c59b52.svg\",\"topRow\":0,\"bottomRow\":4,\"type\":\"TEXT_WIDGET\",\"hideCard\":false,\"animateLoading\":true,\"dynamicTriggerPathList\":[],\"overflow\":\"NONE\",\"leftColumn\":0,\"dynamicBindingPathList\":[],\"truncateButtonColor\":\"#FFC13D\",\"text\":\"Reachable Customers\",\"key\":\"deco66gubs\",\"rightColumn\":64,\"textAlign\":\"LEFT\",\"widgetId\":\"p4ieqw603v\",\"isVisible\":true,\"fontStyle\":\"\",\"textColor\":\"#2E3D49\",\"version\":1,\"parentId\":\"0tbog0qb4e\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"fontSize\":\"0.875rem\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"labelTextSize\":\"0.875rem\",\"fontFamily\":\"System Default\",\"minDynamicHeight\":4,\"maxDynamicHeight\":9000,\"dynamicHeight\":\"FIXED\"},{\"widgetName\":\"Text7Copy3CopyCopy\",\"displayName\":\"Text\",\"iconSVG\":\"/static/media/icon.97c59b52.svg\",\"topRow\":4,\"bottomRow\":8,\"type\":\"TEXT_WIDGET\",\"hideCard\":false,\"animateLoading\":true,\"dynamicTriggerPathList\":[],\"overflow\":\"NONE\",\"leftColumn\":1,\"dynamicBindingPathList\":[{\"key\":\"text\"}],\"truncateButtonColor\":\"#FFC13D\",\"text\":\"{{allCustomerList.data.length}}\",\"key\":\"deco66gubs\",\"rightColumn\":37,\"textAlign\":\"LEFT\",\"widgetId\":\"yt0hi52if6\",\"isVisible\":true,\"fontStyle\":\"BOLD\",\"textColor\":\"#2E3D49\",\"version\":1,\"parentId\":\"0tbog0qb4e\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"fontSize\":\"1.5rem\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"dynamicPropertyPathList\":[{\"key\":\"fontSize\"}],\"labelTextSize\":\"0.875rem\",\"fontFamily\":\"System Default\",\"minDynamicHeight\":4,\"maxDynamicHeight\":9000,\"dynamicHeight\":\"FIXED\"},{\"boxShadow\":\"none\",\"widgetName\":\"IconButton2CopyCopy\",\"buttonColor\":\"#64508C\",\"displayName\":\"Icon Button\",\"iconSVG\":\"/static/media/icon.1a0c634a.svg\",\"topRow\":4,\"bottomRow\":8,\"type\":\"ICON_BUTTON_WIDGET\",\"hideCard\":false,\"animateLoading\":true,\"dynamicTriggerPathList\":[],\"leftColumn\":51,\"dynamicBindingPathList\":[],\"isDisabled\":false,\"key\":\"1vdnabqlfq\",\"rightColumn\":64,\"iconName\":\"new-person\",\"widgetId\":\"8ouo8d7pqy\",\"buttonStyle\":\"PRIMARY\",\"isVisible\":true,\"version\":1,\"parentId\":\"0tbog0qb4e\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"borderRadius\":\"0.375rem\",\"buttonVariant\":\"PRIMARY\",\"labelTextSize\":\"0.875rem\"}],\"parentId\":\"0\"},{\"widgetId\":\"6yn34g8ujl\",\"list\":[{\"boxShadow\":\"none\",\"widgetName\":\"Container6CopyCopy\",\"borderColor\":\"transparent\",\"isCanvas\":true,\"displayName\":\"Container\",\"iconSVG\":\"/static/media/icon.1977dca3.svg\",\"topRow\":15,\"bottomRow\":27,\"parentRowSpace\":10,\"type\":\"CONTAINER_WIDGET\",\"hideCard\":false,\"animateLoading\":true,\"parentColumnSpace\":18.0625,\"dynamicTriggerPathList\":[],\"leftColumn\":36,\"dynamicBindingPathList\":[],\"children\":[\"ykizpmhpsg\"],\"borderWidth\":\"0\",\"key\":\"p5ueindstb\",\"backgroundColor\":\"#FFFFFF\",\"rightColumn\":49,\"widgetId\":\"6yn34g8ujl\",\"containerStyle\":\"card\",\"isVisible\":true,\"version\":1,\"parentId\":\"0\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"borderRadius\":\"15px\",\"dynamicPropertyPathList\":[{\"key\":\"borderRadius\"}],\"labelTextSize\":\"0.875rem\",\"minDynamicHeight\":4,\"maxDynamicHeight\":9000,\"dynamicHeight\":\"FIXED\"},{\"widgetName\":\"Canvas9CopyCopy\",\"rightColumn\":433.5,\"detachFromLayout\":true,\"displayName\":\"Canvas\",\"widgetId\":\"ykizpmhpsg\",\"containerStyle\":\"none\",\"topRow\":0,\"bottomRow\":120,\"parentRowSpace\":1,\"isVisible\":true,\"type\":\"CANVAS_WIDGET\",\"canExtend\":false,\"version\":1,\"hideCard\":true,\"parentId\":\"6yn34g8ujl\",\"minHeight\":400,\"renderMode\":\"CANVAS\",\"isLoading\":false,\"parentColumnSpace\":1,\"leftColumn\":0,\"children\":[\"8vz0i9q06h\"],\"key\":\"he8asa5zlk\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"labelTextSize\":\"0.875rem\"},{\"widgetName\":\"Statbox1CopyCopy\",\"backgroundColor\":\"#FFFFFF\",\"rightColumn\":64,\"isCanvas\":true,\"displayName\":\"Stats Box\",\"iconSVG\":\"/static/media/icon.382a7c7b.svg\",\"widgetId\":\"8vz0i9q06h\",\"topRow\":0,\"bottomRow\":10,\"parentRowSpace\":10,\"isVisible\":true,\"type\":\"STATBOX_WIDGET\",\"hideCard\":false,\"parentId\":\"ykizpmhpsg\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"animateLoading\":true,\"parentColumnSpace\":18.0625,\"dynamicTriggerPathList\":[],\"leftColumn\":0,\"dynamicBindingPathList\":[],\"children\":[\"0y0vy0g8hm\"],\"key\":\"e50ggjmboq\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"labelTextSize\":\"0.875rem\",\"minDynamicHeight\":4,\"maxDynamicHeight\":9000,\"dynamicHeight\":\"FIXED\"},{\"widgetName\":\"Canvas8CopyCopy\",\"rightColumn\":289,\"detachFromLayout\":true,\"displayName\":\"Canvas\",\"widgetId\":\"0y0vy0g8hm\",\"containerStyle\":\"none\",\"topRow\":0,\"bottomRow\":100,\"parentRowSpace\":1,\"isVisible\":true,\"type\":\"CANVAS_WIDGET\",\"canExtend\":false,\"version\":1,\"hideCard\":true,\"parentId\":\"8vz0i9q06h\",\"minHeight\":140,\"renderMode\":\"CANVAS\",\"isLoading\":false,\"parentColumnSpace\":1,\"leftColumn\":0,\"children\":[\"j3z2ve8ag5\",\"kwtiaoo3ks\",\"fubfdyc3va\"],\"key\":\"he8asa5zlk\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"labelTextSize\":\"0.875rem\"},{\"widgetName\":\"Text6Copy4Copy\",\"displayName\":\"Text\",\"iconSVG\":\"/static/media/icon.97c59b52.svg\",\"topRow\":0,\"bottomRow\":4,\"type\":\"TEXT_WIDGET\",\"hideCard\":false,\"animateLoading\":true,\"dynamicTriggerPathList\":[],\"overflow\":\"NONE\",\"leftColumn\":1,\"dynamicBindingPathList\":[],\"truncateButtonColor\":\"#FFC13D\",\"text\":\"Do not Disturb Customers\",\"key\":\"deco66gubs\",\"rightColumn\":64,\"textAlign\":\"LEFT\",\"widgetId\":\"j3z2ve8ag5\",\"isVisible\":true,\"fontStyle\":\"\",\"textColor\":\"#2E3D49\",\"version\":1,\"parentId\":\"0y0vy0g8hm\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"fontSize\":\"0.875rem\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"labelTextSize\":\"0.875rem\",\"fontFamily\":\"System Default\",\"minDynamicHeight\":4,\"maxDynamicHeight\":9000,\"dynamicHeight\":\"FIXED\"},{\"widgetName\":\"Text7Copy3Copy\",\"displayName\":\"Text\",\"iconSVG\":\"/static/media/icon.97c59b52.svg\",\"topRow\":4,\"bottomRow\":8,\"type\":\"TEXT_WIDGET\",\"hideCard\":false,\"animateLoading\":true,\"dynamicTriggerPathList\":[],\"overflow\":\"NONE\",\"leftColumn\":1,\"dynamicBindingPathList\":[{\"key\":\"text\"}],\"truncateButtonColor\":\"#FFC13D\",\"text\":\"{{doNotDisturbCount.data.n}}\",\"key\":\"deco66gubs\",\"rightColumn\":37,\"textAlign\":\"LEFT\",\"widgetId\":\"kwtiaoo3ks\",\"isVisible\":true,\"fontStyle\":\"BOLD\",\"textColor\":\"#2E3D49\",\"version\":1,\"parentId\":\"0y0vy0g8hm\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"fontSize\":\"1.5rem\",\"borderRadius\":\"0px\",\"boxShadow\":\"none\",\"dynamicPropertyPathList\":[{\"key\":\"fontSize\"}],\"labelTextSize\":\"0.875rem\",\"fontFamily\":\"System Default\",\"minDynamicHeight\":4,\"maxDynamicHeight\":9000,\"dynamicHeight\":\"FIXED\"},{\"boxShadow\":\"none\",\"widgetName\":\"IconButton2Copy\",\"buttonColor\":\"#64508C\",\"displayName\":\"Icon Button\",\"iconSVG\":\"/static/media/icon.1a0c634a.svg\",\"topRow\":4,\"bottomRow\":8,\"type\":\"ICON_BUTTON_WIDGET\",\"hideCard\":false,\"animateLoading\":true,\"dynamicTriggerPathList\":[],\"leftColumn\":51,\"dynamicBindingPathList\":[],\"isDisabled\":false,\"key\":\"1vdnabqlfq\",\"rightColumn\":64,\"iconName\":\"blocked-person\",\"widgetId\":\"fubfdyc3va\",\"buttonStyle\":\"PRIMARY\",\"isVisible\":true,\"version\":1,\"parentId\":\"0y0vy0g8hm\",\"renderMode\":\"CANVAS\",\"isLoading\":false,\"borderRadius\":\"0.375rem\",\"buttonVariant\":\"PRIMARY\",\"labelTextSize\":\"0.875rem\"}],\"parentId\":\"0\"}],\"flexLayers\":[]}" -} + "widgets": "" } diff --git a/app/server/appsmith-server/src/test/resources/test_assets/ImportExportServiceTest/partial-export-valid-without-widget.json b/app/server/appsmith-server/src/test/resources/test_assets/ImportExportServiceTest/partial-export-valid-without-widget.json new file mode 100644 index 0000000000..232e05ab80 --- /dev/null +++ b/app/server/appsmith-server/src/test/resources/test_assets/ImportExportServiceTest/partial-export-valid-without-widget.json @@ -0,0 +1,189 @@ +{ + "clientSchemaVersion": 1, + "serverSchemaVersion": 7, + "datasourceList": [ + { + "datasourceConfiguration": {}, + "name": "A-force Airtable", + "pluginId": "restapi-plugin", + "messages": [], + "isAutoGenerated": false, + "isValid": true, + "embedded": false, + "new": true + } + ], + "customJSLibList": [ + { + "name": "xmlParser", + "accessor": [ + "xmlParser" + ], + "url": "https://cdnjs.cloudflare.com/ajax/libs/fast-xml-parser/3.17.5/parser.min.js", + "version": "3.17.5", + "defs": "{\"!name\":\"LIB/xmlParser\",\"xmlParser\":{\"parse\":{\"!type\":\"fn()\",\"prototype\":{}},\"convertTonimn\":{\"!type\":\"fn()\",\"prototype\":{}},\"getTraversalObj\":{\"!type\":\"fn()\",\"prototype\":{}},\"convertToJson\":{\"!type\":\"fn()\",\"prototype\":{}},\"convertToJsonString\":{\"!type\":\"fn()\",\"prototype\":{}},\"validate\":{\"!type\":\"fn()\",\"prototype\":{}},\"j2xParser\":{\"!type\":\"fn()\",\"prototype\":{\"parse\":{\"!type\":\"fn()\",\"prototype\":{}},\"j2x\":{\"!type\":\"fn()\",\"prototype\":{}}}},\"parseToNimn\":{\"!type\":\"fn()\",\"prototype\":{}}}}", + "userPermissions": [], + "uidString": "xmlParser_https://cdnjs.cloudflare.com/ajax/libs/fast-xml-parser/3.17.5/parser.min.js", + "new": true + } + ], + "actionList": [ + { + "id": "Todays Updates_get_force_roster", + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "get_force_roster", + "datasource": { + "id": "A-force Airtable", + "userPermissions": [], + "name": "A-force Airtable", + "pluginId": "restapi-plugin", + "messages": [], + "isValid": true, + "new": false + }, + "pageId": "Todays Updates", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "path": "/v0/appgSZSXDttNUK57V/Roster", + "headers": [], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [ + { + "key": "view", + "value": "Grid view" + }, + { + "key": "sort[0][field]", + "value": "StartDate" + }, + { + "key": "sort[0][direction]", + "value": "desc" + }, + { + "key": "maxRecords", + "value": "20" + } + ], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [ + { + "value": false + } + ] + }, + "executeOnLoad": true, + "dynamicBindingPathList": [], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "get_force_roster", + "selfReferencingDataPaths": [] + }, + "publishedAction": { + "name": "get_force_roster", + "datasource": { + "id": "A-force Airtable", + "userPermissions": [], + "name": "A-force Airtable", + "pluginId": "restapi-plugin", + "messages": [], + "isValid": true, + "new": false + }, + "pageId": "Todays Updates", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "path": "/v0/appgSZSXDttNUK57V/Roster", + "headers": [], + "autoGeneratedHeaders": [], + "encodeParamsToggle": true, + "queryParameters": [ + { + "key": "view", + "value": "Grid view" + }, + { + "key": "sort[0][field]", + "value": "StartDate" + }, + { + "key": "sort[0][direction]", + "value": "desc" + }, + { + "key": "maxRecords", + "value": "20" + } + ], + "httpMethod": "GET", + "selfReferencingDataPaths": [], + "pluginSpecifiedTemplates": [ + { + "value": false + } + ] + }, + "executeOnLoad": true, + "dynamicBindingPathList": [], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "get_force_roster", + "selfReferencingDataPaths": [] + }, + "new": false + } + ], + "actionCollectionList": [ + { + "id": "Todays Updates_Github_Transformer", + "unpublishedCollection": { + "name": "Github_Transformer", + "pageId": "Todays Updates", + "pluginId": "js-plugin", + "pluginType": "JS", + "actions": [], + "archivedActions": [], + "body": "export default {\n\tresults: [],\n\tgetCriticalIssues: () => {\n\t\treturn fetchCriticalIssues.data.map((issue) => { \n\t\t\treturn { \n\t\t\t\ttitle: issue.title, \n\t\t\t\tuser: issue.user.login, \n\t\t\t\tage: moment(issue.created_at).fromNow(), \n\t\t\t\tlabels: issue.labels.map((label) => label.name).join(', '),\n\t\t\t\tassignees: issue.assignees.map((label) => label.login).join(', '), \n\t\t\t\tlink: issue.html_url, \n\t\t\t\tbody: issue.body, \n\t\t\t\tnumber: issue.number,\n\t\t\t}\n\t\t})\n\t}\n}", + "variables": [ + { + "name": "results", + "value": "[]" + } + ], + "userPermissions": [] + }, + "publishedCollection": { + "name": "Github_Transformer", + "pageId": "Todays Updates", + "pluginId": "js-plugin", + "pluginType": "JS", + "actions": [], + "archivedActions": [], + "body": "export default {\n\tresults: [],\n\tgetCriticalIssues: () => {\n\t\treturn fetchCriticalIssues.data.map((issue) => { \n\t\t\treturn { \n\t\t\t\ttitle: issue.title, \n\t\t\t\tuser: issue.user.login, \n\t\t\t\tage: moment(issue.created_at).fromNow(), \n\t\t\t\tlabels: issue.labels.map((label) => label.name).join(', '),\n\t\t\t\tassignees: issue.assignees.map((label) => label.login).join(', '), \n\t\t\t\tlink: issue.html_url, \n\t\t\t\tbody: issue.body, \n\t\t\t\tnumber: issue.number,\n\t\t\t}\n\t\t})\n\t}\n}", + "variables": [ + { + "name": "results", + "value": "[]" + } + ], + "userPermissions": [] + }, + "new": false + } + ], + "widgets": "" +}