Skip to content

Commit

Permalink
feat: Allow to edit non compatible pages - MEED-5312 - Meeds-io/MIPs#131
Browse files Browse the repository at this point in the history


This change will allow to edit exiting pages layout which aren't compatible with the current layout editor. The upgrade of existing pages will be made manually using two dynamic sections.
  • Loading branch information
boubaker committed Apr 29, 2024
1 parent 1ad7ef6 commit ea24d34
Show file tree
Hide file tree
Showing 17 changed files with 167 additions and 211 deletions.
2 changes: 1 addition & 1 deletion layout-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<rest.api.doc.version>1.0</rest.api.doc.version>
<rest.api.doc.description>Layout Rest endpoints</rest.api.doc.description>

<exo.test.coverage.ratio>0.60</exo.test.coverage.ratio>
<exo.test.coverage.ratio>0.65</exo.test.coverage.ratio>
</properties>
<dependencies>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,12 @@
import org.exoplatform.commons.exception.ObjectNotFoundException;
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.social.rest.entity.SiteEntity;

import io.meeds.layout.model.PermissionUpdateModel;
import io.meeds.layout.model.SiteCreateModel;
import io.meeds.layout.model.SiteUpdateModel;
import io.meeds.layout.rest.model.SiteRestEntity;
import io.meeds.layout.rest.util.RestEntityBuilder;
import io.meeds.layout.service.PageLayoutService;
import io.meeds.layout.service.SiteLayoutService;

import io.swagger.v3.oas.annotations.Operation;
Expand All @@ -67,24 +66,21 @@ public class SiteLayoutRest {
@Autowired
private SiteLayoutService siteLayoutService;

@Autowired
private PageLayoutService pageLayoutService;

@GetMapping("{siteId}")
@Operation(summary = "Gets a specific site by its id", description = "Gets site by id", method = "GET")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Request fulfilled"),
@ApiResponse(responseCode = "403", description = "Forbidden"),
@ApiResponse(responseCode = "500", description = "Internal server error"),
})
public ResponseEntity<SiteRestEntity> getSiteById(
HttpServletRequest request,
@Parameter(description = "site id")
@PathVariable("siteId")
long siteId,
@Parameter(description = "Language used to retrieve names", required = false)
@RequestParam(name = "lang", required = false)
String lang) throws Exception {
public ResponseEntity<SiteEntity> getSiteById(
HttpServletRequest request,
@Parameter(description = "site id")
@PathVariable("siteId")
long siteId,
@Parameter(description = "Language used to retrieve names", required = false)
@RequestParam(name = "lang", required = false)
String lang) throws Exception {
try {
PortalConfig site = siteLayoutService.getSite(siteId, request.getRemoteUser());
Locale locale;
Expand All @@ -93,10 +89,9 @@ public ResponseEntity<SiteRestEntity> getSiteById(
} else {
locale = Locale.forLanguageTag(lang);
}
SiteRestEntity siteEntity = RestEntityBuilder.toSiteEntity(pageLayoutService,
site,
request,
locale);
SiteEntity siteEntity = RestEntityBuilder.toSiteEntity(site,
request,
locale);
return ResponseEntity.ok()
.eTag(String.valueOf(Objects.hash(siteEntity, locale)))
.body(siteEntity);
Expand All @@ -114,17 +109,17 @@ public ResponseEntity<SiteRestEntity> getSiteById(
@ApiResponse(responseCode = "403", description = "Forbidden"),
@ApiResponse(responseCode = "500", description = "Internal server error"),
})
public ResponseEntity<SiteRestEntity> getSite(
HttpServletRequest request,
@Parameter(description = "site type")
@RequestParam("siteType")
String siteType,
@Parameter(description = "site name")
@RequestParam("siteName")
String siteName,
@Parameter(description = "Language used to retrieve names", required = false)
@RequestParam(name = "lang", required = false)
String lang) throws Exception {
public ResponseEntity<SiteEntity> getSite(
HttpServletRequest request,
@Parameter(description = "site type")
@RequestParam("siteType")
String siteType,
@Parameter(description = "site name")
@RequestParam("siteName")
String siteName,
@Parameter(description = "Language used to retrieve names", required = false)
@RequestParam(name = "lang", required = false)
String lang) throws Exception {
try {
PortalConfig site = siteLayoutService.getSite(new SiteKey(siteType, siteName), request.getRemoteUser());
Locale locale;
Expand All @@ -133,10 +128,9 @@ public ResponseEntity<SiteRestEntity> getSite(
} else {
locale = Locale.forLanguageTag(lang);
}
SiteRestEntity siteEntity = RestEntityBuilder.toSiteEntity(pageLayoutService,
site,
request,
locale);
SiteEntity siteEntity = RestEntityBuilder.toSiteEntity(site,
request,
locale);
return ResponseEntity.ok()
.eTag(String.valueOf(Objects.hash(siteEntity, locale)))
.body(siteEntity);
Expand Down Expand Up @@ -214,17 +208,16 @@ public void updateSitePermissions(
@Operation(summary = "create a site", method = "POST", description = "This create a new site")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Request fulfilled"),
@ApiResponse(responseCode = "500", description = "Internal server error"), })
public ResponseEntity<SiteRestEntity> createSite(
HttpServletRequest request,
@Parameter(description = "site to create", required = true)
@RequestBody
SiteCreateModel createModel) throws Exception {
public ResponseEntity<SiteEntity> createSite(
HttpServletRequest request,
@Parameter(description = "site to create", required = true)
@RequestBody
SiteCreateModel createModel) throws Exception {
try {
PortalConfig site = siteLayoutService.createSite(createModel, request.getRemoteUser());
SiteRestEntity siteEntity = RestEntityBuilder.toSiteEntity(pageLayoutService,
site,
request,
request.getLocale());
SiteEntity siteEntity = RestEntityBuilder.toSiteEntity(site,
request,
request.getLocale());
return ResponseEntity.ok()
.eTag(String.valueOf(Objects.hash(siteEntity, request.getLocale())))
.body(siteEntity);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,11 @@
import org.exoplatform.portal.config.model.ModelObject;
import org.exoplatform.portal.config.model.Page;
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.mop.page.PageKey;
import org.exoplatform.portal.mop.rest.model.UserNodeRestEntity;
import org.exoplatform.portal.mop.service.LayoutService;
import org.exoplatform.social.rest.api.EntityBuilder;
import org.exoplatform.social.rest.entity.SiteEntity;

import io.meeds.layout.rest.model.LayoutModel;
import io.meeds.layout.rest.model.SiteRestEntity;
import io.meeds.layout.service.PageLayoutService;

import jakarta.servlet.http.HttpServletRequest;

Expand All @@ -50,39 +46,17 @@ public class RestEntityBuilder {
private RestEntityBuilder() {
}

public static SiteRestEntity toSiteEntity(PageLayoutService pageLayoutService,
PortalConfig site,
HttpServletRequest request,
Locale locale) throws Exception {
SiteEntity siteEntity = EntityBuilder.buildSiteEntity(site,
request,
true,
null,
true,
false,
false,
locale);
SiteRestEntity siteRestEntity = new SiteRestEntity(siteEntity);
List<UserNodeRestEntity> siteNavigations = siteEntity.getSiteNavigations();
computeCompatibilityWithEditor(pageLayoutService, siteRestEntity, siteNavigations);
return siteRestEntity;
}

private static void computeCompatibilityWithEditor(PageLayoutService pageLayoutService,
SiteRestEntity siteRestEntity,
List<UserNodeRestEntity> siteNavigations) {
if (CollectionUtils.isNotEmpty(siteNavigations)) {
siteNavigations.forEach(n -> {
PageKey pageKey = n.getPageKey();
if (n.isCanEditPage()) {
Page page = pageLayoutService.getPageLayout(pageKey);
siteRestEntity.getPagesCompatibility().put(pageKey.format(), page != null && isCompatibleWithEditor(page));
} else if (pageKey != null) {
siteRestEntity.getPagesCompatibility().put(pageKey.format(), false);
}
computeCompatibilityWithEditor(pageLayoutService, siteRestEntity, n.getChildren());
});
}
public static SiteEntity toSiteEntity(PortalConfig site,
HttpServletRequest request,
Locale locale) throws Exception {
return EntityBuilder.buildSiteEntity(site,
request,
true,
null,
true,
false,
false,
locale);
}

public static LayoutModel toLayoutModel(Page page, LayoutService layoutService, String expand) {
Expand Down Expand Up @@ -133,43 +107,4 @@ public static Page fromLayoutModel(LayoutModel layoutModel) {
return layoutModel.toPage();
}

private static boolean isCompatibleWithEditor(Page page) { // NOSONAR
ArrayList<ModelObject> children = page.getChildren();
if (CollectionUtils.isEmpty(children)) {
return true;
} else {
if (children.size() != 1) {
return false;
}
ModelObject parentContainer = children.get(0);
if (parentContainer != null
&& parentContainer instanceof Container appContainer
&& StringUtils.contains(appContainer.getTemplate(), "UIPageLayout.gtmpl")) {
return isChildrenOfTypeSection(appContainer);
} else if (parentContainer == null
|| !(parentContainer instanceof Container vAppContainer)
|| !StringUtils.contains(vAppContainer.getCssClass(), "VuetifyApp")) {
return false;
} else if (CollectionUtils.isEmpty(vAppContainer.getChildren())) {
return true;
} else {
parentContainer = vAppContainer.getChildren().get(0);
if (parentContainer == null
|| !(parentContainer instanceof Container appContainer)
|| !StringUtils.contains(appContainer.getCssClass(), "v-application")) {
return false;
}
return isChildrenOfTypeSection(appContainer);
}
}
}

private static boolean isChildrenOfTypeSection(Container appContainer) {
return appContainer.getChildren()
.stream()
.allMatch(c -> c instanceof Container container
&& (StringUtils.equals("GridContainer", container.getTemplate())
|| StringUtils.equals("FlexContainer", container.getTemplate())));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import org.apache.commons.collections4.CollectionUtils;
Expand All @@ -29,6 +30,7 @@

import com.google.javascript.jscomp.jarjar.com.google.re2j.Pattern;

import org.exoplatform.commons.addons.AddOnService;
import org.exoplatform.commons.exception.ObjectNotFoundException;
import org.exoplatform.portal.config.UserPortalConfigService;
import org.exoplatform.portal.config.model.Application;
Expand Down Expand Up @@ -81,6 +83,9 @@ public class PageLayoutService {
@Autowired
private UserPortalConfigService userPortalConfigService;

@Autowired
private AddOnService addOnService;

public List<PageContext> getPages(String siteTypeName,
String siteName,
String pageDisplayName,
Expand Down Expand Up @@ -122,7 +127,11 @@ public Page getPageLayout(PageKey pageKey,
}

public Page getPageLayout(PageKey pageKey) {
return layoutService.getPage(pageKey);
Page page = layoutService.getPage(pageKey);
if (page != null) {
expandAddonContainerChildren(page);
}
return page;
}

@SneakyThrows
Expand Down Expand Up @@ -165,7 +174,7 @@ public PageContext createPage(PageCreateModel pageModel,
public PageKey clonePage(PageKey pageKey,
String username) throws IllegalAccessException,
ObjectNotFoundException {
Page page = layoutService.getPage(pageKey);
Page page = getPageLayout(pageKey);
if (page == null) {
throw new ObjectNotFoundException(String.format(PAGE_NOT_EXISTS_MESSAGE, pageKey.format()));
} else if (!aclService.canEditPage(pageKey, username)) {
Expand Down Expand Up @@ -302,6 +311,22 @@ private PageType getPageType(String pageType) {
return StringUtils.isBlank(pageType) ? PageType.PAGE : PageType.valueOf(pageType.toUpperCase());
}

private void expandAddonContainerChildren(Container container) {
if (StringUtils.equals(container.getFactoryId(), "addonContainer")) {
List<Application<?>> applications = addOnService.getApplications(container.getName());
if (CollectionUtils.isNotEmpty(applications)) {
container.setChildren(new ArrayList<>(applications));
}
} else if (container.getChildren() != null) {
container.getChildren()
.stream()
.filter(Objects::nonNull)
.filter(Container.class::isInstance)
.map(Container.class::cast)
.forEach(this::expandAddonContainerChildren);
}
}

private void validateCSSInputs(ModelObject modelObject) {
String width;
String height;
Expand Down
Loading

0 comments on commit ea24d34

Please sign in to comment.