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
 (#47)

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 authored and exo-swf committed Apr 30, 2024
1 parent b5b6c81 commit c778f29
Show file tree
Hide file tree
Showing 18 changed files with 177 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 c778f29

Please sign in to comment.