CE equivalent for removing js obj action id map (#32917)
This commit is contained in:
parent
b867f9c643
commit
58671d6e8b
|
|
@ -29,7 +29,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
|
@ -46,11 +45,9 @@ import java.util.Objects;
|
|||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNewFieldValuesIntoOldObject;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
@Slf4j
|
||||
public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionRepository, ActionCollection, String>
|
||||
|
|
@ -171,17 +168,12 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
@Override
|
||||
public Mono<ActionCollectionDTO> populateActionCollectionByViewMode(
|
||||
ActionCollectionDTO actionCollectionDTO1, Boolean viewMode) {
|
||||
return Mono.just(actionCollectionDTO1).flatMap(actionCollectionDTO -> Flux.fromIterable(
|
||||
actionCollectionDTO.getDefaultToBranchedActionIdsMap().values())
|
||||
.mergeWith(Flux.fromIterable(actionCollectionDTO
|
||||
.getDefaultToBranchedArchivedActionIdsMap()
|
||||
.values()))
|
||||
.flatMap(actionId -> {
|
||||
return newActionService.findActionDTObyIdAndViewMode(
|
||||
actionId, viewMode, actionPermission.getReadPermission());
|
||||
})
|
||||
return newActionService
|
||||
.findByCollectionIdAndViewMode(
|
||||
actionCollectionDTO1.getId(), viewMode, actionPermission.getReadPermission())
|
||||
.map(action -> newActionService.generateActionByViewMode(action, false))
|
||||
.collectList()
|
||||
.flatMap(actionsList -> splitValidActionsByViewMode(actionCollectionDTO, actionsList, viewMode)));
|
||||
.flatMap(actionsList -> splitValidActionsByViewMode(actionCollectionDTO1, actionsList, viewMode));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -191,28 +183,17 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
public Mono<ActionCollectionDTO> splitValidActionsByViewMode(
|
||||
ActionCollectionDTO actionCollectionDTO, List<ActionDTO> actionsList, Boolean viewMode) {
|
||||
return Mono.just(actionCollectionDTO).map(actionCollectionDTO1 -> {
|
||||
List<ActionDTO> archivedActionList = new ArrayList<>();
|
||||
List<ActionDTO> validActionList = new ArrayList<>();
|
||||
final List<String> collect = actionsList.stream()
|
||||
.parallel()
|
||||
.map(ActionDTO::getPluginId)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
if (collect.size() == 1) {
|
||||
actionCollectionDTO.setPluginId(collect.get(0));
|
||||
actionCollectionDTO.setPluginType(actionsList.get(0).getPluginType());
|
||||
}
|
||||
actionsList.forEach(action -> {
|
||||
if (action.getDeletedAt() == null) {
|
||||
validActionList.add(action);
|
||||
} else {
|
||||
archivedActionList.add(action);
|
||||
}
|
||||
});
|
||||
List<ActionDTO> validActionList = new ArrayList<>(actionsList);
|
||||
actionCollectionDTO.setActions(validActionList);
|
||||
if (Boolean.FALSE.equals(viewMode)) {
|
||||
actionCollectionDTO.setArchivedActions(archivedActionList);
|
||||
}
|
||||
return actionCollectionDTO;
|
||||
});
|
||||
}
|
||||
|
|
@ -273,9 +254,9 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
defaults.setPageId(actionCollection.getPublishedCollection().getPageId());
|
||||
}
|
||||
actionCollectionViewDTO.setDefaultResources(defaults);
|
||||
return Flux.fromIterable(
|
||||
actionCollectionDTO.getDefaultToBranchedActionIdsMap().values())
|
||||
.flatMap(actionId -> newActionService.findActionDTObyIdAndViewMode(actionId, viewMode, aclPermission))
|
||||
return newActionService
|
||||
.findByCollectionIdAndViewMode(actionCollection.getId(), viewMode, aclPermission)
|
||||
.map(action -> newActionService.generateActionByViewMode(action, false))
|
||||
.collectList()
|
||||
.map(actionDTOList -> {
|
||||
actionCollectionViewDTO.setActions(actionDTOList);
|
||||
|
|
@ -395,16 +376,15 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
if (toDelete.getPublishedCollection() != null
|
||||
&& toDelete.getPublishedCollection().getName() != null) {
|
||||
toDelete.getUnpublishedCollection().setDeletedAt(Instant.now());
|
||||
modifiedActionCollectionMono = Flux.fromIterable(toDelete.getUnpublishedCollection()
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.values())
|
||||
.flatMap(actionId -> newActionService
|
||||
.deleteUnpublishedActionWithOptionalPermission(actionId, deleteActionPermission)
|
||||
modifiedActionCollectionMono = newActionService
|
||||
.findByCollectionIdAndViewMode(id, false, deleteActionPermission.orElse(null))
|
||||
.flatMap(newAction -> newActionService
|
||||
.deleteGivenNewAction(newAction)
|
||||
// return an empty action so that the filter can remove it from the list
|
||||
.onErrorResume(throwable -> {
|
||||
log.debug(
|
||||
"Failed to delete action with id {} for collection: {}",
|
||||
actionId,
|
||||
newAction.getId(),
|
||||
toDelete.getUnpublishedCollection()
|
||||
.getName());
|
||||
log.error(throwable.getMessage());
|
||||
|
|
@ -482,28 +462,7 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
String applicationId, AclPermission permission) {
|
||||
return repository
|
||||
.findByApplicationId(applicationId, permission, null)
|
||||
.flatMap(actionCollection -> {
|
||||
Set<String> actionIds = new HashSet<>();
|
||||
actionIds.addAll(actionCollection
|
||||
.getUnpublishedCollection()
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.values());
|
||||
if (actionCollection.getPublishedCollection() != null
|
||||
&& !CollectionUtils.isEmpty(
|
||||
actionCollection.getPublishedCollection().getDefaultToBranchedActionIdsMap())) {
|
||||
actionIds.addAll(actionCollection
|
||||
.getPublishedCollection()
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.values());
|
||||
}
|
||||
return Flux.fromIterable(actionIds)
|
||||
.flatMap(newActionService::archiveById)
|
||||
.onErrorResume(throwable -> {
|
||||
log.error(throwable.getMessage());
|
||||
return Mono.empty();
|
||||
})
|
||||
.then(repository.archive(actionCollection));
|
||||
})
|
||||
.flatMap(this::archiveGivenActionCollection)
|
||||
.collectList();
|
||||
}
|
||||
|
||||
|
|
@ -539,43 +498,29 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
.switchIfEmpty(Mono.error(
|
||||
new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION_COLLECTION, id)))
|
||||
.cache();
|
||||
return actionCollectionMono
|
||||
.map(actionCollection -> {
|
||||
final ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection();
|
||||
final ActionCollectionDTO publishedCollection = actionCollection.getPublishedCollection();
|
||||
final Set<String> actionIds = new HashSet<>();
|
||||
if (unpublishedCollection != null) {
|
||||
actionIds.addAll(unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.values());
|
||||
actionIds.addAll(unpublishedCollection
|
||||
.getDefaultToBranchedArchivedActionIdsMap()
|
||||
.values());
|
||||
}
|
||||
if (publishedCollection != null
|
||||
&& !CollectionUtils.isEmpty(publishedCollection.getDefaultToBranchedActionIdsMap())) {
|
||||
actionIds.addAll(publishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.values());
|
||||
actionIds.addAll(publishedCollection
|
||||
.getDefaultToBranchedArchivedActionIdsMap()
|
||||
.values());
|
||||
}
|
||||
return actionIds;
|
||||
})
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.flatMap(actionId -> newActionService
|
||||
.archiveById(actionId)
|
||||
return actionCollectionMono.flatMap(this::archiveGivenActionCollection);
|
||||
}
|
||||
|
||||
protected Mono<ActionCollection> archiveGivenActionCollection(ActionCollection actionCollection) {
|
||||
Flux<NewAction> unpublishedJsActionsFlux = newActionService.findByCollectionIdAndViewMode(
|
||||
actionCollection.getId(), false, actionPermission.getDeletePermission());
|
||||
Flux<NewAction> publishedJsActionsFlux = newActionService.findByCollectionIdAndViewMode(
|
||||
actionCollection.getId(), true, actionPermission.getDeletePermission());
|
||||
return unpublishedJsActionsFlux
|
||||
.mergeWith(publishedJsActionsFlux)
|
||||
.flatMap(toArchive -> newActionService
|
||||
.archiveGivenNewAction(toArchive)
|
||||
// return an empty action so that the filter can remove it from the list
|
||||
.onErrorResume(throwable -> {
|
||||
log.debug("Failed to delete action with id {} for collection with id: {}", actionId, id);
|
||||
log.debug(
|
||||
"Failed to delete action with id {} for collection with id: {}",
|
||||
toArchive.getId(),
|
||||
actionCollection.getId());
|
||||
log.error(throwable.getMessage());
|
||||
return Mono.empty();
|
||||
}))
|
||||
.collectList()
|
||||
.flatMap(actionList -> actionCollectionMono)
|
||||
.flatMap(
|
||||
actionCollection -> repository.archive(actionCollection).thenReturn(actionCollection))
|
||||
.then(repository.archive(actionCollection).thenReturn(actionCollection))
|
||||
.flatMap(deletedActionCollection -> analyticsService.sendDeleteEvent(
|
||||
deletedActionCollection, getAnalyticsProperties(deletedActionCollection)));
|
||||
}
|
||||
|
|
@ -856,10 +801,6 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
defaults.setApplicationId(actionCollection.getApplicationId());
|
||||
}
|
||||
actionCollection.setDefaultResources(defaults);
|
||||
|
||||
final Map<String, String> actionIds = actions.stream()
|
||||
.collect(toMap(actionDTO -> actionDTO.getDefaultResources().getActionId(), ActionDTO::getId));
|
||||
collectionDTO.setDefaultToBranchedActionIdsMap(actionIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -6,15 +6,12 @@ import com.appsmith.server.clonepage.ClonePageServiceCE;
|
|||
import com.appsmith.server.domains.ActionCollection;
|
||||
import com.appsmith.server.dtos.ActionCollectionDTO;
|
||||
import com.appsmith.server.dtos.ClonePageMetaDTO;
|
||||
import com.appsmith.server.newactions.base.NewActionService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties;
|
||||
|
|
@ -23,7 +20,6 @@ import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullP
|
|||
@RequiredArgsConstructor
|
||||
public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceCE<ActionCollection> {
|
||||
private final ActionCollectionService actionCollectionService;
|
||||
private final NewActionService newActionService;
|
||||
|
||||
@Override
|
||||
public Mono<Void> cloneEntities(ClonePageMetaDTO clonePageMetaDTO) {
|
||||
|
|
@ -49,54 +45,6 @@ public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceC
|
|||
defaultResourcesForDTO.setPageId(clonedPageDefaultResources.getPageId());
|
||||
toBeClonedActionCollection.getUnpublishedCollection().setDefaultResources(defaultResourcesForDTO);
|
||||
|
||||
// Replace all action Ids from map
|
||||
Map<String, String> updatedDefaultToBranchedActionId = new HashMap<>();
|
||||
// Check if the application is connected with git and update
|
||||
// defaultActionIds accordingly
|
||||
//
|
||||
// 1. If the app is connected with git keep the actionDefaultId as it is and
|
||||
// update branchedActionId only
|
||||
//
|
||||
// 2. If app is not connected then both default and branchedActionId will be
|
||||
// same as newly created action Id
|
||||
|
||||
if (StringUtils.isEmpty(clonedPageDefaultResources.getBranchName())) {
|
||||
unpublishedCollection.getDefaultToBranchedActionIdsMap().forEach((defaultId, oldActionId) -> {
|
||||
// Filter out the actionIds for which the reference is not
|
||||
// present in cloned actions, this happens when we have
|
||||
// deleted action in unpublished mode
|
||||
if (StringUtils.hasLength(oldActionId)
|
||||
&& StringUtils.hasLength(clonePageMetaDTO
|
||||
.getOldToNewActionIdMap()
|
||||
.get(oldActionId))) {
|
||||
updatedDefaultToBranchedActionId.put(
|
||||
clonePageMetaDTO
|
||||
.getOldToNewActionIdMap()
|
||||
.get(oldActionId),
|
||||
clonePageMetaDTO
|
||||
.getOldToNewActionIdMap()
|
||||
.get(oldActionId));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
unpublishedCollection.getDefaultToBranchedActionIdsMap().forEach((defaultId, oldActionId) -> {
|
||||
// Filter out the actionIds for which the reference is not
|
||||
// present in cloned actions, this happens when we have
|
||||
// deleted action in unpublished mode
|
||||
if (StringUtils.hasLength(defaultId)
|
||||
&& StringUtils.hasLength(clonePageMetaDTO
|
||||
.getOldToNewActionIdMap()
|
||||
.get(oldActionId))) {
|
||||
updatedDefaultToBranchedActionId.put(
|
||||
defaultId,
|
||||
clonePageMetaDTO
|
||||
.getOldToNewActionIdMap()
|
||||
.get(oldActionId));
|
||||
}
|
||||
});
|
||||
}
|
||||
unpublishedCollection.setDefaultToBranchedActionIdsMap(updatedDefaultToBranchedActionId);
|
||||
|
||||
// Set id as null, otherwise create (which is using under the hood save)
|
||||
// will try to overwrite same resource instead of creating a new resource
|
||||
toBeClonedActionCollection.setId(null);
|
||||
|
|
@ -110,7 +58,9 @@ public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceC
|
|||
return actionCollectionService
|
||||
.create(toBeClonedActionCollection)
|
||||
.flatMap(clonedActionCollection -> {
|
||||
clonePageMetaDTO.getClonedActionCollections().add(clonedActionCollection);
|
||||
clonePageMetaDTO
|
||||
.getOldToNewCollectionIds()
|
||||
.put(sourceActionCollection.getId(), clonedActionCollection.getId());
|
||||
if (!StringUtils.hasLength(clonedActionCollection
|
||||
.getDefaultResources()
|
||||
.getCollectionId())) {
|
||||
|
|
@ -127,32 +77,6 @@ public class ActionCollectionClonePageServiceCEImpl implements ClonePageServiceC
|
|||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> updateClonedEntities(ClonePageMetaDTO clonePageMetaDTO) {
|
||||
return Flux.fromIterable(clonePageMetaDTO.getClonedActionCollections())
|
||||
.flatMap(clonedActionCollection -> {
|
||||
return Flux.fromIterable(clonedActionCollection
|
||||
.getUnpublishedCollection()
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.values())
|
||||
.flatMap(newActionService::findById)
|
||||
.flatMap(newlyCreatedAction -> {
|
||||
newlyCreatedAction
|
||||
.getUnpublishedAction()
|
||||
.setCollectionId(clonedActionCollection.getId());
|
||||
newlyCreatedAction
|
||||
.getUnpublishedAction()
|
||||
.getDefaultResources()
|
||||
.setCollectionId(clonedActionCollection
|
||||
.getDefaultResources()
|
||||
.getCollectionId());
|
||||
return newActionService.update(newlyCreatedAction.getId(), newlyCreatedAction);
|
||||
});
|
||||
})
|
||||
.collectList()
|
||||
.then();
|
||||
}
|
||||
|
||||
protected Flux<ActionCollection> getCloneableActionCollections(String pageId) {
|
||||
return actionCollectionService.findByPageId(pageId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,12 @@ package com.appsmith.server.actioncollections.clonepage;
|
|||
import com.appsmith.server.actioncollections.base.ActionCollectionService;
|
||||
import com.appsmith.server.clonepage.ClonePageService;
|
||||
import com.appsmith.server.domains.ActionCollection;
|
||||
import com.appsmith.server.newactions.base.NewActionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ActionCollectionClonePageServiceImpl extends ActionCollectionClonePageServiceCEImpl
|
||||
implements ClonePageService<ActionCollection> {
|
||||
public ActionCollectionClonePageServiceImpl(
|
||||
ActionCollectionService actionCollectionService, NewActionService newActionService) {
|
||||
super(actionCollectionService, newActionService);
|
||||
public ActionCollectionClonePageServiceImpl(ActionCollectionService actionCollectionService) {
|
||||
super(actionCollectionService);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,10 +279,6 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic
|
|||
final String fallbackDefaultContextId = unpublishedCollection.calculateContextId();
|
||||
|
||||
if (unpublishedCollection.getName() != null) {
|
||||
unpublishedCollection.setDefaultToBranchedActionIdsMap(mappedImportableResourcesDTO
|
||||
.getActionResultDTO()
|
||||
.getUnpublishedCollectionIdToActionIdsMap()
|
||||
.get(idFromJsonFile));
|
||||
unpublishedCollection.setPluginId(
|
||||
mappedImportableResourcesDTO.getPluginMap().get(unpublishedCollection.getPluginId()));
|
||||
|
||||
|
|
@ -291,10 +287,6 @@ public class ActionCollectionImportableServiceCEImpl implements ImportableServic
|
|||
}
|
||||
|
||||
if (publishedCollection != null && publishedCollection.getName() != null) {
|
||||
publishedCollection.setDefaultToBranchedActionIdsMap(mappedImportableResourcesDTO
|
||||
.getActionResultDTO()
|
||||
.getPublishedCollectionIdToActionIdsMap()
|
||||
.get(idFromJsonFile));
|
||||
publishedCollection.setPluginId(
|
||||
mappedImportableResourcesDTO.getPluginMap().get(publishedCollection.getPluginId()));
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import reactor.core.publisher.Flux;
|
|||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
|
@ -119,17 +118,10 @@ public class ActionCollectionRefactoringServiceCEImpl implements EntityRefactori
|
|||
|
||||
return branchedActionCollectionDTOMono
|
||||
.flatMap(branchedActionCollection -> {
|
||||
final HashMap<String, String> actionIds = new HashMap<>();
|
||||
if (branchedActionCollection.getDefaultToBranchedActionIdsMap() != null) {
|
||||
actionIds.putAll(branchedActionCollection.getDefaultToBranchedActionIdsMap());
|
||||
}
|
||||
if (branchedActionCollection.getDefaultToBranchedArchivedActionIdsMap() != null) {
|
||||
actionIds.putAll(branchedActionCollection.getDefaultToBranchedArchivedActionIdsMap());
|
||||
}
|
||||
|
||||
Flux<ActionDTO> actionUpdatesFlux = Flux.fromIterable(actionIds.values())
|
||||
.flatMap(actionId -> newActionService.findActionDTObyIdAndViewMode(
|
||||
actionId, false, actionPermission.getEditPermission()))
|
||||
Flux<ActionDTO> actionUpdatesFlux = newActionService
|
||||
.findByCollectionIdAndViewMode(
|
||||
branchedActionCollection.getId(), false, actionPermission.getEditPermission())
|
||||
.map(action -> newActionService.generateActionByViewMode(action, false))
|
||||
.flatMap(actionDTO -> {
|
||||
actionDTO.setFullyQualifiedName(newName + "." + actionDTO.getName());
|
||||
return newActionService
|
||||
|
|
|
|||
|
|
@ -6,6 +6,4 @@ import reactor.core.publisher.Mono;
|
|||
|
||||
public interface ClonePageServiceCE<T extends BaseDomain> {
|
||||
Mono<Void> cloneEntities(ClonePageMetaDTO clonePageMetaDTO);
|
||||
|
||||
Mono<Void> updateClonedEntities(ClonePageMetaDTO clonePageMetaDTO);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,8 +78,15 @@ public class NewActionCE extends BranchAwareDomain {
|
|||
public static final String unpublishedAction_actionConfiguration_httpMethod =
|
||||
dotted(unpublishedAction, ActionDTO.Fields.actionConfiguration, ActionConfiguration.Fields.httpMethod);
|
||||
|
||||
public static final String publishedAction_datasource_id =
|
||||
dotted(publishedAction, ActionDTO.Fields.datasource, Datasource.Fields.id);
|
||||
public static final String publishedAction_name = dotted(publishedAction, ActionDTO.Fields.name);
|
||||
public static final String publishedAction_pageId = dotted(publishedAction, ActionDTO.Fields.pageId);
|
||||
public static final String publishedAction_contextType = dotted(publishedAction, ActionDTO.Fields.contextType);
|
||||
|
||||
public static final String unpublishedAction_collectionId =
|
||||
dotted(unpublishedAction, ActionDTO.Fields.collectionId);
|
||||
public static final String publishedAction_collectionId =
|
||||
dotted(publishedAction, ActionDTO.Fields.collectionId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
package com.appsmith.server.dtos;
|
||||
|
||||
import com.appsmith.server.domains.ActionCollection;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
|
|
@ -19,6 +16,5 @@ public class ClonePageMetaDTO {
|
|||
String branchedSourcePageId;
|
||||
PageDTO clonedPageDTO;
|
||||
String branchName;
|
||||
Map<String, String> oldToNewActionIdMap = new HashMap<>();
|
||||
List<ActionCollection> clonedActionCollections = new ArrayList<>();
|
||||
Map<String, String> oldToNewCollectionIds = new HashMap<>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import org.springframework.data.annotation.Transient;
|
|||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNewFieldValuesIntoOldObject;
|
||||
|
|
@ -74,32 +73,12 @@ public class ActionCollectionCE_DTO {
|
|||
@JsonView(Views.Public.class)
|
||||
Instant deletedAt;
|
||||
|
||||
// This property is not shared with the client since the reference is only useful to server
|
||||
// Map<defaultActionId, branchedActionId>
|
||||
@JsonView(Views.Internal.class)
|
||||
Map<String, String> defaultToBranchedActionIdsMap = Map.of();
|
||||
|
||||
@Deprecated
|
||||
@JsonView(Views.Public.class)
|
||||
Set<String> actionIds = Set.of();
|
||||
|
||||
// This property is not shared with the client since the reference is only useful to server
|
||||
// Archived actions represent actions that have been removed from a js object but may be subject to re-use by the
|
||||
// user
|
||||
// Map<defaultActionId, branchedActionId>
|
||||
@JsonView(Views.Internal.class)
|
||||
Map<String, String> defaultToBranchedArchivedActionIdsMap = Map.of();
|
||||
|
||||
@Deprecated
|
||||
@JsonView(Views.Public.class)
|
||||
Set<String> archivedActionIds = Set.of();
|
||||
|
||||
// Instead of storing the entire action object, we only populate this field while interacting with the client side
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
List<ActionDTO> actions = List.of();
|
||||
|
||||
// Instead of storing the entire action object, we only populate this field while interacting with the client side
|
||||
// TODO : Remove after clean up, this is only kept as of now because removing it will show up as a diff on git
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
List<ActionDTO> archivedActions = List.of();
|
||||
|
|
@ -152,10 +131,6 @@ public class ActionCollectionCE_DTO {
|
|||
public void sanitiseForExport() {
|
||||
this.resetTransientFields();
|
||||
this.setDefaultResources(null);
|
||||
this.setDefaultToBranchedActionIdsMap(null);
|
||||
this.setDefaultToBranchedArchivedActionIdsMap(null);
|
||||
this.setActionIds(null);
|
||||
this.setArchivedActionIds(null);
|
||||
this.setUserPermissions(Set.of());
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +145,6 @@ public class ActionCollectionCE_DTO {
|
|||
this.setApplicationId(null);
|
||||
this.setErrorReports(null);
|
||||
this.setActions(List.of());
|
||||
this.setArchivedActions(List.of());
|
||||
}
|
||||
|
||||
public String calculateContextId() {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.appsmith.server.fork.internal;
|
|||
|
||||
import com.appsmith.external.constants.ActionCreationSourceTypeEnum;
|
||||
import com.appsmith.external.constants.AnalyticsEvents;
|
||||
import com.appsmith.external.dtos.DslExecutableDTO;
|
||||
import com.appsmith.external.helpers.AppsmithEventContext;
|
||||
import com.appsmith.external.helpers.AppsmithEventContextType;
|
||||
import com.appsmith.external.models.ActionDTO;
|
||||
|
|
@ -33,6 +32,7 @@ import com.appsmith.server.fork.forkable.ForkableService;
|
|||
import com.appsmith.server.helpers.ResponseUtils;
|
||||
import com.appsmith.server.helpers.UserPermissionUtils;
|
||||
import com.appsmith.server.imports.internal.ImportService;
|
||||
import com.appsmith.server.layouts.UpdateLayoutService;
|
||||
import com.appsmith.server.newactions.base.NewActionService;
|
||||
import com.appsmith.server.repositories.ActionCollectionRepository;
|
||||
import com.appsmith.server.repositories.NewActionRepository;
|
||||
|
|
@ -55,6 +55,7 @@ import org.apache.commons.lang.StringUtils;
|
|||
import org.bson.types.ObjectId;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -90,6 +91,7 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic
|
|||
private final NewActionRepository newActionRepository;
|
||||
private final WorkspaceRepository workspaceRepository;
|
||||
private final ForkableService<Datasource> datasourceForkableService;
|
||||
private final UpdateLayoutService updateLayoutService;
|
||||
/**
|
||||
* Clone all applications (except deleted ones), including its pages and actions from one workspace into
|
||||
* another. Also clones all datasources (not just the ones used by any applications) provided in the parameter list.
|
||||
|
|
@ -178,219 +180,174 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic
|
|||
.forkWithConfiguration(forkWithConfig)
|
||||
.build();
|
||||
|
||||
return applicationPageService
|
||||
Mono<NewPage> createForkedPageMono = applicationPageService
|
||||
.createPage(page)
|
||||
.flatMap(savedPage -> isDefault
|
||||
? applicationPageService
|
||||
.makePageDefault(savedPage)
|
||||
.thenReturn(savedPage)
|
||||
: Mono.just(savedPage))
|
||||
.flatMap(savedPage -> newPageRepository.findById(savedPage.getId()))
|
||||
.flatMap(savedPage -> {
|
||||
clonedPages.add(savedPage);
|
||||
Flux<NewAction> sourceActionFlux = newActionService
|
||||
.findByPageId(templatePageId)
|
||||
.cache();
|
||||
.flatMap(savedPage -> newPageRepository.findById(savedPage.getId()));
|
||||
|
||||
forkingSourceToForkableActionsFluxMap.put(sourceMetaForPage, sourceActionFlux);
|
||||
return createForkedPageMono.flatMap(savedPage -> {
|
||||
clonedPages.add(savedPage);
|
||||
Flux<NewAction> sourceActionFlux = newActionService
|
||||
.findByPageIdsForExport(List.of(templatePageId), Optional.empty())
|
||||
.cache();
|
||||
|
||||
ForkingMetaDTO targetMetaForPage = targetMeta.toBuilder()
|
||||
.applicationId(newPage.getApplicationId())
|
||||
.pageId(newPage.getId())
|
||||
.forkWithConfiguration(forkWithConfig)
|
||||
.build();
|
||||
forkingSourceToForkableActionsFluxMap.put(sourceMetaForPage, sourceActionFlux);
|
||||
|
||||
Flux<Datasource> forkableDatasourceFlux = datasourceForkableService
|
||||
.getForkableEntitiesFromSource(sourceMetaForPage, sourceActionFlux)
|
||||
.map(forkableDatasource -> {
|
||||
if (!clonedDatasourceMonos.containsKey(forkableDatasource.getId())) {
|
||||
Mono<Datasource> datasourceMono = datasourceForkableService
|
||||
.createForkedEntity(
|
||||
forkableDatasource,
|
||||
sourceMetaForPage,
|
||||
targetMetaForPage,
|
||||
existingDatasourcesMono)
|
||||
.cache();
|
||||
clonedDatasourceMonos.put(forkableDatasource.getId(), datasourceMono);
|
||||
}
|
||||
return forkableDatasource;
|
||||
});
|
||||
ForkingMetaDTO targetMetaForPage = targetMeta.toBuilder()
|
||||
.applicationId(newPage.getApplicationId())
|
||||
.pageId(newPage.getId())
|
||||
.forkWithConfiguration(forkWithConfig)
|
||||
.build();
|
||||
|
||||
return forkableDatasourceFlux
|
||||
.thenMany(sourceActionFlux)
|
||||
.map(newAction -> {
|
||||
ActionDTO action = newAction.getUnpublishedAction();
|
||||
log.info(
|
||||
"Preparing action for cloning {} {}.",
|
||||
action.getName(),
|
||||
newAction.getId());
|
||||
action.setPageId(savedPage.getId());
|
||||
action.setDefaultResources(null);
|
||||
return newAction;
|
||||
})
|
||||
.flatMap(newAction -> {
|
||||
final String originalActionId = newAction.getId();
|
||||
log.info("Creating clone of action {}", originalActionId);
|
||||
newAction.makePristine();
|
||||
newAction.setWorkspaceId(toWorkspaceId);
|
||||
ActionDTO action = newAction.getUnpublishedAction();
|
||||
action.setCollectionId(null);
|
||||
Flux<Datasource> forkableDatasourceFlux = datasourceForkableService
|
||||
.getForkableEntitiesFromSource(sourceMetaForPage, sourceActionFlux)
|
||||
.map(forkableDatasource -> {
|
||||
if (!clonedDatasourceMonos.containsKey(forkableDatasource.getId())) {
|
||||
Mono<Datasource> datasourceMono = datasourceForkableService
|
||||
.createForkedEntity(
|
||||
forkableDatasource,
|
||||
sourceMetaForPage,
|
||||
targetMetaForPage,
|
||||
existingDatasourcesMono)
|
||||
.cache();
|
||||
clonedDatasourceMonos.put(forkableDatasource.getId(), datasourceMono);
|
||||
}
|
||||
return forkableDatasource;
|
||||
});
|
||||
|
||||
Mono<ActionDTO> actionMono = Mono.just(action);
|
||||
final Datasource datasourceInsideAction = action.getDatasource();
|
||||
if (datasourceInsideAction != null) {
|
||||
if (datasourceInsideAction.getId() != null) {
|
||||
final String datasourceId = datasourceInsideAction.getId();
|
||||
actionMono = clonedDatasourceMonos
|
||||
.get(datasourceId)
|
||||
.map(newDatasource -> {
|
||||
action.setDatasource(newDatasource);
|
||||
return action;
|
||||
});
|
||||
} else {
|
||||
// If this is an embedded datasource, the config will get forked
|
||||
// along with the action
|
||||
datasourceInsideAction.setWorkspaceId(toWorkspaceId);
|
||||
Mono<HashMap<String, String>> forkedCollectionsMono = actionCollectionService
|
||||
.findByPageId(templatePageId)
|
||||
.flatMap(actionCollection -> {
|
||||
// Keep a record of the original collection id
|
||||
final String originalCollectionId = actionCollection.getId();
|
||||
log.info("Creating clone of action collection {}", originalCollectionId);
|
||||
// Sanitize them
|
||||
actionCollection.makePristine();
|
||||
actionCollection.setPublishedCollection(null);
|
||||
final ActionCollectionDTO unpublishedCollection =
|
||||
actionCollection.getUnpublishedCollection();
|
||||
unpublishedCollection.setPageId(savedPage.getId());
|
||||
|
||||
DefaultResources defaultResources = new DefaultResources();
|
||||
defaultResources.setPageId(savedPage.getId());
|
||||
unpublishedCollection.setDefaultResources(defaultResources);
|
||||
|
||||
actionCollection.setWorkspaceId(toWorkspaceId);
|
||||
actionCollection.setApplicationId(savedPage.getApplicationId());
|
||||
|
||||
DefaultResources defaultResources1 = new DefaultResources();
|
||||
defaultResources1.setApplicationId(savedPage.getApplicationId());
|
||||
actionCollection.setDefaultResources(defaultResources1);
|
||||
|
||||
actionCollectionService.generateAndSetPolicies(savedPage, actionCollection);
|
||||
|
||||
return actionCollectionService
|
||||
.create(actionCollection)
|
||||
.flatMap(clonedActionCollection -> {
|
||||
Mono<Tuple2<String, String>> tuple2Mono = Mono.zip(
|
||||
Mono.just(clonedActionCollection.getId()),
|
||||
Mono.just(originalCollectionId));
|
||||
|
||||
if (org.springframework.util.StringUtils.isEmpty(clonedActionCollection
|
||||
.getDefaultResources()
|
||||
.getCollectionId())) {
|
||||
ActionCollection updates = new ActionCollection();
|
||||
DefaultResources defaultResources2 =
|
||||
clonedActionCollection.getDefaultResources();
|
||||
defaultResources2.setCollectionId(clonedActionCollection.getId());
|
||||
updates.setDefaultResources(defaultResources2);
|
||||
return actionCollectionService
|
||||
.update(clonedActionCollection.getId(), updates)
|
||||
.then(tuple2Mono);
|
||||
}
|
||||
}
|
||||
return Mono.zip(
|
||||
actionMono
|
||||
.flatMap(actionDTO -> {
|
||||
// Indicates that source of action creation is fork
|
||||
// application
|
||||
actionDTO.setSource(
|
||||
ActionCreationSourceTypeEnum.FORK_APPLICATION);
|
||||
return layoutActionService.createAction(
|
||||
actionDTO,
|
||||
new AppsmithEventContext(
|
||||
AppsmithEventContextType.CLONE_PAGE),
|
||||
Boolean.FALSE);
|
||||
})
|
||||
.map(ActionDTO::getId),
|
||||
Mono.justOrEmpty(originalActionId));
|
||||
})
|
||||
// This call to `collectMap` will wait for all actions in all pages to have been
|
||||
// processed, and so the
|
||||
// `clonedPages` list will also contain all pages cloned.
|
||||
.collect(
|
||||
HashMap<String, String>::new,
|
||||
(map, tuple2) -> map.put(tuple2.getT2(), tuple2.getT1()))
|
||||
.flatMap(actionIdsMap -> {
|
||||
// Map of <originalCollectionId, clonedActionCollectionIds>
|
||||
HashMap<String, String> collectionIdsMap = new HashMap<>();
|
||||
// Pick all action collections
|
||||
return actionCollectionService
|
||||
.findByPageId(templatePageId)
|
||||
.flatMap(actionCollection -> {
|
||||
// Keep a record of the original collection id
|
||||
final String originalCollectionId = actionCollection.getId();
|
||||
log.info(
|
||||
"Creating clone of action collection {}",
|
||||
originalCollectionId);
|
||||
// Sanitize them
|
||||
actionCollection.makePristine();
|
||||
actionCollection.setPublishedCollection(null);
|
||||
final ActionCollectionDTO unpublishedCollection =
|
||||
actionCollection.getUnpublishedCollection();
|
||||
unpublishedCollection.setPageId(savedPage.getId());
|
||||
return tuple2Mono;
|
||||
});
|
||||
})
|
||||
.collect(
|
||||
HashMap<String, String>::new,
|
||||
(map, tuple2) -> map.put(tuple2.getT2(), tuple2.getT1()))
|
||||
.cache();
|
||||
|
||||
DefaultResources defaultResources = new DefaultResources();
|
||||
defaultResources.setPageId(savedPage.getId());
|
||||
unpublishedCollection.setDefaultResources(defaultResources);
|
||||
Mono<HashMap<String, String>> forkedActionsMono =
|
||||
forkedCollectionsMono.flatMap(collectionIdMap -> {
|
||||
return sourceActionFlux
|
||||
.map(newAction -> {
|
||||
ActionDTO action = newAction.getUnpublishedAction();
|
||||
log.info(
|
||||
"Preparing action for cloning {} {}.",
|
||||
action.getName(),
|
||||
newAction.getId());
|
||||
action.setPageId(savedPage.getId());
|
||||
action.setDefaultResources(null);
|
||||
return newAction;
|
||||
})
|
||||
.flatMap(newAction -> {
|
||||
final String originalActionId = newAction.getId();
|
||||
String originalCollectionId = newAction
|
||||
.getUnpublishedAction()
|
||||
.getCollectionId();
|
||||
String forkedCollectionId = collectionIdMap.get(originalCollectionId);
|
||||
log.info("Creating clone of action {}", originalActionId);
|
||||
newAction.makePristine();
|
||||
newAction.setWorkspaceId(toWorkspaceId);
|
||||
ActionDTO action = newAction.getUnpublishedAction();
|
||||
action.setCollectionId(forkedCollectionId);
|
||||
|
||||
actionCollection.setWorkspaceId(toWorkspaceId);
|
||||
actionCollection.setApplicationId(savedPage.getApplicationId());
|
||||
|
||||
DefaultResources defaultResources1 = new DefaultResources();
|
||||
defaultResources1.setApplicationId(
|
||||
savedPage.getApplicationId());
|
||||
actionCollection.setDefaultResources(defaultResources1);
|
||||
|
||||
actionCollectionService.generateAndSetPolicies(
|
||||
savedPage, actionCollection);
|
||||
|
||||
// Replace all action Ids from map and replace with newly
|
||||
// created actionIds
|
||||
final Map<String, String> newActionIds = new HashMap<>();
|
||||
unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.forEach((defaultActionId, oldActionId) -> {
|
||||
if (org.springframework.util.StringUtils.hasLength(
|
||||
oldActionId)
|
||||
&& org.springframework.util.StringUtils
|
||||
.hasLength(actionIdsMap.get(
|
||||
oldActionId))) {
|
||||
|
||||
// As this is a new application and not
|
||||
// connected
|
||||
// through git branch, the default and newly
|
||||
// created actionId will be same
|
||||
newActionIds.put(
|
||||
actionIdsMap.get(oldActionId),
|
||||
actionIdsMap.get(oldActionId));
|
||||
} else {
|
||||
log.debug(
|
||||
"Unable to find action {} while forking inside ID map: {}",
|
||||
oldActionId,
|
||||
actionIdsMap);
|
||||
}
|
||||
Mono<ActionDTO> actionMono = Mono.just(action);
|
||||
final Datasource datasourceInsideAction = action.getDatasource();
|
||||
if (datasourceInsideAction != null) {
|
||||
if (datasourceInsideAction.getId() != null) {
|
||||
final String datasourceId = datasourceInsideAction.getId();
|
||||
actionMono = clonedDatasourceMonos
|
||||
.get(datasourceId)
|
||||
.map(newDatasource -> {
|
||||
action.setDatasource(newDatasource);
|
||||
return action;
|
||||
});
|
||||
|
||||
unpublishedCollection.setDefaultToBranchedActionIdsMap(
|
||||
newActionIds);
|
||||
|
||||
return actionCollectionService
|
||||
.create(actionCollection)
|
||||
.flatMap(clonedActionCollection -> {
|
||||
if (org.springframework.util.StringUtils.isEmpty(
|
||||
clonedActionCollection
|
||||
.getDefaultResources()
|
||||
.getCollectionId())) {
|
||||
ActionCollection updates =
|
||||
new ActionCollection();
|
||||
DefaultResources defaultResources2 =
|
||||
clonedActionCollection
|
||||
.getDefaultResources();
|
||||
defaultResources2.setCollectionId(
|
||||
clonedActionCollection.getId());
|
||||
updates.setDefaultResources(defaultResources2);
|
||||
return actionCollectionService.update(
|
||||
clonedActionCollection.getId(),
|
||||
updates);
|
||||
}
|
||||
return Mono.just(clonedActionCollection);
|
||||
} else {
|
||||
// If this is an embedded datasource, the config will get forked
|
||||
// along with the action
|
||||
datasourceInsideAction.setWorkspaceId(toWorkspaceId);
|
||||
}
|
||||
}
|
||||
return Mono.zip(
|
||||
actionMono
|
||||
.flatMap(actionDTO -> {
|
||||
actionDTO.setId(null);
|
||||
// Indicates that source of action creation is fork
|
||||
// application
|
||||
actionDTO.setSource(
|
||||
ActionCreationSourceTypeEnum
|
||||
.FORK_APPLICATION);
|
||||
return layoutActionService.createAction(
|
||||
actionDTO,
|
||||
new AppsmithEventContext(
|
||||
AppsmithEventContextType
|
||||
.CLONE_PAGE),
|
||||
Boolean.FALSE);
|
||||
})
|
||||
.flatMap(clonedActionCollection -> {
|
||||
collectionIdsMap.put(
|
||||
originalCollectionId,
|
||||
clonedActionCollection.getId());
|
||||
return Flux.fromIterable(newActionIds.values())
|
||||
.flatMap(newActionService::findById)
|
||||
.flatMap(newlyCreatedAction -> {
|
||||
ActionDTO unpublishedAction =
|
||||
newlyCreatedAction
|
||||
.getUnpublishedAction();
|
||||
unpublishedAction.setCollectionId(
|
||||
clonedActionCollection.getId());
|
||||
unpublishedAction
|
||||
.getDefaultResources()
|
||||
.setCollectionId(
|
||||
clonedActionCollection
|
||||
.getId());
|
||||
return newActionService.update(
|
||||
newlyCreatedAction.getId(),
|
||||
newlyCreatedAction);
|
||||
})
|
||||
.collectList();
|
||||
});
|
||||
})
|
||||
.collectList()
|
||||
.then(Mono.zip(
|
||||
Mono.just(actionIdsMap), Mono.just(collectionIdsMap)));
|
||||
});
|
||||
});
|
||||
.map(ActionDTO::getId),
|
||||
Mono.justOrEmpty(originalActionId));
|
||||
})
|
||||
// This call to `collectMap` will wait for all actions in all pages to have
|
||||
// been processed,
|
||||
// and so the `clonedPages` list will also contain all pages cloned.
|
||||
.collect(
|
||||
HashMap::new,
|
||||
(map, tuple2) -> map.put(tuple2.getT2(), tuple2.getT1()));
|
||||
});
|
||||
|
||||
return forkableDatasourceFlux
|
||||
.then(forkedCollectionsMono)
|
||||
.zipWhen(forkedCollectionsMap -> forkedActionsMono);
|
||||
});
|
||||
})
|
||||
.flatMap(tuple -> updateActionAndCollectionsIdsInForkedPages(clonedPages, tuple.getT1(), tuple.getT2()))
|
||||
.flatMapIterable(tuple2 -> clonedPages)
|
||||
.flatMap(clonedPage -> updateLayoutService.updatePageLayoutsByPageId(clonedPage.getId()))
|
||||
// Now publish all the example applications which have been cloned to ensure that there is a
|
||||
// view mode for the newly created user.
|
||||
.then(Mono.just(newApplicationIds))
|
||||
|
|
@ -399,63 +356,6 @@ public class ApplicationForkingServiceCEImpl implements ApplicationForkingServic
|
|||
.collectList();
|
||||
}
|
||||
|
||||
private Flux<NewPage> updateActionAndCollectionsIdsInForkedPages(
|
||||
List<NewPage> clonedPages, Map<String, String> actionIdsMap, Map<String, String> actionCollectionIdsMap) {
|
||||
final List<Mono<NewPage>> pageSaveMonos = new ArrayList<>();
|
||||
|
||||
for (final NewPage page : clonedPages) {
|
||||
// If there are no unpublished layouts, there would be no published layouts either.
|
||||
// Move on to the next page.
|
||||
if (page.getUnpublishedPage().getLayouts() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean shouldSave = false;
|
||||
|
||||
for (final Layout layout : page.getUnpublishedPage().getLayouts()) {
|
||||
if (layout.getLayoutOnLoadActions() != null) {
|
||||
shouldSave = updateOnLoadActionsWithNewActionAndCollectionIds(
|
||||
actionIdsMap, actionCollectionIdsMap, page.getId(), shouldSave, layout);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldSave) {
|
||||
pageSaveMonos.add(newPageRepository.save(page));
|
||||
}
|
||||
}
|
||||
|
||||
return Flux.concat(pageSaveMonos);
|
||||
}
|
||||
|
||||
private boolean updateOnLoadActionsWithNewActionAndCollectionIds(
|
||||
Map<String, String> actionIdsMap,
|
||||
Map<String, String> collectionIdsMap,
|
||||
String pageId,
|
||||
boolean shouldSave,
|
||||
Layout layout) {
|
||||
for (final Set<DslExecutableDTO> actionSet : layout.getLayoutOnLoadActions()) {
|
||||
for (final DslExecutableDTO actionDTO : actionSet) {
|
||||
if (actionIdsMap.containsKey(actionDTO.getId())) {
|
||||
final String srcActionId = actionDTO.getId();
|
||||
final String srcCollectionId = actionDTO.getCollectionId();
|
||||
actionDTO.setId(actionIdsMap.get(srcActionId));
|
||||
actionDTO.setDefaultActionId(actionIdsMap.get(srcActionId));
|
||||
if (org.springframework.util.StringUtils.hasLength(srcCollectionId)) {
|
||||
actionDTO.setDefaultCollectionId(collectionIdsMap.get(actionDTO.getCollectionId()));
|
||||
actionDTO.setCollectionId(collectionIdsMap.get(actionDTO.getCollectionId()));
|
||||
}
|
||||
shouldSave = true;
|
||||
} else {
|
||||
log.error(
|
||||
"Couldn't find cloned action ID for publishedLayoutOnLoadAction {} in page {}",
|
||||
actionDTO.getId(),
|
||||
pageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return shouldSave;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function simply creates a clone of the Application object without cloning its children (page and actions)
|
||||
* Once the new application object is created, it adds the new application's id into the list applicationIds
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.appsmith.server.applications.base.ApplicationService;
|
|||
import com.appsmith.server.fork.forkable.ForkableService;
|
||||
import com.appsmith.server.helpers.ResponseUtils;
|
||||
import com.appsmith.server.imports.internal.ImportService;
|
||||
import com.appsmith.server.layouts.UpdateLayoutService;
|
||||
import com.appsmith.server.newactions.base.NewActionService;
|
||||
import com.appsmith.server.repositories.ActionCollectionRepository;
|
||||
import com.appsmith.server.repositories.NewActionRepository;
|
||||
|
|
@ -51,7 +52,8 @@ public class ApplicationForkingServiceImpl extends ApplicationForkingServiceCEIm
|
|||
ActionCollectionRepository actionCollectionRepository,
|
||||
NewActionRepository newActionRepository,
|
||||
WorkspaceRepository workspaceRepository,
|
||||
ForkableService<Datasource> datasourceForkableService) {
|
||||
ForkableService<Datasource> datasourceForkableService,
|
||||
UpdateLayoutService updateLayoutService) {
|
||||
super(
|
||||
applicationService,
|
||||
workspaceService,
|
||||
|
|
@ -73,6 +75,7 @@ public class ApplicationForkingServiceImpl extends ApplicationForkingServiceCEIm
|
|||
actionCollectionRepository,
|
||||
newActionRepository,
|
||||
workspaceRepository,
|
||||
datasourceForkableService);
|
||||
datasourceForkableService,
|
||||
updateLayoutService);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ import com.appsmith.server.dtos.ActionCollectionDTO;
|
|||
import com.appsmith.server.dtos.PageDTO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -134,16 +132,6 @@ public class DefaultResourcesUtils {
|
|||
collectionDTODefaultResources.setBranchName(null);
|
||||
collectionDTODefaultResources.setCollectionId(null);
|
||||
|
||||
if (updateActionIds) {
|
||||
Map<String, String> updatedActionIds = new HashMap<>();
|
||||
if (!CollectionUtils.isNullOrEmpty(collectionDTO.getDefaultToBranchedActionIdsMap())) {
|
||||
collectionDTO
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.values()
|
||||
.forEach(val -> updatedActionIds.put(val, val));
|
||||
collectionDTO.setDefaultToBranchedActionIdsMap(updatedActionIds);
|
||||
}
|
||||
}
|
||||
collectionDTO.setDefaultResources(collectionDTODefaultResources);
|
||||
}
|
||||
return resource;
|
||||
|
|
|
|||
|
|
@ -265,10 +265,6 @@ public class ResponseUtilsCE {
|
|||
actionDto.setCollectionId(defaultResourceIds.getCollectionId());
|
||||
this.updateActionDTOWithDefaultResources(actionDto);
|
||||
});
|
||||
collection.getArchivedActions().forEach(actionDto -> {
|
||||
actionDto.setCollectionId(defaultResourceIds.getCollectionId());
|
||||
this.updateActionDTOWithDefaultResources(actionDto);
|
||||
});
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ public interface NewActionServiceCE extends CrudService<NewAction, String> {
|
|||
|
||||
Flux<ActionDTO> getUnpublishedActions(MultiValueMap<String, String> params, String branchName);
|
||||
|
||||
Mono<ActionDTO> deleteGivenNewAction(NewAction toDelete);
|
||||
|
||||
Mono<ActionDTO> populateHintMessages(ActionDTO action);
|
||||
|
||||
Mono<NewAction> save(NewAction action);
|
||||
|
|
@ -104,6 +106,8 @@ public interface NewActionServiceCE extends CrudService<NewAction, String> {
|
|||
|
||||
Flux<NewAction> findByPageId(String pageId);
|
||||
|
||||
Mono<NewAction> archiveGivenNewAction(NewAction toDelete);
|
||||
|
||||
Mono<NewAction> archive(NewAction newAction);
|
||||
|
||||
Mono<NewAction> archiveById(String id);
|
||||
|
|
@ -160,4 +164,6 @@ public interface NewActionServiceCE extends CrudService<NewAction, String> {
|
|||
void updateDefaultResourcesInAction(NewAction newAction);
|
||||
|
||||
Mono<Void> saveLastEditInformationInParent(ActionDTO actionDTO);
|
||||
|
||||
Flux<NewAction> findByCollectionIdAndViewMode(String collectionId, boolean viewMode, AclPermission aclPermission);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -858,80 +858,49 @@ public class NewActionServiceCEImpl extends BaseService<NewActionRepository, New
|
|||
.findById(id, newActionDeletePermission)
|
||||
.switchIfEmpty(
|
||||
Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION, id)));
|
||||
return actionMono
|
||||
.flatMap(toDelete -> {
|
||||
Mono<NewAction> newActionMono;
|
||||
return actionMono.flatMap(this::deleteGivenNewAction);
|
||||
}
|
||||
|
||||
// Using the name field to determine if the action was ever published. In case of never published
|
||||
// action, publishedAction would exist with empty datasource and default fields.
|
||||
if (toDelete.getPublishedAction() != null
|
||||
&& toDelete.getPublishedAction().getName() != null) {
|
||||
toDelete.getUnpublishedAction().setDeletedAt(Instant.now());
|
||||
newActionMono = repository
|
||||
.save(toDelete)
|
||||
.zipWith(Mono.defer(() -> {
|
||||
final ActionDTO action = toDelete.getUnpublishedAction();
|
||||
if (action.getDatasource() != null
|
||||
&& action.getDatasource().getId() != null) {
|
||||
return datasourceService.findById(
|
||||
action.getDatasource().getId());
|
||||
} else {
|
||||
return Mono.justOrEmpty(action.getDatasource());
|
||||
}
|
||||
}))
|
||||
.flatMap(zippedActions -> {
|
||||
final Datasource datasource = zippedActions.getT2();
|
||||
final NewAction newAction1 = zippedActions.getT1();
|
||||
final Map<String, Object> data =
|
||||
this.getAnalyticsProperties(newAction1, datasource);
|
||||
final Map<String, Object> eventData = Map.of(
|
||||
FieldName.APP_MODE,
|
||||
ApplicationMode.EDIT.toString(),
|
||||
FieldName.ACTION,
|
||||
newAction1);
|
||||
data.put(FieldName.EVENT_DATA, eventData);
|
||||
@Override
|
||||
public Mono<ActionDTO> deleteGivenNewAction(NewAction toDelete) {
|
||||
Mono<NewAction> newActionMono;
|
||||
|
||||
return analyticsService
|
||||
.sendArchiveEvent(newAction1, data)
|
||||
.thenReturn(zippedActions.getT1());
|
||||
})
|
||||
.thenReturn(toDelete);
|
||||
} else {
|
||||
// This action was never published. This document can be safely archived
|
||||
newActionMono = repository
|
||||
.archive(toDelete)
|
||||
.zipWith(Mono.defer(() -> {
|
||||
final ActionDTO action = toDelete.getUnpublishedAction();
|
||||
if (action.getDatasource() != null
|
||||
&& action.getDatasource().getId() != null) {
|
||||
return datasourceService.findById(
|
||||
action.getDatasource().getId());
|
||||
} else {
|
||||
return Mono.justOrEmpty(action.getDatasource());
|
||||
}
|
||||
}))
|
||||
.flatMap(zippedActions -> {
|
||||
final Datasource datasource = zippedActions.getT2();
|
||||
final NewAction newAction1 = zippedActions.getT1();
|
||||
final Map<String, Object> data =
|
||||
this.getAnalyticsProperties(newAction1, datasource);
|
||||
final Map<String, Object> eventData = Map.of(
|
||||
FieldName.APP_MODE,
|
||||
ApplicationMode.EDIT.toString(),
|
||||
FieldName.ACTION,
|
||||
newAction1);
|
||||
data.put(FieldName.EVENT_DATA, eventData);
|
||||
// Using the name field to determine if the action was ever published. In case of never published
|
||||
// action, publishedAction would exist with empty datasource and default fields.
|
||||
if (toDelete.getPublishedAction() != null
|
||||
&& toDelete.getPublishedAction().getName() != null) {
|
||||
toDelete.getUnpublishedAction().setDeletedAt(Instant.now());
|
||||
newActionMono = repository
|
||||
.save(toDelete)
|
||||
.zipWith(Mono.defer(() -> {
|
||||
final ActionDTO action = toDelete.getUnpublishedAction();
|
||||
if (action.getDatasource() != null
|
||||
&& action.getDatasource().getId() != null) {
|
||||
return datasourceService.findById(
|
||||
action.getDatasource().getId());
|
||||
} else {
|
||||
return Mono.justOrEmpty(action.getDatasource());
|
||||
}
|
||||
}))
|
||||
.flatMap(zippedActions -> {
|
||||
final Datasource datasource = zippedActions.getT2();
|
||||
final NewAction newAction1 = zippedActions.getT1();
|
||||
final Map<String, Object> data = this.getAnalyticsProperties(newAction1, datasource);
|
||||
final Map<String, Object> eventData = Map.of(
|
||||
FieldName.APP_MODE, ApplicationMode.EDIT.toString(), FieldName.ACTION, newAction1);
|
||||
data.put(FieldName.EVENT_DATA, eventData);
|
||||
|
||||
return analyticsService
|
||||
.sendDeleteEvent(newAction1, data)
|
||||
.thenReturn(zippedActions.getT1());
|
||||
})
|
||||
.thenReturn(toDelete);
|
||||
}
|
||||
return analyticsService
|
||||
.sendArchiveEvent(newAction1, data)
|
||||
.thenReturn(zippedActions.getT1());
|
||||
})
|
||||
.thenReturn(toDelete);
|
||||
} else {
|
||||
// This action was never published. This document can be safely archived
|
||||
newActionMono = archiveGivenNewAction(toDelete);
|
||||
}
|
||||
|
||||
return newActionMono;
|
||||
})
|
||||
.map(updatedAction -> generateActionByViewMode(updatedAction, false));
|
||||
return newActionMono.map(updatedAction -> generateActionByViewMode(updatedAction, false));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1459,7 +1428,12 @@ public class NewActionServiceCEImpl extends BaseService<NewActionRepository, New
|
|||
.findById(id)
|
||||
.switchIfEmpty(
|
||||
Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.ACTION, id)));
|
||||
return actionMono.flatMap(toDelete -> repository
|
||||
return actionMono.flatMap(this::archiveGivenNewAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<NewAction> archiveGivenNewAction(NewAction toDelete) {
|
||||
return repository
|
||||
.archive(toDelete)
|
||||
.zipWith(Mono.defer(() -> {
|
||||
final ActionDTO action = toDelete.getUnpublishedAction();
|
||||
|
|
@ -1479,7 +1453,7 @@ public class NewActionServiceCEImpl extends BaseService<NewActionRepository, New
|
|||
|
||||
return analyticsService.sendDeleteEvent(newAction1, data).thenReturn(zippedActions.getT1());
|
||||
})
|
||||
.thenReturn(toDelete));
|
||||
.thenReturn(toDelete);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1832,4 +1806,10 @@ public class NewActionServiceCEImpl extends BaseService<NewActionRepository, New
|
|||
// Do nothing as this is already taken care for actions in the context of page
|
||||
return Mono.empty().then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<NewAction> findByCollectionIdAndViewMode(
|
||||
String collectionId, boolean viewMode, AclPermission aclPermission) {
|
||||
return repository.findAllByCollectionIds(List.of(collectionId), viewMode, aclPermission);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ import com.appsmith.external.models.DefaultResources;
|
|||
import com.appsmith.server.clonepage.ClonePageServiceCE;
|
||||
import com.appsmith.server.domains.NewAction;
|
||||
import com.appsmith.server.dtos.ClonePageMetaDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.newactions.base.NewActionService;
|
||||
import com.appsmith.server.services.LayoutActionService;
|
||||
import com.appsmith.server.solutions.ActionPermission;
|
||||
|
|
@ -18,8 +16,6 @@ import org.springframework.stereotype.Service;
|
|||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNestedNonNullProperties;
|
||||
|
||||
@Service
|
||||
|
|
@ -33,13 +29,23 @@ public class ActionClonePageServiceCEImpl implements ClonePageServiceCE<NewActio
|
|||
public Mono<Void> cloneEntities(ClonePageMetaDTO clonePageMetaDTO) {
|
||||
return getCloneableActions(clonePageMetaDTO.getBranchedSourcePageId())
|
||||
.flatMap(action -> {
|
||||
String originalActionId = action.getId();
|
||||
// Set new page id in the actionDTO
|
||||
final DefaultResources clonedPageDefaultResources =
|
||||
clonePageMetaDTO.getClonedPageDTO().getDefaultResources();
|
||||
action.getUnpublishedAction()
|
||||
.setPageId(clonePageMetaDTO.getClonedPageDTO().getId());
|
||||
action.getUnpublishedAction().setDefaultResources(clonedPageDefaultResources);
|
||||
ActionDTO actionDTO = action.getUnpublishedAction();
|
||||
DefaultResources defaultResources = new DefaultResources();
|
||||
defaultResources.setPageId(clonedPageDefaultResources.getPageId());
|
||||
defaultResources.setBranchName(clonedPageDefaultResources.getBranchName());
|
||||
defaultResources.setApplicationId(clonedPageDefaultResources.getApplicationId());
|
||||
actionDTO.setDefaultResources(defaultResources);
|
||||
|
||||
actionDTO.setPageId(clonePageMetaDTO.getClonedPageDTO().getId());
|
||||
if (actionDTO.getCollectionId() != null) {
|
||||
String clonedActionCollectionId =
|
||||
clonePageMetaDTO.getOldToNewCollectionIds().get(actionDTO.getCollectionId());
|
||||
actionDTO.setCollectionId(clonedActionCollectionId);
|
||||
actionDTO.getDefaultResources().setCollectionId(clonedActionCollectionId);
|
||||
}
|
||||
/*
|
||||
* - Now create the new action from the template of the source action.
|
||||
* - Use CLONE_PAGE context to make sure that page / application clone quirks are
|
||||
|
|
@ -51,42 +57,16 @@ public class ActionClonePageServiceCEImpl implements ClonePageServiceCE<NewActio
|
|||
|
||||
// Indicates that source of action creation is clone page action
|
||||
cloneActionDTO.setSource(ActionCreationSourceTypeEnum.CLONE_PAGE);
|
||||
copyNestedNonNullProperties(action.getUnpublishedAction(), cloneActionDTO);
|
||||
return Mono.zip(
|
||||
layoutActionService
|
||||
.createAction(cloneActionDTO, eventContext, Boolean.FALSE)
|
||||
.map(clonedAction -> {
|
||||
clonePageMetaDTO
|
||||
.getOldToNewActionIdMap()
|
||||
.put(action.getId(), clonedAction.getId());
|
||||
return clonedAction.getId();
|
||||
}),
|
||||
Mono.justOrEmpty(originalActionId));
|
||||
copyNestedNonNullProperties(actionDTO, cloneActionDTO);
|
||||
return layoutActionService.createAction(cloneActionDTO, eventContext, Boolean.FALSE);
|
||||
})
|
||||
.collect(HashMap<String, String>::new, (map, tuple2) -> map.put(tuple2.getT2(), tuple2.getT1()))
|
||||
.flatMap(oldToClonedActionIdMap -> {
|
||||
clonePageMetaDTO.setOldToNewActionIdMap(oldToClonedActionIdMap);
|
||||
return Mono.empty().then();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> updateClonedEntities(ClonePageMetaDTO clonePageMetaDTO) {
|
||||
return Mono.error(new AppsmithException(AppsmithError.UNSUPPORTED_OPERATION));
|
||||
.then();
|
||||
}
|
||||
|
||||
protected Flux<NewAction> getCloneableActions(String pageId) {
|
||||
Flux<NewAction> sourceActionFlux = newActionService
|
||||
return newActionService
|
||||
.findByPageId(pageId, actionPermission.getEditPermission())
|
||||
// Set collection reference in actions to null to reset to the new application's collections later
|
||||
.map(newAction -> {
|
||||
if (newAction.getUnpublishedAction() != null) {
|
||||
newAction.getUnpublishedAction().setCollectionId(null);
|
||||
}
|
||||
return newAction;
|
||||
})
|
||||
// In case there are no actions in the page being cloned, return empty
|
||||
.switchIfEmpty(Flux.empty());
|
||||
return sourceActionFlux;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,10 +84,6 @@ public class JsActionRefactoringServiceCEImpl implements EntityRefactoringServic
|
|||
|
||||
actionCollectionDTO.setName(
|
||||
dbActionCollection.getUnpublishedCollection().getName());
|
||||
actionCollectionDTO.setDefaultToBranchedActionIdsMap(
|
||||
dbActionCollection.getUnpublishedCollection().getDefaultToBranchedActionIdsMap());
|
||||
actionCollectionDTO.setDefaultToBranchedArchivedActionIdsMap(
|
||||
dbActionCollection.getUnpublishedCollection().getDefaultToBranchedArchivedActionIdsMap());
|
||||
copyNewFieldValuesIntoOldObject(actionCollectionDTO, dbActionCollection.getUnpublishedCollection());
|
||||
|
||||
// First perform refactor of the action itself
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ public interface CustomNewActionRepositoryCE extends AppsmithRepository<NewActio
|
|||
|
||||
Flux<NewAction> findAllByApplicationIdsWithoutPermission(List<String> applicationIds, List<String> includeFields);
|
||||
|
||||
Flux<NewAction> findAllByCollectionIds(List<String> collectionIds, boolean viewMode, AclPermission aclPermission);
|
||||
|
||||
Flux<NewAction> findAllUnpublishedActionsByContextIdAndContextType(
|
||||
String contextId, CreatorContextType contextType, AclPermission permission, boolean includeJs);
|
||||
|
||||
|
|
|
|||
|
|
@ -404,6 +404,19 @@ public class CustomNewActionRepositoryCEImpl extends BaseAppsmithRepositoryImpl<
|
|||
.all();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<NewAction> findAllByCollectionIds(
|
||||
List<String> collectionIds, boolean viewMode, AclPermission aclPermission) {
|
||||
String collectionIdPath;
|
||||
if (viewMode) {
|
||||
collectionIdPath = NewAction.Fields.publishedAction_collectionId;
|
||||
} else {
|
||||
collectionIdPath = NewAction.Fields.unpublishedAction_collectionId;
|
||||
}
|
||||
BridgeQuery<NewAction> q = Bridge.in(collectionIdPath, collectionIds);
|
||||
return queryBuilder().criteria(q).permission(aclPermission).all();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<NewAction> findAllUnpublishedActionsByContextIdAndContextType(
|
||||
String contextId, CreatorContextType contextType, AclPermission permission, boolean includeJs) {
|
||||
|
|
|
|||
|
|
@ -641,10 +641,6 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE {
|
|||
return page;
|
||||
}));
|
||||
|
||||
final Flux<ActionCollection> sourceActionCollectionsFlux = getCloneableActionCollections(pageId);
|
||||
|
||||
Flux<NewAction> sourceActionFlux = getCloneableActions(pageId);
|
||||
|
||||
return sourcePageMono
|
||||
.flatMap(page -> {
|
||||
clonePageMetaDTO.setBranchedSourcePageId(page.getId());
|
||||
|
|
@ -703,10 +699,9 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE {
|
|||
}
|
||||
|
||||
protected Mono<Void> clonePageDependentEntities(ClonePageMetaDTO clonePageMetaDTO) {
|
||||
return actionClonePageService
|
||||
return actionCollectionClonePageService
|
||||
.cloneEntities(clonePageMetaDTO)
|
||||
.then(Mono.defer(() -> actionCollectionClonePageService.cloneEntities(clonePageMetaDTO)))
|
||||
.then(Mono.defer(() -> actionCollectionClonePageService.updateClonedEntities(clonePageMetaDTO)));
|
||||
.then(Mono.defer(() -> actionClonePageService.cloneEntities(clonePageMetaDTO)));
|
||||
}
|
||||
|
||||
protected Mono<PageDTO> updateClonedPageLayout(PageDTO savedPage) {
|
||||
|
|
@ -1527,8 +1522,9 @@ public class ApplicationPageServiceCEImpl implements ApplicationPageServiceCE {
|
|||
|
||||
private Mono<Boolean> validateDatasourcesForCreatePermission(Mono<Application> applicationMono) {
|
||||
Flux<BaseDomain> datasourceFlux = applicationMono
|
||||
.flatMapMany(application ->
|
||||
newActionRepository.findIdAndDatasourceIdByApplicationIdIn(List.of(application.getId())))
|
||||
.flatMapMany(application -> newActionRepository.findAllByApplicationIdsWithoutPermission(
|
||||
List.of(application.getId()),
|
||||
List.of(NewAction.Fields.id, NewAction.Fields.unpublishedAction_datasource_id)))
|
||||
.collectList()
|
||||
.map(actions -> {
|
||||
return actions.stream()
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -201,17 +199,11 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE
|
|||
.flatMap(tuple -> {
|
||||
NewPage destinationPage = tuple.getT1();
|
||||
ActionCollectionDTO actionCollectionDTO = tuple.getT2();
|
||||
final Map<String, String> actionIds = new HashMap<>();
|
||||
if (actionCollectionDTO.getDefaultToBranchedActionIdsMap() != null) {
|
||||
actionIds.putAll(actionCollectionDTO.getDefaultToBranchedActionIdsMap());
|
||||
}
|
||||
if (actionCollectionDTO.getDefaultToBranchedArchivedActionIdsMap() != null) {
|
||||
actionIds.putAll(actionCollectionDTO.getDefaultToBranchedArchivedActionIdsMap());
|
||||
}
|
||||
|
||||
final Flux<ActionDTO> actionUpdatesFlux = Flux.fromIterable(actionIds.values())
|
||||
.flatMap(actionId -> newActionService.findActionDTObyIdAndViewMode(
|
||||
actionId, false, actionPermission.getEditPermission()))
|
||||
final Flux<ActionDTO> actionUpdatesFlux = newActionService
|
||||
.findByCollectionIdAndViewMode(
|
||||
actionCollectionDTO.getId(), false, actionPermission.getEditPermission())
|
||||
.map(newAction -> newActionService.generateActionByViewMode(newAction, false))
|
||||
.flatMap(actionDTO -> {
|
||||
actionDTO.setPageId(destinationPageId);
|
||||
// Update default page ID in actions as per destination page object
|
||||
|
|
@ -336,13 +328,8 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE
|
|||
.map(ActionDTO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
final Set<String> archivedDefaultActionIds = actionCollectionDTO.getArchivedActions().stream()
|
||||
.map(ActionDTO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
final Set<String> defaultActionIds = new HashSet<>();
|
||||
defaultActionIds.addAll(validDefaultActionIds);
|
||||
defaultActionIds.addAll(archivedDefaultActionIds);
|
||||
|
||||
final Mono<Map<String, String>> newValidActionIdsMono = branchedActionCollectionMono.flatMap(
|
||||
branchedActionCollection -> Flux.fromIterable(actionCollectionDTO.getActions())
|
||||
|
|
@ -393,102 +380,28 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE
|
|||
.collect(toMap(
|
||||
actionDTO -> actionDTO.getDefaultResources().getActionId(), ActionDTO::getId)));
|
||||
|
||||
final Mono<Map<String, String>> newArchivedActionIdsMono = branchedActionCollectionMono.flatMap(
|
||||
branchedActionCollection -> Flux.fromIterable(actionCollectionDTO.getArchivedActions())
|
||||
.flatMap(actionDTO -> {
|
||||
actionDTO.setCollectionId(branchedActionCollection.getId());
|
||||
actionDTO.setDeletedAt(Instant.now());
|
||||
setContextId(branchedActionCollection, actionDTO);
|
||||
if (actionDTO.getId() == null) {
|
||||
actionDTO.getDatasource().setWorkspaceId(actionCollectionDTO.getWorkspaceId());
|
||||
actionDTO.getDatasource().setPluginId(actionCollectionDTO.getPluginId());
|
||||
actionDTO.getDatasource().setName(FieldName.UNUSED_DATASOURCE);
|
||||
actionDTO.setFullyQualifiedName(
|
||||
actionCollectionDTO.getName() + "." + actionDTO.getName());
|
||||
actionDTO.setDefaultResources(branchedActionCollection.getDefaultResources());
|
||||
actionDTO.getDefaultResources().setBranchName(branchName);
|
||||
final String defaultPageId = branchedActionCollection
|
||||
.getUnpublishedCollection()
|
||||
.getDefaultResources()
|
||||
.getPageId();
|
||||
actionDTO.getDefaultResources().setPageId(defaultPageId);
|
||||
// actionCollectionService is a new action, we need to create one
|
||||
return layoutActionService
|
||||
.createSingleAction(actionDTO, Boolean.TRUE)
|
||||
// return an empty action so that the filter can remove it from the list
|
||||
.onErrorResume(throwable -> {
|
||||
log.debug(
|
||||
"Failed to create action with name {} for collection: {}",
|
||||
actionDTO.getName(),
|
||||
actionCollectionDTO.getName());
|
||||
log.error(throwable.getMessage());
|
||||
return Mono.empty();
|
||||
});
|
||||
} else {
|
||||
// Client only knows about the default action ID, fetch branched action id to update the
|
||||
// action
|
||||
Mono<String> branchedActionIdMono = StringUtils.isEmpty(branchName)
|
||||
? Mono.just(actionDTO.getId())
|
||||
: newActionService
|
||||
.findByBranchNameAndDefaultActionId(
|
||||
branchName,
|
||||
actionDTO.getId(),
|
||||
false,
|
||||
actionPermission.getEditPermission())
|
||||
.map(NewAction::getId);
|
||||
actionDTO.setId(null);
|
||||
return branchedActionIdMono.flatMap(
|
||||
actionId -> layoutActionService.updateSingleAction(actionId, actionDTO));
|
||||
}
|
||||
})
|
||||
.collect(toMap(
|
||||
actionDTO -> actionDTO.getDefaultResources().getActionId(), ActionDTO::getId)));
|
||||
|
||||
// First collect all valid action ids from before, and diff against incoming action ids
|
||||
return branchedActionCollectionMono
|
||||
.map(branchedActionCollection -> {
|
||||
// From the existing collection, if an action id is not referenced at all anymore,
|
||||
// this means the action has been somehow deleted
|
||||
final Set<String> oldDefaultActionIds = new HashSet<>();
|
||||
if (branchedActionCollection.getUnpublishedCollection().getDefaultToBranchedActionIdsMap()
|
||||
!= null) {
|
||||
oldDefaultActionIds.addAll(branchedActionCollection
|
||||
.getUnpublishedCollection()
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.keySet());
|
||||
}
|
||||
if (branchedActionCollection.getUnpublishedCollection().getDefaultToBranchedArchivedActionIdsMap()
|
||||
!= null) {
|
||||
oldDefaultActionIds.addAll(branchedActionCollection
|
||||
.getUnpublishedCollection()
|
||||
.getDefaultToBranchedArchivedActionIdsMap()
|
||||
.keySet());
|
||||
}
|
||||
|
||||
return oldDefaultActionIds.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(x -> !defaultActionIds.contains(x))
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
})
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.flatMap(defaultActionId -> newActionService
|
||||
.findBranchedIdByBranchNameAndDefaultActionId(
|
||||
branchName, defaultActionId, actionPermission.getEditPermission())
|
||||
.flatMap(newActionService::deleteUnpublishedAction)
|
||||
Mono<List<ActionDTO>> deleteNonExistingActionMono = newActionService
|
||||
.findByCollectionIdAndViewMode(actionCollectionDTO.getId(), false, actionPermission.getEditPermission())
|
||||
.filter(newAction -> !defaultActionIds.contains(
|
||||
newAction.getDefaultResources().getActionId()))
|
||||
.flatMap(x -> newActionService
|
||||
.deleteGivenNewAction(x)
|
||||
// return an empty action so that the filter can remove it from the list
|
||||
.onErrorResume(throwable -> {
|
||||
log.debug(
|
||||
"Failed to delete action with id {}, branch {} for collection: {}",
|
||||
defaultActionId,
|
||||
x.getDefaultResources().getActionId(),
|
||||
branchName,
|
||||
actionCollectionDTO.getName());
|
||||
log.error(throwable.getMessage());
|
||||
return Mono.empty();
|
||||
}))
|
||||
.then(Mono.zip(newValidActionIdsMono, newArchivedActionIdsMono))
|
||||
.collectList();
|
||||
|
||||
return deleteNonExistingActionMono
|
||||
.then(newValidActionIdsMono)
|
||||
.flatMap(tuple -> {
|
||||
actionCollectionDTO.setDefaultToBranchedActionIdsMap(tuple.getT1());
|
||||
actionCollectionDTO.setDefaultToBranchedArchivedActionIdsMap(tuple.getT2());
|
||||
return branchedActionCollectionMono.map(dbActionCollection -> {
|
||||
actionCollectionDTO.setId(null);
|
||||
resetContextId(actionCollectionDTO);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.appsmith.server.services.ce;
|
||||
package com.appsmith.server.git;
|
||||
|
||||
import com.appsmith.external.dtos.GitBranchDTO;
|
||||
import com.appsmith.external.dtos.GitStatusDTO;
|
||||
|
|
@ -63,6 +63,7 @@ import com.appsmith.server.services.LayoutCollectionService;
|
|||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.UserService;
|
||||
import com.appsmith.server.services.WorkspaceService;
|
||||
import com.appsmith.server.services.ce.GitServiceCE;
|
||||
import com.appsmith.server.solutions.ApplicationPermission;
|
||||
import com.appsmith.server.solutions.EnvironmentPermission;
|
||||
import com.appsmith.server.themes.base.ThemeService;
|
||||
|
|
@ -1241,7 +1242,6 @@ public class GitServiceCETest {
|
|||
actionCollectionDTO.setActions(List.of(action1));
|
||||
actionCollectionDTO.setPluginType(PluginType.JS);
|
||||
actionCollectionDTO.setDefaultResources(branchedResources);
|
||||
actionCollectionDTO.setDefaultToBranchedActionIdsMap(Map.of("branchedId", "collectionId"));
|
||||
|
||||
return Mono.zip(
|
||||
layoutActionService
|
||||
|
|
@ -1329,16 +1329,6 @@ public class GitServiceCETest {
|
|||
|
||||
ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection();
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap())
|
||||
.hasSize(1);
|
||||
unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.keySet()
|
||||
.forEach(key -> assertThat(key)
|
||||
.isEqualTo(unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.get(key)));
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultResources()).isNotNull();
|
||||
assertThat(unpublishedCollection.getDefaultResources().getPageId())
|
||||
.isEqualTo(application.getPages().get(0).getId());
|
||||
|
|
@ -2682,11 +2672,6 @@ public class GitServiceCETest {
|
|||
|
||||
ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection();
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap())
|
||||
.hasSize(1);
|
||||
unpublishedCollection.getDefaultToBranchedActionIdsMap().forEach((key, value) -> assertThat(key)
|
||||
.isNotEqualTo(value));
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultResources()).isNotNull();
|
||||
assertThat(unpublishedCollection.getDefaultResources().getPageId())
|
||||
.isEqualTo(parentApplication.getPages().get(0).getId());
|
||||
|
|
@ -46,7 +46,6 @@ import reactor.test.StepVerifier;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.appsmith.server.services.ce.ApplicationPageServiceCEImpl.EVALUATION_VERSION;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
|
@ -270,7 +269,6 @@ class RefactoringServiceCEImplTest {
|
|||
oldActionCollection.setId("testCollectionId");
|
||||
oldUnpublishedCollection.setPageId("testPageId");
|
||||
oldUnpublishedCollection.setName("oldName");
|
||||
oldUnpublishedCollection.setDefaultToBranchedActionIdsMap(Map.of("defaultTestActionId", "testActionId"));
|
||||
oldActionCollection.setUnpublishedCollection(oldUnpublishedCollection);
|
||||
oldActionCollection.setDefaultResources(setDefaultResources(oldActionCollection));
|
||||
oldUnpublishedCollection.setDefaultResources(setDefaultResources(oldUnpublishedCollection));
|
||||
|
|
|
|||
|
|
@ -813,11 +813,9 @@ class RefactoringServiceCETest {
|
|||
assert createdActionCollectionDTO1 != null;
|
||||
final Mono<ActionCollection> actionCollectionMono =
|
||||
actionCollectionService.getById(createdActionCollectionDTO1.getId());
|
||||
final Optional<String> optional =
|
||||
createdActionCollectionDTO1.getDefaultToBranchedActionIdsMap().values().stream()
|
||||
.findFirst();
|
||||
assert optional.isPresent();
|
||||
final Mono<NewAction> actionMono = newActionService.findById(optional.get());
|
||||
final Mono<NewAction> actionMono = newActionService
|
||||
.findByCollectionIdAndViewMode(createdActionCollectionDTO1.getId(), false, null)
|
||||
.next();
|
||||
|
||||
StepVerifier.create(Mono.zip(actionCollectionMono, actionMono))
|
||||
.assertNext(tuple -> {
|
||||
|
|
|
|||
|
|
@ -12,23 +12,17 @@ import com.appsmith.server.applications.base.ApplicationService;
|
|||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.defaultresources.DefaultResourcesService;
|
||||
import com.appsmith.server.domains.ActionCollection;
|
||||
import com.appsmith.server.domains.Layout;
|
||||
import com.appsmith.server.domains.NewAction;
|
||||
import com.appsmith.server.domains.NewPage;
|
||||
import com.appsmith.server.dtos.ActionCollectionDTO;
|
||||
import com.appsmith.server.dtos.ActionCollectionMoveDTO;
|
||||
import com.appsmith.server.dtos.LayoutDTO;
|
||||
import com.appsmith.server.dtos.PageDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.helpers.ObjectMapperUtils;
|
||||
import com.appsmith.server.helpers.ResponseUtils;
|
||||
import com.appsmith.server.layouts.UpdateLayoutService;
|
||||
import com.appsmith.server.newactions.base.NewActionService;
|
||||
import com.appsmith.server.newpages.base.NewPageService;
|
||||
import com.appsmith.server.refactors.applications.RefactoringService;
|
||||
import com.appsmith.server.repositories.ActionCollectionRepository;
|
||||
import com.appsmith.server.repositories.ce.params.QueryAllParams;
|
||||
import com.appsmith.server.solutions.ActionPermission;
|
||||
import com.appsmith.server.solutions.ActionPermissionImpl;
|
||||
import com.appsmith.server.solutions.ApplicationPermission;
|
||||
|
|
@ -39,7 +33,6 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.validation.Validator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -54,18 +47,14 @@ import reactor.test.StepVerifier;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
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 java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@Slf4j
|
||||
|
|
@ -477,6 +466,10 @@ public class ActionCollectionServiceImplTest {
|
|||
Mockito.when(newPageService.findById(Mockito.any(), Mockito.<AclPermission>any()))
|
||||
.thenReturn(Mono.just(newPage));
|
||||
|
||||
Mockito.when(newActionService.findByCollectionIdAndViewMode(
|
||||
Mockito.anyString(), Mockito.anyBoolean(), Mockito.any()))
|
||||
.thenReturn(Flux.empty());
|
||||
|
||||
final Mono<ActionCollectionDTO> actionCollectionDTOMono =
|
||||
layoutCollectionService.updateUnpublishedActionCollection("testId", actionCollectionDTO, null);
|
||||
|
||||
|
|
@ -489,113 +482,6 @@ public class ActionCollectionServiceImplTest {
|
|||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUnpublishedActionCollection_withModifiedCollection_returnsValidCollection()
|
||||
throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
ObjectMapperUtils objectMapperUtils = new ObjectMapperUtils(objectMapper);
|
||||
|
||||
final JsonNode jsonNode = objectMapperUtils.readFromFile(mockObjects, Views.Public.class, JsonNode.class);
|
||||
|
||||
String actionCollectionString =
|
||||
objectMapperUtils.writeAsString(jsonNode.get("actionCollectionWithAction"), Views.Public.class);
|
||||
final ActionCollection actionCollection =
|
||||
objectMapperUtils.readFromString(actionCollectionString, Views.Public.class, ActionCollection.class);
|
||||
|
||||
String actionCollectionDTOWithModifiedActionsString = objectMapperUtils.writeAsString(
|
||||
jsonNode.get("actionCollectionDTOWithModifiedActions"), Views.Public.class);
|
||||
final ActionCollectionDTO modifiedActionCollectionDTO = objectMapperUtils.readFromString(
|
||||
actionCollectionDTOWithModifiedActionsString, Views.Public.class, ActionCollectionDTO.class);
|
||||
|
||||
String actionCollectionAfterModifiedActionsString = objectMapperUtils.writeAsString(
|
||||
jsonNode.get("actionCollectionAfterModifiedActions"), Views.Public.class);
|
||||
final ActionCollection modifiedActionCollection = objectMapperUtils.readFromString(
|
||||
actionCollectionAfterModifiedActionsString, Views.Public.class, ActionCollection.class);
|
||||
|
||||
final ActionCollectionDTO unpublishedCollection = modifiedActionCollection.getUnpublishedCollection();
|
||||
unpublishedCollection.setDefaultToBranchedActionIdsMap(
|
||||
Map.of("defaultTestActionId1", "testActionId1", "defaultTestActionId3", "testActionId3"));
|
||||
unpublishedCollection.setDefaultToBranchedArchivedActionIdsMap(Map.of("defaultTestActionId2", "testActionId2"));
|
||||
actionCollection.setDefaultResources(setDefaultResources(actionCollection));
|
||||
modifiedActionCollection.setDefaultResources(actionCollection.getDefaultResources());
|
||||
modifiedActionCollectionDTO.setDefaultResources(setDefaultResources(modifiedActionCollectionDTO));
|
||||
unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection));
|
||||
|
||||
final Instant archivedAfter = Instant.now();
|
||||
|
||||
Map<String, ActionDTO> updatedActions = new HashMap<>();
|
||||
Mockito.when(layoutActionService.updateSingleAction(Mockito.any(), Mockito.any()))
|
||||
.thenAnswer(invocation -> {
|
||||
final ActionDTO argument = (ActionDTO) invocation.getArguments()[1];
|
||||
DefaultResources defaultResources = new DefaultResources();
|
||||
defaultResources.setActionId((String) invocation.getArguments()[0]);
|
||||
argument.setDefaultResources(defaultResources);
|
||||
argument.setId(defaultResources.getActionId());
|
||||
updatedActions.put(argument.getId(), argument);
|
||||
return Mono.just(argument);
|
||||
});
|
||||
|
||||
Mockito.when(newActionService.deleteUnpublishedAction(Mockito.any())).thenAnswer(invocation -> {
|
||||
final ActionDTO argument = (ActionDTO) invocation.getArguments()[1];
|
||||
return Mono.just(argument);
|
||||
});
|
||||
|
||||
final QueryAllParams<ActionCollection> params = Mockito.spy(new QueryAllParams<>(null));
|
||||
doReturn(Mono.just(1)).when(params).updateFirst(Mockito.<ActionCollection>any());
|
||||
Mockito.when(actionCollectionRepository.queryBuilder()).thenReturn(params);
|
||||
|
||||
Mockito.when(actionCollectionRepository.findById(Mockito.anyString(), Mockito.<AclPermission>any()))
|
||||
.thenReturn(Mono.just(actionCollection));
|
||||
|
||||
Mockito.when(actionCollectionRepository.findById(Mockito.anyString()))
|
||||
.thenReturn(Mono.just(modifiedActionCollection));
|
||||
|
||||
Mockito.when(newActionService.findActionDTObyIdAndViewMode(Mockito.any(), Mockito.any(), Mockito.any()))
|
||||
.thenAnswer(invocation -> {
|
||||
String id = (String) invocation.getArguments()[0];
|
||||
return Mono.just(updatedActions.get(id));
|
||||
});
|
||||
|
||||
Mockito.when(responseUtils.updateCollectionDTOWithDefaultResources(Mockito.any()))
|
||||
.thenReturn(modifiedActionCollectionDTO);
|
||||
|
||||
final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class);
|
||||
|
||||
Mockito.when(newPageService.findByBranchNameAndDefaultPageId(Mockito.any(), Mockito.any(), Mockito.any()))
|
||||
.thenReturn(Mono.just(newPage));
|
||||
|
||||
Mockito.when(newPageService.findById(Mockito.any(), Mockito.<AclPermission>any()))
|
||||
.thenReturn(Mono.just(newPage));
|
||||
|
||||
Mockito.when(actionCollectionRepository.setUserPermissionsInObject(Mockito.any()))
|
||||
.thenReturn(Mono.just(modifiedActionCollection));
|
||||
|
||||
Mockito.when(updateLayoutService.updatePageLayoutsByPageId(Mockito.anyString()))
|
||||
.thenAnswer(invocationOnMock -> {
|
||||
return Mono.just(actionCollection.getUnpublishedCollection().getPageId());
|
||||
});
|
||||
|
||||
final Mono<ActionCollectionDTO> actionCollectionDTOMono =
|
||||
layoutCollectionService.updateUnpublishedActionCollection(
|
||||
"testCollectionId", modifiedActionCollectionDTO, null);
|
||||
|
||||
StepVerifier.create(actionCollectionDTOMono)
|
||||
.assertNext(actionCollectionDTO1 -> {
|
||||
assertEquals(2, actionCollectionDTO1.getActions().size());
|
||||
assertEquals(1, actionCollectionDTO1.getArchivedActions().size());
|
||||
assertTrue(actionCollectionDTO1.getActions().stream()
|
||||
.map(ActionDTO::getId)
|
||||
.collect(Collectors.toSet())
|
||||
.containsAll(Set.of("testActionId1", "testActionId3")));
|
||||
assertEquals(
|
||||
"testActionId2",
|
||||
actionCollectionDTO1.getArchivedActions().get(0).getId());
|
||||
assertTrue(archivedAfter.isBefore(
|
||||
actionCollectionDTO1.getArchivedActions().get(0).getDeletedAt()));
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteUnpublishedActionCollection_withInvalidId_throwsError() {
|
||||
Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
|
||||
|
|
@ -631,6 +517,10 @@ public class ActionCollectionServiceImplTest {
|
|||
Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
|
||||
.thenReturn(Mono.just(actionCollection));
|
||||
|
||||
Mockito.when(newActionService.findByCollectionIdAndViewMode(
|
||||
Mockito.anyString(), Mockito.anyBoolean(), Mockito.any()))
|
||||
.thenReturn(Flux.empty());
|
||||
|
||||
Mockito.when(actionCollectionRepository.save(Mockito.any())).thenAnswer(invocation -> {
|
||||
final ActionCollection argument = (ActionCollection) invocation.getArguments()[0];
|
||||
return Mono.just(argument);
|
||||
|
|
@ -662,8 +552,6 @@ public class ActionCollectionServiceImplTest {
|
|||
.writeValueAsString(jsonNode.get("actionCollectionWithAction")),
|
||||
ActionCollection.class);
|
||||
ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection();
|
||||
unpublishedCollection.setDefaultToBranchedActionIdsMap(
|
||||
Map.of("defaultTestActionId1", "testActionId1", "defaultTestActionId2", "testActionId2"));
|
||||
actionCollection.setDefaultResources(setDefaultResources(actionCollection));
|
||||
unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection));
|
||||
Instant deletedAt = Instant.now();
|
||||
|
|
@ -671,9 +559,15 @@ public class ActionCollectionServiceImplTest {
|
|||
Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
|
||||
.thenReturn(Mono.just(actionCollection));
|
||||
|
||||
Mockito.when(newActionService.deleteUnpublishedActionWithOptionalPermission(Mockito.any(), Mockito.any()))
|
||||
.thenReturn(Mono.just(
|
||||
actionCollection.getUnpublishedCollection().getActions().get(0)));
|
||||
ActionDTO actionDTO =
|
||||
actionCollection.getUnpublishedCollection().getActions().get(0);
|
||||
NewAction newAction = new NewAction();
|
||||
newAction.setUnpublishedAction(actionDTO);
|
||||
Mockito.when(newActionService.findByCollectionIdAndViewMode(
|
||||
Mockito.anyString(), Mockito.anyBoolean(), Mockito.any()))
|
||||
.thenReturn(Flux.just(newAction));
|
||||
|
||||
Mockito.when(newActionService.deleteGivenNewAction(Mockito.any())).thenReturn(Mono.just(actionDTO));
|
||||
|
||||
Mockito.when(actionCollectionRepository.save(Mockito.any())).thenAnswer(invocation -> {
|
||||
final ActionCollection argument = (ActionCollection) invocation.getArguments()[0];
|
||||
|
|
@ -716,6 +610,16 @@ public class ActionCollectionServiceImplTest {
|
|||
Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
|
||||
.thenReturn(Mono.just(actionCollection));
|
||||
|
||||
ActionDTO actionDTO =
|
||||
actionCollection.getUnpublishedCollection().getActions().get(0);
|
||||
NewAction newAction = new NewAction();
|
||||
newAction.setUnpublishedAction(actionDTO);
|
||||
Mockito.when(newActionService.findByCollectionIdAndViewMode(
|
||||
Mockito.anyString(), Mockito.anyBoolean(), Mockito.any()))
|
||||
.thenReturn(Flux.just(newAction));
|
||||
|
||||
Mockito.when(newActionService.archiveGivenNewAction(Mockito.any())).thenReturn(Mono.just(newAction));
|
||||
|
||||
Mockito.when(actionCollectionRepository.findById(Mockito.anyString())).thenReturn(Mono.just(actionCollection));
|
||||
|
||||
Mockito.when(actionCollectionRepository.archive(Mockito.any())).thenReturn(Mono.empty());
|
||||
|
|
@ -742,10 +646,6 @@ public class ActionCollectionServiceImplTest {
|
|||
.writerWithView(Views.Public.class)
|
||||
.writeValueAsString(jsonNode.get("actionCollectionWithAction")),
|
||||
ActionCollection.class);
|
||||
actionCollection
|
||||
.getUnpublishedCollection()
|
||||
.setDefaultToBranchedActionIdsMap(
|
||||
Map.of("defaultTestActionId1", "testActionId1", "defaultTestActionId2", "testActionId2"));
|
||||
actionCollection.setPublishedCollection(null);
|
||||
DefaultResources resources = new DefaultResources();
|
||||
resources.setApplicationId("testApplicationId");
|
||||
|
|
@ -758,6 +658,16 @@ public class ActionCollectionServiceImplTest {
|
|||
Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<Optional<AclPermission>>any()))
|
||||
.thenReturn(Mono.just(actionCollection));
|
||||
|
||||
ActionDTO actionDTO =
|
||||
actionCollection.getUnpublishedCollection().getActions().get(0);
|
||||
NewAction newAction = new NewAction();
|
||||
newAction.setUnpublishedAction(actionDTO);
|
||||
Mockito.when(newActionService.findByCollectionIdAndViewMode(
|
||||
Mockito.anyString(), Mockito.anyBoolean(), Mockito.any()))
|
||||
.thenReturn(Flux.just(newAction));
|
||||
|
||||
Mockito.when(newActionService.archiveGivenNewAction(Mockito.any())).thenReturn(Mono.just(newAction));
|
||||
|
||||
Mockito.when(actionCollectionRepository.findById(Mockito.anyString())).thenReturn(Mono.just(actionCollection));
|
||||
|
||||
Mockito.when(newActionService.archiveById(Mockito.any())).thenReturn(Mono.just(new NewAction()));
|
||||
|
|
@ -772,90 +682,6 @@ public class ActionCollectionServiceImplTest {
|
|||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveCollection_toValidPage_returnsCollection() throws IOException {
|
||||
final ActionCollectionMoveDTO actionCollectionMoveDTO = new ActionCollectionMoveDTO();
|
||||
actionCollectionMoveDTO.setCollectionId("testCollectionId");
|
||||
actionCollectionMoveDTO.setDestinationPageId("newPageId");
|
||||
|
||||
final ActionCollection actionCollection = new ActionCollection();
|
||||
final ActionCollectionDTO unpublishedCollection = new ActionCollectionDTO();
|
||||
unpublishedCollection.setPageId("oldPageId");
|
||||
unpublishedCollection.setName("collectionName");
|
||||
unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection));
|
||||
unpublishedCollection.setDefaultToBranchedActionIdsMap(Map.of("defaultTestActionId", "testActionId"));
|
||||
actionCollection.setUnpublishedCollection(unpublishedCollection);
|
||||
actionCollection.setDefaultResources(setDefaultResources(actionCollection));
|
||||
unpublishedCollection.setDefaultResources(setDefaultResources(unpublishedCollection));
|
||||
|
||||
ActionDTO action = new ActionDTO();
|
||||
action.setName("testAction");
|
||||
DefaultResources actionResources = new DefaultResources();
|
||||
actionResources.setActionId("testAction");
|
||||
actionResources.setPageId("newPageId");
|
||||
action.setDefaultResources(actionResources);
|
||||
|
||||
Mockito.when(actionCollectionRepository.findById(Mockito.any(), Mockito.<AclPermission>any()))
|
||||
.thenReturn(Mono.just(actionCollection));
|
||||
|
||||
Mockito.when(newActionService.findActionDTObyIdAndViewMode(Mockito.any(), Mockito.anyBoolean(), Mockito.any()))
|
||||
.thenReturn(Mono.just(action));
|
||||
|
||||
Mockito.when(newActionService.updateUnpublishedAction(Mockito.any(), Mockito.any()))
|
||||
.thenReturn(Mono.just(new ActionDTO()));
|
||||
|
||||
Mockito.when(actionCollectionRepository.findById(Mockito.anyString())).thenReturn(Mono.just(actionCollection));
|
||||
|
||||
final QueryAllParams<ActionCollection> params = Mockito.spy(new QueryAllParams<>(null));
|
||||
doReturn(Mono.just(1)).when(params).updateFirst(Mockito.<ActionCollection>any());
|
||||
Mockito.when(actionCollectionRepository.queryBuilder()).thenReturn(params);
|
||||
|
||||
PageDTO oldPageDTO = new PageDTO();
|
||||
oldPageDTO.setId("oldPageId");
|
||||
oldPageDTO.setLayouts(List.of(new Layout()));
|
||||
|
||||
PageDTO newPageDTO = new PageDTO();
|
||||
newPageDTO.setId("newPageId");
|
||||
newPageDTO.setLayouts(List.of(new Layout()));
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
final JsonNode jsonNode = objectMapper.readValue(mockObjects, JsonNode.class);
|
||||
final NewPage newPage = objectMapper.convertValue(jsonNode.get("newPage"), NewPage.class);
|
||||
DefaultResources pageDefaultResources = new DefaultResources();
|
||||
pageDefaultResources.setPageId(newPage.getId());
|
||||
newPage.setDefaultResources(pageDefaultResources);
|
||||
|
||||
Mockito.when(newPageService.findPageById(Mockito.any(), Mockito.any(), Mockito.anyBoolean()))
|
||||
.thenReturn(Mono.just(oldPageDTO))
|
||||
.thenReturn(Mono.just(newPageDTO));
|
||||
|
||||
Mockito.when(newPageService.findById(Mockito.any(), Mockito.<AclPermission>any()))
|
||||
.thenReturn(Mono.just(newPage));
|
||||
|
||||
LayoutDTO layout = new LayoutDTO();
|
||||
final JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("key", "value");
|
||||
layout.setDsl(jsonObject);
|
||||
|
||||
Mockito.when(updateLayoutService.unescapeMongoSpecialCharacters(Mockito.any()))
|
||||
.thenReturn(jsonObject);
|
||||
|
||||
Mockito.when(updateLayoutService.updateLayout(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()))
|
||||
.thenReturn(Mono.just(layout));
|
||||
|
||||
Mockito.when(actionCollectionRepository.setUserPermissionsInObject(Mockito.any()))
|
||||
.thenReturn(Mono.just(actionCollection));
|
||||
|
||||
final Mono<ActionCollectionDTO> actionCollectionDTOMono =
|
||||
layoutCollectionService.moveCollection(actionCollectionMoveDTO);
|
||||
|
||||
StepVerifier.create(actionCollectionDTOMono)
|
||||
.assertNext(actionCollectionDTO -> {
|
||||
assertEquals("newPageId", actionCollectionDTO.getPageId());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateActionCollectionByViewModeTestTransientFields() {
|
||||
ActionCollection actionCollection = new ActionCollection();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import com.appsmith.server.domains.Plugin;
|
|||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.domains.Workspace;
|
||||
import com.appsmith.server.dtos.ActionCollectionDTO;
|
||||
import com.appsmith.server.dtos.ActionCollectionMoveDTO;
|
||||
import com.appsmith.server.dtos.ActionCollectionViewDTO;
|
||||
import com.appsmith.server.dtos.EntityType;
|
||||
import com.appsmith.server.dtos.LayoutDTO;
|
||||
|
|
@ -277,6 +278,52 @@ public class ActionCollectionServiceTest {
|
|||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void testMoveActionCollection_whenMovedAcrossPages_thenContainsNewPageId() {
|
||||
Application application = new Application();
|
||||
application.setName(UUID.randomUUID().toString());
|
||||
|
||||
Application createdApplication = applicationPageService
|
||||
.createApplication(application, workspaceId)
|
||||
.block();
|
||||
|
||||
PageDTO newPageDTO = new PageDTO();
|
||||
newPageDTO.setName("newPage");
|
||||
newPageDTO.setApplicationId(createdApplication.getId());
|
||||
newPageDTO.setLayouts(List.of(new Layout()));
|
||||
PageDTO newPageRes = applicationPageService.createPage(newPageDTO).block();
|
||||
|
||||
assert createdApplication != null;
|
||||
final String pageId = createdApplication.getPages().get(0).getId();
|
||||
|
||||
ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO();
|
||||
actionCollectionDTO.setName("testActionCollectionSoftDeleted");
|
||||
actionCollectionDTO.setApplicationId(createdApplication.getId());
|
||||
actionCollectionDTO.setWorkspaceId(createdApplication.getWorkspaceId());
|
||||
actionCollectionDTO.setPageId(pageId);
|
||||
actionCollectionDTO.setPluginId(datasource.getPluginId());
|
||||
actionCollectionDTO.setPluginType(PluginType.JS);
|
||||
actionCollectionDTO.setDeletedAt(Instant.now());
|
||||
layoutCollectionService.createCollection(actionCollectionDTO, null).block();
|
||||
ActionCollection createdActionCollection = actionCollectionRepository
|
||||
.findByApplicationId(createdApplication.getId(), READ_ACTIONS, null)
|
||||
.blockFirst();
|
||||
|
||||
final ActionCollectionMoveDTO actionCollectionMoveDTO = new ActionCollectionMoveDTO();
|
||||
actionCollectionMoveDTO.setCollectionId(createdActionCollection.getId());
|
||||
actionCollectionMoveDTO.setDestinationPageId(newPageRes.getId());
|
||||
|
||||
final Mono<ActionCollectionDTO> actionCollectionDTOMono =
|
||||
layoutCollectionService.moveCollection(actionCollectionMoveDTO);
|
||||
|
||||
StepVerifier.create(actionCollectionDTOMono)
|
||||
.assertNext(res -> {
|
||||
assertThat(res.getPageId()).isEqualTo(newPageRes.getId());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void createValidActionCollectionAndCheckPermissions() {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import com.appsmith.server.dtos.ApplicationAccessDTO;
|
|||
import com.appsmith.server.dtos.ApplicationJson;
|
||||
import com.appsmith.server.dtos.ApplicationPagesDTO;
|
||||
import com.appsmith.server.dtos.InviteUsersDTO;
|
||||
import com.appsmith.server.dtos.LayoutDTO;
|
||||
import com.appsmith.server.dtos.PageDTO;
|
||||
import com.appsmith.server.dtos.RecentlyUsedEntityDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
|
|
@ -115,7 +116,7 @@ import reactor.core.publisher.Flux;
|
|||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuple3;
|
||||
import reactor.util.function.Tuple4;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -607,7 +608,7 @@ public class ApplicationServiceCETest {
|
|||
assertThat(page.getPolicies().stream()
|
||||
.map(Policy::getPermission)
|
||||
.collect(Collectors.toSet()))
|
||||
.containsExactlyInAnyOrder(
|
||||
.contains(
|
||||
MANAGE_PAGES.getValue(),
|
||||
READ_PAGES.getValue(),
|
||||
PAGE_CREATE_PAGE_ACTIONS.getValue(),
|
||||
|
|
@ -2167,9 +2168,9 @@ public class ApplicationServiceCETest {
|
|||
.isEqualTo(application.getId());
|
||||
|
||||
newPage.getUnpublishedPage().getLayouts().forEach(layout -> {
|
||||
assertThat(layout.getLayoutOnLoadActions()).hasSize(2);
|
||||
assertThat(layout.getLayoutOnLoadActions()).hasSize(1);
|
||||
layout.getLayoutOnLoadActions().forEach(dslActionDTOS -> {
|
||||
assertThat(dslActionDTOS).hasSize(1);
|
||||
assertThat(dslActionDTOS).hasSize(2);
|
||||
dslActionDTOS.forEach(actionDTO -> {
|
||||
assertThat(actionDTO.getId()).isEqualTo(actionDTO.getDefaultActionId());
|
||||
if (StringUtils.hasLength(actionDTO.getCollectionId())) {
|
||||
|
|
@ -2193,7 +2194,7 @@ public class ApplicationServiceCETest {
|
|||
assertThat(action.getDefaultResources()).isNotNull();
|
||||
assertThat(action.getDefaultResources().getPageId())
|
||||
.isEqualTo(application.getPages().get(0).getId());
|
||||
if (!StringUtils.isEmpty(action.getDefaultResources().getCollectionId())) {
|
||||
if (StringUtils.hasLength(action.getDefaultResources().getCollectionId())) {
|
||||
assertThat(action.getDefaultResources().getCollectionId())
|
||||
.isEqualTo(action.getCollectionId());
|
||||
}
|
||||
|
|
@ -2209,16 +2210,6 @@ public class ApplicationServiceCETest {
|
|||
|
||||
ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection();
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap())
|
||||
.hasSize(2);
|
||||
unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.keySet()
|
||||
.forEach(key -> assertThat(key)
|
||||
.isEqualTo(unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.get(key)));
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultResources()).isNotNull();
|
||||
assertThat(unpublishedCollection.getDefaultResources().getPageId())
|
||||
.isEqualTo(application.getPages().get(0).getId());
|
||||
|
|
@ -2325,7 +2316,7 @@ public class ApplicationServiceCETest {
|
|||
.collectList();
|
||||
|
||||
Map<String, List<String>> originalResourceIds = new HashMap<>();
|
||||
Mono<Application> resultMono = originalApplicationMono
|
||||
Tuple4<ActionCollectionDTO, ActionDTO, LayoutDTO, Application> tuple4 = originalApplicationMono
|
||||
.zipWhen(application -> newPageService.findPageById(
|
||||
application.getPages().get(0).getId(), READ_PAGES, false))
|
||||
.flatMap(tuple -> {
|
||||
|
|
@ -2429,53 +2420,51 @@ public class ApplicationServiceCETest {
|
|||
testPage.getId(), testPage.getApplicationId(), layout.getId(), layout),
|
||||
Mono.just(tuple.getT3()));
|
||||
})
|
||||
.flatMap(tuple -> {
|
||||
List<String> pageIds = new ArrayList<>(), collectionIds = new ArrayList<>();
|
||||
ActionCollectionDTO collectionDTO = tuple.getT1();
|
||||
collectionIds.add(collectionDTO.getId());
|
||||
tuple.getT4().getPages().forEach(page -> pageIds.add(page.getId()));
|
||||
.block();
|
||||
|
||||
originalResourceIds.put("pageIds", pageIds);
|
||||
originalResourceIds.put("collectionIds", collectionIds);
|
||||
List<String> pageIds = new ArrayList<>(), collectionIds = new ArrayList<>();
|
||||
ActionCollectionDTO collectionDTO = tuple4.getT1();
|
||||
collectionIds.add(collectionDTO.getId());
|
||||
tuple4.getT4().getPages().forEach(page -> pageIds.add(page.getId()));
|
||||
|
||||
String deletedActionIdWithinActionCollection =
|
||||
String.valueOf(collectionDTO.getDefaultToBranchedActionIdsMap().values().stream()
|
||||
.findAny()
|
||||
.orElse(null));
|
||||
originalResourceIds.put("pageIds", pageIds);
|
||||
originalResourceIds.put("collectionIds", collectionIds);
|
||||
|
||||
return newActionService
|
||||
.deleteUnpublishedAction(deletedActionIdWithinActionCollection)
|
||||
.thenMany(newActionService.findAllByApplicationIdAndViewMode(
|
||||
tuple.getT4().getId(), false, READ_ACTIONS, null))
|
||||
.collectList()
|
||||
.flatMap(actionList -> {
|
||||
List<String> actionIds = actionList.stream()
|
||||
.map(BaseDomain::getId)
|
||||
.collect(Collectors.toList());
|
||||
originalResourceIds.put("actionIds", actionIds);
|
||||
return applicationPageService.cloneApplication(
|
||||
tuple.getT4().getId(), null);
|
||||
});
|
||||
String deletedActionIdWithinActionCollection = newActionService
|
||||
.findByCollectionIdAndViewMode(collectionDTO.getId(), false, null)
|
||||
.blockFirst()
|
||||
.getId();
|
||||
|
||||
Application application1 = newActionService
|
||||
.deleteUnpublishedAction(deletedActionIdWithinActionCollection)
|
||||
.thenMany(newActionService.findAllByApplicationIdAndViewMode(
|
||||
tuple4.getT4().getId(), false, READ_ACTIONS, null))
|
||||
.collectList()
|
||||
.flatMap(actionList -> {
|
||||
List<String> actionIds =
|
||||
actionList.stream().map(BaseDomain::getId).collect(Collectors.toList());
|
||||
originalResourceIds.put("actionIds", actionIds);
|
||||
return applicationPageService.cloneApplication(
|
||||
tuple4.getT4().getId(), null);
|
||||
})
|
||||
.cache();
|
||||
.block();
|
||||
|
||||
StepVerifier.create(resultMono.zipWhen(application -> Mono.zip(
|
||||
StepVerifier.create(Mono.zip(
|
||||
newActionService
|
||||
.findAllByApplicationIdAndViewMode(application.getId(), false, READ_ACTIONS, null)
|
||||
.findAllByApplicationIdAndViewMode(application1.getId(), false, READ_ACTIONS, null)
|
||||
.collectList(),
|
||||
actionCollectionService
|
||||
.findAllByApplicationIdAndViewMode(application.getId(), false, READ_ACTIONS, null)
|
||||
.findAllByApplicationIdAndViewMode(application1.getId(), false, READ_ACTIONS, null)
|
||||
.collectList(),
|
||||
newPageService
|
||||
.findNewPagesByApplicationId(application.getId(), READ_PAGES)
|
||||
.findNewPagesByApplicationId(application1.getId(), READ_PAGES)
|
||||
.collectList(),
|
||||
defaultPermissionGroupsMono)))
|
||||
defaultPermissionGroupsMono))
|
||||
.assertNext(tuple -> {
|
||||
Application application = tuple.getT1(); // cloned application
|
||||
List<NewAction> actionList = tuple.getT2().getT1();
|
||||
List<ActionCollection> actionCollectionList = tuple.getT2().getT2();
|
||||
List<NewPage> pageList = tuple.getT2().getT3();
|
||||
List<PermissionGroup> permissionGroups = tuple.getT2().getT4();
|
||||
List<NewAction> actionList = tuple.getT1();
|
||||
List<ActionCollection> actionCollectionList = tuple.getT2();
|
||||
List<NewPage> pageList = tuple.getT3();
|
||||
List<PermissionGroup> permissionGroups = tuple.getT4();
|
||||
|
||||
PermissionGroup adminPermissionGroup = permissionGroups.stream()
|
||||
.filter(permissionGroup -> permissionGroup.getName().startsWith(ADMINISTRATOR))
|
||||
|
|
@ -2517,17 +2506,17 @@ public class ApplicationServiceCETest {
|
|||
viewerPermissionGroup.getId()))
|
||||
.build();
|
||||
|
||||
assertThat(application).isNotNull();
|
||||
assertThat(application.isAppIsExample()).isFalse();
|
||||
assertThat(application.getId()).isNotNull();
|
||||
assertThat(application.getName())
|
||||
assertThat(application1).isNotNull();
|
||||
assertThat(application1.isAppIsExample()).isFalse();
|
||||
assertThat(application1.getId()).isNotNull();
|
||||
assertThat(application1.getName())
|
||||
.isEqualTo(
|
||||
"ApplicationServiceTest-clone-application-deleted-action-within-collection Copy");
|
||||
assertThat(application.getPolicies()).containsAll(Set.of(manageAppPolicy, readAppPolicy));
|
||||
assertThat(application.getWorkspaceId()).isEqualTo(workspaceId);
|
||||
assertThat(application.getModifiedBy()).isEqualTo("api_user");
|
||||
assertThat(application.getUpdatedAt()).isNotNull();
|
||||
List<ApplicationPage> pages = application.getPages();
|
||||
assertThat(application1.getPolicies()).containsAll(Set.of(manageAppPolicy, readAppPolicy));
|
||||
assertThat(application1.getWorkspaceId()).isEqualTo(workspaceId);
|
||||
assertThat(application1.getModifiedBy()).isEqualTo("api_user");
|
||||
assertThat(application1.getUpdatedAt()).isNotNull();
|
||||
List<ApplicationPage> pages = application1.getPages();
|
||||
Set<String> pageIdsFromApplication =
|
||||
pages.stream().map(ApplicationPage::getId).collect(Collectors.toSet());
|
||||
Set<String> pageIdsFromDb =
|
||||
|
|
@ -2538,7 +2527,7 @@ public class ApplicationServiceCETest {
|
|||
assertThat(pageList).isNotEmpty();
|
||||
for (NewPage page : pageList) {
|
||||
assertThat(page.getPolicies()).containsAll(Set.of(managePagePolicy, readPagePolicy));
|
||||
assertThat(page.getApplicationId()).isEqualTo(application.getId());
|
||||
assertThat(page.getApplicationId()).isEqualTo(application1.getId());
|
||||
}
|
||||
|
||||
assertThat(pageList).isNotEmpty();
|
||||
|
|
@ -2546,12 +2535,12 @@ public class ApplicationServiceCETest {
|
|||
assertThat(newPage.getDefaultResources()).isNotNull();
|
||||
assertThat(newPage.getDefaultResources().getPageId()).isEqualTo(newPage.getId());
|
||||
assertThat(newPage.getDefaultResources().getApplicationId())
|
||||
.isEqualTo(application.getId());
|
||||
.isEqualTo(application1.getId());
|
||||
|
||||
newPage.getUnpublishedPage().getLayouts().forEach(layout -> {
|
||||
assertThat(layout.getLayoutOnLoadActions()).hasSize(2);
|
||||
assertThat(layout.getLayoutOnLoadActions()).hasSize(1);
|
||||
layout.getLayoutOnLoadActions().forEach(dslActionDTOS -> {
|
||||
assertThat(dslActionDTOS).hasSize(1);
|
||||
assertThat(dslActionDTOS).hasSize(2);
|
||||
dslActionDTOS.forEach(actionDTO -> {
|
||||
assertThat(actionDTO.getId()).isEqualTo(actionDTO.getDefaultActionId());
|
||||
if (StringUtils.hasLength(actionDTO.getCollectionId())) {
|
||||
|
|
@ -2569,13 +2558,13 @@ public class ApplicationServiceCETest {
|
|||
assertThat(newAction.getDefaultResources().getActionId())
|
||||
.isEqualTo(newAction.getId());
|
||||
assertThat(newAction.getDefaultResources().getApplicationId())
|
||||
.isEqualTo(application.getId());
|
||||
.isEqualTo(application1.getId());
|
||||
|
||||
ActionDTO action = newAction.getUnpublishedAction();
|
||||
assertThat(action.getDefaultResources()).isNotNull();
|
||||
assertThat(action.getDefaultResources().getPageId())
|
||||
.isEqualTo(application.getPages().get(0).getId());
|
||||
if (!StringUtils.isEmpty(action.getDefaultResources().getCollectionId())) {
|
||||
.isEqualTo(application1.getPages().get(0).getId());
|
||||
if (StringUtils.hasLength(action.getDefaultResources().getCollectionId())) {
|
||||
assertThat(action.getDefaultResources().getCollectionId())
|
||||
.isEqualTo(action.getCollectionId());
|
||||
}
|
||||
|
|
@ -2587,24 +2576,13 @@ public class ApplicationServiceCETest {
|
|||
assertThat(actionCollection.getDefaultResources().getCollectionId())
|
||||
.isEqualTo(actionCollection.getId());
|
||||
assertThat(actionCollection.getDefaultResources().getApplicationId())
|
||||
.isEqualTo(application.getId());
|
||||
.isEqualTo(application1.getId());
|
||||
|
||||
ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection();
|
||||
|
||||
// We should have single entry as other action is deleted from the parent application
|
||||
assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap())
|
||||
.hasSize(1);
|
||||
unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.keySet()
|
||||
.forEach(key -> assertThat(key)
|
||||
.isEqualTo(unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.get(key)));
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultResources()).isNotNull();
|
||||
assertThat(unpublishedCollection.getDefaultResources().getPageId())
|
||||
.isEqualTo(application.getPages().get(0).getId());
|
||||
.isEqualTo(application1.getPages().get(0).getId());
|
||||
});
|
||||
})
|
||||
.verifyComplete();
|
||||
|
|
@ -2775,7 +2753,7 @@ public class ApplicationServiceCETest {
|
|||
Application.NavigationSetting appNavigationSetting = new Application.NavigationSetting();
|
||||
appNavigationSetting.setOrientation("top");
|
||||
testApplication.getUnpublishedApplicationDetail().setNavigationSetting(appNavigationSetting);
|
||||
Mono<Tuple3<NewAction, ActionCollection, NewPage>> resultMono = applicationPageService
|
||||
Mono<Tuple4<NewAction, ActionCollection, NewPage, NewAction>> resultMono = applicationPageService
|
||||
.createApplication(testApplication, workspaceId)
|
||||
.flatMap(application -> {
|
||||
PageDTO page = new PageDTO();
|
||||
|
|
@ -2827,6 +2805,10 @@ public class ApplicationServiceCETest {
|
|||
.flatMap(tuple1 -> {
|
||||
ActionDTO savedAction = tuple1.getT1();
|
||||
ActionCollectionDTO savedActionCollection = tuple1.getT2();
|
||||
String actionId = savedActionCollection
|
||||
.getActions()
|
||||
.get(0)
|
||||
.getId();
|
||||
return applicationPageService
|
||||
.publish(testApplication.getId(), true)
|
||||
.then(applicationPageService.deleteUnpublishedPage(page.getId()))
|
||||
|
|
@ -2836,24 +2818,18 @@ public class ApplicationServiceCETest {
|
|||
this.getArchivedResource(savedAction.getId(), NewAction.class),
|
||||
(Mono<ActionCollection>) this.getArchivedResource(
|
||||
savedActionCollection.getId(), ActionCollection.class),
|
||||
(Mono<NewPage>) this.getArchivedResource(page.getId(), NewPage.class)));
|
||||
(Mono<NewPage>) this.getArchivedResource(page.getId(), NewPage.class),
|
||||
(Mono<NewAction>) this.getArchivedResource(actionId, NewAction.class)));
|
||||
});
|
||||
})
|
||||
.cache();
|
||||
|
||||
Mono<NewAction> archivedActionFromActionCollectionMono = resultMono.flatMap(tuple -> {
|
||||
final Optional<String> actionId =
|
||||
tuple.getT2().getUnpublishedCollection().getDefaultToBranchedActionIdsMap().values().stream()
|
||||
.findFirst();
|
||||
return (Mono<NewAction>) this.getArchivedResource(actionId.get(), NewAction.class);
|
||||
});
|
||||
|
||||
StepVerifier.create(resultMono.zipWith(archivedActionFromActionCollectionMono))
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(tuple -> {
|
||||
NewAction archivedAction = tuple.getT1().getT1();
|
||||
ActionCollection archivedActionCollection = tuple.getT1().getT2();
|
||||
NewPage archivedPage = tuple.getT1().getT3();
|
||||
NewAction archivedActionFromActionCollection = tuple.getT2();
|
||||
NewAction archivedAction = tuple.getT1();
|
||||
ActionCollection archivedActionCollection = tuple.getT2();
|
||||
NewPage archivedPage = tuple.getT3();
|
||||
NewAction archivedActionFromActionCollection = tuple.getT4();
|
||||
|
||||
assertThat(archivedAction.getDeletedAt()).isNotNull();
|
||||
|
||||
|
|
@ -3747,7 +3723,7 @@ public class ApplicationServiceCETest {
|
|||
String appName = "deleteApplicationWithPagesAndActions";
|
||||
testApplication.setName(appName);
|
||||
|
||||
Mono<Tuple3<NewAction, ActionCollection, NewPage>> resultMono = applicationPageService
|
||||
Mono<Tuple4<NewAction, ActionCollection, NewPage, NewAction>> resultMono = applicationPageService
|
||||
.createApplication(testApplication, workspaceId)
|
||||
.flatMap(application -> {
|
||||
PageDTO page = new PageDTO();
|
||||
|
|
@ -3804,29 +3780,31 @@ public class ApplicationServiceCETest {
|
|||
.findById(page.getApplicationId(), MANAGE_APPLICATIONS)
|
||||
.flatMap(application ->
|
||||
applicationPageService.deleteApplication(application.getId()))
|
||||
.flatMap(ignored -> Mono.zip(
|
||||
(Mono<NewAction>)
|
||||
this.getArchivedResource(savedAction.getId(), NewAction.class),
|
||||
(Mono<ActionCollection>) this.getArchivedResource(
|
||||
savedActionCollection.getId(), ActionCollection.class),
|
||||
(Mono<NewPage>) this.getArchivedResource(page.getId(), NewPage.class)));
|
||||
.flatMap(ignored -> {
|
||||
final String actionId = savedActionCollection
|
||||
.getActions()
|
||||
.get(0)
|
||||
.getId();
|
||||
return Mono.zip(
|
||||
(Mono<NewAction>) this.getArchivedResource(
|
||||
savedAction.getId(), NewAction.class),
|
||||
(Mono<ActionCollection>) this.getArchivedResource(
|
||||
savedActionCollection.getId(), ActionCollection.class),
|
||||
(Mono<NewPage>)
|
||||
this.getArchivedResource(page.getId(), NewPage.class),
|
||||
(Mono<NewAction>)
|
||||
this.getArchivedResource(actionId, NewAction.class));
|
||||
});
|
||||
});
|
||||
})
|
||||
.cache();
|
||||
|
||||
Mono<NewAction> archivedActionFromActionCollectionMono = resultMono.flatMap(tuple -> {
|
||||
final Optional<String> actionId =
|
||||
tuple.getT2().getUnpublishedCollection().getDefaultToBranchedActionIdsMap().values().stream()
|
||||
.findFirst();
|
||||
return (Mono<NewAction>) this.getArchivedResource(actionId.get(), NewAction.class);
|
||||
});
|
||||
|
||||
StepVerifier.create(resultMono.zipWith(archivedActionFromActionCollectionMono))
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(tuple -> {
|
||||
NewAction archivedAction = tuple.getT1().getT1();
|
||||
ActionCollection archivedActionCollection = tuple.getT1().getT2();
|
||||
NewPage archivedPage = tuple.getT1().getT3();
|
||||
NewAction archivedActionFromActionCollection = tuple.getT2();
|
||||
NewAction archivedAction = tuple.getT1();
|
||||
ActionCollection archivedActionCollection = tuple.getT2();
|
||||
NewPage archivedPage = tuple.getT3();
|
||||
NewAction archivedActionFromActionCollection = tuple.getT4();
|
||||
|
||||
assertThat(archivedAction.getDeletedAt()).isNotNull();
|
||||
|
||||
|
|
|
|||
|
|
@ -441,16 +441,6 @@ public class ApplicationForkingServiceTests {
|
|||
|
||||
ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection();
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap())
|
||||
.hasSize(1);
|
||||
unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.keySet()
|
||||
.forEach(key -> assertThat(key)
|
||||
.isEqualTo(unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.get(key)));
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultResources()).isNotNull();
|
||||
assertThat(unpublishedCollection.getDefaultResources().getPageId())
|
||||
.isEqualTo(application.getPages().get(0).getId());
|
||||
|
|
@ -623,16 +613,6 @@ public class ApplicationForkingServiceTests {
|
|||
|
||||
ActionCollectionDTO unpublishedCollection = actionCollection.getUnpublishedCollection();
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultToBranchedActionIdsMap())
|
||||
.hasSize(1);
|
||||
unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.keySet()
|
||||
.forEach(key -> assertThat(key)
|
||||
.isEqualTo(unpublishedCollection
|
||||
.getDefaultToBranchedActionIdsMap()
|
||||
.get(key)));
|
||||
|
||||
assertThat(unpublishedCollection.getDefaultResources()).isNotNull();
|
||||
assertThat(unpublishedCollection.getDefaultResources().getPageId())
|
||||
.isEqualTo(application.getPages().get(0).getId());
|
||||
|
|
|
|||
|
|
@ -51,14 +51,6 @@
|
|||
"name": "testCollection",
|
||||
"pageId": "testPageId",
|
||||
"pluginId": "testPluginId",
|
||||
"defaultToBranchedActionIdsMap": [
|
||||
{
|
||||
"defaultTestActionId1": "testActionId1"
|
||||
},
|
||||
{
|
||||
"defaultTestActionId2": "testActionId2"
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"id": "testActionId1"
|
||||
|
|
@ -71,12 +63,7 @@
|
|||
"publishedCollection": {
|
||||
"name": "testCollection",
|
||||
"pageId": "testPageId",
|
||||
"pluginId": "testPluginId",
|
||||
"defaultToBranchedActionIdsMap": [
|
||||
{
|
||||
"defaultTestActionId1": "testActionId1"
|
||||
}
|
||||
]
|
||||
"pluginId": "testPluginId"
|
||||
}
|
||||
},
|
||||
"actionCollectionDTOWithModifiedActions": {
|
||||
|
|
@ -86,19 +73,6 @@
|
|||
"name": "testCollection",
|
||||
"pageId": "testPageId",
|
||||
"pluginId": "testPluginId",
|
||||
"defaultToBranchedActionIdsMap": [
|
||||
{
|
||||
"defaultTestActionId1": "testActionId1"
|
||||
},
|
||||
{
|
||||
"defaultTestActionId3": "testActionId3"
|
||||
}
|
||||
],
|
||||
"defaultToBranchedArchivedActionIdsMap": [
|
||||
{
|
||||
"defaultTestActionId2": "testActionId2"
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"id": "testActionId1"
|
||||
|
|
@ -106,11 +80,6 @@
|
|||
{
|
||||
"id": "testActionId3"
|
||||
}
|
||||
],
|
||||
"archivedActions": [
|
||||
{
|
||||
"id": "testActionId2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"actionCollectionAfterModifiedActions": {
|
||||
|
|
@ -123,19 +92,6 @@
|
|||
"name": "testCollection",
|
||||
"pageId": "testPageId",
|
||||
"pluginId": "testPluginId",
|
||||
"defaultToBranchedActionIdsMap": [
|
||||
{
|
||||
"defaultTestActionId1": "testActionId1"
|
||||
},
|
||||
{
|
||||
"defaultTestActionId3": "testActionId3"
|
||||
}
|
||||
],
|
||||
"defaultToBranchedArchivedActionIdsMap": [
|
||||
{
|
||||
"defaultTestActionId2": "testActionId2"
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"id": "testActionId1"
|
||||
|
|
@ -143,22 +99,12 @@
|
|||
{
|
||||
"id": "testActionId3"
|
||||
}
|
||||
],
|
||||
"archivedActions": [
|
||||
{
|
||||
"id": "testActionId2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"publishedCollection": {
|
||||
"name": "testCollection",
|
||||
"pageId": "testPageId",
|
||||
"pluginId": "testPluginId",
|
||||
"defaultToBranchedActionIdsMap": [
|
||||
{
|
||||
"defaultTestActionId1": "testActionId1"
|
||||
}
|
||||
]
|
||||
"pluginId": "testPluginId"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user