Create and edit steps for postal address asset

pull/10/head
Jens Pelzetter 2021-05-14 14:51:33 +02:00
parent bf62007391
commit c64155af7b
15 changed files with 553 additions and 4 deletions

View File

@ -19,6 +19,7 @@
package org.librecms.ui.contentsections.assets;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.AuthorizationRequired;
import org.librecms.contentsection.Asset;
import org.librecms.contentsection.AssetManager;
import org.librecms.contentsection.AssetRepository;
@ -36,6 +37,10 @@ import java.util.Optional;
import javax.inject.Inject;
import javax.mvc.Models;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
@ -312,4 +317,6 @@ public abstract class AbstractMvcAssetEditStep implements MvcAssetEditStep {
.orElse("");
}
}

View File

@ -370,7 +370,7 @@ public class AssetsController {
models.put("contentSection", section.getLabel());
models.put("assetType", assetType);
return "org/librecms/ui/contentsection/assetfolder/asset-type-not-found.xhtml";
return "org/librecms/ui/contentsection/assets/asset-type-not-found.xhtml";
}
private String showCreateStepNotAvailable(
@ -382,7 +382,7 @@ public class AssetsController {
models.put("folderPath", folderPath);
models.put("assetType", assetType);
return "org/librecms/ui/contentsection/assetfolder/create-step-not-available.xhtml";
return "org/librecms/ui/contentsection/assets/create-step-not-available.xhtml";
}

View File

@ -18,12 +18,35 @@
*/
package org.librecms.ui.contentsections.assets;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.AuthorizationRequired;
import org.librecms.assets.PostalAddress;
import org.librecms.contentsection.AssetManager;
import org.librecms.contentsection.AssetRepository;
import org.librecms.contentsection.FolderManager;
import org.librecms.ui.contentsections.AssetPermissionsChecker;
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.mvc.Controller;
import javax.mvc.Models;
import javax.transaction.Transactional;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
/**
*
@ -39,6 +62,322 @@ import javax.ws.rs.Path;
labelKey = "postaladdress.editstep.label",
supportedAssetType = PostalAddress.class
)
public class PostalAddressEditStep {
public class PostalAddressEditStep extends AbstractMvcAssetEditStep {
@Inject
private AssetStepsDefaultMessagesBundle messageBundle;
@Inject
private AssetManager assetManager;
@Inject
private AssetUi assetUi;
@Inject
private AssetRepository assetRepo;
@Inject
private FolderManager folderManager;
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private AssetPermissionsChecker assetPermissionsChecker;
@Inject
private Models models;
private Map<String, String> titleValues;
private List<String> unusedTitleLocales;
@Override
public Class<? extends MvcAssetEditStep> getStepClass() {
return PostalAddressEditStep.class;
}
@GET
@Path("/")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String showStep(
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
final String assetPath
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (AssetNotFoundException ex) {
return ex.showErrorMessage();
}
if (assetPermissionsChecker.canEditAsset(getAsset())) {
titleValues = getAsset()
.getTitle()
.getValues()
.entrySet()
.stream()
.collect(
Collectors.toMap(
entry -> entry.getKey().toString(),
entry -> entry.getValue()
)
);
final Set<Locale> titleLocales = getAsset()
.getTitle()
.getAvailableLocales();
unusedTitleLocales = globalizationHelper
.getAvailableLocales()
.stream()
.filter(locale -> !titleLocales.contains(locale))
.map(Locale::toString)
.collect(Collectors.toList());
return "org/librecms/ui/assets/postaladdress/edit-postaladdress.xhtml";
} else {
return assetUi.showAccessDenied(
getContentSection(),
getAsset(),
messageBundle.get("asset.edit.denied"));
}
}
public String getName() {
return getAsset().getDisplayName();
}
public PostalAddress getPostalAddress() {
return (PostalAddress) getAsset();
}
@POST
@Path("/name")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String updateName(
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
final String assetPath,
@FormParam("name") @DefaultValue("") final String name
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (AssetNotFoundException ex) {
return ex.showErrorMessage();
}
if (assetPermissionsChecker.canEditAsset(getAsset())) {
if (name.isEmpty() || name.matches("\\s*")) {
models.put("nameMissing", true);
return showStep(sectionIdentifier, assetPath);
}
getAsset().setDisplayName(name);
assetRepo.save(getAsset());
updateAssetPath();
return buildRedirectPathForStep();
} else {
return assetUi.showAccessDenied(
getContentSection(),
getAsset(),
messageBundle.get("asset.edit.denied"));
}
}
public Map<String, String> getTitleValues() {
return Collections.unmodifiableMap(titleValues);
}
public List<String> getUnusedTitleLocales() {
return Collections.unmodifiableList(unusedTitleLocales);
}
@POST
@Path("/title/@add")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String addTitle(
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
final String assetPath,
@FormParam("locale") final String localeParam,
@FormParam("value") final String value
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (AssetNotFoundException ex) {
return ex.showErrorMessage();
}
if (assetPermissionsChecker.canEditAsset(getAsset())) {
final Locale locale = new Locale(localeParam);
getAsset().getTitle().addValue(locale, value);
assetRepo.save(getAsset());
return buildRedirectPathForStep();
} else {
return assetUi.showAccessDenied(
getContentSection(),
getAsset(),
messageBundle.get("asset.edit.denied"));
}
}
@POST
@Path("/title/@edit/{locale}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String editTitle(
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
final String assetPath,
@PathParam("locale") final String localeParam,
@PathParam("value") final String value
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (AssetNotFoundException ex) {
return ex.showErrorMessage();
}
if (assetPermissionsChecker.canEditAsset(getAsset())) {
final Locale locale = new Locale(localeParam);
getAsset().getTitle().addValue(locale, value);
assetRepo.save(getAsset());
return buildRedirectPathForStep();
} else {
return assetUi.showAccessDenied(
getContentSection(),
getAsset(),
messageBundle.get("asset.edit.denied"));
}
}
@POST
@Path("/title/@remove/{locale}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String removeTitle(
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
final String assetPath,
@PathParam("locale") final String localeParam
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (AssetNotFoundException ex) {
return ex.showErrorMessage();
}
if (assetPermissionsChecker.canEditAsset(getAsset())) {
final Locale locale = new Locale(localeParam);
getAsset().getTitle().removeValue(locale);
assetRepo.save(getAsset());
return buildRedirectPathForStep();
} else {
return assetUi.showAccessDenied(
getContentSection(),
getAsset(),
messageBundle.get("asset.edit.denied"));
}
}
public String getAddress() {
return getPostalAddress().getAddress();
}
public String getPostalCode() {
return getPostalAddress().getPostalCode();
}
public String getCity() {
return getPostalAddress().getCity();
}
public String getState() {
return getPostalAddress().getState();
}
public String getIsoCountryCode() {
return getPostalAddress().getIsoCountryCode();
}
@POST
@Path("/properties")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String updateProperties(
@PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME)
final String assetPath,
@FormParam("address") final String address,
@FormParam("postalCode") final String postalCode,
@FormParam("city") final String city,
@FormParam("state") final String state,
@FormParam("isoCountryCode") final String isoCountryCode
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (AssetNotFoundException ex) {
return ex.showErrorMessage();
}
if (assetPermissionsChecker.canEditAsset(getAsset())) {
final PostalAddress postalAddress = getPostalAddress();
postalAddress.setAddress(address);
postalAddress.setCity(city);
postalAddress.setIsoCountryCode(isoCountryCode);
postalAddress.setPostalCode(postalCode);
postalAddress.setState(state);
assetRepo.save(postalAddress);
return buildRedirectPathForStep();
} else {
return assetUi.showAccessDenied(
getContentSection(),
getAsset(),
messageBundle.get("asset.edit.denied"));
}
}
public Map<String, String> getCountries() {
return Arrays
.stream(Locale.getISOCountries())
.map(country -> new Locale(country))
.collect(
Collectors.toMap(
Locale::toString,
locale -> locale.getDisplayCountry(globalizationHelper
.getNegotiatedLocale())
)
);
}
}

View File

@ -20,6 +20,7 @@ package org.librecms.ui.contenttypes;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.l10n.LocalizedString;
import org.libreccm.security.AuthorizationRequired;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.FolderManager;
@ -122,6 +123,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep {
@GET
@Path("/")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String showStep(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
@ -215,6 +217,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep {
*/
@POST
@Path("/name")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String updateName(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
@ -283,6 +286,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep {
*/
@POST
@Path("/title/@add")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String addTitle(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
@ -327,6 +331,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep {
*/
@POST
@Path("/title/@edit/{locale}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String editTitle(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
@ -370,6 +375,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep {
*/
@POST
@Path("/title/@remove/{locale}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String removeTitle(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)

View File

@ -0,0 +1,27 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/assets/asset.xhtml">
<ui:param name="activePage" value="asset" />
<ui:param name="title" value="#{CmsAdminMessages['contentsection.asset_access_denied.title']}" />
<ui:define name="breadcrumb">
<li aria-current="page" class="breadcrumb-item">
#{CmsAdminMessages['contentsection.asset_access_denied.breadcrumb']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<div class="alert alert-danger" role="alert">
#{CmsAdminMessages.getMessage('contentsection.asset_access_denied.message', [section, assetPath])}
</div>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,29 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/assets/asset.xhtml">
<ui:param name="activePage" value="asset" />
<ui:param name="title" value="#{CmsAdminMessages['contentsection.assets.asset_not_found.title']}" />
<ui:define name="breadcrumb">
<ui:include src="asset-breadcrumbs.xhtml" />
<li aria-current="page" class="breadcrumb-item">
#{CmsAdminMessages['contentsection.asset_not_found.breadcrumb']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<div class="alert alert-danger" role="alert">
#{CmsAdminMessages.getMessage('contentsection.asset.not_found.message', [section, assetPath])}
</div>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,28 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/assets/asset.xhtml">
<ui:param name="activePage" value="document" />
<ui:param name="title" value="#{CmsAdminMessages['contentsection.assets.asset_type.not_available.title']}" />
<ui:define name="breadcrumb">
<li aria-current="page" class="breadcrumb-item">
#{assetType}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<div class="alert alert-danger" role="alert">
#{CmsAdminMessages.getMessage('contentsection.assets.asset_type.not_available.message', [section, assetType])}
</div>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,57 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/contentsection.xhtml">
<ui:param name="activePage" value="assetFolders" />
<ui:param
name="title"
value="#{CmsAdminMessages['contentsection.assetfolders.title']}" />
<ui:define name="breadcrumb">
<c:choose>
<c:when test="#{AssetFolderModel.breadcrumbs.isEmpty()}">
<li aria-current="page" class="breadcrumb-item">
#{CmsAdminMessages['contentsection.assetfolders.title']}
</li>
</c:when>
<c:otherwise>
<li class="breadcrumb-item">
<a href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/assetsfolders">
#{CmsAdminMessages['contentsection.assetfolders.title']}
</a>
</li>
</c:otherwise>
</c:choose>
<c:forEach items="#{AssetFolderModel.breadcrumbs}"
var="breadcrumb">
<c:choose>
<c:when test="#{breadcrumb.currentFolder}">
<li class="breadcrumb-item #{breadcrumb.currentFolder ? 'active' : ''}">
#{breadcrumb.pathToken}
</li>
</c:when>
<c:otherwise>
<li class="breadcrumb-item">
<a href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/assetfolders/#{breadcrumb.path}">
#{breadcrumb.pathToken}
</a>
</li>
</c:otherwise>
</c:choose>
</c:forEach>
</ui:define>
<ui:define name="main">
<div class="container-fluid">
<h1>#{CmsAdminMessages.getMessage("contentsection.asset.heading", [ContentSectionModel.sectionName, CmsSelectedAssetModel.assetTitle])}</h1>
<ui:insert name="assetMain" />
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/assets/asset.xhtml">
<ui:param name="activePage" value="asset" />
<ui:param name="title" value="#{CmsAdminMessages['contentsection.assets.createstep.not_available.title']}" />
<ui:define name="breadcrumb">
<li aria-current="page" class="breadcrumb-item">
#{CmsAdminMessages['contentsection.assets.createstep.breadcrumb']} #{assetType}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<div class="alert alert-danger" role="alert">
#{CmsAdminMessages.getMessage('contentsection.assets.createstep.not_available.message', [section, folderPath, assetType])}
</div>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -783,3 +783,14 @@ contentsection.assetfolder.new_asset_dialog.title=Create new asset
contentsection.assetfolder.new_asset_dialog.assettype.help=Select the type of the new asset.
contentsection.assetfolder.new_asset_dialog.assettype.label=Type
contentsection.assetfolder.new_asset_dialog.submit=Create asset
contentsection.asset_access_denied.title=Access denied
contentsection.asset_access_denied.breadcrumb=Access denied
contentsection.asset_access_denied.message=Access to edit step of asset {1} of content section {0} denied.
contentsection.assets.asset_not_found.title=Asset not found
contentsection.asset_not_found.breadcrumb=Asset not found
contentsection.asset.not_found.message=There is no asset {1} in content section {0}.
contentsection.assets.asset_type.not_available.title=Asset Type not available
contentsection.assets.asset_type.not_available.message=No asset type {1} available for content section {0}.
contentsection.assets.createstep.not_available.title=No create step available
contentsection.assets.createstep.breadcrumb=Create {0} asset
contentsection.assets.createstep.not_available.message=Unable to create new asset of type {2} in folder {1} of content section{0}. Create step for asset type {2} not available.

View File

@ -784,3 +784,14 @@ contentsection.assetfolder.new_asset_dialog.title=Neues Asset erstellen
contentsection.assetfolder.new_asset_dialog.assettype.help=W\u00e4hlen Sie den Typ des neuen Assets aus.
contentsection.assetfolder.new_asset_dialog.assettype.label=Typ
contentsection.assetfolder.new_asset_dialog.submit=Asset erstellen
contentsection.asset_access_denied.title=Zugriff verweigert
contentsection.asset_access_denied.breadcrumb=Zugriff verweigert
contentsection.asset_access_denied.message=Zugriff zur Bearbeitung von Asset {1} der Content Section {0} verweigert.
contentsection.assets.asset_not_found.title=Asset nicht gefunden
contentsection.asset_not_found.breadcrumb=Asset nicht gefunden
contentsection.asset.not_found.message=Es kein Asset {1} in Content Section {0}.
contentsection.assets.asset_type.not_available.title=Asset Typ nicht verf\u00fcgbar
contentsection.assets.asset_type.not_available.message=Kein Asset Typ {1} f\u00fcr Content Section {0} verf\u00fcgbar.
contentsection.assets.createstep.not_available.title=Kein Formular zum Erstellen verf\u00fcgbar
contentsection.assets.createstep.breadcrumb={0} asset anlegen
contentsection.assets.createstep.not_available.message=Anlegen eines Assets vom Type {2} in Ordner {1} der Content Section {0} nicht m\u00f6glich. Formular zum Anlegen von Assets des Types {2} nicht verf\u00fcgbar.

View File

@ -1,2 +1,3 @@
create_step=Access denied
asset.edit.denied=Access denied.

View File

@ -1,2 +1,3 @@
create_step=Zugriff verweigert
asset.edit.denied=Zugriff verweigert