Merge pull request #5020 from appsmithorg/feature/page-order-api
Feature/page order api
This commit is contained in:
commit
df38f9d311
|
|
@ -93,6 +93,16 @@ public class ApplicationController extends BaseController<ApplicationService, Ap
|
|||
.map(updatedApplication -> new ResponseDTO<>(HttpStatus.OK.value(), updatedApplication, null));
|
||||
}
|
||||
|
||||
@PutMapping("/{applicationId}/page/{pageId}/reorder")
|
||||
public Mono<ResponseDTO<Application>> reorderPage(
|
||||
@PathVariable String applicationId,
|
||||
@PathVariable String pageId,
|
||||
@RequestParam Integer order
|
||||
) {
|
||||
return applicationPageService.reorderPage(applicationId, pageId, order)
|
||||
.map(updatedApplication -> new ResponseDTO<>(HttpStatus.OK.value(), updatedApplication, null));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public Mono<ResponseDTO<Application>> delete(@PathVariable String id) {
|
||||
log.debug("Going to delete application with id: {}", id);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ public class ApplicationPage {
|
|||
|
||||
Boolean isDefault;
|
||||
|
||||
Integer order;
|
||||
|
||||
@JsonIgnore
|
||||
public boolean isDefault() {
|
||||
return Boolean.TRUE.equals(isDefault);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import com.appsmith.server.domains.Sequence;
|
|||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.domains.UserData;
|
||||
import com.appsmith.server.domains.UserRole;
|
||||
import com.appsmith.server.domains.ApplicationPage;
|
||||
import com.appsmith.server.dtos.ActionDTO;
|
||||
import com.appsmith.server.dtos.DslActionDTO;
|
||||
import com.appsmith.server.dtos.OrganizationPluginStatus;
|
||||
|
|
@ -2454,7 +2455,7 @@ public class DatabaseChangelog {
|
|||
.users(adminUsernames).build();
|
||||
application.getPolicies().add(newExportAppPolicy);
|
||||
}
|
||||
|
||||
|
||||
mongoTemplate.save(application);
|
||||
}
|
||||
}
|
||||
|
|
@ -2494,7 +2495,6 @@ public class DatabaseChangelog {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@ChangeSet(order = "073", id = "mongo-form-merge-update-commands", author = "")
|
||||
public void migrateUpdateOneToUpdateManyMongoFormCommand(MongockTemplate mongockTemplate) {
|
||||
|
||||
|
|
@ -2601,4 +2601,33 @@ public class DatabaseChangelog {
|
|||
mongoTemplate.save(user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* - Older order file where not present for the pages created within the application because page reordering with in
|
||||
* the application was not supported.
|
||||
* - New Form order field will be added to the Page object and is used to order the pages with in the application
|
||||
* Since the previously created pages doesnt have the order, we will be updating/adding order to all the previously
|
||||
* created pages of all the application present.
|
||||
* - []
|
||||
*/
|
||||
@ChangeSet(order = "075", id = "add-and-update-order-for-all-pages", author = "")
|
||||
public void addOrderToAllPagesOfApplication(MongoTemplate mongoTemplate) {
|
||||
for (Application application : mongoTemplate.findAll(Application.class)) {
|
||||
if(application.getPages() != null) {
|
||||
int i = 0;
|
||||
for (ApplicationPage page : application.getPages()) {
|
||||
page.setOrder(i);
|
||||
i++;
|
||||
}
|
||||
if(application.getPublishedPages() != null) {
|
||||
i = 0;
|
||||
for (ApplicationPage page : application.getPublishedPages()) {
|
||||
page.setOrder(i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
mongoTemplate.save(application);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ package com.appsmith.server.repositories;
|
|||
|
||||
import com.appsmith.server.acl.AclPermission;
|
||||
import com.appsmith.server.domains.Application;
|
||||
import com.appsmith.server.domains.ApplicationPage;
|
||||
import com.mongodb.client.result.UpdateResult;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface CustomApplicationRepository extends AppsmithRepository<Application> {
|
||||
|
|
@ -20,7 +22,9 @@ public interface CustomApplicationRepository extends AppsmithRepository<Applicat
|
|||
|
||||
Flux<Application> findByClonedFromApplicationId(String applicationId, AclPermission permission);
|
||||
|
||||
Mono<UpdateResult> addPageToApplication(String applicationId, String pageId, boolean isDefault);
|
||||
Mono<UpdateResult> addPageToApplication(String applicationId, String pageId, boolean isDefault, Integer order);
|
||||
|
||||
Mono<UpdateResult> setPages(String applicationId, List<ApplicationPage> pages);
|
||||
|
||||
Mono<UpdateResult> setDefaultPage(String applicationId, String pageId);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,11 +73,20 @@ public class CustomApplicationRepositoryImpl extends BaseAppsmithRepositoryImpl<
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<UpdateResult> addPageToApplication(String applicationId, String pageId, boolean isDefault) {
|
||||
final ApplicationPage applicationPage = new ApplicationPage(pageId, isDefault);
|
||||
public Mono<UpdateResult> addPageToApplication(String applicationId, String pageId, boolean isDefault, Integer order) {
|
||||
final ApplicationPage applicationPage = new ApplicationPage(pageId, isDefault, order);
|
||||
return mongoOperations.updateFirst(
|
||||
Query.query(getIdCriteria(applicationId)),
|
||||
new Update().addToSet(FieldName.PAGES, applicationPage),
|
||||
new Update().addToSet(fieldName(QApplication.application.pages), applicationPage),
|
||||
Application.class
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<UpdateResult> setPages(String applicationId, List<ApplicationPage> pages) {
|
||||
return mongoOperations.updateFirst(
|
||||
Query.query(getIdCriteria(applicationId)),
|
||||
new Update().set(fieldName(QApplication.application.pages), pages),
|
||||
Application.class
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,4 +38,6 @@ public interface ApplicationPageService {
|
|||
void generateAndSetPagePolicies(Application application, PageDTO page);
|
||||
|
||||
Mono<Void> sendApplicationPublishedEvent(Application application);
|
||||
|
||||
Mono<Application> reorderPage(String applicationId, String pageId, Integer order);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,8 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
|
|||
*/
|
||||
@Override
|
||||
public Mono<UpdateResult> addPageToApplication(Application application, PageDTO page, Boolean isDefault) {
|
||||
return applicationRepository.addPageToApplication(application.getId(), page.getId(), isDefault)
|
||||
Integer order = application.getPages() != null ? application.getPages().size() : 0;
|
||||
return applicationRepository.addPageToApplication(application.getId(), page.getId(), isDefault, order)
|
||||
.doOnSuccess(result -> {
|
||||
if (result.getModifiedCount() != 1) {
|
||||
log.error("Add page to application didn't update anything, probably because application wasn't found.");
|
||||
|
|
@ -667,4 +668,55 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
|
|||
});
|
||||
}
|
||||
|
||||
/** This function walks through all the pages and reorders them and updates the order as per the user preference.
|
||||
* A page can be moved up or down from the current position and accordingly the order of the remaining page changes.
|
||||
* @param applicationId The id of the Application
|
||||
* @param pageId Targetted page id
|
||||
* @param order New order for the selected page
|
||||
* @return Application object with the latest order
|
||||
**/
|
||||
@Override
|
||||
public Mono<Application> reorderPage(String applicationId, String pageId, Integer order) {
|
||||
return applicationService.findById(applicationId, MANAGE_APPLICATIONS)
|
||||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.APPLICATION, applicationId)))
|
||||
.flatMap(application -> {
|
||||
// Update the order in unpublished pages here, since this should only ever happen in edit mode.
|
||||
final List<ApplicationPage> pages = application.getPages();
|
||||
|
||||
ApplicationPage foundPage = null;
|
||||
for (final ApplicationPage page : pages) {
|
||||
if (pageId.equals(page.getId())) {
|
||||
foundPage = page;
|
||||
}
|
||||
}
|
||||
|
||||
/* there are two cases where page is re-ordered. Lets assume there are five pages 1,2,3,4,5
|
||||
* Case 1(isMovingUp == true): p5 to p2, order of p2,p3,p4 increases by 1.
|
||||
*
|
||||
* Case 2(isMovingUp == false): p2 to p5, order of p3,p4,p5 decreases by 1.
|
||||
**/
|
||||
if(foundPage != null) {
|
||||
boolean isMovingUp = order < foundPage.getOrder();
|
||||
if(isMovingUp) {
|
||||
for (final ApplicationPage page : pages) {
|
||||
if (page.getOrder() < foundPage.getOrder() && page.getOrder() >= order) {
|
||||
page.setOrder(page.getOrder()+1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (final ApplicationPage page : pages) {
|
||||
if (page.getOrder() > foundPage.getOrder() && page.getOrder() <= order) {
|
||||
page.setOrder(page.getOrder()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
//set the selected page order to the given order
|
||||
foundPage.setOrder(order);
|
||||
}
|
||||
return applicationRepository
|
||||
.setPages(applicationId, pages)
|
||||
.then(applicationService.getById(applicationId));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -766,6 +766,7 @@ public class ApplicationServiceTest {
|
|||
ApplicationPage applicationPage = new ApplicationPage();
|
||||
applicationPage.setId(newPage.getId());
|
||||
applicationPage.setIsDefault(false);
|
||||
applicationPage.setOrder(1);
|
||||
|
||||
StepVerifier
|
||||
.create(applicationService.findById(newPage.getApplicationId(), MANAGE_APPLICATIONS))
|
||||
|
|
@ -811,25 +812,37 @@ public class ApplicationServiceTest {
|
|||
Mono<Application> updatedDefaultPageApplicationMono = applicationMono
|
||||
.flatMap(application -> applicationPageService.makePageDefault(application.getId(), newPage.getId()));
|
||||
|
||||
ApplicationPage unpublishedEditedPage = new ApplicationPage();
|
||||
unpublishedEditedPage.setId(newPage.getId());
|
||||
unpublishedEditedPage.setIsDefault(true);
|
||||
|
||||
ApplicationPage publishedEditedPage = new ApplicationPage();
|
||||
publishedEditedPage.setId(newPage.getId());
|
||||
publishedEditedPage.setIsDefault(false);
|
||||
|
||||
ApplicationPage unpublishedEditedPage = new ApplicationPage();
|
||||
unpublishedEditedPage.setId(newPage.getId());
|
||||
unpublishedEditedPage.setIsDefault(true);
|
||||
|
||||
StepVerifier
|
||||
.create(updatedDefaultPageApplicationMono)
|
||||
.assertNext(editedApplication -> {
|
||||
|
||||
List<ApplicationPage> publishedPages = editedApplication.getPublishedPages();
|
||||
assertThat(publishedPages).size().isEqualTo(2);
|
||||
assertThat(publishedPages).containsAnyOf(publishedEditedPage);
|
||||
boolean isFound = false;
|
||||
for( ApplicationPage page: publishedPages) {
|
||||
if(page.getId().equals(publishedEditedPage.getId()) && page.getIsDefault().equals(publishedEditedPage.getIsDefault())) {
|
||||
isFound = true;
|
||||
}
|
||||
}
|
||||
assertThat(isFound).isTrue();
|
||||
|
||||
List<ApplicationPage> editedApplicationPages = editedApplication.getPages();
|
||||
assertThat(editedApplicationPages.size()).isEqualTo(2);
|
||||
assertThat(editedApplicationPages).containsAnyOf(unpublishedEditedPage);
|
||||
isFound = false;
|
||||
for( ApplicationPage page: editedApplicationPages) {
|
||||
if(page.getId().equals(unpublishedEditedPage.getId()) && page.getIsDefault().equals(unpublishedEditedPage.getIsDefault())) {
|
||||
isFound = true;
|
||||
}
|
||||
}
|
||||
assertThat(isFound).isTrue();
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
|
@ -873,7 +886,13 @@ public class ApplicationServiceTest {
|
|||
.assertNext(viewApplication -> {
|
||||
List<ApplicationPage> editedApplicationPages = viewApplication.getPages();
|
||||
assertThat(editedApplicationPages.size()).isEqualTo(2);
|
||||
assertThat(editedApplicationPages).containsAnyOf(applicationPage);
|
||||
boolean isFound = false;
|
||||
for( ApplicationPage page: editedApplicationPages) {
|
||||
if(page.getId().equals(applicationPage.getId()) && page.getIsDefault().equals(applicationPage.getIsDefault())) {
|
||||
isFound = true;
|
||||
}
|
||||
}
|
||||
assertThat(isFound).isTrue();
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.appsmith.server.domains.Layout;
|
|||
import com.appsmith.server.domains.NewAction;
|
||||
import com.appsmith.server.domains.Plugin;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.domains.ApplicationPage;
|
||||
import com.appsmith.server.dtos.ActionDTO;
|
||||
import com.appsmith.server.dtos.LayoutDTO;
|
||||
import com.appsmith.server.dtos.PageDTO;
|
||||
|
|
@ -44,6 +45,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.appsmith.server.acl.AclPermission.MANAGE_PAGES;
|
||||
import static com.appsmith.server.acl.AclPermission.READ_ACTIONS;
|
||||
|
|
@ -385,6 +387,127 @@ public class PageServiceTest {
|
|||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void reOrderPageFromHighOrderToLowOrder() {
|
||||
|
||||
User apiUser = userService.findByEmail("api_user").block();
|
||||
orgId = apiUser.getOrganizationIds().iterator().next();
|
||||
Application newApp = new Application();
|
||||
newApp.setName(UUID.randomUUID().toString());
|
||||
|
||||
application = applicationPageService.createApplication(newApp, orgId).block();
|
||||
applicationId = application.getId();
|
||||
final String[] pageIds = new String[4];
|
||||
|
||||
PageDTO testPage1 = new PageDTO();
|
||||
testPage1.setName("Page2");
|
||||
testPage1.setApplicationId(applicationId);
|
||||
Mono<Application> applicationPageReOrdered = applicationPageService.createPage(testPage1)
|
||||
.flatMap(pageDTO -> {
|
||||
PageDTO testPage = new PageDTO();
|
||||
testPage.setName("Page3");
|
||||
testPage.setApplicationId(applicationId);
|
||||
return applicationPageService.createPage(testPage);
|
||||
})
|
||||
.flatMap(pageDTO -> {
|
||||
PageDTO testPage = new PageDTO();
|
||||
testPage.setName("Page4");
|
||||
testPage.setApplicationId(applicationId);
|
||||
return applicationPageService.createPage(testPage);
|
||||
})
|
||||
.flatMap(pageDTO -> applicationService.getById(pageDTO.getApplicationId()))
|
||||
.flatMap( application -> {
|
||||
pageIds[0] = application.getPages().get(0).getId();
|
||||
pageIds[1] = application.getPages().get(1).getId();
|
||||
pageIds[2] = application.getPages().get(2).getId();
|
||||
pageIds[3] = application.getPages().get(3).getId();
|
||||
return applicationPageService.reorderPage(application.getId(), application.getPages().get(3).getId(), 1);
|
||||
});
|
||||
|
||||
StepVerifier
|
||||
.create(applicationPageReOrdered)
|
||||
.assertNext(application -> {
|
||||
final List<ApplicationPage> pages = application.getPages();
|
||||
assertThat(application.getPages().size()).isEqualTo(4);
|
||||
for(ApplicationPage page : pages) {
|
||||
if(pageIds[0].equals(page.getId())) {
|
||||
assertThat(page.getOrder()).isEqualTo(0);
|
||||
}
|
||||
if(pageIds[1].equals(page.getId())) {
|
||||
assertThat(page.getOrder()).isEqualTo(2);
|
||||
}
|
||||
if(pageIds[2].equals(page.getId())) {
|
||||
assertThat(page.getOrder()).isEqualTo(3);
|
||||
}
|
||||
if(pageIds[3].equals(page.getId())) {
|
||||
assertThat(page.getOrder()).isEqualTo(1);
|
||||
}
|
||||
}
|
||||
} )
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value ="api_user")
|
||||
public void reOrderPageFromLowOrderToHighOrder() {
|
||||
|
||||
User apiUser = userService.findByEmail("api_user").block();
|
||||
orgId = apiUser.getOrganizationIds().iterator().next();
|
||||
Application newApp = new Application();
|
||||
newApp.setName(UUID.randomUUID().toString());
|
||||
|
||||
application = applicationPageService.createApplication(newApp, orgId).block();
|
||||
applicationId = application.getId();
|
||||
final String[] pageIds = new String[4];
|
||||
|
||||
PageDTO testPage1 = new PageDTO();
|
||||
testPage1.setName("Page2");
|
||||
testPage1.setApplicationId(applicationId);
|
||||
Mono<Application> applicationPageReOrdered = applicationPageService.createPage(testPage1)
|
||||
.flatMap(pageDTO -> {
|
||||
PageDTO testPage = new PageDTO();
|
||||
testPage.setName("Page3");
|
||||
testPage.setApplicationId(applicationId);
|
||||
return applicationPageService.createPage(testPage);
|
||||
})
|
||||
.flatMap(pageDTO -> {
|
||||
PageDTO testPage = new PageDTO();
|
||||
testPage.setName("Page4");
|
||||
testPage.setApplicationId(applicationId);
|
||||
return applicationPageService.createPage(testPage);
|
||||
})
|
||||
.flatMap(pageDTO -> applicationService.getById(pageDTO.getApplicationId()))
|
||||
.flatMap( application -> {
|
||||
pageIds[0] = application.getPages().get(0).getId();
|
||||
pageIds[1] = application.getPages().get(1).getId();
|
||||
pageIds[2] = application.getPages().get(2).getId();
|
||||
pageIds[3] = application.getPages().get(3).getId();
|
||||
return applicationPageService.reorderPage(application.getId(), application.getPages().get(0).getId(), 3);
|
||||
});
|
||||
|
||||
StepVerifier
|
||||
.create(applicationPageReOrdered)
|
||||
.assertNext(application -> {
|
||||
final List<ApplicationPage> pages = application.getPages();
|
||||
assertThat(application.getPages().size()).isEqualTo(4);
|
||||
for(ApplicationPage page : pages) {
|
||||
if(pageIds[0].equals(page.getId())) {
|
||||
assertThat(page.getOrder()).isEqualTo(3);
|
||||
}
|
||||
if(pageIds[1].equals(page.getId())) {
|
||||
assertThat(page.getOrder()).isEqualTo(0);
|
||||
}
|
||||
if(pageIds[2].equals(page.getId())) {
|
||||
assertThat(page.getOrder()).isEqualTo(1);
|
||||
}
|
||||
if(pageIds[3].equals(page.getId())) {
|
||||
assertThat(page.getOrder()).isEqualTo(2);
|
||||
}
|
||||
}
|
||||
} )
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@After
|
||||
public void purgeAllPages() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user